Custom WooCommerce theme for orgsteklo.ru including: - Product catalog with category/subcategory hierarchy - Custom checkout with delivery calculation - Price calculator - Admin settings panel - Search functionality - User account pages
279 lines
11 KiB
JavaScript
279 lines
11 KiB
JavaScript
/**
|
||
* Калькулятор цен на оргстекло (с поддержкой скидок)
|
||
*/
|
||
|
||
(function($) {
|
||
'use strict';
|
||
|
||
if (typeof orgstekloCalc === 'undefined') {
|
||
return;
|
||
}
|
||
|
||
var calculator = {
|
||
productId: orgstekloCalc.productId,
|
||
ajaxUrl: orgstekloCalc.ajaxUrl,
|
||
nonce: orgstekloCalc.nonce,
|
||
|
||
$thicknessField: null,
|
||
$widthField: null,
|
||
$lengthField: null,
|
||
$quantityField: null,
|
||
|
||
currentThickness: null,
|
||
currentWidth: null,
|
||
currentLength: null,
|
||
currentQuantity: 1,
|
||
|
||
init: function() {
|
||
this.cacheElements();
|
||
this.bindEvents();
|
||
this.initializeFields();
|
||
},
|
||
|
||
cacheElements: function() {
|
||
this.$thicknessField = $('#orgsteklo_thickness');
|
||
this.$widthField = $('#orgsteklo_width');
|
||
this.$lengthField = $('#orgsteklo_length');
|
||
this.$quantityField = $('#orgsteklo_quantity');
|
||
},
|
||
|
||
bindEvents: function() {
|
||
var self = this;
|
||
|
||
this.$thicknessField.on('change', function() {
|
||
self.onThicknessChange();
|
||
});
|
||
|
||
this.$widthField.on('input change', function() {
|
||
self.onDimensionsChange();
|
||
});
|
||
|
||
this.$lengthField.on('input change', function() {
|
||
self.onDimensionsChange();
|
||
});
|
||
|
||
this.$quantityField.on('input change', function() {
|
||
self.onQuantityChange();
|
||
});
|
||
|
||
$('#orgsteklo_qty_plus').on('click', function(e) {
|
||
e.preventDefault();
|
||
self.$quantityField.val((parseInt(self.$quantityField.val()) || 1) + 1).trigger('change');
|
||
});
|
||
|
||
$('#orgsteklo_qty_minus').on('click', function(e) {
|
||
e.preventDefault();
|
||
var val = parseInt(self.$quantityField.val()) || 1;
|
||
if (val > 1) {
|
||
self.$quantityField.val(val - 1).trigger('change');
|
||
}
|
||
});
|
||
},
|
||
|
||
initializeFields: function() {
|
||
if (this.$thicknessField.length === 0) {
|
||
console.error('ОШИБКА: Поле толщины #orgsteklo_thickness не найдено!');
|
||
return;
|
||
}
|
||
|
||
// Если толщина не выбрана, автоматически выбираем первую из списка
|
||
var currentVal = this.$thicknessField.val();
|
||
|
||
if (!currentVal) {
|
||
var firstThickness = this.$thicknessField.find('option:not([value=""])').first().val();
|
||
if (firstThickness) {
|
||
this.$thicknessField.val(firstThickness);
|
||
}
|
||
}
|
||
|
||
// Если теперь есть выбранная толщина, запускаем расчет
|
||
var finalVal = this.$thicknessField.val();
|
||
if (finalVal) {
|
||
this.onThicknessChange();
|
||
}
|
||
},
|
||
|
||
onThicknessChange: function() {
|
||
var thickness = parseFloat(this.$thicknessField.val());
|
||
if (!thickness) return;
|
||
|
||
this.currentThickness = thickness;
|
||
this.loadStandardDimensions(thickness);
|
||
},
|
||
|
||
onDimensionsChange: function() {
|
||
this.currentWidth = parseFloat(this.$widthField.val()) || null;
|
||
this.currentLength = parseFloat(this.$lengthField.val()) || null;
|
||
this.calculate();
|
||
},
|
||
|
||
onQuantityChange: function() {
|
||
this.currentQuantity = parseInt(this.$quantityField.val()) || 1;
|
||
this.calculate();
|
||
},
|
||
|
||
loadStandardDimensions: function(thickness) {
|
||
var self = this;
|
||
|
||
$.post(this.ajaxUrl, {
|
||
action: 'orgsteklo_get_standard_dimensions',
|
||
nonce: this.nonce,
|
||
product_id: this.productId,
|
||
thickness: thickness
|
||
}, function(response) {
|
||
if (response.success) {
|
||
// Обновляем стандартные размеры (ТОЛЬКО здесь!)
|
||
$('#orgsteklo_standard_width').text(self.formatPrice(Math.round(response.data.width)));
|
||
$('#orgsteklo_standard_length').text(self.formatPrice(Math.round(response.data.length)));
|
||
|
||
// Заполняем поля ввода
|
||
self.$widthField.val(response.data.width);
|
||
self.$lengthField.val(response.data.length);
|
||
self.currentWidth = response.data.width;
|
||
self.currentLength = response.data.length;
|
||
self.calculate();
|
||
} else {
|
||
console.error('Ошибка get_standard_dimensions:', response.data);
|
||
alert('ОШИБКА: ' + (response.data?.message || 'неизвестная ошибка'));
|
||
}
|
||
}).fail(function(xhr, status, error) {
|
||
console.error('AJAX FAIL get_standard_dimensions:', status, error);
|
||
alert('AJAX ОШИБКА: ' + error);
|
||
});
|
||
},
|
||
|
||
calculate: function() {
|
||
var self = this;
|
||
if (!this.currentThickness) return;
|
||
|
||
this.showLoading();
|
||
|
||
$.post(this.ajaxUrl, {
|
||
action: 'orgsteklo_calculate',
|
||
nonce: this.nonce,
|
||
product_id: this.productId,
|
||
thickness: this.currentThickness,
|
||
width: this.currentWidth,
|
||
length: this.currentLength,
|
||
quantity: this.currentQuantity
|
||
}, function(response) {
|
||
if (response.success) {
|
||
self.displayResults(response.data);
|
||
} else {
|
||
console.error('Ошибка calculate:', response.data);
|
||
alert('ОШИБКА: ' + (response.data?.message || 'неизвестная ошибка'));
|
||
}
|
||
}).fail(function(xhr, status, error) {
|
||
console.error('AJAX FAIL calculate:', status, error, xhr.responseText);
|
||
alert('AJAX ОШИБКА: ' + error);
|
||
}).always(function() {
|
||
self.hideLoading();
|
||
});
|
||
},
|
||
|
||
displayResults: function(data) {
|
||
// ВАЖНО: Стандартные размеры обновляются ТОЛЬКО в loadStandardDimensions()
|
||
// и НЕ должны меняться при изменении пользовательских размеров!
|
||
|
||
// ===== ОСНОВНЫЕ ЦЕНЫ =====
|
||
$('#orgsteklo_price_standard_sheet').text(this.formatPrice(data.price_standard_sheet));
|
||
|
||
// ШАГ 5: Для заданных размеров показываем price_per_kg_current (Ст. кг ЛЗР),
|
||
// для стандартных - price_per_kg_standard (Ст. кг ЛСР)
|
||
var pricePerKg = data.price_per_kg_current || data.price_per_kg_standard;
|
||
$('#orgsteklo_price_per_kg_standard').text(this.formatPrice(pricePerKg));
|
||
|
||
$('#orgsteklo_price_sqm').text(this.formatPrice(data.price_sqm));
|
||
$('#orgsteklo_current_sheet_price').text(this.formatPrice(data.price_current_sheet));
|
||
// ВАЖНО: Вычисляем стоимость заказа как цена_за_единицу * количество
|
||
// чтобы совпадало с расчетом в корзине WooCommerce
|
||
$('#orgsteklo_order_price').text(this.formatPrice(data.price_current_sheet * this.currentQuantity));
|
||
|
||
// ===== ВЕС =====
|
||
$('#orgsteklo_weight_standard_sheet').text(this.formatWeight(data.weight_standard_sheet));
|
||
$('#orgsteklo_weight_sqm').text(this.formatWeight(data.weight_sqm));
|
||
// Вес заказа также вычисляем как вес_за_единицу * количество
|
||
$('#orgsteklo_order_weight').text(this.formatWeight(data.weight_current_sheet * this.currentQuantity));
|
||
|
||
// ===== СБРОС СТАРЫХ ЦЕН =====
|
||
$('.orgsteklo-old-price').hide().text('');
|
||
$('#orgsteklo_order_price_old').hide();
|
||
|
||
// ===== СКИДКИ =====
|
||
if (data.has_discount) {
|
||
|
||
if (data.price_standard_sheet_old) {
|
||
$('#orgsteklo_price_standard_sheet_old')
|
||
.text(this.formatPrice(data.price_standard_sheet_old) + ' ₽')
|
||
.show();
|
||
}
|
||
|
||
// ШАГ 5: Для старой цены также используем правильное значение
|
||
var pricePerKgOld = data.price_per_kg_current_old || data.price_per_kg_standard_old;
|
||
if (pricePerKgOld) {
|
||
$('#orgsteklo_price_per_kg_standard_old')
|
||
.text(this.formatPrice(pricePerKgOld) + ' ₽')
|
||
.show();
|
||
}
|
||
|
||
if (data.price_sqm_old) {
|
||
$('#orgsteklo_price_sqm_old')
|
||
.text(this.formatPrice(data.price_sqm_old) + ' ₽')
|
||
.show();
|
||
}
|
||
|
||
if (data.price_current_sheet_old) {
|
||
$('#orgsteklo_current_sheet_price_old')
|
||
.text(this.formatPrice(data.price_current_sheet_old) + ' ₽')
|
||
.show();
|
||
}
|
||
|
||
if (data.price_current_sheet_old) {
|
||
// Старая цена заказа = старая цена за единицу * количество
|
||
$('#orgsteklo_order_price_old span:first')
|
||
.text(this.formatPrice(data.price_current_sheet_old * this.currentQuantity));
|
||
$('#orgsteklo_order_price_old').show();
|
||
}
|
||
}
|
||
},
|
||
|
||
resetOldPrices: function() {
|
||
$('.orgsteklo-old-price').hide().text('');
|
||
$('#orgsteklo_order_price_old').hide();
|
||
},
|
||
|
||
showOldPrice: function(selector, value, wrapper) {
|
||
if (!value) return;
|
||
$(selector).text(this.formatPrice(value)).show();
|
||
if (wrapper) $(wrapper).show();
|
||
},
|
||
|
||
formatPrice: function(price) {
|
||
return new Intl.NumberFormat('ru-RU', {
|
||
minimumFractionDigits: 0,
|
||
maximumFractionDigits: 0
|
||
}).format(price);
|
||
},
|
||
|
||
formatWeight: function(weight) {
|
||
// Используем 'en-US' для точки как разделителя дробной части
|
||
return new Intl.NumberFormat('en-US', {
|
||
minimumFractionDigits: 3,
|
||
maximumFractionDigits: 3
|
||
}).format(weight);
|
||
},
|
||
|
||
showLoading: function() {
|
||
$('.orgsteklo-calculator-results').addClass('loading');
|
||
},
|
||
|
||
hideLoading: function() {
|
||
$('.orgsteklo-calculator-results').removeClass('loading');
|
||
}
|
||
};
|
||
|
||
$(document).ready(function() {
|
||
calculator.init();
|
||
});
|
||
|
||
})(jQuery); |