From fab4c78966d2af000a90b4d5970fe8d8b730cef1 Mon Sep 17 00:00:00 2001 From: Andrey Smakotin Date: Sun, 16 Nov 2025 14:54:31 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=BD?= =?UTF-8?q?=D1=8B=20=D0=BA=D0=B0=D1=80=D1=82=D0=BE=D1=87=D0=BA=D0=B8=20?= =?UTF-8?q?=D1=82=D0=BE=D0=B2=D0=B0=D1=80=D0=BE=D0=B2=20=D0=B2=20POS:=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D1=84?= =?UTF-8?q?=D0=BE=D1=82=D0=BE,=20=D0=B0=D1=80=D1=82=D0=B8=D0=BA=D1=83?= =?UTF-8?q?=D0=BB,=20=D1=86=D0=B5=D0=BD=D0=B0=20=D0=B8=20=D1=81=D1=82?= =?UTF-8?q?=D0=B0=D1=82=D1=83=D1=81=20=D0=BD=D0=B0=D0=BB=D0=B8=D1=87=D0=B8?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- myproject/pos/static/pos/css/terminal.css | 66 +++++++++++++++++++---- myproject/pos/static/pos/js/terminal.js | 50 +++++++++++++++-- myproject/pos/templates/pos/terminal.html | 1 + myproject/pos/views.py | 8 ++- 4 files changed, 111 insertions(+), 14 deletions(-) diff --git a/myproject/pos/static/pos/css/terminal.css b/myproject/pos/static/pos/css/terminal.css index 549e024..28a7a70 100644 --- a/myproject/pos/static/pos/css/terminal.css +++ b/myproject/pos/static/pos/css/terminal.css @@ -30,7 +30,9 @@ body { border: 1px solid #dee2e6; background: white; height: 100%; - min-height: 140px; + min-height: 200px; + display: flex; + flex-direction: column; } .product-card:hover { @@ -44,27 +46,73 @@ body { } .product-card .card-body { - padding: 1.25rem; + padding: 0; display: flex; flex-direction: column; - justify-content: center; + height: 100%; +} + +.product-image { + width: 100%; + aspect-ratio: 1 / 1; + object-fit: cover; + border-radius: 12px 12px 0 0; + background: #f8f9fa; + display: flex; align-items: center; - text-align: center; + justify-content: center; + color: #adb5bd; + font-size: 3rem; +} + +.product-image img { + width: 100%; + height: 100%; + object-fit: cover; + border-radius: 12px 12px 0 0; +} + +.product-info { + padding: 0.75rem; + display: flex; + flex-direction: column; + gap: 0.25rem; + flex-grow: 1; } .product-name { - font-weight: 500; - font-size: 1rem; - margin-bottom: 0.5rem; - color: #495057; + font-weight: 600; + font-size: 0.9rem; + line-height: 1.2; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + color: #212529; } .product-stock { - font-size: 0.9rem; + font-size: 0.8rem; color: #6c757d; font-style: italic; } +.product-sku { + font-size: 0.75rem; + color: #adb5bd; + margin-top: auto; + display: flex; + justify-content: space-between; + align-items: center; +} + +.product-price { + font-size: 0.85rem; + font-weight: 600; + color: #212529; +} + /* Карточки категорий */ .category-card { cursor: pointer; diff --git a/myproject/pos/static/pos/js/terminal.js b/myproject/pos/static/pos/js/terminal.js index 234be72..dc878ee 100644 --- a/myproject/pos/static/pos/js/terminal.js +++ b/myproject/pos/static/pos/js/terminal.js @@ -3,6 +3,11 @@ const CATEGORIES = JSON.parse(document.getElementById('categoriesData').textContent); const PRODUCTS = JSON.parse(document.getElementById('productsData').textContent); +// Отладка: проверить количество загруженных товаров +console.log('Загружено категорий:', CATEGORIES.length); +console.log('Загружено товаров:', PRODUCTS.length); +console.log('Товары:', PRODUCTS); + let currentCategoryId = null; const cart = new Map(); // productId -> {id, name, price, qty} @@ -85,16 +90,52 @@ function renderProducts() { const body = document.createElement('div'); body.className = 'card-body'; + // Изображение товара + const imageDiv = document.createElement('div'); + imageDiv.className = 'product-image'; + if (p.image) { + const img = document.createElement('img'); + img.src = p.image; + img.alt = p.name; + imageDiv.appendChild(img); + } else { + imageDiv.innerHTML = ''; + } + + // Информация о товаре + const info = document.createElement('div'); + info.className = 'product-info'; + const name = document.createElement('div'); name.className = 'product-name'; name.textContent = p.name; const stock = document.createElement('div'); stock.className = 'product-stock'; - stock.textContent = 'В наличии'; + stock.textContent = p.in_stock ? 'В наличии' : 'Под заказ'; + if (!p.in_stock) { + stock.style.color = '#dc3545'; + } - body.appendChild(name); - body.appendChild(stock); + const sku = document.createElement('div'); + sku.className = 'product-sku'; + + const skuText = document.createElement('span'); + skuText.textContent = p.sku || 'н/д'; + + const priceSpan = document.createElement('span'); + priceSpan.className = 'product-price'; + priceSpan.textContent = `${formatMoney(p.price)}`; + + sku.appendChild(skuText); + sku.appendChild(priceSpan); + + info.appendChild(name); + info.appendChild(stock); + info.appendChild(sku); + + body.appendChild(imageDiv); + body.appendChild(info); card.appendChild(body); col.appendChild(card); grid.appendChild(col); @@ -218,3 +259,6 @@ document.getElementById('customerSelectBtn').addEventListener('click', () => { renderCategories(); renderProducts(); renderCart(); + +// Установить фокус на строку поиска +document.getElementById('searchInput').focus(); diff --git a/myproject/pos/templates/pos/terminal.html b/myproject/pos/templates/pos/terminal.html index aa28295..cc3c204 100644 --- a/myproject/pos/templates/pos/terminal.html +++ b/myproject/pos/templates/pos/terminal.html @@ -23,6 +23,7 @@
+
diff --git a/myproject/pos/views.py b/myproject/pos/views.py index 99f3d3e..8349d2d 100644 --- a/myproject/pos/views.py +++ b/myproject/pos/views.py @@ -12,14 +12,18 @@ def pos_terminal(request): Shows categories and in-stock products for quick tap-to-add. """ categories_qs = ProductCategory.objects.filter(is_active=True) - products_qs = Product.objects.filter(in_stock=True).prefetch_related('categories') + # Показываем все товары, не только in_stock + products_qs = Product.objects.all().prefetch_related('categories', 'photos') categories = [{'id': c.id, 'name': c.name} for c in categories_qs] products = [{ 'id': p.id, 'name': p.name, 'price': str(p.actual_price), - 'category_ids': [c.id for c in p.categories.all()] + 'category_ids': [c.id for c in p.categories.all()], + 'in_stock': p.in_stock, + 'sku': p.sku or '', + 'image': p.photos.first().get_thumbnail_url() if p.photos.exists() else None } for p in products_qs] context = {