diff --git a/cron-jobs.js b/cron-jobs.js new file mode 100644 index 0000000..79580e6 --- /dev/null +++ b/cron-jobs.js @@ -0,0 +1,92 @@ +// cron-jobs.js +const { logActivity } = require('./database'); + +/** + * Проверяет задачи с типом document_approval, у которых указан номер документа, + * и автоматически переводит всех их исполнителей в статус completed. + * Задача остаётся открытой (closed_at не заполняется). + * @param {Object} db - экземпляр базы данных SQLite + */ +function checkDocumentsForCompletion(db) { + console.log('🔄 [CRON] Проверка задач документов для автоматического завершения исполнителей...'); + + // Находим активные задачи типа document, у которых есть номер документа + // и которые ещё не закрыты (closed_at IS NULL) – можно оставить для страховки + const query = ` + SELECT id, title, document_n + FROM tasks + WHERE task_type = 'document' + AND status = 'active' + AND closed_at IS NULL + AND document_n IS NOT NULL + AND document_n != '' + `; + + db.all(query, [], (err, tasks) => { + if (err) { + console.error('❌ [CRON] Ошибка при поиске задач документов:', err); + return; + } + + if (!tasks || tasks.length === 0) { + console.log('ℹ️ [CRON] Нет задач документов, требующих завершения исполнителей.'); + return; + } + + console.log(`🔍 [CRON] Найдено ${tasks.length} задач документов с номером.`); + + tasks.forEach(task => { + // Для каждой задачи находим всех исполнителей, у которых статус не 'completed' + const assignmentQuery = ` + SELECT id, user_id, status + FROM task_assignments + WHERE task_id = ? AND status != 'completed' + `; + + db.all(assignmentQuery, [task.id], (err, assignments) => { + if (err) { + console.error(`❌ [CRON] Ошибка при получении исполнителей задачи ${task.id}:`, err); + return; + } + + if (!assignments || assignments.length === 0) { + console.log(`ℹ️ [CRON] Задача ${task.id} (${task.title}) уже имеет всех исполнителей со статусом completed.`); + return; + } + + console.log(`📋 [CRON] Задача ${task.id}: нужно завершить ${assignments.length} исполнителей.`); + + // Обновляем статус каждого исполнителя на 'completed' + assignments.forEach(assignment => { + db.run( + `UPDATE task_assignments SET status = 'completed', updated_at = CURRENT_TIMESTAMP WHERE id = ?`, + [assignment.id], + function(err) { + if (err) { + console.error(`❌ [CRON] Ошибка обновления назначения ${assignment.id}:`, err); + } else { + console.log(`✅ [CRON] Исполнитель ${assignment.user_id} задачи ${task.id} завершён автоматически.`); + + // Логируем действие + try { + logActivity( + task.id, + 0, // системное действие, user_id = null + 'AUTO_COMPLETED', + `Автоматически завершено после указания номера документа` + ); + } catch (logErr) { + console.error('❌ [CRON] Ошибка логирования:', logErr); + } + } + } + ); + }); + }); + }); + }); +} + +module.exports = { + checkDocumentsForCompletion +}; \ No newline at end of file diff --git a/server.js b/server.js index 6905b51..701adb2 100644 --- a/server.js +++ b/server.js @@ -6,6 +6,8 @@ const fs = require('fs'); const session = require('express-session'); require('dotenv').config(); +const cronJobs = require('./cron-jobs'); + // Импортируем модули const { initializeDatabase, getDb, isInitialized } = require('./database'); const authService = require('./auth'); @@ -1582,6 +1584,7 @@ initializeServer().then(() => { // Запускаем фоновые задачи setInterval(checkOverdueTasks, 60000); setInterval(checkUpcomingDeadlines, 60000); + setInterval(() => cronJobs.checkDocumentsForCompletion(db), 60000); }); }).catch(error => { console.error('❌ Не удалось запустить сервер:', error);