import Database from 'better-sqlite3'; import fs from 'fs'; import path from 'path'; import crypto from 'crypto'; // 1. Load DATABASE_URL from .env let dbPath = 'local.db'; try { const envContent = fs.readFileSync('.env', 'utf8'); const match = envContent.match(/^DATABASE_URL=(.+)$/m); if (match && match[1]) { dbPath = match[1].trim().replace(/['"]/g, ''); } } catch (e) { console.log('Aviso: .env não encontrado ou erro ao ler. Usando local.db por defeito.'); } console.log(`A ligar à base de dados em: ${dbPath}`); const db = new Database(dbPath); try { // Começar transação db.transaction(() => { // 1. Limpar a tabela de entregas (deliveries) console.log('A limpar tabela de entregas (deliveries)...'); db.prepare('DELETE FROM deliveries').run(); // 2. Garantir que existe pelo menos um turno (shift) let shift = db.prepare("SELECT * FROM shifts LIMIT 1").get(); if (!shift) { console.log('Nenhum turno encontrado. A criar turno padrão T1...'); const nowTs = Date.now(); const shiftId = crypto.randomUUID(); db.prepare(` INSERT INTO shifts (id, code, start_time, end_time, days, created_at, updated_at) VALUES (?, 'T1', '14:30', '16:30', '2,4', ?, ?) `).run(shiftId, nowTs, nowTs); shift = db.prepare("SELECT * FROM shifts LIMIT 1").get(); } if (!shift) { throw new Error('Não foi possível encontrar ou criar um turno padrão.'); } console.log(`Turno utilizado: ${shift.code} (ID: ${shift.id})`); // 3. Garantir que os beneficiários de teste #1, #2, #3 existem e estão ativos/parent const testCreationTime = Date.now() - 35 * 24 * 60 * 60 * 1000; for (const num of [1, 2, 3]) { const existing = db.prepare('SELECT * FROM beneficiaries WHERE number = ?').get(num); if (!existing) { const bId = crypto.randomUUID(); console.log(`A criar Beneficiário Teste #${num}...`); db.prepare(` INSERT INTO beneficiaries (id, number, name, contact, household_size, status, is_parent, created_at, updated_at) VALUES (?, ?, ?, ?, ?, 'ativo', 1, ?, ?) `).run( bId, num, `Beneficiário Teste #${num}`, `91234560${num}`, num, testCreationTime, Date.now() ); } else { console.log(`A atualizar Beneficiário Teste #${num}...`); db.prepare(` UPDATE beneficiaries SET status = 'ativo', is_parent = 1, created_at = ?, updated_at = ? WHERE id = ? `).run(testCreationTime, Date.now(), existing.id); } } // 4. Buscar todos os beneficiários ativos que são chefes de família (is_parent = 1) const activeBeneficiaries = db.prepare(` SELECT * FROM beneficiaries WHERE status = 'ativo' AND is_parent = 1 `).all(); console.log(`Encontrados ${activeBeneficiaries.length} beneficiários ativos (chefes de família).`); // 5. Calcular as terças (2) e quintas (4) nos últimos 30 dias const dates = []; const today = new Date(); const todayStr = today.toLocaleDateString('sv-SE', { timeZone: 'Europe/Lisbon' }); for (let i = 1; i <= 30; i++) { const d = new Date(); d.setDate(d.getDate() - i); const dayOfWeek = d.getDay(); if (dayOfWeek === 2 || dayOfWeek === 4) { const dateStr = d.toLocaleDateString('sv-SE', { timeZone: 'Europe/Lisbon' }); if (dateStr < todayStr) { dates.push(dateStr); } } } dates.sort(); if (dates.length === 0) { throw new Error('Não foram encontradas datas de entregas válidas nos últimos 30 dias.'); } console.log(`Datas calculadas para entregas (Terças/Quintas dos últimos 30 dias):`, dates); // 6. Inserir entregas de teste let insertedCount = 0; for (const b of activeBeneficiaries) { let datesToInsert = [...dates]; // Logica para criar diferentes níveis de ausências nos dados de teste if (b.number === 1) { datesToInsert = dates.slice(1); } else if (b.number === 2) { datesToInsert = dates.slice(2); } else if (b.number === 3) { datesToInsert = dates.slice(3); } for (const dateStr of datesToInsert) { const deliveryId = crypto.randomUUID(); db.prepare(` INSERT INTO deliveries (id, beneficiary_id, shift_id, date, created_at) VALUES (?, ?, ?, ?, ?) `).run(deliveryId, b.id, shift.id, dateStr, Date.now()); insertedCount++; } } console.log(`Sucesso! Foram geradas ${insertedCount} entregas para os beneficiários ativos.`); })(); } catch (err) { console.error('Erro ao gerar dados de teste:', err); process.exit(1); }