diff --git a/frontend/api.js b/frontend/api.js
index 4a241b8..ceb89d3 100644
--- a/frontend/api.js
+++ b/frontend/api.js
@@ -337,3 +337,144 @@ function deleteUser(userId) {
apiDeleteUser(userId)
);
}
+
+//Reports
+//GET all reports
+async function getReports() {
+ const token = localStorage.getItem("token");
+ try {
+ const response = await fetch(`${API_BASE_URL}/reports`, {
+ method: "GET",
+ headers: {
+ Authorization: `Bearer ${token}`,
+ "Content-Type": "application/json",
+ },
+ });
+ const data = await response.json();
+ if (response.ok) {
+ return { success: true, reports: data.reports };
+ } else {
+ return {
+ success: false,
+ error: data.error || data.message || "Ошибка получения отчетов",
+ };
+ }
+ } catch (err) {
+ return { success: false, error: "Нет соединения с сервером" };
+ }
+}
+
+async function loadReports() {
+ const tbody = document.getElementById("reportsTableBody");
+ const filterStore = document.getElementById("filterStore");
+
+ const result = await getReports();
+ console.log("getReports() result:", result);
+
+ window.reportsList = result.success ? result.reports : [];
+
+ if (!result.success) {
+ showNotification(result.error || "Ошибка загрузки отчетов", "error");
+ return;
+ }
+ const reports = result.reports;
+
+ // Build a map storeId => storeName from all reports
+ const storeMap = {};
+ reports.forEach((r) => {
+ if (r.storeId && r.storeName) {
+ storeMap[r.storeId] = r.storeName;
+ }
+ });
+
+ // Get unique [storeId, storeName] pairs sorted alphabetically
+ const storesWithReports = Object.entries(storeMap)
+ .map(([id, name]) => ({ id, name }))
+ .sort((a, b) => a.name.localeCompare(b.name));
+
+ filterStore.innerHTML = `
+
+ ${storesWithReports
+ .map((store) => ``)
+ .join("")}
+`;
+
+ 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);
+
+ const row = document.createElement("tr");
+ row.className = "hover:bg-gray-50";
+ row.innerHTML = `
+
-
-
-
Основная информация
-
-
Дата: ${report.date}
-
Магазин: ${
- store ? store.name : "Неизвестно"
- }
-
Пользователь: ${
- user ? user.username : "Неизвестно"
- }
-
Статус:
-
- ${
- report.verified
- ? "Проверен"
- : "Не проверен"
- }
-
-
-
-
-
-
-
-
Доходы (Ingresos)
-
-
Income: €${report.income.toFixed(
- 2
- )}
-
Caja inicial: €${report.cajaInicial.toFixed(
- 2
- )}
-
Total income: €${report.totalIncome.toFixed(
- 2
- )}
-
-
-
-
-
-
Зарплаты (Wages)
- ${
- report.wages && report.wages.length > 0
- ? `
-
- ${report.wages
- .map(
- (w) => `
-
- ${w.name}
- €${w.amount.toFixed(2)}
-
- `
- )
- .join("")}
-
-
- Total wages:
- €${report.totalWages.toFixed(
- 2
- )}
-
-
-
- `
- : '
Нет данных о зарплатах
'
- }
-
-
-
-
-
Расходы (Expenses)
- ${
- report.expenses && report.expenses.length > 0
- ? `
-
- ${report.expenses
- .map(
- (e) => `
-
- ${e.name}
- €${e.amount.toFixed(2)}
-
- `
- )
- .join("")}
-
-
- Total expenses internal:
- €${report.totalExpensesInternal.toFixed(
- 2
- )}
-
-
-
- `
- : '
Нет данных о расходах
'
- }
-
-
-
-
-
Итоговые расчеты
-
-
Total income: €${report.totalIncome.toFixed(
- 2
- )}
-
Total expenses: €${report.totalExpenses.toFixed(
- 2
- )}
-
Envelope: €${report.envelope.toFixed(
- 2
- )}
-
- Caja final: €${report.cajaFinal.toFixed(
- 2
- )}
-
-
-
+
+
+
+
Основная информация
+
+
Дата: ${
+ report.date || report.reportDate || ""
+ }
+
Магазин: ${
+ report.storeName || report.storeId
+ }
+
Пользователь: ${
+ user ? user.username : report.userId
+ }
+
Статус:
+
+ ${
+ report.isVerified || report.verified
+ ? "Проверен"
+ : "Не проверен"
+ }
+
+
+
+
+
+
+
Доходы (Ingresos)
+
+
Income: €${safeToFixed(report.income)}
+
Caja inicial: €${safeToFixed(
+ report.cajaInicial || report.initialCash
+ )}
+
Total income: €${safeToFixed(
+ report.totalIncome
+ )}
+
+
+
+
+
Зарплаты (Wages)
+ ${
+ Array.isArray(report.wages) && report.wages.length > 0
+ ? `
+
+ ${report.wages
+ .map(
+ (w) => `
+
+ ${w.name}
+ €${safeToFixed(w.amount)}
+
+ `
+ )
+ .join("")}
+
+
+ Total wages:
+ €${safeToFixed(report.totalWages)}
- `;
+
+
+ `
+ : '
Нет данных о зарплатах
'
+ }
+
+
+
+
Расходы (Expenses)
+ ${
+ Array.isArray(report.expenses) && report.expenses.length > 0
+ ? `
+
+ ${report.expenses
+ .map(
+ (e) => `
+
+ ${e.name}
+ €${safeToFixed(e.amount)}
+
+ `
+ )
+ .join("")}
+
+
+ Total expenses internal:
+ €${safeToFixed(report.totalExpensesInternal)}
+
+
+
+ `
+ : '
Нет данных о расходах
'
+ }
+
+
+
+
Итоговые расчеты
+
+
Total income: €${safeToFixed(
+ report.totalIncome
+ )}
+
Total expenses: €${safeToFixed(
+ report.totalExpenses
+ )}
+
Envelope: €${safeToFixed(
+ report.envelope
+ )}
+
+ Caja final: €${safeToFixed(
+ report.cajaFinal || report.finalCash
+ )}
+
+
+
+
+ `;
- // Настройка кнопок в зависимости от роли и статуса
buttons.innerHTML = "";
if (isAdmin) {
- // Кнопки для администратора
buttons.innerHTML = `
-
-
-
- `;
+
+
+
+ `;
document.getElementById("editReportBtn").addEventListener("click", () => {
editReport(report);
@@ -669,16 +662,15 @@ function showReportModal(report, isAdmin = false) {
verifyReport(report.id);
});
} else {
- // Кнопки для пользователя
- if (!report.verified) {
+ if (!report.isVerified && !report.verified) {
buttons.innerHTML = `
-
-
- `;
+
+
+ `;
document
.getElementById("editReportUserBtn")
@@ -688,10 +680,10 @@ function showReportModal(report, isAdmin = false) {
});
} else {
buttons.innerHTML = `
-
- `;
+
+ `;
}
}
@@ -1161,83 +1153,83 @@ function createCharts() {
}
// Загрузка отчетов в админке
-function loadReports() {
- const tbody = document.getElementById("reportsTableBody");
- const filterStore = document.getElementById("filterStore");
+// function loadReports() {
+// const tbody = document.getElementById("reportsTableBody");
+// const filterStore = document.getElementById("filterStore");
- // Заполнение фильтра магазинов
- filterStore.innerHTML = '
';
- database.stores.forEach((store) => {
- const option = document.createElement("option");
- option.value = store.id;
- option.textContent = store.name;
- filterStore.appendChild(option);
- });
+// // Заполнение фильтра магазинов
+// filterStore.innerHTML = '
';
+// database.stores.forEach((store) => {
+// const option = document.createElement("option");
+// option.value = store.id;
+// option.textContent = store.name;
+// filterStore.appendChild(option);
+// });
- // Отображение отчетов
- tbody.innerHTML = "";
- database.reports.forEach((report) => {
- const store = database.stores.find((s) => s.id === report.storeId);
- const user = database.users.find((u) => u.id === report.userId);
- const profit = report.totalIncome - report.totalExpenses;
+// // Отображение отчетов
+// tbody.innerHTML = "";
+// database.reports.forEach((report) => {
+// const store = database.stores.find((s) => s.id === report.storeId);
+// const user = database.users.find((u) => u.id === report.userId);
+// const profit = report.totalIncome - report.totalExpenses;
- const row = document.createElement("tr");
- row.className = "hover:bg-gray-50";
- row.innerHTML = `
-
${
- report.date
- } |
-
${
- store ? store.name : "Неизвестно"
- } |
-
€${report.totalIncome.toFixed(
- 2
- )} |
-
€${report.totalExpenses.toFixed(
- 2
- )} |
-
€${profit.toFixed(2)} |
-
${
- user ? user.username : "Неизвестно"
- } |
-
-
- ${report.verified ? "Проверен" : "Не проверен"}
-
- |
-
-
-
- |
- `;
- tbody.appendChild(row);
- });
+// const row = document.createElement("tr");
+// row.className = "hover:bg-gray-50";
+// row.innerHTML = `
+//
${
+// report.date
+// } |
+//
${
+// store ? store.name : "Неизвестно"
+// } |
+//
€${report.totalIncome.toFixed(
+// 2
+// )} |
+//
€${report.totalExpenses.toFixed(
+// 2
+// )} |
+//
€${profit.toFixed(2)} |
+//
${
+// user ? user.username : "Неизвестно"
+// } |
+//
+//
+// ${report.verified ? "Проверен" : "Не проверен"}
+//
+// |
+//
+//
+//
+// |
+// `;
+// tbody.appendChild(row);
+// });
- // Настройка фильтров и экспорта
- setupReportsFilters();
-}
+// // Настройка фильтров и экспорта
+// setupReportsFilters();
+// }
// Просмотр отчета
-function viewReport(reportId) {
- const report = database.reports.find((r) => r.id === reportId);
- if (report) {
- showReportModal(report, true); // true = админ режим
- }
-}
+// function viewReport(reportId) {
+// const report = database.reports.find((r) => r.id === reportId);
+// if (report) {
+// showReportModal(report, true); // true = админ режим
+// }
+// }
// Удаление отчета
function deleteReport(reportId) {