Andrei | правки в каталоге - настроил ошибки и их вывод при добавлении в корзину товара сверх остатков

pull/34/head
Andrei 2 months ago
parent fc73740773
commit 3f0fc9e260
  1. 131
      wp-content/themes/cosmopet/global-functions/multisite-functions.php
  2. 71
      wp-content/themes/cosmopet/modules/layout/assets/css/gp-style-core.css
  3. 39
      wp-content/themes/cosmopet/modules/shop/components/cart/assets/js/cart.js
  4. 55
      wp-content/themes/cosmopet/temp-functions/woocommerce-logic.php
  5. 3
      wp-content/themes/cosmopet/templates/layout.twig
  6. 2
      wp-content/themes/cosmopet/woocommerce/assets/css/gp-style-core.css

@ -275,137 +275,6 @@ add_action('wp_footer', 'add_facebook_pixel_events');
}
}
// Ваш код для custom_enqueue_ajax_add_to_cart остается без изменений
add_action('wp_enqueue_scripts', 'custom_enqueue_ajax_add_to_cart');
function custom_enqueue_ajax_add_to_cart() {
// Подключаем скрипт только на странице товара
if (is_product()) {
// Убедимся, что jQuery подключен
wp_enqueue_script('jquery');
// Inline JavaScript с поддержкой jQuery.noConflict
$ajax_script = "
jQuery(document).ready(function($) {
console.log('AJAX Add to Cart script loaded'); // Отладка: проверяем загрузку скрипта
// Перехват клика по кнопке
$('.single_add_to_cart_button').on('click', function(e) {
e.preventDefault();
e.stopPropagation(); // Предотвращаем всплытие события
console.log('Add to cart button clicked'); // Отладка: клик по кнопке
var \$button = $(this);
var \$form = \$button.closest('form.cart');
var product_id = \$button.val(); // Извлекаем product_id из value кнопки
var quantity = \$form.find('input[name=\"quantity\"]').val() || 1;
// Проверка на корректность product_id
if (!product_id || isNaN(product_id)) {
console.log('Invalid product_id:', product_id); // Отладка
console.log('Error: Неверный ID товара');
\$button.removeClass('loading').prop('disabled', false); // Разблокируем кнопку
return;
}
// Блокируем кнопку
\$button.addClass('loading').prop('disabled', true);
console.log('Sending AJAX request for product_id: ' + product_id + ', quantity: ' + quantity); // Отладка
// Подготовка данных
var data = {
action: 'woocommerce_ajax_add_to_cart',
product_id: product_id,
quantity: quantity
};
// Добавляем поле url, если есть
var urlField = \$form.find('input[name=\"url\"]');
if (urlField.length) {
data.url = urlField.val();
}
$.ajax({
type: 'POST',
url: ajax_object.ajax_url,
data: data,
dataType: 'json',
success: function(response) {
console.log('AJAX response:', response); // Отладка
if (response.success) {
console.log('Товар добавлен в корзину'); // Уведомление в консоли
// Обновляем фрагменты корзины
if (response.data.fragments) {
$.each(response.data.fragments, function(key, value) {
console.log('Updating fragment:', key); // Отладка
$(key).replaceWith(value);
});
}
$(document.body).trigger('wc_fragment_refresh');
$(document.body).trigger('added_to_cart', [response.data.fragments, response.data.cart_hash]);
// Сбрасываем форму
\$form[0].reset();
console.log('Form reset after successful add to cart'); // Отладка
} else {
console.log('Error: ' + (response.data.message || 'Ошибка при добавлении товара в корзину')); // Уведомление в консоли
}
},
error: function(xhr, status, error) {
console.error('AJAX error:', status, error); // Отладка
console.log('Error: Произошла ошибка при добавлении товара: ' + error);
},
complete: function() {
console.log('AJAX request completed'); // Отладка
\$button.removeClass('loading').prop('disabled', false); // Разблокируем кнопку
}
});
});
// Перехват отправки формы
$('form.cart').on('submit', function(e) {
e.preventDefault();
e.stopPropagation(); // Предотвращаем всплытие
console.log('Form submit prevented'); // Отладка
});
});
";
wp_add_inline_script('jquery', $ajax_script);
// Передаем AJAX URL
wp_localize_script('jquery', 'ajax_object', array(
'ajax_url' => admin_url('admin-ajax.php')
));
// Inline CSS
wp_enqueue_style('woocommerce-custom-styles', get_template_directory_uri() . '/style.css', array(), '1.0');
$custom_css = "
.single_add_to_cart_button.loading {
opacity: 0.5;
cursor: not-allowed;
position: relative;
}
.single_add_to_cart_button.loading:after {
content: '';
display: inline-block;
width: 16px;
height: 16px;
border: 2px solid #fff;
border-radius: 50%;
border-top-color: transparent;
animation: spin 1s linear infinite;
position: absolute;
right: 10px;
}
@keyframes spin {
100% {
transform: rotate(360deg);
}
}
";
wp_add_inline_style('woocommerce-custom-styles', $custom_css);
}
}
// Отключаем кэширование для страниц товаров
add_action('template_redirect', function() {
if (is_product()) {

@ -2283,3 +2283,74 @@ textarea{
padding: 24px 16px!important;
}
}
.woocommerce-notices-wrapper{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
margin-bottom: 0 !important;
z-index: 10000;
}
.woocommerce-error,.woocommerce-info,.woocommerce-message {
padding: 1em 2em 1em 3.5em;
margin: 0 0 0em;
position: relative;
background-color: #f6f5f8;
color: #515151;
border-top: 3px solid #720eec;
list-style: none outside;
width: auto;
word-wrap: break-word
}
.woocommerce-error::after,.woocommerce-error::before,.woocommerce-info::after,.woocommerce-info::before,.woocommerce-message::after,.woocommerce-message::before {
content: " ";
display: table
}
.woocommerce-error::after,.woocommerce-info::after,.woocommerce-message::after {
clear: both
}
.woocommerce-error::before,.woocommerce-info::before,.woocommerce-message::before {
font-family: WooCommerce;
content: "\e028";
content: "\e028"/"";
display: inline-block;
position: absolute;
top: 1em;
left: 1.5em
}
.woocommerce-error .button,.woocommerce-info .button,.woocommerce-message .button {
float: right
}
.woocommerce-error li,.woocommerce-info li,.woocommerce-message li {
list-style: none outside!important;
padding-left: 0!important;
margin-left: 0!important
}
.woocommerce-message {
border-top-color: #8fae1b
}
.woocommerce-message::before {
content: "\e015";
color: #8fae1b
}
.woocommerce-info {
border-top-color: #1e85be
}
.woocommerce-info::before {
color: #1e85be
}
.woocommerce-error {
border-top-color: #b81c23
}
.woocommerce-error::before {
content: "\e016";
color: #b81c23
}

@ -99,6 +99,7 @@ jQuery(document).ready(function($) {
// Все элементы обработаны
localStorage.removeItem(removedItemsStorageKey);
updateCartFragment();
updateNotices();
$('#modal-basket').removeClass('loading');
return;
}
@ -166,6 +167,7 @@ jQuery(document).ready(function($) {
localStorage.setItem(removedItemsStorageKey, JSON.stringify(updatedItems));
updateCartFragment();
updateNotices();
// $('[data-key="' + key + '"]').remove()
}
}
@ -203,6 +205,7 @@ jQuery(document).ready(function($) {
$('.proceed-to-checkout').css('display', '');
updateCartFragment();
updateNotices();
}
}
});
@ -266,6 +269,7 @@ jQuery(document).ready(function($) {
// Обновление корзины при добавлении товара
$(document.body).on('added_to_cart', function() {
updateCartFragment();
updateNotices();
openBasketOnFirstAdd();
});
@ -288,6 +292,7 @@ jQuery(document).ready(function($) {
success: function(response) {
if (response.success) {
updateCartFragment(update_full);
updateNotices();
} else {
console.error('Ошибка при обновлении корзины');
}
@ -335,6 +340,33 @@ jQuery(document).ready(function($) {
});
}
function updateNotices() {
$.ajax({
type: 'POST',
url: woocommerce_params.ajax_url,
data: {
action: 'get_wc_notices'
},
beforeSend: function() {
console.log('Загрузка уведомлений...');
},
success: function(response) {
if (response.success && response.data && response.data.html) {
$('.woocommerce-notices-wrapper').html(response.data.html)
setTimeout(function(){
$('.woocommerce-notices-wrapper').html('')
}, 5000)
} else {
console.warn('Нет уведомлений');
}
},
error: function(xhr, status, error) {
console.error('Ошибка AJAX:', error);
}
});
}
// Добавляем спиннер на кнопку 'Добавить в корзину' в корзине
$('body').on('click', '.add_to_cart_button', function() {
var btn = $(this);
@ -379,6 +411,7 @@ jQuery(document).ready(function($) {
}
updateCartFragment();
updateNotices();
openBasketOnFirstAdd();
},
error: function(xhr) {
@ -421,4 +454,10 @@ jQuery(function($){
}
});
});
});

@ -295,3 +295,58 @@ function custom_remove_woocommerce_styles_on_checkout( $enqueue_styles ) {
return $enqueue_styles;
}
add_filter( 'woocommerce_enqueue_styles', 'custom_remove_woocommerce_styles_on_checkout' );
// Перехватываем валидацию и заменяем поведение
add_filter('woocommerce_add_to_cart_validation', 'custom_limit_stock_add_to_cart_behavior', 10, 5);
function custom_limit_stock_add_to_cart_behavior($passed, $product_id, $quantity, $variation_id = 0, $variations = []) {
$product = wc_get_product($variation_id ?: $product_id);
if (!$passed || !$product || !$product->managing_stock()) {
return $passed;
}
$stock = $product->get_stock_quantity();
$in_cart = WC()->cart->get_cart_item_quantities();
$already_in_cart = $in_cart[$product->get_id()] ?? 0;
$total = $already_in_cart + $quantity;
if ($total > $stock) {
$can_add = max($stock - $already_in_cart, 0);
if ($can_add > 0) {
// Добавим максимум
WC()->cart->add_to_cart($product_id, $can_add, $variation_id, $variations);
wc_add_notice(sprintf(
__('Вы запросили %d шт., но доступно только %d. Добавлено максимально возможное количество.', 'woocommerce'),
$quantity, $can_add
), 'notice');
} else {
wc_add_notice(__('Вы не можете добавить больше — товар закончился на складе.', 'woocommerce'), 'error');
}
// Возвращаем false, чтобы остановить оригинальное добавление
return false;
}
return $passed;
}
// Убираем редирект на страницу товара при неудаче добавления
add_filter('woocommerce_cart_redirect_after_error', '__return_false');
add_action('wp_ajax_get_wc_notices', 'custom_get_wc_notices');
add_action('wp_ajax_nopriv_get_wc_notices', 'custom_get_wc_notices');
function custom_get_wc_notices() {
ob_start();
wc_print_notices(); // выводим уведомления, если они есть
$html = ob_get_clean();
wp_send_json_success([
'html' => $html,
]);
}

@ -12,6 +12,9 @@
<body class="{{bodyClass}}">
{% include 'header.twig' %}
<main class="{{ mainClass }}">
<div class="woocommerce-notices-wrapper">
{{ fn('wc_print_notices') }}
</div>
{% block content %}
{% endblock %}
{% include 'modal.twig' %}

@ -1304,3 +1304,5 @@ button{
.to-know--background-none{
background: none;
}

Loading…
Cancel
Save