Merge branch 'main' of git.targo.ca:Targo/targo_backend into origin/dev/setup/AuthMiddleware/NicolasD
This commit is contained in:
commit
615f0848e5
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -56,3 +56,5 @@ pids
|
|||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
/generated/prisma
|
||||
|
||||
!swagger-spec.json
|
||||
|
|
|
|||
2285
docs/swagger/swagger-spec.json
Normal file
2285
docs/swagger/swagger-spec.json
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -12,6 +12,7 @@ import { LeaveRequestsModule } from './modules/leave-requests/leave-requests.mod
|
|||
import { ShiftCodeModule } from './modules/shift-codes/shift-codes.module';
|
||||
import { ShiftsModule } from './modules/shifts/shifts.module';
|
||||
import { TimesheetsModule } from './modules/timesheets/timesheets.module';
|
||||
import { AuthenticationModule } from './modules/authentication/auth.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
|
|
@ -25,6 +26,7 @@ import { TimesheetsModule } from './modules/timesheets/timesheets.module';
|
|||
ShiftCodeModule,
|
||||
ShiftsModule,
|
||||
TimesheetsModule,
|
||||
AuthenticationModule,
|
||||
],
|
||||
controllers: [AppController, HealthController],
|
||||
providers: [AppService],
|
||||
|
|
|
|||
37
src/main.ts
37
src/main.ts
|
|
@ -5,11 +5,13 @@ import { ValidationPipe } from '@nestjs/common';
|
|||
import { JwtAuthGuard } from './modules/authentication/guards/jwt-auth.guard';
|
||||
import { RolesGuard } from './common/guards/roles.guard';
|
||||
import { OwnershipGuard } from './common/guards/ownership.guard';
|
||||
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
||||
import { writeFileSync } from 'fs';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
//setup Reflector for Roles()
|
||||
const reflector = app.get(Reflector);
|
||||
|
||||
const reflector = app.get(Reflector); //setup Reflector for Roles()
|
||||
|
||||
app.useGlobalPipes(
|
||||
new ValidationPipe({ whitelist: true, transform: true}));
|
||||
|
|
@ -19,6 +21,37 @@ async function bootstrap() {
|
|||
new OwnershipGuard(reflector, app.get(ModuleRef)), //Global use of OwnershipGuard, not implemented yet
|
||||
);
|
||||
|
||||
//swagger config
|
||||
const config = new DocumentBuilder()
|
||||
.setTitle('Targo_Backend')
|
||||
.setDescription('Documentation de l`API REST pour Targo (NestJS + Prisma)')
|
||||
.setVersion('1.0')
|
||||
.addBearerAuth({
|
||||
type: 'http',
|
||||
scheme: 'bearer',
|
||||
bearerFormat: 'JWT',
|
||||
name: 'Authorization',
|
||||
description: 'Invalid JWT token',
|
||||
in: 'header',
|
||||
}, 'access-token')
|
||||
.addTag('Users')
|
||||
.addTag('Employees')
|
||||
.addTag('Customers')
|
||||
.addTag('Timesheets')
|
||||
.addTag('Shifts')
|
||||
.addTag('Leave Requests')
|
||||
.addTag('Shift Codes')
|
||||
.addTag('OAuth Access Tokens')
|
||||
.addTag('Authorization')
|
||||
.build();
|
||||
|
||||
//document builder for swagger docs
|
||||
const documentFactory = () => SwaggerModule.createDocument(app, config);
|
||||
const document = documentFactory()
|
||||
SwaggerModule.setup('api/docs', app, document);
|
||||
|
||||
writeFileSync('./docs/swagger/swagger-spec.json', JSON.stringify(document, null, 2));
|
||||
|
||||
await app.listen(process.env.PORT ?? 3000);
|
||||
}
|
||||
bootstrap();
|
||||
|
|
|
|||
|
|
@ -1,35 +1,53 @@
|
|||
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from '@nestjs/common';
|
||||
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post, UseGuards } from '@nestjs/common';
|
||||
import { CustomersService } from '../services/customers.service';
|
||||
import { Customers, Employees } from '@prisma/client';
|
||||
import { CreateCustomerDto } from '../dtos/create-customer';
|
||||
import { UpdateCustomerDto } from '../dtos/update-customer';
|
||||
import { Customers } from '@prisma/client';
|
||||
import { CreateCustomerDto } from '../dtos/create-customer.dto';
|
||||
import { UpdateCustomerDto } from '../dtos/update-customer.dto';
|
||||
import { RolesAllowed } from "src/common/decorators/roles.decorators";
|
||||
import { Roles as RoleEnum } from '.prisma/client';
|
||||
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { JwtAuthGuard } from 'src/modules/authentication/guards/jwt-auth.guard';
|
||||
import { CustomerEntity } from '../dtos/swagger-entities/customers.entity';
|
||||
|
||||
@ApiTags('Customers')
|
||||
@ApiBearerAuth('access-token')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Controller('customers')
|
||||
export class CustomersController {
|
||||
constructor(private readonly customersService: CustomersService) {}
|
||||
|
||||
@Post()
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({ summary: 'Create customer' })
|
||||
@ApiResponse({ status: 201, description: 'Customer created', type: CustomerEntity })
|
||||
@ApiResponse({ status: 400, description: 'Invalid task or invalid data' })
|
||||
create(@Body() dto: CreateCustomerDto): Promise<Customers> {
|
||||
return this.customersService.create(dto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({ summary: 'Find all customers' })
|
||||
@ApiResponse({ status: 201, description: 'List of customers found', type: CustomerEntity, isArray: true })
|
||||
@ApiResponse({ status: 400, description: 'List of customers not found' })
|
||||
findAll(): Promise<Customers[]> {
|
||||
return this.customersService.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({ summary: 'Find customer' })
|
||||
@ApiResponse({ status: 201, description: 'Customer found', type: CustomerEntity })
|
||||
@ApiResponse({ status: 400, description: 'Customer not found' })
|
||||
findOne(@Param('id', ParseIntPipe) id: number): Promise<Customers> {
|
||||
return this.customersService.findOne(id);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE,RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({ summary: 'Update customer' })
|
||||
@ApiResponse({ status: 201, description: 'Customer updated', type: CustomerEntity })
|
||||
@ApiResponse({ status: 400, description: 'Customer not found' })
|
||||
update(
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@Body() dto: UpdateCustomerDto,
|
||||
|
|
@ -39,6 +57,9 @@ export class CustomersController {
|
|||
|
||||
@Delete(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({ summary: 'Delete customer' })
|
||||
@ApiResponse({ status: 201, description: 'Customer deleted', type: CustomerEntity })
|
||||
@ApiResponse({ status: 400, description: 'Customer not found' })
|
||||
remove(@Param('id', ParseIntPipe) id: number): Promise<Customers>{
|
||||
return this.customersService.remove(id);
|
||||
}
|
||||
|
|
|
|||
64
src/modules/customers/dtos/create-customer.dto.ts
Normal file
64
src/modules/customers/dtos/create-customer.dto.ts
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { Type } from "class-transformer";
|
||||
import {
|
||||
IsEmail,
|
||||
IsInt,
|
||||
IsNotEmpty,
|
||||
IsOptional,
|
||||
IsPositive,
|
||||
IsString,
|
||||
} from "class-validator";
|
||||
|
||||
export class CreateCustomerDto {
|
||||
|
||||
@ApiProperty({
|
||||
example: 'Gandalf',
|
||||
description: 'Customer`s first name',
|
||||
})
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
first_name: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'TheGray',
|
||||
description: 'Customer`s last name',
|
||||
})
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
last_name: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'you_shall_not_pass@middleEarth.com',
|
||||
description: 'Customer`s email',
|
||||
})
|
||||
@IsEmail()
|
||||
@IsOptional()
|
||||
email: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: '8436637464',
|
||||
description: 'Customer`s phone number',
|
||||
})
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
@IsPositive()
|
||||
phone_number: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: '1 Ringbearer`s way, Mount Doom city, ME, T1R 1N6 ',
|
||||
description: 'Customer`s residence',
|
||||
required: false,
|
||||
})
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
residence?: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: '4263253',
|
||||
description: 'Customer`s invoice number',
|
||||
required: false,
|
||||
})
|
||||
@IsInt()
|
||||
@IsNotEmpty()
|
||||
invoice_id: number;
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
import { Type } from "class-transformer";
|
||||
import {
|
||||
IsEmail,
|
||||
IsInt,
|
||||
IsNotEmpty,
|
||||
IsOptional,
|
||||
IsPositive,
|
||||
IsString,
|
||||
} from "class-validator";
|
||||
|
||||
export class CreateCustomerDto {
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
first_name: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
last_name: string;
|
||||
|
||||
@IsEmail()
|
||||
@IsOptional()
|
||||
email?: string;
|
||||
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
@IsPositive()
|
||||
phone_number: number;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
residence?: string;
|
||||
|
||||
@IsInt()
|
||||
@IsNotEmpty()
|
||||
invoice_id: number;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class CustomerEntity {
|
||||
@ApiProperty({
|
||||
example: 1,
|
||||
description: 'Unique ID of a customer(primary-key, auto-incremented)',
|
||||
})
|
||||
id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: '0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d',
|
||||
description: 'UUID of the user linked to that customer',
|
||||
})
|
||||
user_id: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'you_shall_not_pass@middleEarth.com',
|
||||
description: 'customer`s email (optional)',
|
||||
required: false,
|
||||
})
|
||||
email?: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 8436637464,
|
||||
description: 'customer`s phone number (numbers only)',
|
||||
})
|
||||
phone_number: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: '1 Ringbearer’s way, Mount Doom city, ME, T1R 1N6',
|
||||
description: 'customer`s residence address (optional)',
|
||||
required: false,
|
||||
})
|
||||
residence?: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 4263253,
|
||||
description: 'customer`s invoice number (optionnal, unique)',
|
||||
required: false,
|
||||
})
|
||||
invoice_id?: number;
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { PartialType } from "@nestjs/swagger";
|
||||
import { CreateCustomerDto } from "./create-customer";
|
||||
import { CreateCustomerDto } from "./create-customer.dto";
|
||||
|
||||
export class UpdateCustomerDto extends PartialType(CreateCustomerDto) {}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { PrismaService } from 'src/prisma/prisma.service';
|
||||
import { CreateCustomerDto } from '../dtos/create-customer';
|
||||
import { CreateCustomerDto } from '../dtos/create-customer.dto';
|
||||
import { Customers, Users } from '@prisma/client';
|
||||
import { UpdateCustomerDto } from '../dtos/update-customer';
|
||||
import { UpdateCustomerDto } from '../dtos/update-customer.dto';
|
||||
|
||||
@Injectable()
|
||||
export class CustomersService {
|
||||
|
|
|
|||
|
|
@ -1,46 +1,52 @@
|
|||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
Patch,
|
||||
Post,
|
||||
} from '@nestjs/common';
|
||||
import { Employees } from '@prisma/client';
|
||||
import { Body,Controller,Delete,Get,Param,ParseIntPipe,Patch,Post,UseGuards } from '@nestjs/common';
|
||||
import { Employees, Roles as RoleEnum } from '@prisma/client';
|
||||
import { EmployeesService } from '../services/employees.service';
|
||||
import { CreateEmployeeDto } from '../dtos/create-employee.dto';
|
||||
import { UpdateEmployeeDto } from '../dtos/update-employee.dto';
|
||||
|
||||
//decorators and roles imports
|
||||
import { RolesAllowed } from '../../../common/decorators/roles.decorators';
|
||||
import { Roles as RoleEnum } from 'prisma/prisma-client';
|
||||
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { JwtAuthGuard } from 'src/modules/authentication/guards/jwt-auth.guard';
|
||||
import { EmployeeEntity } from '../dtos/swagger-entities/employees.entity';
|
||||
|
||||
@ApiTags('Employees')
|
||||
@ApiBearerAuth('access-token')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Controller('employees')
|
||||
export class EmployeesController {
|
||||
constructor(private readonly employeesService: EmployeesService) {}
|
||||
|
||||
@Post()
|
||||
@RolesAllowed(RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({summary: 'Create employee' })
|
||||
@ApiResponse({ status: 201, description: 'Employee created', type: EmployeeEntity })
|
||||
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
|
||||
create(@Body() dto: CreateEmployeeDto): Promise<Employees> {
|
||||
return this.employeesService.create(dto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RolesAllowed(RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR, RoleEnum.ACCOUNTING)
|
||||
@ApiOperation({summary: 'Find all employees' })
|
||||
@ApiResponse({ status: 201, description: 'List of employees found', type: EmployeeEntity, isArray: true })
|
||||
@ApiResponse({ status: 400, description: 'List of employees not found' })
|
||||
findAll(): Promise<Employees[]> {
|
||||
return this.employeesService.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RolesAllowed(RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR,RoleEnum.ACCOUNTING )
|
||||
@ApiOperation({summary: 'Find employee' })
|
||||
@ApiResponse({ status: 201, description: 'Employee found', type: EmployeeEntity })
|
||||
@ApiResponse({ status: 400, description: 'Employee not found' })
|
||||
findOne(@Param('id', ParseIntPipe) id: number): Promise<Employees> {
|
||||
return this.employeesService.findOne(id);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@RolesAllowed(RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR,RoleEnum.ACCOUNTING )
|
||||
@ApiOperation({summary: 'Update employee' })
|
||||
@ApiResponse({ status: 201, description: 'Employee updated', type: EmployeeEntity })
|
||||
@ApiResponse({ status: 400, description: 'Employee not found' })
|
||||
update(
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@Body() dto: UpdateEmployeeDto,
|
||||
|
|
@ -50,6 +56,9 @@ export class EmployeesController {
|
|||
|
||||
@Delete(':id')
|
||||
@RolesAllowed(RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR )
|
||||
@ApiOperation({summary: 'Delete employee' })
|
||||
@ApiResponse({ status: 201, description: 'Employee deleted', type: EmployeeEntity })
|
||||
@ApiResponse({ status: 400, description: 'Employee not found' })
|
||||
remove(@Param('id', ParseIntPipe) id: number): Promise<Employees> {
|
||||
return this.employeesService.remove(id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,44 +9,84 @@ import {
|
|||
IsString,
|
||||
} from 'class-validator';
|
||||
import { Type } from 'class-transformer';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class CreateEmployeeDto {
|
||||
|
||||
@ApiProperty({
|
||||
example: 'Frodo',
|
||||
description: 'Employee`s first name',
|
||||
})
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
first_name: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'Baggins',
|
||||
description: 'Employee`s last name',
|
||||
})
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
last_name: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'i_cant_do_this_sam@targointernet.com',
|
||||
description: 'Employee`s email',
|
||||
})
|
||||
@IsEmail()
|
||||
@IsOptional()
|
||||
email: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: '82538437464',
|
||||
description: 'Employee`s phone number',
|
||||
})
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
@IsPositive()
|
||||
phone_number: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: '1 Bagshot Row, Hobbiton, The Shire, Middle-earth',
|
||||
description: 'Employee`s residence',
|
||||
required: false,
|
||||
})
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
residence?: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'BagginsF7464',
|
||||
description: 'Employee`s payroll id',
|
||||
})
|
||||
@IsInt()
|
||||
@IsPositive()
|
||||
@Type(() => Number)
|
||||
external_payroll_id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: '335567447',
|
||||
description: 'Employee`s company code',
|
||||
})
|
||||
@IsInt()
|
||||
@IsPositive()
|
||||
@Type(() => Number)
|
||||
company_code: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: '23/09/3018',
|
||||
description: 'Employee`s first working day',
|
||||
})
|
||||
@IsDateString()
|
||||
@Type(() => Date)
|
||||
@IsDate()
|
||||
first_work_day: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: '25/03/3019',
|
||||
description: 'Employee`s last working day',
|
||||
required: false,
|
||||
})
|
||||
@IsDateString()
|
||||
@Type(() => Date)
|
||||
@IsDate()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class EmployeeEntity {
|
||||
@ApiProperty({
|
||||
example: 1,
|
||||
description: 'Unique ID of an employee(primary-key, auto-incremented)',
|
||||
})
|
||||
id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: '0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d',
|
||||
description: 'UUID of the user linked to that employee',
|
||||
})
|
||||
user_id: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 7464,
|
||||
description: 'external ID for the pay system',
|
||||
})
|
||||
external_payroll_id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: 335567447,
|
||||
description: 'company code',
|
||||
})
|
||||
company_code: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: '3018-09-23T00:00:00.000Z',
|
||||
description: 'Employee first day at work',
|
||||
})
|
||||
first_work_day: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: '3019-03-25T00:00:00.000Z',
|
||||
description: 'Employee last day at work',
|
||||
required: false,
|
||||
})
|
||||
last_work_day?: Date;
|
||||
}
|
||||
|
|
@ -1,44 +1,62 @@
|
|||
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from "@nestjs/common";
|
||||
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post, UseGuards } from "@nestjs/common";
|
||||
import { LeaveRequestsService } from "../services/leave-request.service";
|
||||
import { CreateLeaveRequestsDto } from "../dtos/create-leave-requests.dto";
|
||||
import { LeaveRequests } from "@prisma/client";
|
||||
import { UpdateLeaveRequestsDto } from "../dtos/update-leave-requests.dto";
|
||||
import { RolesAllowed } from "src/common/decorators/roles.decorators";
|
||||
import { Roles as RoleEnum } from '.prisma/client';
|
||||
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
|
||||
import { JwtAuthGuard } from "src/modules/authentication/guards/jwt-auth.guard";
|
||||
import { LeaveRequestEntity } from "../dtos/swagger-entities/leave-requests.entity";
|
||||
|
||||
@ApiTags('Leave Requests')
|
||||
@ApiBearerAuth('access-token')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Controller('leave-requests')
|
||||
export class LeaveRequestController {
|
||||
constructor(private readonly leaveRequetsService: LeaveRequestsService){}
|
||||
|
||||
@Post()
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({summary: 'Create leave request' })
|
||||
@ApiResponse({ status: 201, description: 'Leave request created',type: LeaveRequestEntity })
|
||||
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
|
||||
create(@Body() dto: CreateLeaveRequestsDto): Promise<LeaveRequests> {
|
||||
return this. leaveRequetsService.create(dto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({summary: 'Find all leave request' })
|
||||
@ApiResponse({ status: 201, description: 'List of Leave requests found',type: LeaveRequestEntity, isArray: true })
|
||||
@ApiResponse({ status: 400, description: 'Leave request not found' })
|
||||
findAll(): Promise<LeaveRequests[]> {
|
||||
return this.leaveRequetsService.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({summary: 'Find leave request' })
|
||||
@ApiResponse({ status: 201, description: 'Leave request found',type: LeaveRequestEntity })
|
||||
@ApiResponse({ status: 400, description: 'Leave request not found' })
|
||||
findOne(@Param('id', ParseIntPipe) id: number): Promise<LeaveRequests> {
|
||||
return this.leaveRequetsService.findOne(id);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
update(
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@Body() dto: UpdateLeaveRequestsDto,
|
||||
): Promise<LeaveRequests> {
|
||||
@ApiOperation({summary: 'Update leave request' })
|
||||
@ApiResponse({ status: 201, description: 'Leave request updated',type: LeaveRequestEntity })
|
||||
@ApiResponse({ status: 400, description: 'Leave request not found' })
|
||||
update(@Param('id', ParseIntPipe) id: number,@Body() dto: UpdateLeaveRequestsDto): Promise<LeaveRequests> {
|
||||
return this.leaveRequetsService.update(id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({summary: 'Delete leave request' })
|
||||
@ApiResponse({ status: 201, description: 'Leave request deleted',type: LeaveRequestEntity })
|
||||
@ApiResponse({ status: 400, description: 'Leave request not found' })
|
||||
remove(@Param('id', ParseIntPipe) id: number): Promise<LeaveRequests> {
|
||||
return this.leaveRequetsService.remove(id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,52 @@
|
|||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { LeaveApprovalStatus, LeaveTypes } from "@prisma/client";
|
||||
import { Type } from "class-transformer";
|
||||
import { IsEnum, IsInt, IsNotEmpty, IsOptional, IsString } from "class-validator";
|
||||
|
||||
export class CreateLeaveRequestsDto {
|
||||
@ApiProperty({
|
||||
example: '4655867',
|
||||
description: 'Employee`s id',
|
||||
})
|
||||
@Type(()=> Number)
|
||||
@IsInt()
|
||||
employee_id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'Sick or Vacation or Unpaid or Bereavement or Parental or Legal',
|
||||
description: 'type of leave request for an accounting perception',
|
||||
})
|
||||
@IsEnum(LeaveTypes)
|
||||
leave_type: LeaveTypes;
|
||||
|
||||
@ApiProperty({
|
||||
example: '22/06/2463',
|
||||
description: 'Leave request`s start date',
|
||||
})
|
||||
@Type(()=>Date)
|
||||
@IsNotEmpty()
|
||||
start_date_time:Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: '25/03/3019',
|
||||
description: 'Leave request`s end date',
|
||||
})
|
||||
@Type(()=>Date)
|
||||
@IsOptional()
|
||||
end_date_time?: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'My precious',
|
||||
description: 'Leave request`s comment',
|
||||
})
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
comment: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'True or False or Pending or Denied or Cancelled or Escalated',
|
||||
description: 'Leave request`s approval status',
|
||||
})
|
||||
@IsEnum(LeaveApprovalStatus)
|
||||
@IsOptional()
|
||||
approval_status?: LeaveApprovalStatus;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { LeaveApprovalStatus, LeaveTypes } from '@prisma/client';
|
||||
|
||||
export class LeaveRequestEntity {
|
||||
@ApiProperty({
|
||||
example: 1,
|
||||
description: 'Leave request`s unique id(auto-incremented)',
|
||||
})
|
||||
id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: 42,
|
||||
description: 'ID of concerned employee',
|
||||
})
|
||||
employee_id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'SICK',
|
||||
enum: LeaveTypes,
|
||||
description: 'type of leave request for an accounting perception',
|
||||
})
|
||||
leave_type: LeaveTypes;
|
||||
|
||||
@ApiProperty({
|
||||
example: '22/06/2463',
|
||||
description: 'Leave request`s start date',
|
||||
})
|
||||
start_date_time: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: '25/03/3019',
|
||||
description: 'Leave request`s end date (optionnal)',
|
||||
required: false,
|
||||
})
|
||||
end_date_time?: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'My precious',
|
||||
description: 'Leave request employee`s comment',
|
||||
})
|
||||
comment: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'PENDING',
|
||||
enum: LeaveApprovalStatus,
|
||||
description: 'Leave request`s approval status',
|
||||
})
|
||||
approval_status: LeaveApprovalStatus;
|
||||
}
|
||||
|
|
@ -1,41 +1,62 @@
|
|||
import { Body, Controller, Delete, Get, Param, Patch, Post } from '@nestjs/common';
|
||||
import { Body, Controller, Delete, Get, Param, Patch, Post, UseGuards } from '@nestjs/common';
|
||||
import { OauthAccessTokensService } from '../services/oauth-access-tokens.service';
|
||||
import { CreateOauthAccessTokenDto } from '../dtos/create-oauth-access-token.dto';
|
||||
import { OAuthAccessTokens } from '@prisma/client';
|
||||
import { UpdateOauthAccessTokenDto } from '../dtos/update-oauth-access-token.dto';
|
||||
import { RolesAllowed } from "src/common/decorators/roles.decorators";
|
||||
import { Roles as RoleEnum } from '.prisma/client';
|
||||
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { JwtAuthGuard } from 'src/modules/authentication/guards/jwt-auth.guard';
|
||||
import { OAuthAccessTokenEntity } from '../dtos/swagger-entities/oauth-access-token.entity';
|
||||
|
||||
@ApiTags('OAuth Access Tokens')
|
||||
@ApiBearerAuth('access-token')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Controller('oauth-access-tokens')
|
||||
export class OauthAccessTokensController {
|
||||
constructor(private readonly oauthAccessTokensService: OauthAccessTokensService){}
|
||||
|
||||
@Post()
|
||||
@RolesAllowed(RoleEnum.ADMIN)
|
||||
@ApiOperation({summary: 'Create OAuth access token' })
|
||||
@ApiResponse({ status: 201, description: 'OAuth access token created', type: OAuthAccessTokenEntity })
|
||||
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
|
||||
create(@Body()dto: CreateOauthAccessTokenDto): Promise<OAuthAccessTokens> {
|
||||
return this.oauthAccessTokensService.create(dto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RolesAllowed(RoleEnum.ADMIN)
|
||||
@ApiOperation({summary: 'Find all OAuth access token' })
|
||||
@ApiResponse({ status: 201, description: 'List of OAuth access token found', type: OAuthAccessTokenEntity, isArray: true })
|
||||
@ApiResponse({ status: 400, description: 'List of OAuth access token not found' })
|
||||
findAll(): Promise<OAuthAccessTokens[]> {
|
||||
return this.oauthAccessTokensService.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RolesAllowed(RoleEnum.ADMIN)
|
||||
@ApiOperation({summary: 'Find OAuth access token' })
|
||||
@ApiResponse({ status: 201, description: 'OAuth access token found', type: OAuthAccessTokenEntity })
|
||||
@ApiResponse({ status: 400, description: 'OAuth access token not found' })
|
||||
findOne(@Param('id') id: string): Promise<OAuthAccessTokens> {
|
||||
return this.oauthAccessTokensService.findOne(id);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@RolesAllowed(RoleEnum.ADMIN)
|
||||
@ApiOperation({summary: 'Update OAuth access token' })
|
||||
@ApiResponse({ status: 201, description: 'OAuth access token updated', type: OAuthAccessTokenEntity })
|
||||
@ApiResponse({ status: 400, description: 'OAuth access token not found' })
|
||||
update(@Param('id') id: string, @Body() dto: UpdateOauthAccessTokenDto): Promise<OAuthAccessTokens> {
|
||||
return this.oauthAccessTokensService.update(id,dto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RolesAllowed(RoleEnum.ADMIN)
|
||||
@ApiOperation({summary: 'Delete OAuth access token' })
|
||||
@ApiResponse({ status: 201, description: 'OAuth access token deleted', type: OAuthAccessTokenEntity })
|
||||
@ApiResponse({ status: 400, description: 'OAuth access token not found' })
|
||||
remove(@Param('id') id: string): Promise<OAuthAccessTokens> {
|
||||
return this.oauthAccessTokensService.remove(id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,60 @@
|
|||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { Type } from "class-transformer";
|
||||
import { IsArray, IsDate, IsOptional, IsString, IsUUID } from "class-validator";
|
||||
|
||||
export class CreateOauthAccessTokenDto {
|
||||
|
||||
@ApiProperty({
|
||||
example: 'S7A2U8R7O6N6',
|
||||
description: 'User`s unique identification number',
|
||||
})
|
||||
@IsUUID()
|
||||
user_id: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'app.targo.ca',
|
||||
description: 'URL in which the access token is used for',
|
||||
})
|
||||
@IsString()
|
||||
application: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'L5O6R4D3/O6F3#T8H4E3&R6I4N6G4S7 ...',
|
||||
description: 'Access token',
|
||||
})
|
||||
@IsString()
|
||||
access_token: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'Th3731102h1p07Th3R1n92',
|
||||
description: 'Refresh token',
|
||||
})
|
||||
@IsString()
|
||||
refresh_token: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: '25/12/3018',
|
||||
description: 'Access token`s expiry date',
|
||||
})
|
||||
@Type(()=> Date)
|
||||
@IsDate()
|
||||
access_token_expiry: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: '26/02/3019',
|
||||
description: 'Refresh token`s expiry date',
|
||||
required: false,
|
||||
})
|
||||
@Type(()=> Date)
|
||||
@IsDate()
|
||||
@IsOptional()
|
||||
refresh_token_expiry?: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'access tolkiens, email, etc... ',
|
||||
description: 'scopes of infos linked to the access token',
|
||||
required: false,
|
||||
})
|
||||
@IsArray()
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class OAuthAccessTokenEntity {
|
||||
@ApiProperty({
|
||||
example: 'cklwi0vb70000z2z20q6f19qk',
|
||||
description: 'Unique ID of an OAuth token (auto-generated)',
|
||||
})
|
||||
id: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: '0e6e2e1f-b157-4c7c-ae3f-999b3e4f914d',
|
||||
description: 'UUID User`s unique identification number',
|
||||
})
|
||||
user_id: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'app.targo.ca',
|
||||
description: 'URL in which the access token is used for',
|
||||
})
|
||||
application: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'L5O6R4D3/O6F3#T8H4E3&R6I4N6G4S7',
|
||||
description: 'Access token',
|
||||
})
|
||||
access_token: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'Th3731102h1p07Th3R1n92',
|
||||
description: 'Refresh token',
|
||||
})
|
||||
refresh_token: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: '3018-12-25T00:00:00.000Z',
|
||||
description: 'Access token`s expiry date',
|
||||
})
|
||||
access_token_expiry: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: '3019-02-26T00:00:00.000Z',
|
||||
description: 'Refresh token`s expiry date (optional)',
|
||||
required: false,
|
||||
})
|
||||
refresh_token_expiry?: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: ['email', 'profile', 'access_tolkiens'],
|
||||
description: 'scopes of infos linked to the access token',
|
||||
required: false,
|
||||
})
|
||||
scopes: string[];
|
||||
|
||||
@ApiProperty({
|
||||
example: false,
|
||||
description: 'revoke status',
|
||||
})
|
||||
is_revoked: boolean;
|
||||
|
||||
@ApiProperty({
|
||||
example: '2025-07-22',
|
||||
description: 'creation date',
|
||||
})
|
||||
created_at: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: '2025-07-23',
|
||||
description: 'Latest update (optional)',
|
||||
required: false,
|
||||
})
|
||||
updated_at?: Date;
|
||||
}
|
||||
|
|
@ -1,35 +1,53 @@
|
|||
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from "@nestjs/common";
|
||||
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post, UseGuards } from "@nestjs/common";
|
||||
import { ShiftCodesService } from "../services/shift-codes.service";
|
||||
import { CreateShiftCodesDto } from "../dtos/create-shift-codes.dto";
|
||||
import { ShiftCodes } from "@prisma/client";
|
||||
import { UpdateShiftCodesDto } from "../dtos/update-shift-codes.dto";
|
||||
import { RolesAllowed } from "src/common/decorators/roles.decorators";
|
||||
import { Roles as RoleEnum } from '.prisma/client';
|
||||
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
|
||||
import { JwtAuthGuard } from "src/modules/authentication/guards/jwt-auth.guard";
|
||||
import { ShiftCodesEntity } from "../dtos/swagger-entities/shift-codes.entity";
|
||||
|
||||
@Controller()
|
||||
@ApiTags('Shift Codes')
|
||||
@ApiBearerAuth('access-token')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Controller('shift-codes')
|
||||
export class ShiftCodesController {
|
||||
constructor(private readonly shiftCodesService: ShiftCodesService) {}
|
||||
|
||||
@Post()
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR)
|
||||
@ApiOperation({ summary: 'Create shift code' })
|
||||
@ApiResponse({ status: 201, description: 'Shift code created',type: ShiftCodesEntity })
|
||||
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
|
||||
create(@Body()dto: CreateShiftCodesDto): Promise<ShiftCodes> {
|
||||
return this.shiftCodesService.create(dto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR)
|
||||
@ApiOperation({ summary: 'Find all shift codes' })
|
||||
@ApiResponse({ status: 201, description: 'List of shift codes found',type: ShiftCodesEntity, isArray: true })
|
||||
@ApiResponse({ status: 400, description: 'List of shift codes not found' })
|
||||
findAll(): Promise<ShiftCodes[]> {
|
||||
return this.shiftCodesService.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR)
|
||||
@ApiOperation({ summary: 'Find shift code' })
|
||||
@ApiResponse({ status: 201, description: 'Shift code found',type: ShiftCodesEntity })
|
||||
@ApiResponse({ status: 400, description: 'Shift code not found' })
|
||||
findOne(@Param('id', ParseIntPipe) id: number): Promise<ShiftCodes> {
|
||||
return this.shiftCodesService.findOne(id);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR)
|
||||
@ApiOperation({ summary: 'Update shift code' })
|
||||
@ApiResponse({ status: 201, description: 'Shift code updated',type: ShiftCodesEntity })
|
||||
@ApiResponse({ status: 400, description: 'Shift code not found' })
|
||||
update(@Param('id', ParseIntPipe) id: number,
|
||||
@Body() dto: UpdateShiftCodesDto): Promise<ShiftCodes> {
|
||||
return this.shiftCodesService.update(id,dto);
|
||||
|
|
@ -37,6 +55,9 @@ export class ShiftCodesController {
|
|||
|
||||
@Delete(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR)
|
||||
@ApiOperation({ summary: 'Delete shift code' })
|
||||
@ApiResponse({ status: 201, description: 'Shift code deleted',type: ShiftCodesEntity })
|
||||
@ApiResponse({ status: 400, description: 'Shift code not found' })
|
||||
remove(@Param('id', ParseIntPipe)id: number): Promise<ShiftCodes> {
|
||||
return this.shiftCodesService.remove(id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,20 @@
|
|||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { IsNotEmpty, IsString } from "class-validator";
|
||||
|
||||
export class CreateShiftCodesDto {
|
||||
|
||||
@ApiProperty({
|
||||
example: 'Regular or Night or Emergency, etc...',
|
||||
description: 'Type of shifts for an account perception',
|
||||
})
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
shift_type: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'G1, G2, G3, etc...',
|
||||
description: 'bank`s code related to the type of shift',
|
||||
})
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
bank_code: string;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class ShiftCodesEntity {
|
||||
@ApiProperty({
|
||||
example: 1,
|
||||
description: 'Unique ID of a shift-code (auto-generated)',
|
||||
})
|
||||
id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'Night',
|
||||
description: 'Type of shifts for an account perception',
|
||||
})
|
||||
shift_type: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'G2',
|
||||
description: 'bank`s code related to the type of shift',
|
||||
})
|
||||
bank_code: string;
|
||||
}
|
||||
|
|
@ -1,45 +1,62 @@
|
|||
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from "@nestjs/common";
|
||||
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post, UseGuards } from "@nestjs/common";
|
||||
import { ShiftsService } from "../services/shifts.service";
|
||||
import { Shifts } from "@prisma/client";
|
||||
import { CreateShiftDto } from "../dtos/create-shifts.dto";
|
||||
import { UpdateShiftsDto } from "../dtos/update-shifts.dto";
|
||||
import { RolesAllowed } from "src/common/decorators/roles.decorators";
|
||||
import { Roles as RoleEnum } from '.prisma/client';
|
||||
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger";
|
||||
import { JwtAuthGuard } from "src/modules/authentication/guards/jwt-auth.guard";
|
||||
import { ShiftEntity } from "../dtos/swagger-entities/shift.entity";
|
||||
|
||||
@ApiTags('Shifts')
|
||||
@ApiBearerAuth('access-token')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Controller('shifts')
|
||||
export class ShiftsController {
|
||||
constructor(private readonly shiftsService: ShiftsService){}
|
||||
|
||||
|
||||
@Post()
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({ summary: 'Create shift' })
|
||||
@ApiResponse({ status: 201, description: 'Shift created',type: ShiftEntity })
|
||||
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
|
||||
create(@Body() dto: CreateShiftDto): Promise<Shifts> {
|
||||
return this.shiftsService.create(dto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({ summary: 'Find all shifts' })
|
||||
@ApiResponse({ status: 201, description: 'List of shifts found',type: ShiftEntity, isArray: true })
|
||||
@ApiResponse({ status: 400, description: 'List of shifts not found' })
|
||||
findAll(): Promise<Shifts[]> {
|
||||
return this.shiftsService.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({ summary: 'Find shift' })
|
||||
@ApiResponse({ status: 201, description: 'Shift found',type: ShiftEntity })
|
||||
@ApiResponse({ status: 400, description: 'Shift not found' })
|
||||
findOne(@Param('id', ParseIntPipe) id: number): Promise<Shifts> {
|
||||
return this.shiftsService.findOne(id);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
update(
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@Body() dto: UpdateShiftsDto,
|
||||
): Promise<Shifts> {
|
||||
@ApiOperation({ summary: 'Update shift' })
|
||||
@ApiResponse({ status: 201, description: 'Shift updated',type: ShiftEntity })
|
||||
@ApiResponse({ status: 400, description: 'Shift not found' })
|
||||
update(@Param('id', ParseIntPipe) id: number,@Body() dto: UpdateShiftsDto): Promise<Shifts> {
|
||||
return this.shiftsService.update(id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({ summary: 'Delete shift' })
|
||||
@ApiResponse({ status: 201, description: 'Shift deleted',type: ShiftEntity })
|
||||
@ApiResponse({ status: 400, description: 'Shift not found' })
|
||||
remove(@Param('id', ParseIntPipe) id: number): Promise<Shifts> {
|
||||
return this.shiftsService.remove(id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,47 @@
|
|||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { Type } from "class-transformer";
|
||||
import { IsDate, IsDateString, IsInt } from "class-validator";
|
||||
|
||||
export class CreateShiftDto {
|
||||
|
||||
@ApiProperty({
|
||||
example: 'Th3F3110w5h1pX2024',
|
||||
description: 'ID number for a set timesheet',
|
||||
})
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
timesheet_id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: '0n3R1n962Ru13xX',
|
||||
description: 'ID number of a shift code (link with shift-codes)',
|
||||
})
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
shift_code_id: number;
|
||||
|
||||
|
||||
@ApiProperty({
|
||||
example: '20/10/3018',
|
||||
description: 'Date where the shift takes place',
|
||||
})
|
||||
@IsDateString()
|
||||
@Type(() => Date)
|
||||
@IsDate()
|
||||
date: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: '08:00',
|
||||
description: 'Start time of the said shift',
|
||||
})
|
||||
@IsDateString()
|
||||
@Type(() => Date)
|
||||
@IsDate()
|
||||
start_time: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: '17:00',
|
||||
description: 'End time of the said shift',
|
||||
})
|
||||
@IsDateString()
|
||||
@Type(() => Date)
|
||||
@IsDate()
|
||||
|
|
|
|||
39
src/modules/shifts/dtos/swagger-entities/shift.entity.ts
Normal file
39
src/modules/shifts/dtos/swagger-entities/shift.entity.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class ShiftEntity {
|
||||
@ApiProperty({
|
||||
example: 1,
|
||||
description: 'Unique ID of the shift (auto-generated)',
|
||||
})
|
||||
id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: 101,
|
||||
description: 'ID number for a set timesheet',
|
||||
})
|
||||
timesheet_id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: 7,
|
||||
description: 'ID number of a shift code (link with shift-codes)',
|
||||
})
|
||||
shift_code_id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: '3018-10-20T00:00:00.000Z',
|
||||
description: 'Date where the shift takes place',
|
||||
})
|
||||
date: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: '3018-10-20T08:00:00.000Z',
|
||||
description: 'Start time of the said shift',
|
||||
})
|
||||
start_time: Date;
|
||||
|
||||
@ApiProperty({
|
||||
example: '3018-10-20T17:00:00.000Z',
|
||||
description: 'End time of the said shift',
|
||||
})
|
||||
end_time: Date;
|
||||
}
|
||||
|
|
@ -1,35 +1,53 @@
|
|||
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from '@nestjs/common';
|
||||
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post, UseGuards } from '@nestjs/common';
|
||||
import { TimesheetsService } from '../services/timesheets.service';
|
||||
import { CreateTimesheetDto } from '../dtos/create-timesheet.dto';
|
||||
import { Timesheets } from '@prisma/client';
|
||||
import { UpdateTimesheetDto } from '../dtos/update-timesheet.dto';
|
||||
import { RolesAllowed } from "src/common/decorators/roles.decorators";
|
||||
import { Roles as RoleEnum } from '.prisma/client';
|
||||
import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import { JwtAuthGuard } from 'src/modules/authentication/guards/jwt-auth.guard';
|
||||
import { TimesheetEntity } from '../dtos/swagger-entities/timesheet.entity';
|
||||
|
||||
@ApiTags('Timesheets')
|
||||
@ApiBearerAuth('access-token')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Controller('timesheets')
|
||||
export class TimesheetsController {
|
||||
constructor(private readonly timesheetsService: TimesheetsService) {}
|
||||
|
||||
@Post()
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({ summary: 'Create timesheet' })
|
||||
@ApiResponse({ status: 201, description: 'Timesheet created', type: TimesheetEntity })
|
||||
@ApiResponse({ status: 400, description: 'Incomplete task or invalid data' })
|
||||
create(@Body() dto: CreateTimesheetDto): Promise<Timesheets> {
|
||||
return this.timesheetsService.create(dto);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({ summary: 'Find all timesheets' })
|
||||
@ApiResponse({ status: 201, description: 'List of timesheet found', type: TimesheetEntity, isArray: true })
|
||||
@ApiResponse({ status: 400, description: 'List of timesheets not found' })
|
||||
findAll(): Promise<Timesheets[]> {
|
||||
return this.timesheetsService.findAll();
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.EMPLOYEE, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({ summary: 'Find timesheet' })
|
||||
@ApiResponse({ status: 201, description: 'Timesheet found', type: TimesheetEntity })
|
||||
@ApiResponse({ status: 400, description: 'Timesheet not found' })
|
||||
findOne(@Param('id', ParseIntPipe) id: number): Promise<Timesheets> {
|
||||
return this.timesheetsService.findOne(id);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({ summary: 'Update timesheet' })
|
||||
@ApiResponse({ status: 201, description: 'Timesheet updated', type: TimesheetEntity })
|
||||
@ApiResponse({ status: 400, description: 'Timesheet not found' })
|
||||
update(
|
||||
@Param('id', ParseIntPipe) id:number,
|
||||
@Body() dto: UpdateTimesheetDto,
|
||||
|
|
@ -39,6 +57,9 @@ export class TimesheetsController {
|
|||
|
||||
@Delete(':id')
|
||||
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||
@ApiOperation({ summary: 'Delete timesheet' })
|
||||
@ApiResponse({ status: 201, description: 'Timesheet deleted', type: TimesheetEntity })
|
||||
@ApiResponse({ status: 400, description: 'Timesheet not found' })
|
||||
remove(@Param('id', ParseIntPipe) id: number): Promise<Timesheets> {
|
||||
return this.timesheetsService.remove(id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,21 @@
|
|||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { Type } from "class-transformer";
|
||||
import { IsBoolean, IsInt, IsOptional } from "class-validator";
|
||||
|
||||
export class CreateTimesheetDto {
|
||||
|
||||
@ApiProperty({
|
||||
example: '426433',
|
||||
description: 'employee`s ID number of linked timsheet',
|
||||
})
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
employee_id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'True or False or Pending or Denied or Cancelled or Escalated',
|
||||
description: 'Timesheet`s approval status',
|
||||
})
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
is_approved?: boolean;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class TimesheetEntity {
|
||||
@ApiProperty({
|
||||
example: 1,
|
||||
description: 'timesheet`s unique ID (auto-generated)',
|
||||
})
|
||||
id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: 426433,
|
||||
description: 'employee`s ID number of linked timsheet',
|
||||
})
|
||||
employee_id: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: true,
|
||||
description: 'Timesheet`s approval status',
|
||||
})
|
||||
is_approved: boolean;
|
||||
}
|
||||
48
src/modules/users-management/swagger-entities/user.entity.ts
Normal file
48
src/modules/users-management/swagger-entities/user.entity.ts
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Roles } from '@prisma/client';
|
||||
|
||||
export class UserEntity {
|
||||
@ApiProperty({
|
||||
example: 'd67f05be-6dd1-464f-b5f7-31b325e21b4a',
|
||||
description: 'User`s unique UUID (primary key)',
|
||||
})
|
||||
id: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'Aragorn',
|
||||
description: 'user`s first name',
|
||||
})
|
||||
first_name: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'Elessar',
|
||||
description: 'user`s last name',
|
||||
})
|
||||
last_name: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'king@arnor-gondor.gov',
|
||||
description: 'Unique email address',
|
||||
})
|
||||
email: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 5141234567,
|
||||
description: 'Unique phone number',
|
||||
})
|
||||
phone_number: number;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'Minas Tirith, Gondor',
|
||||
description: 'residence address (optional)',
|
||||
required: false,
|
||||
})
|
||||
residence?: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'EMPLOYEE',
|
||||
enum: Roles,
|
||||
description: 'User`s given role',
|
||||
})
|
||||
role: Roles;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user