feat(modules): CRUD for all modules

This commit is contained in:
Matthieu Haineault 2025-07-17 09:48:42 -04:00
parent 3d6bde36ae
commit fcf9635d53
18 changed files with 316 additions and 29 deletions

View File

@ -17,8 +17,7 @@ model Users {
id String @id @default(uuid()) id String @id @default(uuid())
first_name String first_name String
last_name String last_name String
email String @unique email String? @unique
password String
phone_number Int @unique phone_number Int @unique
residence String? residence String?
role Roles @default(GUEST) role Roles @default(GUEST)

View File

@ -0,0 +1,38 @@
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from '@nestjs/common';
import { CustomersService } from '../services/customers.service';
import { Customers, Employees } from '@prisma/client';
import { CreateCustomerDto } from '../dtos/create-customers';
import { UpdateCustomerDto } from '../dtos/update-customers';
@Controller('customers')
export class CustomersController {
constructor(private readonly customersService: CustomersService) {}
@Post()
create(@Body() dto: CreateCustomerDto): Promise<Customers> {
return this.customersService.create(dto);
}
@Get()
findAll(): Promise<Customers[]> {
return this.customersService.findAll();
}
@Get(':id')
findOne(@Param('id', ParseIntPipe) id: number): Promise<Customers> {
return this.customersService.findOne(id);
}
@Patch(':id')
update(
@Param('id', ParseIntPipe) id: number,
@Body() dto: UpdateCustomerDto,
): Promise<Customers> {
return this.customersService.update(id, dto);
}
@Delete(':id')
remove(@Param('id', ParseIntPipe) id: number): Promise<Customers>{
return this.customersService.remove(id);
}
}

View File

@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { CustomersController } from './controllers/customers.controller';
import { CustomersService } from './services/customers.service';
@Module({
controllers:[CustomersController],
providers:[CustomersService],
})
export class CustomersModule {}

View File

@ -0,0 +1,37 @@
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;
}

View File

@ -0,0 +1,4 @@
import { PartialType } from "@nestjs/swagger";
import { CreateCustomerDto } from "./create-customers";
export class UpdateCustomerDto extends PartialType(CreateCustomerDto) {}

View File

@ -0,0 +1,97 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { CreateCustomerDto } from '../dtos/create-customers';
import { Customers, Users } from '@prisma/client';
import { UpdateCustomerDto } from '../dtos/update-customers';
@Injectable()
export class CustomersService {
constructor(private readonly prisma: PrismaService) {}
async create(dto: CreateCustomerDto): Promise<Customers> {
const {
first_name,
last_name,
email,
phone_number,
residence,
invoice_id,
} = dto;
return this.prisma.$transaction(async (tx) => {
const user: Users = await tx.users.create({
data: {
first_name,
last_name,
email,
phone_number,
residence,
},
});
return tx.customers.create({
data: {
user_id: user.id,
invoice_id,
},
});
});
}
findAll(): Promise<Customers[]> {
return this.prisma.customers.findMany({
include: { user: true },
})
}
async findOne(id:number): Promise<Customers> {
const customer = await this.prisma.customers.findUnique({
where: { id },
include: { user: true },
});
if(!customer) {
throw new NotFoundException(`Customer #${id} not found`);
}
return customer;
}
async update(
id: number,
dto: UpdateCustomerDto,
): Promise<Customers> {
const customer = await this.findOne(id);
const {
first_name,
last_name,
email,
phone_number,
residence,
invoice_id,
} = dto;
return this.prisma.$transaction(async (tx) => {
await tx.users.update({
where: { id: customer.user_id },
data: {
...(first_name !== undefined && { first_name }),
...(last_name !== undefined && { last_name }),
...(email !== undefined && { email }),
...(phone_number !== undefined && { phone_number }),
...(residence !== undefined && { residence }),
},
});
return tx.customers.update({
where: { id },
data: {
...(invoice_id !== undefined && { invoice_id }),
},
});
});
}
async remove(id: number): Promise<Customers> {
await this.findOne(id);
return this.prisma.customers.delete({ where: { id }});
}
}

View File

