From e76f2a9a72f79c6f70559236f217a21dece54e8b Mon Sep 17 00:00:00 2001 From: Matthieu Haineault Date: Thu, 27 Nov 2025 08:47:47 -0500 Subject: [PATCH] feat(preferences): added validation pipes to DTO, commented migration scripts --- scripts/done/import-employees-from-csv.ts | 444 +++++++++--------- scripts/done/import-users-from-csv.ts | 172 +++---- scripts/done/init-preferences.ts | 104 ++-- scripts/migrate-expenses.ts | 286 +++++------ scripts/migrate-shifts.ts | 376 +++++++-------- scripts/migrate-timesheets.ts | 208 ++++---- scripts/migration.service.ts | 34 +- .../preferences/dtos/preferences.dto.ts | 19 +- .../services/preferences.service.ts | 4 +- src/main.ts | 6 +- 10 files changed, 829 insertions(+), 824 deletions(-) diff --git a/scripts/done/import-employees-from-csv.ts b/scripts/done/import-employees-from-csv.ts index d36cf8a..3b4c638 100644 --- a/scripts/done/import-employees-from-csv.ts +++ b/scripts/done/import-employees-from-csv.ts @@ -1,270 +1,270 @@ -// src/scripts/import-employees-from-csv.ts -import { PrismaClient, Roles } from '@prisma/client'; -import * as fs from 'fs'; -import * as path from 'path'; +// // src/scripts/import-employees-from-csv.ts +// import { PrismaClient, Roles } from '@prisma/client'; +// import * as fs from 'fs'; +// import * as path from 'path'; -const prisma = new PrismaClient(); +// const prisma = new PrismaClient(); -// ⚙️ Chemin vers ton CSV employees -const CSV_PATH = path.resolve(__dirname, '../../data/export_new_employee_table.csv'); +// // ⚙️ Chemin vers ton CSV employees +// const CSV_PATH = path.resolve(__dirname, '../../data/export_new_employee_table.csv'); -// Rôles éligibles pour la table Employees -const ELIGIBLE_ROLES: Roles[] = [ - Roles.EMPLOYEE, - Roles.SUPERVISOR, - Roles.HR, - Roles.ACCOUNTING, - Roles.ADMIN, -]; +// // Rôles éligibles pour la table Employees +// const ELIGIBLE_ROLES: Roles[] = [ +// Roles.EMPLOYEE, +// Roles.SUPERVISOR, +// Roles.HR, +// Roles.ACCOUNTING, +// Roles.ADMIN, +// ]; -// Type correspondant EXACT aux colonnes de ton CSV -type EmployeeCsvRow = { - employee_number: string; - email: string; - job_title: string; - company: string; // sera converti en number - is_supervisor: string; // "True"/"False" (ou variantes) - onboarding: string; // millis - offboarding: string; // millis ou "NULL" -}; +// // Type correspondant EXACT aux colonnes de ton CSV +// type EmployeeCsvRow = { +// employee_number: string; +// email: string; +// job_title: string; +// company: string; // sera converti en number +// is_supervisor: string; // "True"/"False" (ou variantes) +// onboarding: string; // millis +// offboarding: string; // millis ou "NULL" +// }; -// Représentation minimale d'un user -type UserSummary = { - id: string; // UUID - email: string; - role: Roles; -}; +// // Représentation minimale d'un user +// type UserSummary = { +// id: string; // UUID +// email: string; +// role: Roles; +// }; -// ============ Helpers CSV ============ +// // ============ Helpers CSV ============ -function splitCsvLine(line: string): string[] { - const result: string[] = []; - let current = ''; - let inQuotes = false; +// function splitCsvLine(line: string): string[] { +// const result: string[] = []; +// let current = ''; +// let inQuotes = false; - for (let i = 0; i < line.length; i++) { - const char = line[i]; +// for (let i = 0; i < line.length; i++) { +// const char = line[i]; - if (char === '"') { - // guillemet échappé "" - if (inQuotes && line[i + 1] === '"') { - current += '"'; - i++; - } else { - inQuotes = !inQuotes; - } - } else if (char === ',' && !inQuotes) { - result.push(current); - current = ''; - } else { - current += char; - } - } +// if (char === '"') { +// // guillemet échappé "" +// if (inQuotes && line[i + 1] === '"') { +// current += '"'; +// i++; +// } else { +// inQuotes = !inQuotes; +// } +// } else if (char === ',' && !inQuotes) { +// result.push(current); +// current = ''; +// } else { +// current += char; +// } +// } - result.push(current); - return result.map((v) => v.trim()); -} +// result.push(current); +// return result.map((v) => v.trim()); +// } -// ============ Helpers de parsing ============ +// // ============ Helpers de parsing ============ -function parseBoolean(value: string): boolean { - const v = value.trim().toLowerCase(); - return v === 'true' || v === '1' || v === 'yes' || v === 'y' || v === 'oui'; -} +// function parseBoolean(value: string): boolean { +// const v = value.trim().toLowerCase(); +// return v === 'true' || v === '1' || v === 'yes' || v === 'y' || v === 'oui'; +// } -function parseIntSafe(value: string, fieldName: string): number | null { - const trimmed = value.trim(); - if (!trimmed || trimmed.toUpperCase() === 'NULL') return null; +// function parseIntSafe(value: string, fieldName: string): number | null { +// const trimmed = value.trim(); +// if (!trimmed || trimmed.toUpperCase() === 'NULL') return null; - const n = Number.parseInt(trimmed, 10); - if (Number.isNaN(n)) { - console.warn(`⚠️ Impossible de parser "${value}" en entier pour le champ ${fieldName}`); - return null; - } - return n; -} +// const n = Number.parseInt(trimmed, 10); +// if (Number.isNaN(n)) { +// console.warn(`⚠️ Impossible de parser "${value}" en entier pour le champ ${fieldName}`); +// return null; +// } +// return n; +// } -function millisToDate(value: string): Date | null { - const trimmed = value.trim().toUpperCase(); - if (!trimmed || trimmed === 'NULL') return null; +// function millisToDate(value: string): Date | null { +// const trimmed = value.trim().toUpperCase(); +// if (!trimmed || trimmed === 'NULL') return null; - const ms = Number(trimmed); - if (!Number.isFinite(ms)) { - console.warn(`⚠️ Impossible de parser "${value}" en millis pour une Date`); - return null; - } +// const ms = Number(trimmed); +// if (!Number.isFinite(ms)) { +// console.warn(`⚠️ Impossible de parser "${value}" en millis pour une Date`); +// return null; +// } - const d = new Date(ms); - // On normalise au jour (minuit UTC) - const normalized = new Date(Date.UTC( - d.getUTCFullYear(), - d.getUTCMonth(), - d.getUTCDate(), - )); +// const d = new Date(ms); +// // On normalise au jour (minuit UTC) +// const normalized = new Date(Date.UTC( +// d.getUTCFullYear(), +// d.getUTCMonth(), +// d.getUTCDate(), +// )); - return normalized; -} +// return normalized; +// } -// ============ MAIN ============ +// // ============ MAIN ============ -async function main() { - // 1. Lecture du CSV - const fileContent = fs.readFileSync(CSV_PATH, 'utf-8'); +// async function main() { +// // 1. Lecture du CSV +// const fileContent = fs.readFileSync(CSV_PATH, 'utf-8'); - const lines = fileContent - .split(/\r?\n/) - .map((l) => l.trim()) - .filter((l) => l.length > 0); +// const lines = fileContent +// .split(/\r?\n/) +// .map((l) => l.trim()) +// .filter((l) => l.length > 0); - if (lines.length <= 1) { - console.error('CSV vide ou seulement un header'); - return; - } +// if (lines.length <= 1) { +// console.error('CSV vide ou seulement un header'); +// return; +// } - const header = splitCsvLine(lines[0]); // ["employee_number","email",...] - const dataLines = lines.slice(1); +// const header = splitCsvLine(lines[0]); // ["employee_number","email",...] +// const dataLines = lines.slice(1); - const csvRows: EmployeeCsvRow[] = dataLines.map((line) => { - const values = splitCsvLine(line); - const row: any = {}; +// const csvRows: EmployeeCsvRow[] = dataLines.map((line) => { +// const values = splitCsvLine(line); +// const row: any = {}; - header.forEach((col, idx) => { - row[col] = values[idx] ?? ''; - }); +// header.forEach((col, idx) => { +// row[col] = values[idx] ?? ''; +// }); - return row as EmployeeCsvRow; - }); +// return row as EmployeeCsvRow; +// }); - console.log(`➡️ ${csvRows.length} lignes trouvées dans le CSV employees`); +// console.log(`➡️ ${csvRows.length} lignes trouvées dans le CSV employees`); - // 2. Récupérer tous les emails du CSV - const emails = Array.from( - new Set( - csvRows - .map((r) => r.email.trim()) - .filter((e) => e.length > 0), - ), - ); +// // 2. Récupérer tous les emails du CSV +// const emails = Array.from( +// new Set( +// csvRows +// .map((r) => r.email.trim()) +// .filter((e) => e.length > 0), +// ), +// ); - console.log(`➡️ ${emails.length} emails uniques trouvés dans le CSV`); +// console.log(`➡️ ${emails.length} emails uniques trouvés dans le CSV`); - // 3. Charger les users correspondants avec les bons rôles - const users = (await prisma.users.findMany({ - where: { - email: { in: emails }, - role: { in: ELIGIBLE_ROLES }, - }, - select: { - id: true, - email: true, - role: true, - }, - })) as UserSummary[]; +// // 3. Charger les users correspondants avec les bons rôles +// const users = (await prisma.users.findMany({ +// where: { +// email: { in: emails }, +// role: { in: ELIGIBLE_ROLES }, +// }, +// select: { +// id: true, +// email: true, +// role: true, +// }, +// })) as UserSummary[]; - console.log(`➡️ ${users.length} users éligibles trouvés dans la DB`); +// console.log(`➡️ ${users.length} users éligibles trouvés dans la DB`); - // Map email → user - const userByEmail = new Map(); - for (const user of users) { - const key = user.email.trim().toLowerCase(); - userByEmail.set(key, user); - } +// // Map email → user +// const userByEmail = new Map(); +// for (const user of users) { +// const key = user.email.trim().toLowerCase(); +// userByEmail.set(key, user); +// } - // 4. Construire les données pour employees.createMany - const employeesToCreate: { - user_id: string; - external_payroll_id: number; - company_code: number; - first_work_day: Date; - last_work_day: Date | null; - job_title: string | null; - is_supervisor: boolean; - supervisor_id?: number | null; - }[] = []; +// // 4. Construire les données pour employees.createMany +// const employeesToCreate: { +// user_id: string; +// external_payroll_id: number; +// company_code: number; +// first_work_day: Date; +// last_work_day: Date | null; +// job_title: string | null; +// is_supervisor: boolean; +// supervisor_id?: number | null; +// }[] = []; - const rowsWithoutUser: EmployeeCsvRow[] = []; - const rowsWithInvalidNumbers: EmployeeCsvRow[] = []; +// const rowsWithoutUser: EmployeeCsvRow[] = []; +// const rowsWithInvalidNumbers: EmployeeCsvRow[] = []; - for (const row of csvRows) { - const emailKey = row.email.trim().toLowerCase(); - const user = userByEmail.get(emailKey); +// for (const row of csvRows) { +// const emailKey = row.email.trim().toLowerCase(); +// const user = userByEmail.get(emailKey); - if (!user) { - rowsWithoutUser.push(row); - continue; - } +// if (!user) { +// rowsWithoutUser.push(row); +// continue; +// } - const external_payroll_id = parseIntSafe(row.employee_number, 'external_payroll_id'); - const company_code = parseIntSafe(String(row.company), 'company_code'); +// const external_payroll_id = parseIntSafe(row.employee_number, 'external_payroll_id'); +// const company_code = parseIntSafe(String(row.company), 'company_code'); - if (external_payroll_id === null || company_code === null) { - rowsWithInvalidNumbers.push(row); - continue; - } +// if (external_payroll_id === null || company_code === null) { +// rowsWithInvalidNumbers.push(row); +// continue; +// } - const first_work_day = millisToDate(row.onboarding); - const last_work_day = millisToDate(row.offboarding); - const is_supervisor = parseBoolean(row.is_supervisor); - const job_title = row.job_title?.trim() || null; +// const first_work_day = millisToDate(row.onboarding); +// const last_work_day = millisToDate(row.offboarding); +// const is_supervisor = parseBoolean(row.is_supervisor); +// const job_title = row.job_title?.trim() || null; - if (!first_work_day) { - console.warn( - `⚠️ Date d'onboarding invalide pour ${row.email} (employee_number=${row.employee_number})`, - ); - continue; - } +// if (!first_work_day) { +// console.warn( +// `⚠️ Date d'onboarding invalide pour ${row.email} (employee_number=${row.employee_number})`, +// ); +// continue; +// } - employeesToCreate.push({ - user_id: user.id, - external_payroll_id, - company_code, - first_work_day, - last_work_day, - job_title, - is_supervisor, - supervisor_id: null, // on pourra gérer ça plus tard si tu as les infos - }); - } +// employeesToCreate.push({ +// user_id: user.id, +// external_payroll_id, +// company_code, +// first_work_day, +// last_work_day, +// job_title, +// is_supervisor, +// supervisor_id: null, // on pourra gérer ça plus tard si tu as les infos +// }); +// } - console.log(`➡️ ${employeesToCreate.length} entrées Employees prêtes à être insérées`); +// console.log(`➡️ ${employeesToCreate.length} entrées Employees prêtes à être insérées`); - if (rowsWithoutUser.length > 0) { - console.warn(`⚠️ ${rowsWithoutUser.length} lignes CSV sans user correspondant (email / rôle) :`); - for (const row of rowsWithoutUser) { - console.warn( - ` - email=${row.email}, employee_number=${row.employee_number}, company=${row.company}`, - ); - } - } +// if (rowsWithoutUser.length > 0) { +// console.warn(`⚠️ ${rowsWithoutUser.length} lignes CSV sans user correspondant (email / rôle) :`); +// for (const row of rowsWithoutUser) { +// console.warn( +// ` - email=${row.email}, employee_number=${row.employee_number}, company=${row.company}`, +// ); +// } +// } - if (rowsWithInvalidNumbers.length > 0) { - console.warn(`⚠️ ${rowsWithInvalidNumbers.length} lignes CSV avec ids/compagnies invalides :`); - for (const row of rowsWithInvalidNumbers) { - console.warn( - ` - email=${row.email}, employee_number="${row.employee_number}", company="${row.company}"`, - ); - } - } +// if (rowsWithInvalidNumbers.length > 0) { +// console.warn(`⚠️ ${rowsWithInvalidNumbers.length} lignes CSV avec ids/compagnies invalides :`); +// for (const row of rowsWithInvalidNumbers) { +// console.warn( +// ` - email=${row.email}, employee_number="${row.employee_number}", company="${row.company}"`, +// ); +// } +// } - if (employeesToCreate.length === 0) { - console.warn('⚠️ Aucun Employees à créer, arrêt.'); - return; - } +// if (employeesToCreate.length === 0) { +// console.warn('⚠️ Aucun Employees à créer, arrêt.'); +// return; +// } - // 5. Insert en batch - const result = await prisma.employees.createMany({ - data: employeesToCreate, - skipDuplicates: true, // évite les erreurs si tu relances le script - }); +// // 5. Insert en batch +// const result = await prisma.employees.createMany({ +// data: employeesToCreate, +// skipDuplicates: true, // évite les erreurs si tu relances le script +// }); - console.log(`✅ ${result.count} employees insérés dans la DB`); -} +// console.log(`✅ ${result.count} employees insérés dans la DB`); +// } -main() - .catch((err) => { - console.error('❌ Erreur pendant l’import CSV → Employees', err); - process.exit(1); - }) - .finally(async () => { - await prisma.$disconnect(); - }); +// main() +// .catch((err) => { +// console.error('❌ Erreur pendant l’import CSV → Employees', err); +// process.exit(1); +// }) +// .finally(async () => { +// await prisma.$disconnect(); +// }); diff --git a/scripts/done/import-users-from-csv.ts b/scripts/done/import-users-from-csv.ts index 2c0dad2..0bcf5a9 100644 --- a/scripts/done/import-users-from-csv.ts +++ b/scripts/done/import-users-from-csv.ts @@ -1,106 +1,106 @@ -// src/scripts/import-users-from-csv.ts -import { PrismaClient } from '@prisma/client'; -import * as fs from 'fs'; -import * as path from 'path'; +// // src/scripts/import-users-from-csv.ts +// import { PrismaClient } from '@prisma/client'; +// import * as fs from 'fs'; +// import * as path from 'path'; -const prisma = new PrismaClient(); +// const prisma = new PrismaClient(); -// ⚙️ Chemin vers ton CSV (à adapter selon où tu le mets) -const CSV_PATH = path.resolve(__dirname, '../../data/export_employee_table.csv'); +// // ⚙️ Chemin vers ton CSV (à adapter selon où tu le mets) +// const CSV_PATH = path.resolve(__dirname, '../../data/export_employee_table.csv'); -// Type aligné sur les colonnes du CSV -type CsvUserRow = { - email: string; - first_name: string; - last_name: string; - phone_number: string; -}; +// // Type aligné sur les colonnes du CSV +// type CsvUserRow = { +// email: string; +// first_name: string; +// last_name: string; +// phone_number: string; +// }; -// Petit parseur de ligne CSV sans dépendance -function splitCsvLine(line: string): string[] { - const result: string[] = []; - let current = ''; - let inQuotes = false; +// // Petit parseur de ligne CSV sans dépendance +// function splitCsvLine(line: string): string[] { +// const result: string[] = []; +// let current = ''; +// let inQuotes = false; - for (let i = 0; i < line.length; i++) { - const char = line[i]; +// for (let i = 0; i < line.length; i++) { +// const char = line[i]; - if (char === '"') { - // guillemet échappé "" - if (inQuotes && line[i + 1] === '"') { - current += '"'; - i++; // on saute le deuxième - } else { - inQuotes = !inQuotes; - } - } else if (char === ',' && !inQuotes) { - result.push(current); - current = ''; - } else { - current += char; - } - } +// if (char === '"') { +// // guillemet échappé "" +// if (inQuotes && line[i + 1] === '"') { +// current += '"'; +// i++; // on saute le deuxième +// } else { +// inQuotes = !inQuotes; +// } +// } else if (char === ',' && !inQuotes) { +// result.push(current); +// current = ''; +// } else { +// current += char; +// } +// } - result.push(current); - return result.map((v) => v.trim()); -} +// result.push(current); +// return result.map((v) => v.trim()); +// } -async function main() { - // 1. Lecture du fichier CSV - const fileContent = fs.readFileSync(CSV_PATH, 'utf-8'); +// async function main() { +// // 1. Lecture du fichier CSV +// const fileContent = fs.readFileSync(CSV_PATH, 'utf-8'); - const lines = fileContent - .split(/\r?\n/) - .map((l) => l.trim()) - .filter((l) => l.length > 0); +// const lines = fileContent +// .split(/\r?\n/) +// .map((l) => l.trim()) +// .filter((l) => l.length > 0); - if (lines.length <= 1) { - console.error('CSV vide ou seulement un header'); - return; - } +// if (lines.length <= 1) { +// console.error('CSV vide ou seulement un header'); +// return; +// } - // 2. Header (noms de colonnes) -> ["email", "first_name", "last_name", "phone_number"] - const header = splitCsvLine(lines[0]); - const dataLines = lines.slice(1); +// // 2. Header (noms de colonnes) -> ["email", "first_name", "last_name", "phone_number"] +// const header = splitCsvLine(lines[0]); +// const dataLines = lines.slice(1); - // 3. Conversion de chaque ligne en objet { email, first_name, last_name, phone_number } - const records: CsvUserRow[] = dataLines.map((line) => { - const values = splitCsvLine(line); - const row: any = {}; +// // 3. Conversion de chaque ligne en objet { email, first_name, last_name, phone_number } +// const records: CsvUserRow[] = dataLines.map((line) => { +// const values = splitCsvLine(line); +// const row: any = {}; - header.forEach((col, idx) => { - row[col] = values[idx] ?? ''; - }); +// header.forEach((col, idx) => { +// row[col] = values[idx] ?? ''; +// }); - return row as CsvUserRow; - }); +// return row as CsvUserRow; +// }); - // 4. Mapping vers le format attendu par Prisma (model Users) - const data = records.map((row) => ({ - email: row.email.trim(), - first_name: row.first_name.trim(), - last_name: row.last_name.trim(), - phone_number: row.phone_number.trim(), - // residence: null, // si tu veux la forcer à null - // role: 'GUEST', // sinon Prisma va appliquer la valeur par défaut - })); +// // 4. Mapping vers le format attendu par Prisma (model Users) +// const data = records.map((row) => ({ +// email: row.email.trim(), +// first_name: row.first_name.trim(), +// last_name: row.last_name.trim(), +// phone_number: row.phone_number.trim(), +// // residence: null, // si tu veux la forcer à null +// // role: 'GUEST', // sinon Prisma va appliquer la valeur par défaut +// })); - console.log(`➡️ ${data.length} lignes trouvées dans le CSV`); - console.log('Exemple importé :', data[0]); +// console.log(`➡️ ${data.length} lignes trouvées dans le CSV`); +// console.log('Exemple importé :', data[0]); - const result = await prisma.users.createMany({ - data, - }); +// const result = await prisma.users.createMany({ +// data, +// }); - console.log(`✅ ${result.count} utilisateurs insérés dans la DB`); -} +// console.log(`✅ ${result.count} utilisateurs insérés dans la DB`); +// } -main() - .catch((err) => { - console.error('❌ Erreur pendant l’import CSV → DB', err); - process.exit(1); - }) - .finally(async () => { - await prisma.$disconnect(); - }); +// main() +// .catch((err) => { +// console.error('❌ Erreur pendant l’import CSV → DB', err); +// process.exit(1); +// }) +// .finally(async () => { +// await prisma.$disconnect(); +// }); diff --git a/scripts/done/init-preferences.ts b/scripts/done/init-preferences.ts index f520857..d2c5421 100644 --- a/scripts/done/init-preferences.ts +++ b/scripts/done/init-preferences.ts @@ -1,67 +1,67 @@ -// src/scripts/init-preferences.ts -import { PrismaClient } from '@prisma/client'; +// // src/scripts/init-preferences.ts +// import { PrismaClient } from '@prisma/client'; -const prisma = new PrismaClient(); +// const prisma = new PrismaClient(); -type UserSummary = { - id: string; // UUID - email: string; -}; +// type UserSummary = { +// id: string; // UUID +// email: string; +// }; -async function main() { - console.log('➡️ Initialisation des préférences utilisateurs…'); +// async function main() { +// console.log('➡️ Initialisation des préférences utilisateurs…'); - // 1. Récupérer tous les users - const users = (await prisma.users.findMany({ - select: { - id: true, - email: true, - }, - })) as UserSummary[]; +// // 1. Récupérer tous les users +// const users = (await prisma.users.findMany({ +// select: { +// id: true, +// email: true, +// }, +// })) as UserSummary[]; - console.log(`➡️ ${users.length} users trouvés dans la DB`); +// console.log(`➡️ ${users.length} users trouvés dans la DB`); - // 2. Récupérer toutes les préférences existantes - const existingPrefs = await prisma.preferences.findMany({ - select: { - user_id: true, - }, - }); +// // 2. Récupérer toutes les préférences existantes +// const existingPrefs = await prisma.preferences.findMany({ +// select: { +// user_id: true, +// }, +// }); - const userIdsWithPrefs = new Set(existingPrefs.map((p) => p.user_id)); +// const userIdsWithPrefs = new Set(existingPrefs.map((p) => p.user_id)); - console.log(`➡️ ${existingPrefs.length} users ont déjà des préférences`); +// console.log(`➡️ ${existingPrefs.length} users ont déjà des préférences`); - // 3. Filtrer les users qui n'ont pas encore de preferences - const usersWithoutPrefs = users.filter((u) => !userIdsWithPrefs.has(u.id)); +// // 3. Filtrer les users qui n'ont pas encore de preferences +// const usersWithoutPrefs = users.filter((u) => !userIdsWithPrefs.has(u.id)); - console.log(`➡️ ${usersWithoutPrefs.length} users n'ont pas encore de préférences`); +// console.log(`➡️ ${usersWithoutPrefs.length} users n'ont pas encore de préférences`); - if (usersWithoutPrefs.length === 0) { - console.log('✅ Rien à faire, toutes les préférences sont déjà créées.'); - return; - } +// if (usersWithoutPrefs.length === 0) { +// console.log('✅ Rien à faire, toutes les préférences sont déjà créées.'); +// return; +// } - // 4. Préparer les entrées pour createMany - const prefsToCreate = usersWithoutPrefs.map((u) => ({ - user_id: u.id, - // tous les autres champs prendront leurs valeurs par défaut (0) - })); +// // 4. Préparer les entrées pour createMany +// const prefsToCreate = usersWithoutPrefs.map((u) => ({ +// user_id: u.id, +// // tous les autres champs prendront leurs valeurs par défaut (0) +// })); - // 5. Insertion en batch - const result = await prisma.preferences.createMany({ - data: prefsToCreate, - skipDuplicates: true, // sécurité si jamais le script est relancé - }); +// // 5. Insertion en batch +// const result = await prisma.preferences.createMany({ +// data: prefsToCreate, +// skipDuplicates: true, // sécurité si jamais le script est relancé +// }); - console.log(`✅ ${result.count} préférences créées dans la DB`); -} +// console.log(`✅ ${result.count} préférences créées dans la DB`); +// } -main() - .catch((err) => { - console.error('❌ Erreur pendant l’initialisation des préférences', err); - process.exit(1); - }) - .finally(async () => { - await prisma.$disconnect(); - }); +// main() +// .catch((err) => { +// console.error('❌ Erreur pendant l’initialisation des préférences', err); +// process.exit(1); +// }) +// .finally(async () => { +// await prisma.$disconnect(); +// }); diff --git a/scripts/migrate-expenses.ts b/scripts/migrate-expenses.ts index 215f2bb..364a49d 100644 --- a/scripts/migrate-expenses.ts +++ b/scripts/migrate-expenses.ts @@ -1,165 +1,165 @@ -import { PrismaClient as Prisma } from "@prisma/client"; -import { PrismaClient as PrismaLegacy } from "@prisma/client-legacy" -import { toDateFromString, toHHmmFromDate, toStringFromDate } from "src/common/utils/date-utils"; +// import { PrismaClient as Prisma } from "@prisma/client"; +// import { PrismaClient as PrismaLegacy } from "@prisma/client-legacy" +// import { toDateFromString, toHHmmFromDate, toStringFromDate } from "src/common/utils/date-utils"; -const prisma_legacy = new PrismaLegacy({}); -const prisma = new Prisma({}); +// const prisma_legacy = new PrismaLegacy({}); +// const prisma = new Prisma({}); -type NewEmployee = { - id: number; - company_code: number; - external_payroll_id: number; -} +// type NewEmployee = { +// id: number; +// company_code: number; +// external_payroll_id: number; +// } -type OldExpense = { - time_sheet_id: string | null; - date: string | null; - code: string | null; - description: string | null; - value: number | null; - status: boolean | null; -} +// type OldExpense = { +// time_sheet_id: string | null; +// date: string | null; +// code: string | null; +// description: string | null; +// value: number | null; +// status: boolean | null; +// } -export const extractOldExpenses = async () => { - for (let id = 1; id <= 61; id++) { +// export const extractOldExpenses = async () => { +// for (let id = 1; id <= 61; id++) { - console.log(`Start of Expense migration ***************************************************************`); +// console.log(`Start of Expense migration ***************************************************************`); - const new_employee = await findOneNewEmployee(id); - console.log(`Employee ${id} found in new DB`); +// const new_employee = await findOneNewEmployee(id); +// console.log(`Employee ${id} found in new DB`); - const new_timesheets = await findManyNewTimesheets(new_employee.id); - console.log(`New Timesheets found for employee ${id}`); +// const new_timesheets = await findManyNewTimesheets(new_employee.id); +// console.log(`New Timesheets found for employee ${id}`); - const old_employee_id = await findOneOldEmployee(new_employee); - console.log(`Employee ${new_employee.id} found in old DB`); +// const old_employee_id = await findOneOldEmployee(new_employee); +// console.log(`Employee ${new_employee.id} found in old DB`); - const old_timesheets = await findManyOldTimesheets(old_employee_id); - console.log(`Timesheets for employee ${old_employee_id}/${new_employee.id} found in old DB`); +// const old_timesheets = await findManyOldTimesheets(old_employee_id); +// console.log(`Timesheets for employee ${old_employee_id}/${new_employee.id} found in old DB`); - console.log('Start of Expense creation*****************************************************************'); - for (const old_timesheet of old_timesheets) { - if (!old_timesheet.start_date) continue; - const new_timesheet = new_timesheets.find((ts) => ts.start_date.getTime() === old_timesheet.start_date!.getTime()); - if (!new_timesheet) { - console.warn(`No new timesheet matching legacy timesheet ${old_timesheet.id}`); - continue; - } - const old_expenses = await prisma_legacy.expenses.findMany({ - where: { time_sheet_id: old_timesheet.id }, - select: { - time_sheet_id: true, - date: true, - code: true, - description: true, - value: true, - status: true, +// console.log('Start of Expense creation*****************************************************************'); +// for (const old_timesheet of old_timesheets) { +// if (!old_timesheet.start_date) continue; +// const new_timesheet = new_timesheets.find((ts) => ts.start_date.getTime() === old_timesheet.start_date!.getTime()); +// if (!new_timesheet) { +// console.warn(`No new timesheet matching legacy timesheet ${old_timesheet.id}`); +// continue; +// } +// const old_expenses = await prisma_legacy.expenses.findMany({ +// where: { time_sheet_id: old_timesheet.id }, +// select: { +// time_sheet_id: true, +// date: true, +// code: true, +// description: true, +// value: true, +// status: true, - }, - }); - await createManyNewExpenses(new_timesheet.id, old_expenses); - } +// }, +// }); +// await createManyNewExpenses(new_timesheet.id, old_expenses); +// } - } - await prisma_legacy.$disconnect(); - await prisma.$disconnect(); -} +// } +// await prisma_legacy.$disconnect(); +// await prisma.$disconnect(); +// } -const findOneNewEmployee = async (id: number): Promise => { - const new_employee = await prisma.employees.findUnique({ - where: { id: id }, - select: { - id: true, - company_code: true, - external_payroll_id: true, - }, - }); - if (!new_employee) throw new Error(`New Employee with id ${id} not found`) - return new_employee; -} +// const findOneNewEmployee = async (id: number): Promise => { +// const new_employee = await prisma.employees.findUnique({ +// where: { id: id }, +// select: { +// id: true, +// company_code: true, +// external_payroll_id: true, +// }, +// }); +// if (!new_employee) throw new Error(`New Employee with id ${id} not found`) +// return new_employee; +// } -const findOneOldEmployee = async (new_employee: NewEmployee): Promise => { - const old_employee = await prisma_legacy.employees.findFirst({ - where: { - company: new_employee.company_code, - employee_number: new_employee.external_payroll_id.toString(), - }, - select: { - id: true, - }, - }); - if (!old_employee) throw new Error(`Old Employee not found`); - return old_employee.id; -} +// const findOneOldEmployee = async (new_employee: NewEmployee): Promise => { +// const old_employee = await prisma_legacy.employees.findFirst({ +// where: { +// company: new_employee.company_code, +// employee_number: new_employee.external_payroll_id.toString(), +// }, +// select: { +// id: true, +// }, +// }); +// if (!old_employee) throw new Error(`Old Employee not found`); +// return old_employee.id; +// } -const findManyOldTimesheets = async (old_employee_id: string) => { - const old_timesheets = await prisma_legacy.time_sheets.findMany({ - where: { employee_id: old_employee_id }, - select: { id: true, start_date: true, status: true } - }); - return old_timesheets; -} +// const findManyOldTimesheets = async (old_employee_id: string) => { +// const old_timesheets = await prisma_legacy.time_sheets.findMany({ +// where: { employee_id: old_employee_id }, +// select: { id: true, start_date: true, status: true } +// }); +// return old_timesheets; +// } -const findManyNewTimesheets = async (employee_id: number) => { - const timesheets = await prisma.timesheets.findMany({ - where: { employee_id: employee_id }, - select: { id: true, start_date: true } - }) - return timesheets; -} +// const findManyNewTimesheets = async (employee_id: number) => { +// const timesheets = await prisma.timesheets.findMany({ +// where: { employee_id: employee_id }, +// select: { id: true, start_date: true } +// }) +// return timesheets; +// } -const createManyNewExpenses = async (timesheet_id: number, old_expenses: OldExpense[]) => { - for (const old_expense of old_expenses) { - let mileage: number = 0; - let amount: number = old_expense.value ?? 0; - if (old_expense.code === 'G503') { - mileage = old_expense.value!; - amount = mileage * 0.72; - } - if (mileage < 0 || amount < 0) { - console.warn(`expense of value less than '0' found`) - continue; - } +// const createManyNewExpenses = async (timesheet_id: number, old_expenses: OldExpense[]) => { +// for (const old_expense of old_expenses) { +// let mileage: number = 0; +// let amount: number = old_expense.value ?? 0; +// if (old_expense.code === 'G503') { +// mileage = old_expense.value!; +// amount = mileage * 0.72; +// } +// if (mileage < 0 || amount < 0) { +// console.warn(`expense of value less than '0' found`) +// continue; +// } - if (old_expense.date == null) { - console.warn(`Expense date invalid ${old_expense.date}`); - continue; - } - const date = toDateFromString(old_expense.date); +// if (old_expense.date == null) { +// console.warn(`Expense date invalid ${old_expense.date}`); +// continue; +// } +// const date = toDateFromString(old_expense.date); - if (old_expense.status == null) { - console.warn(`status null for legacy expense ${old_expense}`); - continue; - } +// if (old_expense.status == null) { +// console.warn(`status null for legacy expense ${old_expense}`); +// continue; +// } - if (old_expense.code == null) { - console.warn(`Code null for legacy expense ${old_expense.code}`); - continue; - } - const bank_code_id = await findBankCodeIdUsingOldCode(old_expense.code); +// if (old_expense.code == null) { +// console.warn(`Code null for legacy expense ${old_expense.code}`); +// continue; +// } +// const bank_code_id = await findBankCodeIdUsingOldCode(old_expense.code); - await prisma.expenses.create({ - // where: { unique_ts_id_date_amount_mileage: { timesheet_id: timesheet_id, date, amount, mileage } }, - // update: { - // is_approved: old_expense.status, - // }, - data: { - date: date, - comment: old_expense.description ?? '', - timesheet_id: timesheet_id, - bank_code_id: bank_code_id, - amount: amount, - mileage: mileage, - } - }); - } -} +// await prisma.expenses.create({ +// // where: { unique_ts_id_date_amount_mileage: { timesheet_id: timesheet_id, date, amount, mileage } }, +// // update: { +// // is_approved: old_expense.status, +// // }, +// data: { +// date: date, +// comment: old_expense.description ?? '', +// timesheet_id: timesheet_id, +// bank_code_id: bank_code_id, +// amount: amount, +// mileage: mileage, +// } +// }); +// } +// } -const findBankCodeIdUsingOldCode = async (code: string): Promise => { - const bank_code = await prisma.bankCodes.findFirst({ - where: { bank_code: code }, - select: { id: true }, - }); - if (!bank_code) throw new Error(`Bank_code_id not found for Code ${code}`) - return bank_code.id; -} \ No newline at end of file +// const findBankCodeIdUsingOldCode = async (code: string): Promise => { +// const bank_code = await prisma.bankCodes.findFirst({ +// where: { bank_code: code }, +// select: { id: true }, +// }); +// if (!bank_code) throw new Error(`Bank_code_id not found for Code ${code}`) +// return bank_code.id; +// } \ No newline at end of file diff --git a/scripts/migrate-shifts.ts b/scripts/migrate-shifts.ts index a3dfce5..c9fc36d 100644 --- a/scripts/migrate-shifts.ts +++ b/scripts/migrate-shifts.ts @@ -1,210 +1,210 @@ -import { PrismaClient as PrismaNew } from "@prisma/client"; -import { PrismaClient as PrismaLegacy } from "@prisma/client-legacy" +// import { PrismaClient as PrismaNew } from "@prisma/client"; +// import { PrismaClient as PrismaLegacy } from "@prisma/client-legacy" -const prisma_legacy = new PrismaLegacy({}); -const prisma = new PrismaNew({}); +// const prisma_legacy = new PrismaLegacy({}); +// const prisma = new PrismaNew({}); -type NewEmployee = { - id: number; - company_code: number; - external_payroll_id: number; -} +// type NewEmployee = { +// id: number; +// company_code: number; +// external_payroll_id: number; +// } -type OldShifts = { - time_sheet_id: string | null; - code: string | null; - type: string | null; - date: Date | null; - start_time: bigint | null; - end_time: bigint | null; - comment: string | null; - status: boolean | null; -} +// type OldShifts = { +// time_sheet_id: string | null; +// code: string | null; +// type: string | null; +// date: Date | null; +// start_time: bigint | null; +// end_time: bigint | null; +// comment: string | null; +// status: boolean | null; +// } -export const extractOldShifts = async () => { - // for (let id = 1; id <= 61; id++) { - console.log(`Start of shift migration ***************************************************************`); - const new_employee = await findOneNewEmployee(50); - console.log(`Employee ${50} found in new DB`); +// export const extractOldShifts = async () => { +// // for (let id = 1; id <= 61; id++) { +// console.log(`Start of shift migration ***************************************************************`); +// const new_employee = await findOneNewEmployee(50); +// console.log(`Employee ${50} found in new DB`); - const new_timesheets = await findManyNewTimesheets(new_employee.id); - console.log(`New Timesheets found for employee ${50}`); - for (const ts of new_timesheets) { - console.log(`start_date = ${ts.start_date} timesheet_id = ${ts.id}`) +// const new_timesheets = await findManyNewTimesheets(new_employee.id); +// console.log(`New Timesheets found for employee ${50}`); +// for (const ts of new_timesheets) { +// console.log(`start_date = ${ts.start_date} timesheet_id = ${ts.id}`) - } - console.log('***************************************************************'); - const old_employee_id = await findOneOldEmployee(new_employee); - console.log(`Employee ${new_employee.id} found in old DB`); +// } +// console.log('***************************************************************'); +// const old_employee_id = await findOneOldEmployee(new_employee); +// console.log(`Employee ${new_employee.id} found in old DB`); - const old_timesheets = await findManyOldTimesheets(old_employee_id); - console.log(`Timesheets for employee ${old_employee_id}/${new_employee.id} found in old DB`); +// const old_timesheets = await findManyOldTimesheets(old_employee_id); +// console.log(`Timesheets for employee ${old_employee_id}/${new_employee.id} found in old DB`); - for (const old_timesheet of old_timesheets) { - if (!old_timesheet.start_date) continue; - const new_timesheet = new_timesheets.find((ts) => ts.start_date.getTime() === old_timesheet.start_date!.getTime()); - if (!new_timesheet) { - console.warn(`No new timesheet ${new_timesheet} matching legacy timesheet ${old_timesheet.id}`); - continue; - } - const old_shifts = await prisma_legacy.shifts.findMany({ - where: { time_sheet_id: old_timesheet.id }, - select: { - time_sheet_id: true, - code: true, - type: true, - date: true, - start_time: true, - end_time: true, - comment: true, - status: true, - }, - }); - await createManyNewShifts(new_timesheet.id, old_shifts); - } - // } - await prisma_legacy.$disconnect(); - await prisma.$disconnect(); -} +// for (const old_timesheet of old_timesheets) { +// if (!old_timesheet.start_date) continue; +// const new_timesheet = new_timesheets.find((ts) => ts.start_date.getTime() === old_timesheet.start_date!.getTime()); +// if (!new_timesheet) { +// console.warn(`No new timesheet ${new_timesheet} matching legacy timesheet ${old_timesheet.id}`); +// continue; +// } +// const old_shifts = await prisma_legacy.shifts.findMany({ +// where: { time_sheet_id: old_timesheet.id }, +// select: { +// time_sheet_id: true, +// code: true, +// type: true, +// date: true, +// start_time: true, +// end_time: true, +// comment: true, +// status: true, +// }, +// }); +// await createManyNewShifts(new_timesheet.id, old_shifts); +// } +// // } +// await prisma_legacy.$disconnect(); +// await prisma.$disconnect(); +// } -const findOneNewEmployee = async (id: number): Promise => { - const new_employee = await prisma.employees.findUnique({ - where: { id: id }, - select: { - id: true, - company_code: true, - external_payroll_id: true, - }, - }); - if (!new_employee) throw new Error(`New Employee with id ${id} not found`) - return new_employee; -} +// const findOneNewEmployee = async (id: number): Promise => { +// const new_employee = await prisma.employees.findUnique({ +// where: { id: id }, +// select: { +// id: true, +// company_code: true, +// external_payroll_id: true, +// }, +// }); +// if (!new_employee) throw new Error(`New Employee with id ${id} not found`) +// return new_employee; +// } -const findOneOldEmployee = async (new_employee: NewEmployee): Promise => { - const old_employee = await prisma_legacy.employees.findFirst({ - where: { - company: new_employee.company_code, - employee_number: new_employee.external_payroll_id.toString(), - }, - select: { - id: true, - }, - }); - if (!old_employee) throw new Error(`Old Employee not found`); - return old_employee.id; -} +// const findOneOldEmployee = async (new_employee: NewEmployee): Promise => { +// const old_employee = await prisma_legacy.employees.findFirst({ +// where: { +// company: new_employee.company_code, +// employee_number: new_employee.external_payroll_id.toString(), +// }, +// select: { +// id: true, +// }, +// }); +// if (!old_employee) throw new Error(`Old Employee not found`); +// return old_employee.id; +// } -const findManyOldTimesheets = async (old_employee_id: string) => { - const old_timesheets = await prisma_legacy.time_sheets.findMany({ - where: { employee_id: old_employee_id }, - select: { id: true, start_date: true, status: true } - }); - return old_timesheets; -} +// const findManyOldTimesheets = async (old_employee_id: string) => { +// const old_timesheets = await prisma_legacy.time_sheets.findMany({ +// where: { employee_id: old_employee_id }, +// select: { id: true, start_date: true, status: true } +// }); +// return old_timesheets; +// } -const findManyNewTimesheets = async (employee_id: number) => { - const timesheets = await prisma.timesheets.findMany({ - where: { employee_id: employee_id }, - select: { id: true, start_date: true } - }) - return timesheets; -} +// const findManyNewTimesheets = async (employee_id: number) => { +// const timesheets = await prisma.timesheets.findMany({ +// where: { employee_id: employee_id }, +// select: { id: true, start_date: true } +// }) +// return timesheets; +// } -const createManyNewShifts = async (timesheet_id: number, old_shifts: OldShifts[]) => { - for (const old_shift of old_shifts) { - let is_remote = true; +// const createManyNewShifts = async (timesheet_id: number, old_shifts: OldShifts[]) => { +// for (const old_shift of old_shifts) { +// let is_remote = true; - const start = toHHmmfromLegacyTimestamp(old_shift.start_time); - if (old_shift.start_time == null || !start) { - console.warn(`Shift start invalid ${old_shift.start_time}`); - continue; - } +// const start = toHHmmfromLegacyTimestamp(old_shift.start_time); +// if (old_shift.start_time == null || !start) { +// console.warn(`Shift start invalid ${old_shift.start_time}`); +// continue; +// } - const end = toHHmmfromLegacyTimestamp(old_shift.end_time); - if (old_shift.end_time == null || !end) { - console.warn(`Shift end invalid ${old_shift.end_time}`); - continue; - } +// const end = toHHmmfromLegacyTimestamp(old_shift.end_time); +// if (old_shift.end_time == null || !end) { +// console.warn(`Shift end invalid ${old_shift.end_time}`); +// continue; +// } - if (old_shift.date == null) { - console.warn(`Shift date invalid ${old_shift.date}`); - continue; - } +// if (old_shift.date == null) { +// console.warn(`Shift date invalid ${old_shift.date}`); +// continue; +// } - if (old_shift.status == null) { - console.warn(`status null for legacy shift ${old_shift}`); - continue; - } - if (old_shift.type == null) { - console.warn(`type null for legacy shift ${old_shift.type}`); - continue; - } +// if (old_shift.status == null) { +// console.warn(`status null for legacy shift ${old_shift}`); +// continue; +// } +// if (old_shift.type == null) { +// console.warn(`type null for legacy shift ${old_shift.type}`); +// continue; +// } - if (old_shift.type === 'office') { - is_remote = false; - } +// if (old_shift.type === 'office') { +// is_remote = false; +// } - if (old_shift.code == null) { - console.warn(`Code null for legacy shift ${old_shift.code}`); - continue; - } - const bank_code_id = await findBankCodeIdUsingOldCode(old_shift.code); - try { - await prisma.shifts.create({ - // where: { unique_ts_id_date_start_time: { - // timesheet_id, - // date: old_shift.date, - // start_time: toDateFromHHmm(start) }}, - // update: { - // start_time: toDateFromHHmm(start), - // end_time: toDateFromHHmm(end), - // comment: old_shift.comment, - // is_approved: old_shift.status, - // is_remote: is_remote, - // bank_code_id: bank_code_id, - // }, - data: { - date: old_shift.date, - start_time: toDateFromHHmm(start), - end_time: toDateFromHHmm(end), - comment: old_shift.comment, - is_approved: old_shift.status, - is_remote: is_remote, - timesheet_id: timesheet_id, - bank_code_id: bank_code_id, - }, - }); - } catch (error) { - console.log('An error occured during shifts creation'); - } - } -} +// if (old_shift.code == null) { +// console.warn(`Code null for legacy shift ${old_shift.code}`); +// continue; +// } +// const bank_code_id = await findBankCodeIdUsingOldCode(old_shift.code); +// try { +// await prisma.shifts.create({ +// // where: { unique_ts_id_date_start_time: { +// // timesheet_id, +// // date: old_shift.date, +// // start_time: toDateFromHHmm(start) }}, +// // update: { +// // start_time: toDateFromHHmm(start), +// // end_time: toDateFromHHmm(end), +// // comment: old_shift.comment, +// // is_approved: old_shift.status, +// // is_remote: is_remote, +// // bank_code_id: bank_code_id, +// // }, +// data: { +// date: old_shift.date, +// start_time: toDateFromHHmm(start), +// end_time: toDateFromHHmm(end), +// comment: old_shift.comment, +// is_approved: old_shift.status, +// is_remote: is_remote, +// timesheet_id: timesheet_id, +// bank_code_id: bank_code_id, +// }, +// }); +// } catch (error) { +// console.log('An error occured during shifts creation'); +// } +// } +// } -const toHHmmfromLegacyTimestamp = (value: bigint | null): string | null => { - if (value == null) return null; - const date = new Date(Number(value)); - const hh = String(date.getHours()).padStart(2, '0'); - const mm = String(date.getMinutes()).padStart(2, '0'); - return `${hh}:${mm}`; -} +// const toHHmmfromLegacyTimestamp = (value: bigint | null): string | null => { +// if (value == null) return null; +// const date = new Date(Number(value)); +// const hh = String(date.getHours()).padStart(2, '0'); +// const mm = String(date.getMinutes()).padStart(2, '0'); +// return `${hh}:${mm}`; +// } -const toDateFromHHmm = (hhmm: string): Date => { - const [hh, mm] = hhmm.split(':'); - const hours = Number(hh); - const minutes = Number(mm); - return new Date(Date.UTC(1970, 0, 1, hours, minutes, 0, 0)); -} +// const toDateFromHHmm = (hhmm: string): Date => { +// const [hh, mm] = hhmm.split(':'); +// const hours = Number(hh); +// const minutes = Number(mm); +// return new Date(Date.UTC(1970, 0, 1, hours, minutes, 0, 0)); +// } -const findBankCodeIdUsingOldCode = async (code: string): Promise => { - if (code === 'G700') { - code = 'G104'; - } else if (code === 'G140') { - code = 'G56' - } - const bank_code = await prisma.bankCodes.findFirst({ - where: { bank_code: code }, - select: { id: true, bank_code: true }, - }); - if (!bank_code) throw new Error(`Bank_code_id not found for Code ${code}`) - return bank_code.id; -} +// const findBankCodeIdUsingOldCode = async (code: string): Promise => { +// if (code === 'G700') { +// code = 'G104'; +// } else if (code === 'G140') { +// code = 'G56' +// } +// const bank_code = await prisma.bankCodes.findFirst({ +// where: { bank_code: code }, +// select: { id: true, bank_code: true }, +// }); +// if (!bank_code) throw new Error(`Bank_code_id not found for Code ${code}`) +// return bank_code.id; +// } diff --git a/scripts/migrate-timesheets.ts b/scripts/migrate-timesheets.ts index da25839..dd65564 100644 --- a/scripts/migrate-timesheets.ts +++ b/scripts/migrate-timesheets.ts @@ -1,118 +1,118 @@ -import { PrismaClient as Prisma } from "@prisma/client"; -import { PrismaClient as PrismaLegacy } from "@prisma/client-legacy" -import { toStringFromDate } from "src/common/utils/date-utils"; +// import { PrismaClient as Prisma } from "@prisma/client"; +// import { PrismaClient as PrismaLegacy } from "@prisma/client-legacy" +// import { toStringFromDate } from "src/common/utils/date-utils"; -type NewEmployee = { - id: number; - company_code: number; - external_payroll_id: number; -} +// type NewEmployee = { +// id: number; +// company_code: number; +// external_payroll_id: number; +// } -type OldTimesheets = { - id: string; - start_date: Date | null; - status: boolean | null; -} +// type OldTimesheets = { +// id: string; +// start_date: Date | null; +// status: boolean | null; +// } -const prisma_legacy = new PrismaLegacy({}); -const prisma_new = new Prisma({}); +// const prisma_legacy = new PrismaLegacy({}); +// const prisma_new = new Prisma({}); -export const extractOldTimesheets = async () => { - for (let id = 1; id <= 61; id++) { - const new_employee = await findOneNewEmployee(id); - console.log(`Employee ${id} found in new DB ${new_employee.external_payroll_id}`); +// export const extractOldTimesheets = async () => { +// for (let id = 1; id <= 61; id++) { +// const new_employee = await findOneNewEmployee(id); +// console.log(`Employee ${id} found in new DB ${new_employee.external_payroll_id}`); - const old_employee_id = await findOneOldEmployee(new_employee); - console.log(`Employee ${new_employee.id} found in old DB`); +// const old_employee_id = await findOneOldEmployee(new_employee); +// console.log(`Employee ${new_employee.id} found in old DB`); - const old_timesheets = await findManyOldTimesheets(old_employee_id); - console.log(` ${old_timesheets.length} Timesheets for employee ${old_employee_id}/${new_employee.id} found in old DB`); +// const old_timesheets = await findManyOldTimesheets(old_employee_id); +// console.log(` ${old_timesheets.length} Timesheets for employee ${old_employee_id}/${new_employee.id} found in old DB`); - await createManyNewTimesheets(old_timesheets, new_employee); - console.log(`${old_timesheets.length} New Timesheets created in new DB for employee ${new_employee.id}`); - } - await prisma_legacy.$disconnect(); - await prisma_new.$disconnect(); -} +// await createManyNewTimesheets(old_timesheets, new_employee); +// console.log(`${old_timesheets.length} New Timesheets created in new DB for employee ${new_employee.id}`); +// } +// await prisma_legacy.$disconnect(); +// await prisma_new.$disconnect(); +// } -const findOneNewEmployee = async (id: number): Promise => { - const new_employee = await prisma_new.employees.findUnique({ - where: { id: id }, - select: { - id: true, - company_code: true, - external_payroll_id: true, - }, - }); - if (!new_employee) throw new Error(`New Employee with id ${id} not found`) - return new_employee; -} +// const findOneNewEmployee = async (id: number): Promise => { +// const new_employee = await prisma_new.employees.findUnique({ +// where: { id: id }, +// select: { +// id: true, +// company_code: true, +// external_payroll_id: true, +// }, +// }); +// if (!new_employee) throw new Error(`New Employee with id ${id} not found`) +// return new_employee; +// } -const findOneOldEmployee = async (new_employee: NewEmployee): Promise => { - const employee_number = new_employee.external_payroll_id.toString() - const old_employee = await prisma_legacy.employees.findFirst({ - where: { - company: new_employee.company_code, - employee_number: employee_number, - }, - select: { - id: true, - }, - }); - if (!old_employee) throw new Error(`Old Employee not found`); - return old_employee.id; -} +// const findOneOldEmployee = async (new_employee: NewEmployee): Promise => { +// const employee_number = new_employee.external_payroll_id.toString() +// const old_employee = await prisma_legacy.employees.findFirst({ +// where: { +// company: new_employee.company_code, +// employee_number: employee_number, +// }, +// select: { +// id: true, +// }, +// }); +// if (!old_employee) throw new Error(`Old Employee not found`); +// return old_employee.id; +// } -const findManyOldTimesheets = async (old_employee_id: string) => { - const old_timesheets = await prisma_legacy.time_sheets.findMany({ - where: { employee_id: old_employee_id }, - select: { id: true, start_date: true, status: true } - }); - if (!old_timesheets) throw new Error(`old Timesheets not found for employee_id ${old_employee_id}`) - return old_timesheets; -} +// const findManyOldTimesheets = async (old_employee_id: string) => { +// const old_timesheets = await prisma_legacy.time_sheets.findMany({ +// where: { employee_id: old_employee_id }, +// select: { id: true, start_date: true, status: true } +// }); +// if (!old_timesheets) throw new Error(`old Timesheets not found for employee_id ${old_employee_id}`) +// return old_timesheets; +// } -const createManyNewTimesheets = async (old_timesheets: OldTimesheets[], new_employee: NewEmployee) => { - for (const timesheet of old_timesheets) { - if (timesheet.start_date == null) { - console.warn(`start_date invalid for legacy timesheet ${timesheet.id}`); - continue; - } - if (timesheet.status == null) { - console.warn(`status null for legacy timesheet ${timesheet.id}`); - continue; - } +// const createManyNewTimesheets = async (old_timesheets: OldTimesheets[], new_employee: NewEmployee) => { +// for (const timesheet of old_timesheets) { +// if (timesheet.start_date == null) { +// console.warn(`start_date invalid for legacy timesheet ${timesheet.id}`); +// continue; +// } +// if (timesheet.status == null) { +// console.warn(`status null for legacy timesheet ${timesheet.id}`); +// continue; +// } - try { - const new_timesheet = await prisma_new.timesheets.upsert({ - where: { employee_id_start_date: { employee_id: new_employee.id, start_date: timesheet.start_date } }, - update: { - is_approved: timesheet.status, - }, - create: { - employee_id: new_employee.id, - start_date: timesheet.start_date, - is_approved: timesheet.status, - }, - }); - if (!new_timesheet) throw new Error( - `Timesheet with start_date: ${toStringFromDate(timesheet.start_date!)} for employee ${new_employee.id} not created` - ); - } catch (error) { - throw new Error('An error occured during timesheets creation'); - } - } -} +// try { +// const new_timesheet = await prisma_new.timesheets.upsert({ +// where: { employee_id_start_date: { employee_id: new_employee.id, start_date: timesheet.start_date } }, +// update: { +// is_approved: timesheet.status, +// }, +// create: { +// employee_id: new_employee.id, +// start_date: timesheet.start_date, +// is_approved: timesheet.status, +// }, +// }); +// if (!new_timesheet) throw new Error( +// `Timesheet with start_date: ${toStringFromDate(timesheet.start_date!)} for employee ${new_employee.id} not created` +// ); +// } catch (error) { +// throw new Error('An error occured during timesheets creation'); +// } +// } +// } -extractOldTimesheets() - .then(() => { - console.log("Migration completed"); - }) - .catch((error) => { - console.error("Migration failed:", error); - }) - .finally(async () => { - await prisma_legacy.$disconnect(); - await prisma_new.$disconnect(); - }); \ No newline at end of file +// extractOldTimesheets() +// .then(() => { +// console.log("Migration completed"); +// }) +// .catch((error) => { +// console.error("Migration failed:", error); +// }) +// .finally(async () => { +// await prisma_legacy.$disconnect(); +// await prisma_new.$disconnect(); +// }); \ No newline at end of file diff --git a/scripts/migration.service.ts b/scripts/migration.service.ts index 2bb37d6..3a9b3ba 100644 --- a/scripts/migration.service.ts +++ b/scripts/migration.service.ts @@ -1,21 +1,21 @@ -// import { extractOldTimesheets } from "scripts/migrate-timesheets"; -// import { extractOldExpenses } from "scripts/migrate-expenses"; -// import { extractOldShifts } from "scripts/migrate-shifts"; -import { Injectable } from "@nestjs/common"; +// // import { extractOldTimesheets } from "scripts/migrate-timesheets"; +// // import { extractOldExpenses } from "scripts/migrate-expenses"; +// // import { extractOldShifts } from "scripts/migrate-shifts"; +// import { Injectable } from "@nestjs/common"; -@Injectable() -export class MigrationService { - constructor() {} +// @Injectable() +// export class MigrationService { +// constructor() {} - async migrateTimesheets() { - // extractOldTimesheets(); - }; +// async migrateTimesheets() { +// // extractOldTimesheets(); +// }; - async migrateShifts() { - // extractOldShifts(); - } +// async migrateShifts() { +// // extractOldShifts(); +// } - async migrateExpenses() { - // extractOldExpenses(); - } -} \ No newline at end of file +// async migrateExpenses() { +// // extractOldExpenses(); +// } +// } \ No newline at end of file diff --git a/src/identity-and-account/preferences/dtos/preferences.dto.ts b/src/identity-and-account/preferences/dtos/preferences.dto.ts index 4eb8b79..1c7530f 100644 --- a/src/identity-and-account/preferences/dtos/preferences.dto.ts +++ b/src/identity-and-account/preferences/dtos/preferences.dto.ts @@ -1,10 +1,15 @@ -import { IsInt } from "class-validator"; +import { IsBoolean, IsEnum, IsInt, IsOptional } from "class-validator"; + +export enum DisplayLanguage { + FR = 'fr-FR', + EN = 'en-CA', +} export class PreferencesDto { - notifications: number; - is_dark_mode: boolean | null; - display_language: string | 'fr-FR' | 'en-CA'; - is_lefty_mode: boolean; - is_employee_list_grid: boolean; - is_timesheet_approval_grid: boolean; + @IsInt() notifications: number; + @IsOptional() @IsBoolean() is_dark_mode?: boolean; + @IsEnum(DisplayLanguage) display_language: string; + @IsBoolean() is_lefty_mode: boolean; + @IsBoolean() is_employee_list_grid: boolean; + @IsBoolean() is_timesheet_approval_grid: boolean; } \ No newline at end of file diff --git a/src/identity-and-account/preferences/services/preferences.service.ts b/src/identity-and-account/preferences/services/preferences.service.ts index 674a706..a2643c7 100644 --- a/src/identity-and-account/preferences/services/preferences.service.ts +++ b/src/identity-and-account/preferences/services/preferences.service.ts @@ -1,4 +1,4 @@ -import { PreferencesDto } from "../dtos/preferences.dto"; +import { DisplayLanguage, PreferencesDto } from "../dtos/preferences.dto"; import { PrismaService } from "src/prisma/prisma.service"; import { Preferences } from "@prisma/client"; import { Injectable } from "@nestjs/common"; @@ -32,7 +32,7 @@ export class PreferencesService { const preferences: PreferencesDto = { is_dark_mode: user_preferences.is_dark_mode, - display_language: user_preferences.display_language, + display_language: user_preferences.display_language ?? DisplayLanguage.FR , is_lefty_mode: user_preferences.is_lefty_mode, notifications: user_preferences.notifications, is_employee_list_grid: user_preferences.is_employee_list_grid, diff --git a/src/main.ts b/src/main.ts index 7228b76..0be6b3c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -18,9 +18,9 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; import { writeFileSync } from 'fs'; import * as session from 'express-session'; import * as passport from 'passport'; -import { extractOldShifts } from 'scripts/migrate-shifts'; -import { extractOldTimesheets } from 'scripts/migrate-timesheets'; -import { extractOldExpenses } from 'scripts/migrate-expenses'; +// import { extractOldShifts } from 'scripts/migrate-shifts'; +// import { extractOldTimesheets } from 'scripts/migrate-timesheets'; +// import { extractOldExpenses } from 'scripts/migrate-expenses'; const SESSION_TOKEN_DURATION_MINUTES = 180