targo-backend/prisma/mock-seeds-scripts/10-shifts.ts
2025-08-29 09:34:30 -04:00

130 lines
3.9 KiB
TypeScript

import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// ====== Config ======
const PREVIOUS_WEEKS = 5;
const INCLUDE_CURRENT = false;
function timeAt(hour: number, minute: number) {
return new Date(Date.UTC(1970, 0, 1, hour, minute, 0));
}
function mondayOfThisWeekUTC(now = new Date()) {
const d = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
const day = d.getUTCDay();
const diffToMonday = (day + 6) % 7;
d.setUTCDate(d.getUTCDate() - diffToMonday);
d.setUTCHours(0, 0, 0, 0);
return d;
}
function weekDatesFromMonday(monday: Date) {
return Array.from({ length: 5 }, (_, i) => {
const d = new Date(monday);
d.setUTCDate(monday.getUTCDate() + i);
return d;
});
}
function mondayNWeeksBefore(monday: Date, n: number) {
const d = new Date(monday);
d.setUTCDate(d.getUTCDate() - n * 7);
return d;
}
function rndInt(min: number, max: number) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
async function main() {
// Bank codes utilisés
const BANKS = ['G1', 'G56', 'G48', 'G700', 'G105', 'G305', 'G43'] 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]));
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 tsByEmp = new Map<number, { id: number }[]>();
{
const allTs = await prisma.timesheets.findMany({
where: { employee_id: { in: employees.map(e => e.id) } },
select: { id: true, employee_id: true },
orderBy: { id: 'asc' },
});
for (const e of employees) {
tsByEmp.set(e.id, allTs.filter(t => t.employee_id === e.id).map(t => ({ id: t.id })));
}
}
const mondayThisWeek = mondayOfThisWeekUTC();
const mondays: Date[] = [];
if (INCLUDE_CURRENT) mondays.push(mondayThisWeek);
for (let n = 1; n <= PREVIOUS_WEEKS; n++) {
mondays.push(mondayNWeeksBefore(mondayThisWeek, n));
}
let created = 0;
for (let wi = 0; wi < mondays.length; wi++) {
const monday = mondays[wi];
const weekDays = weekDatesFromMonday(monday);
for (let ei = 0; ei < employees.length; ei++) {
const e = employees[ei];
const tss = tsByEmp.get(e.id) ?? [];
if (!tss.length) continue;
const baseStartHour = 6 + (ei % 5);
const baseStartMinute = (ei * 15) % 60;
for (let di = 0; di < weekDays.length; di++) {
const date = weekDays[di];
// Tirage aléatoire du bank_code
const randomCode = BANKS[Math.floor(Math.random() * BANKS.length)];
const bank_code_id = bcMap.get(randomCode)!;
const duration = rndInt(4, 10);
const dayWeekOffset = (di + wi + (ei % 3)) % 3;
const startH = Math.min(12, baseStartHour + dayWeekOffset);
const startM = baseStartMinute;
const endH = startH + duration;
const endM = startM;
const ts = tss[(di + wi) % tss.length];
await prisma.shifts.create({
data: {
timesheet_id: ts.id,
bank_code_id,
description: `Shift ${di + 1} (semaine du ${monday.toISOString().slice(0, 10)}) emp ${e.id}${randomCode}`,
date,
start_time: timeAt(startH, startM),
end_time: timeAt(endH, endM),
is_approved: Math.random() < 0.5,
},
});
created++;
}
}
}
const total = await prisma.shifts.count();
console.log(`✓ Shifts: ${created} nouvelles lignes, ${total} total rows (${INCLUDE_CURRENT ? 'courante +' : ''}${PREVIOUS_WEEKS} semaines précédentes, L→V)`);
}
main().finally(() => prisma.$disconnect());