@ -9,7 +9,6 @@ import {
IsString, IsString,
} from 'class-validator'; } from 'class-validator';
import { Type } from 'class-transformer'; import { Type } from 'class-transformer';
import { Roles } from '@prisma/client';
export class CreateEmployeeDto { export class CreateEmployeeDto {
@IsString() @IsString()
@ -21,12 +20,8 @@ export class CreateEmployeeDto {
last_name: string; last_name: string;
@IsEmail() @IsEmail()
@IsNotEmpty() @IsOptional()
email: string; email?: string;
@IsString()
@IsNotEmpty()
password: string;
@Type(() => Number) @Type(() => Number)
@IsInt() @IsInt()
@ -37,10 +32,6 @@ export class CreateEmployeeDto {
@IsOptional() @IsOptional()
residence?: string; residence?: string;
@IsString()
@IsNotEmpty()
role: Roles;
@IsInt() @IsInt()
@IsPositive() @IsPositive()
@Type(() => Number) @Type(() => Number)

View File

@ -1,6 +1,5 @@
import { Injectable, NotFoundException } from '@nestjs/common'; import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service'; import { PrismaService } from 'src/prisma/prisma.service';
import { UsersService } from 'src/modules/users-management/services/users.service';
import { CreateEmployeeDto } from '../dtos/create-employee.dto'; import { CreateEmployeeDto } from '../dtos/create-employee.dto';
import { UpdateEmployeeDto } from '../dtos/update-employee.dto'; import { UpdateEmployeeDto } from '../dtos/update-employee.dto';
import { Employees, Users } from '@prisma/client'; import { Employees, Users } from '@prisma/client';
@ -9,7 +8,6 @@ import { Employees, Users } from '@prisma/client';
export class EmployeesService { export class EmployeesService {
constructor( constructor(
private readonly prisma: PrismaService, private readonly prisma: PrismaService,
private readonly usersService: UsersService,
) {} ) {}
async create(dto: CreateEmployeeDto): Promise<Employees> { async create(dto: CreateEmployeeDto): Promise<Employees> {
@ -17,10 +15,8 @@ export class EmployeesService {
first_name, first_name,
last_name, last_name,
email, email,
password,
phone_number, phone_number,
residence, residence,
role,
external_payroll_id, external_payroll_id,
company_code, company_code,
first_work_day, first_work_day,
@ -33,10 +29,8 @@ export class EmployeesService {
first_name, first_name,
last_name, last_name,
email, email,
password,
phone_number, phone_number,
residence, residence,
role,
}, },
}); });
return tx.employees.create({ return tx.employees.create({
@ -68,22 +62,49 @@ export class EmployeesService {
return emp; return emp;
} }
async update( async update(
id: number, id: number,
dto: UpdateEmployeeDto, dto: UpdateEmployeeDto,
): Promise<Employees> { ): Promise<Employees> {
await this.findOne(id); const emp = await this.findOne(id);
return this.prisma.employees.update({
where: { id }, const {
data: { first_name,
external_payroll_id: dto.external_payroll_id, last_name,
company_code: dto.company_code, email,
first_work_day: dto.first_work_day, phone_number,
last_work_day: dto.last_work_day, residence,
}, external_payroll_id,
company_code,
first_work_day,
last_work_day,
} = dto;
return this.prisma.$transaction(async (tx) => {
await tx.users.update({
where: { id: emp.user_id },
data: {
...(first_name !== undefined && { first_name }),
...(last_name !== undefined && { last_name }),
...(email !== undefined && { email }),
...(phone_number !== undefined && { phone_number }),
...(residence !== undefined && { residence }),
},
});
return tx.employees.update({
where: { id },
data: {
...(external_payroll_id !== undefined && { external_payroll_id }),
...(company_code !== undefined && { company_code }),
...(first_work_day !== undefined && { first_work_day }),
...(last_work_day !== undefined && { last_work_day }),
},
});
}); });
} }
async remove(id: number): Promise<Employees> { async remove(id: number): Promise<Employees> {
await this.findOne(id); await this.findOne(id);
return this.prisma.employees.delete({ where: { id } }); return this.prisma.employees.delete({ where: { id } });

View File

@ -0,0 +1,3 @@
export class CreateLeaveRequestsDto {
}

View File

@ -0,0 +1,3 @@
export class UpdateLeaveRequestsDto {
}

View File

@ -0,0 +1,11 @@
import { IsNotEmpty, IsString } from "class-validator";
export class CreateShiftCodesDto {
@IsString()
@IsNotEmpty()
shift_type: string;
@IsString()
@IsNotEmpty()
bank_code: string;
}

View File

@ -0,0 +1,4 @@
import { PartialType } from '@nestjs/swagger';
import { CreateShiftCodesDto } from './create-shift-codes.dto';
export class UpdateShiftCodesDto extends PartialType(CreateShiftCodesDto) {}

View File

@ -0,0 +1,17 @@
import { Injectable } from "@nestjs/common";
import { PrismaService } from "src/prisma/prisma.service";
import { CreateShiftCodesDto } from "../dtos/create-shift-codes.dto";
import { ShiftCodes } from "@prisma/client";
@Injectable()
export class ShiftCodesService {
constructor(private readonly prisma: PrismaService) {}
create(dto: CreateShiftCodesDto): Promise<ShiftCodes> {
const {
shift_type,
bank_code,
} = dto;
return this.prisma.$queryRaw(dto)
}
}

View File

@ -0,0 +1,6 @@
import { Controller } from "@nestjs/common";
@Controller('shifts')
export class ShiftsController {
}

View File

@ -0,0 +1,19 @@
import { Type } from "class-transformer";
import { IsDate, IsDateString } from "class-validator";
export class CreateShiftDto {
@IsDateString()
@Type(() => Date)
@IsDate()
date: Date;
@IsDateString()
@Type(() => Date)
@IsDate()
start_time: Date;
@IsDateString()
@Type(() => Date)
@IsDate()
end_time: Date;
}

View File

@ -0,0 +1,4 @@
import { PartialType } from "@nestjs/swagger";
import { CreateShiftDto } from "./create-shifts.dto";
export class UpdateShiftsDto extends PartialType(CreateShiftDto){}

View File

@ -0,0 +1,14 @@
import { Injectable } from "@nestjs/common";
import { TimesheetsService } from "src/modules/timesheets/services/timesheets.service";
import { PrismaService } from "src/prisma/prisma.service";
import { CreateShiftDto } from "../dtos/create-shifts.dto";
import { Shifts } from "@prisma/client";
@Injectable()
export class ShiftsService {
constructor(
private readonly prisma: PrismaService,
private readonly timesheetsService: TimesheetsService,
) {}
}

View File

@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { ShiftsController } from './controllers/shifts.controller';
import { ShiftsService } from './services/shifts.service';
@Module({
controllers: [ShiftsController],
providers: [ShiftsService]
})
export class ShiftsModule {}