feat: delete report by admin updated
This commit is contained in:
parent
6cf32f119e
commit
bd2d19a543
101
frontend/api.js
101
frontend/api.js
@ -351,6 +351,7 @@ async function getReports() {
|
||||
},
|
||||
});
|
||||
const data = await response.json();
|
||||
console.log(data);
|
||||
if (response.ok) {
|
||||
return { success: true, reports: data.reports };
|
||||
} else {
|
||||
@ -401,9 +402,6 @@ async function loadReports() {
|
||||
|
||||
tbody.innerHTML = "";
|
||||
reports.forEach((report) => {
|
||||
const store = database.stores.find((s) => s.id === report.storeId);
|
||||
// Fallback for username if user might be missing from local array:
|
||||
const user = database.users.find((u) => u.id === report.userId);
|
||||
const profit =
|
||||
(Number(report.totalIncome) || 0) - (Number(report.totalExpenses) || 0);
|
||||
|
||||
@ -426,7 +424,7 @@ async function loadReports() {
|
||||
profit >= 0 ? "text-green-600" : "text-red-600"
|
||||
}">€${profit.toFixed(2)}</td>
|
||||
<td class="px-6 py-4 text-sm text-gray-900">${
|
||||
user ? user.username : report.userId
|
||||
report.username || report.userId
|
||||
}</td>
|
||||
<td class="px-6 py-4">
|
||||
<span class="px-2 py-1 text-xs rounded-full ${
|
||||
@ -470,8 +468,6 @@ function viewReport(reportId) {
|
||||
}
|
||||
}
|
||||
|
||||
//create report
|
||||
// createReport(data)
|
||||
//edit report
|
||||
async function updateReport(reportId, data) {
|
||||
const token = localStorage.getItem("token");
|
||||
@ -490,6 +486,8 @@ async function updateReport(reportId, data) {
|
||||
hideModal("reportViewModal");
|
||||
await loadReports();
|
||||
|
||||
console.log(data);
|
||||
|
||||
if (typeof updateDashboard === "function") updateDashboard();
|
||||
return { success: true };
|
||||
} else {
|
||||
@ -602,15 +600,32 @@ function editReport(report) {
|
||||
}
|
||||
|
||||
async function saveEditedReport(reportId) {
|
||||
const data = {
|
||||
storeId: parseInt(document.getElementById("editStoreSelect").value, 10),
|
||||
reportDate: document.getElementById("editDate").value,
|
||||
income: parseFloat(document.getElementById("editIncome").value),
|
||||
initialCash: parseFloat(document.getElementById("editCajaInicial").value),
|
||||
envelope: parseFloat(document.getElementById("editEnvelope").value),
|
||||
isVerified: document.getElementById("editVerified").checked ? 1 : 0,
|
||||
};
|
||||
data.totalIncome = data.income + data.initialCash;
|
||||
// Get values from the form
|
||||
const storeId = document.getElementById("editStoreSelect").value;
|
||||
const reportDate = document.getElementById("editDate").value;
|
||||
const incomeVal = document.getElementById("editIncome").value;
|
||||
const initialCashVal = document.getElementById("editCajaInicial").value;
|
||||
const envelopeVal = document.getElementById("editEnvelope").value;
|
||||
const isVerified = document.getElementById("editVerified").checked ? 1 : 0;
|
||||
|
||||
// Build the payload dynamically
|
||||
const data = {};
|
||||
|
||||
if (storeId) data.storeId = parseInt(storeId, 10);
|
||||
if (reportDate) data.reportDate = reportDate;
|
||||
if (incomeVal !== "") data.income = parseFloat(incomeVal);
|
||||
if (initialCashVal !== "") data.initialCash = parseFloat(initialCashVal);
|
||||
if (envelopeVal !== "") data.envelope = parseFloat(envelopeVal);
|
||||
|
||||
if (data.income !== undefined && data.initialCash !== undefined) {
|
||||
data.totalIncome = data.income + data.initialCash;
|
||||
}
|
||||
data.isVerified = isVerified;
|
||||
|
||||
// REMOVE any NaN values
|
||||
Object.keys(data).forEach((k) => {
|
||||
if (typeof data[k] === "number" && isNaN(data[k])) delete data[k];
|
||||
});
|
||||
|
||||
await updateReport(reportId, data);
|
||||
}
|
||||
@ -645,5 +660,57 @@ async function verifyReport(reportId) {
|
||||
}
|
||||
}
|
||||
|
||||
//delete report
|
||||
// deleteReport(id)
|
||||
//delete report (admin only)
|
||||
async function apiDeleteReport(reportId) {
|
||||
const token = localStorage.getItem("token");
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/reports/${reportId}`, {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
const data = await response.json();
|
||||
if (response.ok && data.deleted) {
|
||||
showNotification("Отчет удален!");
|
||||
await loadReports();
|
||||
if (typeof updateDashboard === "function") updateDashboard();
|
||||
} else {
|
||||
showNotification(data.error || "Ошибка удаления отчета", "error");
|
||||
}
|
||||
} catch {
|
||||
showNotification("Нет соединения с сервером", "error");
|
||||
}
|
||||
}
|
||||
|
||||
//worker
|
||||
//create report
|
||||
// api.js
|
||||
async function createReport(data) {
|
||||
const token = localStorage.getItem("token");
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/reports`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
const result = await response.json();
|
||||
if (response.ok && result.id) {
|
||||
return { success: true, id: result.id };
|
||||
} else {
|
||||
return {
|
||||
success: false,
|
||||
error:
|
||||
result.error ||
|
||||
(result.errors && result.errors[0]?.msg) ||
|
||||
"Ошибка создания отчета",
|
||||
};
|
||||
}
|
||||
} catch (err) {
|
||||
return { success: false, error: "Нет соединения с сервером" };
|
||||
}
|
||||
}
|
||||
|
@ -256,11 +256,9 @@ function loadUserStores() {
|
||||
let userStores = [];
|
||||
|
||||
if (currentUser.role === "admin") {
|
||||
userStores = database.stores;
|
||||
userStores = currentUser.stores;
|
||||
} else {
|
||||
userStores = database.stores.filter((store) =>
|
||||
currentUser.stores.includes(store.id)
|
||||
);
|
||||
userStores = currentUser.stores;
|
||||
}
|
||||
|
||||
userStores.forEach((store) => {
|
||||
@ -405,85 +403,133 @@ function updateTotals() {
|
||||
}
|
||||
|
||||
// Отправка формы отчета
|
||||
document.getElementById("reportForm").addEventListener("submit", (e) => {
|
||||
// document.getElementById("reportForm").addEventListener("submit", (e) => {
|
||||
// e.preventDefault();
|
||||
|
||||
// const formData = {
|
||||
// id: editingReportId || Date.now(),
|
||||
// date: new Date().toISOString().split("T")[0],
|
||||
// storeId: parseInt(document.getElementById("storeSelect").value),
|
||||
// userId: currentUser.id,
|
||||
// income: parseFloat(document.getElementById("income").value),
|
||||
// cajaInicial: parseFloat(document.getElementById("cajaInicial").value),
|
||||
// totalIncome: parseFloat(document.getElementById("totalIncome").value),
|
||||
// envelope: parseFloat(document.getElementById("envelope").value),
|
||||
// verified: false,
|
||||
// createdAt: new Date().toISOString(),
|
||||
// };
|
||||
|
||||
// // Сбор зарплат
|
||||
// const wages = [];
|
||||
// const wageRows = document.querySelectorAll(".wage-row");
|
||||
// wageRows.forEach((row) => {
|
||||
// const name = row.querySelector(".wage-name").value;
|
||||
// const amount = parseFloat(row.querySelector(".wage-amount").value) || 0;
|
||||
// if (name && amount > 0) {
|
||||
// wages.push({ name, amount });
|
||||
// }
|
||||
// });
|
||||
|
||||
// // Сбор расходов
|
||||
// const expenses = [];
|
||||
// const expenseRows = document.querySelectorAll(".expense-row");
|
||||
// expenseRows.forEach((row) => {
|
||||
// const name = row.querySelector(".expense-name").value;
|
||||
// const amount = parseFloat(row.querySelector(".expense-amount").value) || 0;
|
||||
// if (name && amount > 0) {
|
||||
// expenses.push({ name, amount });
|
||||
// }
|
||||
// });
|
||||
|
||||
// formData.wages = wages;
|
||||
// formData.expenses = expenses;
|
||||
// formData.totalWages = calculateTotalWages();
|
||||
// formData.totalExpensesInternal = calculateTotalExpenses();
|
||||
// formData.totalExpenses = formData.totalWages + formData.totalExpensesInternal;
|
||||
// formData.cajaFinal =
|
||||
// formData.totalIncome - formData.totalExpenses - formData.envelope;
|
||||
|
||||
// if (editingReportId) {
|
||||
// const index = database.reports.findIndex((r) => r.id === editingReportId);
|
||||
// database.reports[index] = formData;
|
||||
// editingReportId = null;
|
||||
// showNotification("Отчет успешно обновлен!");
|
||||
// } else {
|
||||
// database.reports.push(formData);
|
||||
// showNotification("Отчет успешно сохранен!");
|
||||
// }
|
||||
|
||||
// // Очистка формы
|
||||
// document.getElementById("reportForm").reset();
|
||||
// document.getElementById("wagesContainer").innerHTML = `
|
||||
// <div class="wage-row grid grid-cols-1 md:grid-cols-3 gap-4 mb-3">
|
||||
// <input type="text" placeholder="Имя сотрудника" class="wage-name form-input px-3 py-2 rounded-lg">
|
||||
// <input type="number" step="0.01" placeholder="Сумма €" class="wage-amount form-input px-3 py-2 rounded-lg">
|
||||
// <button type="button" class="remove-wage bg-red-500 text-white px-3 py-2 rounded-lg hover:bg-red-600 transition-colors">
|
||||
// <i class="fas fa-times"></i>
|
||||
// </button>
|
||||
// </div>
|
||||
// `;
|
||||
// document.getElementById("expensesContainer").innerHTML = `
|
||||
// <div class="expense-row grid grid-cols-1 md:grid-cols-3 gap-4 mb-3">
|
||||
// <input type="text" placeholder="Название расхода" class="expense-name form-input px-3 py-2 rounded-lg">
|
||||
// <input type="number" step="0.01" placeholder="Сумма €" class="expense-amount form-input px-3 py-2 rounded-lg">
|
||||
// <button type="button" class="remove-expense bg-red-500 text-white px-3 py-2 rounded-lg hover:bg-red-600 transition-colors">
|
||||
// <i class="fas fa-times"></i>
|
||||
// </button>
|
||||
// </div>
|
||||
// `;
|
||||
|
||||
// updateTotals();
|
||||
// });
|
||||
|
||||
document.getElementById("reportForm").addEventListener("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = {
|
||||
id: editingReportId || Date.now(),
|
||||
date: new Date().toISOString().split("T")[0],
|
||||
storeId: parseInt(document.getElementById("storeSelect").value),
|
||||
userId: currentUser.id,
|
||||
reportDate: new Date().toISOString().split("T")[0], // Or get from input if user chooses date
|
||||
income: parseFloat(document.getElementById("income").value),
|
||||
cajaInicial: parseFloat(document.getElementById("cajaInicial").value),
|
||||
initialCash: parseFloat(document.getElementById("cajaInicial").value),
|
||||
totalIncome: parseFloat(document.getElementById("totalIncome").value),
|
||||
wages: JSON.stringify(collectWages()),
|
||||
expenses: JSON.stringify(collectExpenses()),
|
||||
totalWages: calculateTotalWages(),
|
||||
totalExpenses: calculateTotalExpenses() + calculateTotalWages(),
|
||||
envelope: parseFloat(document.getElementById("envelope").value),
|
||||
verified: false,
|
||||
createdAt: new Date().toISOString(),
|
||||
finalCash:
|
||||
parseFloat(document.getElementById("totalIncome").value) -
|
||||
(calculateTotalWages() + calculateTotalExpenses()) -
|
||||
parseFloat(document.getElementById("envelope").value),
|
||||
};
|
||||
console.log("Sending report:", formData);
|
||||
const result = await createReport(formData);
|
||||
if (result.success) {
|
||||
showNotification("Отчет успешно создан!");
|
||||
document.getElementById("reportForm").reset();
|
||||
} else {
|
||||
showNotification(result.error || "Ошибка создания отчета", "error");
|
||||
}
|
||||
});
|
||||
|
||||
// Сбор зарплат
|
||||
function collectWages() {
|
||||
const wages = [];
|
||||
const wageRows = document.querySelectorAll(".wage-row");
|
||||
wageRows.forEach((row) => {
|
||||
document.querySelectorAll(".wage-row").forEach((row) => {
|
||||
const name = row.querySelector(".wage-name").value;
|
||||
const amount = parseFloat(row.querySelector(".wage-amount").value) || 0;
|
||||
if (name && amount > 0) {
|
||||
wages.push({ name, amount });
|
||||
}
|
||||
if (name && amount > 0) wages.push({ name, amount });
|
||||
});
|
||||
|
||||
// Сбор расходов
|
||||
return wages;
|
||||
}
|
||||
function collectExpenses() {
|
||||
const expenses = [];
|
||||
const expenseRows = document.querySelectorAll(".expense-row");
|
||||
expenseRows.forEach((row) => {
|
||||
document.querySelectorAll(".expense-row").forEach((row) => {
|
||||
const name = row.querySelector(".expense-name").value;
|
||||
const amount = parseFloat(row.querySelector(".expense-amount").value) || 0;
|
||||
if (name && amount > 0) {
|
||||
expenses.push({ name, amount });
|
||||
}
|
||||
if (name && amount > 0) expenses.push({ name, amount });
|
||||
});
|
||||
|
||||
formData.wages = wages;
|
||||
formData.expenses = expenses;
|
||||
formData.totalWages = calculateTotalWages();
|
||||
formData.totalExpensesInternal = calculateTotalExpenses();
|
||||
formData.totalExpenses = formData.totalWages + formData.totalExpensesInternal;
|
||||
formData.cajaFinal =
|
||||
formData.totalIncome - formData.totalExpenses - formData.envelope;
|
||||
|
||||
if (editingReportId) {
|
||||
const index = database.reports.findIndex((r) => r.id === editingReportId);
|
||||
database.reports[index] = formData;
|
||||
editingReportId = null;
|
||||
showNotification("Отчет успешно обновлен!");
|
||||
} else {
|
||||
database.reports.push(formData);
|
||||
showNotification("Отчет успешно сохранен!");
|
||||
}
|
||||
|
||||
// Очистка формы
|
||||
document.getElementById("reportForm").reset();
|
||||
document.getElementById("wagesContainer").innerHTML = `
|
||||
<div class="wage-row grid grid-cols-1 md:grid-cols-3 gap-4 mb-3">
|
||||
<input type="text" placeholder="Имя сотрудника" class="wage-name form-input px-3 py-2 rounded-lg">
|
||||
<input type="number" step="0.01" placeholder="Сумма €" class="wage-amount form-input px-3 py-2 rounded-lg">
|
||||
<button type="button" class="remove-wage bg-red-500 text-white px-3 py-2 rounded-lg hover:bg-red-600 transition-colors">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
document.getElementById("expensesContainer").innerHTML = `
|
||||
<div class="expense-row grid grid-cols-1 md:grid-cols-3 gap-4 mb-3">
|
||||
<input type="text" placeholder="Название расхода" class="expense-name form-input px-3 py-2 rounded-lg">
|
||||
<input type="number" step="0.01" placeholder="Сумма €" class="expense-amount form-input px-3 py-2 rounded-lg">
|
||||
<button type="button" class="remove-expense bg-red-500 text-white px-3 py-2 rounded-lg hover:bg-red-600 transition-colors">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
updateTotals();
|
||||
});
|
||||
return expenses;
|
||||
}
|
||||
|
||||
// Отчет за сегодня для пользователя
|
||||
document.getElementById("todayReportBtn").addEventListener("click", () => {
|
||||
@ -510,9 +556,6 @@ function showReportModal(report, isAdmin = false) {
|
||||
const buttons = document.getElementById("reportModalButtons");
|
||||
const title = document.getElementById("reportModalTitle");
|
||||
|
||||
const store = database.stores.find((s) => s.id === report.storeId);
|
||||
const user = database.users.find((u) => u.id === report.userId);
|
||||
|
||||
title.textContent = `Отчет от ${report.reportDate || report.date} - ${
|
||||
report.storeName || report.storeId || "Неизвестный магазин"
|
||||
}`;
|
||||
@ -530,7 +573,7 @@ function showReportModal(report, isAdmin = false) {
|
||||
report.storeName || report.storeId
|
||||
}</div>
|
||||
<div><strong>Пользователь:</strong> ${
|
||||
user ? user.username : report.userId
|
||||
report.username || report.fullName || report.userId
|
||||
}</div>
|
||||
<div><strong>Статус:</strong>
|
||||
<span class="px-2 py-1 rounded text-xs ${
|
||||
@ -1232,13 +1275,22 @@ function createCharts() {
|
||||
// }
|
||||
|
||||
// Удаление отчета
|
||||
// function deleteReport(reportId) {
|
||||
// if (confirm("Вы уверены, что хотите удалить этот отчет?")) {
|
||||
// database.reports = database.reports.filter((r) => r.id !== reportId);
|
||||
// loadReports();
|
||||
// updateDashboard();
|
||||
// showNotification("Отчет удален!");
|
||||
// }
|
||||
// }
|
||||
|
||||
function deleteReport(reportId) {
|
||||
if (confirm("Вы уверены, что хотите удалить этот отчет?")) {
|
||||
database.reports = database.reports.filter((r) => r.id !== reportId);
|
||||
showConfirmModal("Вы уверены, что хотите удалить этот отчет?", () => {
|
||||
apiDeleteReport(reportId);
|
||||
loadReports();
|
||||
updateDashboard();
|
||||
showNotification("Отчет удален!");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Настройка фильтров отчетов
|
||||
|
Loading…
Reference in New Issue
Block a user