- ${report.expenses
+ ${expenses
.map(
(e) => `
@@ -848,9 +915,25 @@ function showReportModal(report, isAdmin = false) {
`;
buttons.innerHTML = "";
-
if (isAdmin) {
- buttons.innerHTML = `
+ if (report.isVerified || report.verified) {
+ // Verified: only unverify + close
+ buttons.innerHTML = `
+
Отчет подтвержден. Для внесения изменений снимите подтверждение.
+
+
+ `;
+ document
+ .getElementById("unverifyReportBtn")
+ .addEventListener("click", () => {
+ unverifyReport(report.id);
+ });
+ } else {
+ buttons.innerHTML = `
@@ -861,37 +944,39 @@ function showReportModal(report, isAdmin = false) {
Закрыть
`;
-
- document.getElementById("editReportBtn").addEventListener("click", () => {
- editReport(report);
- });
-
- document.getElementById("verifyReportBtn").addEventListener("click", () => {
- verifyReport(report.id);
- });
+ document.getElementById("editReportBtn").addEventListener("click", () => {
+ editReport(report);
+ });
+ document
+ .getElementById("verifyReportBtn")
+ .addEventListener("click", () => {
+ verifyReport(report.id);
+ });
+ }
} else {
if (!report.isVerified && !report.verified) {
buttons.innerHTML = `
-
-
- `;
-
+
+
+ `;
document
.getElementById("editReportUserBtn")
.addEventListener("click", () => {
+ appState.editingReportId = report.id;
fillFormWithReport(report);
hideModal("reportViewModal");
});
} else {
buttons.innerHTML = `
-
- `;
+
Отчет подтвержден и не может быть изменен. Обратитесь к администратору для изменений.
+
+ `;
}
}
@@ -904,6 +989,14 @@ function showReportModal(report, isAdmin = false) {
showModal("reportViewModal");
}
+// helpder of the modal of showReportModal - unverify report for ADMIN
+async function unverifyReport(reportId) {
+ await updateReport(reportId, { isVerified: 0 });
+ showNotification("Подтверждение снято. Теперь можно редактировать.");
+ await loadReports();
+ hideModal("reportViewModal");
+}
+
// Настройка фильтров отчетов
function setupReportsFilters() {
document
@@ -999,49 +1092,69 @@ function deleteReport(reportId) {
});
}
+//USER BEHAVIOUR INSIDE REPORTS
// Заполнение формы данными отчета (для пользователя)
function fillFormWithReport(report) {
appState.editingReportId = report.id;
document.getElementById("storeSelect").value = report.storeId;
- document.getElementById("income").value = report.income;
- document.getElementById("cajaInicial").value = report.cajaInicial;
+ document.getElementById("income").value = report.income || 0;
+ document.getElementById("cajaInicial").value =
+ report.cajaInicial || report.initialCash || 0;
document.getElementById("envelope").value = report.envelope;
- // Заполнение зарплат
+ // --- Parse wages/expenses if they are string ---
+ let wages = report.wages;
+ let expenses = report.expenses;
+ if (typeof wages === "string") {
+ try {
+ wages = JSON.parse(wages);
+ } catch {
+ wages = [];
+ }
+ }
+ if (typeof expenses === "string") {
+ try {
+ expenses = JSON.parse(expenses);
+ } catch {
+ expenses = [];
+ }
+ }
+
+ // --- Fill Wages ---
const wagesContainer = document.getElementById("wagesContainer");
wagesContainer.innerHTML = "";
- if (report.wages && report.wages.length > 0) {
- report.wages.forEach((wage) => {
+ if (Array.isArray(wages) && wages.length > 0) {
+ wages.forEach((wage) => {
const row = document.createElement("div");
row.className = "wage-row grid grid-cols-1 md:grid-cols-3 gap-4 mb-3";
row.innerHTML = `
-
-
-
- `;
+
+
+
+ `;
wagesContainer.appendChild(row);
});
} else {
addWageRow();
}
- // Заполнение расходов
+ // --- Fill Expenses ---
const expensesContainer = document.getElementById("expensesContainer");
expensesContainer.innerHTML = "";
- if (report.expenses && report.expenses.length > 0) {
- report.expenses.forEach((expense) => {
+ if (Array.isArray(expenses) && expenses.length > 0) {
+ expenses.forEach((expense) => {
const row = document.createElement("div");
row.className = "expense-row grid grid-cols-1 md:grid-cols-3 gap-4 mb-3";
row.innerHTML = `
-
-
-
- `;
+
+
+
+ `;
expensesContainer.appendChild(row);
});
} else {
@@ -1186,41 +1299,86 @@ function setupFormCalculations() {
cajaInicialInput.addEventListener("input", updateCalculations);
envelopeInput.addEventListener("input", updateCalculations);
- setupDynamicRows();
+ // setupDynamicRows();
}
+document.addEventListener("DOMContentLoaded", setupDynamicRows);
+
// Настройка динамических строк
+// function setupDynamicRows() {
+// document.getElementById("addWage").addEventListener("click", () => {
+// addWageRow();
+// });
+
+// document.getElementById("addExpense").addEventListener("click", () => {
+// addExpenseRow();
+// });
+
+// // Обновление при изменении значений
+// document.addEventListener("input", (e) => {
+// if (
+// e.target.classList.contains("wage-amount") ||
+// e.target.classList.contains("expense-amount")
+// ) {
+// updateTotals();
+// }
+// });
+
+// // Удаление строк
+// document.addEventListener("click", (e) => {
+// if (e.target.classList.contains("remove-wage")) {
+// e.target.closest(".wage-row").remove();
+// updateTotals();
+// } else if (e.target.classList.contains("remove-expense")) {
+// e.target.closest(".expense-row").remove();
+// updateTotals();
+// }
+// });
+// }
+
+let dynamicRowsInitialized = false;
+
function setupDynamicRows() {
- document.getElementById("addWage").addEventListener("click", () => {
- addWageRow();
- });
+ // Only run the global listeners ONCE!
+ if (!dynamicRowsInitialized) {
+ document.addEventListener("input", (e) => {
+ if (
+ e.target.classList.contains("wage-amount") ||
+ e.target.classList.contains("expense-amount")
+ ) {
+ updateTotals();
+ }
+ });
- document.getElementById("addExpense").addEventListener("click", () => {
- addExpenseRow();
- });
+ document.addEventListener("click", (e) => {
+ if (e.target.classList.contains("remove-wage")) {
+ e.target.closest(".wage-row").remove();
+ updateTotals();
+ } else if (e.target.classList.contains("remove-expense")) {
+ e.target.closest(".expense-row").remove();
+ updateTotals();
+ }
+ });
- // Обновление при изменении значений
- document.addEventListener("input", (e) => {
- if (
- e.target.classList.contains("wage-amount") ||
- e.target.classList.contains("expense-amount")
- ) {
- updateTotals();
- }
- });
+ dynamicRowsInitialized = true;
+ }
- // Удаление строк
- document.addEventListener("click", (e) => {
- if (e.target.classList.contains("remove-wage")) {
- e.target.closest(".wage-row").remove();
- updateTotals();
- } else if (e.target.classList.contains("remove-expense")) {
- e.target.closest(".expense-row").remove();
- updateTotals();
- }
- });
+ // Always attach these because they might be removed and re-injected
+ const addWageBtn = document.getElementById("addWage");
+ if (addWageBtn && !addWageBtn.hasListener) {
+ addWageBtn.addEventListener("click", () => addWageRow());
+ addWageBtn.hasListener = true;
+ }
+
+ const addExpenseBtn = document.getElementById("addExpense");
+ if (addExpenseBtn && !addExpenseBtn.hasListener) {
+ addExpenseBtn.addEventListener("click", () => addExpenseRow());
+ addExpenseBtn.hasListener = true;
+ }
}
+document.addEventListener("DOMContentLoaded", setupDynamicRows);
+
function addWageRow() {
const container = document.getElementById("wagesContainer");
const row = document.createElement("div");
@@ -1286,6 +1444,7 @@ function updateTotals() {
const totalIncome = income + cajaInicial;
const cajaFinal = totalIncome - totalExpenses - envelope;
+ document.getElementById("totalIncome").value = totalIncome.toFixed(2); // <-- Add this line!
document.getElementById("cajaFinal").textContent = cajaFinal.toFixed(2);
}
@@ -1312,47 +1471,104 @@ function safeToFixed(value, digits = 2) {
return (Number(value) || 0).toFixed(digits);
}
+// save report as user-worker
document.getElementById("reportForm").addEventListener("submit", async (e) => {
e.preventDefault();
+ const incomeValue = parseFloat(document.getElementById("income").value);
+ const cajaInicialValue = parseFloat(
+ document.getElementById("cajaInicial").value
+ );
+ const envelopeValue = parseFloat(document.getElementById("envelope").value);
+
+ const totalIncomeValue = incomeValue + cajaInicialValue;
+ const totalWagesValue = calculateTotalWages();
+ const totalExpensesValue = calculateTotalExpenses() + totalWagesValue;
+ const finalCashValue = totalIncomeValue - totalExpensesValue - envelopeValue;
+
const formData = {
storeId: parseInt(document.getElementById("storeSelect").value),
- reportDate: new Date().toISOString().split("T")[0], // Or get from input if user chooses date
- income: parseFloat(document.getElementById("income").value),
- initialCash: parseFloat(document.getElementById("cajaInicial").value),
- totalIncome: parseFloat(document.getElementById("totalIncome").value),
+ reportDate: new Date().toISOString().split("T")[0],
+ income: isNaN(incomeValue) ? 0 : incomeValue,
+ initialCash: isNaN(cajaInicialValue) ? 0 : cajaInicialValue,
+ totalIncome: isNaN(totalIncomeValue) ? 0 : totalIncomeValue,
wages: JSON.stringify(collectWages()),
expenses: JSON.stringify(collectExpenses()),
- totalWages: calculateTotalWages(),
- totalExpenses: calculateTotalExpenses() + calculateTotalWages(),
- envelope: parseFloat(document.getElementById("envelope").value),
- finalCash:
- parseFloat(document.getElementById("totalIncome").value) -
- (calculateTotalWages() + calculateTotalExpenses()) -
- parseFloat(document.getElementById("envelope").value),
+ totalWages: isNaN(totalWagesValue) ? 0 : totalWagesValue,
+ totalExpenses: isNaN(totalExpensesValue) ? 0 : totalExpensesValue,
+ envelope: isNaN(envelopeValue) ? 0 : envelopeValue,
+ finalCash: isNaN(finalCashValue) ? 0 : finalCashValue,
};
- // console.log("Sending report:", formData);
- const result = await createReport(formData);
- if (result.success) {
- showNotification("Отчет успешно создан!");
- await loadReports();
- document.getElementById("reportForm").reset();
+
+ let result;
+ if (appState.editingReportId) {
+ // EDIT mode: update existing report
+ // Update!
+ result = await updateReport(appState.editingReportId, formData);
} else {
+ // CREATE mode: new report
+ result = await createReport(formData);
+ }
+ // if result is missing --> error
+ if (!result) {
+ showNotification("Нет ответа от сервера. Попробуйте еще раз.", "error");
+ return;
+ }
+
+ if (result.success) {
+ const wasEdit = !!appState.editingReportId;
+ appState.editingReportId = null;
+ window.scrollTo({ top: 0, behavior: "smooth" });
+ document.getElementById("reportForm").reset();
+ document.getElementById("wagesContainer").innerHTML = "";
+ addWageRow();
+
+ document.getElementById("expensesContainer").innerHTML = "";
+ addExpenseRow();
+
+ showNotification(
+ wasEdit ? "Отчет успешно отредактирован!" : "Отчет успешно создан!"
+ );
+ await loadReports();
+ refreshTodaysReports();
+ console.log("Updated todaysReports:", appState.todaysReports);
+ } else {
+ window.scrollTo({ top: 0, behavior: "smooth" });
+ document.getElementById("reportForm").reset();
showNotification(result.error || "Ошибка создания отчета", "error");
}
});
+//helper for USER UI
+function refreshTodaysReports() {
+ const today = new Date().toISOString().split("T")[0];
+ appState.todaysReports = (appState.reportsList || []).filter(
+ (r) => (r.reportDate || r.date) === today
+ );
+}
+
// Отчет за сегодня для пользователя
document.getElementById("todayReportBtn").addEventListener("click", () => {
- const today = new Date().toISOString().split("T")[0];
- const todayReport = database.reports.find(
- (r) => r.date === today && r.userId === appState.currentUser.id
+ const storeId = document.getElementById("storeSelect").value;
+ if (!storeId) {
+ showNotification("Пожалуйста, выберите магазин!", "error");
+ return;
+ }
+ const report = (appState.todaysReports || []).find(
+ (r) => String(r.storeId) === String(storeId)
);
-
- if (todayReport) {
- showReportModal(todayReport, false); // false = не админ режим
+ if (report) {
+ showReportModal(report, false);
} else {
- showNotification("Отчет за сегодня не найден", "error");
+ showNotification("Сегодняшний отчет еще не создан", "error");
+ document.getElementById("reportForm").reset();
+ document.getElementById("storeSelect").value = storeId;
+
+ document.getElementById("wagesContainer").innerHTML = "";
+ addWageRow();
+
+ document.getElementById("expensesContainer").innerHTML = "";
+ addExpenseRow();
}
});
@@ -1545,6 +1761,7 @@ async function saveUser() {
hideModal("userEditModal");
loadUsers();
updateDashboard();
+ loadReports();
} else if (result) {
showNotification(result.error || "Ошибка операции", "error");
}