PageSourceSearch

https://www.unionmart.ru/bitrix/cache/js/s1/design2025/page_e44e37…1bdca1e610e79768ddc1_v1.js?1789638665362994

js unionmart.ru collected 2026-10-01 12:36:17 UTC 362,994 bytes, 8,262 lines download raw bytes

1
2; /* Start:"a:4:{s:4:"full";s:106:"/bitrix/templates/design2025/components/bitrix/sale.order.ajax/tanais.order.ajax/script.js?178829006313420";s:6:"source";s:90:"/bitrix/templates/design2025/components/bitrix/sale.order.ajax/tanais.order.ajax/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
3BX.saleOrderAjax = { // bad solution, actually, a singleton at the page
4
5	BXCallAllowed: false,
6
7	options: {},
8	indexCache: {},
9	controls: {},
10
11	modes: {},
12	properties: {},
13
14	// called once, on component load
15	init: function(options)
16	{
17		var ctx = this;
18		this.options = options;
19
20		window.submitFormProxy = BX.proxy(function(){
21			ctx.submitFormProxy.apply(ctx, arguments);
22		}, this);
23
24		BX(function(){
25			ctx.initDeferredControl();
26		});
27		BX(function(){
28			ctx.BXCallAllowed = true; // unlock form refresher
29		});
30
31		this.controls.scope = BX('bx-soa-order');
32
33		// user presses "add location" when he cannot find location in popup mode
34		BX.bindDelegate(this.controls.scope, 'click', {className: '-bx-popup-set-mode-add-loc'}, function(){
35
36			var input = BX.create('input', {
37				attrs: {
38					type: 'hidden',
39					name: 'PERMANENT_MODE_STEPS',
40					value: '1'
41				}
42			});
43
44			BX.prepend(input, BX('bx-soa-order'));
45
46			ctx.BXCallAllowed = false;
47			BX.Sale.OrderAjaxComponent.sendRequest();
48		});
49	},
50
51	cleanUp: function(){
52
53		for(var k in this.properties)
54		{
55			if (this.properties.hasOwnProperty(k))
56			{
57				if(typeof this.properties[k].input != 'undefined')
58				{
59					BX.unbindAll(this.properties[k].input);
60					this.properties[k].input = null;
61				}
62
63				if(typeof this.properties[k].control != 'undefined')
64					BX.unbindAll(this.properties[k].control);
65			}
66		}
67
68		this.properties = {};
69	},
70
71	addPropertyDesc: function(desc){
72		this.properties[desc.id] = desc.attributes;
73		this.properties[desc.id].id = desc.id;
74	},
75
76	// called each time form refreshes
77	initDeferredControl: function()
78	{
79		var ctx = this,
80			k,
81			row,
82			input,
83			locPropId,
84			m,
85			control,
86			code,
87			townInputFlag,
88			adapter;
89
90		// first, init all controls
91		if(typeof window.BX.locationsDeferred != 'undefined'){
92
93			this.BXCallAllowed = false;
94
95			for(k in window.BX.locationsDeferred){
96
97				window.BX.locationsDeferred[k].call(this);
98				window.BX.locationsDeferred[k] = null;
99				delete(window.BX.locationsDeferred[k]);
100
101				this.properties[k].control = window.BX.locationSelectors[k];
102				delete(window.BX.locationSelectors[k]);
103			}
104		}
105
106		for(k in this.properties){
107
108			// zip input handling
109			if(this.properties[k].isZip){
110				row = this.controls.scope.querySelector('[data-property-id-row="'+k+'"]');
111				if(BX.type.isElementNode(row)){
112
113					input = row.querySelector('input[type="text"]');
114					if(BX.type.isElementNode(input)){
115						this.properties[k].input = input;
116
117						// set value for the first "location" property met
118						locPropId = false;
119						for(m in this.properties){
120							if(this.properties[m].type == 'LOCATION'){
121								locPropId = m;
122								break;
123							}
124						}
125
126						if(locPropId !== false){
127							BX.bindDebouncedChange(input, function(value){
128
129								var zipChangedNode = BX('ZIP_PROPERTY_CHANGED');
130								zipChangedNode && (zipChangedNode.value = 'Y');
131
132								input = null;
133								row = null;
134
135								if(BX.type.isNotEmptyString(value) && /^\s*\d+\s*$/.test(value) && value.length > 3){
136
137									ctx.getLocationsByZip(value, function(locationsData){
138										ctx.properties[locPropId].control.setValueByLocationIds(locationsData);
139									}, function(){
140										try{
141											// ctx.properties[locPropId].control.clearSelected();
142										}catch(e){}
143									});
144								}
145							});
146						}
147					}
148				}
149			}
150
151			// location handling, town property, etc...
152			if(this.properties[k].type == 'LOCATION')
153			{
154
155				if(typeof this.properties[k].control != 'undefined'){
156
157					control = this.properties[k].control; // reference to sale.location.selector.*
158					code = control.getSysCode();
159
160					// we have town property (alternative location)
161					if(typeof this.properties[k].altLocationPropId != 'undefined')
162					{
163						if(code == 'sls') // for sale.location.selector.search
164						{
165							// replace default boring "nothing found" label for popup with "-bx-popup-set-mode-a
165dd-loc" inside
166							control.replaceTemplate('nothing-found', this.options.messages.notFoundPrompt);
167						}
168
169						if(code == 'slst')  // for sale.location.selector.steps
170						{
171							(function(k, control){
172
173								// control can have "select other location" option
174								control.setOption('pseudoValues', ['other']);
175
176								// insert "other location" option to popup
177								control.bindEvent('control-before-display-page', function(adapter){
178
179									control = null;
180
181									var parentValue = adapter.getParentValue();
182
183									// you can choose "other" location only if parentNode is not root and is selectable
184									if(parentValue == this.getOption('rootNodeValue') || !this.checkCanSelectItem(parentValue))
185										return;
186
187									var controlInApater = adapter.getControl();
188
189									if(typeof controlInApater.vars.cache.nodes['other'] == 'undefined')
190									{
191										controlInApater.fillCache([{
192											CODE:		'other',
193											DISPLAY:	ctx.options.messages.otherLocation,
194											IS_PARENT:	false,
195											VALUE:		'other'
196										}], {
197											modifyOrigin:			true,
198											modifyOriginPosition:	'prepend'
199										});
200									}
201								});
202
203								townInputFlag = BX('LOCATION_ALT_PROP_DISPLAY_MANUAL['+parseInt(k)+']');
204
205								control.bindEvent('after-select-real-value', function(){
206
207									// some location chosen
208									if(BX.type.isDomNode(townInputFlag))
209										townInputFlag.value = '0';
210								});
211								control.bindEvent('after-select-pseudo-value', function(){
212
213									// option "other location" chosen
214									if(BX.type.isDomNode(townInputFlag))
215										townInputFlag.value = '1';
216								});
217
218								// when user click at default location or call .setValueByLocation*()
219								control.bindEvent('before-set-value', function(){
220									if(BX.type.isDomNode(townInputFlag))
221										townInputFlag.value = '0';
222								});
223
224								// restore "other location" label on the last control
225								if(BX.type.isDomNode(townInputFlag) && townInputFlag.value == '1'){
226
227									// a little hack: set "other location" text display
228									adapter = control.getAdapterAtPosition(control.getStackSize() - 1);
229
230									if(typeof adapter != 'undefined' && adapter !== null)
231										adapter.setValuePair('other', ctx.options.messages.otherLocation);
232								}
233
234							})(k, control);
235						}
236					}
237				}
238			}
239		}
240
241		this.BXCallAllowed = true;
242
243		//set location initialized flag and refresh region & property actual content
244		if (BX.Sale.OrderAjaxComponent)
245			BX.Sale.OrderAjaxComponent.locationsCompletion();
246	},
247
248	checkMode: function(propId, mode){
249
250		//if(typeof this.modes[propId] == 'undefined')
251		//	this.modes[propId] = {};
252
253		//if(typeof this.modes[propId] != 'undefined' && this.modes[propId][mode])
254		//	return true;
255
256		if(mode == 'altLocationChoosen'){
257
258			if(this.checkAbility(propId, 'canHaveAltLocation')){
259
260				var input = this.getInputByPropId(this.properties[propId].altLocationPropId);
261				var altPropId = this.properties[propId].altLocationPropId;
262
263				if(input !== false && input.value.length > 0 && !input.disabled && this.properties[altPropId].valueSource != 'default'){
264
265					//this.modes[propId][mode] = true;
266					return true;
267				}
268			}
269		}
270
271		return false;
272	},
273
274	checkAbility: function(propId, ability){
275
276		if(typeof this.properties[propId] == 'undefined')
277			this.properties[propId] = {};
278
279		if(typeof this.properties[propId].abilities == 'undefined')
280			this.properties[propId].abilities = {};
281
282		if(typeof this.properties[propId].abilities != 'undefined' && this.properties[propId].abilities[ability])
283			return true;
284
285		if(ability == 'canHaveAltLocation'){
286
287			if(this.properties[propId].type == 'LOCATION'){
288
289				// try to find corresponding alternate location prop
290				if(typeof this.properties[propId].altLocationPropId != 'undefined' && typeof this.properties[this.properties[propId].altLocationPropId]){
291
292					var altLocPropId = this.properties[propId].altLocationPropId;
293
294					if(typeof this.properties[propId].control != 'undefined' && this.properties[propId].control.getSysCode() == 'slst'){
295
296						if(this.getInputByPropId(altLocPropId) !== false){
297							this.properties[propId].abilities[ability] = true;
298							return true;
299						}
300					}
301				}
302			}
303
304		}
305
306		return false;
307	},
308
309	getInputByPropId: function(propId){
310		if(typeof this.properties[propId].input != 'undefined')
311			return this.properties[propId].input;
312
313		var row = this.getRowByPropId(propId);
314		if(BX.type.isElementNode(row)){
315			var input = row.querySelector('input[type="text"]');
316			if(BX.type.isElementNode(input)){
317				this.properties[propId].input = input;
318				return input;
319			}
320		}
321
322		return false;
323	},
324
325	getRowByPropId: function(propId){
326
327		if(typeof this.properties[propId].row != 'undefined')
328			return this.properties[propId].row;
329
330		var row = this.controls.scope.querySelector('[data-property-id-row="'+propId+'"]');
331		if(BX.type.isElementNode(row)){
332			this.properties[propId].row = row;
333			return row;
334		}
335
336		return false;
337	},
338
339	getAltLocPropByRealLocProp: function(propId){
340		if(typeof this.properties[propId].altLocationPropId != 'undefined')
341			return this.properties[this.properties[propId].altLocationPropId];
342
343		return false;
344	},
345
346	toggleProperty: function(propId, way, dontModifyRow){
347
348		var prop = this.properties[propId];
349
350		if(typeof prop.row == 'undefined')
351			prop.row = this.getRowByPropId(propId);
352
353		if(typeof prop.input == 'undefined')
354			prop.input = this.getInputByPropId(propId);
355
356		if(!way){
357			if(!dontModifyRow)
358				BX.hide(prop.row);
359			prop.input.disabled = true;
360		}else{
361			if(!dontModifyRow)
362				BX.show(prop.row);
363			prop.input.disabled = false;
364		}
365	},
366
367	submitFormProxy: function(item, control)
368	{
369		var propId = false;
370		for(var k in this.properties){
371			if(typeof this.properties[k].control != 'undefined' && this.properties[k].control == control){
372				propId = k;
373				break;
374			}
375		}
376
377		// turning LOCATION_ALT_PROP_DISPLAY_MANUAL on\off
378
379		if(item != 'other'){
380
381			if(this.BXCallAllowed){
382
383				this.BXCallAllowed = false;
384				setTimeout(function(){BX.Sale.OrderAjaxComponent.sendRequest()}, 20);
385			}
386
387		}
388	},
389
390	getPreviousAdapterSelectedNode: function(control, adapter){
391
392		var index = adapter.getIndex();
393		var prevAdapter = control.getAdapterAtPosition(index - 1);
394
395		if(typeof prevAdapter !== 'undefined' && prevAdapter != null){
396			var prevValue = prevAdapter.getControl().getValue();
397
398			if(typeof prevValue != 'undefined'){
399				var node = control.getNodeByValue(prevValue);
400
401				if(typeof node != 'undefined')
402					return node;
403
404				return false;
405			}
406		}
407
408		return false;
409	},
410	getLocationsByZip: function(value, successCallback, notFoundCallback)
411	{
412		if(typeof this.indexCache[value] != 'undefined')
413		{
414			successCallback.apply(this, [this.indexCache[value]]);
415			return;
416		}
417
418		var ctx = this;
419
420		BX.ajax({
421			url: this.options.source,
422			method: 'post',
423			dataType: 'json',
424			async: true,
425			processData: true,
426			emulateOnload: true,
427			start: true,
428			data: {'ACT': 'GET_LOCS_BY_ZIP', 'ZIP': value},
429			//cache: true,
430			onsuccess: function(result){
431				if(result.result)
432				{
433					ctx.indexCache[value] = result.data;
434					successCallback.apply(ctx, [result.data]);
435				}
436				else
437				{
438					notFoundCallback.call(ctx);
439				}
440			},
441			onfailure: function(type, e){
442				// on error do nothing
443			}
444		});
445	}
446};
447
448$(function () {
449	$(".soa-action-save-to-pdf").on("click", function () {
450		window.location.href = BX.Sale.OrderAjaxComponent.templateFolder + "/ajax/spec_ajax.php?type=pdf";
451	});
452
453	$(".soa-action-print").on("click", function () {
454		$.get(
455			BX.Sale.OrderAjaxComponent.templateFolder + "/ajax/spec_ajax.php",
456			{
457				"type": "html"
458			},
459			function (resultHtml) {
460				var printWindow = window.open("", "", "left=50,top=50,width=930,height=640,toolbar=0,scrollbars=1,status=0");
461				printWindow.document.write(resultHtml);
462				printWindow.document.close();
463				printWindow.focus();
464				printWindow.print();
465			},
466			"html"
467		);
468	});
469
470    $(".soa-icon-share-basket").on("click", function (event) {
471        event.preventDefault();
472
473        const items = BX.Sale.BasketComponent.items;
474        const itemStrings = Object.keys(items).map((key) => {
475            const item = items[key];
476            const delayedValue = item.DELAYED ? '1' : '0';
477            return `${item.PRODUCT_ID}.${item.QUANTITY}.${delayedValue}`;
478        });
479
480        const prodUrl = itemStrings.join('/');
481
482        const finalUrl = window.location.protocol + "//" + window.location.hostname + window.location.pathname + "share_order/" + btoa(prodUrl);
483
484        let tempInput = document.createElement("input");
485        tempInput.value = finalUrl;
486        document.body.appendChild(tempInput);
487        tempInput.select();
488        document.execCommand("copy");
489        document.body.removeChild(tempInput);
490
491        $(".copy-success-message").show();
492
493        setTimeout(function () {
494            $(".copy-success-message").fadeOut();
495        }, 3000);
496    });
497});
498
499/* End */
500;
501; /* Start:"a:4:{s:4:"full";
501s:111:"/bitrix/templates/design2025/components/bitrix/sale.order.ajax/tanais.order.ajax/order_ajax.js?1788290063335535";s:6:"source";s:94:"/bitrix/templates/design2025/components/bitrix/sale.order.ajax/tanais.order.ajax/order_ajax.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
502BX.namespace('BX.Sale.OrderAjaxComponent');
503
504(function () {
505    'use strict';
506
507    /**
508     * Show empty default property value to multiple properties without default values
509     */
510    if (BX.Sale && BX.Sale.Input && BX.Sale.Input.Utils) {
511        BX.Sale.Input.Utils.asMultiple = function (value) {
512            if (value === undefined || value === null || value === '') {
513                return [];
514            } else if (value.constructor === Array) {
515                var i = 0, length = value.length, val;
516
517                for (; i < length;) {
518                    val = value[i];
519
520                    if (val === undefined || val === null || val === '') {
521                        value.splice(i, 1);
522                        --length;
523                    } else {
524                        ++i;
525                    }
526                }
527
528                return value.length ? value : [''];
529            } else {
530                return [value];
531            }
532        };
533    }
534
535    BX.Sale.OrderAjaxComponent = {
536
537        initializePrimaryFields: function () {
538            this.BXFormPosting = false;
539            this.regionBlockNotEmpty = false;
540            this.locationsInitialized = false;
541            this.locations = {};
542            this.cleanLocations = {};
543            this.locationsTemplate = '';
544            this.pickUpMapFocused = false;
545            this.options = {};
546            this.activeSectionId = '';
547            this.firstLoad = true;
548            this.initialized = {};
549            this.mapsReady = false;
550            this.lastSelectedDelivery = 0;
551            this.deliveryLocationInfo = {};
552            this.deliveryPagination = {};
553            this.deliveryCachedInfo = [];
554            this.paySystemPagination = {};
555            this.validation = {};
556            this.hasErrorSection = {};
557            this.pickUpPagination = {};
558            this.timeOut = {};
559            this.isMobile = BX.browser.IsMobile();
560            this.isHttps = window.location.protocol === "https:";
561            this.orderSaveAllowed = false;
562            this.socServiceHiddenNode = false;
563        },
564
565        /**
566         * Initialization of sale.order.ajax component js
567         */
568        init: function (parameters) {
569            this.initializePrimaryFields();
570
571            this.result = parameters.result || {};
572            this.prepareLocations(parameters.locations);
573            this.params = parameters.params || {};
574            this.signedParamsString = parameters.signedParamsString || '';
575            this.siteId = parameters.siteID || '';
576            this.ajaxUrl = parameters.ajaxUrl || '';
577            this.templateFolder = parameters.templateFolder || '';
578            this.imgFolder = parameters.imgFolder || '';
579            this.defaultBasketItemLogo = this.templateFolder + "/images/product_logo.png";
580            this.defaultStoreLogo = this.templateFolder + "/images/pickup_logo.png";
581            this.defaultDeliveryLogo = this.templateFolder + "/images/delivery_logo.png";
582            this.defaultPaySystemLogo = this.templateFolder + "/images/pay_system_logo.png";
583
584            this.orderBlockNode = BX(parameters.orderBlockId);
585            this.totalBlockNode = BX(parameters.totalBlockId);
586            this.mobileTotalBlockNode = BX(parameters.totalBlockId + '-mobile');
587            this.savedFilesBlockNode = BX('bx-soa-saved-files');
588            this.orderSaveBlockNode = BX('bx-soa-orderSave');
589            this.mainErrorsNode = BX('bx-soa-main-notifications');
590
591            this.authBlockNode = BX(parameters.authBlockId);
592            this.authHiddenBlockNode = BX(parameters.authBlockId + '-hidden');
593            this.basketBlockNode = BX(parameters.basketBlockId);
594            this.basketHiddenBlockNode = BX(parameters.basketBlockId + '-hidden');
595            this.regionBlockNode = BX(parameters.regionBlockId);
596            this.regionHiddenBlockNode = BX(parameters.regionBlockId + '-hidden');
597            this.paySystemBlockNode = BX(parameters.paySystemBlockId);
598            this.paySystemHiddenBlockNode = BX(parameters.paySystemBlockId + '-hidden');
599            this.deliveryBlockNode = BX(parameters.deliveryBlockId);
600            this.deliveryHiddenBlockNode = BX(parameters.deliveryBlockId + '-hidden');
601            this.pickUpBlockNode = BX(parameters.pickUpBlockId);
602            this.pickUpHiddenBlockNode = BX(parameters.pickUpBlockId + '-hidden');
603            this.propsBlockNode = BX(parameters.propsBlockId);
604            this.propsHiddenBlockNode = BX(parameters.propsBlockId + '-hidden');
605
606            if (this.result.SHOW_AUTH) {
607                this.authBlockNode.style.display = '';
608                BX.addClass(this.authBlockNode, 'bx-active');
609                this.authGenerateUser = this.result.AUTH.new_user_registration_email_confirmation !== 'Y' && this.result.AUTH.new_user_phone_required !== 'Y';
610            }
611
612            if (this.totalBlockNode) {
613                this.totalInfoBlockNode = this.totalBlockNode.querySelector('.bx-soa-cart-total');
614                this.totalInfoBlockDataNode = this.totalBlockNode.querySelector('.bx-soa-cart-total-data');
615                this.totalGhostBlockNode = this.totalBlockNode.querySelector('.bx-soa-cart-total-ghost');
616            }
617
618            this.options.deliveriesPerPage = parseInt(parameters.params.DELIVERIES_PER_PAGE);
619            this.options.paySystemsPerPage = parseInt(parameters.params.PAY_SYSTEMS_PER_PAGE);
620            this.options.pickUpsPerPage = parseInt(parameters.params.PICKUPS_PER_PAGE);
621
622            this.options.showWarnings = !!parameters.showWarnings;
623            this.options.propertyValidation = !!parameters.propertyValidation;
624            this.options.priceDiffWithLastTime = false;
625
626            this.options.pickUpMap = parameters.pickUpMap;
627            this.options.propertyMap = parameters.propertyMap;
628
629            this.options.totalPriceChanged = false;
630
631            if (!this.result.IS_AUTHORIZED || typeof this.result.LAST_ORDER_DATA.FAIL !== 'undefined')
632                this.initFirstSection();
633
634            BX.addClass(this.basketBlockNode, 'bx-selected');
635
636            this.initOptions();
637            this.editOrder();
638            this.bindEvents();
639
640            this.orderBlockNode.removeAttribute('style');
641            this.basketBlockScrollCheck();
642
643            if (this.params.USE_ENHANCED_ECOMMERCE === 'Y') {
644                this.setAnalyticsDataLayer('checkout');
645            }
646
647            if (this.params.USER_CONSENT === 'Y') {
648                this.initUserConsent();
649            }
650        },
651
652        /**
653         * Send ajax request with order data and executes callback by action
654         */
655        sendRequest: function (action, actionData) {
656            var form;
657
658            if (!this.startLoader())
659                return;
660
661            this.firstLoad = false;
662
663            action = BX.type.isNotEmptyString(action) ? action : 'refreshOrderAjax';
664
665            if (action === 'saveOrderAjax') {
666                form = BX('bx-soa-order-form');
667                if (form) {
668                    form.querySelector('input[type=hidden][name=sessid]').value = BX.bitrix_sessid();
669                }
670
671                BX.ajax.submitAjax(
672                    BX('bx-soa-order-form'),
673                    {
674                        url: this.ajaxUrl,
675                        method: 'POST',
676                        dataType: 'json',
677                        data: {
678                            via_ajax: 'Y',
679                            action: 'saveOrderAjax',
680                            sessid: BX.bitrix_sessid(),
681                            SITE_ID: this.siteId,
682                            signedParamsString: this.signedParamsString
683                        },
684                        onsuccess: BX.proxy(this.saveOrderWithJson, this),
685                        onfailure: BX.proxy(this.handleNotRedirected, this)
686                    }
687                );
688            } else {
689                BX.ajax({
690                    method: 'POST',
691                    dataType: 'json',
692                    url: this.ajaxUrl,
693                    data: this.getData(action, actionData),
694                    onsuccess: BX.delegate(function (result) {
695                        if (result.redirect && result.redirect.length)
696                            document.location.href = result.redirect;
697
698                        this.saveFiles();
699                        switch (action) {
700                            case 'refreshOrderAjax':
701                                this.refreshOrder(result);
702                                break;
703                            case 'confirmSmsCode':
704                            case 'showAuthForm':
705                                this.firstLoad = true;
706                                this.refreshOrder(result);
707                                break;
708                            case 'enterCoupon':
709                                if (result && result.order) {
710                                    this.deliveryCachedInfo = [];
711                                    this.refreshOrder(result);
712                                    BX.Sale.BasketComponent.sendRequest("refreshAjax", {onlyBasketRefresh: true});
713                                } else {
714                                    this.addCoupon(result);
715                                }
716
717                                break;
718                            case 'removeCoupon':
719                                if (result && result.order) {
720                                    this.deliveryCachedInfo = [];
721                                    this.refreshOrder(result);
722                                    BX.Sale.BasketComponent.sendRequest("refreshAjax", {onlyBasketRefresh: true});
723                                } else {
724                                    this.removeCoupon(result);
725                                }
726
727                                break;
728                        }
729                        BX.cleanNode(this.savedFilesBlockNode);
730                        this.endLoader();
731                    }, this),
732                    onfailure: BX.delegate(function () {
733                        this.endLoader();
734                    }, this)
735                });
736            }
737        },
738
739        getData: function (action, actionData) {
740            var data = {
741                order: this.getAllFormData(),
742                sessid: BX.bitrix_sessid(),
743                via_ajax: 'Y',
744                SITE_ID: this.siteId,
745                signedParamsString: this.signedParamsString
746            };
747
748            data[this.params.ACTION_VARIABLE] = action;
749
750            if (action === 'enterCoupon' || action === 'removeCoupon')
751                data.coupon = actionData;
752
753            return data;
754        },
755
756        getAllFormData: function () {
757            var form = BX('bx-soa-order-form'),
758                prepared = BX.ajax.prepareForm(form),
759                i;
760
761            for (i in prepared.data) {
762                if (prepared.data.hasOwnProperty(i) && i == '') {
763                    delete prepared.data[i];
764                }
765            }
766
767            return !!prepared && prepared.data ? prepared.data : {};
768        },
769
770        /**
771         * Refreshes order via json data from ajax request
772         */
773        refreshOrder: function (result) {
774            if (result.error) {
775                this.showError(this.mainErrorsNode, result.error);
776                this.animateScrollTo(this.mainErrorsNode, 800, 20);
777            } else if (result.order.SHOW_AUTH) {
778                var animation;
779
780                if (
781                    (result.order.OK_MESSAGE && result.order.OK_MESSAGE.length)
782                    || (result.order.SMS_AUTH && result.order.SMS_AUTH.TYPE === 'OK')
783                ) {
784                    animation = 'bx-step-good';
785                } else {
786                    animation = 'bx-step-bad';
787                }
788
789                this.addAnimationEffect(this.authBlockNode, animation);
790                BX.merge(this.result, result.order);
791                this.editAuthBlock();
792                this.showAuthBlock();
793                this.showErrors(result.order.ERROR, false);
794                this.animateScrollTo(this.authBlockNode);
795            } else {
796                this.isPriceChanged(result);
797
798                if (this.activeSectionId !== this.deliveryBlockNode.id)
799                    this.deliveryCachedInfo = [];
800
801                this.result = result.order;
802                this.prepareLocations(result.locations);
803                this.locationsInitialized = false;
804                this.maxWaitTimeExpired = false;
805                this.pickUpMapFocused = false;
806                this.deliveryLocationInfo = {};
807
808                this.initialized = {};
809
810                this.initOptions();
811                this.editOrder();
812                this.mapsReady && this.initMaps();
813                BX.saleOrderAjax && BX.saleOrderAjax.initDeferredControl();
814            }
815
816            return true;
817        },
818
819        saveOrderWithJson: function (result) {
820            var redirected = false;
821
822            if (result && result.order) {
823                result = result.order;
824
825                if (result.REDIRECT_URL) {
826                    if (this.params.USE_ENHANCED_ECOMMERCE === 'Y') {
827                        this.setAnalyticsDataLayer('purchase', result.ID);
828                    }
829
830                    (window.b24order = window.b24order || []).push({id: result.ID, sum: this.result.TOTAL.ORDER_PRICE});
831
832                    redirected = true;
833                    location.href = result.REDIRECT_URL;
834                } else if (result.SHOW_AUTH) {
835                    this.result.SHOW_AUTH = result.SHOW_AUTH;
836                    this.result.AUTH = result.AUTH;
837                    this.result.SMS_AUTH = result.SMS_AUTH;
838
839                    this.editAuthBlock();
840                    this.showAuthBlock();
841                    this.animateScrollTo(this.authBlockNode);
842                } else {
843                    this.showErrors(result.ERROR, true, true);
844                }
845            }
846
847            if (!redirected) {
848                this.handleNotRedirected();
849            }
850        },
851
852        handleNotRedirected: function () {
853            this.endLoader();
854            this.disallowOrderSave();
855        },
856
857        /**
858         * Showing loader image with overlay.
859         */
860        startLoader: function () {
861            if (this.BXFormPosting === true)
862                return false;
863
864            this.BXFormPosting = true;
865
866            if (!this.loadingScreen) {
867                this.loadingScreen = new BX.PopupWindow('loading_screen', null, {
868                    overlay: {backgroundColor: 'white', opacity: 1},
869                    events: {
870                        onAfterPopupShow: BX.delegate(function () {
871                            BX.cleanNode(this.loadingScreen.popupContainer);
872                            BX.removeClass(this.loadingScreen.popupContainer, 'popup-window');
873                            this.loadingScreen.popupContainer.appendChild(
874                                BX.create('IMG', {props: {src: this.imgFolder + '/loader.gif'}})
875                            );
876                            this.loadingScreen.popupContainer.removeAttribute('style');
877                            this.loadingScreen.popupContainer.style.display = 'block';
878                        }, this)
879                    }
880                });
881                BX.addClass(this.loadingScreen.overlay.element, 'bx-step-opacity');
882            }
883
884            this.loadingScreen.overlay.element.style.opacity = '0';
885            this.loadingScreen.show();
886            this.loadingScreen.overlay.element.style.opacity = '0.6';
887
888            return true;
889        },
890
891        /**
892         * Hiding loader image with overlay.
893         */
894        endLoader: function () {
895            this.BXFormPosting = false;
896
897            if (this.loadingScreen && this.loadingScreen.isShown()) {
898                this.loadingScreen.close();
899            }
900        },
901
902        htmlspecialcharsEx: function (str) {
903            return str.replace(/&amp;/g, '&amp;amp;')
904                .replace(/&lt;/g, '&amp;lt;').replace(/&gt;/g, '&amp;gt;')
905                .replace(/&quot;/g, '&amp;quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
906        },
907
908        saveFiles: function () {
909            if (this.result.ORDER_PROP && this.result.ORDER_PROP.properties) {
910                var props = this.result.ORDER_PROP.properties, i, prop;
911                for (i = 0; i < props.length; i++) {
912                    if (props[i].TYPE == 'FILE') {
913                        prop = this.orderBlockNode.querySelector('div[data-property-id-row="' + props[i].ID + '"]');
914                        if (prop)
915                            this.savedFilesBlockNode.appendChild(prop);
916                    }
917                }
918            }
919        },
920
921        /**
922         * Animating scroll to certain node
923         */
924        animateScrollTo: function (node, duration, shiftToTop) {
925            if (!node)
926                return;
927
928            var scrollTop = BX.GetWindowScrollPos().scrollTop,
929                orderBlockPos = BX.pos(this.orderBlockNode),
930                ghostTop = BX.pos(node).top - (this.isMobile ? 50 : 0);
931
932            if (shiftToTop)
933                ghostTop -= parseInt(shiftToTop);
934
935            if (ghostTop + window.innerHeight > orderBlockPos.bottom)
936                ghostTop = orderBlockPos.bottom - window.innerHeight + 17;
937
938            new BX.easing({
939                duration: duration || 800,
940                start: {scroll: scrollTop},
941                finish: {scroll: ghostTop},
942                transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
943                step: BX.delegate(function (state) {
944                    window.scrollTo(0, state.scroll);
945                }, this)
946            }).animate();
947        },
948
949        checkKeyPress: function (event) {
950            if (event.keyCode == 13) {
951                var target = event.target || event.srcElement,
952                    send = target.getAttribute('data-send'),
953                    nextAttr, next;
954
955                if (!send) {
956                    nextAttr = target.getAttribute('data-next');
957                    if (nextAttr) {
958                        next = this.orderBlockNode.querySelector('input[name=' + nextAttr + ']');
959                        next && next.focus();
960                    }
961
962                    return BX.PreventDefault(event);
963                }
964            }
965        },
966
967        getSizeString: function (maxSize, len) {
968            var gbDivider = 1024 * 1024 * 1024,
969                mbDivider = 1024 * 1024,
970                kbDivider = 1024,
971                str;
972
973            maxSize = parseInt(maxSize);
974            len = parseInt(len);
975
976            if (maxSize >
976 gbDivider)
977                str = parseFloat(maxSize / gbDivider).toFixed(len) + ' Gb';
978            else if (maxSize > mbDivider)
979                str = parseFloat(maxSize / mbDivider).toFixed(len) + ' Mb';
980            else if (maxSize > kbDivider)
981                str = parseFloat(maxSize / kbDivider).toFixed(len) + ' Kb';
982            else
983                str = maxSize + ' B';
984
985            return str;
986        },
987
988        getFileAccepts: function (accepts) {
989            var arr = [],
990                arAccepts = accepts.split(','),
991                i, currentAccept;
992
993            var mimeTypesMap = {
994                json: 'application/json',
995                javascript: 'application/javascript',
996                'octet-stream': 'application/octet-stream',
997                ogg: 'application/ogg',
998                pdf: 'application/pdf',
999                zip: 'application/zip',
1000                gzip: 'application/gzip',
1001                aac: 'audio/aac',
1002                mp3: 'audio/mpeg',
1003                gif: 'image/gif',
1004                jpeg: 'image/jpeg',
1005                png: 'image/png',
1006                svg: 'image/svg+xml',
1007                tiff: 'image/tiff',
1008                css: 'text/css',
1009                csv: 'text/csv',
1010                html: 'text/html',
1011                plain: 'text/plain',
1012                php: 'text/php',
1013                xml: 'text/xml',
1014                mpeg: 'video/mpeg',
1015                mp4: 'video/mp4',
1016                quicktime: 'video/quicktime',
1017                flv: 'video/x-flv',
1018                doc: 'application/msword',
1019                docx: 'application/msword',
1020                xls: 'application/vnd.ms-excel',
1021                xlsx: 'application/vnd.ms-excel'
1022            };
1023
1024            for (i = 0; i < arAccepts.length; i++) {
1025                currentAccept = BX.util.trim(arAccepts[i]);
1026                currentAccept = mimeTypesMap[currentAccept] || currentAccept;
1027                arr.push(currentAccept);
1028            }
1029
1030            return arr.join(',');
1031        },
1032
1033        uniqueText: function (text, separator) {
1034            var phrases, i, output = [];
1035
1036            text = text || '';
1037            separator = separator || '<br>';
1038
1039            phrases = text.split(separator);
1040            phrases = BX.util.array_unique(phrases);
1041
1042            for (i = 0; i < phrases.length; i++) {
1043                if (phrases[i] == '')
1044                    continue;
1045
1046                output.push(BX.util.trim(phrases[i]));
1047            }
1048
1049            return output.join(separator);
1050        },
1051
1052        getImageSources: function (item, key) {
1053            if (!item || !key || !item[key])
1054                return false;
1055
1056            return {
1057                src_1x: item[key + '_SRC'],
1058                src_2x: item[key + '_SRC_2X'],
1059                src_orig: item[key + '_SRC_ORIGINAL']
1060            };
1061        },
1062
1063        getErrorContainer: function (node) {
1064            if (!node)
1065                return;
1066
1067            node.appendChild(
1068                BX.create('DIV', {props: {className: 'alert alert-danger'}, style: {display: 'none'}})
1069            );
1070        },
1071
1072        showError: function (node, msg, border) {
1073            if (BX.type.isArray(msg))
1074                msg = msg.join('<br>');
1075
1076            var errorContainer = node.querySelector('.alert.alert-danger'), animate;
1077            if (errorContainer && msg.length) {
1078                BX.cleanNode(errorContainer);
1079                errorContainer.appendChild(BX.create('DIV', {html: msg}));
1080
1081                animate = !this.hasErrorSection[node.id];
1082                if (animate) {
1083                    errorContainer.style.opacity = 0;
1084                    errorContainer.style.display = '';
1085                    new BX.easing({
1086                        duration: 300,
1087                        start: {opacity: 0},
1088                        finish: {opacity: 100},
1089                        transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
1090                        step: function (state) {
1091                            errorContainer.style.opacity = state.opacity / 100;
1092                        },
1093                        complete: function () {
1094                            errorContainer.removeAttribute('style');
1095                        }
1096                    }).animate();
1097                } else
1098                    errorContainer.style.display = '';
1099
1100                if (!!border)
1101                    BX.addClass(node, 'bx-step-error');
1102            }
1103        },
1104
1105        showErrors: function (errors, scroll, showAll) {
1106            var errorNodes = this.orderBlockNode.querySelectorAll('div.alert.alert-danger'),
1107                section, k, blockErrors;
1108
1109            for (k = 0; k < errorNodes.length; k++) {
1110                section = BX.findParent(errorNodes[k], {className: 'bx-soa-section'});
1111                BX.removeClass(section, 'bx-step-error');
1112                errorNodes[k].style.display = 'none';
1113                BX.cleanNode(errorNodes[k]);
1114            }
1115
1116            if (!errors || BX.util.object_keys(errors).length < 1)
1117                return;
1118
1119            for (k in errors) {
1120                if (!errors.hasOwnProperty(k))
1121                    continue;
1122
1123                blockErrors = errors[k];
1124                switch (k.toUpperCase()) {
1125                    case 'MAIN':
1126                        this.showError(this.mainErrorsNode, blockErrors);
1127                        this.animateScrollTo(this.mainErrorsNode, 800, 20);
1128                        scroll = false;
1129                        break;
1130                    case 'AUTH':
1131                        if (this.authBlockNode.style.display == 'none') {
1132                            this.showError(this.mainErrorsNode, blockErrors, true);
1133                            this.animateScrollTo(this.mainErrorsNode, 800, 20);
1134                            scroll = false;
1135                        } else
1136                            this.showError(this.authBlockNode, blockErrors, true);
1137                        break;
1138                    case 'REGION':
1139                        if (showAll || this.regionBlockNode.getAttribute('data-visited') === 'true') {
1140                            this.showError(this.regionBlockNode, blockErrors, true);
1141                            this.showError(this.regionHiddenBlockNode, blockErrors);
1142                        }
1143                        break;
1144                    case 'DELIVERY':
1145                        if (showAll || this.deliveryBlockNode.getAttribute('data-visited') === 'true') {
1146                            this.showError(this.deliveryBlockNode, blockErrors, true);
1147                            this.showError(this.deliveryHiddenBlockNode, blockErrors);
1148                        }
1149                        break;
1150                    case 'PAY_SYSTEM':
1151                        if (showAll || this.paySystemBlockNode.getAttribute('data-visited') === 'true') {
1152                            this.showError(this.paySystemBlockNode, blockErrors, true);
1153                            this.showError(this.paySystemHiddenBlockNode, blockErrors);
1154                        }
1155                        break;
1156                    case 'PROPERTY':
1157                        if (showAll || this.propsBlockNode.getAttribute('data-visited') === 'true') {
1158                            this.showError(this.propsBlockNode, blockErrors, true);
1159                            this.showError(this.propsHiddenBlockNode, blockErrors);
1160                        }
1161                        break;
1162                }
1163            }
1164
1165            !!scroll && this.scrollToError();
1166        },
1167
1168        showBlockErrors: function (node) {
1169            var errorNode = node.querySelector('div.alert.alert-danger'),
1170                hiddenNode, errors;
1171
1172            if (!errorNode)
1173                return;
1174
1175            BX.removeClass(node, 'bx-step-error');
1176            errorNode.style.display = 'none';
1177            BX.cleanNode(errorNode);
1178
1179            switch (node.id) {
1180                case this.regionBlockNode.id:
1181                    hiddenNode = this.regionHiddenBlockNode;
1182                    errors = this.result.ERROR.REGION;
1183                    break;
1184                case this.deliveryBlockNode.id:
1185                    hiddenNode = this.deliveryHiddenBlockNode;
1186                    errors = this.result.ERROR.DELIVERY;
1187                    break;
1188                case this.paySystemBlockNode.id:
1189                    hiddenNode = this.paySystemHiddenBlockNode;
1190                    errors = this.result.ERROR.PAY_SYSTEM;
1191                    break;
1192                case this.propsBlockNode.id:
1193                    hiddenNode = this.propsHiddenBlockNode;
1194                    errors = this.result.ERROR.PROPERTY;
1195                    break;
1196            }
1197
1198            if (errors && BX.util.object_keys(errors).length) {
1199                this.showError(node, errors, true);
1200                this.showError(hiddenNode, errors);
1201            }
1202        },
1203
1204        checkNotifications: function () {
1205            var informer = this.mainErrorsNode.querySelector('[data-type="informer"]'),
1206                success, sections, className, text, scrollTop, informerPos;
1207
1208            if (informer) {
1209                if (this.firstLoad && this.result.IS_AUTHORIZED && typeof this.result.LAST_ORDER_DATA.FAIL === 'undefined') {
1210                    sections = this.orderBlockNode.querySelectorAll('.bx-soa-section.bx-active');
1211                    success = sections.length && sections[sections.length - 1].getAttribute('data-visited') == 'true';
1212                    className = success ? 'success' : 'warning';
1213                    text = (success ? this.params.MESS_SUCCESS_PRELOAD_TEXT : this.params.MESS_FAIL_PRELOAD_TEXT).split('#ORDER_BUTTON#').join(this.params.MESS_ORDER);
1214
1215                    informer.appendChild(
1216                        BX.create('DIV', {
1217                            children: [
1218                                BX.create('DIV', {
1219                                    style: {position: 'relative', paddingLeft: '48px'},
1220                                    children: [
1221                                        BX.create('DIV', {props: {className: 'icon-' + className}}),
1222                                        BX.create('DIV', {html: text})
1223                                    ]
1224                                })
1225                            ]
1226                        })
1227                    );
1228                    BX.addClass(informer, 'alert alert-' + className);
1229                    informer.style.display = '';
1230                } else if (BX.hasClass(informer, 'alert')) {
1231                    scrollTop = BX.GetWindowScrollPos().scrollTop;
1232                    informerPos = BX.pos(informer);
1233                }
1234            }
1235        },
1236
1237        /**
1238         * Returns status of preloaded data from back-end for certain block
1239         */
1240        checkPreload: function (node) {
1241            var status;
1242
1243            switch (node.id) {
1244                case this.regionBlockNode.id:
1245                    status = this.result.LAST_ORDER_DATA && this.result.LAST_ORDER_DATA.PERSON_TYPE;
1246                    break;
1247                case this.paySystemBlockNode.id:
1248                    status = this.result.LAST_ORDER_DATA && this.result.LAST_ORDER_DATA.PAY_SYSTEM;
1249                    break;
1250                case this.deliveryBlockNode.id:
1251                    status = this.result.LAST_ORDER_DATA && this.result.LAST_ORDER_DATA.DELIVERY;
1252                    break;
1253                case this.pickUpBlockNode.id:
1254                    status = this.result.LAST_ORDER_DATA && this.result.LAST_ORDER_DATA.PICK_UP;
1255                    break;
1256                default:
1257                    status = true;
1258            }
1259
1260            return status;
1261        },
1262
1263        checkBlockErrors: function (node) {
1264            var hiddenNode, errorNode, showError, showWarning, errorTooltips, i;
1265
1266            if (hiddenNode = BX(node.id + '-hidden')) {
1267                errorNode = hiddenNode.querySelector('div.alert.alert-danger');
1268                showError = errorNode && errorNode.style.display != 'none';
1269                showWarning = hiddenNode.querySelector('div.alert.alert-warning.alert-show');
1270
1271                if (!showError) {
1272                    errorTooltips = hiddenNode.querySelectorAll('div.tooltip');
1273                    for (i = 0; i < errorTooltips.length; i++) {
1274                        if (errorTooltips[i].getAttribute('data-state') == 'opened') {
1275                            showError = true;
1276                            break;
1277                        }
1278                    }
1279                }
1280            }
1281
1282            if (showError)
1283                BX.addClass(node, 'bx-step-error');
1284            else if (showWarning)
1285                BX.addClass(node, 'bx-step-warning');
1286            else
1287                BX.removeClass(node, 'bx-step-error bx-step-warning');
1288
1289            return !showError;
1290        },
1291
1292        scrollToError: function () {
1293            var sections = this.orderBlockNode.querySelectorAll('div.bx-soa-section.bx-active'),
1294                i, errorNode;
1295
1296            for (i in sections) {
1297                if (sections.hasOwnProperty(i)) {
1298                    errorNode = sections[i].querySelector('.alert.alert-danger');
1299                    if (errorNode && errorNode.style.display != 'none') {
1300                        this.animateScrollTo(sections[i]);
1301                        break;
1302                    }
1303                }
1304            }
1305        },
1306
1307        showWarnings: function () {
1308            var sections = this.orderBlockNode.querySelectorAll('div.bx-soa-section.bx-active'),
1309                currentDelivery = this.getSelectedDelivery(),
1310                k, warningString;
1311
1312            for (k = 0; k < sections.length; k++) {
1313                BX.removeClass(sections[k], 'bx-step-warning');
1314
1315                if (sections[k].getAttribute('data-visited') == 'false')
1316                    BX.removeClass(sections[k], 'bx-step-completed');
1317            }
1318
1319            if (currentDelivery && currentDelivery.CALCULATE_ERRORS) {
1320                BX.addClass(this.deliveryBlockNode, 'bx-step-warning');
1321
1322                warningString = '<strong>' + this.params.MESS_DELIVERY_CALC_ERROR_TITLE + '</strong>';
1323                if (this.params.MESS_DELIVERY_CALC_ERROR_TEXT.length)
1324                    warningString += '<br><small>' + this.params.MESS_DELIVERY_CALC_ERROR_TEXT + '</small>';
1325
1326                this.showBlockWarning(this.deliveryBlockNode, warningString);
1327                this.showBlockWarning(this.deliveryHiddenBlockNode, warningString);
1328
1329                if (this.activeSectionId != this.deliveryBlockNode.id) {
1330                    BX.addClass(this.deliveryBlockNode, 'bx-step-completed');
1331                    BX.bind(this.deliveryBlockNode.querySelector('.alert.alert-warning'), 'click', BX.proxy(this.showByClick, this));
1332                }
1333            } else if (BX.hasClass(this.deliveryBlockNode, 'bx-step-warning') && this.activeSectionId != this.deliveryBlockNode.id) {
1334                BX.removeClass(this.deliveryBlockNode, 'bx-step-warning');
1335            }
1336
1337            if (!this.result.WARNING || !this.options.showWarnings)
1338                return;
1339
1340            for (k in this.result.WARNING) {
1341                if (this.result.WARNING.hasOwnProperty(k)) {
1342                    switch (k.toUpperCase()) {
1343                        case 'DELIVERY':
1344                            if (this.deliveryBlockNode.getAttribute('data-visited') === 'true') {
1345                                this.showBlockWarning(this.deliveryBlockNode, this.result.WARNING[k], true);
1346                                this.showBlockWarning(this.deliveryHiddenBlockNode, this.result.WARNING[k], true);
1347                            }
1348
1349                            break;
1350                        case 'PAY_SYSTEM':
1351                            if (this.paySystemBlockNode.getAttribute('data-visited') === 'true') {
1352                                this.showBlockWarning(this.paySystemBlockNode, this.result.WARNING[k], true);
1353                                this.showBlockWarning(this.paySystemHiddenBlockNode, this.result.WARNING[k], true);
1354                            }
1355
1356                            break;
1357                    }
1358                }
1359            }
1360        },
1361
1362        notifyAboutWarnings: function (node) {
1363            if (!BX.type.isDomNode(node))
1364                return;
1365
1366            switch (node.id) {
1367                case this.deliveryBlockNode.id:
1368                    this.showBlockWarning(this.deliveryBlockNode, this.result.WARNING.DELIVERY, true);
1369                    break;
1370                case this.paySystemBlockNode.id:
1371                    this.showBlockWarning(this.paySystemBlockNode, this.result.WARNING.PAY_SYSTEM, true);
1372                    break;
1373            }
1374        },
1375
1376        showBlockWarning: function (node, warnings, hide) {
1377            var errorNode = node.querySelector('.alert.alert-danger'),
1378                warnStr = '',
1379                i, warningNode, existedWarningNodes;
1380
1381            if (errorNode) {
1382                if (BX.type.isString(warnings)) {
1383                    warnStr = warnings;
1384                } else {
1385                    for (i in warnings) {
1386                        if (warnings.hasOwnProperty(i) && warnings[i]) {
1387                            warnStr += warnings[i] + '<br>';
1388                        }
1389                    }
1390                }
1391
1392                if (!warnStr) {
1393                    return;
1394                }
1395
1396                existedWarningNodes = node.querySelectorAll('.alert.alert-warning');
1397                for (i in existedWarningNodes) {
1398                    if (existedWarningNodes.hasOwnProperty(i) && BX.type.isDomNode(existedWarningNodes[i])
1398) {
1399                        if (existedWarningNodes[i].innerHTML.indexOf(warnStr) !== -1) {
1400                            return;
1401                        }
1402                    }
1403                }
1404
1405                warningNode = BX.create('DIV', {
1406                    props: {className: 'alert alert-warning' + (!!hide ? ' alert-hide' : ' alert-show')},
1407                    html: warnStr
1408                });
1409                BX.prepend(warningNode, errorNode.parentNode);
1410                BX.addClass(node, 'bx-step-warning');
1411            }
1412        },
1413
1414        showPagination: function (entity, node) {
1415            if (!node || !entity)
1416                return;
1417
1418            var pagination, navigation = [], i,
1419                pageCounter, active, paginationNode;
1420
1421            switch (entity) {
1422                case 'delivery':
1423                    pagination = this.deliveryPagination;
1424                    break;
1425                case 'paySystem':
1426                    pagination = this.paySystemPagination;
1427                    break;
1428                case 'pickUp':
1429                    pagination = this.pickUpPagination;
1430                    break;
1431            }
1432
1433            if (pagination.pages.length > 1) {
1434                navigation.push(
1435                    BX.create('LI', {
1436                        attrs: {
1437                            'data-action': 'prev',
1438                            'data-entity': entity
1439                        },
1440                        props: {className: 'bx-pag-prev'},
1441                        html: pagination.pageNumber == 1
1442                            ? '<span>' + this.params.MESS_NAV_BACK + '</span>'
1443                            : '<a href=""><span>' + this.params.MESS_NAV_BACK + '</span></a>',
1444                        events: {click: BX.proxy(this.doPagination, this)}
1445                    })
1446                );
1447                for (i = 0; i < pagination.pages.length; i++) {
1448                    pageCounter = parseInt(i) + 1;
1449                    active = pageCounter == pagination.pageNumber ? 'bx-active' : '';
1450
1451                    navigation.push(
1452                        BX.create('LI', {
1453                            attrs: {
1454                                'data-action': pageCounter,
1455                                'data-entity': entity
1456                            },
1457                            props: {className: active},
1458                            html: '<a href=""><span>' + pageCounter + '</span></a>',
1459                            events: {click: BX.proxy(this.doPagination, this)}
1460                        })
1461                    );
1462                }
1463
1464                navigation.push(
1465                    BX.create('LI', {
1466                        attrs: {
1467                            'data-action': 'next',
1468                            'data-entity': entity
1469                        },
1470                        props: {className: 'bx-pag-next'},
1471                        html: pagination.pageNumber == pagination.pages.length
1472                            ? '<span>' + this.params.MESS_NAV_FORWARD + '</span>'
1473                            : '<a href=""><span>' + this.params.MESS_NAV_FORWARD + '</span></a>',
1474                        events: {click: BX.proxy(this.doPagination, this)}
1475                    })
1476                );
1477
1478                paginationNode = BX.create('DIV', {
1479                    props: {className: 'bx-pagination'},
1480                    children: [
1481                        BX.create('DIV', {
1482                            props: {className: 'bx-pagination-container'},
1483                            children: [BX.create('UL', {children: navigation})]
1484                        })
1485                    ]
1486                });
1487
1488                node.appendChild(BX.create('DIV', {style: {clear: 'both'}}));
1489                node.appendChild(paginationNode);
1490            }
1491        },
1492
1493        doPagination: function (e) {
1494            var target = e.target || e.srcElement,
1495                node = target.tagName == 'LI' ? target : BX.findParent(target, {tagName: 'LI'}),
1496                page = node.getAttribute('data-action'),
1497                entity = node.getAttribute('data-entity'),
1498                pageNum;
1499
1500            if (BX.hasClass(node, 'bx-active'))
1501                return BX.PreventDefault(e);
1502
1503            if (page == 'prev' || page == 'next') {
1504                pageNum = parseInt(BX.findParent(node).querySelector('.bx-active').getAttribute('data-action'));
1505                page = page == 'next' ? ++pageNum : --pageNum;
1506            }
1507
1508            if (entity == 'delivery')
1509                this.showDeliveryItemsPage(page);
1510            else if (entity == 'paySystem')
1511                this.showPaySystemItemsPage(page);
1512            else if (entity == 'pickUp')
1513                this.showPickUpItemsPage(page);
1514
1515            return BX.PreventDefault(e);
1516        },
1517
1518        showDeliveryItemsPage: function (page) {
1519            this.getCurrentPageItems('delivery', page);
1520
1521            var selectedDelivery = this.getSelectedDelivery(), hidden,
1522                deliveryItemsContainer, k, deliveryItemNode;
1523
1524            if (selectedDelivery && selectedDelivery.ID) {
1525                hidden = this.deliveryBlockNode.querySelector('input[type=hidden][name=DELIVERY_ID]');
1526                if (!hidden) {
1527                    hidden = BX.create('INPUT', {
1528                        props: {
1529                            type: 'hidden',
1530                            name: 'DELIVERY_ID',
1531                            value: selectedDelivery.ID
1532                        }
1533                    })
1534                }
1535            }
1536
1537            deliveryItemsContainer = this.deliveryBlockNode.querySelector('.bx-soa-pp-item-container');
1538            BX.cleanNode(deliveryItemsContainer);
1539
1540            if (BX.type.isDomNode(hidden))
1541                BX.prepend(hidden, BX.findParent(deliveryItemsContainer));
1542
1543            for (k = 0; k < this.deliveryPagination.currentPage.length; k++) {
1544                deliveryItemNode = this.createDeliveryItem(this.deliveryPagination.currentPage[k]);
1545                deliveryItemsContainer.appendChild(deliveryItemNode);
1546            }
1547
1548            this.showPagination('delivery', deliveryItemsContainer);
1549        },
1550
1551        showPaySystemItemsPage: function (page) {
1552            this.getCurrentPageItems('paySystem', page);
1553
1554            var selectedPaySystem = this.getSelectedPaySystem(), hidden,
1555                paySystemItemsContainer, k, paySystemItemNode;
1556
1557            if (selectedPaySystem && selectedPaySystem.ID) {
1558                hidden = this.paySystemBlockNode.querySelector('input[type=hidden][name=PAY_SYSTEM_ID]');
1559                if (!hidden) {
1560                    hidden = BX.create('INPUT', {
1561                        props: {
1562                            type: 'hidden',
1563                            name: 'PAY_SYSTEM_ID',
1564                            value: selectedPaySystem.ID
1565                        }
1566                    })
1567                }
1568            }
1569
1570            paySystemItemsContainer = this.paySystemBlockNode.querySelector('.bx-soa-pp-item-container');
1571            BX.cleanNode(paySystemItemsContainer);
1572
1573            if (BX.type.isDomNode(hidden))
1574                BX.prepend(hidden, BX.findParent(paySystemItemsContainer));
1575
1576            for (k = 0; k < this.paySystemPagination.currentPage.length; k++) {
1577                paySystemItemNode = this.createPaySystemItem(this.paySystemPagination.currentPage[k]);
1578                paySystemItemsContainer.appendChild(paySystemItemNode);
1579            }
1580
1581            this.showPagination('paySystem', paySystemItemsContainer);
1582        },
1583
1584        showPickUpItemsPage: function (page) {
1585            this.getCurrentPageItems('pickUp', page);
1586            this.editPickUpList(false);
1587        },
1588
1589        getCurrentPageItems: function (entity, page) {
1590            if (!entity || typeof page === 'undefined')
1591                return;
1592
1593            var pagination, perPage;
1594
1595            switch (entity) {
1596                case 'delivery':
1597                    pagination = this.deliveryPagination;
1598                    perPage = this.options.deliveriesPerPage;
1599                    break;
1600                case 'paySystem':
1601                    pagination = this.paySystemPagination;
1602                    perPage = this.options.paySystemsPerPage;
1603                    break;
1604                case 'pickUp':
1605                    pagination = this.pickUpPagination;
1606                    perPage = this.options.pickUpsPerPage;
1607                    break;
1608            }
1609
1610            if (pagination && perPage > 0) {
1611                if (page <= 0 || page > pagination.pages.length)
1612                    return;
1613
1614                pagination.pageNumber = page;
1615                pagination.currentPage = pagination.pages.slice(pagination.pageNumber - 1, pagination.pageNumber)[0];
1616            }
1617        },
1618
1619        initPropsListForLocation: function () {
1620            if (BX.saleOrderAjax && this.result.ORDER_PROP && this.result.ORDER_PROP.properties) {
1621                var i, k, curProp, attrObj;
1622
1623                BX.saleOrderAjax.cleanUp();
1624
1625                for (i = 0; i < this.result.ORDER_PROP.properties.length; i++) {
1626                    curProp = this.result.ORDER_PROP.properties[i];
1627
1628                    if (curProp.TYPE == 'LOCATION' && curProp.MULTIPLE == 'Y' && curProp.IS_LOCATION != 'Y') {
1629                        for (k = 0; k < this.locations[curProp.ID].length; k++) {
1630                            BX.saleOrderAjax.addPropertyDesc({
1631                                id: curProp.ID + '_' + k,
1632                                attributes: {
1633                                    id: curProp.ID + '_' + k,
1634                                    type: curProp.TYPE,
1635                                    valueSource: curProp.SOURCE == 'DEFAULT' ? 'default' : 'form'
1636                                }
1637                            });
1638                        }
1639                    } else {
1640                        attrObj = {
1641                            id: curProp.ID,
1642                            type: curProp.TYPE,
1643                            valueSource: curProp.SOURCE == 'DEFAULT' ? 'default' : 'form'
1644                        };
1645
1646                        if (!this.deliveryLocationInfo.city && parseInt(curProp.INPUT_FIELD_LOCATION) > 0) {
1647                            attrObj.altLocationPropId = parseInt(curProp.INPUT_FIELD_LOCATION);
1648                            this.deliveryLocationInfo.city = curProp.INPUT_FIELD_LOCATION;
1649                        }
1650
1651                        if (!this.deliveryLocationInfo.loc && curProp.IS_LOCATION == 'Y')
1652                            this.deliveryLocationInfo.loc = curProp.ID;
1653
1654                        if (!this.deliveryLocationInfo.zip && curProp.IS_ZIP == 'Y') {
1655                            attrObj.isZip = true;
1656                            this.deliveryLocationInfo.zip = curProp.ID;
1657                        }
1658
1659                        BX.saleOrderAjax.addPropertyDesc({
1660                            id: curProp.ID,
1661                            attributes: attrObj
1662                        });
1663                    }
1664                }
1665            }
1666        },
1667
1668        /**
1669         * Binds main events for scrolling/resizing
1670         */
1671        bindEvents: function () {
1672            BX.bind(this.orderSaveBlockNode.querySelector('[data-save-button]'), 'click', BX.proxy(this.clickOrderSaveAction, this));
1673            BX.bind(window, 'scroll', BX.proxy(this.totalBlockScrollCheck, this));
1674            BX.bind(window, 'resize', BX.throttle(function () {
1675                this.totalBlockResizeCheck();
1676                this.alignBasketColumns();
1677                this.basketBlockScrollCheck();
1678                this.mapsReady && this.resizeMapContainers();
1679            }, 50, this));
1680            BX.addCustomEvent('onDeliveryExtraServiceValueChange', BX.proxy(this.sendRequest, this));
1681        },
1682
1683        initFirstSection: function () {
1684            var firstSection = this.orderBlockNode.querySelector('.bx-soa-section.bx-active');
1685            if (this.basketBlockNode && firstSection.id != this.basketBlockNode.id) {
1686                BX.addClass(firstSection, 'bx-selected');
1687            }
1688            this.activeSectionId = firstSection.id;
1689        },
1690
1691        initOptions: function () {
1692            var headers, i, total;
1693
1694            this.initPropsListForLocation();
1695
1696            this.propertyCollection = new BX.Sale.PropertyCollection(BX.merge({publicMode: true}, this.result.ORDER_PROP));
1697            this.fadedPropertyCollection = new BX.Sale.PropertyCollection(BX.merge({publicMode: true}, this.result.ORDER_PROP));
1698
1699            if (this.options.propertyValidation)
1700                this.initValidation();
1701
1702            this.initPagination();
1703
1704            this.options.showPreviewPicInBasket = false;
1705            this.options.showDetailPicInBasket = false;
1706            this.options.showPropsInBasket = false;
1707            this.options.showPriceNotesInBasket = false;
1708
1709            if (this.result.GRID && this.result.GRID.HEADERS) {
1710                headers = this.result.GRID.HEADERS;
1711                for (i = 0; i < headers.length; i++) {
1712                    if (headers[i].id === 'PREVIEW_PICTURE')
1713                        this.options.showPreviewPicInBasket = true;
1714
1715                    if (headers[i].id === 'DETAIL_PICTURE')
1716                        this.options.showDetailPicInBasket = true;
1717
1718                    if (headers[i].id === 'PROPS')
1719                        this.options.showPropsInBasket = true;
1720
1721                    if (headers[i].id === 'NOTES')
1722                        this.options.showPriceNotesInBasket = true;
1723                }
1724            }
1725
1726            if (this.result.TOTAL) {
1727                total = this.result.TOTAL;
1728                this.options.showOrderWeight = total.ORDER_WEIGHT && parseFloat(total.ORDER_WEIGHT) > 0;
1729                this.options.showPriceWithoutDiscount = parseFloat(total.ORDER_PRICE) < parseFloat(total.PRICE_WITHOUT_DISCOUNT_VALUE);
1730                this.options.showDiscountPrice = total.DISCOUNT_PRICE && parseFloat(total.DISCOUNT_PRICE) > 0;
1731                this.options.showTaxList = total.TAX_LIST && total.TAX_LIST.length;
1732                this.options.showPayedFromInnerBudget = total.PAYED_FROM_ACCOUNT_FORMATED && total.PAYED_FROM_ACCOUNT_FORMATED.length;
1733            }
1734        },
1735
1736        reachGoal: function (goal, section) {
1737            var counter = this.params.YM_GOALS_COUNTER || '',
1738                useGoals = this.params.USE_YM_GOALS == 'Y' && typeof window['yaCounter' + counter] !== 'undefined',
1739                goalId;
1740
1741            if (useGoals) {
1742                goalId = this.getGoalId(goal, section);
1743                window['yaCounter' + counter].reachGoal(goalId);
1744            }
1745        },
1746
1747        getGoalId: function (goal, section) {
1748            if (!goal)
1749                return '';
1750
1751            if (goal == 'initialization')
1752                return this.params.YM_GOALS_INITIALIZE;
1753
1754            if (goal == 'order')
1755                return this.params.YM_GOALS_SAVE_ORDER;
1756
1757            var goalId = '',
1758                isEdit = goal == 'edit';
1759
1760            if (!section || !section.id)
1761                return '';
1762
1763            switch (section.id) {
1764                case this.basketBlockNode.id:
1765                    goalId = isEdit ? this.params.YM_GOALS_EDIT_BASKET : this.params.YM_GOALS_NEXT_BASKET;
1766                    break;
1767                case this.regionBlockNode.id:
1768                    goalId = isEdit ? this.params.YM_GOALS_EDIT_REGION : this.params.YM_GOALS_NEXT_REGION;
1769                    break;
1770                case this.paySystemBlockNode.id:
1771                    goalId = isEdit ? this.params.YM_GOALS_EDIT_PAY_SYSTEM : this.params.YM_GOALS_NEXT_PAY_SYSTEM;
1772                    break;
1773                case this.deliveryBlockNode.id:
1774                    goalId = isEdit ? this.params.YM_GOALS_EDIT_DELIVERY : this.params.YM_GOALS_NEXT_DELIVERY;
1775                    break;
1776                case this.pickUpBlockNode.id:
1777                    goalId = isEdit ? this.params.YM_GOALS_EDIT_PICKUP : this.params.YM_GOALS_NEXT_PICKUP;
1778                    break;
1779                case this.propsBlockNode.id:
1780                    goalId = isEdit ? this.params.YM_GOALS_EDIT_PROPERTIES : this.params.YM_GOALS_NEXT_PROPERTIES;
1781                    break;
1782            }
1783
1784            return goalId;
1785        },
1786
1787        isPriceChanged: function (result) {
1788            var priceBefore = this.result.TOTAL.ORDER_TOTAL_LEFT_TO_PAY === null || this.result.TOTAL.ORDER_TOTAL_LEFT_TO_PAY === ''
1789                    ? this.result.TOTAL.ORDER_TOTAL_PRICE
1790                    : this.result.TOTAL.ORDER_TOTAL_LEFT_TO_PAY,
1791                priceAfter = result.order.TOTAL.ORDER_TOTAL_LEFT_TO_PAY === null ? result.order.TOTAL.ORDER_TOTAL_PRICE : result.order.TOTAL.ORDER_TOTAL_LEFT_TO_PAY;
1792
1793            this.options.totalPriceChanged = parseFloat(priceBefore) != parseFloat(priceAfter);
1794        },
1795
1796        initValidation: function () {
1797            if (!this.result.ORDER_PROP || !this.result.ORDER_PROP.properties)
1798                return;
1799
1800            var properties = this.result.ORDER_PROP.properties,
1801                obj = {}, i;
1802
1803            for (i in properties) {
1804                if (properties.hasOwnProperty(i))
1805                    obj[properties[i].ID] = properties[i];
1806            }
1807
1808            this.validation.properties = obj;
1809        },
1810
1811        initPagination: function () {
1812            var arReserve, pages, arPages, i;
1813
1814            if (this.result.DELIVERY) {
1815                this.result.DELIVERY = this.getDeliverySortedArray(this.result.DELIVERY);
1816
1817                if (this.options.deliveriesPerPage > 0 && this.result.DELIVERY.length > this.options.deliveriesPerPage) {
1818                    arReserve = this.result.DELIVERY.slice();
1819                    pages = Math.ceil(arReserve.length / this.options.deliveriesPerPage);
1820                    arPages = [];
1821
1822                    for (i = 0; i < pages; i++) {
1823                        arPages.push(arReserve.splice(0, this.options.deliveriesPerPage));
1824                    }
1825                    this.deliveryPagination.pages = arPages;
1826
1827                    for (i = 0; i < this.result.DELIVERY.length; i++) {
1828                        if (this.result.DELIVERY[i].CHECKED == 'Y') {
1829                            this.deliveryPagination.pageNumber = Math.ceil(++i / this.options.deliveriesPerPage);
1830                            break;
1831                        }
1832                    }
1833
1834                    this.deliveryPagination.pageNumber = this.deliveryPagination.pageNumber || 1;
1835                    this.deliveryPagination.currentPage = arPages.slice(this.deliveryPagination.pageNumber - 1, this.deliveryPagination.pageNumber)[0];
1836                    this.deliveryPagination.show = true
1837                } else {
1838                    this.deliveryPagination.pageNumber = 1;
1839                    this.deliveryPagination.currentPage = this.result.DELIVERY;
1840                    this.deliveryPagination.show = false;
1841                }
1842            }
1843
1844            if (this.result.PAY_SYSTEM) {
1845                if (this.options.paySystemsPerPage > 0 && this.result.PAY_SYSTEM.length > this.options.paySystemsPerPage) {
1846                    arReserve = this.result.PAY_SYSTEM.slice();
1847                    pages = Math.ceil(arReserve.length / this.options.paySystemsPerPage);
1848                    arPages = [];
1849
1850                    for (i = 0; i < pages; i++) {
1851                        arPages.push(arReserve.splice(0, this.options.paySystemsPerPage));
1852                    }
1853                    this.paySystemPagination.pages = arPages;
1854
1855                    for (i = 0; i < this.result.PAY_SYSTEM.length; i++) {
1856                        if (this.result.PAY_SYSTEM[i].CHECKED == 'Y') {
1857                            this.paySystemPagination.pageNumber = Math.ceil(++i / this.options.paySystemsPerPage);
1858                            break;
1859                        }
1860                    }
1861
1862                    this.paySystemPagination.pageNumber = this.paySystemPagination.pageNumber || 1;
1863                    this.paySystemPagination.currentPage = arPages.slice(this.paySystemPagination.pageNumber - 1, this.paySystemPagination.pageNumber)[0];
1864                    this.paySystemPagination.show = true
1865                } else {
1866                    this.paySystemPagination.pageNumber = 1;
1867                    this.paySystemPagination.currentPage = this.result.PAY_SYSTEM;
1868                    this.paySystemPagination.show = false;
1869                }
1870            }
1871        },
1872
1873        initPickUpPagination: function () {
1874            var usePickUpPagination = false,
1875                usePickUp = false,
1876                stores, i = 0,
1877                arReserve, pages, arPages;
1878
1879            if (this.options.pickUpsPerPage >= 0 && this.result.DELIVERY) {
1880                for (i = 0; i < this.result.DELIVERY.length; i++) {
1881                    if (this.result.DELIVERY[i].CHECKED === 'Y' && this.result.DELIVERY[i].STORE_MAIN) {
1882                        usePickUp = this.result.DELIVERY[i].STORE_MAIN.length > 0;
1883                        usePickUpPagination = this.result.DELIVERY[i].STORE_MAIN.length > this.options.pickUpsPerPage;
1884                        if (usePickUp)
1885                            stores = this.getPickUpInfoArray(this.result.DELIVERY[i].STORE_MAIN);
1886                        break;
1887                    }
1888                }
1889            }
1890
1891            if (usePickUp) {
1892                if (this.options.pickUpsPerPage > 0 && usePickUpPagination) {
1893                    arReserve = stores.slice();
1894                    pages = Math.ceil(arReserve.length / this.options.pickUpsPerPage);
1895                    arPages = [];
1896
1897                    for (i = 0; i < pages; i++)
1898                        arPages.push(arReserve.splice(0, this.options.pickUpsPerPage));
1899
1900                    this.pickUpPagination.pages = arPages;
1901
1902                    for (i = 0; i < stores.length; i++) {
1903                        if (!this.result.BUYER_STORE || stores[i].ID == this.result.BUYER_STORE) {
1904                            this.pickUpPagination.pageNumber = Math.
1904ceil(++i / this.options.pickUpsPerPage);
1905                            break;
1906                        }
1907                    }
1908
1909                    if (!this.pickUpPagination.pageNumber)
1910                        this.pickUpPagination.pageNumber = 1;
1911
1912                    this.pickUpPagination.currentPage = arPages.slice(this.pickUpPagination.pageNumber - 1, this.pickUpPagination.pageNumber)[0];
1913                    this.pickUpPagination.show = true
1914                } else {
1915                    this.pickUpPagination.pageNumber = 1;
1916                    this.pickUpPagination.currentPage = stores;
1917                    this.pickUpPagination.show = false;
1918                }
1919            }
1920        },
1921
1922        prepareLocations: function (locations) {
1923            this.locations = {};
1924            this.cleanLocations = {};
1925
1926            var temporaryLocations,
1927                i, k, output;
1928
1929            if (BX.util.object_keys(locations).length) {
1930                for (i in locations) {
1931                    if (!locations.hasOwnProperty(i))
1932                        continue;
1933
1934                    this.locationsTemplate = locations[i].template || '';
1935                    temporaryLocations = [];
1936                    output = locations[i].output;
1937
1938                    if (output.clean) {
1939                        this.cleanLocations[i] = BX.processHTML(output.clean, false);
1940                        delete output.clean;
1941                    }
1942
1943                    for (k in output) {
1944                        if (output.hasOwnProperty(k)) {
1945                            temporaryLocations.push({
1946                                output: BX.processHTML(output[k], false),
1947                                showAlt: locations[i].showAlt,
1948                                lastValue: locations[i].lastValue,
1949                                coordinates: locations[i].coordinates || false
1950                            });
1951                        }
1952                    }
1953
1954                    this.locations[i] = temporaryLocations;
1955                }
1956            }
1957        },
1958
1959        locationsCompletion: function () {
1960            var i, locationNode, clearButton, inputStep, inputSearch,
1961                arProperty, data, section;
1962
1963            this.locationsInitialized = true;
1964            this.fixLocationsStyle(this.regionBlockNode, this.regionHiddenBlockNode);
1965            this.fixLocationsStyle(this.propsBlockNode, this.propsHiddenBlockNode);
1966
1967            for (i in this.locations) {
1968                if (!this.locations.hasOwnProperty(i))
1969                    continue;
1970
1971                locationNode = this.orderBlockNode.querySelector('div[data-property-id-row="' + i + '"]');
1972                if (!locationNode)
1973                    continue;
1974
1975                clearButton = locationNode.querySelector('div.bx-ui-sls-clear');
1976                inputStep = locationNode.querySelector('div.bx-ui-slst-pool');
1977                inputSearch = locationNode.querySelector('input.bx-ui-sls-fake[type=text]');
1978
1979                locationNode.removeAttribute('style');
1980                this.bindValidation(i, locationNode);
1981                if (clearButton) {
1982                    BX.bind(clearButton, 'click', function (e) {
1983                        var target = e.target || e.srcElement,
1984                            parent = BX.findParent(target, {tagName: 'DIV', className: 'tanais-form-group'}),
1985                            locationInput;
1986
1987                        if (parent)
1988                            locationInput = parent.querySelector('input.bx-ui-sls-fake[type=text]');
1989
1990                        if (locationInput)
1991                            BX.fireEvent(locationInput, 'keyup');
1992                    });
1993                }
1994
1995                if (!this.firstLoad && this.options.propertyValidation) {
1996                    if (inputStep) {
1997                        arProperty = this.validation.properties[i];
1998                        data = this.getValidationData(arProperty, locationNode);
1999                        section = BX.findParent(locationNode, {className: 'bx-soa-section'});
2000
2001                        if (section && section.getAttribute('data-visited') == 'true')
2002                            this.isValidProperty(data);
2003                    }
2004
2005                    if (inputSearch)
2006                        BX.fireEvent(inputSearch, 'keyup');
2007                }
2008            }
2009
2010            if (this.firstLoad && this.result.IS_AUTHORIZED && typeof this.result.LAST_ORDER_DATA.FAIL === 'undefined') {
2011                this.showActualBlock();
2012            } else if (!this.result.SHOW_AUTH) {
2013                this.changeVisibleContent();
2014            }
2015
2016            this.checkNotifications();
2017        },
2018
2019        fixLocationsStyle: function (section, hiddenSection) {
2020            if (!section || !hiddenSection)
2021                return;
2022
2023            var regionActive = this.activeSectionId == section.id ? section : hiddenSection,
2024                locationSearchInputs, locationStepInputs, i;
2025
2026            locationSearchInputs = regionActive.querySelectorAll('div.bx-sls div.dropdown-block.bx-ui-sls-input-block');
2027            locationStepInputs = regionActive.querySelectorAll('div.bx-slst div.dropdown-block.bx-ui-slst-input-block');
2028
2029            if (locationSearchInputs.length)
2030                for (i = 0; i < locationSearchInputs.length; i++)
2031                    BX.addClass(locationSearchInputs[i], 'tanais-form-control');
2032
2033            if (locationStepInputs.length)
2034                for (i = 0; i < locationStepInputs.length; i++)
2035                    BX.addClass(locationStepInputs[i], 'tanais-form-control');
2036        },
2037
2038        /**
2039         * Order saving action with validation. Doesn't send request while have errors
2040         */
2041        clickOrderSaveAction: function (event) {
2042            if (this.isValidForm()) {
2043                this.allowOrderSave();
2044
2045                if (this.params.USER_CONSENT === 'Y' && BX.UserConsent) {
2046                    BX.onCustomEvent('bx-soa-order-save', []);
2047                } else {
2048                    this.doSaveAction();
2049                }
2050            }
2051
2052            return BX.PreventDefault(event);
2053        },
2054
2055        doSaveAction: function () {
2056            if (this.isOrderSaveAllowed()) {
2057                this.reachGoal('order');
2058                this.sendRequest('saveOrderAjax');
2059            }
2060        },
2061
2062        /**
2063         * Hiding current block node and showing next available block node
2064         */
2065        clickNextAction: function (event) {
2066            var target = event.target || event.srcElement,
2067                actionSection = BX.findParent(target, {className: "bx-active"}),
2068                section = this.getNextSection(actionSection),
2069                allSections, titleNode, editStep;
2070
2071            this.reachGoal('next', actionSection);
2072
2073            if (
2074                (!this.result.IS_AUTHORIZED || typeof this.result.LAST_ORDER_DATA.FAIL !== 'undefined')
2075                && section.next.getAttribute('data-visited') == 'false'
2076            ) {
2077                titleNode = section.next.querySelector('.bx-soa-section-title-container');
2078                BX.bind(titleNode, 'click', BX.proxy(this.showByClick, this));
2079                editStep = section.next.querySelector('.bx-soa-editstep');
2080                if (editStep)
2081                    editStep.style.display = '';
2082
2083                allSections = this.orderBlockNode.querySelectorAll('.bx-soa-section.bx-active');
2084                if (section.next.id == allSections[allSections.length - 1].id)
2085                    this.switchOrderSaveButtons(true);
2086            }
2087
2088            this.fade(actionSection, section.next);
2089            this.show(section.next);
2090
2091            return BX.PreventDefault(event);
2092        },
2093
2094        /**
2095         * Hiding current block node and showing previous available block node
2096         */
2097        clickPrevAction: function (event) {
2098            var target = event.target || event.srcElement,
2099                actionSection = BX.findParent(target, {className: "bx-active"}),
2100                section = this.getPrevSection(actionSection);
2101
2102            this.fade(actionSection);
2103            this.show(section.next);
2104            this.animateScrollTo(section.next, 800);
2105            return BX.PreventDefault(event);
2106        },
2107
2108        /**
2109         * Showing authentication block node
2110         */
2111        showAuthBlock: function () {
2112            var showNode = this.authBlockNode,
2113                fadeNode = BX(this.activeSectionId);
2114
2115            if (!showNode || BX.hasClass(showNode, 'bx-selected'))
2116                return;
2117
2118            fadeNode && this.fade(fadeNode);
2119            this.show(showNode);
2120        },
2121
2122        /**
2123         * Hiding authentication block node
2124         */
2125        closeAuthBlock: function () {
2126            var actionSection = this.authBlockNode,
2127                nextSection = this.getNextSection(actionSection).next;
2128
2129            this.fade(actionSection);
2130            BX.cleanNode(BX(nextSection.id + '-hidden'));
2131            this.show(nextSection);
2132        },
2133
2134        /**
2135         * Checks possibility to skip section
2136         */
2137        shouldSkipSection: function (section) {
2138            var skip = false;
2139
2140            if (this.params.SKIP_USELESS_BLOCK === 'Y') {
2141                if (section.id === this.pickUpBlockNode.id) {
2142                    var delivery = this.getSelectedDelivery();
2143                    if (delivery) {
2144                        skip = this.getPickUpInfoArray(delivery.STORE).length === 1;
2145                    }
2146                }
2147
2148                if (section.id === this.deliveryBlockNode.id) {
2149                    skip = this.result.DELIVERY && this.result.DELIVERY.length === 1
2150                        && this.result.DELIVERY[0].EXTRA_SERVICES.length === 0
2151                        && !this.result.DELIVERY[0].CALCULATE_ERRORS;
2152                }
2153
2154                if (section.id === this.paySystemBlockNode.id) {
2155                    skip = this.result.PAY_SYSTEM && this.result.PAY_SYSTEM.length === 1 && this.result.PAY_FROM_ACCOUNT !== 'Y';
2156                }
2157            }
2158
2159            return skip;
2160        },
2161
2162        /**
2163         * Returns next available block node (node skipped while have one pay system, delivery or pick up)
2164         */
2165        getNextSection: function (actionSection, skippedSection) {
2166            if (!this.orderBlockNode || !actionSection)
2167                return {};
2168
2169            var allSections = this.orderBlockNode.querySelectorAll('.bx-soa-section.bx-active'),
2170                nextSection, i;
2171
2172            for (i = 0; i < allSections.length; i++) {
2173                if (allSections[i].id === actionSection.id && allSections[i + 1]) {
2174                    nextSection = allSections[i + 1];
2175
2176                    if (this.shouldSkipSection(nextSection)) {
2177                        this.markSectionAsCompleted(nextSection);
2178
2179                        return this.getNextSection(nextSection, nextSection);
2180                    }
2181
2182                    return {
2183                        prev: actionSection,
2184                        next: nextSection,
2185                        skip: skippedSection
2186                    };
2187                }
2188            }
2189
2190            return {next: actionSection};
2191        },
2192
2193        markSectionAsCompleted: function (section) {
2194            var titleNode;
2195
2196            if (
2197                (!this.result.IS_AUTHORIZED || typeof this.result.LAST_ORDER_DATA.FAIL !== 'undefined')
2198                && section.getAttribute('data-visited') === 'false'
2199            ) {
2200                this.changeVisibleSection(section, true);
2201            }
2202
2203            section.setAttribute('data-visited', 'true');
2204            BX.addClass(section, 'bx-step-completed');
2205            BX.remove(section.querySelector('.alert.alert-warning.alert-hide'));
2206            this.checkBlockErrors(section);
2207        },
2208
2209        /**
2210         * Returns previous available block node (node skipped while have one pay system, delivery or pick up)
2211         */
2212        getPrevSection: function (actionSection) {
2213            if (!this.orderBlockNode || !actionSection)
2214                return {};
2215
2216            var allSections = this.orderBlockNode.querySelectorAll('.bx-soa-section.bx-active'),
2217                prevSection, i;
2218
2219            for (i = 0; i < allSections.length; i++) {
2220                if (allSections[i].id === actionSection.id && allSections[i - 1]) {
2221                    prevSection = allSections[i - 1];
2222
2223                    if (this.shouldSkipSection(prevSection)) {
2224                        this.markSectionAsCompleted(prevSection);
2225
2226                        return this.getPrevSection(prevSection);
2227                    }
2228
2229                    return {
2230                        prev: actionSection,
2231                        next: prevSection
2232                    };
2233                }
2234            }
2235
2236            return {next: actionSection};
2237        },
2238
2239        addAnimationEffect: function (node, className, timeout) {
2240            if (!node || !className)
2241                return;
2242
2243            if (this.timeOut[node.id]) {
2244                clearTimeout(this.timeOut[node.id].timer);
2245                BX.removeClass(node, this.timeOut[node.id].className);
2246            }
2247
2248            setTimeout(function () {
2249                BX.addClass(node, className)
2250            }, 10);
2251            this.timeOut[node.id] = {
2252                className: className,
2253                timer: setTimeout(
2254                    BX.delegate(function () {
2255                        BX.removeClass(node, className);
2256                        delete this.timeOut[node.id];
2257                    }, this),
2258                    timeout || 5000)
2259            };
2260        },
2261
2262        /**
2263         * Replacing current active block node with generated fade block node
2264         */
2265        fade: function (node, nextSection) {
2266            if (!node || !node.id || this.activeSectionId != node.id)
2267                return;
2268
2269            this.hasErrorSection[node.id] = false;
2270
2271            var objHeightOrig = node.offsetHeight,
2272                objHeight;
2273
2274            switch (node.id) {
2275                case this.authBlockNode.id:
2276                    this.authBlockNode.style.display = 'none';
2277                    BX.removeClass(this.authBlockNode, 'bx-active');
2278                    break;
2279                case this.basketBlockNode.id:
2280                    this.editFadeBasketBlock();
2281                    break;
2282                case this.regionBlockNode.id:
2283                    this.editFadeRegionBlock();
2284                    break;
2285                case this.paySystemBlockNode.id:
2286                    BX.remove(this.paySystemBlockNode.querySelector('.alert.alert-warning.alert-hide'));
2287                    this.editFadePaySystemBlock();
2288                    break;
2289                case this.deliveryBlockNode.id:
2290                    BX.remove(this.deliveryBlockNode.querySelector('.alert.alert-warning.alert-hide'));
2291                    this.editFadeDeliveryBlock();
2292                    break;
2293                case this.pickUpBlockNode.id:
2294                    this.editFadePickUpBlock();
2295                    break;
2296                case this.propsBlockNode.id:
2297                    this.editFadePropsBlock();
2298                    break;
2299            }
2300
2301            BX.addClass(node, 'bx-step-completed');
2302            BX.removeClass(node, 'bx-selected');
2303
2304            objHeight = node.offsetHeight;
2305            node.style.height = objHeightOrig + 'px';
2306
2307            // calculations of scrolling animation
2308            if (nextSection) {
2309                var windowScrollTop = BX.GetWindowScrollPos().scrollTop,
2310                    orderPos = BX.pos(this.orderBlockNode),
2311                    nodePos = BX.pos(node),
2312                    diff, scrollTo, nextSectionHeightBefore, nextSectionHeightAfter, nextSectionHidden, offset;
2313
2314                nextSectionHidden = BX(nextSection.id + '-hidden');
2315                nextSectionHidden.style.left = '-10000';
2316                nextSectionHidden.style.position = 'absolute';
2317                this.orderBlockNode.appendChild(nextSectionHidden);
2318                nextSectionHeightBefore = nextSection.offsetHeight;
2319                nextSectionHeightAfter = nextSectionHidden.offsetHeight + 57;
2320                BX(node.id + '-hidden').parentNode.appendChild(nextSectionHidden);
2321                nextSectionHidden.removeAttribute('style');
2322
2323                diff = objHeight + nextSectionHeightAfter - objHeightOrig - nextSectionHeightBefore;
2324
2325                offset = window.innerHeight - orderPos.height - diff;
2326                if (offset > 0)
2327                    scrollTo = orderPos.top - offset / 2;
2328                else {
2329                    if (nodePos.top > windowScrollTop)
2330                        scrollTo = nodePos.top;
2331                    else
2332                        scrollTo = nodePos.bottom + 6 - objHeightOrig + objHeight;
2333
2334                    if (scrollTo + window.innerHeight > orderPos.bottom + 25 + diff)
2335                        scrollTo = orderPos.bottom + 25 + diff - window.innerHeight;
2336                }
2337
2338                scrollTo -= this.isMobile ? 50 : 0;
2339            }
2340
2341            new BX.easing({
2342                duration: nextSection ? 800 : 600,
2343                start: {height: objHeightOrig, scrollTop: windowScrollTop},
2344                finish: {height: objHeight, scrollTop: scrollTo},
2345                transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
2346                step: function (state) {
2347                    node.style.height = state.height + "px";
2348                    if (nextSection)
2349                        window.scrollTo(0, state.scrollTop);
2350                },
2351                complete: function () {
2352                    node.style.height = '';
2353                }
2354            }).animate();
2355
2356            this.checkBlockErrors(node);
2357        },
2358
2359        /**
2360         * Showing active data in certain block node
2361         */
2362        show: function (node) {
2363            if (!node || !node.id || this.activeSectionId == node.id)
2364                return;
2365
2366            this.activeSectionId = node.id;
2367            BX.removeClass(node, 'bx-step-error bx-step-warning');
2368
2369            switch (node.id) {
2370                case this.authBlockNode.id:
2371                    this.authBlockNode.style.display = '';
2372                    BX.addClass(this.authBlockNode, 'bx-active');
2373                    break;
2374                case this.regionBlockNode.id:
2375                    this.editActiveRegionBlock(true);
2376                    break;
2377                case this.deliveryBlockNode.id:
2378                    this.editActiveDeliveryBlock(true);
2379                    break;
2380                case this.paySystemBlockNode.id:
2381                    this.editActivePaySystemBlock(true);
2382                    break;
2383                case this.pickUpBlockNode.id:
2384                    this.editActivePickUpBlock(true);
2385                    break;
2386                case this.propsBlockNode.id:
2387                    this.editActivePropsBlock(true);
2388                    break;
2389            }
2390
2391            if (this.basketBlockNode && node.id == this.basketBlockNode.id) {
2392                this.editActiveBasketBlock(true);
2393                this.alignBasketColumns();
2394            }
2395
2396            if (node.getAttribute('data-visited') === 'false') {
2397                this.showBlockErrors(node);
2398                this.notifyAboutWarnings(node);
2399            }
2400
2401            node.setAttribute('data-visited', 'true');
2402            BX.addClass(node, 'bx-selected');
2403            BX.removeClass(node, 'bx-step-completed');
2404        },
2405
2406        showByClick: function (event) {
2407            var target = event.target || event.srcElement,
2408                showNode = BX.findParent(target, {className: "bx-active"}),
2409                // fadeNode = BX(this.activeSectionId),
2410                scrollTop = BX.GetWindowScrollPos().scrollTop;
2411
2412            if (!showNode || BX.hasClass(showNode, 'bx-selected'))
2413                return BX.PreventDefault(event);
2414
2415            this.reachGoal('edit', showNode);
2416
2417            // fadeNode && this.fade(fadeNode);
2418            this.show(showNode);
2419
2420            setTimeout(BX.delegate(function () {
2421                if (BX.pos(showNode).top < scrollTop)
2422                    this.animateScrollTo(showNode, 300);
2423            }, this), 320);
2424
2425            return BX.PreventDefault(event);
2426        },
2427
2428        /**
2429         * Checks each active block from top to bottom for errors (showing first block with errors or last block)
2430         */
2431        showActualBlock: function () {
2432            var allSections = this.orderBlockNode.querySelectorAll('.bx-soa-section.bx-active'),
2433                i = 0;
2434
2435            while (allSections[i]) {
2436                if (allSections[i].id === this.regionBlockNode.id)
2437                    this.isValidRegionBlock();
2438
2439                if (allSections[i].id === this.propsBlockNode.id)
2440                    this.isValidPropertiesBlock();
2441
2442                if (!this.checkBlockErrors(allSections[i]) || !this.checkPreload(allSections[i])) {
2443                    if (this.activeSectionId !== allSections[i].id) {
2444                        BX(this.activeSectionId) && this.fade(BX(this.activeSectionId));
2445                        this.show(allSections[i]);
2446                    }
2447
2448                    break;
2449                }
2450
2451                BX.addClass(allSections[i], 'bx-step-completed');
2452                allSections[i].setAttribute('data-visited', 'true');
2453                i++;
2454            }
2455        },
2456
2457        /**
2458         * Returns footer node with navigation buttons
2459         */
2460        getBlockFooter: function (node) {
2461            var sections = this.orderBlockNode.querySelectorAll('.bx-soa-section.bx-active'),
2462                firstSection = sections[0],
2463                lastSection = sections[sections.length - 1],
2464                currentSection = BX.findParent(node, {className: "bx-soa-section"}),
2465                isLastNode = false,
2466                buttons = [];
2467
2468            if (currentSection && currentSection.id.indexOf(firstSection.id) == '-1') {
2469                buttons.push(
2470                    BX.create('A', {
2471                        props: {
2472                            href: 'javascript:void(0)',
2473                            className: 'pull-left btn btn-default btn-md'
2474                        },
2475                        html: this.params.MESS_BACK,
2476                        events: {
2477                            click: BX.proxy(this.clickPrevAction, this)
2478                        }
2479                    })
2480                );
2481            }
2482
2483            if (currentSection && currentSection.id.indexOf(lastSection.id) != '-1')
2484                isLastNode = true;
2485
2486            if (!isLastNode) {
2487                buttons.push(
2488                    BX.create('A', {
2489                        props: {href: 'javascript:void(0)', className: 'pull-right btn btn-default btn-md'},
2490                        html: this.params.MESS_FURTHER,
2491                        events: {click: BX.proxy(this.clickNextAction, this)}
2492                    })
2493                );
2494            }
2495
2496            /*node.appendChild(
2497				BX.create('DIV', {
2498					props: {className: 'row bx-soa-more'},
2499					children: [
2500						BX.create('DIV', {
2501							props: {className: 'bx-soa-more-btn'},
2502							children: buttons
2503						})
2504					]
2505				})
2506			);*/
2507        },
2508
2509        getNewContainer: function (notFluid) {
2510            return BX.create('DIV', {props: {className: 'bx-soa-section-content' + (!!notFluid ? '' : ' container-fluid')}});
2511        },
2512
2513        /**
2514         * Showing/hiding order save buttons
2515         */
2516        switchOrderSaveButtons: function (state) {
2517            var orderSaveNode = this.orderSaveBlockNode,
2518                totalButton = this.totalBlockNode.querySelector('.bx-soa-cart-total-button-container'),
2519                mobileButton = this.mobileTotalBlockNode.querySelector('.bx-soa-cart-total-button-container'),
2520                lastState = this.orderSaveBlockNode.style.display == '';
2521
2522            if (lastState != state) {
2523                if (state) {
2524                    orderSaveNode.style.opacity = 0;
2525                    orderSaveNode.style.display = '';
2526                    if (totalButton) {
2527                        totalButton.style.opacity = 0;
2528                        totalButton.style.display = '';
2529                    }
2530                    if (mobileButton) {
2531                        mobileButton.style.opacity = 0;
2532                        mobileButton.style.display = '';
2533                    }
2534
2535                    new BX.easing({
2536                        duration: 500,
2537                        start: {opacity: 0},
2538                        finish: {opacity: 100},
2539                        transition: BX.easing.transitions.linear,
2540                        step: function (state) {
2541                            orderSaveNode.style.opacity = state.opacity / 100;
2542                            if (totalButton)
2543                                totalButton.style.opacity = state.opacity / 100;
2544                            if (mobileButton)
2545                                mobileButton.style.opacity = state.opacity / 100;
2546                        },
2547                        complete: function () {
2548                            orderSaveNode.removeAttribute('style');
2549                            totalButton && totalButton.removeAttribute('style');
2550                            mobileButton && mobileButton.removeAttribute('style');
2551                        }
2552                    }).animate();
2553                } else {
2554                    orderSaveNode.style.display = 'none';
2555                    if (totalButton)
2556                        totalButton.setAttribute('style', 'display: none !important');
2557                    if (mobileButton)
2558                        mobileButton.setAttribute('style', 'display: none !important');
2559                }
2560            }
2561        },
2562
2563        /**
2564         * Returns true if current section or next sections had already visited
2565         */
2566        shouldBeSectionVisible: function (sections, currentPosition) {
2567            var state = false, editStepNode;
2568
2569            if (!sections || !sections.length)
2570                return state;
2571
2572            for (; currentPosition < sections.length; currentPosition++) {
2573                if (sections[currentPosition].getAttribute('data-visited') == 'true') {
2574                    state = true;
2575                    break;
2576                }
2577
2578                if (!this.firstLoad) {
2579                    editStepNode = sections[currentPosition].querySelector('.bx-soa-editstep');
2580                    if (editStepNode && editStepNode.style.display !== 'none') {
2581                        state = true;
2582                        break;
2583                    }
2584                }
2585            }
2586
2587            return state;
2588        },
2589
2590        /**
2591         * Showing/hiding blocks content if user authorized/unauthorized
2592         */
2593        changeVisibleContent: function () {
2594            var sections = this.orderBlockNode.querySelectorAll('.bx-soa-section.bx-active'),
2595                i, state;
2596
2597            var orderDataLoaded = !!this.result.IS_AUTHORIZED && this.params.USE_PRELOAD === 'Y' && this.result.LAST_ORDER_DATA.FAIL !== true,
2598                skipFlag = true;
2599
2600            for (i = 0; i < sections.length; i++) {
2601                state = this.firstLoad && orderDataLoaded;
2602                state = state || this.shouldBeSectionVisible(sections, i);
2603
2604                this.changeVisibleSection(sections[i], state);
2605
2606                if (this.firstLoad && skipFlag) {
2607                    if (
2608                        state
2609                        && sections[i + 1]
2610                        && this.checkBlockErrors(sections[i])
2611                        && (
2612                            (orderDataLoaded && this.checkPreload(sections[i]))
2613                            || (!orderDataLoaded && this.shouldSkipSection(sections[i]))
2614                        )
2615                    ) {
2616                        this.fade(sections[i]);
2617                        this.markSectionAsCompleted(sections[i]);
2618                        this.show(sections[i + 1]);
2619                    } else {
2620                        skipFlag = false;
2621                    }
2622                }
2623            }
2624        },
2625
2626        changeVisibleSection: function (section, state) {
2627            var titleNode, content, editStep;
2628
2629            if (this.basketBlockNode && section.id !== this.basketBlockNode.id) {
2630                content = section.querySelector('.bx-soa-section-content');
2631                if (content)
2632                    content.style.display = state ? '' : 'none';
2633            }
2634        },
2635
2636        /**
2637         * Edit order block nodes with this.result/this.params data
2638         */
2639        editOrder: function () {
2640            if (!this.orderBlockNode || !this.result)
2641                return;
2642
2643            if (this.result.DELIVERY.length > 0) {
2644                BX.addClass(this.deliveryBlockNode, 'bx-active');
2645                this.deliveryBlockNode.removeAttribute('style');
2646            } else {
2647                BX.removeClass(this.deliveryBlockNode, 'bx-active');
2648                this.deliveryBlockNode.style.display = 'none';
2649            }
2650
2651            this.orderSaveBlockNode.style.display = this.result.SHOW_AUTH ? 'none' : '';
2652            this.mobileTotalBlockNode.style.display = this.result.SHOW_AUTH ? 
2652'none' : '';
2653
2654            this.checkPickUpShow();
2655
2656            var sections = this.orderBlockNode.querySelectorAll('.bx-soa-section.bx-active'), i;
2657            for (i in sections) {
2658                if (sections.hasOwnProperty(i)) {
2659                    this.editSection(sections[i]);
2660                }
2661            }
2662
2663            this.editTotalBlock();
2664            this.totalBlockFixFont();
2665
2666            this.showErrors(this.result.ERROR, false);
2667            this.showWarnings();
2668        },
2669
2670        /**
2671         * Edit certain block node
2672         */
2673        editSection: function (section) {
2674            if (!section || !section.id)
2675                return;
2676
2677            if (this.result.SHOW_AUTH && section.id != this.authBlockNode.id && (this.basketBlockNode && section.id != this.basketBlockNode.id))
2678                section.style.display = 'none';
2679            else if (section.id != this.pickUpBlockNode.id)
2680                section.style.display = '';
2681
2682            var active = true,
2683                titleNode = section.querySelector('.bx-soa-section-title-container'),
2684                editButton, errorContainer;
2685
2686            errorContainer = section.querySelector('.alert.alert-danger');
2687            this.hasErrorSection[section.id] = errorContainer && errorContainer.style.display != 'none';
2688
2689            switch (section.id) {
2690                case this.authBlockNode.id:
2691                    this.editAuthBlock();
2692                    break;
2693                case this.regionBlockNode.id:
2694                    this.editRegionBlock(active);
2695                    break;
2696                case this.paySystemBlockNode.id:
2697                    this.editPaySystemBlock(active);
2698                    break;
2699                case this.deliveryBlockNode.id:
2700                    this.editDeliveryBlock(active);
2701                    break;
2702                case this.pickUpBlockNode.id:
2703                    this.editPickUpBlock(active);
2704                    break;
2705                case this.propsBlockNode.id:
2706                    this.editPropsBlock(active);
2707                    break;
2708            }
2709
2710            if (this.basketBlockNode && section.id == this.basketBlockNode.id) {
2711                this.editBasketBlock(active);
2712            }
2713
2714            if (active)
2715                section.setAttribute('data-visited', 'true');
2716        },
2717
2718        editAuthBlock: function () {
2719            if (!this.authBlockNode)
2720                return;
2721
2722            var authContent = this.authBlockNode.querySelector('.bx-soa-section-content'),
2723                regContent, okMessageNode;
2724
2725            if (BX.hasClass(authContent, 'reg')) {
2726                regContent = authContent;
2727                authContent = BX.firstChild(this.authHiddenBlockNode);
2728            } else
2729                regContent = BX.firstChild(this.authHiddenBlockNode);
2730
2731            BX.cleanNode(authContent);
2732            BX.cleanNode(regContent);
2733
2734            if (this.result.SHOW_AUTH) {
2735                this.getErrorContainer(authContent);
2736                this.editAuthorizeForm(authContent);
2737                this.editSocialContent(authContent);
2738                this.getAuthReference(authContent);
2739
2740                this.getErrorContainer(regContent);
2741                this.editRegistrationForm(regContent);
2742                this.getAuthReference(regContent);
2743            } else {
2744                BX.onCustomEvent('OnBasketChange');
2745                this.closeAuthBlock();
2746            }
2747
2748            if (this.result.OK_MESSAGE && this.result.OK_MESSAGE.length) {
2749                this.toggleAuthForm({target: this.authBlockNode.querySelector('input[type=submit]')});
2750                okMessageNode = BX.create('DIV', {
2751                    props: {className: 'alert alert-success'},
2752                    text: this.result.OK_MESSAGE.join()
2753                });
2754                this.result.OK_MESSAGE = '';
2755                BX.prepend(okMessageNode, this.authBlockNode.querySelector('.bx-soa-section-content'));
2756            }
2757        },
2758
2759        editAuthorizeForm: function (authContent) {
2760            var login, password, remember, button, authFormNode;
2761
2762            login = this.createAuthFormInputContainer(
2763                BX.message('STOF_LOGIN'),
2764                BX.create('INPUT', {
2765                    attrs: {'data-next': 'USER_PASSWORD'},
2766                    props: {
2767                        name: 'USER_LOGIN',
2768                        type: 'text',
2769                        value: this.result.AUTH.USER_LOGIN,
2770                        maxlength: "30"
2771                    },
2772                    events: {keypress: BX.proxy(this.checkKeyPress, this)}
2773                })
2774            );
2775            password = this.createAuthFormInputContainer(
2776                BX.message('STOF_PASSWORD'),
2777                BX.create('INPUT', {
2778                    attrs: {'data-send': true},
2779                    props: {
2780                        name: 'USER_PASSWORD',
2781                        type: 'password',
2782                        value: '',
2783                        maxlength: "30"
2784                    },
2785                    events: {keypress: BX.proxy(this.checkKeyPress, this)}
2786                })
2787            );
2788            remember = BX.create('DIV', {
2789                props: {className: 'bx-authform-formgroup-container'},
2790                children: [
2791                    BX.create('DIV', {
2792                        props: {className: 'checkbox'},
2793                        children: [
2794                            BX.create('LABEL', {
2795                                props: {className: 'bx-filter-param-label'},
2796                                children: [
2797                                    BX.create('INPUT', {
2798                                        props: {
2799                                            type: 'checkbox',
2800                                            name: 'USER_REMEMBER',
2801                                            value: 'Y'
2802                                        }
2803                                    }),
2804                                    BX.create('SPAN', {
2805                                        props: {className: 'bx-filter-param-text'},
2806                                        text: BX.message('STOF_REMEMBER')
2807                                    })
2808                                ]
2809                            })
2810                        ]
2811                    })
2812                ]
2813            });
2814            button = BX.create('DIV', {
2815                props: {className: 'bx-authform-formgroup-container'},
2816                children: [
2817                    BX.create('INPUT', {
2818                        props: {
2819                            id: 'do_authorize',
2820                            type: 'hidden',
2821                            name: 'do_authorize',
2822                            value: 'N'
2823                        }
2824                    }),
2825                    BX.create('INPUT', {
2826                        props: {
2827                            type: 'submit',
2828                            className: 'btn btn-default',
2829                            value: BX.message('STOF_ENTER')
2830                        },
2831                        events: {
2832                            click: BX.delegate(function (e) {
2833                                BX('do_authorize').value = 'Y';
2834                                this.sendRequest('showAuthForm');
2835                                return BX.PreventDefault(e);
2836                            }, this)
2837                        }
2838                    })
2839                ]
2840            });
2841            authFormNode = BX.create('DIV', {
2842                props: {className: 'bx-authform'},
2843                children: [
2844                    BX.create('H3', {props: {className: 'bx-title'}, text: BX.message('STOF_AUTH_REQUEST')}),
2845                    login,
2846                    password,
2847                    remember,
2848                    button,
2849                    BX.create('A', {
2850                        props: {
2851                            href: this.params.PATH_TO_AUTH + '?forgot_password=yes&back_url=' + encodeURIComponent(document.location.href)
2852                        },
2853                        text: BX.message('STOF_FORGET_PASSWORD')
2854                    })
2855                ]
2856            });
2857
2858            authContent.appendChild(BX.create('DIV', {children: [authFormNode]}));
2859        },
2860
2861        createAuthFormInputContainer: function (labelText, inputNode, required) {
2862            var labelHtml = '';
2863
2864            if (required)
2865                labelHtml += '<span class="bx-authform-starrequired">*</span>';
2866
2867            labelHtml += labelText;
2868
2869            return BX.create('DIV', {
2870                props: {className: 'bx-authform-formgroup-container'},
2871                children: [
2872                    BX.create('DIV', {props: {className: 'bx-authform-label-container'}, html: labelHtml}),
2873                    BX.create('DIV', {props: {className: 'bx-authform-input-container'}, children: [inputNode]})
2874                ]
2875            });
2876        },
2877
2878        activatePhoneAuth: function () {
2879            if (!this.result.SMS_AUTH)
2880                return;
2881
2882            new BX.PhoneAuth({
2883                containerId: 'bx_register_resend',
2884                errorContainerId: 'bx_register_error',
2885                interval: 60,
2886                data: {
2887                    signedData: this.result.SMS_AUTH.SIGNED_DATA
2888                },
2889                onError: function (response) {
2890                    var errorDiv = BX('bx_register_error');
2891                    var errorNode = BX.findChildByClassName(errorDiv, 'errortext');
2892                    errorNode.innerHTML = '';
2893
2894                    for (var i = 0; i < response.errors.length; i++) {
2895                        errorNode.innerHTML = errorNode.innerHTML + BX.util.htmlspecialchars(response.errors[i].message) + '<br>';
2896                    }
2897
2898                    errorDiv.style.display = '';
2899                }
2900            });
2901        },
2902
2903        editRegistrationForm: function (authContent) {
2904            if (!this.result.AUTH)
2905                return;
2906
2907            var authFormNodes = [];
2908            var showSmsConfirm = this.result.SMS_AUTH && this.result.SMS_AUTH.TYPE === 'OK';
2909
2910            if (showSmsConfirm) {
2911                authFormNodes.push(BX.create('DIV', {
2912                    props: {className: 'alert alert-success'},
2913                    text: BX.message('STOF_REG_SMS_REQUEST')
2914                }));
2915                authFormNodes.push(BX.create('INPUT', {
2916                    props: {
2917                        type: 'hidden',
2918                        name: 'SIGNED_DATA',
2919                        value: this.result.SMS_AUTH.SIGNED_DATA || ''
2920                    }
2921                }));
2922                authFormNodes.push(this.createAuthFormInputContainer(
2923                    BX.message('STOF_SMS_CODE'),
2924                    BX.create('INPUT', {
2925                        attrs: {'data-send': true},
2926                        props: {
2927                            name: 'SMS_CODE',
2928                            type: 'text',
2929                            size: 40,
2930                            value: ''
2931                        },
2932                        events: {keypress: BX.proxy(this.checkKeyPress, this)}
2933                    }),
2934                    true
2935                ));
2936                authFormNodes.push(BX.create('DIV', {
2937                    props: {className: 'bx-authform-formgroup-container'},
2938                    children: [
2939                        BX.create('INPUT', {
2940                            props: {
2941                                name: 'code_submit_button',
2942                                type: 'submit',
2943                                className: 'btn btn-default',
2944                                value: BX.message('STOF_SEND')
2945                            },
2946                            events: {
2947                                click: BX.delegate(function (e) {
2948                                    this.sendRequest('confirmSmsCode');
2949                                    return BX.PreventDefault(e);
2950                                }, this)
2951                            }
2952                        })
2953                    ]
2954                }));
2955                authFormNodes.push(BX.create('DIV', {
2956                    props: {className: 'bx-authform-formgroup-container'},
2957                    children: [
2958                        BX.create('DIV', {
2959                            props: {id: 'bx_register_error'},
2960                            style: {display: 'none'}
2961                        }),
2962                        BX.create('DIV', {
2963                            props: {id: 'bx_register_resend'}
2964                        })
2965                    ]
2966                }));
2967            } else {
2968                authFormNodes.push(BX.create('H3', {
2969                    props: {className: 'bx-title'},
2970                    text: BX.message('STOF_REG_REQUEST')
2971                }));
2972                authFormNodes.push(this.createAuthFormInputContainer(
2973                    BX.message('STOF_NAME'),
2974                    BX.create('INPUT', {
2975                        attrs: {'data-next': 'NEW_LAST_NAME'},
2976                        props: {
2977                            name: 'NEW_NAME',
2978                            type: 'text',
2979                            size: 40,
2980                            value: this.result.AUTH.NEW_NAME || ''
2981                        },
2982                        events: {keypress: BX.proxy(this.checkKeyPress, this)}
2983                    }),
2984                    true
2985                ));
2986                authFormNodes.push(this.createAuthFormInputContainer(
2987                    BX.message('STOF_LASTNAME'),
2988                    BX.create('INPUT', {
2989                        attrs: {'data-next': 'NEW_EMAIL'},
2990                        props: {
2991                            name: 'NEW_LAST_NAME',
2992                            type: 'text',
2993                            size: 40,
2994                            value: this.result.AUTH.NEW_LAST_NAME || ''
2995                        },
2996                        events: {keypress: BX.proxy(this.checkKeyPress, this)}
2997                    }),
2998                    true
2999                ));
3000                authFormNodes.push(this.createAuthFormInputContainer(
3001                    BX.message('STOF_EMAIL'),
3002                    BX.create('INPUT', {
3003                        attrs: {'data-next': 'PHONE_NUMBER'},
3004                        props: {
3005                            name: 'NEW_EMAIL',
3006                            type: 'text',
3007                            size: 40,
3008                            value: this.result.AUTH.NEW_EMAIL || ''
3009                        },
3010                        events: {keypress: BX.proxy(this.checkKeyPress, this)}
3011                    }),
3012                    this.result.AUTH.new_user_email_required == 'Y'
3013                ));
3014
3015                if (this.result.AUTH.new_user_phone_auth === 'Y') {
3016                    authFormNodes.push(this.createAuthFormInputContainer(
3017                        BX.message('STOF_PHONE'),
3018                        BX.create('INPUT', {
3019                            attrs: {'data-next': 'captcha_word'},
3020                            props: {
3021                                name: 'PHONE_NUMBER',
3022                                type: 'text',
3023                                size: 40,
3024                                value: this.result.AUTH.PHONE_NUMBER || ''
3025                            },
3026                            events: {keypress: BX.proxy(this.checkKeyPress, this)}
3027                        }),
3028                        this.result.AUTH.new_user_phone_required === 'Y'
3029                    ));
3030                }
3031
3032                if (this.authGenerateUser) {
3033                    authFormNodes.push(
3034                        BX.create('LABEL', {
3035                            props: {for: 'NEW_GENERATE_N'},
3036                            children: [
3037                                BX.create('INPUT', {
3038                                    attrs: {checked: !this.authGenerateUser},
3039                                    props: {
3040                                        id: 'NEW_GENERATE_N',
3041                                        type: 'radio',
3042                                        name: 'NEW_GENERATE',
3043                                        value: 'N'
3044                                    }
3045                                }),
3046                                BX.message('STOF_MY_PASSWORD')
3047                            ],
3048                            events: {
3049                                change: BX.delegate(function () {
3050                                    var generated = this.authBlockNode.querySelector('.generated');
3051                                    generated.style.display = '';
3052                                    this.authGenerateUser = false;
3053                                }, this)
3054                            }
3055                        })
3056                    );
3057                    authFormNodes.push(BX.create('BR'));
3058                    authFormNodes.push(
3059                        BX.create('LABEL', {
3060                            props: {for: 'NEW_GENERATE_Y'},
3061                            children: [
3062                                BX.create('INPUT', {
3063                                    attrs: {checked: this.authGenerateUser},
3064                                    props: {
3065                                        id: 'NEW_GENERATE_Y',
3066                                        type: 'radio',
3067                                        name: 'NEW_GENERATE',
3068                                        value: 'Y'
3069                                    }
3070                                }),
3071                                BX.message('STOF_SYS_PASSWORD')
3072                            ],
3073                            events: {
3074                                change: BX.delegate(function () {
3075                                    var generated = this.authBlockNode.querySelector('.generated');
3076                                    generated.style.display = 'none';
3077                                    this.authGenerateUser = true;
3078                                }, this)
3079                            }
3080                        })
3081                    );
3082                }
3083
3084                authFormNodes.push(
3085                    BX.create('DIV', {
3086                        props: {className: 'generated'},
3087                        style: {display: this.authGenerateUser ? 'none' : ''},
3088                        children: [
3089                            this.createAuthFormInputContainer(
3090                                BX.message('STOF_LOGIN'),
3091                                BX.create('INPUT', {
3092                                    props: {
3093                                        name: 'NEW_LOGIN',
3094                                        type: 'text',
3095                                        size: 30,
3096                                        value: this.result.AUTH.NEW_LOGIN || ''
3097                                    },
3098                                    events: {
3099                                        keypress: BX.proxy(this.checkKeyPress, this)
3100                                    }
3101                                }),
3102                                true
3103                            ),
3104                            this.createAuthFormInputContainer(
3105                                BX.message('STOF_PASSWORD'),
3106                                BX.create('INPUT', {
3107                                    props: {
3108                                        name: 'NEW_PASSWORD',
3109                                        type: 'password',
3110                                        size: 30
3111                                    },
3112                                    events: {
3113                                        keypress: BX.proxy(this.checkKeyPress, this)
3114                                    }
3115                                }),
3116                                true
3117                            ),
3118                            this.createAuthFormInputContainer(
3119                                BX.message('STOF_RE_PASSWORD'),
3120                                BX.create('INPUT', {
3121                                    props: {
3122                                        name: 'NEW_PASSWORD_CONFIRM',
3123                                        type: 'password',
3124                                        size: 30
3125                                    },
3126                                    events: {
3127                                        keypress: BX.proxy(this.checkKeyPress, this)
3128                                    }
3129                                }),
3130                                true
3131                            )
3132                        ]
3133                    })
3134                );
3135
3136                if (this.result.AUTH.captcha_registration == 'Y') {
3137                    authFormNodes.push(BX.create('DIV', {
3138                        props: {className: 'bx-authform-formgroup-container'},
3139                        children: [
3140                            BX.create('DIV', {
3141                                props: {className: 'bx-authform-label-container'},
3142                                children: [
3143                                    BX.create('SPAN', {props: {className: 'bx-authform-starrequired'}, text: '*'}),
3144                                    BX.message('CAPTCHA_REGF_PROMT'),
3145                                    BX.create('DIV', {
3146                                        props: {className: 'bx-captcha'},
3147                                        children: [
3148                                            BX.create('INPUT', {
3149                                                props: {
3150                                                    name: 'captcha_sid',
3151                                                    type: 'hidden',
3152                                                    value: this.result.AUTH.capCode || ''
3153                                                }
3154                                            }),
3155                                            BX.create('IMG', {
3156                                                props: {
3157                                                    src: '/bitrix/tools/captcha.php?captcha_sid=' + this.result.AUTH.capCode,
3158                                                    alt: ''
3159                                                }
3160                                            })
3161                                        ]
3162                                    })
3163                                ]
3164                            }),
3165                            BX.create('DIV', {
3166                                props: {className: 'bx-authform-input-container'},
3167                                children: [
3168                                    BX.create('INPUT', {
3169                                        attrs: {'data-send': true},
3170                                        props: {
3171                                            name: 'captcha_word',
3172                                            type: 'text',
3173                                            size: '30',
3174                                            maxlength: '50',
3175                                            value: ''
3176                                        },
3177                                        events: {keypress: BX.proxy(this.checkKeyPress, this)}
3178                                    })
3179                                ]
3180                            })
3181                        ]
3182                    }));
3183                }
3184                authFormNodes.push(
3185                    BX.create('DIV', {
3186                        props: {className: 'bx-authform-formgroup-container'},
3187                        children: [
3188                            BX.create('INPUT', {
3189                                props: {
3190                                    id: 'do_register',
3191                                    name: 'do_register',
3192                                    type: 'hidden',
3193                                    value: 'N'
3194                                }
3195                            }),
3196                            BX.create('INPUT', {
3197                                props: {
3198                                    type: 'submit',
3199                                    className: 'btn btn-default',
3200                                    value: BX.message('STOF_REGISTER')
3201                                },
3202                                events: {
3203                                    click: BX.delegate(function (e) {
3204                                        BX('do_register').value = 'Y';
3205                                        this.sendRequest('showAuthForm');
3206                                        return BX.PreventDefault(e);
3207                                    }, this)
3208                                }
3209                            }),
3210                            BX.create('A', {
3211                                props: {className: 'btn btn-link', href: ''},
3212                                text: BX.message('STOF_DO_AUTHORIZE'),
3213                                events: {
3214                                    click: BX.delegate(function (e) {
3215                                        this.toggleAuthForm(e);
3216                                        return BX.PreventDefault(e);
3217                                    }, this)
3218                                }
3219                            })
3220                        ]
3221                    })
3222                );
3223            }
3224
3225            authContent.appendChild(
3226                BX.create('DIV', {
3227                    children: [BX.create('DIV', {props: {className: 'bx-authform'}, children: authFormNodes})]
3228                })
3229            );
3230
3231            if (showSmsConfirm) {
3232                this.activatePhoneAuth();
3233            }
3234        },
3235
3236        editSocialContent: function (authContent) {
3237            if (!BX('bx-soa-soc-auth-services'))
3238                return;
3239
3240            var nodes = [];
3241
3242            if (this.socServiceHiddenNode === false) {
3243                var socServiceHiddenNode = BX('bx-soa-soc-auth-services').querySelector('.bx-authform-social');
3244
3245                if (BX.type.isDomNode(socServiceHiddenNode)) {
3246                    this.socServiceHiddenNode = socServiceHiddenNode.innerHTML;
3247                    BX.remove(socServiceHiddenNode);
3248                }
3249            }
3250
3251            if (this.socServiceHiddenNode) {
3252                nodes.push(BX.create('DIV', {
3253                    props: {className: 'bx-authform-social'},
3254                    html: '<h3 class="bx-title">' + BX.message('SOA_DO_SOC_SERV') + '</h3>' + this.socServiceHiddenNode
3255                }));
3256                nodes.push(BX.create('hr', {props: {className: 'bxe-light'}}));
3257            }
3258
3259            if (this.result.AUTH.new_user_registration === 'Y') {
3260                nodes.push(BX.create('DIV', {
3261                    props: {className: 'bx-soa-reg-block'},
3262                    children: [
3263                        BX.create('P', {html: this.params.MESS_REGISTRATION_REFERENCE}),
3264                        BX.create('A', {
3265                            props: {className: 'btn btn-default'},
3266                            text: BX.message('STOF_DO_REGISTER'),
3267                            events: {
3268                                click: BX.delegate(function (e) {
3269                                    this.toggleAuthForm(e);
3270                                    return BX.PreventDefault(e);
3271                                }, this)
3272                            }
3273                        })
3274                    ]
3275                }));
3276            }
3277
3278            authContent.appendChild(BX.create('DIV', {children: nodes}));
3279        },
3280
3281        getAuthReference: function (authContent) {
3282            authContent.appendChild(
3283                BX.create('DIV', {
3284                    children: [
3285                        BX.create('DIV', {
3286                            props: {className: 'bx-soa-reference'},
3287                            children: [
3288                                this.params.MESS_AUTH_REFERENCE_1,
3289                                BX.create('BR'),
3290                                this.params.MESS_AUTH_REFERENCE_2,
3291                                BX.create('BR'),
3292                                this.params.MESS_AUTH_REFERENCE_3
3293                            ]
3294                        })
3295                    ]
3296                })
3297            );
3298        },
3299
3300        toggleAuthForm: function (event) {
3301            if (!event)
3302                return;
3303
3304            var target = event.target || event.srcElement,
3305                section = BX.findParent(target, {className: 'bx-soa-section'}),
3306                container = BX.findParent(target, {className: 'bx-soa-section-content'}),
3307                insertContainer = BX.firstChild(this.authHiddenBlockNode);
3308
3309            new BX.easing({
3310                duration: 100,
3311                start: {opacity: 100},
3312                finish: {opacity: 0},
3313                transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
3314                step: function (state) {
3315                    container.style.opacity = state.opacity / 100;
3316                }
3317            }).animate();
3318
3319            this.authHiddenBlockNode.appendChild(container);
3320            BX.cleanNode(section);
3321            section.appendChild(
3322                BX.create('DIV', {
3323                    props: {className: 'bx-soa-section-title-container'},
3324                    children: [
3325                        BX.create('h2', {
3326                            props: {className: 'bx-soa-section-title'},
3327                            html: BX.hasClass(insertContainer, 'reg') ? this.params.MESS_REG_BLOCK_NAME : this.params.MESS_AUTH_BLOCK_NAME
3328                        })
3329                    ]
3330                })
3331            );
3332            insertContainer.style.opacity = 0;
3333            section.appendChild(insertContainer);
3334
3335            setTimeout(function () {
3336                new BX.easing({
3337                    duration: 100,
3338                    start: {opacity: 0},
3339                    finish: {opacity: 100},
3340                    transition: BX.easing.makeEaseOut(BX.easing.transitions.quart),
3341                    step: function (state) {
3342                        insertContainer.style.opacity = state.opacity / 100;
3343                    },
3344                    complete: function () {
3345                        insertContainer.style.height = '';
3346                        insertContainer.style.opacity = '';
3347                    }
3348                }).animate();
3349            }, 110);
3350
3351            this.animateScrollTo(section);
3352        },
3353
3354        alignBasketColumns: function () {
3355            if (!this.basketBlockNode)
3356                return;
3357
3358            var i = 0, k, columns = 0, columnNodes,
3359                windowSize = BX.GetWindowInnerSize(),
3360                basketRows, percent;
3361
3362            if (windowSize.innerWidth > 580 && windowSize.innerWidth < 992) {
3363                basketRows = this.basketBlockNode.querySelectorAll('.bx-soa-basket-info');
3364                percent = 100;
3365
3366                if (basketRows.length) {
3367                    columnNodes = basketRows[0].querySelectorAll('.bx-soa-item-properties');
3368
3369                    if (columnNodes.length && columnNodes[0].style.width != '')
3370                        return;
3371
3372                    columns = columnNodes.length;
3373                    if (columns > 0) {
3374                        columns = columns > 4 ? 4 : columns;
3375                        percent = parseInt(percent / columns);
3376                        for (; i < basketRows.length; i++) {
3377                            columnNodes = basketRows[i].querySelectorAll('.bx-soa-item-properties')
3378                            for (k = 0; k < columnNodes.length; k++) {
3379                                columnNodes[k].style.width = percent + '%';
3380                            }
3381                        }
3382                    }
3383                }
3384            } else {
3385                columnNodes = this.basketBlockNode.querySelectorAll('.bx-soa-item-properties');
3386
3387                if (columnNodes.length && columnNodes[0].style.width == '')
3388                    return;
3389
3390                for (; i < columnNodes.length; i++) {
3391                    columnNodes[i].style.width = '';
3392                }
3393            }
3394        },
3395
3396        editBasketBlock: function (active) {
3397            if (!this.basketBlockNode || !this.basketHiddenBlockNode || !this.result.GRID)
3398                return;
3399
3400            BX.remove(BX.lastChild(this.basketBlockNode));
3401            BX.remove(BX.lastChild(this.basketHiddenBlockNode));
3402
3403            this.editActiveBasketBlock(active);
3404            this.editFadeBasketBlock(active);
3405
3406            this.initialized.basket = true;
3407        },
3408
3409        editActiveBasketBlock: function (activeNodeMode) {
3410            var node = !!activeNodeMode ? this.basketBlockNode : this.basketHiddenBlockNode,
3411                basketContent, basketTable;
3412
3413            if (this.initialized.basket) {
3414                this.basketHiddenBlockNode.appendChild(BX.lastChild(node));
3415                node.appendChild(BX.firstChild(this.basketHiddenBlockNode));
3416            } else {
3417                basketContent = node.querySelector('.bx-soa-section-content');
3418                basketTable = BX.create('DIV', {props: {className: 'bx-soa-item-table'}});
3419
3420                if (!basketContent) {
3421                    basketContent = this.getNewContainer();
3422                    node.appendChild(basketContent);
3423                } else {
3424                    BX.cleanNode(basketContent);
3425                }
3426
3427                this.editBasketItems(basketTable, true);
3428
3429                basketContent.appendChild(
3430                    BX.create('DIV', {
3431                        props: {className: 'bx-soa-table-fade'},
3432                        children: [
3433                            BX.create('DIV', {
3434                                style: {overflowX: 'auto', overflowY: 'hidden'},
3435                                children: [basketTable]
3436                            })
3437                        ]
3438                    })
3439                );
3440
3441                if (this.params.SHOW_COUPONS_BASKET === 'Y') {
3442                    this.editCoupons(basketContent);
3443                }
3444
3445                this.getBlockFooter(basketContent);
3446
3447                BX.bind(
3448                    basketContent.querySelector('div.bx-soa-table-fade').firstChild,
3449                    'scroll',
3450                    BX.proxy(this.basketBlockScrollCheckEvent, this)
3451                );
3452            }
3453
3454            this.alignBasketColumns();
3455        },
3456
3457        editFadeBasketBlock: function (activeNodeMode) {
3458            var node = !!activeNodeMode ? this.basketHiddenBlockNode : this.basketBlockNode,
3459                newContent, basketTable;
3460
3461            if (!this.initialized.basket) {
3462                newContent = this.getNewContainer();
3463                basketTable = BX.create('DIV', {props: {className: 'bx-soa-item-table'}});
3464
3465                this.editBasketItems(basketTable, false);
3466
3467                newContent.appendChild(
3468                    BX.create('DIV', {
3469                        props: {className: 'bx-soa-table-fade'},
3470                        children: [
3471                            BX.create('DIV', {
3472                                style: {overflowX: 'auto', overflowY: 'hidden'},
3473                                children: [basketTable]
3474                            })
3475                        ]
3476                    })
3477                );
3478
3479                if (this.params.SHOW_COUPONS_BASKET === 'Y') {
3480                    this.editCouponsFade(newContent);
3481                }
3482
3483                node.appendChild(newContent);
3484                this.alignBasketColumns();
3485                this.basketBlockScrollCheck();
3486
3487                BX.bind(
3488                    this.basketBlockNode.querySelector('div.bx-soa-table-fade').firstChild,
3489                    'scroll',
3490                    BX.proxy(this.basketBlockScrollCheckEvent, this)
3491                );
3492            }
3493
3494            this.alignBasketColumns();
3495        },
3496
3497        editBasketItems: function (basketItemsNode, active) {
3498            if (!this.result.GRID.ROWS)
3499                return;
3500
3501            var index = 0, i;
3502
3503            if (this.params.SHOW_BASKET_HEADERS === 'Y') {
3504                this.editBasketItemsHeader(basketItemsNode);
3505            }
3506
3507            for (i in this.result.GRID.ROWS) {
3508                if (this.result.GRID.ROWS.hasOwnProperty(i)) {
3509                    this.createBasketItem(basketItemsNode, this.result.GRID.ROWS[i], index++, !!active);
3510                }
3511            }
3512        },
3513
3514        editBasketItemsHeader: function (basketItemsNode) {
3515            if (!basketItemsNode)
3516                return;
3517
3518            var headers = [
3519                    BX.create('DIV', {
3520                        props: {className: 'bx-soa-item-td'},
3521                        style: {paddingBottom: '5px'},
3522                        children: [
3523                            BX.create('DIV', {
3524                                props: {className: 'bx-soa-item-td-title'},
3525                                text: BX.message('SOA_SUM_NAME')
3526                            })
3527                        ]
3528                    })
3529                ],
3530                toRight = false, column, basketColumnIndex = 0, i;
3531
3532            for (i = 0; i < this.result.GRID.HEADERS.length; i++) {
3533                column = this.result.GRID.HEADERS[i];
3534
3535                if (column.id === 'NAME' || column.id === 'PREVIEW_PICTURE' || column.id === 'PROPS' || column.id === 'NOTES')
3536                    continue;
3537
3538                if (column.id === 'DETAIL_PICTURE' && !this.options.showPreviewPicInBasket)
3539                    continue;
3540
3541                toRight = BX.util.in_array(column.id, ["QUANTITY", "PRICE_FORMATED", "DISCOUNT_PRICE_PERCENT_FORMATED", "SUM"]);
3542                headers.push(
3543                    BX.create('DIV', {
3544                        props: {className: 'bx-soa-item-td bx-soa-item-properties' + (toRight ? ' bx-text-right' : '')},
3545                        style: {paddingBottom: '5px'},
3546                        children: [
3547                            BX.create('DIV', {
3548                                props: {className: 'bx-soa-item-td-title'},
3549                                text: column.name
3550                            })
3551                        ]
3552                    })
3553                );
3554
3555                ++basketColumnIndex;
3556                if (basketColumnIndex == 4 && this.result.GRID.HEADERS[i + 1]) {
3557                    headers.push(BX.create('DIV', {props: {className: 'bx-soa-item-nth-4p1'}}));
3558                    basketColumnIndex = 0;
3559                }
3560            }
3561
3562            basketItemsNode.appendChild(
3563                BX.create('DIV', {
3564                    props: {className: 'bx-soa-item-tr'},
3565                    children: headers
3566                })
3567            );
3568        },
3569
3570        createBasketItem: function (basketItemsNode, item, index, active) {
3571            var mainColumns = [],
3572                otherColumns = [],
3573                hiddenColumns = [],
3574                currentColumn, basketColumnIndex = 0,
3575                i, tr, cols;
3576
3577            if (this.options.showPreviewPicInBasket || this.options.showDetailPicInBasket)
3578                mainColumns.push(this.createBasketItemImg(item.data));
3579
3580            mainColumns.push(this.createBasketItemContent(item.data));
3581
3582            for (i = 0; i < this.result.GRID.HEADERS.length; i++) {
3583                currentColumn = this.result.GRID.HEADERS[i];
3584
3585                if (currentColumn.id === 'NAME' || currentColumn.id === 'PREVIEW_PICTURE' || currentColumn.id === 'PROPS' || currentColumn.id === 'NOTES')
3586                    continue;
3587
3588                if (currentColumn.id === 'DETAIL_PICTURE' && !this.options.showPreviewPicInBasket)
3589                    continue;
3590
3591                otherColumns.push(this.createBasketItemColumn(currentColumn, item, active));
3592
3593                ++basketColumnIndex;
3594                if (basketColumnIndex == 4 && this.result.GRID.HEADERS[i + 1]) {
3595                    otherColumns.push(BX.create('DIV', {props: {className: 'bx-soa-item-nth-4p1'}}));
3596                    basketColumnIndex = 0;
3597                }
3598            }
3599
3600            if (active) {
3601                for (i = 0; i < this.result.GRID.HEADERS_HIDDEN.length; i++) {
3602                    tr = this.createBasketItemHiddenColumn(this.result.GRID.HEADERS_HIDDEN[i], item);
3603                    if (BX.type.isArray(tr))
3604                        hiddenColumns = hiddenColumns.concat(tr);
3605                    else if (tr)
3606                        hiddenColumns.push(tr);
3607                }
3608            }
3609
3610            cols = [
3611                BX.create('DIV', {
3612                    props: {className: 'bx-soa-item-td'},
3613                    style: {minWidth: '300px'},
3614                    children: [
3615                        BX.create('DIV', {
3616                            props: {className: 'bx-soa-item-block'},
3617                            children: mainColumns
3618                        })
3619                    ]
3620                })
3621            ].concat(otherColumns);
3622
3623            basketItemsNode.appendChild(
3624                BX.create('DIV', {
3625                    props: {className: 'bx-soa-item-tr bx-soa-basket-info' + (index == 0 ? ' bx-soa-item-tr-first' : '')},
3626                    children: cols
3627                })
3628            );
3629
3630            if (hiddenColumns.length) {
3631                basketItemsNode.appendChild(
3632                    BX.create('DIV', {
3633                        props: {className: 'bx-soa-item-tr bx-soa-item-info-container'},
3634                        children: [
3635                            BX.create('DIV', {
3636                                props: {className: 'bx-soa-item-td'},
3637                                children: [
3638                                    BX.create('A', {
3639                                        props: {href: '', className: 'bx-soa-info-s
3639hower'},
3640                                        html: this.params.MESS_ADDITIONAL_PROPS,
3641                                        events: {
3642                                            click: BX.proxy(this.showAdditionalProperties, this)
3643                                        }
3644                                    }),
3645                                    BX.create('DIV', {
3646                                        props: {className: 'bx-soa-item-info-block'},
3647                                        children: [
3648                                            BX.create('TABLE', {
3649                                                props: {className: 'bx-soa-info-block'},
3650                                                children: hiddenColumns
3651                                            })
3652                                        ]
3653                                    })
3654                                ]
3655                            })
3656                        ]
3657                    })
3658                );
3659            }
3660        },
3661
3662        showAdditionalProperties: function (event) {
3663            var target = event.target || event.srcElement,
3664                infoContainer = target.nextSibling,
3665                parentContainer = BX.findParent(target, {className: 'bx-soa-item-tr bx-soa-item-info-container'}),
3666                parentHeight = parentContainer.offsetHeight;
3667
3668            if (BX.hasClass(infoContainer, 'bx-active')) {
3669                new BX.easing({
3670                    duration: 300,
3671                    start: {opacity: 100, height: parentHeight},
3672                    finish: {opacity: 0, height: 35},
3673                    transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
3674                    step: function (state) {
3675                        infoContainer.style.opacity = state.opacity / 100;
3676                        infoContainer.style.height = state.height + 'px';
3677                        parentContainer.style.height = state.height + 'px';
3678                    },
3679                    complete: function () {
3680                        BX.removeClass(infoContainer, 'bx-active');
3681                        infoContainer.removeAttribute("style");
3682                        parentContainer.removeAttribute("style");
3683                    }
3684                }).animate();
3685            } else {
3686                infoContainer.style.opacity = 0;
3687                BX.addClass(infoContainer, 'bx-active');
3688                var height = infoContainer.offsetHeight + parentHeight;
3689                BX.removeClass(infoContainer, 'bx-active');
3690                infoContainer.style.paddingTop = '10px';
3691
3692                new BX.easing({
3693                    duration: 300,
3694                    start: {opacity: 0, height: parentHeight},
3695                    finish: {opacity: 100, height: height},
3696                    transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
3697                    step: function (state) {
3698                        infoContainer.style.opacity = state.opacity / 100;
3699                        infoContainer.style.height = state.height + 'px';
3700                        parentContainer.style.height = state.height + 'px';
3701                    },
3702                    complete: function () {
3703                        BX.addClass(infoContainer, 'bx-active');
3704                        infoContainer.removeAttribute("style");
3705                    }
3706                }).animate();
3707            }
3708
3709            return BX.PreventDefault(event);
3710        },
3711
3712        createBasketItemImg: function (data) {
3713            if (!data)
3714                return;
3715
3716            var logoNode, logotype;
3717
3718            logoNode = BX.create('DIV', {props: {className: 'bx-soa-item-imgcontainer'}});
3719
3720            if (data.PREVIEW_PICTURE_SRC && data.PREVIEW_PICTURE_SRC.length)
3721                logotype = this.getImageSources(data, 'PREVIEW_PICTURE');
3722            else if (data.DETAIL_PICTURE_SRC && data.DETAIL_PICTURE_SRC.length)
3723                logotype = this.getImageSources(data, 'DETAIL_PICTURE');
3724
3725            if (logotype && logotype.src_2x) {
3726                logoNode.setAttribute('style',
3727                    'background-image: url("' + logotype.src_1x + '");' +
3728                    'background-image: -webkit-image-set(url(' + logotype.src_1x + ') 1x, url(' + logotype.src_2x + ') 2x)'
3729                );
3730            } else {
3731                logotype = logotype && logotype.src_1x || this.defaultBasketItemLogo;
3732                logoNode.setAttribute('style', 'background-image: url("' + logotype + '");');
3733            }
3734
3735            if (this.params.HIDE_DETAIL_PAGE_URL !== 'Y' && data.DETAIL_PAGE_URL && data.DETAIL_PAGE_URL.length) {
3736                logoNode = BX.create('A', {
3737                    props: {href: data.DETAIL_PAGE_URL},
3738                    children: [logoNode]
3739                });
3740            }
3741
3742            return BX.create('DIV', {
3743                props: {className: 'bx-soa-item-img-block'},
3744                children: [logoNode]
3745            });
3746        },
3747
3748        createBasketItemContent: function (data) {
3749            var itemName = data.NAME || '',
3750                titleHtml = this.htmlspecialcharsEx(itemName),
3751                props = data.PROPS || [],
3752                propsNodes = [];
3753
3754            if (this.params.HIDE_DETAIL_PAGE_URL !== 'Y' && data.DETAIL_PAGE_URL && data.DETAIL_PAGE_URL.length) {
3755                titleHtml = '<a href="' + data.DETAIL_PAGE_URL + '">' + titleHtml + '</a>';
3756            }
3757
3758            if (this.options.showPropsInBasket && props.length) {
3759                for (var i in props) {
3760                    if (props.hasOwnProperty(i)) {
3761                        var name = props[i].NAME || '',
3762                            value = props[i].VALUE || '';
3763
3764                        propsNodes.push(
3765                            BX.create('DIV', {
3766                                props: {className: 'bx-soa-item-td-title'},
3767                                style: {textAlign: 'left'},
3768                                text: name
3769                            })
3770                        );
3771                        propsNodes.push(
3772                            BX.create('DIV', {
3773                                props: {className: 'bx-soa-item-td-text'},
3774                                style: {textAlign: 'left'},
3775                                text: value
3776                            })
3777                        );
3778                    }
3779                }
3780            }
3781
3782            return BX.create('DIV', {
3783                props: {className: 'bx-soa-item-content'},
3784                children: propsNodes.length ? [
3785                    BX.create('DIV', {props: {className: 'bx-soa-item-title'}, html: titleHtml}),
3786                    BX.create('DIV', {props: {className: 'bx-scu-container'}, children: propsNodes})
3787                ] : [
3788                    BX.create('DIV', {props: {className: 'bx-soa-item-title'}, html: titleHtml})
3789                ]
3790            });
3791        },
3792
3793        createBasketItemColumn: function (column, allData, active) {
3794            if (!column || !allData)
3795                return;
3796
3797            var data = allData.columns[column.id] ? allData.columns : allData.data,
3798                toRight = BX.util.in_array(column.id, ["QUANTITY", "PRICE_FORMATED", "DISCOUNT_PRICE_PERCENT_FORMATED", "SUM"]),
3799                textNode = BX.create('DIV', {props: {className: 'bx-soa-item-td-text'}}
3799),
3800                logotype, img;
3801
3802            if (column.id === 'PRICE_FORMATED') {
3803                textNode.appendChild(BX.create('STRONG', {props: {className: 'bx-price'}, html: data.PRICE_FORMATED}));
3804                if (parseFloat(data.DISCOUNT_PRICE) > 0) {
3805                    textNode.appendChild(BX.create('BR'));
3806                    textNode.appendChild(BX.create('STRONG', {
3807                        props: {className: 'bx-price-old'},
3808                        html: data.BASE_PRICE_FORMATED
3809                    }));
3810                }
3811
3812                if (this.options.showPriceNotesInBasket && active) {
3813                    textNode.appendChild(BX.create('BR'));
3814                    textNode.appendChild(BX.create('SMALL', {text: data.NOTES}));
3815                }
3816            } else if (column.id === 'SUM') {
3817                textNode.appendChild(BX.create('STRONG', {props: {className: 'bx-price all'}, html: data.SUM}));
3818                if (parseFloat(data.DISCOUNT_PRICE) > 0) {
3819                    textNode.appendChild(BX.create('BR'));
3820                    textNode.appendChild(BX.create('STRONG', {
3821                        props: {className: 'bx-price-old'},
3822                        html: data.SUM_BASE_FORMATED
3823                    }));
3824                }
3825            } else if (column.id === 'DISCOUNT') {
3826                textNode.appendChild(BX.create('STRONG', {
3827                    props: {className: 'bx-price'},
3828                    text: data.DISCOUNT_PRICE_PERCENT_FORMATED
3829                }));
3830            } else if (column.id === 'DETAIL_PICTURE') {
3831                logotype = this.getImageSources(allData.data, column.id),
3832                    img = BX.create('IMG', {props: {src: logotype && logotype.src_1x || this.defaultBasketItemLogo}});
3833
3834                if (logotype && logotype.src_1x && logotype.src_orig) {
3835                    BX.bind(img, 'click', BX.delegate(function (e) {
3836                        this.popupShow(e, logotype.src_orig);
3837                    }, this));
3838                }
3839
3840                textNode.appendChild(img);
3841            } else if (BX.util.in_array(column.id, ["QUANTITY", "WEIGHT_FORMATED", "DISCOUNT_PRICE_PERCENT_FORMATED"])) {
3842                textNode.appendChild(BX.create('SPAN', {html: data[column.id]}));
3843            } else if (column.id === 'PREVIEW_TEXT') {
3844                if (data['PREVIEW_TEXT_TYPE'] === 'html') {
3845                    textNode.appendChild(BX.create('SPAN', {html: data['PREVIEW_TEXT'] || ''}));
3846                } else {
3847                    textNode.appendChild(BX.create('SPAN', {text: data['PREVIEW_TEXT'] || ''}));
3848                }
3849            } else {
3850                var columnData = data[column.id], val = [];
3851                if (BX.type.isArray(columnData)) {
3852                    for (var i in columnData) {
3853                        if (columnData.hasOwnProperty(i)) {
3854                            if (columnData[i].type == 'image')
3855                                val.push(this.getImageContainer(columnData[i].value, columnData[i].source));
3856                            else if (columnData[i].type == 'linked') {
3857                                textNode.appendChild(BX.create('SPAN', {html: columnData[i].value_format}));
3858                                textNode.appendChild(BX.create('BR'));
3859                            } else if (columnData[i].value) {
3860                                textNode.appendChild(BX.create('SPAN', {html: columnData[i].value}));
3861                                textNode.appendChild(BX.create('BR'));
3862                            }
3863                        }
3864                    }
3865
3866                    if (val.length) {
3867                        textNode.appendChild(
3868                            BX.create('DIV', {
3869                                props: {className: 'bx-scu-list'},
3870                                children: [BX.create('UL', {props: {className: 'bx-scu-itemlist'}, children: val})]
3871                            })
3872                        );
3873                    }
3874                } else if (columnData) {
3875                    textNode.appendChild(BX.create('SPAN', {html: BX.util.htmlspecialchars(columnData)}));
3876                }
3877            }
3878
3879            return BX.create('DIV', {
3880                props: {className: 'bx-soa-item-td bx-soa-item-properties' + (toRight ? ' bx-text-right' : '')},
3881                children: [
3882                    BX.create('DIV', {
3883                        props: {className: 'bx-soa-item-td-title'},
3884                        text: column.name
3885                    }),
3886                    textNode
3887                ]
3888            });
3889        },
3890
3891        createBasketItemHiddenColumn: function (column, allData) {
3892            if (!column || !allData)
3893                return;
3894
3895            var data = allData.columns[column.id] ? allData.columns : allData.data,
3896                textNode = BX.create('TD', {props: {className: 'bx-soa-info-text'}}
3896),
3897                logotype, img, i;
3898
3899            if (column.id === 'PROPS') {
3900                var propsNodes = [], props = allData.data.PROPS;
3901                if (props && props.length) {
3902                    for (i in props) {
3903                        if (props.hasOwnProperty(i)) {
3904                            var name = props[i].NAME || '',
3905                                value = props[i].VALUE || '';
3906
3907                            if (value.length == 0)
3908                                continue;
3909
3910                            propsNodes.push(
3911                                BX.create('TR', {
3912                                    props: {className: 'bx-soa-info-line'},
3913                                    children: [
3914                                        BX.create('TD', {props: {className: 'bx-soa-info-title'}, text: name + ':'}),
3915                                        BX.create('TD', {
3916                                            props: {className: 'bx-soa-info-text'},
3917                                            html: BX.util.htmlspecialchars(value)
3918                                        })
3919                                    ]
3920                                })
3921                            );
3922                        }
3923                    }
3924
3925                    return propsNodes;
3926                } else return;
3927            } else if (column.id === 'PRICE_FORMATED') {
3928                textNode.appendChild(BX.create('STRONG', {props: {className: 'bx-price'}, html: data.PRICE_FORMATED}));
3929                if (parseFloat(data.DISCOUNT_PRICE) > 0) {
3930                    textNode.appendChild(BX.create('BR'));
3931                    textNode.appendChild(BX.create('STRONG', {
3932                        props: {className: 'bx-price-old'},
3933                        html: data.BASE_PRICE_FORMATED
3934                    }));
3935                }
3936            } else if (column.id === 'SUM')
3937                textNode.appendChild(BX.create('STRONG', {props: {className: 'bx-price all'}, text: data.SUM}));
3938            else if (column.id === 'DISCOUNT')
3939                textNode.appendChild(BX.create('STRONG', {
3940                    props: {className: 'bx-price'},
3941                    text: data.DISCOUNT_PRICE_PERCENT_FORMATED
3942                }));
3943            else if (column.id === 'DETAIL_PICTURE' || column.id === 'PREVIEW_PICTURE') {
3944                logotype = this.getImageSources(allData.data, column.id),
3945                    img = BX.create('IMG', {
3946                        props: {src: logotype && logotype.src_1x || this.defaultBasketItemLogo},
3947                        style: {maxWidth: '50%'}
3948                    });
3949
3950                if (logotype && logotype.src_1x && logotype.src_orig) {
3951                    BX.bind(img, 'click', BX.delegate(function (e) {
3952                        this.popupShow(e, logotype.src_orig);
3953                    }, this));
3954                }
3955
3956                textNode.appendChild(img);
3957            } else if (BX.util.in_array(column.id, ["QUANTITY", "WEIGHT_FORMATED", "DISCOUNT_PRICE_PERCENT_FORMATED"])) {
3958                textNode.appendChild(BX.create('SPAN', {html: data[column.id]}));
3959            } else if (column.id === 'PREVIEW_TEXT') {
3960                if (data['PREVIEW_TEXT_TYPE'] === 'html') {
3961                    textNode.appendChild(BX.create('SPAN', {html: data['PREVIEW_TEXT'] || ''}));
3962                } else {
3963                    textNode.appendChild(BX.create('SPAN', {text: data['PREVIEW_TEXT'] || ''}));
3964                }
3965            } else {
3966                var columnData = data[column.id], val = [];
3967                if (BX.type.isArray(columnData)) {
3968                    for (i in columnData) {
3969                        if (columnData.hasOwnProperty(i)) {
3970                            if (columnData[i].type == 'image')
3971                                val.push(this.getImageContainer(columnData[i].value, columnData[i].source));
3972                            else if (columnData[i].type == 'linked') {
3973                                textNode.appendChild(BX.create('SPAN', {html: columnData[i].value_format}));
3974                                textNode.appendChild(BX.create('BR'));
3975                            } else if (columnData[i].value) {
3976                                textNode.appendChild(BX.create('SPAN', {html: columnData[i].value}));
3977                                textNode.appendChild(BX.create('BR'));
3978                            } else return;
3979                        }
3980                    }
3981
3982                    if (val.length) {
3983                        textNode.appendChild(
3984                            BX.create('DIV', {
3985                                props: {className: 'bx-scu-list'},
3986                                children: [BX.create('UL', {props: {className: 'bx-scu-itemlist'}, children: val})]
3987                            })
3988                        );
3989                    }
3990
3991                } else if (columnData) {
3992                    textNode.appendChild(BX.create('SPAN', {html: BX.util.htmlspecialchars(columnData)}));
3993                } else {
3994                    return;
3995                }
3996            }
3997
3998            return BX.create('TR', {
3999                props: {className: 'bx-soa-info-line'},
4000                children: [
4001                    BX.create('TD', {
4002                        props: {className: 'bx-soa-info-title'},
4003                        text: column.name + ':'
4004                    }),
4005                    textNode
4006                ]
4007            });
4008        },
4009
4010        popupShow: function (e, url, source) {
4011            if (this.popup)
4012                this.popup.destroy();
4013
4014            var that = this;
4015            this.popup = new BX.PopupWindow('bx-soa-image-popup', null, {
4016                lightShadow: true,
4017                offsetTop: 0,
4018                offsetLeft: 0,
4019                closeIcon: {top: '3px', right: '10px'},
4020                autoHide: true,
4021                bindOptions: {position: "bottom"},
4022                closeByEsc: true,
4023                zIndex: 100,
4024                events: {
4025                    onPopupShow: function () {
4026                        BX.create("IMG", {
4027                            props: {src: source || url},
4028                            events: {
4029                                load: function () {
4030                                    var content = BX('bx-soa-image-popup-content');
4031                                    if (content) {
4032                                        var windowSize = BX.GetWindowInnerSize(),
4033                                            ratio = this.isMobile ? 0.5 : 0.9,
4034                                            contentHeight, contentWidth;
4035
4036                                        BX.cleanNode(content);
4037                                        content.appendChild(this);
4038
4039                                        contentHeight = content.offsetHeight;
4040                                        contentWidth = content.offsetWidth;
4041
4042                                        if (contentHeight >
4042 windowSize.innerHeight * ratio) {
4043                                            content.style.height = windowSize.innerHeight * ratio + 'px';
4044                                            content.style.width = contentWidth * (windowSize.innerHeight * ratio / contentHeight) + 'px';
4045                                            contentHeight = content.offsetHeight;
4046                                            contentWidth = content.offsetWidth;
4047                                        }
4048
4049                                        if (contentWidth > windowSize.innerWidth * ratio) {
4050                                            content.style.width = windowSize.innerWidth * ratio + 'px';
4051                                            content.style.height = contentHeight * (windowSize.innerWidth * ratio / contentWidth) + 'px';
4052                                        }
4053
4054                                        content.style.height = content.offsetHeight + 'px';
4055                                        content.style.width = content.offsetWidth + 'px';
4056
4057                                        that.popup.adjustPosition();
4058                                    }
4059                                }
4060                            }
4061                        });
4062                    },
4063                    onPopupClose: function () {
4064                        this.destroy();
4065                    }
4066                },
4067                content: BX.create('DIV', {
4068                    props: {id: 'bx-soa-image-popup-content'},
4069                    children: [BX.create('IMG', {props: {src: this.imgFolder + "/loader.gif"}})]
4070                })
4071            });
4072            this.popup.show();
4073        },
4074
4075        getImageContainer: function (link, source) {
4076            return BX.create('LI', {
4077                props: {className: 'bx-img-item'},
4078                children: [
4079                    BX.create('DIV', {
4080                        props: {className: 'bx-scu-itemColorBlock'},
4081                        children: [
4082                            BX.create('DIV', {
4083                                props: {className: 'bx-img-itemColor'},
4084                                style: {backgroundImage: 'url(' + link + ')'}
4085                            })
4086                        ],
4087                        events: {
4088                            click: BX.delegate(function (e) {
4089                                this.popupShow(e, link, source)
4090                            }, this)
4091                        }
4092                    })
4093                ]
4094            });
4095        },
4096
4097        getCouponChangeEvent: function () {
4098            return BX.delegate(function (event) {
4099                var newCoupon = BX.getEventTarget(event);
4100                if (newCoupon && newCoupon.value) {
4101                    this.sendRequest('enterCoupon', newCoupon.value);
4102                    newCoupon.value = '';
4103                }
4104            }, this);
4105        },
4106
4107        editCoupons: function (basketItemsNode) {
4108            var couponsList = this.getCouponsList(true),
4109                couponsLabel = this.getCouponsLabel(true),
4110                couponsBlock = BX.create('DIV', {
4111                    props: {className: 'bx-soa-coupon-block'},
4112                    children: [
4113                        BX.create('DIV', {
4114                            props: {className: 'bx-soa-coupon-input'},
4115                            children: [
4116                                BX.create('INPUT', {
4117                                    props: {
4118                                        className: 'tanais-form-control bx-ios-fix',
4119                                        type: 'text'
4120                                    },
4121                                    events: {
4122                                        change: this.getCouponChangeEvent()
4123                                    }
4124                                }),
4125                                BX.create("SPAN", {
4126                                    props: {
4127                                        className: 'bx-soa-coupon-btn'
4128                                    }
4129                                })
4130                            ]
4131                        }),
4132                        BX.create('SPAN', {props: {className: 'bx-soa-coupon-item'}, children: couponsList})
4133                    ]
4134                });
4135
4136            basketItemsNode.appendChild(
4137                BX.create('DIV', {
4138                    props: {className: 'bx-soa-coupon'},
4139                    children: [
4140                        couponsLabel,
4141                        couponsBlock
4142                    ]
4143                })
4144            );
4145        },
4146
4147        editCouponsFade: function (basketItemsNode) {
4148            if (this.result.COUPON_LIST.length < 1)
4149                return;
4150
4151            var couponsList = this.getCouponsList(false),
4152                couponsLabel, couponsBlock;
4153
4154            if (couponsList.length) {
4155                couponsLabel = this.getCouponsLabel(false);
4156                couponsBlock = BX.create('DIV', {
4157                    props: {className: 'bx-soa-coupon-block'},
4158                    children: [
4159                        BX.create('DIV', {
4160                            props: {className: 'bx-soa-coupon-list'},
4161                            children: [
4162                                BX.create('DIV', {
4163                                    props: {className: 'bx-soa-coupon-item'},
4164                                    children: [couponsLabel].concat(couponsList)
4165                                })
4166                            ]
4167                        })
4168                    ]
4169                });
4170
4171                basketItemsNode.appendChild(
4172                    BX.create('DIV', {
4173                        props: {className: 'bx-soa-coupon bx-soa-coupon-item-fixed'},
4174                        children: [couponsBlock]
4175                    })
4176                );
4177            }
4178        },
4179
4180        getCouponsList: function (active) {
4181            var couponsList = [], i;
4182
4183            for (i = 0; i < this.result.COUPON_LIST.length; i++) {
4184                if (active || (!active && this.result.COUPON_LIST[i].JS_STATUS == 'APPLIED')) {
4185                    couponsList.push(this.getCouponNode({
4186                        text: this.result.COUPON_LIST[i].COUPON,
4187                        desc: this.result.COUPON_LIST[i].JS_CHECK_CODE,
4188                        status: this.result.COUPON_LIST[i].JS_STATUS
4189                    }, active));
4190                }
4191            }
4192
4193            return couponsList;
4194        },
4195
4196        getCouponNode: function (coupon, active) {
4197            var couponName = BX.util.htmlspecialchars(coupon.text) || '',
4198                couponDesc = coupon.desc && coupon.desc.length
4199                    ? coupon.desc.charAt(0).toUpperCase() + coupon.desc.slice(1)
4200                    : BX.message('SOA_NOT_FOUND'),
4201                couponStatus = coupon.status || 'BAD',
4202                couponItem, tooltip;
4203
4204            switch (couponStatus.toUpperCase()) {
4205                case 'ENTERED':
4206                    couponItem = 'used';
4207                    tooltip = 'warning';
4208                    break;
4209                case 'BAD':
4210                    couponItem = tooltip = 'danger';
4211                    break;
4212                default:
4213                    couponItem = tooltip = 'success';
4214            }
4215
4216            return BX.create('STRONG', {
4217                attrs: {
4218                    'data-coupon': couponName,
4219                    className: 'bx-soa-coupon-item-' + couponItem
4220                },
4221                children: active ? [
4222                    couponName || '',
4223                    BX.create('SPAN', {
4224                        props: {className: 'bx-soa-coupon-remove'},
4225                        events: {
4226                            click: BX.delegate(function (e) {
4227                                var target = e.target || e.srcElement,
4228                                    coupon = BX.findParent(target, {tagName: 'STRONG'});
4229
4230                                if (coupon && coupon.getAttribute('data-coupon')) {
4231                                    this.sendRequest('removeCoupon', coupon.getAttribute('data-coupon'))
4232                                }
4233                            }, this)
4234                        }
4235                    })
4236                ] : [couponName]
4237            });
4238        },
4239
4240        getCouponsLabel: function (active) {
4241            return BX.create('DIV', {
4242                props: {className: 'bx-soa-coupon-label'},
4243                children: active
4244                    ? [BX.create('LABEL', {html: this.params.MESS_USE_COUPON + ':'})]
4245                    : [this.params.MESS_COUPON + ':']
4246            });
4247        },
4248
4249        addCoupon: function (coupon) {
4250            var couponListNodes = this.orderBlockNode.querySelectorAll('.bx-soa-coupon:not(.bx-soa-coupon-item-fixed) .bx-soa-coupon-item');
4251
4252            for (var i = 0; i < couponListNodes.length; i++) {
4253                if (couponListNodes[i].querySelector('[data-coupon="' + BX.util.htmlspecialchars(coupon) + '"]'))
4254                    break;
4255
4256                couponListNodes[i].appendChild(this.getCouponNode({text: coupon}, true, 'bx-soa-coupon-item-danger'));
4257            }
4258        },
4259
4260        removeCoupon: function (coupon) {
4261            var couponNodes = this.orderBlockNode.querySelectorAll('[data-coupon="' + BX.util.htmlspecialchars(coupon) + '"]'),
4262                i;
4263
4264            for (i in couponNodes) {
4265                if (couponNodes.hasOwnProperty(i)) {
4266                    BX.remove(couponNodes[i]);
4267                }
4268            }
4269        },
4270
4271        editRegionBlock: function (active) {
4272            if (!this.regionBlockNode || !this.regionHiddenBlockNode || !this.result.PERSON_TYPE)
4273                return;
4274
4275            if (active) {
4276                this.editActiveRegionBlock(true);
4277                !this.regionBlockNotEmpty && this.editFadeRegionBlock();
4278            } else
4279                this.editFadeRegionBlock();
4280
4281            this.initialized.region = true;
4282        },
4283
4284        editActiveRegionBlock: function (activeNodeMode) {
4285            var node = activeNodeMode ? this.regionBlockNode : this.regionHiddenBlockNode,
4286                regionContent, regionNode, regionNodeCol;
4287
4288            if (this.initialized.region) {
4289                BX.remove(BX.lastChild(node));
4290                node.appendChild(BX.firstChild(this.regionHiddenBlockNode));
4291            } else {
4292                regionContent = node.querySelector('.bx-soa-section-content');
4293                if (!regionContent) {
4294                    regionContent = this.getNewContainer();
4295                    node.appendChild(regionContent);
4296                } else
4297                    BX.cleanNode(regionContent);
4298
4299                this.getErrorContainer(regionContent);
4300
4301                regionNode = BX.create('DIV', {props: {className: 'bx_soa_location'}});
4302                regionNodeCol = BX.create('DIV', {});
4303
4304                this.getPersonTypeControl(regionNodeCol);
4305
4306                this.getProfilesControl(regionNodeCol);
4307
4308                this.getDeliveryLocationInput(regionNodeCol);
4309
4310                if (!this.result.SHOW_AUTH) {
4311                    if (this.regionBlockNotEmpty) {
4312                        BX.addClass(this.regionBlockNode, 'bx-active');
4313                        this.regionBlockNode.style.display = '';
4314                    } else {
4315                        BX.removeClass(this.regionBlockNode, 'bx-active');
4316                        this.regionBlockNode.style.display = 'none';
4317
4318                        if (!this.result.IS_AUTHORIZED || typeof this.result.LAST_ORDER_DATA.FAIL !== 'undefined')
4319                            this.initFirstSection();
4320                    }
4321                }
4322
4323                regionNode.appendChild(regionNodeCol);
4324                regionContent.appendChild(regionNode);
4325                this.getBlockFooter(regionContent);
4326            }
4327        },
4328
4329        editFadeRegionBlock: function () {
4330            var regionContent = this.regionBlockNode.querySelector('.bx-soa-section-content'), newContent;
4331
4332            if (this.initialized.region) {
4333                this.regionHiddenBlockNode.appendChild(regionContent);
4334            } else {
4335                this.editActiveRegionBlock(false);
4336                BX.remove(BX.lastChild(this.regionBlockNode));
4337            }
4338
4339            newContent = this.getNewContainer(true);
4340            this.regionBlockNode.appendChild(newContent);
4341            this.editFadeRegionContent(newContent);
4342        },
4343
4344        editFadeRegionContent: function (node) {
4345            if (!node || !this.locationsInitialized)
4346                return;
4347
4348            var selectedPersonType = this.getSelectedPersonType(),
4349                errorNode = this.regionHiddenBlockNode.querySelector('.alert.alert-danger'),
4350                addedHtml = '', props = [], locationProperty,
4351                input, zipValue = '', zipProperty,
4352                fadeParamName, i, k, locationString, validRegionErrors;
4353
4354            BX.cleanNode(node);
4355
4356            if (errorNode)
4357                node.appendChild(errorNode.cloneNode(true));
4358
4359            if (selectedPersonType && selectedPersonType.NAME && this.result.PERSON_TYPE.length > 1) {
4360                addedHtml += '<strong>' + this.params.MESS_PERSON_TYPE + ':</strong> '
4361                    + BX.util.htmlspecialchars(selectedPersonType.NAME) + '<br>';
4362            }
4363
4364            if (selectedPersonType) {
4365                fadeParamName = 'PROPS_FADE_LIST_' + selectedPersonType.ID;
4366                props = this.params[fadeParamName] || [];
4367            }
4368
4369            for (i in this.result.ORDER_PROP.properties) {
4370                if (this.result.ORDER_PROP.properties.hasOwnProperty(i)) {
4371                    if (this.result.ORDER_PROP.properties[i].IS_LOCATION == 'Y'
4372                        && this.result.ORDER_PROP.properties[i].ID == this.deliveryLocationInfo.loc) {
4373                        locationProperty = this.result.ORDER_PROP.properties[i];
4374                    } else if (this.result.ORDER_PROP.properties[i].IS_ZIP == 'Y'
4375                        && this.result.ORDER_PROP.properties[i].ID == this.deliveryLocationInfo.zip) {
4376                        zipProperty = this.result.ORDER_PROP.properties[i];
4377                        for (k = 0; k < props.length; k++) {
4378                            if (props[k] == zipProperty.ID) {
4379                                input = BX('zipProperty');
4380                                zipValue = input && input.value && input.value.length ? input.value : BX.message('SOA_NOT_SPECIFIED');
4381                                break;
4382                            }
4383                        }
4384                    }
4385                }
4386            }
4387
4388            locationString = this.getLocationString(this.regionHiddenBlockNode);
4389            if (locationProperty && locationString.length)
4390                addedHtml += '<strong>' + BX.util.htmlspecialchars(locationProperty.NAME) + ':</strong> '
4391                    + BX.util.htmlspecialchars(locationString) + '<br>';
4392
4393            if (zipProperty && zipValue.length)
4394                addedHtml += '<strong>' + BX.util.htmlspecialchars(zipProperty.NAME) + ':</strong> '
4395                    + BX.util.htmlspecialchars(zipValue);
4396
4397            node.innerHTML += addedHtml;
4398
4399            if (this.regionBlockNode.getAttribute('data-visited') == 'true') {
4400                validRegionErrors = this.isValidRegionBlock();
4401
4402                if (validRegionErrors.length) {
4403                    BX.addClass(this.regionBlockNode, 'bx-step-error');
4404                    this.showError(this.regionBlockNode, validRegionErrors);
4405                } else
4406                    BX.removeClass(this.regionBlockNode, 'bx-step-error');
4407            }
4408
4409            BX.bind(node.querySelector('.alert.alert-danger'), 'click', BX.proxy(this.showByClick, this));
4410            BX.bind(node.querySelector('.alert.alert-warning'), 'click', BX.proxy(this.showByClick, this));
4411        },
4412
4413        getSelectedPersonType: function () {
4414            var personTypeInput, currentPersonType, personTypeId, i,
4415                personTypeLength = this.result.PERSON_TYPE.length;
4416
4417            if (personTypeLength == 1) {
4418                personTypeInput = this.regionBlockNode.querySelector('input[type=hidden][name=PERSON_TYPE]');
4419                if (!personTypeInput)
4420                    personTypeInput = this.regionHiddenBlockNode.querySelector('input[type=hidden][name=PERSON_TYPE]');
4421            } else if (personTypeLength == 2) {
4422                personTypeInput = this.regionBlockNode.querySelector('input[type=radio][name=PERSON_TYPE]:checked');
4423                if (!personTypeInput)
4424                    personTypeInput = this.regionHiddenBlockNode.querySelector('input[type=radio][name=PERSON_TYPE]:checked');
4425            } else {
4426                personTypeInput = this.regionBlockNode.querySelector('select[name=PERSON_TYPE] > option:checked');
4427                if (!personTypeInput)
4428                    personTypeInput = this.regionHiddenBlockNode.querySelector('select[name=PERSON_TYPE] > option:checked');
4429            }
4430
4431            if (personTypeInput) {
4432                personTypeId = personTypeInput.value;
4433
4434                for (i in this.result.PERSON_TYPE) {
4435                    if (this.result.PERSON_TYPE[i].ID == personTypeId) {
4436                        currentPersonType = this.result.PERSON_TYPE[i];
4437                        break;
4438                    }
4439                }
4440            }
4441
4442            return currentPersonType;
4443        },
4444
4445        getDeliveryLocationInput: function (node) {
4446            var currentProperty, locationId, altId, location, k, altProperty,
4447                labelHtml, currentLocation, insertedLoc,
4448                labelTextHtml, label, input, altNode;
4449
4450            for (k in this.result.ORDER_PROP.properties) {
4451                if (this.result.ORDER_PROP.properties.hasOwnProperty(k)) {
4452                    currentProperty = this.result.ORDER_PROP.properties[k];
4453                    if (currentProperty.IS_LOCATION == 'Y') {
4454                        locationId = currentProperty.ID;
4455                        altId = parseInt(currentProperty.INPUT_FIELD_LOCATION);
4456                        break;
4457                    }
4458                }
4459            }
4460
4461            location = this.locations[locationId];
4462            if (location && location[0] && location[0].output) {
4463                this.regionBlockNotEmpty = true;
4464
4465                labelHtml = '<label class="bx-soa-custom-label" for="soa-property-' + parseInt(locationId) + '">'
4466                    + (currentProperty.REQUIRED == 'Y' ? '<span class="bx-authform-starrequired">*</span> ' : '')
4467                    + BX.util.htmlspecialchars(currentProperty.NAME)
4468                    + (currentProperty.DESCRIPTION.length ? ' <small>(' + BX.util.htmlspecialchars(currentProperty.DESCRIPTION) + ')</small>' : '')
4469                    + '</label>';
4470
4471                currentLocation = location[0].output;
4472                insertedLoc = BX.create('DIV', {
4473                    attrs: {'data-property-id-row': locationId},
4474                    props: {className: 'tanais-form-group bx-soa-location-input-container'},
4475                    style: {visibility: 'hidden'},
4476                    html: labelHtml + currentLocation.HTML
4477                });
4478                node.appendChild(insertedLoc);
4479                node.appendChild(BX.create('INPUT', {
4480                    props: {
4481                        type: 'hidden',
4482                        name: 'RECENT_DELIVERY_VALUE',
4483                        value: location[0].lastValue
4484                    }
4485                }));
4486
4487                for (k in currentLocation.SCRIPT)
4488                    if (currentLocation.SCRIPT.hasOwnProperty(k))
4489                        BX.evalGlobal(currentLocation.SCRIPT[k].JS);
4490            }
4491
4492            if (location && location[0] && location[0].showAlt && altId > 0) {
4493                for (k in this.result.ORDER_PROP.properties) {
4494                    if (parseInt(this.result.ORDER_PROP.properties[k].ID) == altId) {
4495                        altProperty = this.result.ORDER_PROP.properties[k];
4496                        break;
4497                    }
4498                }
4499            }
4500
4501            if (altProperty) {
4502                altNode = BX.create('DIV', {
4503                    attrs: {'data-property-id-row': altProperty.ID},
4504                    props: {className: "tanais-form-group bx-soa-location-input-container"}
4505                });
4506
4507                labelTextHtml = altProperty.REQUIRED == 'Y' ? '<span class="bx-authform-starrequired">*</span> ' : '';
4508                labelTextHtml += BX.util.htmlspecialchars(altProperty.NAME);
4509
4510                label = BX.create('LABEL', {
4511                    attrs: {for: 'altProperty'},
4512                    props: {className: 'bx-soa-custom-label'},
4513                    html: labelTextHtml
4514                });
4515
4516                input = BX.create('INPUT', {
4517                    props: {
4518                        id: 'altProperty',
4519                        type: 'text',
4520                        placeholder: altProperty.DESCRIPTION,
4521                        autocomplete: 'city',
4522                        className: 'tanais-form-control bx-soa-customer-input bx-ios-fix',
4523                        name: 'ORDER_PROP_' + altProperty.ID,
4524                        value: altProperty.VALUE
4525                    }
4526                });
4527
4528                altNode.appendChild(label);
4529                altNode.appendChild(input);
4530                node.appendChild(altNode);
4531
4532                this.bindValidation(altProperty.ID, altNode);
4533            }
4534
4535            this.getZipLocationInput(node);
4536
4537            /*if (location && location[0])
4538			{
4539				node.appendChild(
4540					BX.create('DIV', {
4541						props: {className: 'bx-soa-reference'},
4542						html: this.params.MESS_REGION_REFERENCE
4543					})
4544				);
4545			}*/
4546        },
4547
4548        getLocationString: function (node) {
4549            if (!node)
4550                return '';
4551
4552            var locationInputNode = node.querySelector('.bx-ui-sls-route'),
4553                locationString = '',
4554                locationSteps, i, altLoc;
4555
4556            if (locationInputNode && locationInputNode.value && locationInputNode.value.length)
4557                locationString = locationInputNode.value;
4558            else {
4559                locationSteps = node.querySelectorAll('.bx-ui-combobox-fake.bx-combobox-fake-as-input');
4560                for (i = locationSteps.length; i--;) {
4561                    if (locationSteps[i].innerHTML.indexOf('...') >= 0)
4562                        continue;
4563
4564                    if (locationSteps[i].innerHTML.indexOf('---') >= 0) {
4565                        altLoc = BX('altProperty');
4566                        if (altLoc && altLoc.value.length)
4567                            locationString += altLoc.value;
4568
4569                        continue;
4570                    }
4571
4572                    if (locationString.length)
4573                        locationString += ', ';
4574
4575                    locationString += locationSteps[i].innerHTML;
4576                }
4577
4578                if (locationString.length == 0)
4579                    locationString = BX.message('SOA_NOT_SPECIFIED');
4580            }
4581
4582            return locationString;
4583        },
4584
4585        getZipLocationInput: function (node) {
4586            var zipProperty, i, propsItemNode, labelTextHtml, label, input;
4587
4588            for (i in this.result.ORDER_PROP.properties) {
4589                if (this.result.ORDER_PROP.properties.hasOwnProperty(i) && this.result.ORDER_PROP.properties[i].IS_ZIP == 'Y') {
4590                    zipProperty = this.result.ORDER_PROP.properties[i];
4591                    break;
4592                }
4593            }
4594
4595            if (zipProperty) {
4596                this.regionBlockNotEmpty = true;
4597
4598                propsItemNode = BX.create('DIV', {props: {className: "tanais-form-group bx-soa-location-input-container"}});
4599                propsItemNode.setAttribute('data-property-id-row', zipProperty.ID);
4600
4601                labelTextHtml = zipProperty.REQUIRED == 'Y' ? '<span class="bx-authform-starrequired">*</span> ' : '';
4602                labelTextHtml += BX.util.htmlspecialchars(zipProperty.NAME);
4603
4604                label = BX.create('LABEL', {
4605                    attrs: {'for': 'zipProperty'},
4606                    props: {className: 'bx-soa-custom-label'},
4607                    html: labelTextHtml
4608                });
4609                input = BX.create('INPUT', {
4610                    props: {
4611                        id: 'zipProperty',
4612                        type: 'text',
4613                        placeholder: zipProperty.DESCRIPTION,
4614                        autocomplete: 'zip',
4615                        className: 'tanais-form-control bx-soa-customer-input bx-ios-fix',
4616                        name: 'ORDER_PROP_' + zipProperty.ID,
4617                        value: zipProperty.VALUE
4618                    }
4619                });
4620
4621                propsItemNode.appendChild(label);
4622                propsItemNode.appendChild(input);
4623                node.appendChild(propsItemNode);
4624                node.appendChild(
4625                    BX.create('input', {
4626                        props: {
4627                            id: 'ZIP_PROPERTY_CHANGED',
4628                            name: 'ZIP_PROPERTY_CHANGED',
4629                            type: 'hidden',
4630                            value: this.result.ZIP_PROPERTY_CHANGED || 'N'
4631                        }
4632                    })
4633                );
4634
4635                this.bindValidation(zipProperty.ID, propsItemNode);
4636            }
4637        },
4638
4639        getPersonTypeSortedArray: function (objPersonType) {
4640            var personTypes = [], k;
4641
4642            for (k in objPersonType) {
4643                if (objPersonType.hasOwnProperty(k)) {
4644                    personTypes.push(objPersonType[k]);
4645                }
4646            }
4647
4648            return personTypes.sort(function (a, b) {
4649                return parseInt(a.SORT) - parseInt(b.SORT)
4650            });
4651        },
4652
4653        getPersonTypeControl: function (node) {
4654            if (!this.result.PERSON_TYPE)
4655                return;
4656
4657            this.result.PERSON_TYPE = this.getPersonTypeSortedArray(this.result.PERSON_TYPE);
4658
4659            var personTypesCount = this.result.PERSON_TYPE.length,
4660                currentType, oldPersonTypeId, i,
4661                input, options = [], label, delimiter = false;
4662
4663            if (personTypesCount > 1) {
4664                input = BX.create('DIV', {
4665                    props: {className: 'tanais-form-group person-type'},
4666                });
4667                node.appendChild(input);
4668                node = input;
4669            }
4670
4671            if (personTypesCount > 2) {
4672                for (i in this.result.PERSON_TYPE) {
4673                    if (this.result.PERSON_TYPE.hasOwnProperty(i)) {
4674                        currentType = this.result.PERSON_TYPE[i];
4675                        options.push(BX.create('OPTION', {
4676                            props: {
4677                                value: currentType.ID,
4678                                selected: currentType.CHECKED == 'Y'
4679                            },
4680                            text: currentType.NAME
4681                        }));
4682
4683                        if (currentType.CHECKED == 'Y')
4684                            oldPersonTypeId = currentType.ID;
4685                    }
4686
4687                }
4688                node.appendChild(BX.create('SELECT', {
4689                    props: {name: 'PERSON_TYPE', className: 'tanais-form-control'},
4690                    children: options,
4691                    events: {change: BX.proxy(this.sendRequest, this)}
4692                }));
4693
4694                this.regionBlockNotEmpty = true;
4695            } else if (personTypesCount == 2) {
4696                for (i in this.result.PERSON_TYPE) {
4697                    if (this.result.PERSON_TYPE.hasOwnProperty(i)) {
4698                        currentType = this.result.PERSON_TYPE[i];
4699                        label = BX.create('LABEL', {
4700                            children: [
4701                                BX.create('INPUT', {
4702                                    attrs: {checked: currentType.CHECKED == 'Y'},
4703                                    props: {type: 'radio', name: 'PERSON_TYPE', value: currentType.ID}
4704                                }),
4705                                BX.util.htmlspecialchars(currentType.NAME)
4706                            ],
4707                            events: {change: BX.proxy(this.sendRequest, this)}
4708                        });
4709
4710                        node.appendChild(
4711                            BX.create('DIV', {
4712                                props: {
4713                                    className: 'tanais-radio-inline' + (currentType.CHECKED == 'Y' ? " checked" : "")
4714                                },
4715                                children: [label]
4716                            })
4717                        );
4718
4719                        delimiter = true;
4720
4721                        if (currentType.CHECKED == 'Y')
4722                            oldPersonTypeId = currentType.ID;
4723                    }
4724                }
4725
4726                this.regionBlockNotEmpty = true;
4727            } else {
4728                for (i in this.result.PERSON_TYPE)
4729                    if (this.result.PERSON_TYPE.hasOwnProperty(i))
4730                        node.appendChild(BX.create('INPUT', {
4731                            props: {
4732                                type: 'hidden',
4733                                name: 'PERSON_TYPE',
4734                                value: this.result.PERSON_TYPE[i].ID
4735                            }
4736                        }));
4737            }
4738
4739            if (oldPersonTypeId) {
4740                node.appendChild(
4741                    BX.create('INPUT', {
4742                        props: {
4743                            type: 'hidden',
4744                            name: 'PERSON_TYPE_OLD',
4745                            value: oldPersonTypeId
4746
4747                        }
4748                    })
4749                );
4750            }
4751        },
4752
4753        getProfilesControl: function (node) {
4754            var profilesLength = BX.util.object_keys(this.result.USER_PROFILES).length,
4755                i, label, options = [],
4756                profileChangeInput, input;
4757
4758            if (profilesLength) {
4759                if (
4760                    this.params.ALLOW_USER_PROFILES === 'Y'
4761                    && (profilesLength > 1 || this.params.ALLOW_NEW_PROFILE === 'Y')
4762                ) {
4763                    this.regionBlockNotEmpty = true;
4764
4765                    label = BX.create('LABEL', {
4766                        props: {className: 'bx-soa-custom-label'},
4767                        html: this.params.MESS_SELECT_PROFILE
4768                    });
4769
4770                    for (i in this.result.USER_PROFILES) {
4771                        if (this.result.USER_PROFILES.hasOwnProperty(i)) {
4772                            options.unshift(
4773                                BX.create('OPTION', {
4774                                    props: {
4775                                        value: this.result.USER_PROFILES[i].ID,
4776                                        selected: this.result.USER_PROFILES[i].CHECKED === 'Y'
4777                                    },
4778                                    html: this.result.USER_PROFILES[i].NAME
4779                                })
4780                            );
4781                        }
4782                    }
4783
4784                    if (this.params.ALLOW_NEW_PROFILE === 'Y') {
4785                        options.unshift(BX.create('OPTION', {
4786                            props: {value: 0},
4787                            text: BX.message('SOA_PROP_NEW_PROFILE')
4788                        }));
4789                    }
4790
4791                    profileChangeInput = BX.create('INPUT', {
4792                        props: {
4793                            type: 'hidden',
4794                            value: 'N',
4795                            id: 'profile_change',
4796                            name: 'profile_change'
4797                        }
4798                    });
4799                    input = BX.create('SELECT', {
4800                        props: {className: 'tanais-form-control', name: 'PROFILE_ID'},
4801                        children: options,
4802                        events: {
4803                            change: BX.delegate(function () {
4804                                BX('profile_change').value = 'Y';
4805                                this.sendRequest();
4806                            }, this)
4807                        }
4808                    });
4809
4810                    node.appendChild(
4811                        BX.create('DIV', {
4812                            props: {className: 'tanais-form-group bx-soa-location-input-container'},
4813                            children: [label, profileChangeInput, input]
4814                        })
4815                    );
4816                } else {
4817                    for (i in this.result.USER_PROFILES) {
4818                        if (
4819                            this.result.USER_PROFILES.hasOwnProperty(i)
4820                            && this.result.USER_PROFILES[i].CHECKED === 'Y'
4821                        ) {
4822                            node.appendChild(
4823                                BX.create('INPUT', {
4824                                    props: {
4825                                        name: 'PROFILE_ID',
4826                                        type: 'hidden',
4827                                        value: this.result.USER_PROFILES[i].ID
4828                                    }
4829                                })
4830                            );
4831                        }
4832                    }
4833                }
4834            }
4835        },
4836
4837        editPaySystemBlock: function (active) {
4838            if (!this.paySystemBlockNode || !this.paySystemHiddenBlockNode || !this.result.PAY_SYSTEM)
4839                return;
4840
4841            if (active)
4842                this.editActivePaySystemBlock(true);
4843            else
4844                this.editFadePaySystemBlock();
4845
4846            this.initialized.paySystem = true;
4847        },
4848
4849        editActivePaySystemBlock: function (activeNodeMode) {
4850            var node = activeNodeMode ? this.paySystemBlockNode : this.paySystemHiddenBlockNode,
4851                paySystemContent, paySystemNode;
4852
4853            if (this.initialized.paySystem) {
4854                BX.remove(BX.lastChild(node));
4855                node.appendChild(BX.firstChild(this.paySystemHiddenBlockNode));
4856            } else {
4857                paySystemContent = node.querySelector('.bx-soa-section-content');
4858                if (!paySystemContent) {
4859                    paySystemContent = this.getNewContainer();
4860                    node.appendChild(paySystemContent);
4861                } else
4862                    BX.cleanNode(paySystemContent);
4863
4864                this.getErrorContainer(paySystemContent);
4865                paySystemNode = BX.create('DIV', {props: {className: 'bx-soa-pp'}});
4866                this.editPaySystemItems(paySystemNode);
4867                paySystemContent.appendChild(paySystemNode);
4868
4869                if (this.params.SHOW_COUPONS_PAY_SYSTEM == 'Y')
4870                    this.editCoupons(paySystemContent);
4871
4872                this.getBlockFooter(paySystemContent);
4873            }
4874        },
4875
4876        editFadePaySystemBlock: function () {
4877            var paySystemContent = this.paySystemBlockNode.querySelector('.bx-soa-section-content'), newContent;
4878
4879            if (this.initialized.paySystem) {
4880                this.paySystemHiddenBlockNode.appendChild(paySystemContent);
4881            } else {
4882                this.editActivePaySystemBlock(false);
4883                BX.remove(BX.lastChild(this.paySystemBlockNode));
4884            }
4885
4886            newContent = this.getNewContainer(true);
4887            this.paySystemBlockNode.appendChild(newContent);
4888
4889            this.editFadePaySystemContent(newContent);
4890
4891            if (this.params.SHOW_COUPONS_PAY_SYSTEM == 'Y')
4892                this.editCouponsFade(newContent);
4893        },
4894
4895        editPaySystemItems: function (paySystemNode) {
4896            if (!this.result.PAY_SYSTEM || this.result.PAY_SYSTEM.length <= 0)
4897                return;
4898
4899            var paySystemItemsContainer = BX.create('DIV', {props: {className: 'bx-soa-pp-item-container'}}),
4900                paySystemItemNode, i;
4901
4902            for (i = 0; i < this.paySystemPagination.currentPage.length; i++) {
4903                paySystemItemNode = this.createPaySystemItem(this.paySystemPagination.currentPage[i]);
4904                paySystemItemsContainer.appendChild(paySystemItemNode);
4905            }
4906
4907            if (this.paySystemPagination.show)
4908                this.showPagination('paySystem', paySystemItemsContainer);
4909
4910            paySystemNode.appendChild(paySystemItemsContainer);
4911        },
4912
4913        createPaySystemItem: function (item) {
4914            var checked = item.CHECKED == 'Y',
4915                paySystemId = parseInt(item.ID),
4916                title, label, itemNode;
4917
4918            label = BX.create('DIV', {
4919                props: {className: 'bx-soa-pp-company-graf-container'},
4920                children: [
4921                    BX.create('INPUT', {
4922                        props: {
4923                            id: 'ID_PAY_SYSTEM_ID_' + paySystemId,
4924                            name: 'PAY_SYSTEM_ID',
4925                            type: 'checkbox',
4926                            className: 'bx-soa-pp-company-checkbox',
4927                            value: paySystemId,
4928                            checked: checked
4929                        }
4930                    }),
4931                    BX.create('SPAN', {
4932                        props: {
4933                            className: 'style-checkbox'
4934                        }
4935                    })
4936                ]
4937            });
4938
4939            if (this.params.SHOW_PAY_SYSTEM_LIST_NAMES == 'Y') {
4940                title = BX.create('DIV', {props: {className: 'bx-soa-pp-company-smalltitle'}, text: item.NAME});
4941            }
4942
4943            itemNode = BX.create('DIV', {
4944                props: {className: 'bx-soa-pp-company'},
4945                children: [
4946                    label,
4947                    title,
4948                    BX.create('DIV', {
4949                        props: {className: 'bx-soa-pp-company-smalldescr'},
4950                        html: item.DESCRIPTION
4951                    })
4952                ],
4953                events: {
4954                    click: BX.proxy(this.selectPaySystem, this)
4955                }
4956            });
4957
4958            if (checked)
4959                BX.addClass(itemNode, 'bx-selected');
4960
4961            return itemNode;
4962        },
4963
4964        getInnerPaySystem: function () {
4965            if (!this.result.CURRENT_BUDGET_FORMATED || !this.result.PAY_CURRENT_ACCOUNT || !this.result.INNER_PAY_SYSTEM)
4966                return;
4967
4968            var accountOnly = this.params.ONLY_FULL_PAY_FROM_ACCOUNT && (this.params.ONLY_FULL_PAY_FROM_ACCOUNT == 'Y'),
4969                isSelected = this.result.PAY_CURRENT_ACCOUNT && (this.result.PAY_CURRENT_ACCOUNT == 'Y'),
4970                paySystem = this.result.INNER_PAY_SYSTEM,
4971                logotype, logoNode, subTitle, label, title, hiddenInput, htmlString, innerPsDesc;
4972
4973            if (this.params.SHOW_PAY_SYSTEM_INFO_NAME == 'Y') {
4974                subTitle = BX.create('DIV', {
4975                    props: {className: 'bx-soa-pp-company-subTitle'},
4976                    text: paySystem.NAME
4977                });
4978            }
4979
4980            logoNode = BX.create('DIV', {props: {className: 'bx-soa-pp-company-image'}});
4981            logotype = this.getImageSources(paySystem, 'LOGOTIP');
4982            if (logotype && logotype.src_2x) {
4983                logoNode.setAttribute('style',
4984                    'background-image: url(' + logotype.src_1x + ');' +
4985                    'background-image: -webkit-image-set(url(' + logotype.src_1x + ') 1x, url(' + logotype.src_2x + ') 2x)'
4986                );
4987            } else {
4988                logotype = logotype && logotype.src_1x || this.defaultPaySystemLogo;
4989                logoNode.setAttribute('style', 'background-image: url(' + logotype + ');');
4990            }
4991
4992            label = BX.create('DIV', {
4993                props: {className: 'bx-soa-pp-company-logo'},
4994                children: [
4995                    BX.create('DIV', {
4996                        props: {className: 'bx-soa-pp-company-graf-container'},
4997                        children: [
4998                            BX.create('INPUT', {
4999                                props: {
5000                                    type: 'checkbox',
5001                                    className: 'bx-soa-pp-company-checkbox',
5002                                    name: 'PAY_CURRENT_ACCOUNT',
5003                                    value: 'Y',
5004                                    checked: isSelected
5005                                }
5006                            }),
5007                            logoNode
5008                        ],
5009                        events: {
5010                            click: BX.proxy(this.selectPaySystem, this)
5011                        }
5012                    })
5013                ]
5014            });
5015
5016            if (paySystem.DESCRIPTION && paySystem.DESCRIPTION.length) {
5017                title = BX.create('DIV', {
5018                    props: {className: 'bx-soa-pp-company-block'},
5019                    children: [BX.create('DIV', {
5020                        props: {className: 'bx-soa-pp-company-desc'},
5021                        html: paySystem.DESCRIPTION
5022                    })]
5023                });
5024            }
5025
5026            hiddenInput = BX.create('INPUT', {
5027                props: {
5028                    type: 'hidden',
5029                    name: 'PAY_CURRENT_ACCOUNT',
5030                    value: 'N'
5031                }
5032            });
5033
5034            htmlString = this.params.MESS_INNER_PS_BALANCE + ' <b class="wsnw">' + this.result.CURRENT_BUDGET_FORMATED
5035                + '</b><br>
5035' + (accountOnly ? BX.message('SOA_PAY_ACCOUNT3') : '');
5036            innerPsDesc = BX.create('DIV', {props: {className: 'bx-soa-pp-company-desc'}, html: htmlString});
5037
5038            return BX.create('DIV', {
5039                props: {className: 'bx-soa-pp-inner-ps' + (isSelected ? ' bx-selected' : '')},
5040                children: [hiddenInput, subTitle, label, title, innerPsDesc]
5041            });
5042        },
5043
5044        editFadePaySystemContent: function (node) {
5045            var selectedPaySystem = this.getSelectedPaySystem(),
5046                errorNode = this.paySystemHiddenBlockNode.querySelector('div.alert.alert-danger'),
5047                warningNode = this.paySystemHiddenBlockNode.querySelector('div.alert.alert-warning.alert-show'),
5048                addedHtml = '', logotype, imgSrc;
5049
5050            if (errorNode)
5051                node.appendChild(errorNode.cloneNode(true));
5052            else
5053                this.getErrorContainer(node);
5054
5055            if (warningNode && warningNode.innerHTML)
5056                node.appendChild(warningNode.cloneNode(true));
5057
5058            if (this.isSelectedInnerPayment()) {
5059                logotype = this.getImageSources(this.result.INNER_PAY_SYSTEM, 'LOGOTIP');
5060                imgSrc = logotype && logotype.src_1x || this.defaultPaySystemLogo;
5061
5062                addedHtml += '<div class="bx-soa-pp-company-selected">';
5063                addedHtml += '<img src="' + imgSrc + '" style="height:18px;" alt="">';
5064                addedHtml += '<strong>' + this.result.INNER_PAY_SYSTEM.NAME + '</strong><br>';
5065                addedHtml += '</div>';
5066            }
5067
5068            if (selectedPaySystem && selectedPaySystem.NAME) {
5069                logotype = this.getImageSources(selectedPaySystem, 'PSA_LOGOTIP');
5070                imgSrc = logotype && logotype.src_1x || this.defaultPaySystemLogo;
5071
5072                addedHtml += '<div class="bx-soa-pp-company-selected">';
5073                addedHtml += '<img src="' + imgSrc + '" style="height:18px;" alt="">';
5074                addedHtml += '<strong>' + BX.util.htmlspecialchars(selectedPaySystem.NAME) + '</strong>';
5075                addedHtml += '</div>';
5076            }
5077
5078            if (!addedHtml.length)
5079                addedHtml = '<strong>' + BX.message('SOA_PS_SELECT_ERROR') + '</strong>';
5080
5081            node.innerHTML += addedHtml;
5082
5083            node.appendChild(BX.create('DIV', {style: {clear: 'both'}}));
5084            BX.bind(node.querySelector('.alert.alert-danger'), 'click', BX.proxy(this.showByClick, this));
5085            BX.bind(node.querySelector('.alert.alert-warning'), 'click', BX.proxy(this.showByClick, this));
5086        },
5087
5088        getSelectedPaySystem: function () {
5089            var paySystemCheckbox = this.paySystemBlockNode.querySelector('input[type=checkbox][name=PAY_SYSTEM_ID]:checked'),
5090                currentPaySystem = null, paySystemId, i;
5091
5092            if (!paySystemCheckbox)
5093                paySystemCheckbox = this.paySystemHiddenBlockNode.querySelector('input[type=checkbox][name=PAY_SYSTEM_ID]:checked');
5094
5095            if (!paySystemCheckbox)
5096                paySystemCheckbox = this.paySystemHiddenBlockNode.querySelector('input[type=hidden][name=PAY_SYSTEM_ID]');
5097
5098            if (paySystemCheckbox) {
5099                paySystemId = paySystemCheckbox.value;
5100
5101                for (i = 0; i < this.result.PAY_SYSTEM.length; i++) {
5102                    if (this.result.PAY_SYSTEM[i].ID == paySystemId) {
5103                        currentPaySystem = this.result.PAY_SYSTEM[i];
5104                        break;
5105                    }
5106                }
5107            }
5108
5109            return currentPaySystem;
5110        },
5111
5112        isSelectedInnerPayment: function () {
5113            var innerPaySystemCheckbox = this.paySystemBlockNode.querySelector('input[type=checkbox][name=PAY_CURRENT_ACCOUNT]');
5114
5115            if (!innerPaySystemCheckbox)
5116                innerPaySystemCheckbox = this.paySystemHiddenBlockNode.querySelector('input[type=checkbox][name=PAY_CURRENT_ACCOUNT]');
5117
5118            return innerPaySystemCheckbox && innerPaySystemCheckbox.checked;
5119        },
5120
5121        selectPaySystem: function (event) {
5122            if (!this.orderBlockNode || !event)
5123                return;
5124
5125            var target = event.target || event.srcElement,
5126                innerPaySystemSection = this.paySystemBlockNode.querySelector('div.bx-soa-pp-inner-ps'),
5127                innerPaySystemCheckbox = this.paySystemBlockNode.querySelector('input[type=checkbox][name=PAY_CURRENT_ACCOUNT]'),
5128                fullPayFromInnerPaySystem = this.result.TOTAL && parseFloat(this.result.TOTAL.ORDER_TOTAL_LEFT_TO_PAY) === 0;
5129
5130            var innerPsAction = BX.hasClass(target, 'bx-soa-pp-inner-ps') ? target : BX.findParent(target, {className: 'bx-soa-pp-inner-ps'}),
5131                actionSection = BX.hasClass(target, 'bx-soa-pp-company') ? target : BX.findParent(target, {className: 'bx-soa-pp-company'}),
5132                actionInput, selectedSection;
5133
5134            if (innerPsAction) {
5135                if (target.nodeName == 'INPUT')
5136                    innerPaySystemCheckbox.checked = !innerPaySystemCheckbox.checked;
5137
5138                if (innerPaySystemCheckbox.checked) {
5139                    BX.removeClass(innerPaySystemSection, 'bx-selected');
5140                    innerPaySystemCheckbox.checked = false;
5141                } else {
5142                    BX.addClass(innerPaySystemSection, 'bx-selected');
5143                    innerPaySystemCheckbox.checked = true;
5144                }
5145            } else if (actionSection) {
5146                if (BX.hasClass(actionSection, 'bx-selected')) {
5147                    if (target.nodeName == "A") {
5148                        return;
5149                    }
5150                    return BX.PreventDefault(event);
5151                }
5152
5153                if (innerPaySystemCheckbox && innerPaySystemCheckbox.checked && fullPayFromInnerPaySystem) {
5154                    BX.addClass(actionSection, 'bx-selected');
5155                    actionInput = actionSection.querySelector('input[type=checkbox]');
5156                    actionInput.checked = true;
5157                    BX.removeClass(innerPaySystemSection, 'bx-selected');
5158                    innerPaySystemCheckbox.checked = false;
5159                } else {
5160                    selectedSection = this.paySystemBlockNode.querySelector('.bx-soa-pp-company.bx-selected');
5161                    BX.addClass(actionSection, 'bx-selected');
5162                    actionInput = actionSection.querySelector('input[type=checkbox]');
5163                    actionInput.checked = true;
5164
5165                    if (selectedSection) {
5166                        BX.removeClass(selectedSection, 'bx-selected');
5167                        selectedSection.querySelector('input[type=checkbox]').checked = false;
5168                    }
5169                }
5170            }
5171
5172            this.sendRequest();
5173        },
5174
5175        editDeliveryBlock: function (active) {
5176            if (!this.deliveryBlockNode || !this.deliveryHiddenBlockNode || !this.result.DELIVERY)
5177                return;
5178
5179            if (active)
5180                this.editActiveDeliveryBlock(true);
5181            else
5182                this.editFadeDeliveryBlock();
5183
5184            this.checkPickUpShow();
5185
5186            this.initialized.delivery = true;
5187        },
5188
5189        editActiveDeliveryBlock: function (activeNodeMode) {
5190            var node = activeNodeMode ? this.deliveryBlockNode : this.deliveryHiddenBlockNode,
5191                deliveryContent, deliveryNode;
5192
5193            if (!this.initialized.delivery) {
5194                deliveryContent = node.querySelector('.bx-soa-section-content');
5195                if (!deliveryContent) {
5196                    deliveryContent = this.getNewContainer();
5197                    node.appendChild(deliveryContent);
5198                } else
5199                    BX.cleanNode(deliveryContent);
5200
5201                this.getErrorContainer(deliveryContent);
5202
5203                deliveryNode = BX.create('DIV', {props: {className: 'bx-soa-pp'}});
5204                this.editDeliveryItems(deliveryNode);
5205                deliveryContent.appendChild(deliveryNode);
5206                this.editDeliveryInfo(deliveryNode);
5207
5208                if (this.params.SHOW_COUPONS_DELIVERY == 'Y')
5209                    this.editCoupons(deliveryContent);
5210
5211                this.getBlockFooter(deliveryContent);
5212            }
5213        },
5214
5215        editDeliveryItems: function (deliveryNode) {
5216            if (!this.result.DELIVERY || this.result.DELIVERY.length <= 0)
5217                return;
5218
5219            var deliveryItemsContainer = BX.create('DIV', {props: {className: 'bx-soa-pp-item-container'}}),
5220                deliveryItemNode, k;
5221
5222            for (k = 0; k < this.deliveryPagination.currentPage.length; k++) {
5223                deliveryItemNode = this.createDeliveryItem(this.deliveryPagination.currentPage[k]);
5224                deliveryItemsContainer.appendChild(deliveryItemNode);
5225            }
5226
5227            if (this.deliveryPagination.show)
5228                this.showPagination('delivery', deliveryItemsContainer);
5229
5230            deliveryNode.appendChild(deliveryItemsContainer);
5231        },
5232
5233        editDeliveryInfo: function (deliveryNode) {
5234            if (!this.result.DELIVERY)
5235                return;
5236
5237            var deliveryInfoContainer = BX.create('DIV', {props: {className: 'bx-soa-pp-desc-container'}}),
5238                currentDelivery, title, period,
5239                infoList, extraServices, extraServicesNode;
5240
5241            var isShowDeliveryInfo = false;
5242            var issetPeriod = false;
5243
5244            BX.cleanNode(deliveryInfoContainer);
5245            currentDelivery = this.getSelectedDelivery();
5246
5247            title = BX.create('DIV', {
5248                props: {className: 'bx-soa-pp-company-block'},
5249                children: [
5250                    currentDelivery.CALCULATE_DESCRIPTION
5251                        ? (isShowDeliveryInfo = true) && BX.create('DIV', {
5252                        props: {className: 'bx-soa-pp-company-desc'},
5253                        html: currentDelivery.CALCULATE_DESCRIPTION
5254                    })
5255                        : null
5256                ]
5257            });
5258
5259            if (currentDelivery.PERIOD_TEXT && currentDelivery.PERIOD_TEXT.length) {
5260                period = BX.create('LI', {
5261                    children: [
5262                        BX.create('DIV', {
5263                            props: {className: 'bx-soa-pp-list-termin'},
5264                            html: this.params.MESS_PERIOD + ':'
5265                        }),
5266                        BX.create('DIV', {
5267                            props: {className: 'bx-soa-pp-list-description'},
5268                            html: currentDelivery.PERIOD_TEXT
5269                        })
5270                    ]
5271                });
5272
5273                isShowDeliveryInfo = issetPeriod = true;
5274            }
5275
5276            infoList = !issetPeriod ? null : BX.create('UL', {
5277                props: {className: 'bx-soa-pp-list'},
5278                children: [period]
5279            });
5280            extraServices = this.getDeliveryExtraServices(currentDelivery);
5281
5282            if (extraServices.length) {
5283                extraServicesNode = BX.create('DIV', {
5284                    props: {className: 'bx-soa-pp-company-block'},
5285                    children: extraServices
5286                });
5287                isShowDeliveryInfo = true;
5288            }
5289
5290            if (isShowDeliveryInfo) {
5291                deliveryInfoContainer.appendChild(
5292                    BX.create('DIV', {
5293                        props: {className: 'bx-soa-pp-company'},
5294                        children: [title, extraServicesNode, infoList]
5295                    })
5296                );
5297
5298                deliveryNode.appendChild(deliveryInfoContainer);
5299
5300                BX("bx_soa_item_delivery_id_" + currentDelivery.ID).appendChild(deliveryInfoContainer);
5301            }
5302
5303            if (this.params.DELIVERY_NO_AJAX != 'Y')
5304                this.deliveryCachedInfo[currentDelivery.ID] = currentDelivery;
5305        },
5306
5307        getDeliveryPriceNodes: function (delivery) {
5308            var priceNodesArray;
5309
5310            if (typeof delivery.DELIVERY_DISCOUNT_PRICE !== 'undefined'
5311                && parseFloat(delivery.DELIVERY_DISCOUNT_PRICE) != parseFloat(delivery.PRICE)) {
5312                if (parseFloat(delivery.DELIVERY_DISCOUNT_PRICE) > parseFloat(delivery.PRICE))
5313                    priceNodesArray = [delivery.DELIVERY_DISCOUNT_PRICE_FORMATED];
5314                else
5315                    priceNodesArray = [
5316                        delivery.DELIVERY_DISCOUNT_PRICE_FORMATED,
5317                        BX.create('BR'),
5318                        BX.create('SPAN', {props: {className: 'bx-price-old'}, html: delivery.PRICE_FORMATED})
5319                    ];
5320            } else {
5321                priceNodesArray = [delivery.PRICE_FORMATED];
5322            }
5323
5324            return priceNodesArray;
5325        },
5326
5327        getDeliveryExtraServices: function (delivery) {
5328            var extraServices = [],
5329                i, currentService, serviceNode, serviceName, input;
5330
5331            for (i in delivery.EXTRA_SERVICES) {
5332                if (!delivery.EXTRA_SERVICES.hasOwnProperty(i))
5333                    continue;
5334
5335                currentService = delivery.EXTRA_SERVICES[i];
5336
5337                if (!currentService.canUserEditValue)
5338                    continue;
5339
5340                if (currentService.editControl.indexOf('this.checked') == -1) {
5341                    serviceName = BX.create('LABEL', {
5342                        html: BX.util.htmlspecialchars(currentService.name)
5343                            + (currentService.price ? ' (' + currentService.priceFormatted + ')' : '')
5344                    });
5345
5346                    serviceNode = BX.create('DIV', {
5347                        props: {className: 'tanais-form-group bx-soa-pp-field'},
5348                        html: currentService.editControl
5349                            + (currentService.description && currentService.description.length
5350                                ? '<div class="bx-soa-service-small">' + BX.util.htmlspecialchars(currentService.description) + '</div>'
5351                                : '')
5352                    });
5353
5354                    BX.prepend(serviceName, serviceNode);
5355                    input = serviceNode.querySelector('input[type=text]');
5356                    if (!input)
5357                        input = serviceNode.querySelector('select');
5358
5359                    if (input)
5360                        BX.addClass(input, 'tanais-form-control');
5361                } else {
5362                    serviceNode = BX.create('DIV', {
5363                        props: {className: 'checkbox'},
5364                        children: [
5365                            BX.create('LABEL', {
5366                                html: currentService.editControl + BX.util.htmlspecialchars(currentService.name)
5367                                    + (currentService.price ? ' (' + currentService.priceFormatted + ')' : '')
5368                                    + (currentService.description && currentService.description.length
5369                                        ? '<div class="bx-soa-service-small">' + BX.util.htmlspecialchars(currentService.description) + '</div>'
5370                                        : '')
5371                            })
5372                        ]
5373                    });
5374                }
5375
5376                extraServices.push(serviceNode);
5377            }
5378
5379            return extraServices;
5380        },
5381
5382        editFadeDeliveryBlock: function () {
5383            var deliveryContent = this.deliveryBlockNode.querySelector('.bx-soa-section-content'), newContent;
5384
5385            if (!this.initialized.delivery) {
5386                this.editActiveDeliveryBlock(false);
5387                BX.remove(BX.lastChild(this.deliveryBlockNode));
5388            }
5389
5390            newContent = this.getNewContainer(true);
5391            this.deliveryBlockNode.appendChild(newContent);
5392
5393            this.editFadeDeliveryContent(newContent);
5394
5395            if (this.params.SHOW_COUPONS_DELIVERY == 'Y')
5396                this.editCouponsFade(newContent);
5397        },
5398
5399        createDeliveryItem: function (item) {
5400            var checked = item.CHECKED == 'Y',
5401                deliveryId = parseInt(item.ID),
5402                labelNodes = [
5403                    BX.create('INPUT', {
5404                        props: {
5405                            id: 'ID_DELIVERY_ID_' + deliveryId,
5406                            name: 'DELIVERY_ID',
5407                            type: 'checkbox',
5408                            className: 'bx-soa-pp-company-checkbox',
5409                            value: deliveryId,
5410                            checked: checked
5411                        }
5412                    }),
5413                    BX.create('SPAN', {
5414                        props: {
5415                            className: 'style-checkbox'
5416                        }
5417                    })
5418                ],
5419                deliveryCached = this.deliveryCachedInfo[deliveryId],
5420                logotype, label, title, itemNode, logoNode;
5421
5422            if (this.params.SHOW_DELIVERY_LIST_NAMES == 'Y') {
5423                labelNodes.push(
5424                    BX.create('DIV', {
5425                        props: {className: 'bx-soa-pp-company-smalltitle'},
5426                        children: [
5427                            BX.create("SPAN", {
5428                                text: this.params.SHOW_DELIVERY_PARENT_NAMES != 'N' ? item.NAME : item.OWN_NAME
5429                            })
5430                        ]
5431                    })
5432                );
5433            }
5434
5435            var hasDeliveryCost = false;
5436
5437            if (item.PRICE >= 0 || typeof item.DELIVERY_DISCOUNT_PRICE !== 'undefined') {
5438                var actualPrice = typeof item.DELIVERY_DISCOUNT_PRICE !== 'undefined' ?
5439                    (item.DELIVERY_DISCOUNT_PRICE > 0 ? item.DELIVERY_DISCOUNT_PRICE_FORMATED : this.params.MESS_PRICE_FREE) :
5440                    (item.PRICE > 0 ? item.PRICE_FORMATED : this.params.MESS_PRICE_FREE);
5441
5442                labelNodes.push(
5443                    BX.create('DIV', {
5444                        props: {className: 'bx-soa-pp-delivery-cost'},
5445                        html: actualPrice
5446                    })
5447                );
5448
5449                hasDeliveryCost = true;
5450            } else if (deliveryCached && (deliveryCached.PRICE >= 0 || typeof deliveryCached.DELIVERY_DISCOUNT_PRICE !== 'undefined')) {
5451                var actualPrice = typeof deliveryCached.DELIVERY_DISCOUNT_PRICE !== 'undefined' ?
5452                    (deliveryCached.DELIVERY_DISCOUNT_PRICE > 0 ? deliveryCached.DELIVERY_DISCOUNT_PRICE_FORMATED : this.params.MESS_PRICE_FREE) :
5453                    (deliveryCached.PRICE > 0 ? deliveryCached.PRICE_FORMATED : this.params.MESS_PRICE_FREE);
5454
5455                labelNodes.push(
5456                    BX.create('DIV', {
5457                        props: {className: 'bx-soa-pp-delivery-cost'},
5458                        html: actualPrice
5459                    })
5460                );
5461
5462                hasDeliveryCost = true;
5463            }
5464
5465            label = BX.create('DIV', {
5466                props: {
5467                    className: 'bx-soa-pp-company-graf-container' + (hasDeliveryCost ? ' has-delivery-cost' : '')
5468                        + (item.CALCULATE_ERRORS || deliveryCached && deliveryCached.CALCULATE_ERRORS ? ' bx-bd-waring' : '')
5469                },
5470                children: labelNodes
5471            });
5472
5473            itemNode = BX.create('DIV', {
5474                props: {
5475                    id: 'bx_soa_item_delivery_id_' + deliveryId,
5476                    className: 'bx-soa-pp-company'
5477                },
5478                children: [
5479                    BX.create('DIV', {
5480                        props: {
5481                            className: 'bx-soa-pp-company-inner-block'
5482                        },
5483                        children: [
5484                            label,
5485                            BX.create('DIV', {
5486                                props: {className: 'bx-soa-pp-company-smalldescr' + (checked ? ' bx-soa-pp-company-desc' : '')},
5487                                html: item.DESCRIPTION
5488                            })
5489                        ],
5490                        events: {click: BX.proxy(this.selectDelivery, this)}
5491                    })
5492                ]
5493            });
5494
5495            checked && BX.addClass(itemNode, 'bx-selected');
5496
5497            if (checked && this.result.LAST_ORDER_DATA.PICK_UP)
5498                this.lastSelectedDelivery = deliveryId;
5499
5500            return itemNode;
5501        },
5502
5503        editFadeDeliveryContent: function (node) {
5504            var selectedDelivery = this.getSelectedDelivery(),
5505                name = this.params.SHOW_DELIVERY_PARENT_NAMES != 'N' ? selectedDelivery.NAME : selectedDelivery.OWN_NAME,
5506                errorNode = this.deliveryHiddenBlockNode.querySelector('div.alert.alert-danger'),
5507                warningNode = this.deliveryHiddenBlockNode.querySelector('div.alert.alert-warning.alert-show'),
5508                extraService, logotype, imgSrc, arNodes, i;
5509
5510            if (errorNode && errorNode.innerHTML)
5511                node.appendChild(errorNode.cloneNode(true));
5512            else
5513                this.getErrorContainer(node);
5514
5515            if (warningNode && warningNode.innerHTML)
5516                node.appendChild(warningNode.cloneNode(true));
5517
5518            if (selectedDelivery && selectedDelivery.NAME) {
5519                logotype = this.getImageSources(selectedDelivery, 'LOGOTIP');
5520                imgSrc = logotype && logotype.src_1x || this.defaultDeliveryLogo;
5521                arNodes = [
5522                    BX.create('IMG', {props: {src: imgSrc, alt: ''}, style: {height: '18px'}}),
5523                    BX.create('STRONG', {text: name})
5524                ];
5525
5526                if (this.params.DELIVERY_FADE_EXTRA_SERVICES == 'Y' && BX.util.object_keys(selectedDelivery.EXTRA_SERVICES).length) {
5527                    arNodes.push(BX.create('BR'));
5528
5529                    for (i in selectedDelivery.EXTRA_SERVICES) {
5530                        if (selectedDelivery.EXTRA_SERVICES.hasOwnProperty(i)) {
5531                            extraService = selectedDelivery.EXTRA_SERVICES[i];
5532                            if (extraService.value && extraService.value != 'N' && extraService.canUserEditValue) {
5533                                arNodes.push(BX.create('BR'));
5534                                arNodes.push(BX.create('STRONG', {text: extraService.name + ': '}));
5535                                arNodes.push(extraService.viewControl);
5536                            }
5537                        }
5538                    }
5539                }
5540
5541                node.appendChild(
5542                    BX.create('DIV', {
5543                        props: {className: 'bx-soa-pp-company-selected'},
5544                        children: arNodes
5545                    })
5546                );
5547                node.appendChild(
5548                    BX.create('DIV', {
5549                        props: {className: 'bx-soa-pp-price'},
5550                        children: this.getDeliveryPriceNodes(selectedDelivery)
5551                    })
5552                );
5553            } else
5554                node.appendChild(BX.create('STRONG', {text: BX.message('SOA_DELIVERY_SELECT_ERROR')}));
5555
5556            node.appendChild(BX.create('DIV', {style: {clear: 'both'}}));
5557            BX.bind(node.querySelector('.alert.alert-danger'), 'click', BX.proxy(this.showByClick, this));
5558            BX.bind(node.querySelector('.alert.alert-warning'), 'click', BX.proxy(this.showByClick, this));
5559        },
5560
5561        selectDelivery: function (event) {
5562            if (!this.orderBlockNode)
5563                return;
5564
5565            var target = event.target || event.srcElement,
5566                actionSection = BX.hasClass(target, 'bx-soa-pp-company') ? target : BX.findParent(target, {className: 'bx-soa-pp-company'}),
5567                selectedSection = this.deliveryBlockNode.querySelector('.bx-soa-pp-company.bx-selected'),
5568                actionInput, selectedInput;
5569
5570            if (BX.hasClass(actionSection, 'bx-selected')) {
5571                if (target.nodeName == "A") {
5572                    return;
5573                }
5574                return BX.PreventDefault(event);
5575            }
5576
5577            if (actionSection) {
5578                actionInput = actionSection.querySelector('input[type=checkbox]');
5579                BX.addClass(actionSection, 'bx-selected');
5580                actionInput.checked = true;
5581            }
5582            if (selectedSection) {
5583                selectedInput = selectedSection.querySelector('input[type=checkbox]');
5584                BX.removeClass(selectedSection, 'bx-selected');
5585                selectedInput.checked = false;
5586            }
5587
5588            this.sendRequest();
5589        },
5590
5591        getSelectedDelivery: function () {
5592            var deliveryCheckbox = this.deliveryBlockNode.querySelector('input[type=checkbox][name=DELIVERY_ID]:checked'),
5593                currentDelivery = false,
5594                deliveryId, i;
5595
5596            if (!deliveryCheckbox)
5597                deliveryCheckbox = this.deliveryHiddenBlockNode.querySelector('input[type=checkbox][name=DELIVERY_ID]:checked');
5598
5599            if (!deliveryCheckbox)
5600                deliveryCheckbox = this.deliveryHiddenBlockNode.querySelector('input[type=hidden][name=DELIVERY_ID]');
5601
5602            if (deliveryCheckbox) {
5603                deliveryId = deliveryCheckbox.value;
5604
5605                for (i in this.result.DELIVERY) {
5606                    if (this.result.DELIVERY[i].ID == deliveryId) {
5607                        currentDelivery = this.result.DELIVERY[i];
5608                        break;
5609                    }
5610                }
5611            }
5612
5613            return currentDelivery;
5614        },
5615
5616        activatePickUp: function (deliveryName) {
5617            if (!this.pickUpBlockNode || !this.pickUpHiddenBlockNode)
5618                return;
5619
5620            this.pickUpBlockNode.style.display = '';
5621            this.pickUpBlockNode.querySelector('h2.bx-soa-section-title .bx-soa-section-title-text').innerHTML =
5622                '<span class="bx-soa-section-title-count"></span>' + BX.util.htmlspecialchars(deliveryName);
5623
5624            if (BX.hasClass(this.pickUpBlockNode, 'bx-active'))
5625                return;
5626
5627            BX.addClass(this.pickUpBlockNode, 'bx-active');
5628            this.pickUpBlockNode.style.display = '';
5629        },
5630
5631        deactivatePickUp: function () {
5632            if (!this.pickUpBlockNode || !this.pickUpHiddenBlockNode)
5633                return;
5634
5635            if (!BX.hasClass(this.pickUpBlockNode, 'bx-active'))
5636                return;
5637
5638            BX.removeClass(this.pickUpBlockNode, 'bx-active');
5639            this.pickUpBlockNode.style.display = 'none';
5640        },
5641
5642        editPickUpBlock: function (active) {
5643            if (!this.pickUpBlockNode || !this.pickUpHiddenBlockNode || !BX.hasClass(this.pickUpBlockNode, 'bx-active') || !this.result.DELIVERY)
5644                return;
5645
5646            this.initialized.pickup = false;
5647
5648            if (active)
5649                this.editActivePickUpBlock(true);
5650            else
5651                this.editFadePickUpBlock();
5652
5653            this.initialized.pickup = true;
5654        },
5655
5656        editActivePickUpBlock: function (activeNodeMode) {
5657            var node = activeNodeMode ? this.pickUpBlockNode : this.pickUpHiddenBlockNode,
5658                pickUpContent, pickUpContentCol;
5659
5660            if (this.initialized.pickup) {
5661                if (
5662                    this.params.SHOW_NEAREST_PICKUP === 'Y'
5663                    && this.maps
5664                    && !this.maps.maxWaitTimeExpired
5665                ) {
5666                    this.maps.maxWaitTimeExpired = true;
5667                    this.initPickUpPagination();
5668                    this.editPickUpList(true);
5669                    this.pickUpFinalAction();
5670                }
5671
5672                if (this.maps && !this.pickUpMapFocused) {
5673                    this.pickUpMapFocused = true;
5674                    setTimeout(BX.proxy(this.maps.pickUpMapFocusWaiter, this.maps), 200);
5675                }
5676            } else {
5677                pickUpContent = node.querySelector('.bx-soa-section-content');
5678                if (!pickUpContent) {
5679                    pickUpContent = this.getNewContainer();
5680                    node.appendChild(pickUpContent);
5681                }
5682                BX.cleanNode(pickUpContent);
5683
5684                pickUpContentCol = BX.create('DIV', {});
5685                this.editPickUpMap(pickUpContentCol);
5686                this.editPickUpLoader(pickUpContentCol);
5687
5688                pickUpContent.appendChild(
5689                    BX.create('DIV', {
5690                        props: {className: 'bx_soa_pickup'},
5691                        children: [pickUpContentCol]
5692                    })
5693                );
5694
5695                if (this.params.SHOW_PICKUP_MAP != 'Y' || this.params.SHOW_NEAREST_PICKUP != 'Y') {
5696                    this.initPickUpPagination();
5697                    this.editPickUpList(true);
5698                    this.pickUpFinalAction();
5699                }
5700
5701                this.getBlockFooter(pickUpContent);
5702            }
5703        },
5704
5705        editFadePickUpBlock: function () {
5706            var pickUpContent = this.pickUpBlockNode.querySelector('.bx-soa-section-content'), newContent;
5707
5708            if (this.initialized.pickup) {
5709                this.pickUpHiddenBlockNode.appendChild(pickUpContent);
5710            } else {
5711                this.editActivePickUpBlock(false);
5712                BX.remove(BX.lastChild(this.pickUpBlockNode));
5713            }
5714
5715            newContent = this.getNewContainer();
5716            this.pickUpBlockNode.appendChild(newContent);
5717
5718            this.editFadePickUpContent(newContent);
5719        },
5720
5721        editFadePickUpContent: function (pickUpContainer) {
5722        },
5723
5724        getPickUpInfoArray: function (storeIds) {
5725            if (!storeIds || storeIds.length <= 0)
5726                return [];
5727
5728            var arr = [], i;
5729
5730            for (i = 0; i < storeIds.length; i++)
5731                if (this.result.STORE_LIST[storeIds[i]])
5732                    arr.push(this.result.STORE_LIST[storeIds[i]]);
5733
5734            return arr;
5735        },
5736
5737        getSelectedPickUp: function () {
5738            var pickUpInput = BX('BUYER_STORE'),
5739                currentPickUp, pickUpId,
5740                allStoresList = this.result.STORE_LIST,
5741                stores, i;
5742
5743            if (pickUpInput) {
5744                pickUpId = pickUpInput.value;
5745                currentPickUp = allStoresList[pickUpId];
5746
5747                if (!currentPickUp) {
5748                    stores = this.getSelectedDelivery().STORE;
5749                    if (stores) {
5750                        for (i in stores) {
5751                            if (stores.hasOwnProperty(i)) {
5752                                currentPickUp = allStoresList[stores[i]];
5753                                pickUpInput.setAttribute('value', stores[i]);
5754                                break;
5755                            }
5756                        }
5757                    }
5758                }
5759            }
5760
5761            return currentPickUp;
5762        },
5763
5764        /**
5765         * Checking delivery for pick ups. Displaying/hiding pick up block node.
5766         */
5767        checkPickUpShow: function () {
5768            var currentDelivery = this.getSelectedDelivery(), name, stores;
5769
5770            if (currentDelivery && currentDelivery.STORE && currentDelivery.STORE.length)
5771                stores = this.getPickUpInfoArray(currentDelivery.STORE);
5772
5773            if (stores && stores.length) {
5774                name = this.params.SHOW_DELIVERY_PARENT_NAMES != 'N' ? currentDelivery.NAME : currentDelivery.OWN_NAME;
5775                currentDelivery.STORE_MAIN = currentDelivery.STORE;
5776                this.activatePickUp(name);
5777                this.editSection(this.pickUpBlockNode);
5778            } else {
5779                this.deactivatePickUp();
5780            }
5781        },
5782
5783        geoLocationSuccessCallback: function (result) {
5784            var activeStores,
5785                currentDelivery = this.getSelectedDelivery();
5786
5787            if (currentDelivery && currentDelivery.STORE) {
5788                activeStores = this.getPickUpInfoArray(currentDelivery.STORE);
5789            }
5790
5791            if (activeStores && activeStores.length >= this.options.pickUpMap.minToShowNearestBlock) {
5792                this.editPickUpRecommendList(result.geoObjects.get(0));
5793            }
5794
5795            this.initPickUpPagination();
5796            this.editPickUpList(true);
5797            this.pickUpFinalAction();
5798        },
5799
5800        geoLocationFailCallback: function () {
5801            this.initPickUpPagination();
5802            this.editPickUpList(true);
5803            this.pickUpFinalAction();
5804        },
5805
5806        initMaps: function () {
5807            this.maps = BX.Sale.OrderAjaxComponent.Maps.init(this);
5808            if (this.maps) {
5809                this.mapsReady = true;
5810                this.resizeMapContainers();
5811
5812                if (this.params.SHOW_PICKUP_MAP === 'Y' && BX('pickUpMap')) {
5813                    var currentDelivery = this.getSelectedDelivery();
5814                    if (currentDelivery && currentDelivery.STORE && currentDelivery.STORE.length) {
5815                        var activeStores = this.getPickUpInfoArray(currentDelivery.STORE);
5816                    }
5817
5818                    if (activeStores && activeStores.length) {
5819                        var selected = this.getSelectedPickUp();
5820                        this.maps.initializePickUpMap(selected);
5821
5822                        if (this.params.SHOW_NEAREST_PICKUP === 'Y') {
5823                            this.maps.showNearestPickups(BX.proxy(this.geoLocationSuccessCallback, this), BX.proxy(this.geoLocationFailCallback, this));
5824                        }
5825
5826                        this.maps.buildBalloons(activeStores);
5827                    }
5828                }
5829
5830                if (this.params.SHOW_MAP_IN_PROPS === 'Y' && BX('propsMap')) {
5831                    var propsMapData = this.getPropertyMapData();
5832                    this.maps.initializePropsMap(propsMapData);
5833                }
5834            }
5835        },
5836
5837        getPropertyMapData: function () {
5838            var currentProperty, locationId, k;
5839            var data = this.options.propertyMap.defaultMapPosition;
5840
5841            for (k in this.result.ORDER_PROP.properties) {
5842                if (this.result.ORDER_PROP.properties.hasOwnProperty(k)) {
5843                    currentProperty = this.result.ORDER_PROP.properties[k];
5844                    if (currentProperty.IS_LOCATION == 'Y') {
5845                        locationId = currentProperty.ID;
5846                        break;
5847                    }
5848                }
5849            }
5850
5851            if (this.locations[locationId] && this.locations[locationId][0] && this.locations[locationId][0].coordinates) {
5852                currentProperty = this.locations[locationId][0].coordinates;
5853
5854                var long = parseFloat(currentProperty.LONGITUDE),
5855                    lat = parseFloat(currentProperty.LATITUDE);
5856
5857                if (!isNaN(long) && !isNaN(lat) && long != 0 && lat != 0) {
5858                    data.lon = long;
5859                    data.lat = lat;
5860                }
5861            }
5862
5863            return data;
5864        },
5865
5866        resizeMapContainers: function () {
5867            var pickUpMapContainer = BX('pickUpMap'),
5868                propertyMapContainer = BX('propsMap'),
5869                resizeBy = this.propsBlockNode,
5870                width, height;
5871
5872            if (resizeBy && (pickUpMapContainer || propertyMapContainer)) {
5873                width = resizeBy.clientWidth;
5874                height = parseInt(width / 16 * 9);
5875
5876                if (this.params.SHOW_PICKUP_MAP === 'Y' && pickUpMapContainer) {
5877                    pickUpMapContainer.style.height = height + 'px';
5878                }
5879
5880                if (this.params.SHOW_MAP_IN_PROPS === 'Y' && propertyMapContainer) {
5881                    propertyMapContainer.style.height = height + 'px';
5882                }
5883            }
5884        },
5885
5886        editPickUpMap: function (pickUpContent) {
5887            pickUpContent.appendChild(BX.create('DIV', {
5888                props: {id: 'pickUpMap'},
5889                style: {width: '100%', marginBottom: '10px'}
5890            }));
5891        },
5892
5893        editPickUpLoader: function (pickUpContent) {
5894            pickUpContent.appendChild(
5895                BX.create('DIV', {
5896                    props: {id: 'pickUpLoader', className: 'text-center'},
5897                    children: [BX.create('IMG', {props: {src: this.imgFolder + '/loader.gif'}})]
5898                })
5899            );
5900        },
5901
5902        editPickUpList: function (isNew) {
5903            if (!this.pickUpPagination.currentPage || !this.pickUpPagination.currentPage.length)
5904                return;
5905
5906            BX.remove(BX('pickUpLoader'));
5907
5908            var pickUpList = BX.create('DIV', {props: {className: 'bx-soa-pickup-list main'}}),
5909                buyerStoreInput = BX('BUYER_STORE'),
5910                selectedStore,
5911                container, i, found = false,
5912                recommendList, selectedDelivery, currentStore, storeNode;
5913
5914            if (buyerStoreInput)
5915                selectedStore = buyerStoreInput.value;
5916
5917            recommendList = this.pickUpBlockNode.querySelector('.bx-soa-pickup-list.recommend');
5918            if (!recommendList)
5919                recommendList = this.pickUpHiddenBlockNode.querySelector('.bx-soa-pickup-list.recommend');
5920
5921            if (!recommendList || !recommendList.querySelector('.bx-soa-pickup-list-item.bx-selected')) {
5922                selectedDelivery = this.getSelectedDelivery();
5923                if (selectedDelivery && selectedDelivery.STORE) {
5924                    for (i = 0; i < selectedDelivery.STORE.length; i++)
5925                        if (selectedDelivery.STORE[i] == selectedStore)
5926                            found = true;
5927                }
5928            } else
5929                found = true;
5930
5931            for (i = 0; i < this.pickUpPagination.currentPage.length; i++) {
5932                currentStore = this.pickUpPagination.currentPage[i];
5933
5934                if (currentStore.ID == selectedStore || parseInt(selectedStore) == 0 || !found) {
5935                    selectedStore = buyerStoreInput.value = currentStore.ID;
5936                    found = true;
5937                }
5938
5939                storeNode = this.createPickUpItem(currentStore, {selected: currentStore.ID == selectedStore});
5940                pickUpList.appendChild(storeNode);
5941            }
5942
5943            if (!!isNew) {
5944                container = this.pickUpHiddenBlockNode.querySelector('.bx_soa_pickup>div');
5945                if (!container)
5946                    container = this.pickUpBlockNode.querySelector('.bx_soa_pickup>div');
5947
5948                container.appendChild(
5949                    BX.create('DIV', {
5950                        props: {className: 'bx-soa-pickup-subTitle'},
5951                        html: this.params.MESS_PICKUP_LIST
5952                    })
5953                );
5954                container.appendChild(pickUpList);
5955            } else {
5956                container = this.pickUpBlockNode.querySelector('.bx-soa-pickup-list.main');
5957                BX.insertAfter(pickUpList, container);
5958                BX.remove(container);
5959            }
5960
5961            this.pickUpPagination.show && this.showPagination('pickUp', pickUpList);
5962        },
5963
5964        pickUpFinalAction: function () {
5965            var selectedDelivery = this.getSelectedDelivery(),
5966                deliveryChanged;
5967
5968            if (selectedDelivery) {
5969                deliveryChanged = this.lastSelectedDelivery !== parseInt(selectedDelivery.ID);
5970                this.lastSelectedDelivery = parseInt(selectedDelivery.ID);
5971            }
5972
5973            if (deliveryChanged && this.pickUpBlockNode.id !== this.activeSectionId) {
5974                if (this.pickUpBlockNode.id !== this.activeSectionId) {
5975                    this.editFadePickUpContent(BX.lastChild(this.pickUpBlockNode));
5976                }
5977
5978                BX.removeClass(this.pickUpBlockNode, 'bx-step-completed');
5979            }
5980
5981            this.maps && this.maps.pickUpFinalAction();
5982        },
5983
5984        getStoreInfoHtml: function (currentStore) {
5985            var html = '';
5986
5987            if (currentStore.ADDRESS)
5988                html += BX.message('SOA_PICKUP_ADDRESS') + ': ' + BX.util.htmlspecialchars(currentStore.ADDRESS) + '<br>';
5989
5990            if (currentStore.PHONE)
5991                html += BX.message('SOA_PICKUP_PHONE') + ': ' + BX.util.htmlspecialchars(currentStore.PHONE) + '<br>';
5992
5993            if (currentStore.SCHEDULE)
5994                html += BX.message('SOA_PICKUP_WORK') + ': ' + BX.util.htmlspecialchars(currentStore.SCHEDULE) + '<br>';
5995
5996            if (currentStore.DESCRIPTION)
5997                html += BX.message('SOA_PICKUP_DESC') + ': ' + BX.util.htmlspecialchars(currentStore.DESCRIPTION) + '<br>';
5998
5999            return html;
6000        },
6001
6002        createPickUpItem: function (currentStore, options) {
6003            options = options || {};
6004
6005            var imgClassName = 'bx-soa-pickup-l-item-detail',
6006                buttonClassName = 'bx-soa-pickup-l-item-btn',
6007                logoNode, logotype, html, storeNode, imgSrc;
6008
6009            if (this.params.SHOW_STORES_IMAGES === 'Y') {
6010                logotype = this.getImageSources(currentStore, 'IMAGE_ID');
6011                imgSrc = logotype && logotype.src_1x || this.defaultStoreLogo;
6012                logoNode = BX.create('IMG', {
6013                    props: {
6014                        src: imgSrc,
6015                        className: 'bx-soa-pickup-l-item-img'
6016                    },
6017                    events: {
6018                        click: BX.delegate(function (e) {
6019                            this.popupShow(e, logotype && logotype.src_orig || imgSrc);
6020                        }, this)
6021                    }
6022                });
6023            } else {
6024                imgClassName += ' no-image';
6025                buttonClassName += ' no-image';
6026            }
6027
6028            html = this.getStoreInfoHtml(currentStore);
6029            storeNode = BX.create('DIV', {
6030                props: {className: 'bx-soa-pickup-list-item', id: 'store-' + currentStore.ID},
6031                children: [
6032                    BX.create('DIV', {
6033                        props: {className: 'bx-soa-pickup-l-item-adress'},
6034                        children: options.distance ? [
6035                            BX.util.htmlspecialchars(currentStore.ADDRESS),
6036                            ' ( ~' + options.distance + ' ' + BX.message('SOA_DISTANCE_KM') + ' ) '
6037                        ] : [BX.util.htmlspecialchars(currentStore.ADDRESS)]
6038                    }),
6039                    BX.create('DIV', {
6040                        props: {className: imgClassName},
6041                        children: [
6042                            logoNode,
6043                            BX.create('DIV', {
6044                                props: {className: 'bx-soa-pickup-l-item-name'},
6045                                text: currentStore.TITLE
6046                            }),
6047                            BX.create('DIV', {props: {className: 'bx-soa-pickup-l-item-desc'}, html: html})
6048                        ]
6049                    }),
6050                    BX.create('DIV', {
6051                        props: {className: buttonClassName},
6052                        children: [
6053                            BX.create('A', {
6054                                props: {href: 'javascript:void(0);', className: 'btn btn-default'},
6055                                html: this.params.MESS_SELECT_PICKUP,
6056                                events: {
6057                                    click: BX.delegate(function (event) {
6058                                        this.selectStore(event);
6059                                        this.clickNextAction(event)
6060                                    }, this)
6061                                }
6062                            })
6063                        ]
6064                    })
6065                ],
6066                events: {
6067                    click: BX.proxy(this.selectStore, this)
6068                }
6069            });
6070
6071            if (options.selected)
6072                BX.addClass(storeNode, 'bx-selected');
6073
6074            return storeNode;
6075        },
6076
6077        editPickUpRecommendList: function (geoLocation) {
6078            if (!this.maps || !this.maps.canUseRecommendList() || !geoLocation) {
6079                return;
6080            }
6081
6082            BX.remove(BX('pickUpLoader'));
6083
6084            var recommendList = BX.create('DIV', {props: {className: 'bx-soa-pickup-list recommend'}}),
6085                buyerStoreInput = BX('BUYER_STORE'),
6086                selectedDelivery = this.getSelectedDelivery();
6087
6088            var i, currentStore, currentStoreId, distance, storeNode, container;
6089
6090            var recommendedStoreIds = this.maps.getRecommendedStoreIds(geoLocation);
6091            for (i = 0; i < recommendedStoreIds.length; i++) {
6092                currentStoreId = recommendedStoreIds[i];
6093                currentStore = this.getPickUpInfoArray([currentStoreId])[0];
6094
6095                if (i === 0 && parseInt(selectedDelivery.ID) !== this.lastSelectedDelivery) {
6096                    buyerStoreInput.value = parseInt(currentStoreId);
6097                }
6098
6099                distance = this.maps.getDistance(geoLocation, currentStoreId);
6100                storeNode = this.createPickUpItem(currentStore, {
6101                    selected: buyerStoreInput.value === currentStoreId,
6102                    distance: distance
6103                });
6104                recommendList.appendChild(storeNode);
6105
6106                if (selectedDelivery.STORE_MAIN) {
6107                    selectedDelivery.STORE_MAIN.splice(selectedDelivery.STORE_MAIN.indexOf(currentStoreId), 1);
6108                }
6109            }
6110
6111            container = this.pickUpHiddenBlockNode.querySelector('.bx_soa_pickup>div');
6112            if (!container) {
6113                container = this.pickUpBlockNode.querySelector('.bx_soa_pickup>div');
6114            }
6115
6116            container.appendChild(
6117                BX.create('DIV', {
6118                    props: {className: 'bx-soa-pickup-subTitle'},
6119                    html: this.params.MESS_NEAREST_PICKUP_LIST
6120                })
6121            );
6122            container.appendChild(recommendList);
6123        },
6124
6125        selectStore: function (event) {
6126            var storeItem,
6127                storeInput = BX('BUYER_STORE'),
6128                selectedPickUp, storeItemId, i, k, page,
6129                target, h1, h2;
6130
6131            if (BX.type.isString(event)) {
6132                storeItem = BX('store-' + event);
6133                if (!storeItem) {
6134                    for (i = 0; i < this.pickUpPagination.pages.length; i++) {
6135                        page = this.pickUpPagination.pages[i];
6136                        for (k = 0; k < page.length; k++) {
6137                            if (page[k].ID == event) {
6138                                this.showPickUpItemsPage(++i);
6139                                break;
6140                            }
6141                        }
6142                    }
6143                    storeItem = BX('store-' + event);
6144                }
6145            } else {
6146                target = event.target || event.srcElement;
6147                storeItem = BX.hasClass(target, 'bx-soa-pickup-list-item')
6148                    ? target
6149                    : BX.findParent(target, {className: 'bx-soa-pickup-list-item'});
6150            }
6151
6152            if (storeItem && storeInput) {
6153                if (BX.hasClass(storeItem, 'bx-selected'))
6154                    return;
6155
6156                selectedPickUp = this.pickUpBlockNode.querySelector('.bx-selected');
6157                storeItemId = storeItem.id.substr('store-'.length);
6158
6159                BX.removeClass(selectedPickUp, 'bx-selected');
6160
6161                h1 = storeItem.clientHeight;
6162                storeItem.style.overflow = 'hidden';
6163                BX.addClass(storeItem, 'bx-selected');
6164                h2 = storeItem.clientHeight;
6165                storeItem.style.height = h1 + 'px';
6166
6167                new BX.easing({
6168                    duration: 300,
6169                    start: {height: h1, opacity: 0},
6170                    finish: {height: h2, opacity: 100},
6171                    transition: BX.easing.transitions.quad,
6172                    step: function (state) {
6173                        storeItem.style.height = state.height + "px";
6174                    },
6175                    complete: function () {
6176                        storeItem.removeAttribute('style');
6177                    }
6178                }).animate();
6179
6180                storeInput.setAttribute('value', storeItemId);
6181                this.maps && this.maps.selectBalloon(storeItemId);
6182            }
6183        },
6184
6185        getDeliverySortedArray: function (objDelivery) {
6186            var deliveries = [],
6187                delivery_sort = this.params.ORDER_DELIVERY_SORT,
6188                problemDeliveries = [],
6189                sortFunc = function (a, b) {
6190                    var sort = parseInt(a.SORT) - parseInt(b.SORT);
6191                    if (sort === 0) {
6192                        return a.OWN_NAME.toLowerCase() > b.OWN_NAME.toLowerCase()
6193                            ? 1
6194                            : (a.OWN_NAME.toLowerCase() < b.OWN_NAME.toLowerCase() ? -1 : 0);
6195                    } else {
6196                        return sort;
6197                    }
6198                },
6199                sortFuncByPrice = function (a, b) {
6200                    var sort;
6201                    if (delivery_sort == "PRICE_DESC")
6202                        sort = parseInt(b.PRICE) - parseInt(a.PRICE);
6203                    else
6204                        sort = parseInt(a.PRICE) - parseInt(b.PRICE);
6205                    if (sort === 0) {
6206                        return a.OWN_NAME.toLowerCase() > b.OWN_NAME.toLowerCase()
6207                            ? 1
6208                            : (a.OWN_NAME.toLowerCase() < b.OWN_NAME.toLowerCase() ? -1 : 0);
6209                    } else {
6210                        return sort;
6211                    }
6212                },
6213                k;
6214
6215            for (k in objDelivery) {
6216                if (objDelivery.hasOwnProperty(k)) {
6217                    if (this.params.SHOW_NOT_CALCULATED_DELIVERIES === 'L' && objDelivery[k].CALCULATE_ERRORS) {
6218                        problemDeliveries.push(objDelivery[k]);
6219                    } else {
6220                        deliveries.push(objDelivery[k]);
6221                    }
6222                }
6223            }
6224
6225            deliveries.sort(
6226                this.params.DELIVERY_NO_AJAX == "Y" ?
6227                    (delivery_sort !== "SORT" ? sortFuncByPrice : sortFunc) : sortFunc
6228            );
6229            problemDeliveries.sort(sortFunc);
6230
6231            return deliveries.concat(problemDeliveries);
6232        },
6233
6234        editPropsBlock: function (active) {
6235            if (!this.propsBlockNode || !this.propsHiddenBlockNode || !this.result.ORDER_PROP)
6236                return;
6237
6238            if (active)
6239                this.editActivePropsBlock(true);
6240            else
6241                this.editFadePropsBlock();
6242
6243            this.initialized.props = true;
6244        },
6245
6246        editActivePropsBlock: function (activeNodeMode) {
6247            var node = activeNodeMode ? this.propsBlockNode : this.propsHiddenBlockNode,
6248                propsContent, propsNode, selectedDelivery, showPropM
6248ap = false, i, validationErrors;
6249
6250            if (this.initialized.props) {
6251                this.maps && setTimeout(BX.proxy(this.maps.propsMapFocusWaiter, this.maps), 200);
6252            } else {
6253                propsContent = node.querySelector('.bx-soa-section-content');
6254                if (!propsContent) {
6255                    propsContent = this.getNewContainer();
6256                    node.appendChild(propsContent);
6257                } else
6258                    BX.cleanNode(propsContent);
6259
6260                this.getErrorContainer(propsContent);
6261
6262                propsNode = BX.create('DIV', {});
6263                selectedDelivery = this.getSelectedDelivery();
6264
6265                if (
6266                    selectedDelivery && this.params.SHOW_MAP_IN_PROPS === 'Y'
6267                    && this.params.SHOW_MAP_FOR_DELIVERIES && this.params.SHOW_MAP_FOR_DELIVERIES.length
6268                ) {
6269                    for (i = 0; i < this.params.SHOW_MAP_FOR_DELIVERIES.length; i++) {
6270                        if (parseInt(selectedDelivery.ID) === parseInt(this.params.SHOW_MAP_FOR_DELIVERIES[i])) {
6271                            showPropMap = true;
6272                            break;
6273                        }
6274                    }
6275                }
6276
6277                this.editPropsItems(propsNode);
6278                showPropMap && this.editPropsMap(propsNode);
6279
6280                if (this.params.HIDE_ORDER_DESCRIPTION !== 'Y') {
6281                    this.editPropsComment(propsNode);
6282                }
6283
6284                propsContent.appendChild(propsNode);
6285                this.getBlockFooter(propsContent);
6286            }
6287        },
6288
6289        editFadePropsBlock: function () {
6290            var propsContent = this.propsBlockNode.querySelector('.bx-soa-section-content'), newContent;
6291
6292            if (this.initialized.props) {
6293                this.propsHiddenBlockNode.appendChild(propsContent);
6294            } else {
6295                this.editActivePropsBlock(false);
6296                BX.remove(BX.lastChild(this.propsBlockNode));
6297            }
6298
6299            newContent = this.getNewContainer();
6300            this.propsBlockNode.appendChild(newContent);
6301
6302            this.editFadePropsContent(newContent);
6303        },
6304
6305        editFadePropsContent: function (node) {
6306            if (!node || !this.locationsInitialized)
6307                return;
6308
6309            var errorNode = this.propsHiddenBlockNode.querySelector('.alert'),
6310                personType = this.getSelectedPersonType(),
6311                fadeParamName, props,
6312                group, property, groupIterator, propsIterator, i, validPropsErrors;
6313
6314            BX.cleanNode(node);
6315
6316            if (errorNode)
6317                node.appendChild(errorNode.cloneNode(true));
6318
6319            if (personType) {
6320                fadeParamName = 'PROPS_FADE_LIST_' + personType.ID;
6321                props = this.params[fadeParamName];
6322            }
6323
6324            if (!props || props.length === 0) {
6325                node.innerHTML += '<strong>' + BX.message('SOA_ORDER_PROPS') + '</strong>';
6326            } else {
6327                groupIterator = this.fadedPropertyCollection.getGroupIterator();
6328                while (group = groupIterator()) {
6329                    propsIterator = group.getIterator();
6330                    while (property = propsIterator()) {
6331                        for (i = 0; i < props.length; i++)
6332                            if (props[i] == property.getId() && property.getSettings()['IS_ZIP'] != 'Y')
6333                                this.getPropertyRowNode(property, node, true);
6334                    }
6335                }
6336            }
6337
6338            if (this.propsBlockNode.getAttribute('data-visited') === 'true') {
6339                validPropsErrors = this.isValidPropertiesBlock();
6340                if (validPropsErrors.length)
6341                    this.showError(this.propsBlockNode, validPropsErrors);
6342            }
6343
6344            BX.bind(node.querySelector('.alert.alert-danger'), 'click', BX.proxy(this.showByClick, this));
6345            BX.bind(node.querySelector('.alert.alert-warning'), 'click', BX.proxy(this.showByClick, this));
6346        },
6347
6348        editPropsItems: function (propsNode) {
6349            if (!this.result.ORDER_PROP || !this.propertyCollection)
6350                return;
6351
6352            var propsItemsContainer = BX.create('DIV', {props: {className: 'bx-soa-customer'}}),
6353                group, property, groupIterator = this.propertyCollection.getGroupIterator(), propsIterator;
6354
6355            if (!propsItemsContainer)
6356                propsItemsContainer = this.propsBlockNode.querySelector('.bx-soa-customer');
6357
6358            while (group = groupIterator()) {
6359                propsIterator = group.getIterator();
6360                while (property = propsIterator()) {
6361                    if (
6362                        this.deliveryLocationInfo.loc == property.getId()
6363                        || this.deliveryLocationInfo.zip == property.getId()
6364                        || this.deliveryLocationInfo.city == property.getId()
6365                    )
6366                        continue;
6367
6368                    this.getPropertyRowNode(property, propsItemsContainer, false);
6369                }
6370            }
6371
6372            propsNode.appendChild(propsItemsContainer);
6373        },
6374
6375        getPropertyRowNode: function (property, propsItemsContainer, disabled) {
6376            var propsItemNode = BX.create('DIV'),
6377                textHtml = '',
6378                propertyType = property.getType() || '',
6379                propertyDesc = property.getDescription() || '',
6380                label;
6381
6382            if (disabled) {
6383                propsItemNode.innerHTML = '<strong>' + BX.util.htmlspecialchars(property.getName()) + ':</strong> ';
6384            } else {
6385                BX.addClass(propsItemNode, "tanais-form-group bx-soa-customer-field");
6386
6387                if (property.isRequired())
6388                    textHtml += '<span class="bx-authform-starrequired">*</span> ';
6389
6390                textHtml += BX.util.htmlspecialchars(property.getName());
6391                if (propertyDesc.length && propertyType != 'STRING' && propertyType != 'NUMBER' && propertyType != 'DATE')
6392                    textHtml += ' <small>(' + BX.util.htmlspecialchars(propertyDesc) + ')</small>';
6393
6394                label = BX.create('LABEL', {
6395                    attrs: {'for': 'soa-property-' + property.getId()},
6396                    props: {className: 'bx-soa-custom-label'},
6397                    html: textHtml
6398                });
6399                propsItemNode.setAttribute('data-property-id-row', property.getId());
6400                propsItemNode.appendChild(label);
6401            }
6402
6403            switch (propertyType) {
6404                case 'LOCATION':
6405                    this.insertLocationProperty(property, propsItemNode, disabled);
6406                    break;
6407                case 'DATE':
6408                    this.insertDateProperty(property, propsItemNode, disabled);
6409                    break;
6410                case 'FILE':
6411                    this.insertFileProperty(property, propsItemNode, disabled);
6412                    break;
6413                case 'STRING':
6414                    this.insertStringProperty(property, propsItemNode, disabled);
6415                    break;
6416                case 'ENUM':
6417                    this.insertEnumProperty(property, propsItemNode, disabled);
6418                    break;
6419                case 'Y/N':
6420                    this.insertYNProperty(property, propsItemNode, disabled);
6421                    break;
6422                case 'NUMBER':
6423                    this.insertNumberProperty(property, propsItemNode, disabled);
6424            }
6425
6426            propsItemsContainer.appendChild(propsItemNode);
6427        },
6428
6429        insertLocationProperty: function (property, propsItemNode, disabled) {
6430            var propRow, propNodes, locationString, currentLocation, insertedLoc, propContainer, i, k, values = [];
6431
6432            if (property.getId() in this.locations) {
6433                if (disabled) {
6434                    propRow = this.propsHiddenBlockNode.querySelector('[data-property-id-row="' + property.getId() + '"]');
6435                    if (propRow) {
6436                        propNodes = propRow.querySelectorAll('div.bx-soa-loc');
6437                        for (i = 0; i < propNodes.length; i++) {
6438                            locationString = this.getLocationString(propNodes[i]);
6439                            values.push(locationString.length ? BX.util.htmlspecialchars(locationString) : BX.message('SOA_NOT_SELECTED'));
6440                        }
6441                    }
6442                    propsItemNode.innerHTML += values.join('<br>');
6443                } else {
6444                    propContainer = BX.create('DIV', {props: {className: 'soa-property-container'}});
6445                    propRow = this.locations[property.getId()];
6446                    for (i = 0; i < propRow.length; i++) {
6447                        currentLocation = propRow[i] ? propRow[i].output : {};
6448                        insertedLoc = BX.create('DIV', {props: {className: 'bx-soa-loc'}, html: currentLocation.HTML});
6449
6450                        if (property.isMultiple())
6451                            insertedLoc.style.marginBottom = this.locationsTemplate == 'search' ? '5px' : '20px';
6452
6453                        propContainer.appendChild(insertedLoc);
6454
6455                        for (k in currentLocation.SCRIPT) {
6456                            if (currentLocation.SCRIPT.hasOwnProperty(k))
6457                                BX.evalGlobal(currentLocation.SCRIPT[k].JS);
6458                        }
6459                    }
6460
6461                    if (property.isMultiple()) {
6462                        propContainer.appendChild(
6463                            BX.create('DIV', {
6464                                attrs: {'data-prop-id': property.getId()},
6465                                props: {className: 'btn btn-default'},
6466                                text: BX.message('ADD_DEFAULT'),
6467                                events: {
6468                                    click: BX.proxy(this.addLocationProperty, this)
6469                                }
6470                            })
6471                        );
6472                    }
6473
6474                    propsItemNode.appendChild(propContainer);
6475                }
6476            }
6477        },
6478
6479        addLocationProperty: function (e) {
6480            var target = e.target || e.srcElement,
6481                propId = target.getAttribute('data-prop-id'),
6482                lastProp = BX.previousSibling(target),
6483                insertedLoc, k, input, index = 0,
6484                prefix = 'sls-',
6485                randomStr = BX.util.getRandomString(5);
6486
6487            if (BX.hasClass(lastProp, 'bx-soa-loc')) {
6488                if (this.locationsTemplate == 'search') {
6489                    input = lastProp.querySelector('input[type=text][class=dropdown-field]');
6490                    if (input)
6491                        index = parseInt(input.name.substring(input.name.indexOf('[') + 1, input.name.indexOf(']'))) + 1;
6492                } else {
6493                    input = lastProp.querySelectorAll('input[type=hidden]');
6494                    if (input.length) {
6495                        input = input[input.length - 1];
6496                        index = parseInt(input.name.substring(input.name.indexOf('[') + 1, input.name.indexOf(']'))) + 1;
6497                    }
6498                }
6499            }
6500
6501            if (this.cleanLocations[propId]) {
6502                insertedLoc = BX.create('DIV', {
6503                    props: {className: 'bx-soa-loc'},
6504                    style: {marginBottom: this.locationsTemplate == 'search' ? '5px' : '20px'},
6505                    html: this.cleanLocations[propId].HTML.split('#key#').join(index).replace(/sls-\d{5}/g, prefix + randomStr)
6506                });
6507                target.parentNode.insertBefore(insertedLoc, target);
6508
6509                BX.saleOrderAjax.addPropertyDesc({
6510                    id: propId + '_' + index,
6511                    attributes: {
6512                        id: propId + '_' + index,
6513                        type: 'LOCATION',
6514                        valueSource: 'form'
6515                    }
6516                });
6517
6518
6519                for (k in this.cleanLocations[propId].SCRIPT)
6520                    if (this.cleanLocations[propId].SCRIPT.hasOwnProperty(k))
6521                        BX.evalGlobal(this.cleanLocations[propId].SCRIPT[k].JS.split('_key__').join('_' + index).replace(/sls-\d{5}/g, prefix + randomStr));
6522
6523                BX.saleOrderAjax.initDeferredControl();
6524            }
6525        },
6526
6527        insertDateProperty: function (property, propsItemNode, disabled) {
6528            var prop, dateInputs, values, i,
6529                propContainer, inputText;
6530
6531            if (disabled) {
6532                prop = this.propsHiddenBlockNode.querySelector('div[data-property-id-row="' + property.getId() + '"]');
6533                if (prop) {
6534                    values = [];
6535                    dateInputs = prop.querySelectorAll('input[type=text]');
6536
6537                    for (i = 0; i < dateInputs.length; i++)
6538                        if (dateInputs[i].value && dateInputs[i].value.length)
6539                            values.push(dateInputs[i].value);
6540
6541                    propsItemNode.innerHTML += this.valuesToString(values);
6542                }
6543            } else {
6544                propContainer = BX.create('DIV', {props: {className: 'soa-property-container'}});
6545                property.appendTo(propContainer);
6546                propsItemNode.appendChild(propContainer);
6547                inputText = propContainer.querySelectorAll('input[type=text]');
6548
6549                for (i = 0; i < inputText.length; i++)
6550                    this.alterDateProperty(property.getSettings(), inputText[i]);
6551
6552                this.alterProperty(property.getSettings(), propContainer);
6553                this.bindValidation(property.getId(), propContainer);
6554            }
6555        },
6556
6557        insertFileProperty: function (property, propsItemNode, disabled) {
6558            var prop, fileLinks, values, i, html,
6559                saved, propContainer;
6560
6561            if (disabled) {
6562                prop = this.propsHiddenBlockNode.querySelector('div[data-property-id-row="' + property.getId() + '"]');
6563                if (prop) {
6564                    values = [];
6565                    fileLinks = prop.querySelectorAll('a');
6566
6567                    for (i = 0; i < fileLinks.length; i++) {
6568                        html = fileLinks[i].innerHTML;
6569                        if (html.length)
6570                            values.push(html);
6571                    }
6572
6573                    propsItemNode.innerHTML += this.valuesToString(values);
6574                }
6575            } else {
6576                saved = this.savedFilesBlockNode.querySelector('div[data-property-id-row="' + property.getId() + '"]');
6577                if (saved)
6578                    propContainer = saved.querySelector('div.soa-property-container');
6579
6580                if (propContainer)
6581                    propsItemNode.appendChild(propContainer);
6582                else {
6583                    propContainer = BX.create('DIV', {props: {className: 'soa-property-container'}});
6584                    property.appendTo(propContainer);
6585                    propsItemNode.appendChild(propContainer);
6586                    this.alterProperty(property.getSettings(), propContainer);
6587                }
6588            }
6589        },
6590
6591        insertStringProperty: function (property, propsItemNode, disabled) {
6592            var prop, inputs, values, i, propContainer;
6593
6594            if (disabled) {
6595                prop = this.propsHiddenBlockNode.querySelector('div[data-property-id-row="' + property.getId() + '"]');
6596                if (prop) {
6597                    values = [];
6598                    inputs = prop.querySelectorAll('input[type=text]');
6599                    if (inputs.length == 0)
6600                        inputs = prop.querySelectorAll('textarea');
6601
6602                    if (inputs.length) {
6603                        for (i = 0; i < inputs.length; i++) {
6604                            if (inputs[i].value.length)
6605                                values.push(inputs[i].value);
6606                        }
6607                    }
6608
6609                    propsItemNode.innerHTML += this.valuesToString(values);
6610                }
6611            } else {
6612                propContainer = BX.create('DIV', {props: {className: 'soa-property-container'}});
6613                property.appendTo(propContainer);
6614
6615                var propSettings = property.getSettings();
6616
6617                if (
6618                    this.params.USE_LEGAL_ENTITY_AUTOLOAD_DATA == "Y" &&
6619                    this.params.AUTOLOAD_LEGAL_INN.length > 0 &&
6620                    this.params.AUTOLOAD_LEGAL_INN == propSettings["CODE"]
6621                ) {
6622                    BX.addClass(propContainer, "has-soa-action-button");
6623
6624                    propContainer.appendChild(
6625                        BX.create('A', {
6626                            props: {
6627                                className: 'btn btn-default js-inn-autoload-btn' // Класс кнопки
6628                            },
6629                            html: this.params.MESS_AUTOLOAD_LEGAL_INN_BTN,
6630                            events: {
6631                                click: BX.proxy(this.autoLoadLegalDataByINN, this) // Привязка события
6632                            }
6633                        })
6634                    );
6635                }
6636
6637                if (
6638                    this.params.USE_COMPANY_AUTOCOMPLETE == "Y" &&
6639                    this.params.AUTOLOAD_LEGAL_COMPANY.length > 0 &&
6640                    this.params.AUTOLOAD_LEGAL_COMPANY == propSettings["CODE"]
6641                ) {
6642                    BX.addClass(propContainer, "has-soa-company-suggest");
6643
6644                    propContainer.appendChild(
6645                        BX.create('SPAN', {
6646                            props: {
6647                                className: 'soa-suggests-company-container'
6648                            },
6649                            children: [
6650                                BX.create('SPAN', {
6651                                    props: {
6652                                        className: 'soa-suggests-company-block'
6653                                    }
6654                                })
6655                            ]
6656                        })
6657                    );
6658
6659                    property.addEvent("input", this.autocompleteCompany);
6660                    property.addEvent("blur", function (e) {
6661                        $(this).next(".soa-suggests-company-container").fadeOut();
6662                    });
6663                    property.addEvent("focus", function (e) {
6664                        var _sc = $(this).next(".soa-suggests-company-container");
6665                        var _scb = _sc.find(".soa-suggests-company-block");
6666                        if (_scb.length > 0 && _scb.html() !== "") {
6667                            _sc.fadeIn();
6668                        }
6669                    });
6670                }
6671
6672                if (
6673                    this.params.USE_ADDR_AUTOCOMPLATE == "Y" &&
6674                    this.params.AUTOCOMPLATE_ADDR.length > 0 &&
6675                    this.params.AUTOCOMPLATE_ADDR == propSettings["CODE"]
6676                ) {
6677                    BX.addClass(propContainer, "has-soa-address-suggest");
6678
6679                    propContainer.appendChild(
6680                        BX.create('SPAN', {
6681                            props: {
6682                                className: 'soa-suggests-container'
6683                            },
6684                            children: [
6685                                BX.create('SPAN', {
6686                                    props: {
6687                                        className: 'soa-suggests-block'
6688                                    }
6689                                })
6690                            ]
6691                        })
6692                    );
6693
6694                    property.addEvent("input", this.autocompleteAddr);
6695                    property.addEvent("blur", function (e) {
6696                        $(this).next(".soa-suggests-container").fadeOut();
6697                    });
6698                    property.addEvent("focus", function (e) {
6699                        var _sc = $(this).next(".soa-suggests-container");
6700                        var _scb = _sc.find(".soa-suggests-block");
6701                        if (_scb.length > 0 && _scb.html() !== "") {
6702                            _sc.fadeIn();
6703                        }
6704                    });
6705                }
6706
6707                propsItemNode.appendChild(propContainer);
6708
6709                this.alterProperty(property.getSettings(), propContainer);
6710                this.bindValidation(property.getId(), propContainer);
6711            }
6712        },
6713
6714        insertEnumProperty: function (property, propsItemNode, disabled) {
6715            var prop, inputs, values, i, propContainer;
6716
6717            if (disabled) {
6718                prop = this.propsHiddenBlockNode.querySelector('div[data-property-id-row="' + property.getId() + '"]');
6719                if (prop) {
6720                    values = [];
6721                    inputs = prop.querySelectorAll('input[type=radio]');
6722                    if (inputs.length) {
6723                        for (i = 0; i < inputs.length; i++) {
6724                            if (inputs[i].checked)
6725                                values.push(inputs[i].nextSibling.nodeValue);
6726                        }
6727                    }
6728                    inputs = prop.querySelectorAll('option');
6729                    if (inputs.length) {
6730                        for (i = 0; i < inputs.length; i++) {
6731                            if (inputs[i].selected)
6732                                values.push(inputs[i].innerHTML);
6733                        }
6734                    }
6735
6736                    propsItemNode.innerHTML += this.valuesToString(values);
6737                }
6738            } else {
6739                propContainer = BX.create('DIV', {props: {className: 'soa-property-container'}});
6740                property.appendTo(propContainer);
6741                propsItemNode.appendChild(propContainer);
6742                this.bindValidation(property.getId(), propContainer);
6743            }
6744        },
6745
6746        insertYNProperty: function (property, propsItemNode, disabled) {
6747            var prop, inputs, values, i, propContainer;
6748
6749            if (disabled) {
6750                prop = this.propsHiddenBlockNode.querySelector('div[data-property-id-row="' + property.getId() + '"]');
6751                if (prop) {
6752                    values = [];
6753                    inputs = prop.querySelectorAll('input[type=checkbox]');
6754
6755                    for (i = 0; i < inputs.length; i += 2)
6756                        values.push(inputs[i].checked ? BX.message('SOA_YES') : BX.message('SOA_NO'));
6757
6758                    propsItemNode.innerHTML += this.valuesToString(values);
6759                }
6760            } else {
6761                propContainer = BX.create('DIV', {props: {className: 'soa-property-container'}});
6762                property.appendTo(propContainer);
6763                propsItemNode.appendChild(propContainer);
6764                this.alterProperty(property.getSettings(), propContainer);
6765                this.bindValidation(property.getId(), propContainer);
6766            }
6767        },
6768
6769        insertNumberProperty: function (property, propsItemNode, disabled) {
6770            var prop, inputs, values, i, propContainer;
6771
6772            if (disabled) {
6773                prop = this.propsHiddenBlockNode.querySelector('div[data-property-id-row="' + property.getId() + '"]');
6774                if (prop) {
6775                    values = [];
6776                    inputs = prop.querySelectorAll('input[type=text]');
6777
6778                    for (i = 0; i < inputs.length; i++)
6779                        if (inputs[i].value.length)
6780                            values.push(inputs[i].value);
6781
6782                    propsItemNode.innerHTML += this.valuesToString(values);
6783                }
6784            } else {
6785                propContainer = BX.create('DIV', {props: {className: 'soa-property-container'}});
6786                property.appendTo(propContainer);
6787                propsItemNode.appendChild(propContainer);
6788                this.alterProperty(property.getSettings(), propContainer);
6789                this.bindValidation(property.getId(), propContainer);
6790            }
6791        },
6792
6793        valuesToString: function (values) {
6794            var str = values.join(', ');
6795
6796            return str.length ? BX.util.htmlspecialchars(str) : BX.message('SOA_NOT_SELECTED');
6797        },
6798
6799        alterProperty: function (settings, propContainer) {
6800            var divs = BX.findChildren(propContainer, {tagName: 'DIV'}),
6801                i, textNode, inputs, del, add,
6802                fileInputs, accepts, fileTitles;
6803
6804            if (divs && divs.length) {
6805                for (i = 0; i < divs.length; i++) {
6806                    divs[i].style.margin = '5px 0';
6807                }
6808            }
6809
6810            textNode = propContainer.querySelector('input[type=text]');
6811            if (!textNode)
6812                textNode = propContainer.querySelector('textarea');
6813
6814            if (textNode) {
6815                textNode.id = 'soa-property-' + settings.ID;
6816                if (settings.IS_ADDRESS == 'Y')
6817                    textNode.setAttribute('autocomplete', 'new-password');
6818                if (settings.IS_EMAIL == 'Y')
6819                    textNode.setAttribute('autocomplete', 'email');
6820                if (settings.IS_PAYER == 'Y')
6821                    textNode.setAttribute('autocomplete', 'name');
6822                if (settings.IS_PHONE == 'Y') {
6823                    textNode.setAttribute('autocomplete', 'tel');
6824                    $(textNode).mask(this.params.PHONE_INPUT_MASK);
6825                }
6826
6827                if (settings.PATTERN && settings.PATTERN.length) {
6828                    textNode.removeAttribute('pattern');
6829                }
6830            }
6831
6832            inputs = propContainer.querySelectorAll('input[type=text]');
6833            for (i = 0; i < inputs.length; i++) {
6834                inputs[i].placeholder = settings.DESCRIPTION;
6835                BX.addClass(inputs[i], 'tanais-form-control bx-soa-customer-input bx-ios-fix');
6836            }
6837
6838            inputs = propContainer.querySelectorAll('select');
6839            for (i = 0; i < inputs.length; i++)
6840                BX.addClass(inputs[i], 'tanais-form-control');
6841
6842            inputs = propContainer.querySelectorAll('textarea');
6843            for (i = 0; i < inputs.length; i++) {
6844                inputs[i].placeholder = settings.DESCRIPTION;
6845                BX.addClass(inputs[i], 'tanais-form-control bx-ios-fix');
6846            }
6847
6848            del = propContainer.querySelectorAll('label');
6849            for (i = 0; i < del.length; i++)
6850                BX.remove(del[i]);
6851
6852            if (settings.TYPE == 'FILE') {
6853                if (settings.ACCEPT && settings.ACCEPT.length) {
6854                    fileInputs = propContainer.querySelectorAll('input[type=file]');
6855                    accepts = this.getFileAccepts(settings.ACCEPT);
6856                    for (i = 0; i < fileInputs.length; i++)
6857                        fileInputs[i].setAttribute('accept', accepts);
6858                }
6859
6860                fileTitles = propContainer.querySelectorAll('a');
6861                for (i = 0; i < fileTitles.length; i++) {
6862                    BX.bind(fileTitles[i], 'click', function (e) {
6863                        var target = e.target || e.srcElement,
6864                            fileInput = target && target.nextSibling && target.nextSibling.nextSibling;
6865
6866                        if (fileInput)
6867                            BX.fireEvent(fileInput, 'change');
6868                    });
6869                }
6870            }
6871
6872            add = propContainer.querySelectorAll('input[type=button]');
6873            for (i = 0; i < add.length; i++) {
6874                BX.addClass(add[i], 'btn btn-default');
6875
6876                if (settings.MULTIPLE == 'Y' && i == add.length - 1)
6877                    continue;
6878
6879                if (settings.TYPE == 'FILE') {
6880                    BX.prepend(add[i], add[i].parentNode);
6881                    add[i].style.marginRight = '10px';
6882                }
6883            }
6884
6885            if (add.length) {
6886                add = add[add.length - 1];
6887                BX.bind(add, 'click', BX.delegate(function (e) {
6888                    var target = e.target || e.srcElement,
6889                        targetContainer = BX.findParent(target, {tagName: 'div', className: 'soa-property-container'}),
6890                        del = targetContainer.querySelector('label'),
6891                        add = targetContainer.querySelectorAll('input[type=button]'),
6892                        textInputs = targetContainer.querySelectorAll('input[type=text]'),
6893                        textAreas = targetContainer.querySelectorAll('textarea'),
6894                        divs = BX.findChildren(targetContainer, {tagName: 'DIV'});
6895
6896                    var i, fileTitles, fileInputs, accepts;
6897
6898                    if (divs && divs.length) {
6899                        for (i = 0; i < divs.length; i++) {
6900                            divs[i].style.margin = '5px 0';
6901                        }
6902                    }
6903
6904                    this.bindValidation(settings.ID, targetContainer);
6905
6906                    if (add.length && add[add.length - 2]) {
6907                        BX.prepend(add[add.length - 2], add[add.length - 2].parentNode);
6908                        add[add.length - 2].style.marginRight = '10px';
6909                        BX.addClass(add[add.length - 2], 'btn btn-default');
6910                    }
6911
6912                    del && BX.remove(del);
6913                    if (textInputs.length) {
6914                        textInputs[textInputs.length - 1].placeholder = settings.DESCRIPTION;
6915                        BX.addClass(textInputs[textInputs.length - 1], 'tanais-form-control bx-soa-customer-input bx-ios-fix');
6916                        if (settings.TYPE == 'DATE')
6917                            this.alterDateProperty(settings, textInputs[textInputs.length - 1]);
6918
6919                        if (settings.PATTERN && settings.PATTERN.length)
6920                            textInputs[textInputs.length - 1].removeAttribute('pattern');
6921                    }
6922
6923                    if (textAreas.length) {
6924                        textAreas[textAreas.length - 1].placeholder = settings.DESCRIPTION;
6925                        BX.addClass(textAreas[textAreas.length - 1], 'tanais-form-control bx-ios-fix');
6926                    }
6927
6928                    if (settings.TYPE == 'FILE') {
6929                        if (settings.ACCEPT && settings.ACCEPT.length) {
6930                            fileInputs = propContainer.querySelectorAll('input[type=file]');
6931                            accepts = this.getFileAccepts(settings.ACCEPT);
6932                            for (i = 0; i < fileInputs.length; i++)
6933                                fileInputs[i].setAttribute('accept', accepts);
6934                        }
6935
6936                        fileTitles = targetContainer.querySelectorAll('a');
6937                        BX.bind(fileTitles[fileTitles.length - 1], 'click', function (e) {
6938                            var target = e.target || e.srcElement,
6939                                fileInput = target && target.nextSibling && target.nextSibling.nextSibling;
6940
6941                            if (fileInput)
6942                                setTimeout(function () {
6943                                    BX.fireEvent(fileInput, 'change');
6944                                }, 10);
6945                        });
6946                    }
6947                }, this));
6948            }
6949        },
6950
6951        alterDateProperty: function (settings, inputText) {
6952            var parentNode = BX.findParent(inputText, {tagName: 'DIV'}),
6953                addon;
6954
6955            BX.addClass(parentNode, 'input-group');
6956            addon = BX.create('DIV', {
6957                props: {className: 'input-group-addon'},
6958                children: [BX.create('I', {props: {className: 'bx-calendar'}})]
6959            });
6960            BX.insertAfter(addon, inputText);
6961            BX.remove(parentNode.querySelector('input[type=button]'));
6962            BX.bind(addon, 'click', BX.delegate(function (e) {
6963                var target = e.target || e.srcElement,
6964                    parentNode = BX.findParent(target, {tagName: 'DIV', className: 'input-group'});
6965
6966                BX.calendar({
6967                    node: parentNode.querySelector('.input-group-addon'),
6968                    field: parentNode.querySelector('input[type=text]').name,
6969                    form: '',
6970                    bTime: settings.TIME == 'Y',
6971                    bHideTime: false
6972                });
6973            }, this));
6974        },
6975
6976        isValidForm: function () {
6977            if (!this.options.propertyValidation)
6978                return true;
6979
6980            var regionErrors = this.isValidRegionBlock(),
6981                propsErrors = this.isValidPropertiesBlock(),
6982                navigated = false, tooltips, i;
6983
6984            if (regionErrors.length) {
6985                navigated = true;
6986                this.animateScrollTo(this.regionBlockNode, 800, 50);
6987            }
6988
6989            if (propsErrors.length && !navigated) {
6990                if (this.activeSectionId == this.propsBlockNode.id) {
6991                    tooltips = this.propsBlockNode.querySelectorAll('div.tooltip');
6992                    for (i = 0; i < tooltips.length; i++) {
6993                        if (tooltips[i].getAttribute('data-state') == 'opened') {
6994                            this.animateScrollTo(BX.findParent(tooltips[i], {className: 'tanais-form-group bx-soa-customer-field'}), 800, 50);
6995                            break;
6996                        }
6997                    }
6998                } else
6999                    this.animateScrollTo(this.propsBlockNode, 800, 50);
7000            }
7001
7002            if (regionErrors.length) {
7003                this.showError(this.regionBlockNode, regionErrors);
7004                BX.addClass(this.regionBlockNode, 'bx-step-error');
7005            }
7006
7007            if (propsErrors.length) {
7008                if (this.activeSectionId !== this.propsBlockNode.id)
7009                    this.showError(this.propsBlockNode, propsErrors);
7010
7011                BX.addClass(this.propsBlockNode, 'bx-step-error');
7012            }
7013
7014            return !(regionErrors.length + propsErrors.length);
7015        },
7016
7017        isValidRegionBlock: function () {
7018            if (!this.options.propertyValidation)
7019                return [];
7020
7021            var regionProps = this.orderBlockNode.querySelectorAll('.bx-soa-location-input-container[data-
7021property-id-row]'),
7022                regionErrors = [],
7023                id, arProperty, data, i;
7024
7025            for (i = 0; i < regionProps.length; i++) {
7026                id = regionProps[i].getAttribute('data-property-id-row');
7027                arProperty = this.validation.properties[id];
7028                data = this.getValidationData(arProperty, regionProps[i]);
7029
7030                regionErrors = regionErrors.concat(this.isValidProperty(data, true));
7031            }
7032
7033            return regionErrors;
7034        },
7035
7036        isValidPropertiesBlock: function (excludeLocation) {
7037            if (!this.options.propertyValidation)
7038                return [];
7039
7040            var props = this.orderBlockNode.querySelectorAll('.bx-soa-customer-field[data-property-id-row]'),
7041                propsErrors = [],
7042                id, propContainer, arProperty, data, i;
7043
7044            for (i = 0; i < props.length; i++) {
7045                id = props[i].getAttribute('data-property-id-row');
7046
7047                if (!!excludeLocation && this.locations[id])
7048                    continue;
7049
7050                propContainer = props[i].querySelector('.soa-property-container');
7051                if (propContainer) {
7052                    arProperty = this.validation.properties[id];
7053                    data = this.getValidationData(arProperty, propContainer);
7054                    propsErrors = propsErrors.concat(this.isValidProperty(data, true));
7055                }
7056            }
7057
7058            return propsErrors;
7059        },
7060
7061        isValidProperty: function (data, fieldName) {
7062            var propErrors = [], inputErrors, i;
7063
7064            if (!data || !data.inputs)
7065                return propErrors;
7066
7067            for (i = 0; i < data.inputs.length; i++) {
7068                inputErrors = data.func(data.inputs[i], !!fieldName);
7069                if (inputErrors.length)
7070                    propErrors[i] = inputErrors.join('<br>');
7071            }
7072
7073            this.showValidationResult(data.inputs, propErrors);
7074
7075            return propErrors;
7076        },
7077
7078        bindValidation: function (id, propContainer) {
7079            if (!this.validation.properties || !this.validation.properties[id])
7080                return;
7081
7082            var arProperty = this.validation.properties[id],
7083                data = this.getValidationData(arProperty, propContainer),
7084                i, k;
7085
7086            if (data && data.inputs && data.action) {
7087                for (i = 0; i < data.inputs.length; i++) {
7088                    if (BX.type.isElementNode(data.inputs[i]))
7089                        BX.bind(data.inputs[i], data.action, BX.delegate(function () {
7090                            this.isValidProperty(data);
7091                        }, this));
7092                    else
7093                        for (k = 0; k < data.inputs[i].length; k++)
7094                            BX.bind(data.inputs[i][k], data.action, BX.delegate(function () {
7095                                this.isValidProperty(data);
7096                            }, this));
7097                }
7098            }
7099        },
7100
7101        getValidationData: function (arProperty, propContainer) {
7102            if (!arProperty || !propContainer)
7103                return;
7104
7105            var data = {}, inputs;
7106
7107            switch (arProperty.TYPE) {
7108                case 'STRING':
7109                    data.action = 'change';
7110                    data.func = BX.delegate(function (input, fieldName) {
7111                        return this.validateString(input, arProperty, fieldName);
7112                    }, this);
7113
7114                    inputs = propContainer.querySelectorAll('input[type=text]');
7115                    if (inputs.length) {
7116                        data.inputs = inputs;
7117                        break;
7118                    }
7119                    inputs = propContainer.querySelectorAll('textarea');
7120                    if (inputs.length)
7121                        data.inputs = inputs;
7122                    break;
7123                case 'LOCATION':
7124                    data.func = BX.delegate(function (input, fieldName) {
7125                        return this.validateLocation(input, arProperty, fieldName);
7126                    }, this);
7127
7128                    inputs = propContainer.querySelectorAll('input.bx-ui-sls-fake[type=text]');
7129                    if (inputs.length) {
7130                        data.inputs = inputs;
7131                        data.action = 'keyup';
7132                        break;
7133                    }
7134                    inputs = propContainer.querySelectorAll('div.bx-ui-slst-pool');
7135                    if (inputs.length) {
7136                        data.inputs = inputs;
7137                    }
7138                    break;
7139                case 'Y/N':
7140                    data.inputs = propContainer.querySelectorAll('input[type=checkbox]');
7141                    data.action = 'change';
7142                    data.func = BX.delegate(function (input, fieldName) {
7143                        return this.validateCheckbox(input, arProperty, fieldName);
7144                    }, this);
7145                    break;
7146                case 'NUMBER':
7147                    data.inputs = propContainer.querySelectorAll('input[type=text]');
7148                    data.action = 'blur';
7149                    data.func = BX.delegate(function (input, fieldName) {
7150                        return this.validateNumber(input, arProperty, fieldName);
7151                    }, this);
7152                    break;
7153                case 'ENUM':
7154                    inputs = propContainer.querySelectorAll('input[type=radio]');
7155                    if (!inputs.length)
7156                        inputs = propContainer.querySelectorAll('input[type=checkbox]');
7157
7158                    if (inputs.length) {
7159                        data.inputs = [inputs];
7160                        data.action = 'change';
7161                        data.func = BX.delegate(function (input, fieldName) {
7162                            return this.validateEnum(input, arProperty, fieldName);
7163                        }, this);
7164                        break;
7165                    }
7166
7167                    inputs = propContainer.querySelectorAll('option');
7168                    if (inputs.length) {
7169                        data.inputs = [inputs];
7170                        data.action = 'click';
7171                        data.func = BX.delegate(function (input, fieldName) {
7172                            return this.validateSelect(input, arProperty, fieldName);
7173                        }, this);
7174                    }
7175                    break;
7176                case 'FILE':
7177                    data.inputs = propContainer.querySelectorAll('input[type=file]');
7178                    data.action = 'change';
7179                    data.func = BX.delegate(function (input, fieldName) {
7180                        return this.validateFile(input, arProperty, fieldName);
7181                    }, this);
7182                    break;
7183                case 'DATE':
7184                    data.inputs = propContainer.querySelectorAll('input[type=text]');
7185                    data.action = 'change';
7186                    data.func = BX.delegate(function (input, fieldName) {
7187                        return this.validateDate(input, arProperty, fieldName);
7188                    }, this);
7189                    break;
7190            }
7191
7192            return data;
7193        },
7194
7195        showErrorTooltip: function (tooltipId, targetNode, text) {
7196            if (!tooltipId || !targetNode || !text)
7197                return;
7198
7199            var tooltip = BX('tooltip-' + tooltipId),
7200                tooltipInner, quickLocation;
7201
7202            text = this.uniqueText(text, '<br>');
7203
7204            if (tooltip) {
7205                tooltipInner = tooltip.querySelector('div.tooltip-inner');
7206            } else {
7207                tooltipInner = BX.create('DIV', {props: {className: 'tooltip-inner'}});
7208                tooltip = BX.create('DIV', {
7209                    props: {
7210                        id: 'tooltip-' + tooltipId,
7211                        className: 'bx-soa-tooltip bx-soa-tooltip-static bx-soa-tooltip-danger tooltip top'
7212                    },
7213                    children: [
7214                        BX.create('DIV', {props: {className: 'tooltip-arrow'}}),
7215                        tooltipInner
7216                    ]
7217                });
7218
7219                quickLocation = targetNode.parentNode.querySelector('div.quick-locations');
7220                if (quickLocation)
7221                    targetNode = quickLocation;
7222
7223                BX.insertAfter(tooltip, targetNode);
7224            }
7225
7226            tooltipInner.innerHTML = text;
7227
7228            if (tooltip.getAttribute('data-state') != 'opened') {
7229                tooltip.setAttribute('data-state', 'opened');
7230                tooltip.style.opacity = 0;
7231                tooltip.style.display = 'block';
7232
7233                new BX.easing({
7234                    duration: 150,
7235                    start: {opacity: 0},
7236                    finish: {opacity: 100},
7237                    transition: BX.easing.transitions.quad,
7238                    step: function (state) {
7239                        tooltip.style.opacity = state.opacity / 100;
7240                    }
7241                }).animate();
7242            }
7243        },
7244
7245        closeErrorTooltip: function (tooltipId) {
7246            var tooltip = BX('tooltip-' + tooltipId);
7247            if (tooltip) {
7248                tooltip.setAttribute('data-state', 'closed');
7249
7250                new BX.easing({
7251                    duration: 150,
7252                    start: {opacity: 100},
7253                    finish: {opacity: 0},
7254                    transition: BX.easing.transitions.quad,
7255                    step: function (state) {
7256                        tooltip.style.opacity = state.opacity / 100;
7257                    },
7258                    complete: function () {
7259                        tooltip.style.display = 'none';
7260                    }
7261                }).animate();
7262            }
7263        },
7264
7265        showValidationResult: function (inputs, errors) {
7266            if (!inputs || !inputs.length || !errors)
7267                return;
7268
7269            var input0 = BX.type.isElementNode(inputs[0]) ? inputs[0] : inputs[0][0],
7270                formGroup = BX.findParent(input0, {tagName: 'DIV', className: 'tanais-form-group'}),
7271                label = formGroup.querySelector('label'),
7272                tooltipId, inputDiv, i;
7273
7274            if (label)
7275                tooltipId = label.getAttribute('for');
7276
7277            for (i = 0; i < inputs.length; i++) {
7278                inputDiv = BX.findParent(inputs[i], {tagName: 'DIV', className: 'tanais-form-group'});
7279                if (errors[i] && errors[i].length)
7280                    BX.addClass(inputDiv, 'has-error');
7281                else
7282                    BX.removeClass(inputDiv, 'has-error');
7283            }
7284
7285            if (errors.length)
7286                this.showErrorTooltip(tooltipId, label, errors.join('<br>'));
7287            else
7288                this.closeErrorTooltip(tooltipId);
7289        },
7290
7291        validateString: function (input, arProperty, fieldName) {
7292            if (!input || !arProperty)
7293                return [];
7294
7295            var value = input.value,
7296                errors = [],
7297                name = BX.util.htmlspecialchars(arProperty.NAME),
7298                field = !!fieldName ? BX.message('SOA_FIELD') + ' "' + name + '"' : BX.message('SOA_FIELD'),
7299                re;
7300
7301            if (arProperty.MULTIPLE === 'Y')
7302                return errors;
7303
7304            if (arProperty.REQUIRED === 'Y' && value.length === 0)
7305                errors.push(field + ' ' + BX.message('SOA_REQUIRED'));
7306
7307            if (value.length) {
7308                if (arProperty.MINLENGTH && arProperty.MINLENGTH > value.length)
7309                    errors.push(BX.message('SOA_MIN_LENGTH') + ' "' + name + '" ' + BX.message('SOA_LESS') + ' ' + arProperty.MINLENGTH + ' ' + BX.message('SOA_SYMBOLS'));
7310
7311                if (arProperty.MAXLENGTH && arProperty.MAXLENGTH < value.length)
7312                    errors.push(BX.message('SOA_MAX_LENGTH') + ' "' + name + '" ' + BX.message('SOA_MORE') + ' ' + arProperty.MAXLENGTH + ' ' + BX.message('SOA_SYMBOLS'));
7313
7314                if (arProperty.IS_EMAIL === 'Y') {
7315                    input.value = value = BX.util.trim(value);
7316                    if (value.length) {
7317                        re = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
7318                        if (!re.test(value)) {
7319                            errors.push(BX.message('SOA_INVALID_EMAIL'));
7320                        }
7321                    }
7322                }
7323
7324                if (value.length > 0 && arProperty.PATTERN && arProperty.PATTERN.length) {
7325                    re = new RegExp(arProperty.PATTERN);
7326                    if (!re.test(value))
7327                        errors.push(field + ' ' + BX.message('SOA_INVALID_PATTERN'));
7328                }
7329            }
7330
7331            return errors;
7332        },
7333
7334        validateLocation: function (input, arProperty, fieldName) {
7335            if (!input || !arProperty)
7336                return [];
7337
7338            var parent = BX.findParent(input, {tagName: 'DIV', className: 'tanais-form-group'}),
7339                value = this.getLocationString(parent),
7340                errors = [],
7341                field = !!fieldName ? BX.message('SOA_FIELD') + ' "' + BX.util.htmlspecialchars(arProperty.NAME) + '"' : BX.message('SOA_FIELD');
7342
7343            if (arProperty.MULTIPLE == 'Y' && arProperty.IS_LOCATION !== 'Y')
7344                return errors;
7345
7346            if (arProperty.REQUIRED == 'Y' && (value.length == 0 || value == BX.message('SOA_NOT_SPECIFIED')))
7347                errors.push(field + ' ' + BX.message('SOA_REQUIRED'));
7348
7349            return errors;
7350        },
7351
7352        validateCheckbox: function (input, arProperty, fieldName) {
7353            if (!input || !arProperty)
7354                return [];
7355
7356            var errors = [],
7357                field = !!fieldName ? BX.message('SOA_FIELD') + ' "' + BX.util.htmlspecialchars(arProperty.NAME) + '"' : BX.message('SOA_FIELD');
7358
7359            if (arProperty.MULTIPLE == 'Y')
7360                return errors;
7361
7362            if (arProperty.REQUIRED == 'Y' && !input.checked)
7363                errors.push(field + ' ' + BX.message('SOA_REQUIRED'));
7364
7365            return errors;
7366        },
7367
7368        validateNumber: function (input, arProperty, fieldName) {
7369            if (!input || !arProperty)
7370                return [];
7371
7372            var value = input.value,
7373                errors = [],
7374                name = BX.util.htmlspecialchars(arProperty.NAME),
7375                field = !!fieldName ? BX.message('SOA_FIELD') + ' "' + name + '"' : BX.message('SOA_FIELD'),
7376                num, del;
7377
7378            if (arProperty.MULTIPLE == 'Y')
7379                return errors;
7380
7381            if (arProperty.REQUIRED == 'Y' && value.length == 0)
7382                errors.push(field + ' ' + BX.message('SOA_REQUIRED'));
7383
7384            if (value.length) {
7385                if (!/[0-9]|\./.test(value))
7386                    errors.push(field + ' ' + BX.message('SOA_NOT_NUMERIC'));
7387
7388                if (arProperty.MIN && parseFloat(arProperty.MIN) > parseFloat(value))
7389                    errors.push(BX.message('SOA_MIN_VALUE') + ' "' + name + '" ' + parseFloat(arProperty.MIN));
7390
7391                if (arProperty.MAX && parseFloat(arProperty.MAX) < parseFloat(value))
7392                    errors.push(BX.message('SOA_MAX_VALUE') + ' "' + name + '" ' + parseFloat(arProperty.MAX));
7393
7394                if (arProperty.STEP && parseFloat(arProperty.STEP) > 0) {
7395                    num = Math.abs(parseFloat(value) - (arProperty.MIN && parseFloat(arProperty.MIN) > 0 ? parseFloat(arProperty.MIN) : 0));
7396                    del = (num / parseFloat(arProperty.STEP)).toPrecision(12);
7397                    if (del != parseInt(del))
7398                        errors.push(field + ' ' + BX.message('SOA_NUM_STEP') + ' ' + arProperty.STEP);
7399                }
7400            }
7401
7402            return errors;
7403        },
7404
7405        validateEnum: function (inputs, arProperty, fieldName) {
7406            if (!inputs || !arProperty)
7407                return [];
7408
7409            var values = [], errors = [], i,
7410                field = !!fieldName ? BX.message('SOA_FIELD') + ' "' + BX.util.htmlspecialchars(arProperty.NAME) + '"' : BX.message('SOA_FIELD');
7411
7412            if (arProperty.MULTIPLE == 'Y')
7413                return errors;
7414
7415            for (i = 0; i < inputs.length; i++)
7416                if (inputs[i].checked || inputs[i].selected)
7417                    values.push(i);
7418
7419            if (arProperty.REQUIRED == 'Y' && values.length == 0)
7420                errors.push(field + ' ' + BX.message('SOA_REQUIRED'));
7421
7422            return errors;
7423        },
7424
7425        validateSelect: function (inputs, arProperty, fieldName) {
7426            if (!inputs || !arProperty)
7427                return [];
7428
7429            var values = [], errors = [], i,
7430                field = !!fieldName ? BX.message('SOA_FIELD') + ' "' + BX.util.htmlspecialchars(arProperty.NAME) + '"' : BX.message('SOA_FIELD');
7431
7432            if (arProperty.MULTIPLE == 'Y')
7433                return errors;
7434
7435            for (i = 0; i < inputs.length; i++)
7436                if (inputs[i].selected)
7437                    values.push(i);
7438
7439            if (arProperty.REQUIRED == 'Y' && values.length == 0)
7440                errors.push(field + ' ' + BX.message('SOA_REQUIRED'));
7441
7442            return errors;
7443        },
7444
7445        validateFile: function (inputs, arProperty, fieldName) {
7446            if (!inputs || !arProperty)
7447                return [];
7448
7449            var errors = [], i,
7450                files = inputs.files || [],
7451                field = !!fieldName ? BX.message('SOA_FIELD') + ' "' + BX.util.htmlspecialchars(arProperty.NAME) + '"' : BX.message('SOA_FIELD'),
7452                defaultValue = inputs.previousSibling.value,
7453                file, fileName, splittedName, fileExtension;
7454
7455            if (arProperty.MULTIPLE == 'Y')
7456                return errors;
7457
7458            if (
7459                arProperty.REQUIRED == 'Y' && files.length == 0 && defaultValue == ''
7460                && (!arProperty.DEFAULT_VALUE || !arProperty.DEFAULT_VALUE.length)
7461            ) {
7462                errors.push(field + ' ' + BX.message('SOA_REQUIRED'));
7463            } else {
7464                for (i = 0; i < files.length; i++) {
7465                    file = files[i];
7466                    fileName = BX.util.htmlspecialchars(file.name);
7467                    splittedName = file.name.split('.');
7468                    fileExtension = splittedName.length > 1 ? splittedName[splittedName.length - 1].toLowerCase() : '';
7469
7470                    if (arProperty.ACCEPT.length > 0 && (fileExtension.length == 0 || arProperty.ACCEPT.indexOf(fileExtension) == '-1'))
7471                        errors.push(BX.message('SOA_BAD_EXTENSION') + ' "' + fileName + '" (' + BX.util.htmlspecialchars(arProperty.ACCEPT) + ')');
7472
7473                    if (file.size > parseInt(arProperty.MAXSIZE))
7474                        errors.push(BX.message('SOA_MAX_SIZE') + ' "' + fileName + '" (' + this.getSizeString(arProperty.MAXSIZE, 1) + ')');
7475                }
7476            }
7477
7478            return errors;
7479        },
7480
7481        validateDate: function (input, arProperty, fieldName) {
7482            if (!input || !arProperty)
7483                return [];
7484
7485            var value = input.value,
7486                errors = [],
7487                name = BX.util.htmlspecialchars(arProperty.NAME),
7488                field = !!fieldName ? BX.message('SOA_FIELD') + ' "' + name + '"' : BX.message('SOA_FIELD');
7489
7490            if (arProperty.MULTIPLE == 'Y')
7491                return errors;
7492
7493            if (arProperty.REQUIRED == 'Y' && value.length == 0)
7494                errors.push(field + ' ' + BX.message('SOA_REQUIRED'));
7495
7496            return errors;
7497        },
7498
7499        editPropsMap: function (propsNode) {
7500            var propsMapContainer = BX.create('DIV', {style: {marginBottom: '10px'}}),
7501                map = BX.create('DIV', {props: {id: 'propsMap'}, style: {width: '100%'}});
7502
7503            propsMapContainer.appendChild(map);
7504            propsNode.appendChild(propsMapContainer);
7505        },
7506
7507        editPropsComment: function (propsNode) {
7508            var propsCommentContainer, label, input, div;
7509
7510            propsCommentContainer = BX.create('DIV', {});
7511            label = BX.create('LABEL', {
7512                attrs: {for: 'orderDescription'},
7513                props: {className: 'bx-soa-customer-label'},
7514                html: this.params.MESS_ORDER_DESC
7515            });
7516            input = BX.create('TEXTAREA', {
7517                props: {
7518                    id: 'orderDescription',
7519                    cols: '4',
7520                    className: 'tanais-form-control bx-soa-customer-textarea bx-ios-fix tanais-textarea',
7521                    name: 'ORDER_DESCRIPTION'
7522                },
7523                text: this.result.ORDER_DESCRIPTION ? this.result.ORDER_DESCRIPTION : ''
7524            });
7525            div = BX.create('DIV', {
7526                props: {className: 'tanais-form-group bx-soa-customer-field'},
7527                children: [label, input]
7528            });
7529
7530            propsCommentContainer.appendChild(div);
7531            propsNode.appendChild(propsCommentContainer);
7532        },
7533
7534        declOfNum(n, titles) {
7535            return titles[(n % 10 === 1 && n % 100 !== 11) ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2]
7536        },
7537
7538        editTotalBlock: function () {
7539            if (!this.totalInfoBlockDataNode || !this.result.TOTAL)
7540                return;
7541
7542            var total = this.result.TOTAL,
7543                priceHtml, params = {},
7544                discText, valFormatted, i,
7545                curDelivery, deliveryError, deliveryValue,
7546                showOrderButton = this.params.SHOW_TOTAL_ORDER_BUTTON === 'Y';
7547
7548            BX.cleanNode(this.totalInfoBlockDataNode);
7549
7550            if (parseFloat(total.ORDER_PRICE) === 0) {
7551                priceHtml = this.params.MESS_PRICE_FREE;
7552                params.free = true;
7553            } else {
7554                priceHtml = total.ORDER_PRICE_FORMATED;
7555            }
7556
7557            if (this.options.showPriceWithoutDiscount) {
7558                priceHtml = '<span class="bx-price-old">' +
7559                    total.PRICE_WITHOUT_DISCOUNT + '</span><br>
7559' + '<span class="with-discount-value">' + priceHtml + '</span>';
7560            }
7561
7562            this.totalInfoBlockDataNode.appendChild(this.createTotalUnit(total.BASKET_POSITIONS + this.declOfNum(total.BASKET_POSITIONS, [' товар', ' товара', ' товаров']), priceHtml, params));
7563
7564            if (this.options.showOrderWeight) {
7565                this.totalInfoBlockDataNode.appendChild(this.createTotalUnit(BX.message('SOA_SUM_WEIGHT_SUM'), total.ORDER_WEIGHT_FORMATED));
7566            }
7567
7568            if (this.options.showTaxList) {
7569                for (i = 0; i < total.TAX_LIST.length; i++) {
7570                    valFormatted = total.TAX_LIST[i].VALUE_MONEY_FORMATED || '';
7571                    this.totalInfoBlockDataNode.appendChild(
7572                        this.createTotalUnit(
7573                            total.TAX_LIST[i].NAME + (!!total.TAX_LIST[i].VALUE_FORMATED ? ' ' + total.TAX_LIST[i].VALUE_FORMATED : '') + ':',
7574                            valFormatted
7575                        )
7576                    );
7577                }
7578            }
7579
7580            params = {};
7581            curDelivery = this.getSelectedDelivery();
7582            deliveryError = curDelivery && curDelivery.CALCULATE_ERRORS && curDelivery.CALCULATE_ERRORS.length;
7583
7584            if (deliveryError) {
7585                deliveryValue = BX.message('SOA_NOT_CALCULATED');
7586                params.error = deliveryError;
7587            } else {
7588                if (parseFloat(total.DELIVERY_PRICE) === 0) {
7589                    deliveryValue = this.params.MESS_PRICE_FREE;
7590                    params.free = true;
7591                } else {
7592                    deliveryValue = total.DELIVERY_PRICE_FORMATED;
7593                }
7594
7595                if (
7596                    curDelivery && typeof curDelivery.DELIVERY_DISCOUNT_PRICE !== 'undefined'
7597                    && parseFloat(curDelivery.PRICE) > parseFloat(curDelivery.DELIVERY_DISCOUNT_PRICE)
7598                ) {
7599                    deliveryValue = '<span class="bx-price-old">' + curDelivery.PRICE_FORMATED + '</span><br>' + '<span class="with-discount-value">' + deliveryValue + '</span>';
7600                }
7601            }
7602
7603            if (this.result.DELIVERY.length) {
7604                this.totalInfoBlockDataNode.appendChild(this.createTotalUnit(BX.message('SOA_SUM_DELIVERY'), deliveryValue, params));
7605            }
7606
7607            if (this.options.showDiscountPrice) {
7608                discText = this.params.MESS_ECONOMY;
7609                if (total.DISCOUNT_PERCENT_FORMATED && parseFloat(total.DISCOUNT_PERCENT_FORMATED) > 0)
7610                    discText += total.DISCOUNT_PERCENT_FORMATED;
7611
7612                this.totalInfoBlockDataNode.appendChild(this.createTotalUnit(discText + ':', total.DISCOUNT_PRICE_FORMATED, {highlighted: true}));
7613            }
7614
7615            if (this.options.showPayedFromInnerBudget) {
7616                this.totalInfoBlockDataNode.appendChild(this.createTotalUnit(BX.message('SOA_SUM_IT'), total.ORDER_TOTAL_PRICE_FORMATED));
7617                this.totalInfoBlockDataNode.appendChild(this.createTotalUnit(BX.message('SOA_SUM_PAYED'), total.PAYED_FROM_ACCOUNT_FORMATED));
7618                this.totalInfoBlockDataNode.appendChild(this.createTotalUnit(BX.message('SOA_SUM_LEFT_TO_PAY'), total.ORDER_TOTAL_LEFT_TO_PAY_FORMATED, {total: true}));
7619            } else {
7620                this.totalInfoBlockDataNode.appendChild(this.createTotalUnit(BX.message('SOA_SUM_IT'), total.ORDER_TOTAL_PRICE_FORMATED, {total: true}));
7621            }
7622
7623            if (parseFloat(total.PAY_SYSTEM_PRICE) >= 0 && this.result.DELIVERY.length) {
7624                this.totalInfoBlockDataNode.appendChild(this.createTotalUnit(BX.message('SOA_PAYSYSTEM_PRICE'), '~' + total.PAY_SYSTEM_PRICE_FORMATTED));
7625            }
7626
7627            var couponContainer = BX.create('DIV', {
7628                props: {
7629                    className: 'bx-total-coupon-container'
7630                }
7631            });
7632
7633            if (this.params.SHOW_COUPONS == 'Y') {
7634                this.editCoupons(couponContainer);
7635            }
7636
7637            this.totalInfoBlockDataNode.appendChild(couponContainer);
7638
7639            if (!this.result.SHOW_AUTH) {
7640                var _children = [
7641                    BX.create('A', {
7642                        props: {
7643                            href: 'javascript:void(0)',
7644                            className: 'btn btn-default btn-order-save'
7645                        },
7646                        html: this.params.MESS_ORDER,
7647                        events: {
7648                            click: BX.proxy(this.clickOrderSaveAction, this)
7649                        }
7650                    })
7651                ];
7652
7653                if (this.params.USE_BUY_ONE_CLICK == "Y") {
7654                    _children.push(
7655                        BX.create('A', {
7656                            props: {
7657                                href: 'javascript:void(0)',
7658                                className: 'btn btn-outline-primary btn-order-one-click'
7659                            },
7660                            html: this.params.MESS_TOTAL_BLOCK_BUY_ONE_CLICK_BTN,
7661                            events: {
7662                                click: BX.proxy(this.buyOneClickFormShow, this)
7663                            }
7664                        })
7665                    );
7666                }
7667
7668                this.totalInfoBlockDataNode.appendChild(
7669                    BX.create('DIV', {
7670                        props: {className: 'bx-soa-cart-total-button-container'},
7671                        children: _children
7672                    })
7673                );
7674            }
7675
7676            this.editMobileTotalBlock();
7677        },
7678
7679        editMobileTotalBlock: function () {
7680            BX.cleanNode(this.mobileTotalBlockNode);
7681            this.mobileTotalBlockNode.appendChild(this.totalInfoBlockNode.cloneNode(true));
7682            BX.bind(this.mobileTotalBlockNode.querySelector('a.bx-soa-price-not-calc'), 'click', BX.delegate(function () {
7683                this.animateScrollTo(this.deliveryBlockNode);
7684            }, this));
7685            BX.bind(this.mobileTotalBlockNode.querySelector('a.btn-order-save'), 'click', BX.proxy(this.clickOrderSaveAction, this));
7686
7687            if (this.params.USE_BUY_ONE_CLICK == "Y") {
7688                BX.bind(this.mobileTotalBlockNode.querySelector('.bx-soa-cart-total .btn-order-one-click'), 'click', BX.proxy(this.buyOneClickFormShow, this));
7689            }
7690
7691            BX.bind(
7692                this.mobileTotalBlockNode.querySelector(".bx-soa-coupon-input input[type='text']"),
7693                'change',
7694                this.getCouponChangeEvent()
7695            );
7696        },
7697
7698        createTotalUnit: function (name, value, params) {
7699            var totalValue, className = 'bx-soa-cart-total-line';
7700
7701            name = name || '';
7702            value = value || '';
7703            params = params || {};
7704
7705            if (params.error) {
7706                totalValue = [BX.create('A', {
7707                    props: {className: 'bx-soa-price-not-calc'},
7708                    html: value,
7709                    events: {
7710                        click: BX.delegate(function () {
7711                            this.animateScrollTo(this.deliveryBlockNode);
7712                        }, this)
7713                    }
7714                })];
7715            } else if (params.free) {
7716                totalValue = [BX.create('SPAN', {
7717                    props: {className: 'bx-soa-price-free'},
7718                    html: value
7719                })];
7720            } else {
7721                totalValue = [value];
7722            }
7723
7724            if (params.total) {
7725                className += ' bx-soa-cart-total-line-total';
7726            }
7727
7728            if (params.highlighted) {
7729                className += ' bx-soa-cart-total-line-highlighted';
7730            }
7731
7732            return BX.create('DIV', {
7733                props: {className: className},
7734                children: [
7735                    BX.create('SPAN', {props: {className: 'bx-soa-cart-t'}, text: name}),
7736                    BX.create('SPAN', {
7737                        props: {
7738                            className: 'bx-soa-cart-d' + (!!params.total && this.options.totalPriceChanged ? ' bx-soa-changeCostSign' : '')
7739                        },
7740                        children: totalValue
7741                    })
7742                ]
7743            });
7744        },
7745
7746        basketBlockScrollCheckEvent: function (e) {
7747            var target = e.target || e.srcElement,
7748                scrollLeft = target.scrollLeft,
7749                scrollRight = target.scrollWidth - (scrollLeft + target.clientWidth),
7750                parent = target.parentNode;
7751
7752            if (scrollLeft == 0)
7753                BX.removeClass(parent, 'bx-soa-table-fade-left');
7754            else
7755                BX.addClass(parent, 'bx-soa-table-fade-left');
7756
7757            if (scrollRight == 0)
7758                BX.removeClass(parent, 'bx-soa-table-fade-right');
7759            else
7760                BX.addClass(parent, 'bx-soa-table-fade-right');
7761        },
7762
7763        basketBlockScrollCheck: function () {
7764            var scrollableNodes = this.orderBlockNode.querySelectorAll('div.bx-soa-table-fade'),
7765                parentNode, parentWidth, tableNode, tableWidth,
7766                i, scrollNode, scrollLeft, scrollRight, scrollable = false;
7767
7768            for (i = 0; i < scrollableNodes.length; i++) {
7769                parentNode = scrollableNodes[i];
7770                tableNode = parentNode.querySelector('div.bx-soa-item-table');
7771                parentWidth = parentNode.clientWidth;
7772                tableWidth = tableNode.clientWidth || 0;
7773                scrollable = scrollable || tableWidth > parentWidth;
7774
7775                if (scrollable) {
7776                    scrollNode = BX.firstChild(parentNode);
7777                    scrollLeft = scrollNode.scrollLeft;
7778                    scrollRight = scrollNode.scrollWidth - (scrollLeft + scrollNode.clientWidth);
7779
7780                    if (scrollLeft == 0)
7781                        BX.removeClass(parentNode, 'bx-soa-table-fade-left');
7782                    else
7783                        BX.addClass(parentNode, 'bx-soa-table-fade-left');
7784
7785                    if (scrollRight == 0)
7786                        BX.removeClass(parentNode, 'bx-soa-table-fade-right');
7787                    else
7788                        BX.addClass(parentNode, 'bx-soa-table-fade-right');
7789
7790                    if (scrollLeft == 0 && scrollRight == 0)
7791                        BX.addClass(parentNode, 'bx-soa-table-fade-right');
7792                } else
7793                    BX.removeClass(parentNode, 'bx-soa-table-fade-left bx-soa-table-fade-right');
7794            }
7795        },
7796
7797        totalBlockScrollCheck: function () {
7798            if (!this.totalInfoBlockNode || !this.totalGhostBlockNode)
7799                return;
7800
7801            var scrollTop = BX.GetWindowScrollPos().scrollTop,
7802                ghostTop = BX.pos(this.totalGhostBlockNode).top,
7803                ghostBottom = BX.pos(this.orderBlockNode).bottom,
7804                width;
7805
7806            if (ghostBottom - this.totalBlockNode.offsetHeight < scrollTop + 20)
7807                BX.addClass(this.totalInfoBlockNode, 'bx-soa-cart-total-bottom');
7808            else
7809                BX.removeClass(this.totalInfoBlockNode, 'bx-soa-cart-total-bottom');
7810
7811            if (scrollTop > ghostTop && !BX.hasClass(this.totalInfoBlockNode, 'bx-soa-cart-total-fixed')) {
7812                width = this.totalInfoBlockNode.offsetWidth;
7813                BX.addClass(this.totalInfoBlockNode, 'bx-soa-cart-total-fixed');
7814                this.totalGhostBlockNode.style.paddingTop = this.totalInfoBlockNode.offsetHeight + 'px';
7815                this.totalInfoBlockNode.style.width = width + 'px';
7816            } else if (scrollTop < ghostTop && BX.hasClass(this.totalInfoBlockNode, 'bx-soa-cart-total-fixed')) {
7817                BX.removeClass(this.totalInfoBlockNode, 'bx-soa-cart-total-fixed');
7818                this.totalGhostBlockNode.style.paddingTop = 0;
7819                this.totalInfoBlockNode.style.width = '';
7820            }
7821        },
7822
7823        totalBlockResizeCheck: function () {
7824            if (!this.totalInfoBlockNode || !this.totalGhostBlockNode)
7825                return;
7826
7827            if (BX.hasClass(this.totalInfoBlockNode, 'bx-soa-cart-total-fixed'))
7828                this.totalInfoBlockNode.style.width = this.totalGhostBlockNode.offsetWidth + 'px';
7829        },
7830
7831        totalBlockFixFont: function () {
7832            var totalNode = this.totalInfoBlockNode.querySelector('.bx-soa-cart-total-line.bx-soa-cart-total-line-total'),
7833                buttonNode, target, objList = [];
7834
7835            if (totalNode) {
7836                target = BX.lastChild(totalNode);
7837                objList.push({
7838                    node: target,
7839                    maxFontSize: 28,
7840                    smallestValue: false,
7841                    scaleBy: target.parentNode
7842                });
7843            }
7844
7845            if (objList.length)
7846                BX.FixFontSize.init({objList: objList, onAdaptiveResize: true});
7847        },
7848
7849        setAnalyticsDataLayer: function (action, id) {
7850            if (!this.params.DATA_LAYER_NAME)
7851                return;
7852
7853            var info, i;
7854            var products = [],
7855                dataVariant, item;
7856
7857            for (i in this.result.GRID.ROWS) {
7858                if (this.result.GRID.ROWS.hasOwnProperty(i)) {
7859                    item = this.result.GRID.ROWS[i];
7860                    dataVariant = [];
7861
7862                    for (i = 0; i < item.data.PROPS.length; i++) {
7863                        dataVariant.push(item.data.PROPS[i].VALUE);
7864                    }
7865
7866                    products.push({
7867                        'id': item.data.PRODUCT_ID,
7868                        'name': item.data.NAME,
7869                        'price': item.data.PRICE,
7870                        'brand': (item.data[this.params.BRAND_PROPERTY + '_VALUE'] || '').split(', ').join('/'),
7871                        'variant': dataVariant.join('/'),
7872                        'quantity': item.data.QUANTITY
7873                    });
7874                }
7875            }
7876
7877            switch (action) {
7878                case 'checkout':
7879                    info = {
7880                        'event': 'checkout',
7881                        'ecommerce': {
7882                            'checkout': {
7883                                'products': products
7884                            }
7885                        }
7886                    };
7887                    break;
7888                case 'purchase':
7889                    info = {
7890                        'event': 'purchase',
7891                        'ecommerce': {
7892                            'purchase': {
7893                                'actionField': {
7894                                    'id': id,
7895                                    'revenue': this.result.TOTAL.ORDER_TOTAL_PRICE,
7896                                    'tax': this.result.TOTAL.TAX_PRICE,
7897                                    'shipping': this.result.TOTAL.DELIVERY_PRICE
7898                                },
7899                                'products': products
7900                            }
7901                        }
7902                    };
7903                    break;
7904            }
7905
7906            window[this.params.DATA_LAYER_NAME] = window[this.params.DATA_LAYER_NAME] || [];
7907            window[this.params.DATA_LAYER_NAME].push(info);
7908        },
7909
7910        isOrderSaveAllowed: function () {
7911            return this.orderSaveAllowed === true;
7912        },
7913
7914        allowOrderSave: function () {
7915            this.orderSaveAllowed = true;
7916        },
7917
7918        disallowOrderSave: function () {
7919            this.orderSaveAllowed = false;
7920        },
7921
7922        initUserConsent: function () {
7923            BX.ready(BX.delegate(function () {
7924                var control = BX.UserConsent && BX.UserConsent.load(this.orderBlockNode);
7925                if (control) {
7926                    BX.addCustomEvent(control, BX.UserConsent.events.save, BX.proxy(this.doSaveAction, this));
7927                    BX.addCustomEvent(control, BX.UserConsent.events.refused, BX.proxy(this.disallowOrderSave, this));
7928                }
7929            }, this));
7930        },
7931
7932        buyOneClickFormHide: function () {
7933            $(".bx-soa-cart-total-data").addClass("animate__fadeInBlock").show();
7934            $(".bx-soa-cart-total-form").removeClass("animate__fadeInBlock").hide();
7935        },
7936
7937        buyOneClickFormShow: function () {
7938            $(".bx-soa-cart-total-data").removeClass("animate__fadeInBlock").hide();
7939            $(".bx-soa-cart-total-form").addClass("animate__fadeInBlock").show();
7940        },
7941
7942        buyOneClickFormSend: function (btn) {
7943            var oneClickForm = $(btn).closest(".bx-soa-cart-total-form");
7944            var msgBox = oneClickForm.find(".bx-soa-cart-total-form-message-box");
7945            var requiredInputs = oneClickForm.find(":required");
7946            var _this = this;
7947
7948            var isValidForm = true;
7949
7950            requiredInputs.each(function () {
7951                if ($(this).val().length < 2) {
7952                    $(this).addClass("error");
7953                    isValidForm = false;
7954                } else {
7955                    if ($(this).is(".error")) {
7956                        $(this).removeClass("error");
7957                    }
7958                }
7959            });
7960
7961            var fields = {
7962                "full_name": oneClickForm.find("[name='full_name']").val(),
7963                "phone": oneClickForm.find("[name='phone']").val(),
7964                "email": oneClickForm.find("[name='email']").val(),
7965                "sessid": BX.bitrix_sessid()
7966            };
7967
7968            var comment = oneClickForm.find("[name='comment']");
7969            var captcha_code = oneClickForm.find("[name='captcha_code']");
7970            var captcha_word = oneClickForm.find("[name='captcha_word']");
7971
7972            if (comment.length > 0) {
7973                fields["comment"] = comment.val();
7974            }
7975
7976            if (captcha_code.length > 0) {
7977                fields["captcha_code"] = captcha_code.val();
7978                fields["captcha_word"] = captcha_word.val();
7979            }
7980
7981            if (isValidForm) {
7982                this.startLoader();
7983
7984                $.post(
7985                    this.templateFolder + "/ajax/one_click_order_ajax.php",
7986                    fields,
7987                    function (result) {
7988                        if (result.success) {
7989                            window.location.href = _this.params.CURRENT_PAGE + "?ORDER_ID=" + result.data.ORDER_ID;
7990                        } else {
7991                            msgBox.addClass("error").html("");
7992
7993                            if (result.errors.length < 1) {
7994                                result.errors.push(_this.params.MESS_TOTAL_BLOCK_BUY_ONE_CLICK_FORM_UNKNOWN_ERROR);
7995                            }
7996
7997                            result.errors.forEach(function (item) {
7998                                msgBox.append("<p>" + item + "</p>");
7999                            });
8000                        }
8001
8002                        setTimeout(function () {
8003                            BX.Sale.OrderAjaxComponent.endLoader();
8004                        }, 400);
8005                    },
8006                    "json"
8007                );
8008            }
8009        },
8010
8011        autoLoadLegalDataByINN: function (btn) {
8012            if (
8013                this.params.USE_LEGAL_ENTITY_AUTOLOAD_DATA == "Y" &&
8014                this.params.AUTOLOAD_LEGAL_INN.length > 0
8015            ) {
8016                var inn = document.querySelector(
8017                    ".tanais-order #soa-property-" +
8018                    this.getOrderPropertyIdByCode(this.params.AUTOLOAD_LEGAL_INN)
8019                );
8020
8021                if (inn !== null && inn.value.length > 0) {
8022                    this.startLoader();
8023
8024                    $.post(
8025                        this.templateFolder + "/ajax/get_data_for_legal_inn_ajax.php",
8026                        {
8027                            "inn": inn.value,
8028                            "sessid": BX.bitrix_sessid()
8029                        },
8030                        function (result) {
8031                            var orderAjaxComponent = BX.Sale.OrderAjaxComponent;
8032
8033                            var kpp = document.querySelector(
8034                                ".tanais-order #soa-property-" +
8035                                orderAjaxComponent.getOrderPropertyIdByCode(
8036                                    orderAjaxComponent.params.AUTOLOAD_LEGAL_KPP
8037                                )
8038                            );
8039
8040                            var companyAddr = document.querySelector(
8041                                ".tanais-order #soa-property-" +
8042                                orderAjaxComponent.getOrderPropertyIdByCode(
8043                                    orderAjaxComponent.params.AUTOLOAD_LEGAL_COMPANY_ADDR
8044                                )
8045                            );
8046
8047                            var company = document.querySelector(
8048                                ".tanais-order #soa-property-" +
8049                                orderAjaxComponent.getOrderPropertyIdByCode(
8050                                    orderAjaxComponent.params.AUTOLOAD_LEGAL_COMPANY
8051                                )
8052                            );
8053
8054                            if (result.success) {
8055                                var resultData = result.data;
8056
8057                                if (kpp !== null && (typeof resultData.data.kpp !== "undefined")) {
8058                                    kpp.value = resultData.data.kpp;
8059                                }
8060
8061                                if (companyAddr !== null && (typeof resultData.data.address.value !== "undefined")) {
8062                                    companyAddr.value = resultData.data.address.value;
8063                                }
8064
8065                                if (company !== null && (typeof resultData.value !== "undefined")) {
8066                                    company.value = resultData.value;
8067                                }
8068                            } else {
8069                                if (kpp !== null) kpp.value = "";
8070                                if (companyAddr !== null) companyAddr.value = "";
8071                                if (company !== null) company.value = "";
8072
8073                                console.log(result.errors);
8074                            }
8075
8076                            setTimeout(function () {
8077                                orderAjaxComponent.endLoader();
8078                            }, 400);
8079                        },
8080                        "json"
8081                    );
8082                }
8083
8084            }
8085        },
8086
8087        autocompleteCompany: function () {
8088            var _this = this;
8089            var inputValue = _this.value;
8090            var orderComponent = BX.Sale.OrderAjaxComponent;
8091
8092            if (inputValue.trim().length > 1) {
8093                $.post(
8094                    orderComponent.templateFolder + "/ajax/get_data_for_suggest_ajax.php",
8095                    {
8096                        "company_name": inputValue,
8097                        "sessid": BX.bitrix_sessid()
8098                    },
8099                    function (result) {
8100                        if (result.success) {
8101                            var items = result.data.map(function (item) {
8102                                return $('<span>')
8103                                    .text(item.value)
8104                                    .attr('data-inn', item.data.inn);
8105                            });
8106
8107                            $(_this).next(".soa-suggests-company-container")
8108                                .fadeIn()
8109                                .find(".soa-suggests-company-block")
8110                                .empty()
8111                                .append(items)
8112                                .find("span")
8113                                .on("click", function () {
8114                                    var selected = $(this);
8115                                    var inn = selected.attr('data-inn');
8116
8117                                    var innField = document.querySelector(
8118                                        ".tanais-order #soa-property-" +
8119                                        orderComponent.getOrderPropertyIdByCode(
8120                                            orderComponent.params.AUTOLOAD_LEGAL_INN
8121                                        )
8122                                    );
8123
8124                                    if (innField) {
8125                                        innField.value = inn;
8126                                        orderComponent.autoLoadLegalDataByINN();
8127                                    }
8128
8129                                    $(this).closest(".soa-suggests-company-block").html("");
8130                                    $(this).closest(".soa-suggests-company-container").fadeOut();
8131                                });
8132                        } else {
8133                            console.log(result.errors);
8134                        }
8135                    },
8136                    "json"
8137                );
8138            }
8139        },
8140
8141        autocompleteAddr: function () {
8142            var _this = this;
8143            var inputValue = _this.value;
8144            var numericValue = inputValue.replace(/\D/g, ''); // Оставляем только цифры
8145
8146            // Проверяем, находится ли поле внутри контейнера ИНН
8147            var isINNField = $(_this).closest('.has-soa-action-button').length > 0;
8148
8149            if (isINNField) {
8150                // Для поля ИНН: проверяем ровно 10 цифр
8151                if (numericValue.length === 10) {
8152                    // Находим кнопку и триггерим клик
8153                    var $button = $(_this).closest('.has-soa-action-button').find('.js-inn-autoload-btn');
8154                    if ($button.length) {
8155                        $button.trigger('click'); // Триггерим событие click
8156                    } else {
8157                        console.error('Кнопка для автозагрузки ИНН не найдена');
8158                    }
8159                }
8160            } else {
8161                // Для адреса: оригинальная логика (длина > 1)
8162                if (inputValue.trim().length > 1) {
8163                    $.post(
8164                        BX.Sale.OrderAjaxComponent.templateFolder + "/ajax/get_addr_suggest.php",
8165                        {
8166                            "addr": inputValue,
8167                            "sessid": BX.bitrix_sessid()
8168                        },
8169                        function (result) {
8170                            if (result.success) {
8171                                var items = result.data.map(function (item) {
8172                                    return "<span>" + item.value + "</span>";
8173                                });
8174                                $(_this).next(".soa-suggests-container")
8175                                    .fadeIn()
8176                                    .find(".soa-suggests-block")
8177                                    .html(items.join(""))
8178                                    .find("span")
8179                                    .on("click", function () {
8180                                        _this.value = $(this).text();
8181                                        $(this).closest(".soa-suggests-block").html("");
8182                                        $(this).closest(".soa-suggests-container").fadeOut();
8183                                    });
8184                            } else {
8185                                console.log(result.errors);
8186                            }
8187                        },
8188                        "json"
8189                    );
8190                }
8191            }
8192        },
8193
8194        getOrderPropertyIdByCode: function (code) {
8195            for (var i = 0; i < this.result.ORDER_PROP.properties.length; i++) {
8196                if (this.result.ORDER_PROP.properties[i]["CODE"] == code) {
8197                    return this.result.ORDER_PROP.properties[i]["ID"];
8198                }
8199            }
8200
8201            return 0;
8202        }
8203    };
8204})();
8205
8206$(function () {
8207
8208    if (typeof BX.Sale.OrderAjaxComponent.params !== "undefined") {
8209        $(".tanais-order .bx-soa-cart-total-form [autocomplete='tel']").mask(
8210            BX.Sale.OrderAjaxComponent.params.PHONE_INPUT_MASK
8211        );
8212    }
8213
8214    // Находим статический родительский элемент (например, контейнер корзин
8214ы)
8215    var cartContainer = document.querySelector('#bx-soa-properties'); // Укажите правильный селектор
8216
8217    if (cartContainer) {
8218        // Делегирование события input для поля ИНН
8219        cartContainer.addEventListener('input', function (event) {
8220            var target = event.target;
8221            if (target.matches('.has-soa-action-button input[type="text"]')) {
8222                var inputValue = target.value.replace(/\D/g, ''); // Оставляем только цифры
8223                if (inputValue.length === 10) {
8224                    var button = target.closest('.has-soa-action-button').querySelector('.js-inn-autoload-btn');
8225                    if (button) {
8226                        button.click(); // Триггерим клик по кнопке
8227                    }
8228                }
8229            }
8230        });
8231
8232        // Делегирование события click для кнопки
8233        cartContainer.addEventListener('click', function (event) {
8234            var target = event.target;
8235            if (target.matches('.js-inn-autoload-btn')) {
8236                autoLoadLegalDataByINN.call(target);
8237            }
8238        });
8239    }
8240});
8241
8242/* End */
8243;
8244; /* Start:"a:4:{s:4:"full";s:102:"/bitrix/components/bitrix/sale.location.selector.steps/templates/.default/script.min.js?17882900517752";s:6:"source";s:83:"/bitrix/components/bitrix/sale.location.selector.steps/templates/.default/script.js";s:3:"min";s:87:"/bitrix/components/bitrix/sale.location.selector.steps/templates/.default/script.min.js";s:3:"map";s:87:"/bitrix/components/bitrix/sale.location.selector.steps/templates/.default/script.map.js";}"*/
8245BX.namespace("BX.Sale.component.location.selector");if(typeof BX.Sale.component.location.selector.steps=="undefined"&&typeof BX.ui!="undefined"&&typeof BX.ui.widget!="undefined"){BX.Sale.component.location.selector.steps=function(e,t){this.parentConstruct(BX.Sale.component.location.selector.steps,e);BX.merge(this,{opts:{bindEvents:{"after-select-item":function(e){if(typeof this.opts.callback=="string"&&this.opts.callback.length>0&&this.opts.callback in window)window[this.opts.callback].apply(this,[e,this])}},disableKeyboardInput:false,dontShowNextChoice:false,pseudoValues:[],provideLinkBy:"id",requestParamsInject:false},vars:{cache:{nodesByCode:{}}},sys:{code:"slst"},flags:{skipAfterSelectItemEventOnce:false}});this.handleInitStack(t,BX.Sale.component.location.selector.steps,e)};BX.extend(BX.Sale.component.location.selector.steps,BX.ui.chainedSelectors);BX.merge(BX.Sale.component.location.selector.steps.prototype,{init:function(){this.pushFuncStack("buildUpDOM",BX.Sale.component.location.selector.steps);this.pushFuncStack("bindEvents",BX.Sale.component.location.selector.steps)},buildUpDOM:function(){},bindEvents:function(){var e=this,t=this.opts;if(t.disableKeyboardInput){this.bindEvent("after-control-placed",function(e){var t=e.getControl();BX.unbindAll(t.ctrls.toggle);BX.bind(t.ctrls.scope,"click",function(e){t.toggleDropDown()})})}BX.bindDelegate(this.getControl("quick-locations",true),"click",{tag:"a"},function(){e.setValueByLocationId(BX.data(this,"id"))})},setValueByLocationId:function(e){BX.Sale.component.location.selector.steps.superclass.setValue.apply(this,[e])},setValueByLocationIds:function(e){if(!e.PARENT_ID)return;this.flags.skipAfterSelectItemEventOnce=true;this.setValueByLocationId(e.PARENT_ID);this.bindEvent("after-control-placed",function(t){var s=t.getControl();if(s.vars.value!=false)return;if(e.IDS)this.opts.requestParamsInject={filter:{"=ID":e.IDS}};s.tryDisplayPage("toggle")})},setValueByLocationCode:function(e){var t=this.vars;if(e==null||e==false||typeof e=="undefined"||e.toString().length==0){this.displayRoute([]);this.setValueVariable("");this.setTargetValue("");this.fireEvent("after-clear-selection");return}this.fireEvent("before-set-value",[e]);var s=new BX.deferred;var i=this;s.done(BX.proxy(function(s){this.displayRoute(s);var i=t.cache.nodesByCode[e].VALUE;t.value=i;this.setTargetValue(this.checkCanSelectItem(i)?i:this.getLastValidValue())},this));s.fail(function(e){if(e=="notfound"){i.displayRoute([]);i.setValueVariable("");i.setTargetValue("");i.showError({errors:[i.opts.messages.nothingFound],type:"server-logic",options:{}})}});this.hideError();this.getRouteToNodeByCode(e,s)},setValue:function(e){if(this.opts.provideLinkBy=="id")BX.Sale.component.location.selector.steps.superclass.setValue.apply(this,[e]);else this.setValueByLocationCode(e)},setTargetValue:function(e){this.setTargetInputValue(this.opts.provideLinkBy=="code"?e?this.vars.cache.nodes[e].CODE:"":e);if(!this.flags.skipAfterSelectItemEventOnce)this.fireEvent("after-select-item",[e]);else this.flags.skipAfterSelectItemEventOnce=false},getValue:function(){if(this.opts.provideLinkBy=="id")return this.vars.value===false?"":this.vars.value;else{return this.vars.value?this.vars.cache.nodes[this.vars.value].CODE:""}},getNodeByLocationId:function(e){return this.vars.cache.nodes[e]},getSelectedPath:function(){var e=this.vars,t=[];if(typeof e.value=="undefined"||e.value==false||e.value=="")return t;if(typeof e.cache.nodes[e.value]!="undefined"){var s=e.cache.nodes[e.value];
8245while(typeof s!="undefined"){var i=BX.clone(s);var n=i.PARENT_VALUE;delete i.PATH;delete i.PARENT_VALUE;delete i.IS_PARENT;if(typeof i.TYPE_ID!="undefined"&&typeof this.opts.types!="undefined")i.TYPE=this.opts.types[i.TYPE_ID].CODE;t.push(i);if(typeof n=="undefined"||typeof e.cache.nodes[n]=="undefined")break;else s=e.cache.nodes[n]}}return t},setInitialValue:function(){if(this.opts.selectedItem!==false)this.setValueByLocationId(this.opts.selectedItem);else if(this.ctrls.inputs.origin.value.length>0){if(this.opts.provideLinkBy=="id")this.setValueByLocationId(this.ctrls.inputs.origin.value);else this.setValueByLocationCode(this.ctrls.inputs.origin.value)}},getRouteToNodeByCode:function(e,t){var s=this.vars,i=this;if(typeof e!="undefined"&&e!==false&&e.toString().length>0){var n=[];if(typeof s.cache.nodesByCode[e]!="undefined")n=this.getRouteToNodeFromCache(s.cache.nodesByCode[e].VALUE);if(n.length==0){i.downloadBundle({request:{CODE:e},callbacks:{onLoad:function(o){for(var a in o){if(typeof s.cache.links[a]=="undefined")s.cache.incomplete[a]=true}i.fillCache(o,true);n=[];if(typeof s.cache.nodesByCode[e]!="undefined")n=this.getRouteToNodeFromCache(s.cache.nodesByCode[e].VALUE);if(n.length==0)t.reject("notfound");else t.resolve(n)},onError:function(){t.reject("internal")}},options:{}})}else t.resolve(n)}else t.resolve([])},addItem2Cache:function(e){this.vars.cache.nodes[e.VALUE]=e;this.vars.cache.nodesByCode[e.CODE]=e},controlChangeActions:function(e,t){var s=this,i=this.opts,n=this.vars,o=this.ctrls;this.hideError();if(t.length==0){s.truncateStack(e);n.value=s.getLastValidValue();s.setTargetValue(n.value);this.fireEvent("after-select-real-value")}else if(BX.util.in_array(t,i.pseudoValues)){s.truncateStack(e);s.setTargetValue(s.getLastValidValue());this.fireEvent("after-select-item",[t]);this.fireEvent("after-select-pseudo-value")}else{var a=n.cache.nodes[t];if(typeof a=="undefined")throw new Error("Selected node not found in the cache");s.truncateStack(e);if(i.dontShowNextChoice){if(a.IS_UNCHOOSABLE)s.appendControl(t)}else{if(typeof n.cache.links[t]!="undefined"||a.IS_PARENT)s.appendControl(t)}if(s.checkCanSelectItem(t)){n.value=t;s.setTargetValue(t);this.fireEvent("after-select-real-value")}}},refineRequest:function(e){var t={};var s={VALUE:"ID",DISPLAY:"NAME.NAME",1:"TYPE_ID",2:"CODE"};var i={};if(typeof e["PARENT_VALUE"]!="undefined"){t["=PARENT_ID"]=e.PARENT_VALUE;s["10"]="IS_PARENT"}if(typeof e["VALUE"]!="undefined"){t["=ID"]=e.VALUE;i["1"]="PATH"}if(BX.type.isNotEmptyString(e["CODE"])){t["=CODE"]=e.CODE;i["1"]="PATH"}if(BX.type.isNotEmptyString(this.opts.query.BEHAVIOUR.LANGUAGE_ID))t["=NAME.LANGUAGE_ID"]=this.opts.query.BEHAVIOUR.LANGUAGE_ID;if(BX.type.isNotEmptyString(this.opts.query.FILTER.SITE_ID)){if(typeof this.vars.cache.nodes[e.PARENT_VALUE]=="undefined"||this.vars.cache.nodes[e.PARENT_VALUE].IS_UNCHOOSABLE)t["=SITE_ID"]=this.opts.query.FILTER.SITE_ID}var n={select:s,filter:t,additionals:i,version:"2"};if(this.opts.requestParamsInject){for(var o in this.opts.requestParamsInject){if(this.opts.requestParamsInject.hasOwnProperty(o)){if(n[o]==undefined)n[o]={};for(var a in this.opts.requestParamsInject[o]){if(this.opts.requestParamsInject[o].hasOwnProperty(a)){if(n[o][a]!=undefined){var r=n[o][a];n[o][a]=[];n[o][a].push(r)}else{n[o][a]=[]}for(var l in this.opts.requestParamsInject[o][a])if(this.opts.requestParamsInject[o][a].hasOwnProperty(l))n[o][a].push(this.opts.requestParamsInject[o][a][l])}}}}}return n},refineResponce:function(e,t){if(e.length==0)return e;if(typeof t.PARENT_VALUE!="undefined"){var s={};s[t.PARENT_VALUE]=e["ITEMS"];e=s}else if(typeof t.VALUE!="undefined"||typeof t.CODE!="undefined"){var i={};if(typeof e.ITEMS[0]!="undefined"&&typeof e.ETC.PATH_ITEMS!="undefined"){var n=0;for(var o=e.ITEMS[0]["PATH"].length-1;o>=0;o--){var a=e.ITEMS[0]["PATH"][o];var r=e.ETC.PATH_ITEMS[a];r.IS_PARENT=true;i[n]=[r];n=r.VALUE}i[n]=[e.ITEMS[0]]}e=i}return e},showError:function(e){if(e.type!="server-logic")e.errors=[this.opts.messages.error];this.ctrls.errorMessage.innerHTML='<p><font class="errortext">'+BX.util.htmlspecialchars(e.errors.join(", "))+"</font></p>";BX.show(this.ctrls.errorMessage);BX.debug(e)}})}
8246/* End */
8247;
8248; /* Start:"a:4:{s:4:"full";s:129:"/bitrix/templates/design2025/components/bitrix/sale.order.ajax/tanais.order.ajax/scripts/jquery.maskedinput.min.js?17882900634330";s:6:"source";s:114:"/bitrix/templates/design2025/components/bitrix/sale.order.ajax/tanais.order.ajax/scripts/jquery.maskedinput.min.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
8249/*
8250    jQuery Masked Input Plugin
8251    Copyright (c) 2007 - 2015 Josh Bush (digitalbush.com)
8252    Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license)
8253    Version: 1.4.1
8254*/
8255!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){var b,c=navigator.userAgent,d=/iphone/i.test(c),e=/chrome/i.test(c),f=/android/i.test(c);a.mask={definitions:{9:"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"},autoclear:!0,dataName:"rawMaskFn",placeholder:"_"},a.fn.extend({caret:function(a,b){var c;if(0!==this.length&&!this.is(":hidden"))return"number"==typeof a?(b="number"==typeof b?b:a,this.each(function(){this.setSelectionRange?this.setSelectionRange(a,b):this.createTextRange&&(c=this.createTextRange(),c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",a),c.select())})):(this[0].setSelectionRange?(a=this[0].selectionStart,b=this[0].selectionEnd):document.selection&&document.selection.createRange&&(c=document.selection.createRange(),a=0-c.duplicate().moveStart("character",-1e5),b=a+c.text.length),{begin:a,end:b})},unmask:function(){return this.trigger("unmask")},mask:function(c,g){var h,i,j,k,l,m,n,o;if(!c&&this.length>0){h=a(this[0]);var p=h.data(a.mask.dataName);return p?p():void 0}return g=a.extend({autoclear:a.mask.autoclear,placeholder:a.mask.placeholder,completed:null},g),i=a.mask.definitions,j=[],k=n=c.length,l=null,a.each(c.split(""),function(a,b){"?"==b?(n--,k=a):i[b]?(j.push(new RegExp(i[b])),null===l&&(l=j.length-1),k>a&&(m=j.length-1)):j.push(null)}),this.trigger("unmask").each(function(){function h(){if(g.completed){for(var a=l;m>=a;a++)if(j[a]&&C[a]===p(a))return;g.completed.call(B)}}function p(a){return g.placeholder.charAt(a<g.placeholder.length?a:0)}function q(a){for(;++a<n&&!j[a];);return a}function r(a){for(;--a>=0&&!j[a];);return a}function s(a,b){var c,d;if(!(0>a)){for(c=a,d=q(b);n>c;c++)if(j[c]){if(!(n>d&&j[c].test(C[d])))break;C[c]=C[d],C[d]=p(d),d=q(d)}z(),B.caret(Math.max(l,a))}}function t(a){var b,c,d,e;for(b=a,c=p(a);n>b;b++)if(j[b]){if(d=q(b),e=C[b],C[b]=c,!(n>d&&j[d].test(e)))break;c=e}}function u(){var a=B.val(),b=B.caret();if(o&&o.length&&o.length>a.length){for(A(!0);b.begin>0&&!j[b.begin-1];)b.begin--;if(0===b.begin)for(;b.begin<l&&!j[b.begin];)b.begin++;B.caret(b.begin,b.begin)}else{for(A(!0);b.begin<n&&!j[b.begin];)b.begin++;B.caret(b.begin,b.begin)}h()}function v(){A(),B.val()!=E&&B.change()}function w(a){if(!B.prop("readonly")){var b,c,e,f=a.which||a.keyCode;o=B.val(),8===f||46===f||d&&127===f?(b=B.caret(),c=b.begin,e=b.end,e-c===0&&(c=46!==f?r(c):e=q(c-1),e=46===f?q(e):e),y(c,e),s(c,e-1),a.preventDefault()):13===f?v.call(this,a):27===f&&(B.val(E),B.caret(0,A()),a.preventDefault())}}function x(b){if(!B.prop("readonly")){var c,d,e,g=b.which||b.keyCode,i=B.caret();if(!(b.ctrlKey||b.altKey||b.metaKey||32>g)&&g&&13!==g){if(i.end-i.begin!==0&&(y(i.begin,i.end),s(i.begin,i.end-1)),c=q(i.begin-1),n>c&&(d=String.fromCharCode(g),j[c].test(d))){if(t(c),C[c]=d,z(),e=q(c),f){var k=function(){a.proxy(a.fn.caret,B,e)()};setTimeout(k,0)}else B.caret(e);i.begin<=m&&h()}b.preventDefault()}}}function y(a,b){var c;for(c=a;b>c&&n>c;c++)j[c]&&(C[c]=p(c))}function z(){B.val(C.join(""))}function A(a){var b,c,d,e=B.val(),f=-1;for(b=0,d=0;n>b;b++)if(j[b]){for(C[b]=p(b);d++<e.length;)if(c=e.charAt(d-1),j[b].test(c)){C[b]=c,f=b;break}if(d>e.length){y(b+1,n);break}}else C[b]===e.charAt(d)&&d++,k>b&&(f=b);return a?z():k>f+1?g.autoclear||C.join("")===D?(B.val()&&B.val(""),y(0,n)):z():(z(),B.val(B.val().substring(0,f+1))),k?b:l}var B=a(this),C=a.map(c.split(""),function(a,b){return"?"!=a?i[a]?p(b):a:void 0}),D=C.join(""),E=B.val();B.data(a.mask.dataName,function(){return a.map(C,function(a,b){return j[b]&&a!=p(b)?a:null}).join("")}),B.one("unmask",function(){B.off(".mask").removeData(a.mask.dataName)}).on("focus.mask",function(){if(!B.prop("readonly")){clearTimeout(b);var a;E=B.val(),a=A(),b=setTimeout(function(){B.get(0)===document.activeElement&&(z(),a==c.replace("?","").length?B.caret(0,a):B.caret(a))},10)}}).on("blur.mask",v).on("keydown.mask",w).on("keypress.mask",x).on("input.mask paste.mask",function(){B.prop("readonly")||setTimeout(function(){var a=A(!0);B.caret(a),h()},0)}),e&&f&&B.off("input.mask").on("input.mask",u),A()})}})});
8256/* End */
8257;; /* /bitrix/templates/design2025/components/bitrix/sale.order.ajax/tanais.order.ajax/script.
8257js?178829006313420*/
8258; /* /bitrix/templates/design2025/components/bitrix/sale.order.ajax/tanais.order.ajax/order_ajax.js?1788290063335535*/
8259; /* /bitrix/components/bitrix/sale.location.selector.steps/templates/.default/script.min.js?17882900517752*/
8260; /* /bitrix/templates/design2025/components/bitrix/sale.order.ajax/tanais.order.ajax/scripts/jquery.maskedinput.min.js?17882900634330*/
8261
8262//# sourceMappingURL=page_e44e37779a1c1bdca1e610e79768ddc1.map.js

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.