PageSourceSearch

https://vsestabilizatory.ru/theme/js/cart.js

js vsestabilizatory.ru collected 2026-10-09 22:43:17 UTC 19,919 bytes, 551 lines download raw bytes

1$(function() {
2
3cart = new Vue({
4  data: {
5    DELIVERY_COURIER: 0,
6    DELIVERY_PICKUP: 2,
7    PAYER_INDIVIDUAL: 1,
8    PAYER_LEGAL: 2,
9    PAY_CASH: 1,
10    PAY_BILL: 2,
11    PAY_CARD: 3,
12    products: CART,
13    delivery: 0,
14    payer: 1,
15    pay: 1,
16    name: '',
17    address: '',
18    phone: '',
19    email: '',
20    comments: '',
21    yur_payer: '',
22    yur_address: '',
23    yur_inn: '',
24    yur_kpp: '',
25    yur_rs: '',
26    yur_bank: '',
27    yur_ks: '',
28    yur_bik: '',
29    distance: 0,
30    calculating_delivery: false,
31    calculating_pickup: false,
32    delivery_location: undefined,		// 0/1/2 - нет доставки/по городу/за город
33    pvz: undefined,
34    ymaps_ready: false,
35    pickups_ready: false,
36    inprogress: false,
37    order_num: undefined,
38    coupons: [],
39    coupon: '',
40  },
41  methods: {
42    getProductSum: getProductSum,
43    getProductsCount: getProductsCount,
44    onDeleteProductClick: onDeleteProductClick,
45    onProductQuantityChange: onProductQuantityChange,
46    ajaxDeleteProduct: ajaxDeleteProduct,
47    ajaxUpdateCart: ajaxUpdateCart,
48    updateCounterIcon: updateCounterIcon,
49    calcDelivery: calcDelivery,
50    showDeliveryMap: showDeliveryMap,
51    onCalcDeliveryFinish: onCalcDeliveryFinish,
52    onCalcDeliveryError: onCalcDeliveryError,
53    onCalcDeliveryAddressFound: onCalcDeliveryAddressFound,
54    onCalcPickupFinish: onCalcPickupFinish,
55    onCalcPickupError: onCalcPickupError,
56    focusAddrInput: focusAddrInput,
57    showPickup: showPickup,
58    showDelivery: showDelivery,
59    onPickupSelect: onPickupSelect,
60    onPickupsReady: onPickupsReady,
61    getCargo: getCargo,
62    updateCargo: updateCargo,
63    getYMClientID: getYMClientID,
64    validate: validate,
65    onSubmit: onSubmit,
66    indexOfCoupon: indexOfCoupon,
67    loadCoupons: loadCoupons,
68    MD5: function(d){var r = M(V(Y(X(d),8*d.length)));return r.toLowerCase();function M(d){for(var _,m="0123456789ABCDEF",f="",r=0;r<d.length;
68r++)_=d.charCodeAt(r),f+=m.charAt(_>>>4&15)+m.charAt(15&_);return f}function X(d){for(var _=Array(d.length>>2),m=0;m<_.length;m++)_[m]=0;for(m=0;m<8*d.length;m+=8)_[m>>5]|=(255&d.charCodeAt(m/8))<<m%32;return _}function V(d){for(var _="",m=0;m<32*d.length;m+=8)_+=String.fromCharCode(d[m>>5]>>>m%32&255);return _}function Y(d,_){d[_>>5]|=128<<_%32,d[14+(_+64>>>9<<4)]=_;for(var m=1732584193,f=-271733879,r=-1732584194,i=271733878,n=0;n<d.length;n+=16){var h=m,t=f,g=r,e=i;f=md5_ii(f=md5_ii(f=md5_ii(f=md5_ii(f=md5_hh(f=md5_hh(f=md5_hh(f=md5_hh(f=md5_gg(f=md5_gg(f=md5_gg(f=md5_gg(f=md5_ff(f=md5_ff(f=md5_ff(f=md5_ff(f,r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+0],7,-680876936),f,r,d[n+1],12,-389564586),m,f,d[n+2],17,606105819),i,m,d[n+3],22,-1044525330),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+4],7,-176418897),f,r,d[n+5],12,1200080426),m,f,d[n+6],17,-1473231341),i,m,d[n+7],22,-45705983),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+8],7,1770035416),f,r,d[n+9],12,-1958414417),m,f,d[n+10],17,-42063),i,m,d[n+11],22,-1990404162),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+12],7,1804603682),f,r,d[n+13],12,-40341101),m,f,d[n+14],17,-1502002290),i,m,d[n+15],22,1236535329),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+1],5,-165796510),f,r,d[n+6],9,-1069501632),m,f,d[n+11],14,643717713),i,m,d[n+0],20,-373897302),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+5],5,-701558691),f,r,d[n+10],9,38016083),m,f,d[n+15],14,-660478335),i,m,d[n+4],20,-405537848),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+9],5,568446438),f,r,d[n+14],9,-1019803690),m,f,d[n+3],14,-187363961),i,m,d[n+8],20,1163531501),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+13],5,-1444681467),f,r,d[n+2],9,-51403784),m,f,d[n+7],14,1735328473),i,m,d[n+12],20,-1926607734),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+5],4,-378558),f,r,d[n+8],11,-2022574463),m,f,d[n+11],16,1839030562),i,m,d[n+14],23,-35309556),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+1],4,-1530992060),f,r,d[n+4],11,1272893353),m,f,d[n+7],16,-155497632),i,m,d[n+10],23,-1094730640),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+13],4,681279174),f,r,d[n+0],11,-358537222),m,f,d[n+3],16,-722521979),i,m,d[n+6],23,76029189),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+9],4,-640364487),f,r,d[n+12],11,-421815835),m,f,d[n+15],16,530742520),i,m,d[n+2],23,-995338651),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+0],6,-198630844),f,r,d[n+7],10,1126891415),m,f,d[n+14],15,-1416354905),i,m,d[n+5],21,-57434055),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+12],6,1700485571),f,r,d[n+3],10,-1894986606),m,f,d[n+10],15,-1051523),i,m,d[n+1],21,-2054922799),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+8],6,1873313359),f,r,d[n+15],10,-30611744),m,f,d[n+6],15,-1560198380),i,m,d[n+13],21,1309151649),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+4],6,-145523070),f,r,d[n+11],10,-1120210379),m,f,d[n+2],15,718787259),i,m,d[n+9],21,-343485551),m=safe_add(m,h),f=safe_add(f,t),r=safe_add(r,g),i=safe_add(i,e)}return Array(m,f,r,i)}function md5_cmn(d,_,m,f,r,i){return safe_add(bit_rol(safe_add(safe_add(_,d),safe_add(f,i)),r),m)}function md5_ff(d,_,m,f,r,i,n){return md5_cmn(_&m|~_&f,d,_,r,i,n)}function md5_gg(d,_,m,f,r,i,n){return md5_cmn(_&f|m&~f,d,_,r,i,n)}function md5_hh(d,_,m,f,r,i,n){return md5_cmn(_^m^f,d,_,r,i,n)}function md5_ii(d,_,m,f,r,i,n){return md5_cmn(m^(_|~f),d,_,r,i,n)}function safe_add(d,_){var m=(65535&d)+(65535&_);return(d>>16)+(_>>16)+(m>>16)<<16|65535&m}function bit_rol(d,_){return d<<_|d>>>32-_}},
69  },
70  computed: {
71    cartCost: getCartCost,
72    totalCost: getTotalCost,
73    deliveryCost: getDeliveryCost,
74    suburbDistance: getSuburbDistance,
75    couponDiscountPercent: getCouponDiscountPercent,
76    couponDiscount: getCouponDiscount,
77    commentsWithMessage: getcommentsWithMessage,
78  },
79  filters: {
80    currency: formatPrice,
81  },
82  watch: {
83    payer: onPayerChange,
84    pay: onPayChange,
85    address: onAddressChange,
86    coupon: onCouponChange,
87  },
88  components: {},
89  mounted: function() {},
90  created: function() {
91      this.loadCoupons();
92      var instance = this;
93      ymaps.ready(function(){
94        window.idm = new InteractiveDeliveryMap({
95          cargo: instance.getCargo(),
96          onPickupsReady: instance.onPickupsReady,
97          onCalcDeliveryFinish: instance.onCalcDeliveryFinish,
98          onCalcDeliveryError: instance.onCalcDeliveryError,
99          onCalcDeliveryAddressFound: instance.onCalcDeliveryAddressFound,
100          onPickupSelect: instance.onPickupSelect,
101          onCalcPickupFinish: instance.onCalcPickupFinish,
102          onCalcPickupError: instance.onCalcPickupError,
103        });
104        instance.ymaps_ready = true;
105      });
106  },
107  el: '#cartapp',
108  template: '#cartapp-template',
109});
110
111//////////////////////////////////////////////////////////////
112function getProductSum(product) {
113  return product.price * product.quantity;
114}
115
116/////////////////////////////////////////////////////////////
117function getTotalCost(){
118  return this.cartCost + this.deliveryCost - this.couponDiscount;
119}
120
121/////////////////////////////////////////////
122function getProductsCount(){
123  return this.products.reduce(function(acc, item, index, arr){
124    return acc + item.quantity;
125  }, 0);
126}
127
128/////////////////////////////////////////////////////////////
129function onDeleteProductClick(product){
130  this.products = this.products.filter(function(prod){
131    return prod.code != product.code;
132  });
133  this.ajaxDeleteProduct(product);
134  this.updateCounterIcon();
135  this.updateCargo();
136  ecommerce_remove([{
137    'id': product.code,
138    'name': product.trademark + ' ' + product.model,
139    'brand': product.trademark,
140    'category': product.category,
141    'price': product.price,
142    'quantity': product.quantity,
143  }]);
144}
145
146/////////////////////////////////////////////
147function onProductQuantityChange(product){
148  this.ajaxUpdateCart();
149  this.updateCounterIcon();
150  this.updateCargo();
151  if (product.old_qty != product.quantity) {
152    prod = {
153      'id': product.code,
154      'name': product.trademark + ' ' + product.model,
155      'brand': product.trademark,
156      'category': product.category,
157      'price': product.price,
158      'quantity': Math.abs(product.quantity - product.old_qty),
159    }
160    if (product.quantity > product.old_qty)
161      ecommerce_add([prod]);
162    else
163      ecommerce_remove([prod]);
164    product.old_qty = product.quantity;
165  }
166}
167
168/////////////////////////////////////////////
169function ajaxDeleteProduct(product) {
170  $.ajax({
171    type: 'GET',
172    url: 'remove.php?product=' + product.code,
173    dataType: 'html',
174    data: {},
175    cache: false,
176    beforeSend : function(req) {},
177    complete: function() {},
178    error: function(xhr, ajaxOptions, thrownError) {},
179    success: function(data) {},
180  });
181}
182
183/////////////////////////////////////////////////////////////
184function ajaxUpdateCart() {
185  var data = {};
186  this.products.forEach(function(product, index, arr){
187    data[product.code] = (parseInt(product.quantity) || 1);
188  });
189  $.ajax({
190    type: 'POST',
191    url: 'update.php',
192    dataType: 'html',
193    data: data,
194    cache: false,
195    beforeSend : function(req) {},
196    complete: function() {},
197    error: function(xhr, ajaxOptions, thrownError) {},
198    success: function(data) {},
199  });
200}
201
202/////////////////////////////////////////////////////////////
203function updateCounterIcon(){
204  $('.powericon-cart + sup').text(this.getProductsCount());
205}
206
207/////////////////////////////////////////////////////////////
208function formatPrice(amount) {
209  return formatPriceCustom(amount, (amount == Math.round(amount) ? 0 : 2));
210}
211
212/////////////////////////////////////////////////////////////
213function formatPriceCustom(amount, denomination) {
214  return (amount !== null) ? parseFloat(amount).toFixed(denomination).replace(/(\d)(?=(\d{3})+(\.|$))/g, '$1 ') : '';
215}
216
217/////////////////////////////////////////////////////////////
218function onPayerChange(newVal, oldVal){
219  if (newVal == this.PAYER_LEGAL)
220    this.pay = this.PAY_BILL;
221}
222
223/////////////////////////////////////////////////////////////
224function onPayChange(newVal, oldVal){
225  if (newVal == this.PAY_CASH || newVal == this.PAY_CARD)
226    this.payer = this.PAYER_INDIVIDUAL;
227}
228
229/////////////////////////////////////////////////////////////
230function showDeliveryMap() {
231  var instance = this;
232  window.idm.showDelivery(this.address, false);
233}
234
235/////////////////////////////////////////////////////////////
236function calcDelivery() {
237  if (this.calculating_delivery || !this.ymaps_ready)
238    return;
239  var instance = this;
240  instance.calculating_delivery = true;
241  window.idm.calcDelivery(String(instance.address).trim());
242}
243
244/////////////////////////////////////////////////////////////
245function onCalcDeliveryFinish(delivery_location, dist) {
246  this.calculating_delivery = false;
247  if (delivery_location === undefined)
248    return;
249  this.delivery_location = delivery_location;
250  if (dist !== undefined)
251    this.distance = dist;
252}
253
254/////////////////////////////////////////////////////////////
255function onCalcDeliveryError(err) {
256  this.calculating_delivery = false;
257  console.log('calcDelivery() error: ' + err);
258}
259
260/////////////////////////////////////////////////////////////
261function onCalcDeliveryAddressFound(addr) {
262  addr = this.$refs.addrinput.transformAddress(addr);
263  this.address = addr;
264  return addr;
265}
266
267/////////////////////////////////////////////////////////////
268function focusAddrInput(){
269  this.$refs.addrinput.focus();
270}
271
272/////////////////////////////////////////////////////////////
273function getCartCost() {
274  return this.products.reduce(function(acc, item, index, arr){
275    return acc + getProductSum(item);
276  }, 0);
277}
278
279/////////////////////////////////////////////////////////////
280function getDeliveryCost() {
281  if (this.delivery_location >= 0) {
282    var delivery_cost = (this.cartCost < DELIVERY_FREE_LIMIT) ? DELIVERY_PRICE : 0;
283    delivery_cost += (this.delivery_location > 0) ? Math.round(this.suburbDistance * DELIVERY_EXTRA_PAY) : 0;
284    return delivery_cost
285  } else
286    return 0;
287}
288
289/////////////////////////////////////////////////////////////
290function onAddressChange(newVal, oldVal) {
291  if (typeof newVal === 'string' && newVal.trim() != oldVal)
292    this.delivery_location = undefined;
293}
294
295/////////////////////////////////////////////////////////////
296function getSuburbDistance() {
297  return (this.delivery_location > 0) ? Math.round(this.distance / 100) / 10 : 0;
298}
299
300/////////////////////////////////////////////////////////////
301function showPickup() {
302  var instance = this;
303  //setTimeout(function(){
304  window.idm.showPickup(instance.pvz ? instance.pvz.id : undefined);
305  //}, 1);
306}
307
308/////////////////////////////////////////////////////////////
309function showDelivery() {
310var instance = this;
311setTimeout(function(){
312  window.idm.showDelivery();
313}, 1);
314}
315
316/////////////////////////////////////////////////////////////
317function getCargo(){
318  return this.products.map(function(item, index, arr){
319    var newItem = {
320      id: item.code,
321      count: item.quantity,
322      price: item.price,
323    };
324    if (item.weight)
325      newItem.weight = item.weight;
326    if (item.volume)
327      newItem.volume = item.volume;
328    return newItem;
329  });
330}
331/////////////////////////////////////////////////////////////
332function onPickupSelect(pvz) {
333  this.pvz = JSON.parse(JSON.stringify(pvz));
334  if (this.pvz.inprogress == 1) {
335    this.calculating_pickup = true;
336    window.idm.calculatePickupPrice(this.pvz.id, this.getCargo());
337  }
338}
339
340/////////////////////////////////////////////////////////////
341function updateCargo() {
342  window.idm.setCargo(this.getCargo());
343  if (this.pvz) {
344    this.calculating_pickup = true;
345    window.idm.calculatePickupPrice(this.pvz.id, this.getCargo());
346  }
347}
348
349/////////////////////////////////////////////////////////////
350function onCalcPickupFinish(price) {
351  if (this.pvz)
352    this.pvz.price = price;
353  this.calculating_pickup = false;
354}
355
356/////////////////////////////////////////////////////////////
357function onCalcPickupError(err) {
358  if (this.pvz)
359    this.pvz.price = undefined;
360  this.calculating_pickup = false;
361}
362
363/////////////////////////////////////////////////////////////
364function onPickupsReady() {
365  this.pickups_ready = true;
366}
367
368/////////////////////////////////////////////////////////////
369function getYMClientID() {
370  try {
371    if (!window.hasOwnProperty('Ya') || !window.Ya.hasOwnProperty('_metrika') ||
372        !window.Ya._metrika.hasOwnProperty('counter') ||
373        !window.Ya._metrika.counter.hasOwnProperty('getClientID'))
374      return undefined;
375    return window.Ya._metrika.counter.getClientID();
376  } catch(e) {
377    console.log("Ошибка " + e.name + ": " + e.message);
378  }
379}
380
381/////////////////////////////////////////////////////////////
382function validate() {
383  // Задан адрес доставки?
384  if (this.delivery == this.DELIVERY_COURIER && String(this.address).length < 5 ) {
385    alert('Укажите адрес доставки');
386    return false;
387  }
388  // Задан пункт выдачи?
389  if (this.delivery == this.DELIVERY_PICKUP && this.pvz === undefined ) {
390    alert('Выберите пункт выдачи');
391    return false;
392  }
393  // Указан получатель?
394  if (String(this.name).length < 3 ) {
395    alert('Укажите Ф.И.О получателя');
396    return false;
397  }
398  // Указан телефон?
399  if (String(this.phone).length < 5 ) {
400    alert('Укажите контактный телефон');
401    return false;
402  }
403  // Указан e-mail при безналичной оплате?
404  if (this.pay == this.PAY_BILL && String(this.email).length < 5 ) {
405    alert('Укажите e-mail для получения счёта');
406    return false;
407  }
408  return true;
409}
410
411/////////////////////////////////////////////////////////////
412function onSubmit() {
413  if (this.inprogress)
414    return;
415  var instance = this;
416  if (instance.validate()) {
417    instance.inprogress = true;
418    var tt = {
419      dellin: 3,
420      cdek: 5,
421    }
422    var data = {
423      lname: instance.name,
424      phone: instance.phone,
425      comments: instance.commentsWithMessage,
426      customer: instance.payer,
427      payment: instance.pay,
428      delivery: instance.delivery,
429      address: instance.address,
430      yur_payer: instance.yur_payer,
431      yur_address: instance.yur_address,
432      yur_inn: instance.yur_inn,
433      yur_kpp: instance.yur_kpp,
434      yur_rs: instance.yur_rs,
435      yur_bank: instance.yur_bank,
436      yur_ks: instance.yur_ks,
437      yur_bik: instance.yur_bik,
438      email: instance.email,
439      ym_client_id: instance.getYMClientID(),
440    };
441    if (instance.pay == instance.PAY_BILL && instance.payer == instance.PAYER_INDIVIDUAL) {
442      data['fiz_fname'] = instance.name;
443    }
444    if (instance.delivery == instance.DELIVERY_PICKUP) {
445      data['delivery_city'] = instance.pvz.city;
446      if (instance.pvz.service_code === 'custom') {
447        data['delivery'] = 1;
448      } else {
449        data['transport_company'] = tt[instance.pvz.service_code];
450      }
451    }
452    $.ajax({
453      type: 'POST',
454      url: '/order.php',
455      dataType: 'html',
456      data: data,
457      cache: false,
458      beforeSend : function(req) {},
459      complete: function() {
460        instance.inprogress = false;
461      },
462      error: function(xhr, ajaxOptions, thrownError) {
463        errorMsg(AJAXErrorMessage(xhr, thrownError));
464      },
465      success: function(data) {
466        var res = data.match(/Order: (\d+)/i);
467        if (res.length == 2) {
468          instance.order_num = parseInt(res[1]);
469          var order_products = instance.products.map(function(item){
470            return {
471              'id': item.code,
472              'name': item.trademark + ' ' + item.model,
473              'brand': item.trademark,
474              'category': item.category,
475              'price': item.price,
476              'quantity': item.quantity,
477            };
478          });
479          ecommerce_purchase(instance.order_num, order_products);
480        } else {
481          errorMsg('Неизвестная ошибка. Попробуйте еще раз.');
482        }
483      },
484    });
485  }
486}
487
488/////////////////////////////////////////////////////////////
489function onCouponChange(newVal, olVal) {
490  if (newVal !== olVal) {
491    this.coupon = String(newVal).toUpperCase();
492  }
493}
494
495/////////////////////////////////////////////////////////////
496function indexOfCoupon(coupon) {
497  var hashed = this.MD5(coupon);
498  for (var i = 0; i < this.coupons.length; i++) {
499    if (this.coupons[i].hasOwnProperty('hash') && hashed == this.coupons[i].hash)
500      return i;
501  }
502  return -1;
503}
504
505/////////////////////////////////////////////////////////////
506function getCouponDiscountPercent() {
507  if (!this.coupon.length)
508    return 0;
509  var i = this.indexOfCoupon(this.coupon)
510  if  (i >= 0) {
511    return this.coupons[i].hasOwnProperty('discount') ? this.coupons[i].discount : 0;
512  } else
513    return 0;
514}
515
516/////////////////////////////////////////////////////////////
517function getCouponDiscount() {
518  return this.couponDiscountPercent ? this.cartCost / 100 * this.couponDiscountPercent : 0;
519}
520
521/////////////////////////////////////////////////////////////
522function loadCoupons() {
523  var instance = this;
524  $.ajax({
525    type: 'GET',
526    url: 'custom/coupons.json',
527    dataType: 'json',
528    cache: false,
529    beforeSend : function(req) {},
530    complete: function() {},
531    error: function(xhr, ajaxOptions, thrownError) {},
532    success: function(data) {
533      if (data.constructor === Array && data.length > 0)
534        instance.coupons = data;
535    },
536  });
537}
538
539/////////////////////////////////////////////////////////////
540function getcommentsWithMessage() {
541  var note = this.comments;
542  if (this.couponDiscountPercent) {
543    note += note.length ? "\n\n" : '';
544    note += 'Использован промо-код "' + this.coupon + '".';
545    note += ' Скидка ' + this.couponDiscountPercent + '% (' + this.couponDiscount + ' руб).';
546    note += ' Сумма заказа с учетом скидки ' + (this.cartCost - this.couponDiscount) + ' руб.';
547  }
548  return note;
549}
550
551});

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.