fix(seeds): fix timesheet seeds
This commit is contained in:
parent
18c1ce38be
commit
c52de6ecb8
|
|
@ -425,44 +425,6 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/timesheets": {
|
"/timesheets": {
|
||||||
"post": {
|
|
||||||
"operationId": "TimesheetsController_create",
|
|
||||||
"parameters": [],
|
|
||||||
"requestBody": {
|
|
||||||
"required": true,
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/CreateTimesheetDto"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"responses": {
|
|
||||||
"201": {
|
|
||||||
"description": "Timesheet created",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/CreateTimesheetDto"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"400": {
|
|
||||||
"description": "Incomplete task or invalid data"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"access-token": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"summary": "Create timesheet",
|
|
||||||
"tags": [
|
|
||||||
"Timesheets"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "TimesheetsController_getPeriodByQuery",
|
"operationId": "TimesheetsController_getPeriodByQuery",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- A unique constraint covering the columns `[employee_id,start_date]` on the table `timesheets` will be added. If there are existing duplicate values, this will fail.
|
||||||
|
- Added the required column `start_date` to the `timesheets` table without a default value. This is not possible if the table is not empty.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "public"."timesheets" ADD COLUMN "start_date" DATE NOT NULL;
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "timesheets_employee_id_start_date_key" ON "public"."timesheets"("employee_id", "start_date");
|
||||||
|
|
@ -2,26 +2,59 @@ import { PrismaClient, Prisma } from '@prisma/client';
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
|
// ====== Config ======
|
||||||
|
const PREVIOUS_WEEKS = 16; // nombre de semaines à créer (passé)
|
||||||
|
const INCLUDE_CURRENT = false; // true si tu veux aussi la semaine courante
|
||||||
|
|
||||||
|
// Lundi (UTC) de la semaine courante
|
||||||
|
function mondayOfThisWeekUTC(now = new Date()) {
|
||||||
|
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
|
||||||
|
d.setUTCDate(d.getUTCDate() - diffToMonday);
|
||||||
|
d.setUTCHours(0, 0, 0, 0);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
function mondayNWeeksBefore(monday: Date, n: number) {
|
||||||
|
const d = new Date(monday);
|
||||||
|
d.setUTCDate(d.getUTCDate() - n * 7);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const employees = await prisma.employees.findMany({ select: { id: true } });
|
const employees = await prisma.employees.findMany({ select: { id: true } });
|
||||||
|
if (!employees.length) {
|
||||||
|
console.warn('Aucun employé — rien à insérer.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// ✅ typer rows pour éviter never[]
|
// Construit la liste des lundis (1 par semaine)
|
||||||
|
const mondays: Date[] = [];
|
||||||
|
const mondayThisWeek = mondayOfThisWeekUTC();
|
||||||
|
if (INCLUDE_CURRENT) mondays.push(mondayThisWeek);
|
||||||
|
for (let n = 1; n <= PREVIOUS_WEEKS; n++) {
|
||||||
|
mondays.push(mondayNWeeksBefore(mondayThisWeek, n));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prépare les lignes (1 timesheet / employé / semaine)
|
||||||
const rows: Prisma.TimesheetsCreateManyInput[] = [];
|
const rows: Prisma.TimesheetsCreateManyInput[] = [];
|
||||||
|
|
||||||
// 8 timesheets / employee
|
|
||||||
for (const e of employees) {
|
for (const e of employees) {
|
||||||
for (let i = 0; i < 16; i++) {
|
for (const monday of mondays) {
|
||||||
const is_approved = Math.random() < 0.3;
|
rows.push({
|
||||||
rows.push({ employee_id: e.id, is_approved });
|
employee_id: e.id,
|
||||||
|
start_date: monday,
|
||||||
|
is_approved: Math.random() < 0.3,
|
||||||
|
} as Prisma.TimesheetsCreateManyInput);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Insert en bulk et ignore les doublons si déjà présents
|
||||||
if (rows.length) {
|
if (rows.length) {
|
||||||
await prisma.timesheets.createMany({ data: rows });
|
await prisma.timesheets.createMany({ data: rows, skipDuplicates: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
const total = await prisma.timesheets.count();
|
const total = await prisma.timesheets.count();
|
||||||
console.log(`✓ Timesheets: ${total} rows (added ${rows.length})`);
|
console.log(`✓ Timesheets: ${total} rows (ajout potentiel: ${rows.length}, ${INCLUDE_CURRENT ? 'courante +' : ''}${PREVIOUS_WEEKS} semaines)`);
|
||||||
}
|
}
|
||||||
|
|
||||||
main().finally(() => prisma.$disconnect());
|
main().finally(() => prisma.$disconnect());
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,12 @@ const prisma = new PrismaClient();
|
||||||
const PREVIOUS_WEEKS = 5;
|
const PREVIOUS_WEEKS = 5;
|
||||||
const INCLUDE_CURRENT = false;
|
const INCLUDE_CURRENT = false;
|
||||||
|
|
||||||
|
// Times-only via Date (UTC 1970-01-01)
|
||||||
function timeAt(hour: number, minute: number) {
|
function timeAt(hour: number, minute: number) {
|
||||||
return new Date(Date.UTC(1970, 0, 1, hour, minute, 0));
|
return new Date(Date.UTC(1970, 0, 1, hour, minute, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lundi (UTC) de la date fournie
|
||||||
function mondayOfThisWeekUTC(now = new Date()) {
|
function mondayOfThisWeekUTC(now = new Date()) {
|
||||||
const d = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
|
const d = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
|
||||||
const day = d.getUTCDay();
|
const day = d.getUTCDay();
|
||||||
|
|
@ -37,6 +39,16 @@ function rndInt(min: number, max: number) {
|
||||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper: garantit le timesheet de la semaine (upsert)
|
||||||
|
async function getOrCreateTimesheet(employee_id: number, start_date: Date) {
|
||||||
|
return prisma.timesheets.upsert({
|
||||||
|
where: { employee_id_start_date: { employee_id, start_date } },
|
||||||
|
update: {},
|
||||||
|
create: { employee_id, start_date, is_approved: Math.random() < 0.3 },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
// Bank codes utilisés
|
// Bank codes utilisés
|
||||||
const BANKS = ['G1', 'G56', 'G48', 'G700', 'G105', 'G305', 'G43'] as const;
|
const BANKS = ['G1', 'G56', 'G48', 'G700', 'G105', 'G305', 'G43'] as const;
|
||||||
|
|
@ -55,21 +67,8 @@ async function main() {
|
||||||
return;
|
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 mondayThisWeek = mondayOfThisWeekUTC();
|
||||||
const mondays: Date[] = [];
|
const mondays: Date[] = [];
|
||||||
|
|
||||||
if (INCLUDE_CURRENT) mondays.push(mondayThisWeek);
|
if (INCLUDE_CURRENT) mondays.push(mondayThisWeek);
|
||||||
for (let n = 1; n <= PREVIOUS_WEEKS; n++) {
|
for (let n = 1; n <= PREVIOUS_WEEKS; n++) {
|
||||||
mondays.push(mondayNWeeksBefore(mondayThisWeek, n));
|
mondays.push(mondayNWeeksBefore(mondayThisWeek, n));
|
||||||
|
|
@ -83,8 +82,6 @@ async function main() {
|
||||||
|
|
||||||
for (let ei = 0; ei < employees.length; ei++) {
|
for (let ei = 0; ei < employees.length; ei++) {
|
||||||
const e = employees[ei];
|
const e = employees[ei];
|
||||||
const tss = tsByEmp.get(e.id) ?? [];
|
|
||||||
if (!tss.length) continue;
|
|
||||||
|
|
||||||
const baseStartHour = 6 + (ei % 5);
|
const baseStartHour = 6 + (ei % 5);
|
||||||
const baseStartMinute = (ei * 15) % 60;
|
const baseStartMinute = (ei * 15) % 60;
|
||||||
|
|
@ -92,20 +89,22 @@ async function main() {
|
||||||
for (let di = 0; di < weekDays.length; di++) {
|
for (let di = 0; di < weekDays.length; di++) {
|
||||||
const date = weekDays[di];
|
const date = weekDays[di];
|
||||||
|
|
||||||
// Tirage aléatoire du bank_code
|
// 1) Trouver/Créer le timesheet de CETTE semaine pour CET employé
|
||||||
|
const weekStart = mondayOfThisWeekUTC(date);
|
||||||
|
const ts = await getOrCreateTimesheet(e.id, weekStart);
|
||||||
|
|
||||||
|
// 2) Tirage aléatoire du bank_code
|
||||||
const randomCode = BANKS[Math.floor(Math.random() * BANKS.length)];
|
const randomCode = BANKS[Math.floor(Math.random() * BANKS.length)];
|
||||||
const bank_code_id = bcMap.get(randomCode)!;
|
const bank_code_id = bcMap.get(randomCode)!;
|
||||||
|
|
||||||
|
// 3) Horaire
|
||||||
const duration = rndInt(4, 10);
|
const duration = rndInt(4, 10);
|
||||||
|
|
||||||
const dayWeekOffset = (di + wi + (ei % 3)) % 3;
|
const dayWeekOffset = (di + wi + (ei % 3)) % 3;
|
||||||
const startH = Math.min(12, baseStartHour + dayWeekOffset);
|
const startH = Math.min(12, baseStartHour + dayWeekOffset);
|
||||||
const startM = baseStartMinute;
|
const startM = baseStartMinute;
|
||||||
const endH = startH + duration;
|
const endH = startH + duration;
|
||||||
const endM = startM;
|
const endM = startM;
|
||||||
|
|
||||||
const ts = tss[(di + wi) % tss.length];
|
|
||||||
|
|
||||||
await prisma.shifts.create({
|
await prisma.shifts.create({
|
||||||
data: {
|
data: {
|
||||||
timesheet_id: ts.id,
|
timesheet_id: ts.id,
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@ import { PrismaClient } from '@prisma/client';
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
// Lundi (UTC) de la semaine courante
|
// Lundi (UTC) de la date fournie
|
||||||
function mondayOfThisWeekUTC(now = new Date()) {
|
function mondayOfThisWeekUTC(now = new Date()) {
|
||||||
const d = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
|
const d = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
|
||||||
const day = d.getUTCDay(); // 0=Dim, 1=Lun, ...
|
const day = d.getUTCDay();
|
||||||
const diffToMonday = (day + 6) % 7; // 0 si lundi
|
const diffToMonday = (day + 6) % 7;
|
||||||
d.setUTCDate(d.getUTCDate() - diffToMonday);
|
d.setUTCDate(d.getUTCDate() - diffToMonday);
|
||||||
d.setUTCHours(0, 0, 0, 0);
|
d.setUTCHours(0, 0, 0, 0);
|
||||||
return d;
|
return d;
|
||||||
|
|
@ -27,7 +27,17 @@ function rndInt(min: number, max: number) {
|
||||||
}
|
}
|
||||||
function rndAmount(minCents: number, maxCents: number) {
|
function rndAmount(minCents: number, maxCents: number) {
|
||||||
const cents = rndInt(minCents, maxCents);
|
const cents = rndInt(minCents, maxCents);
|
||||||
return (cents / 100).toFixed(2); // string "123.45"
|
return (cents / 100).toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper: garantit le timesheet de la semaine (upsert)
|
||||||
|
async function getOrCreateTimesheet(employee_id: number, start_date: Date) {
|
||||||
|
return prisma.timesheets.upsert({
|
||||||
|
where: { employee_id_start_date: { employee_id, start_date } },
|
||||||
|
update: {},
|
||||||
|
create: { employee_id, start_date, is_approved: Math.random() < 0.3 },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
|
@ -55,43 +65,35 @@ async function main() {
|
||||||
let created = 0;
|
let created = 0;
|
||||||
|
|
||||||
for (const e of employees) {
|
for (const e of employees) {
|
||||||
// Choisir un timesheet (le plus ancien, ou change 'asc'→'desc' si tu préfères le plus récent)
|
// 1) Semaine courante → assurer le timesheet de la semaine
|
||||||
const ts = await prisma.timesheets.findFirst({
|
const weekStart = mondayOfThisWeekUTC();
|
||||||
where: { employee_id: e.id },
|
const ts = await getOrCreateTimesheet(e.id, weekStart);
|
||||||
select: { id: true },
|
|
||||||
orderBy: { id: 'asc' },
|
|
||||||
});
|
|
||||||
if (!ts) continue;
|
|
||||||
|
|
||||||
// Si l’employé a déjà une dépense cette semaine, on n’en recrée pas (≥1 garanti)
|
// 2) Skip si l’employé a déjà une dépense cette semaine (on garantit ≥1)
|
||||||
const already = await prisma.expenses.findFirst({
|
const already = await prisma.expenses.findFirst({
|
||||||
where: {
|
where: { timesheet_id: ts.id, date: { gte: monday, lte: friday } },
|
||||||
timesheet_id: ts.id,
|
|
||||||
date: { gte: monday, lte: friday },
|
|
||||||
},
|
|
||||||
select: { id: true },
|
select: { id: true },
|
||||||
});
|
});
|
||||||
if (already) continue;
|
if (already) continue;
|
||||||
|
|
||||||
// Choix aléatoire du code + jour
|
// 3) Choix aléatoire du code + jour
|
||||||
const randomCode = BANKS[Math.floor(Math.random() * BANKS.length)];
|
const randomCode = BANKS[Math.floor(Math.random() * BANKS.length)];
|
||||||
const bank_code_id = bcMap.get(randomCode)!;
|
const bank_code_id = bcMap.get(randomCode)!;
|
||||||
const date = weekDays[Math.floor(Math.random() * weekDays.length)];
|
const date = weekDays[Math.floor(Math.random() * weekDays.length)];
|
||||||
|
|
||||||
// Montant aléatoire (ranges par défaut en $ — ajuste au besoin)
|
// 4) Montant varié
|
||||||
// (ex.: G57 plus petit, G517 remboursement plus large)
|
|
||||||
const amount =
|
const amount =
|
||||||
randomCode === 'G56'
|
randomCode === 'G56'
|
||||||
? rndAmount(1000, 7500) // 10.00..75.00
|
? rndAmount(1000, 7500) // 10.00..75.00
|
||||||
: rndAmount(2000, 25000); // 20.00..250.00 pour les autres
|
: rndAmount(2000, 25000); // 20.00..250.00
|
||||||
|
|
||||||
await prisma.expenses.create({
|
await prisma.expenses.create({
|
||||||
data: {
|
data: {
|
||||||
timesheet_id: ts.id,
|
timesheet_id: ts.id,
|
||||||
bank_code_id,
|
bank_code_id,
|
||||||
date,
|
date,
|
||||||
amount, // stocké en string
|
amount,
|
||||||
attachement: null, // garde le champ tel quel si typo volontaire
|
attachement: null,
|
||||||
description: `Expense ${randomCode} ${amount}$ (emp ${e.id})`,
|
description: `Expense ${randomCode} ${amount}$ (emp ${e.id})`,
|
||||||
is_approved: Math.random() < 0.6,
|
is_approved: Math.random() < 0.6,
|
||||||
supervisor_comment: Math.random() < 0.2 ? 'OK' : null,
|
supervisor_comment: Math.random() < 0.2 ? 'OK' : null,
|
||||||
|
|
|
||||||
|
|
@ -149,12 +149,14 @@ model Timesheets {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
employee Employees @relation("TimesheetEmployee", fields: [employee_id], references: [id])
|
employee Employees @relation("TimesheetEmployee", fields: [employee_id], references: [id])
|
||||||
employee_id Int
|
employee_id Int
|
||||||
|
start_date DateTime @db.Date
|
||||||
is_approved Boolean @default(false)
|
is_approved Boolean @default(false)
|
||||||
|
|
||||||
shift Shifts[] @relation("ShiftTimesheet")
|
shift Shifts[] @relation("ShiftTimesheet")
|
||||||
expense Expenses[] @relation("ExpensesTimesheet")
|
expense Expenses[] @relation("ExpensesTimesheet")
|
||||||
archive TimesheetsArchive[] @relation("TimesheetsToArchive")
|
archive TimesheetsArchive[] @relation("TimesheetsToArchive")
|
||||||
|
|
||||||
|
@@unique([employee_id, start_date], name: "employee_id_start_date")
|
||||||
@@map("timesheets")
|
@@map("timesheets")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -233,8 +233,7 @@ export class PayPeriodsQueryService {
|
||||||
const categorie = (shift.bank_code?.categorie || "REGULAR").toUpperCase();
|
const categorie = (shift.bank_code?.categorie || "REGULAR").toUpperCase();
|
||||||
switch (categorie) {
|
switch (categorie) {
|
||||||
case "EVENING": record.evening_hours += hours; break;
|
case "EVENING": record.evening_hours += hours; break;
|
||||||
case "EMERGENCY":
|
case "EMERGENCY": record.emergency_hours += hours; break;
|
||||||
case "URGENT": record.emergency_hours += hours; break;
|
|
||||||
case "OVERTIME": record.overtime_hours += hours; break;
|
case "OVERTIME": record.overtime_hours += hours; break;
|
||||||
default: record.regular_hours += hours; break;
|
default: record.regular_hours += hours; break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,14 @@ export class TimesheetsController {
|
||||||
private readonly timesheetsCommand: TimesheetsCommandService,
|
private readonly timesheetsCommand: TimesheetsCommandService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Post()
|
// @Post()
|
||||||
//@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
// //@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||||
@ApiOperation({ summary: 'Create timesheet' })
|
// @ApiOperation({ summary: 'Create timesheet' })
|
||||||
@ApiResponse({ status: 201, description: 'Timesheet created', type: CreateTimesheetDto })
|
// @ApiResponse({ status: 201, description: 'Timesheet created', type: CreateTimesheetDto })
|
||||||
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
|
// @ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
|
||||||
create(@Body() dto: CreateTimesheetDto): Promise<Timesheets> {
|
// create(@Body() dto: CreateTimesheetDto): Promise<Timesheets> {
|
||||||
return this.timesheetsQuery.create(dto);
|
// return this.timesheetsQuery.create(dto);
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
//@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
//@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||||
|
|
|
||||||
|
|
@ -17,16 +17,16 @@ export class TimesheetsQueryService {
|
||||||
private readonly overtime: OvertimeService,
|
private readonly overtime: OvertimeService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async create(dto : CreateTimesheetDto): Promise<Timesheets> {
|
// async create(dto : CreateTimesheetDto): Promise<Timesheets> {
|
||||||
const { employee_id, is_approved } = dto;
|
// const { employee_id, is_approved } = dto;
|
||||||
return this.prisma.timesheets.create({
|
// return this.prisma.timesheets.create({
|
||||||
data: { employee_id, is_approved: is_approved ?? false },
|
// data: { employee_id, is_approved: is_approved ?? false },
|
||||||
include: {
|
// include: {
|
||||||
employee: { include: { user: true }
|
// employee: { include: { user: true }
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
async findAll(year: number, period_no: number, email: string): Promise<TimesheetPeriodDto> {
|
async findAll(year: number, period_no: number, email: string): Promise<TimesheetPeriodDto> {
|
||||||
//finds the employee
|
//finds the employee
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user