From 6313b8f6e7acf81eede65d8c5ea093488e8f77f5 Mon Sep 17 00:00:00 2001 From: Andrey Smakotin Date: Sun, 11 Jan 2026 01:41:17 +0300 Subject: [PATCH] =?UTF-8?q?fix(pos):=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BF=D1=80=D0=BE=D0=B1=D0=BB?= =?UTF-8?q?=D0=B5=D0=BC=D0=B0=20=D1=81=20CSRF=20=D1=82=D0=BE=D0=BA=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=D0=BC=20=D0=BF=D1=80=D0=B8=20API=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D1=81=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Заменен getCookie('csrftoken') на getCsrfToken() во всех fetch запросах (checkAutoDiscounts, applyPromoCode, handleCheckoutSubmit и др.) - Это исправляет ошибку 403 Forbidden, возникающую из-за CSRF_USE_SESSIONS=True fix(discounts): исправлен фильтр товаров в CRUD скидок - Изменен фильтр с is_active=True на status='active' для корректной работы с моделью Product Co-Authored-By: Claude Opus 4.5 --- myproject/discounts/views.py | 4 ++-- myproject/pos/static/pos/js/terminal.js | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/myproject/discounts/views.py b/myproject/discounts/views.py index 99fd5b3..f7cf7e6 100644 --- a/myproject/discounts/views.py +++ b/myproject/discounts/views.py @@ -128,7 +128,7 @@ class DiscountCreateView(LoginRequiredMixin, RoleRequiredMixin, CreateView): context['is_edit'] = False # Передаем товары и категории для формы from products.models import Product, ProductCategory - context['all_products'] = Product.objects.filter(is_active=True).order_by('name') + context['all_products'] = Product.objects.filter(status='active').order_by('name') context['all_categories'] = ProductCategory.objects.filter(is_active=True).order_by('name') context['selected_products'] = [] context['selected_categories'] = [] @@ -159,7 +159,7 @@ class DiscountUpdateView(LoginRequiredMixin, RoleRequiredMixin, UpdateView): context['is_edit'] = True # Передаем товары и категории для формы from products.models import Product, ProductCategory - context['all_products'] = Product.objects.filter(is_active=True).order_by('name') + context['all_products'] = Product.objects.filter(status='active').order_by('name') context['all_categories'] = ProductCategory.objects.filter(is_active=True).order_by('name') context['selected_products'] = list(self.object.products.values_list('id', flat=True)) context['selected_categories'] = list(self.object.categories.values_list('id', flat=True)) diff --git a/myproject/pos/static/pos/js/terminal.js b/myproject/pos/static/pos/js/terminal.js index 87ced6c..23cfdac 100644 --- a/myproject/pos/static/pos/js/terminal.js +++ b/myproject/pos/static/pos/js/terminal.js @@ -1039,7 +1039,7 @@ async function addToCart(item) { const response = await fetch(`/pos/api/showcase-kits/${item.id}/add-to-cart/`, { method: 'POST', headers: { - 'X-CSRFToken': getCookie('csrftoken'), + 'X-CSRFToken': getCsrfToken(), 'Content-Type': 'application/json' }, body: JSON.stringify({ quantity: 1 }) @@ -1328,7 +1328,7 @@ async function removeFromCart(cartKey) { const response = await fetch(`/pos/api/showcase-kits/${item.id}/remove-from-cart/`, { method: 'POST', headers: { - 'X-CSRFToken': getCookie('csrftoken'), + 'X-CSRFToken': getCsrfToken(), 'Content-Type': 'application/json' }, body: JSON.stringify(body) @@ -1375,7 +1375,7 @@ async function increaseShowcaseKitQty(cartKey) { const response = await fetch(`/pos/api/showcase-kits/${item.id}/add-to-cart/`, { method: 'POST', headers: { - 'X-CSRFToken': getCookie('csrftoken'), + 'X-CSRFToken': getCsrfToken(), 'Content-Type': 'application/json' }, body: JSON.stringify({ quantity: 1 }) @@ -1436,7 +1436,7 @@ async function decreaseShowcaseKitQty(cartKey) { const response = await fetch(`/pos/api/showcase-kits/${item.id}/remove-from-cart/`, { method: 'POST', headers: { - 'X-CSRFToken': getCookie('csrftoken'), + 'X-CSRFToken': getCsrfToken(), 'Content-Type': 'application/json' }, body: JSON.stringify({ showcase_item_ids: [itemIdToRelease] }) @@ -1470,7 +1470,7 @@ async function clearCart() { try { await fetch('/pos/api/showcase-kits/release-all-my-locks/', { method: 'POST', - headers: { 'X-CSRFToken': getCookie('csrftoken') } + headers: { 'X-CSRFToken': getCsrfToken() } }); } catch (e) { console.error('Ошибка сброса блокировок:', e); @@ -2055,7 +2055,7 @@ document.getElementById('confirmCreateTempKit').onclick = async () => { const response = await fetch(url, { method: 'POST', headers: { - 'X-CSRFToken': getCookie('csrftoken') + 'X-CSRFToken': getCsrfToken() // Не указываем Content-Type - браузер сам установит multipart/form-data }, body: formData @@ -2164,7 +2164,7 @@ document.getElementById('disassembleKitBtn').addEventListener('click', async () const response = await fetch(`/pos/api/product-kits/${editingKitId}/disassemble/`, { method: 'POST', headers: { - 'X-CSRFToken': getCookie('csrftoken') + 'X-CSRFToken': getCsrfToken() } }); @@ -2399,7 +2399,7 @@ async function checkAutoDiscounts() { method: 'POST', headers: { 'Content-Type': 'application/json', - 'X-CSRFToken': getCookie('csrftoken') + 'X-CSRFToken': getCsrfToken() }, body: JSON.stringify({ items: items, @@ -2442,7 +2442,7 @@ async function applyPromoCode() { method: 'POST', headers: { 'Content-Type': 'application/json', - 'X-CSRFToken': getCookie('csrftoken') + 'X-CSRFToken': getCsrfToken() }, body: JSON.stringify({ promo_code: code, @@ -2496,7 +2496,7 @@ async function recalculateDiscountsWithPromo(promoCode) { method: 'POST', headers: { 'Content-Type': 'application/json', - 'X-CSRFToken': getCookie('csrftoken') + 'X-CSRFToken': getCsrfToken() }, body: JSON.stringify({ items: items, @@ -2637,7 +2637,7 @@ async function handleCheckoutSubmit(paymentsData) { method: 'POST', headers: { 'Content-Type': 'application/json', - 'X-CSRFToken': getCookie('csrftoken') + 'X-CSRFToken': getCsrfToken() }, body: JSON.stringify(orderData) });