265 lines
8.2 KiB
JavaScript
265 lines
8.2 KiB
JavaScript
// POS Terminal JavaScript
|
||
|
||
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}
|
||
|
||
function formatMoney(v) {
|
||
return (Number(v)).toFixed(2);
|
||
}
|
||
|
||
function renderCategories() {
|
||
const grid = document.getElementById('categoryGrid');
|
||
grid.innerHTML = '';
|
||
|
||
// Кнопка "Все"
|
||
const allCol = document.createElement('div');
|
||
allCol.className = 'col-6 col-sm-4 col-md-3 col-lg-2';
|
||
const allCard = document.createElement('div');
|
||
allCard.className = 'card category-card' + (currentCategoryId === null ? ' active' : '');
|
||
allCard.onclick = () => {
|
||
currentCategoryId = null;
|
||
renderCategories();
|
||
renderProducts();
|
||
};
|
||
const allBody = document.createElement('div');
|
||
allBody.className = 'card-body';
|
||
const allName = document.createElement('div');
|
||
allName.className = 'category-name';
|
||
allName.textContent = 'Все товары';
|
||
allBody.appendChild(allName);
|
||
allCard.appendChild(allBody);
|
||
allCol.appendChild(allCard);
|
||
grid.appendChild(allCol);
|
||
|
||
// Категории
|
||
CATEGORIES.forEach(cat => {
|
||
const col = document.createElement('div');
|
||
col.className = 'col-6 col-sm-4 col-md-3 col-lg-2';
|
||
|
||
const card = document.createElement('div');
|
||
card.className = 'card category-card' + (currentCategoryId === cat.id ? ' active' : '');
|
||
card.onclick = () => {
|
||
currentCategoryId = cat.id;
|
||
renderCategories();
|
||
renderProducts();
|
||
};
|
||
|
||
const body = document.createElement('div');
|
||
body.className = 'card-body';
|
||
|
||
const name = document.createElement('div');
|
||
name.className = 'category-name';
|
||
name.textContent = cat.name;
|
||
|
||
body.appendChild(name);
|
||
card.appendChild(body);
|
||
col.appendChild(card);
|
||
grid.appendChild(col);
|
||
});
|
||
}
|
||
|
||
function renderProducts() {
|
||
const grid = document.getElementById('productGrid');
|
||
grid.innerHTML = '';
|
||
const searchTerm = document.getElementById('searchInput').value.toLowerCase();
|
||
|
||
let filtered = currentCategoryId
|
||
? PRODUCTS.filter(p => (p.category_ids || []).includes(currentCategoryId))
|
||
: PRODUCTS;
|
||
|
||
if (searchTerm) {
|
||
filtered = filtered.filter(p => p.name.toLowerCase().includes(searchTerm));
|
||
}
|
||
|
||
filtered.forEach(p => {
|
||
const col = document.createElement('div');
|
||
col.className = 'col-6 col-sm-4 col-md-3 col-lg-2';
|
||
|
||
const card = document.createElement('div');
|
||
card.className = 'card product-card';
|
||
card.onclick = () => addToCart(p);
|
||
|
||
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 = '<i class="bi bi-image"></i>';
|
||
}
|
||
|
||
// Информация о товаре
|
||
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 = p.in_stock ? 'В наличии' : 'Под заказ';
|
||
if (!p.in_stock) {
|
||
stock.style.color = '#dc3545';
|
||
}
|
||
|
||
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);
|
||
});
|
||
}
|
||
|
||
function addToCart(p) {
|
||
if (!cart.has(p.id)) {
|
||
cart.set(p.id, { id: p.id, name: p.name, price: Number(p.price), qty: 1 });
|
||
} else {
|
||
cart.get(p.id).qty += 1;
|
||
}
|
||
renderCart();
|
||
}
|
||
|
||
function updateQty(id, delta) {
|
||
if (!cart.has(id)) return;
|
||
const item = cart.get(id);
|
||
item.qty += delta;
|
||
if (item.qty <= 0) cart.delete(id);
|
||
renderCart();
|
||
}
|
||
|
||
function renderCart() {
|
||
const list = document.getElementById('cartList');
|
||
list.innerHTML = '';
|
||
let total = 0;
|
||
|
||
if (cart.size === 0) {
|
||
list.innerHTML = '<p class="text-muted text-center py-4 small">Корзина пуста</p>';
|
||
document.getElementById('cartTotal').textContent = '0.00';
|
||
return;
|
||
}
|
||
|
||
cart.forEach(item => {
|
||
const row = document.createElement('div');
|
||
row.className = 'mb-2 pb-2 border-bottom';
|
||
|
||
const nameRow = document.createElement('div');
|
||
nameRow.className = 'd-flex justify-content-between align-items-start mb-1';
|
||
nameRow.innerHTML = `
|
||
<div class="fw-semibold small">${item.name}</div>
|
||
<button class="btn btn-sm btn-link text-danger p-0 ms-2" onclick="event.stopPropagation(); removeFromCart(${item.id});">
|
||
<i class="bi bi-x"></i>
|
||
</button>
|
||
`;
|
||
|
||
const controlsRow = document.createElement('div');
|
||
controlsRow.className = 'd-flex justify-content-between align-items-center';
|
||
|
||
const controls = document.createElement('div');
|
||
controls.className = 'btn-group btn-group-sm';
|
||
|
||
const minus = document.createElement('button');
|
||
minus.className = 'btn btn-outline-secondary';
|
||
minus.innerHTML = '<i class="bi bi-dash"></i>';
|
||
minus.onclick = (e) => { e.stopPropagation(); updateQty(item.id, -1); };
|
||
|
||
const qtySpan = document.createElement('button');
|
||
qtySpan.className = 'btn btn-outline-secondary disabled';
|
||
qtySpan.textContent = item.qty;
|
||
|
||
const plus = document.createElement('button');
|
||
plus.className = 'btn btn-outline-secondary';
|
||
plus.innerHTML = '<i class="bi bi-plus"></i>';
|
||
plus.onclick = (e) => { e.stopPropagation(); updateQty(item.id, +1); };
|
||
|
||
controls.appendChild(minus);
|
||
controls.appendChild(qtySpan);
|
||
controls.appendChild(plus);
|
||
|
||
const priceDiv = document.createElement('div');
|
||
priceDiv.className = 'text-end small';
|
||
priceDiv.innerHTML = `<strong>${formatMoney(item.price * item.qty)}</strong>`;
|
||
|
||
controlsRow.appendChild(controls);
|
||
controlsRow.appendChild(priceDiv);
|
||
|
||
row.appendChild(nameRow);
|
||
row.appendChild(controlsRow);
|
||
list.appendChild(row);
|
||
|
||
total += item.qty * item.price;
|
||
});
|
||
|
||
document.getElementById('cartTotal').textContent = formatMoney(total);
|
||
}
|
||
|
||
function removeFromCart(id) {
|
||
cart.delete(id);
|
||
renderCart();
|
||
}
|
||
|
||
function clearCart() {
|
||
cart.clear();
|
||
renderCart();
|
||
}
|
||
|
||
document.getElementById('clearCart').onclick = clearCart;
|
||
|
||
// Заглушки для функционала (будет реализовано позже)
|
||
document.getElementById('checkoutNow').onclick = async () => {
|
||
alert('Функционал будет подключен позже: создание заказа и списание со склада.');
|
||
};
|
||
|
||
document.getElementById('scheduleLater').onclick = async () => {
|
||
alert('Функционал будет подключен позже: создание заказа на доставку/самовывоз.');
|
||
};
|
||
|
||
// Search functionality
|
||
document.getElementById('searchInput').addEventListener('input', () => {
|
||
renderProducts();
|
||
});
|
||
|
||
// Customer selection
|
||
document.getElementById('customerSelectBtn').addEventListener('click', () => {
|
||
alert('Функция выбора клиента будет реализована позже');
|
||
});
|
||
|
||
// Инициализация
|
||
renderCategories();
|
||
renderProducts();
|
||
renderCart();
|
||
|
||
// Установить фокус на строку поиска
|
||
document.getElementById('searchInput').focus();
|