117 lines
4.1 KiB
TypeScript
117 lines
4.1 KiB
TypeScript
import { PrismaClient } from '@prisma/client';
|
||
|
||
const prisma = new PrismaClient();
|
||
|
||
// Stocker une heure (Postgres TIME) via Date (UTC 1970-01-01)
|
||
function timeAt(hour: number, minute: number) {
|
||
return new Date(Date.UTC(1970, 0, 1, hour, minute, 0));
|
||
}
|
||
|
||
// Lundi de la semaine (en UTC) pour la date courante
|
||
function mondayOfThisWeekUTC(now = new Date()) {
|
||
// converti en UTC (sans l'heure)
|
||
const d = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
|
||
const day = d.getUTCDay(); // 0=Dim, 1=Lun, ...
|
||
const diffToMonday = (day + 6) % 7; // 0 si lundi, 1 si mardi, ... 6 si dimanche
|
||
d.setUTCDate(d.getUTCDate() - diffToMonday);
|
||
d.setUTCHours(0, 0, 0, 0);
|
||
return d;
|
||
}
|
||
|
||
// Retourne les 5 dates Lundi→Vendredi (UTC, à minuit)
|
||
function currentWeekDates() {
|
||
const monday = mondayOfThisWeekUTC();
|
||
return Array.from({ length: 5 }, (_, i) => {
|
||
const d = new Date(monday);
|
||
d.setUTCDate(monday.getUTCDate() + i);
|
||
return d;
|
||
});
|
||
}
|
||
|
||
async function main() {
|
||
// On récupère les bank codes requis (ajuste le nom de la colonne "code" si besoin)
|
||
const BANKS = ['G1', 'G305', 'G105'] as const;
|
||
const bcRows = await prisma.bankCodes.findMany({
|
||
where: { bank_code: { in: BANKS as unknown as string[] } },
|
||
select: { id: true, bank_code: true },
|
||
});
|
||
const bcMap = new Map(bcRows.map(b => [b.bank_code, b.id]));
|
||
|
||
// Vérifications
|
||
for (const c of BANKS) {
|
||
if (!bcMap.has(c)) throw new Error(`Bank code manquant: ${c}`);
|
||
}
|
||
|
||
const employees = await prisma.employees.findMany({ select: { id: true } });
|
||
if (!employees.length) {
|
||
console.log('Aucun employé — rien à insérer.');
|
||
return;
|
||
}
|
||
|
||
const weekDays = currentWeekDates();
|
||
|
||
// Par défaut: G1 (régulier). 1 employé sur 5 : 1 jour de la semaine passe à G305 OU G105 (au hasard)
|
||
// Horaires: on décale par employé pour garantir des horaires différents.
|
||
// - start = 7, 7h30, 8, 8h30 selon l’index employé
|
||
// - durée = 8h sauf vendredi (7h) pour varier un peu
|
||
for (let ei = 0; ei < employees.length; ei++) {
|
||
const e = employees[ei];
|
||
|
||
const tss = await prisma.timesheets.findMany({
|
||
where: { employee_id: e.id },
|
||
select: { id: true },
|
||
orderBy: { id: 'asc' }, // ajuste si tu préfères "created_at" etc.
|
||
});
|
||
if (!tss.length) continue;
|
||
|
||
// Horaires spécifiques à l’employé (déterministes)
|
||
const startHalfHourSlot = ei % 4; // 0..3 -> 7:00, 7:30, 8:00, 8:30
|
||
const startHourBase = 7 + Math.floor(startHalfHourSlot / 2); // 7 ou 8
|
||
const startMinuteBase = (startHalfHourSlot % 2) * 30; // 0 ou 30
|
||
|
||
// Doit-on donner un jour "différent" de G1 à cet employé ?
|
||
const isSpecial = (ei % 5) === 0; // 1 sur 5
|
||
const specialDayIdx = isSpecial ? Math.floor(Math.random() * 5) : -1;
|
||
const specialCode = isSpecial ? (Math.random() < 0.5 ? 'G305' : 'G105') : 'G1';
|
||
|
||
// 5 jours (lun→ven)
|
||
for (let di = 0; di < weekDays.length; di++) {
|
||
const date = weekDays[di];
|
||
|
||
// Bank code du jour
|
||
const codeToday = (di === specialDayIdx) ? specialCode : 'G1';
|
||
const bank_code_id = bcMap.get(codeToday)!;
|
||
|
||
// Durée : 8h habituellement, 7h le vendredi pour varier (di==4)
|
||
const duration = (di === 4) ? 7 : 8;
|
||
|
||
// Légère variation journalière (+0..2h) pour casser la monotonie, mais bornée
|
||
const dayOffset = di % 3; // 0,1,2
|
||
const startH = Math.min(10, startHourBase + dayOffset);
|
||
const startM = startMinuteBase;
|
||
|
||
const endH = startH + duration;
|
||
const endM = startM;
|
||
|
||
const ts = tss[di % tss.length];
|
||
|
||
await prisma.shifts.create({
|
||
data: {
|
||
timesheet_id: ts.id,
|
||
bank_code_id,
|
||
description: `Shift ${di + 1} (Semaine courante) emp ${e.id} — ${codeToday}`,
|
||
date, // Date du jour (UTC minuit)
|
||
start_time: timeAt(startH, startM),
|
||
end_time: timeAt(endH, endM),
|
||
is_approved: Math.random() < 0.5,
|
||
},
|
||
});
|
||
}
|
||
}
|
||
|
||
const total = await prisma.shifts.count();
|
||
console.log(`✓ Shifts: ${total} total rows (semaine courante L→V)`);
|
||
}
|
||
|
||
main().finally(() => prisma.$disconnect());
|