diff --git a/myproject/pos/static/pos/js/terminal.js b/myproject/pos/static/pos/js/terminal.js index d291412..a8ebf30 100644 --- a/myproject/pos/static/pos/js/terminal.js +++ b/myproject/pos/static/pos/js/terminal.js @@ -901,14 +901,42 @@ function renderCart() { qtyControl.className = 'd-flex align-items-center'; qtyControl.style.gap = '2px'; - // СПЕЦИАЛЬНАЯ ЛОГИКА для витринных комплектов (только badge, без кнопок) + // СПЕЦИАЛЬНАЯ ЛОГИКА для витринных комплектов if (isShowcaseKit) { - const badge = document.createElement('span'); - badge.className = 'badge bg-warning text-dark'; - badge.textContent = `${item.qty} шт (витрина)`; - badge.style.fontSize = '0.85rem'; - badge.style.padding = '0.5rem 0.75rem'; - qtyControl.appendChild(badge); + // Кнопка минус + const minusBtn = document.createElement('button'); + minusBtn.className = 'btn btn-outline-secondary btn-sm'; + minusBtn.innerHTML = ''; + minusBtn.onclick = async (e) => { + e.preventDefault(); + await decreaseShowcaseKitQty(cartKey); + }; + + // Поле количества (только для отображения, readonly) + const qtyInput = document.createElement('input'); + qtyInput.type = 'number'; + qtyInput.className = 'qty-input form-control form-control-sm'; + qtyInput.style.width = '60px'; + qtyInput.style.textAlign = 'center'; + qtyInput.style.padding = '0.375rem 0.25rem'; + qtyInput.value = item.qty; + qtyInput.min = 1; + qtyInput.readOnly = true; // Только чтение - изменяем только через +/- + qtyInput.style.backgroundColor = '#fff3cd'; // Желтый фон как у витринных + + // Кнопка плюс + const plusBtn = document.createElement('button'); + plusBtn.className = 'btn btn-outline-secondary btn-sm'; + plusBtn.innerHTML = ''; + plusBtn.onclick = async (e) => { + e.preventDefault(); + await increaseShowcaseKitQty(cartKey); + }; + + // Собираем контейнер + qtyControl.appendChild(minusBtn); + qtyControl.appendChild(qtyInput); + qtyControl.appendChild(plusBtn); } else { // ОБЫЧНАЯ ЛОГИКА для товаров и комплектов @@ -1029,6 +1057,109 @@ async function removeFromCart(cartKey) { } } +/** + * Увеличивает количество витринного комплекта в корзине + * Добавляет еще один экземпляр через API (если есть доступные) + */ +async function increaseShowcaseKitQty(cartKey) { + const item = cart.get(cartKey); + if (!item || item.type !== 'showcase_kit') return; + + try { + // Пытаемся заблокировать еще 1 экземпляр + const response = await fetch(`/pos/api/showcase-kits/${item.id}/add-to-cart/`, { + method: 'POST', + headers: { + 'X-CSRFToken': getCookie('csrftoken'), + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ quantity: 1 }) + }); + + const data = await response.json(); + + if (!response.ok || !data.success) { + // Нет доступных экземпляров + alert(data.error || 'Нет доступных экземпляров этого букета на витрине'); + return; + } + + // Успешно заблокировали - обновляем корзину + const lockedItemIds = data.locked_item_ids || []; + item.qty += lockedItemIds.length; + item.showcase_item_ids = [...(item.showcase_item_ids || []), ...lockedItemIds]; + + renderCart(); + saveCartToRedis(); + + // Обновляем список витрины + if (isShowcaseView) { + await loadShowcaseKits(); + } + } catch (error) { + console.error('Ошибка при увеличении количества витринного комплекта:', error); + alert('Ошибка сервера. Попробуйте еще раз.'); + } +} + +/** + * Уменьшает количество витринного комплекта в корзине + * Снимает блокировку с одного экземпляра (последнего в списке) + */ +async function decreaseShowcaseKitQty(cartKey) { + const item = cart.get(cartKey); + if (!item || item.type !== 'showcase_kit') return; + + // Если количество = 1, удаляем полностью + if (item.qty <= 1) { + await removeFromCart(cartKey); + return; + } + + try { + // Снимаем блокировку с последнего экземпляра + const showcaseItemIds = item.showcase_item_ids || []; + if (showcaseItemIds.length === 0) { + // Нет ID - просто удаляем + await removeFromCart(cartKey); + return; + } + + // Берем последний ID из списка + const itemIdToRelease = showcaseItemIds[showcaseItemIds.length - 1]; + + const response = await fetch(`/pos/api/showcase-kits/${item.id}/remove-from-cart/`, { + method: 'POST', + headers: { + 'X-CSRFToken': getCookie('csrftoken'), + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ showcase_item_ids: [itemIdToRelease] }) + }); + + const data = await response.json(); + + if (!response.ok) { + console.error('Ошибка при снятии блокировки:', data.error); + } + + // Обновляем корзину + item.qty -= 1; + item.showcase_item_ids = showcaseItemIds.filter(id => id !== itemIdToRelease); + + renderCart(); + saveCartToRedis(); + + // Обновляем список витрины + if (isShowcaseView) { + await loadShowcaseKits(); + } + } catch (error) { + console.error('Ошибка при уменьшении количества витринного комплекта:', error); + alert('Ошибка сервера. Попробуйте еще раз.'); + } +} + async function clearCart() { // Сбрасываем все свои блокировки витринных букетов try {