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 {