feat(timesheet): added getTimesheetByEmail
This commit is contained in:
parent
c170481f3b
commit
93cf2d571b
|
|
@ -468,6 +468,42 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"/timesheets/{email}": {
|
||||
"get": {
|
||||
"operationId": "TimesheetsController_getByEmail",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "email",
|
||||
"required": true,
|
||||
"in": "path",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "offset",
|
||||
"required": true,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"access-token": []
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"Timesheets"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/timesheets/{id}": {
|
||||
"get": {
|
||||
"operationId": "TimesheetsController_findOne",
|
||||
|
|
|
|||
|
|
@ -49,6 +49,13 @@ export function getYearStart(date:Date): Date {
|
|||
return new Date(date.getFullYear(),0,1,0,0,0,0);
|
||||
}
|
||||
|
||||
export function getCurrentWeek(): { start_date_week: Date; end_date_week: Date } {
|
||||
const now = new Date();
|
||||
const start_date_week = getWeekStart(now, 0);
|
||||
const end_date_week = getWeekEnd(start_date_week);
|
||||
return { start_date_week, end_date_week };
|
||||
}
|
||||
|
||||
//cloning methods (helps with notify for overtime in a single day)
|
||||
// export function toDateOnly(day: Date): Date {
|
||||
// const d = new Date(day);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { BadRequestException, Body, Controller, Delete, Get, Param, ParseBoolPipe, ParseIntPipe, Patch, Post, Query, UseGuards, UsePipes, ValidationPipe } from '@nestjs/common';
|
||||
import { BadRequestException, Body, Controller, Delete, Get, Param, ParseBoolPipe, ParseIntPipe, Patch, Query } from '@nestjs/common';
|
||||
import { TimesheetsQueryService } from '../services/timesheets-query.service';
|
||||
import { CreateTimesheetDto } from '../dtos/create-timesheet.dto';
|
||||
import { Timesheets } from '@prisma/client';
|
||||
|
|
@ -7,8 +7,8 @@ import { RolesAllowed } from "src/common/decorators/roles.decorators";
|
|||
import { Roles as RoleEnum } from '.prisma/client';
|
||||
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { TimesheetsCommandService } from '../services/timesheets-command.service';
|
||||
import { SearchTimesheetDto } from '../dtos/search-timesheet.dto';
|
||||
import { TimesheetPeriodDto } from '../dtos/timesheet-period.dto';
|
||||
import { TimesheetDto } from '../dtos/overview-timesheet.dto';
|
||||
|
||||
@ApiTags('Timesheets')
|
||||
@ApiBearerAuth('access-token')
|
||||
|
|
@ -39,6 +39,15 @@ export class TimesheetsController {
|
|||
if(!email || !(email = email.trim())) throw new BadRequestException('Query param "email" is mandatory for this route.');
|
||||
return this.timesheetsQuery.findAll(year, period_no, email);
|
||||
}
|
||||
|
||||
@Get('/:email')
|
||||
async getByEmail(
|
||||
@Param('email') email: string,
|
||||
@Query('offset') offset?: string,
|
||||
): Promise<TimesheetDto> {
|
||||
const week_offset = Number.isFinite(Number(offset)) ? Number(offset) : 0;
|
||||
return this.timesheetsQuery.getTimesheetByEmail(email, week_offset);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
//@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
|
|
|
|||
27
src/modules/timesheets/dtos/overview-timesheet.dto.ts
Normal file
27
src/modules/timesheets/dtos/overview-timesheet.dto.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
export class TimesheetDto {
|
||||
is_approved: boolean;
|
||||
start_day: string;
|
||||
end_day: string;
|
||||
label: string;
|
||||
shifts: ShiftsDto[];
|
||||
expenses: ExpensesDto[]
|
||||
}
|
||||
|
||||
export class ShiftsDto {
|
||||
bank_type: string;
|
||||
date: string;
|
||||
start_time: string;
|
||||
end_time: string;
|
||||
description: string;
|
||||
is_approved: boolean;
|
||||
}
|
||||
|
||||
export class ExpensesDto {
|
||||
bank_type: string;
|
||||
date: string;
|
||||
amount: number;
|
||||
km: number;
|
||||
description: string;
|
||||
supervisor_comment: string;
|
||||
is_approved: boolean;
|
||||
}
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { PrismaService } from 'src/prisma/prisma.service';
|
||||
import { CreateTimesheetDto } from '../dtos/create-timesheet.dto';
|
||||
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 } from 'src/common/utils/date-utils';
|
||||
import { computeHours, formatDateISO, getCurrentWeek, 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';
|
||||
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -98,6 +98,102 @@ export class TimesheetsQueryService {
|
|||
return buildPeriod(period.period_start, period.period_end, shifts , expenses);
|
||||
}
|
||||
|
||||
async getTimesheetByEmail(email: string, week_offset = 0): Promise<TimesheetDto> {
|
||||
|
||||
//fetch user related to email
|
||||
const user = await this.prisma.users.findUnique({
|
||||
where: { email },
|
||||
select: { id: true },
|
||||
});
|
||||
if(!user) throw new NotFoundException(`user with email ${email} not found`);
|
||||
|
||||
//fetch employee_id matching the email
|
||||
const employee = await this.prisma.employees.findFirst({
|
||||
where: { user_id: user.id },
|
||||
select: { id: true },
|
||||
});
|
||||
if(!employee) throw new NotFoundException(`Employee with email: ${email} not found`);
|
||||
|
||||
//sets current week Sunday -> Saturday
|
||||
const base = new Date();
|
||||
const offset = new Date(base);
|
||||
offset.setDate(offset.getDate() + (week_offset * 7));
|
||||
|
||||
const start_date_week = getWeekStart(offset, 0);
|
||||
const end_date_week = getWeekEnd(start_date_week);
|
||||
const start_day = formatDateISO(start_date_week);
|
||||
const end_day = formatDateISO(end_date_week);
|
||||
|
||||
//build the label MM/DD/YYYY.MM/DD.YYYY
|
||||
const mm_dd = (date: Date) => `${String(date.getFullYear())}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2,'0')}`;
|
||||
const label = `${mm_dd(start_date_week)}.${mm_dd(end_date_week)}`;
|
||||
|
||||
//fetch timesheet shifts and expenses
|
||||
const timesheet = await this.prisma.timesheets.findUnique({
|
||||
where: {
|
||||
employee_id_start_date: {
|
||||
employee_id: employee.id,
|
||||
start_date: start_date_week,
|
||||
},
|
||||
},
|
||||
include: {
|
||||
shift: {
|
||||
include: { bank_code: true },
|
||||
orderBy: [{ date: 'asc'}, { start_time: 'asc'}],
|
||||
},
|
||||
expense: {
|
||||
include: { bank_code: true },
|
||||
orderBy: [{date: 'asc'}],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
//returns an empty timesheet if not found
|
||||
if(!timesheet) {
|
||||
return {
|
||||
is_approved: false,
|
||||
start_day,
|
||||
end_day,
|
||||
label,
|
||||
shifts:[],
|
||||
expenses: [],
|
||||
} as TimesheetDto;
|
||||
}
|
||||
|
||||
//small helper to format hours:minutes
|
||||
const to_HH_mm = (date: Date) => date.toISOString().slice(11, 16);
|
||||
|
||||
//maps all shifts of selected timesheet
|
||||
const shifts = timesheet.shift.map((sft) => ({
|
||||
bank_type: sft.bank_code?.type ?? '',
|
||||
date: formatDateISO(sft.date),
|
||||
start_time: to_HH_mm(sft.start_time),
|
||||
end_time: to_HH_mm(sft.end_time),
|
||||
description: sft.description ?? '',
|
||||
is_approved: sft.is_approved ?? false,
|
||||
}));
|
||||
|
||||
//maps all expenses of selected timsheet
|
||||
const expenses = timesheet.expense.map((exp) => ({
|
||||
bank_type: exp.bank_code?.type ?? '',
|
||||
date: formatDateISO(exp.date),
|
||||
amount: Number(exp.amount) || 0,
|
||||
km: 0,
|
||||
description: exp.description ?? '',
|
||||
supervisor_comment: exp.supervisor_comment ?? '',
|
||||
is_approved: exp.is_approved ?? false,
|
||||
}));
|
||||
|
||||
return {
|
||||
is_approved: timesheet.is_approved,
|
||||
start_day,
|
||||
end_day,
|
||||
label,
|
||||
shifts,
|
||||
expenses,
|
||||
} as TimesheetDto;
|
||||
}
|
||||
|
||||
async findOne(id: number): Promise<any> {
|
||||
const timesheet = await this.prisma.timesheets.findUnique({
|
||||
where: { id },
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user