diff --git a/src/modules/timesheets/dtos/timesheet-period.dto.ts b/src/modules/timesheets/dtos/timesheet-period.dto.ts index b948f4d..cfd0194 100644 --- a/src/modules/timesheets/dtos/timesheet-period.dto.ts +++ b/src/modules/timesheets/dtos/timesheet-period.dto.ts @@ -3,12 +3,15 @@ export class ShiftDto { type: string; start_time: string; end_time : string; + comment: string; is_approved: boolean; is_remote: boolean; } export class ExpenseDto { amount: number; + comment: string; + supervisor_comment: string; total_mileage: number; total_expense: number; is_approved: boolean; @@ -22,6 +25,7 @@ export class DetailedShifts { evening_hours: number; overtime_hours: number; emergency_hours: number; + comment: string; short_date: string; break_durations?: number; } diff --git a/src/modules/timesheets/services/timesheets-query.service.ts b/src/modules/timesheets/services/timesheets-query.service.ts index e98a62c..f4517e2 100644 --- a/src/modules/timesheets/services/timesheets-query.service.ts +++ b/src/modules/timesheets/services/timesheets-query.service.ts @@ -1,14 +1,12 @@ import { Injectable, NotFoundException } from '@nestjs/common'; import { PrismaService } from 'src/prisma/prisma.service'; import { Timesheets, TimesheetsArchive } from '@prisma/client'; -import { UpdateTimesheetDto } from '../dtos/update-timesheet.dto'; import { OvertimeService } from 'src/modules/business-logics/services/overtime.service'; -import { computeHours, formatDateISO, getCurrentWeek, getWeekEnd, getWeekStart } from 'src/common/utils/date-utils'; +import { computeHours, formatDateISO, getWeekEnd, getWeekStart } from 'src/common/utils/date-utils'; import { TimesheetPeriodDto } from '../dtos/timesheet-period.dto'; import { buildPeriod, endOfDayUTC, toUTCDateOnly } from '../utils/timesheet.helpers'; import type { ShiftRow, ExpenseRow } from '../utils/timesheet.helpers'; import { TimesheetDto } from '../dtos/overview-timesheet.dto'; -import { CreateWeekShiftsDto } from '../dtos/create-timesheet.dto'; @Injectable() @@ -21,14 +19,14 @@ export class TimesheetsQueryService { async findAll(year: number, period_no: number, email: string): Promise { //finds the employee const employee = await this.prisma.employees.findFirst({ - where: { user: { is: { email } } }, + where: { user: { is: { email } } }, select: { id: true }, }); if(!employee) throw new NotFoundException(`no employee with email ${email} found`); //finds the period const period = await this.prisma.payPeriods.findFirst({ - where: { pay_year: year, pay_period_no: period_no }, + where: { pay_year: year, pay_period_no: period_no }, select: { period_start: true, period_end: true }, }); if(!period) throw new NotFoundException(`Period ${year}-${period_no} not found`); @@ -45,6 +43,7 @@ export class TimesheetsQueryService { date: true, start_time: true, end_time: true, + comment: true, is_approved: true, is_remote: true, bank_code: { select: { type: true } }, @@ -60,31 +59,37 @@ export class TimesheetsQueryService { select: { date: true, amount: true, + comment: true, + supervisor_comment: true, is_approved: true, bank_code: { select: { type: true } }, }, orderBy: { date: 'asc' }, }); - const to_num = (value: any) => value && typeof (value as any).toNumber === 'function' - ? (value as any).toNumber() - : Number(value); + const to_num = (value: any) => + value && typeof value.toNumber === 'function' ? value.toNumber() : + typeof value === 'number' ? value : + value ? Number(value) : 0; // data mapping const shifts: ShiftRow[] = raw_shifts.map(shift => ({ date: shift.date, start_time: shift.start_time, end_time: shift.end_time, - type: String(shift.bank_code?.type ?? '').toUpperCase(), + comment: shift.comment ?? '', is_approved: shift.is_approved ?? true, is_remote: shift.is_remote ?? true, + type: String(shift.bank_code?.type ?? '').toUpperCase(), })); const expenses: ExpenseRow[] = raw_expenses.map(expense => ({ date: expense.date, amount: to_num(expense.amount), - type: String(expense.bank_code?.type ?? '').toUpperCase(), + comment: expense.comment ?? '', + supervisor_comment: expense.supervisor_comment ?? '', is_approved: expense.is_approved ?? true, + type: String(expense.bank_code?.type ?? '').toUpperCase(), })); return buildPeriod(period.period_start, period.period_end, shifts , expenses); @@ -231,7 +236,7 @@ export class TimesheetsQueryService { await this.prisma.$transaction(async transaction => { //fetches all timesheets to cutoff const oldSheets = await transaction.timesheets.findMany({ - where: { shift: { every: { date: { lt: cutoff } } }, + where: { shift: { some: { date: { lt: cutoff } } }, }, select: { id: true, diff --git a/src/modules/timesheets/utils/timesheet.helpers.ts b/src/modules/timesheets/utils/timesheet.helpers.ts index eadae40..95ee5f3 100644 --- a/src/modules/timesheets/utils/timesheet.helpers.ts +++ b/src/modules/timesheets/utils/timesheet.helpers.ts @@ -34,8 +34,23 @@ const EXPENSE_TYPES = { } as const; //DB line types -export type ShiftRow = { date: Date; start_time: Date; end_time: Date; is_approved?: boolean; is_remote: boolean; type: string }; -export type ExpenseRow = { date: Date; amount: number; type: string; is_approved?: boolean; }; +export type ShiftRow = { + date: Date; + start_time: Date; + end_time: Date; + comment: string; + is_approved?: boolean; + is_remote: boolean; + type: string +}; +export type ExpenseRow = { + date: Date; + amount: number; + comment: string; + supervisor_comment: string; + is_approved?: boolean; + type: string; +}; //helper functions export function toUTCDateOnly(date: Date | string): Date { @@ -84,6 +99,7 @@ export function makeEmptyWeek(week_start: Date): WeekDto { evening_hours: 0, emergency_hours: 0, overtime_hours: 0, + comment: '', short_date: shortDate(addDays(week_start, offset)), break_durations: 0, }); @@ -129,19 +145,44 @@ export function buildWeek( }, {} as Record>); //shifts's hour by type - type ShiftsHours = - {regular: number; evening: number; overtime: number; emergency: number; sick: number; vacation: number; holiday: number;}; - const make_hours = (): ShiftsHours => - ({ regular: 0, evening: 0, overtime: 0, emergency: 0, sick: 0, vacation: 0, holiday: 0 }); + type ShiftsHours = { + regular: number; + evening: number; + overtime: number; + emergency: number; + sick: number; + vacation: number; + holiday: number; + }; + const make_hours = (): ShiftsHours => ({ + regular: 0, + evening: 0, + overtime: 0, + emergency: 0, + sick: 0, + vacation: 0, + holiday: 0 + }); const day_hours: Record = DAY_KEYS.reduce((acc, key) => { acc[key] = make_hours(); return acc; }, {} as Record); //expenses's amount by type - type ExpensesAmount = - {mileage: number; expense: number; per_diem: number; commission: number; prime_dispo: number }; - const make_amounts = (): ExpensesAmount => - ({ mileage: 0, expense: 0, per_diem: 0, commission: 0, prime_dispo: 0 }); + type ExpensesAmount = { + mileage: number; + expense: number; + per_diem: number; + commission: number; + prime_dispo: number + }; + + const make_amounts = (): ExpensesAmount => ({ + mileage: 0, + expense: 0, + per_diem: 0, + commission: 0, + prime_dispo: 0 + }); const day_amounts: Record = DAY_KEYS.reduce((acc, key) => { acc[key] = make_amounts(); return acc; }, {} as Record); @@ -159,6 +200,7 @@ export function buildWeek( type: shift.type, start_time: toTimeString(shift.start_time), end_time: toTimeString(shift.end_time), + comment: shift.comment, is_approved: shift.is_approved ?? true, is_remote: shift.is_remote, } as ShiftDto); @@ -230,6 +272,8 @@ export function buildWeek( for(const row of dayExpenseRows[key].km) { week.expenses[key].km.push({ amount: round2(row.amount), + comment: row.comment, + supervisor_comment: row.supervisor_comment, total_mileage: round2(total_mileage), total_expense: round2(total_expense), is_approved: row.is_approved ?? true, @@ -240,6 +284,8 @@ export function buildWeek( for(const row of dayExpenseRows[key].cash) { week.expenses[key].cash.push({ amount: round2(row.amount), + comment: row.comment, + supervisor_comment: row.supervisor_comment, total_mileage: round2(total_mileage), total_expense: round2(total_expense), is_approved: row.is_approved ?? true,