Spaces:
Running
Running
document.addEventListener('DOMContentLoaded', function () { | |
const productForm = document.getElementById('productForm'); | |
const productTable = document.getElementById('productTable').getElementsByTagName('tbody')[0]; | |
const searchInput = document.getElementById('searchInput'); | |
const cartTable = document.getElementById('cartTable').getElementsByTagName('tbody')[0]; | |
const totalSoldElement = document.getElementById('totalSold'); | |
const totalRevenueElement = document.getElementById('totalRevenue'); | |
const totalProfitElement = document.getElementById('totalProfit'); | |
let totalSold = 0; // Общее количество проданных товаров | |
let totalRevenue = 0; // Общая выручка | |
let totalProfit = 0; // Общая прибыль | |
let cart = []; // Корзина | |
// Массив для хранения чеков | |
let receipts = JSON.parse(localStorage.getItem('receipts')) || []; | |
// Загрузка данных из localStorage при загрузке страницы | |
loadProducts(); | |
loadStats(); | |
loadCart(); | |
updateReceiptsList(); | |
// Обработка добавления товара | |
productForm.addEventListener('submit', function (e) { | |
e.preventDefault(); | |
const productName = document.getElementById('productName').value.trim(); | |
const purchasePrice = parseFloat(document.getElementById('purchasePrice').value); | |
const wholesalePrice = parseFloat(document.getElementById('wholesalePrice').value) || null; | |
const retailPrice = parseFloat(document.getElementById('retailPrice').value) || null; | |
const quantity = parseInt(document.getElementById('quantity').value); | |
const itemsPerPack = parseInt(document.getElementById('itemsPerPack').value); | |
// Проверка обязательных полей | |
if (!productName || isNaN(purchasePrice) || isNaN(quantity) || isNaN(itemsPerPack)) { | |
alert('Пожалуйста, заполните все обязательные поля корректно.'); | |
return; | |
} | |
// Добавляем товар | |
addProduct(productName, purchasePrice, wholesalePrice, retailPrice, quantity, itemsPerPack); | |
productForm.reset(); // Очистка формы после добавления | |
}); | |
// Поиск по товарам | |
searchInput.addEventListener('input', function () { | |
const searchTerm = searchInput.value.toLowerCase(); | |
const rows = productTable.getElementsByTagName('tr'); | |
for (let row of rows) { | |
const name = row.getElementsByTagName('td')[0]?.textContent.toLowerCase(); | |
if (name) { | |
row.style.display = name.includes(searchTerm) ? '' : 'none'; | |
} | |
} | |
}); | |
// Делегирование событий для кнопок в таблице товаров | |
productTable.addEventListener('click', function (e) { | |
const target = e.target; | |
const row = target.closest('tr'); | |
const productId = parseInt(row.getAttribute('data-id')); | |
if (target.classList.contains('add-to-cart-btn')) { | |
const quantityInput = row.querySelector('.quantity-input'); | |
const quantity = parseInt(quantityInput.value); | |
const isWholesale = row.querySelector('.wholesale-checkbox').checked; // Проверяем галочку | |
if (quantity && quantity > 0) { | |
addToCart(productId, quantity, isWholesale); | |
} else { | |
alert('Пожалуйста, введите корректное количество.'); | |
} | |
} else if (target.classList.contains('add-stock-btn')) { | |
addStock(productId); | |
} else if (target.classList.contains('delete-btn')) { | |
deleteProduct(productId); | |
} | |
}); | |
// Делегирование событий для кнопок в корзине | |
cartTable.addEventListener('click', function (e) { | |
const target = e.target; | |
if (target.classList.contains('delete-btn')) { | |
const row = target.closest('tr'); | |
const productId = parseInt(row.getAttribute('data-id')); | |
removeFromCart(productId); | |
} | |
}); | |
// Функция добавления товара | |
function addProduct(name, purchasePrice, wholesalePrice, retailPrice, quantity, itemsPerPack) { | |
const product = { | |
id: Date.now(), // Уникальный ID на основе времени | |
name, | |
purchasePrice, | |
wholesalePrice, | |
retailPrice, | |
quantity, | |
itemsPerPack | |
}; | |
// Получаем текущие товары из localStorage | |
let products = JSON.parse(localStorage.getItem('products')) || []; | |
products.push(product); // Добавляем новый товар | |
localStorage.setItem('products', JSON.stringify(products)); // Сохраняем в localStorage | |
// Добавляем товар в таблицу | |
addProductToTable(product); | |
} | |
// Функция добавления товара в таблицу | |
function addProductToTable(product) { | |
const row = productTable.insertRow(); | |
row.setAttribute('data-id', product.id); | |
row.innerHTML = ` | |
<td>${product.name}</td> | |
<td>${product.purchasePrice}</td> | |
<td>${product.wholesalePrice || '—'}</td> | |
<td>${product.retailPrice || '—'}</td> | |
<td>${product.quantity}</td> | |
<td>${product.itemsPerPack}</td> | |
<td class="actions"> | |
<input type="number" min="1" max="${product.quantity}" class="quantity-input" placeholder="Количество"> | |
<label> | |
<input type="checkbox" class="wholesale-checkbox"> Опт | |
</label> | |
<button class="add-to-cart-btn">Добавить в корзину</button> | |
<button class="add-stock-btn">Приход</button> | |
<button class="delete-btn">Удалить</button> | |
</td> | |
`; | |
} | |
// Функция загрузки товаров из localStorage | |
function loadProducts() { | |
const products = JSON.parse(localStorage.getItem('products')) || []; | |
productTable.innerHTML = ''; // Очищаем таблицу перед загрузкой | |
products.forEach(product => addProductToTable(product)); | |
} | |
// Функция загрузки статистики из localStorage | |
function loadStats() { | |
const stats = JSON.parse(localStorage.getItem('stats')) || { totalSold: 0, totalRevenue: 0, totalProfit: 0 }; | |
totalSold = stats.totalSold; | |
totalRevenue = stats.totalRevenue; | |
totalProfit = stats.totalProfit; | |
updateStatsDisplay(); | |
} | |
// Функция загрузки корзины из localStorage | |
function loadCart() { | |
cart = JSON.parse(localStorage.getItem('cart')) || []; | |
updateCartDisplay(); | |
} | |
// Функция обновления отображения статистики | |
function updateStatsDisplay() { | |
totalSoldElement.textContent = totalSold; | |
totalRevenueElement.textContent = totalRevenue.toFixed(2); | |
totalProfitElement.textContent = totalProfit.toFixed(2); | |
} | |
// Функция обновления отображения корзины | |
function updateCartDisplay() { | |
cartTable.innerHTML = ''; // Очищаем корзину перед обновлением | |
cart.forEach(item => { | |
const row = cartTable.insertRow(); | |
row.setAttribute('data-id', item.id); | |
row.innerHTML = ` | |
<td>${item.name}</td> | |
<td>${item.quantity}</td> | |
<td>${item.salePrice}</td> | |
<td>${item.saleType}</td> | |
<td>${item.quantity * item.salePrice}</td> | |
<td><button class="delete-btn">Удалить</button></td> | |
`; | |
}); | |
} | |
// Функция добавления товара в корзину | |
function addToCart(productId, quantity, isWholesale) { | |
const products = JSON.parse(localStorage.getItem('products')) || []; | |
const product = products.find(p => p.id === productId); | |
if (product && product.quantity >= quantity) { | |
const saleType = isWholesale ? 'опт' : 'розница'; | |
const price = isWholesale ? product.wholesalePrice : product.retailPrice; | |
if (!price) { | |
alert(`Цена для типа продажи "${saleType}" не указана.`); | |
return; | |
} | |
const cartItem = cart.find(item => item.id === productId && item.saleType === saleType); | |
if (cartItem) { | |
cartItem.quantity += quantity; | |
} else { | |
cart.push({ | |
id: productId, | |
name: product.name, | |
salePrice: price, | |
purchasePrice: product.purchasePrice, | |
quantity: quantity, | |
itemsPerPack: product.itemsPerPack, // Добавляем количество штук в пачке | |
saleType: saleType | |
}); | |
} | |
localStorage.setItem('cart', JSON.stringify(cart)); | |
updateCartDisplay(); | |
} else { | |
alert('Недостаточно товара на складе.'); | |
} | |
} | |
// Функция удаления товара из корзины | |
function removeFromCart(productId) { | |
cart = cart.filter(item => item.id !== productId); | |
localStorage.setItem('cart', JSON.stringify(cart)); | |
updateCartDisplay(); | |
} | |
// Функция продажи товаров из корзины | |
window.sellCart = function () { | |
if (cart.length === 0) { | |
alert('Корзина пуста.'); | |
return; | |
} | |
// Получаем сумму скидки | |
const discountInput = document.getElementById('discountInput'); | |
const discount = parseFloat(discountInput.value) || 0; // Если скидка не указана, считаем её равной 0 | |
// Получаем текущую дату и время по бишкекскому времени | |
const now = new Date(); | |
const options = { timeZone: 'Asia/Bishkek', year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit' }; | |
const receiptDateTime = now.toLocaleString('ru-RU', options); | |
// Создаем чек | |
const receipt = { | |
dateTime: receiptDateTime, | |
items: cart.map(item => ({ | |
name: item.name, | |
quantity: item.quantity, | |
salePrice: item.salePrice, | |
purchasePrice: item.purchasePrice, | |
itemsPerPack: item.itemsPerPack, // Добавляем количество штук в пачке | |
saleType: item.saleType | |
})), | |
discount: discount | |
}; | |
// Отображаем чек в модальном окне | |
openReceiptForConfirmation(receipt); | |
}; | |
// Функция для открытия модального окна с подтверждением продажи | |
function openReceiptForConfirmation(receipt) { | |
const modal = document.getElementById('receiptModal'); | |
const receiptTable = document.getElementById('receiptTable').getElementsByTagName('tbody')[0]; | |
// Заполняем дату и время | |
document.getElementById('receiptDateTime').textContent = receipt.dateTime; | |
// Заполняем таблицу товаров | |
receiptTable.innerHTML = ''; | |
let totalAmount = 0; | |
receipt.items.forEach(item => { | |
const row = receiptTable.insertRow(); | |
row.innerHTML = ` | |
<td>${item.name}</td> | |
<td>${item.quantity} (${item.itemsPerPack} шт/уп)</td> | |
<td>${item.salePrice} (${item.saleType})</td> | |
<td>${item.quantity * item.salePrice}</td> | |
`; | |
totalAmount += item.quantity * item.salePrice; | |
}); | |
// Отображаем общую сумму, скидку и итоговую сумму | |
document.getElementById('receiptTotal').textContent = totalAmount.toFixed(2); | |
document.getElementById('receiptDiscount').textContent = receipt.discount.toFixed(2); | |
document.getElementById('receiptFinalTotal').textContent = (totalAmount - receipt.discount).toFixed(2); | |
// Показываем кнопку "Подтвердить" для завершения продажи | |
document.getElementById('confirmSaleBtn').style.display = 'inline-block'; | |
// Показываем модальное окно | |
modal.style.display = 'flex'; | |
// Обработчик для кнопки "Подтвердить" | |
document.getElementById('confirmSaleBtn').onclick = function () { | |
// Обновляем остатки на складе | |
updateStockAfterSale(receipt); | |
// Обновляем статистику | |
updateStatistics(receipt); | |
// Сохраняем чек | |
saveReceipt(receipt); | |
// Очищаем корзину | |
cart = []; | |
localStorage.setItem('cart', JSON.stringify(cart)); | |
updateCartDisplay(); | |
// Скрываем модальное окно | |
modal.style.display = 'none'; | |
alert('Продажа успешно завершена!'); | |
}; | |
// Обработчик для кнопки "Отмена" | |
document.getElementById('cancelSaleBtn').onclick = function () { | |
modal.style.display = 'none'; // Скрываем модальное окно | |
}; | |
// Обработчик для закрытия модального окна (крестик) | |
document.querySelector('.modal .close').onclick = function () { | |
modal.style.display = 'none'; // Скрываем модальное окно | |
}; | |
} | |
// Функция для уменьшения остатков на складе после продажи | |
function updateStockAfterSale(receipt) { | |
let products = JSON.parse(localStorage.getItem('products')) || []; | |
receipt.items.forEach(item => { | |
const product = products.find(p => p.name === item.name); | |
if (product) { | |
product.quantity -= item.quantity; // Уменьшаем количество товара на складе | |
// Если остаток стал меньше 0, устанавливаем его в 0 | |
if (product.quantity < 0) { | |
product.quantity = 0; | |
} | |
} | |
}); | |
// Сохраняем обновленные товары | |
localStorage.setItem('products', JSON.stringify(products)); | |
// Обновляем таблицу товаров | |
productTable.innerHTML = ''; | |
loadProducts(); | |
} | |
// Функция для сохранения чека | |
function saveReceipt(receipt) { | |
receipts.push(receipt); | |
localStorage.setItem('receipts', JSON.stringify(receipts)); | |
updateReceiptsList(); | |
} | |
// Функция для обновления списка чеков | |
function updateReceiptsList(receiptsToShow = receipts) { | |
const receiptsList = document.getElementById('receiptsList'); | |
receiptsList.innerHTML = ''; // Очищаем список перед обновлением | |
receiptsToShow.forEach((receipt, index) => { | |
const receiptItem = document.createElement('div'); | |
receiptItem.className = 'receipt-item'; | |
receiptItem.textContent = `Чек от ${receipt.dateTime}`; | |
receiptItem.onclick = () => openReceipt(index); | |
receiptsList.appendChild(receiptItem); | |
}); | |
} | |
// Функция для открытия чека (из отчетов) | |
function openReceipt(index) { | |
const receipt = receipts[index]; | |
const modal = document.getElementById('receiptModal'); | |
const receiptTable = document.getElementById('receiptTable').getElementsByTagName('tbody')[0]; | |
// Заполняем дату и время | |
document.getElementById('receiptDateTime').textContent = receipt.dateTime; | |
// Заполняем таблицу товаров | |
receiptTable.innerHTML = ''; | |
let totalAmount = 0; | |
receipt.items.forEach(item => { | |
const row = receiptTable.insertRow(); | |
row.innerHTML = ` | |
<td>${item.name}</td> | |
<td>${item.quantity} (${item.itemsPerPack} шт/уп)</td> | |
<td>${item.salePrice} (${item.saleType})</td> | |
<td>${item.quantity * item.salePrice}</td> | |
`; | |
totalAmount += item.quantity * item.salePrice; | |
}); | |
// Отображаем общую сумму, скидку и итоговую сумму | |
document.getElementById('receiptTotal').textContent = totalAmount.toFixed(2); | |
document.getElementById('receiptDiscount').textContent = receipt.discount.toFixed(2); | |
document.getElementById('receiptFinalTotal').textContent = (totalAmount - receipt.discount).toFixed(2); | |
// Убираем кнопку "Подтвердить" при просмотре чека (для отчетов) | |
document.getElementById('confirmSaleBtn').style.display = 'none'; | |
// Показываем модальное окно | |
modal.style.display = 'flex'; | |
} | |
// Функция для обновления статистики | |
function updateStatistics(receipt) { | |
receipt.items.forEach(item => { | |
totalSold += item.quantity; | |
totalRevenue += item.quantity * item.salePrice; | |
// Прибыль = (отпускная цена - приходная цена) * количество | |
const purchasePrice = item.purchasePrice || 0; // Если purchasePrice отсутствует, считаем его равным 0 | |
totalProfit += item.quantity * (item.salePrice - purchasePrice); | |
}); | |
// Вычитаем скидку из прибыли | |
totalProfit -= receipt.discount; | |
// Сохраняем обновленные данные | |
localStorage.setItem('stats', JSON.stringify({ totalSold, totalRevenue, totalProfit })); | |
updateStatsDisplay(); | |
} | |
// Функция добавления остатков | |
function addStock(productId) { | |
const quantityToAdd = prompt('Введите количество для прихода:'); | |
if (quantityToAdd && !isNaN(quantityToAdd) && quantityToAdd > 0) { | |
let products = JSON.parse(localStorage.getItem('products')) || []; | |
const productIndex = products.findIndex(p => p.id === productId); | |
if (productIndex !== -1) { | |
products[productIndex].quantity += parseInt(quantityToAdd); | |
localStorage.setItem('products', JSON.stringify(products)); | |
// Обновляем таблицу | |
productTable.innerHTML = ''; | |
loadProducts(); | |
} | |
} else { | |
alert('Пожалуйста, введите корректное количество.'); | |
} | |
} | |
// Функция удаления товара | |
function deleteProduct(productId) { | |
if (confirm('Вы уверены, что хотите удалить этот товар?')) { | |
let products = JSON.parse(localStorage.getItem('products')) || []; | |
products = products.filter(p => p.id !== productId); | |
localStorage.setItem('products', JSON.stringify(products)); | |
// Обновляем таблицу | |
productTable.innerHTML = ''; | |
loadProducts(); | |
} | |
} | |
// Функция для переключения бургер-меню | |
window.toggleMenu = function () { | |
const menuItems = document.querySelector('.menu-items'); | |
menuItems.style.display = menuItems.style.display === 'block' ? 'none' : 'block'; | |
}; | |
// Функция для отображения выбранного раздела | |
window.showSection = function (sectionId) { | |
// Скрываем все колонки | |
document.querySelectorAll('.column').forEach(column => { | |
column.classList.remove('active'); | |
}); | |
// Показываем выбранную колонку | |
document.getElementById(sectionId).classList.add('active'); | |
// Скрываем меню после выбора | |
document.querySelector('.menu-items').style.display = 'none'; | |
}; | |
// Функция для фильтрации чеков по дате | |
window.filterReceiptsByDate = function () { | |
const filterDateInput = document.getElementById('filterDateInput'); | |
const filterDate = filterDateInput.value; // Получаем выбранную дату | |
if (!filterDate) { | |
alert('Пожалуйста, выберите дату для фильтрации.'); | |
return; | |
} | |
// Фильтруем чеки по выбранной дате | |
const filteredReceipts = receipts.filter(receipt => { | |
const receiptDate = new Date(receipt.dateTime).toISOString().split('T')[0]; // Получаем дату чека | |
return receiptDate === filterDate; // Сравниваем с выбранной датой | |
}); | |
// Обновляем список чеков | |
updateReceiptsList(filteredReceipts); | |
}; | |
// Функция для сброса фильтрации | |
window.clearDateFilter = function () { | |
document.getElementById('filterDateInput').value = ''; // Очищаем поле ввода даты | |
updateReceiptsList(receipts); // Показываем все чеки | |
}; | |
// Показываем Инвентарь по умолчанию | |
showSection('inventory'); | |
}); |