Merge branch 'main' of git.targo.ca:Targo/targo_backend

This commit is contained in:
Nicolas Drolet 2025-12-03 17:00:42 -05:00
commit 7ee6773235
8 changed files with 44 additions and 24 deletions

View File

@ -0,0 +1,5 @@
-- CreateEnum
CREATE TYPE "modules" AS ENUM ('timesheets', 'timesheets_approval', 'employee_list', 'employee_management', 'personal_profile', 'dashboard');
-- AlterTable
ALTER TABLE "preferences" ALTER COLUMN "is_dark_mode" DROP NOT NULL;

View File

@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "employees" ALTER COLUMN "external_payroll_id" DROP DEFAULT;
DROP SEQUENCE "employees_external_payroll_id_seq";

View File

@ -53,7 +53,7 @@ model Employees {
supervisor Employees? @relation("EmployeeSupervisor", fields: [supervisor_id], references: [id]) supervisor Employees? @relation("EmployeeSupervisor", fields: [supervisor_id], references: [id])
supervisor_id Int? supervisor_id Int?
external_payroll_id Int @default(autoincrement()) external_payroll_id Int
company_code Int company_code Int
first_work_day DateTime @db.Date first_work_day DateTime @db.Date
last_work_day DateTime? @db.Date last_work_day DateTime? @db.Date
@ -347,12 +347,12 @@ model Preferences {
user Users @relation("UserPreferences", fields: [user_id], references: [id]) user Users @relation("UserPreferences", fields: [user_id], references: [id])
user_id String @unique @db.Uuid user_id String @unique @db.Uuid
notifications Boolean @default(true) notifications Boolean @default(true)
is_dark_mode Boolean? @default(false) is_dark_mode Boolean? @default(false)
display_language String @default("fr-FR") //'fr-FR' | 'en-CA'; display_language String @default("fr-FR") //'fr-FR' | 'en-CA';
is_lefty_mode Boolean @default(false) is_lefty_mode Boolean @default(false)
is_employee_list_grid Boolean @default(true) is_employee_list_grid Boolean @default(true)
is_timesheet_approval_grid Boolean @default(true) is_timesheet_approval_grid Boolean @default(true)
@@map("preferences") @@map("preferences")
} }

View File

@ -1,11 +1,11 @@
import { Controller, Get, Query, Body, Post, Patch } from "@nestjs/common"; import { Controller, Get, Query, Body, Post, Patch } from "@nestjs/common";
import { Modules as ModulesEnum } from ".prisma/client";
import { ModuleAccessAllowed } from "src/common/decorators/modules-guard.decorators";
import { Access } from "src/common/decorators/module-access.decorators"; import { Access } from "src/common/decorators/module-access.decorators";
import { Result } from "src/common/errors/result-error.factory"; import { Result } from "src/common/errors/result-error.factory";
import { EmployeeDetailedDto } from "src/identity-and-account/employees/dtos/employee-detailed.dto"; import { EmployeeDetailedDto } from "src/identity-and-account/employees/dtos/employee-detailed.dto";
import { EmployeeDto } from "src/identity-and-account/employees/dtos/employee.dto"; import { EmployeeDto } from "src/identity-and-account/employees/dtos/employee.dto";
import { EmployeesGetService } from "src/identity-and-account/employees/services/employees-get.service"; import { EmployeesGetService } from "src/identity-and-account/employees/services/employees-get.service";
import { ModuleAccessAllowed } from "src/common/decorators/modules-guard.decorators";
import { Modules as ModulesEnum } from ".prisma/client";
import { EmployeesCreateService } from "src/identity-and-account/employees/services/employees-create.service"; import { EmployeesCreateService } from "src/identity-and-account/employees/services/employees-create.service";
import { EmployeesUpdateService } from "src/identity-and-account/employees/services/employees-update.service"; import { EmployeesUpdateService } from "src/identity-and-account/employees/services/employees-update.service";

View File

@ -4,7 +4,7 @@ import { Type } from 'class-transformer';
export class EmployeeDetailedDto { export class EmployeeDetailedDto {
@IsString() @IsNotEmpty() first_name: string; @IsString() @IsNotEmpty() first_name: string;
@IsString() @IsNotEmpty() last_name: string; @IsString() @IsNotEmpty() last_name: string;
@IsString() employee_full_name: string; @IsString() @IsOptional() employee_full_name: string;
@IsString() @IsOptional() supervisor_full_name: string; @IsString() @IsOptional() supervisor_full_name: string;
@IsOptional() @IsBoolean() is_supervisor: boolean; @IsOptional() @IsBoolean() is_supervisor: boolean;
@IsString() company_name: string; @IsString() company_name: string;

View File

@ -14,6 +14,7 @@ export class EmployeesCreateService {
const normalized_access = toBooleanFromString(dto.user_module_access); const normalized_access = toBooleanFromString(dto.user_module_access);
const supervisor_id = await this.toIdFromFullName(dto.supervisor_full_name); const supervisor_id = await this.toIdFromFullName(dto.supervisor_full_name);
const company_code = toCompanyCodeFromString(dto.company_name) const company_code = toCompanyCodeFromString(dto.company_name)
await this.prisma.$transaction(async (tx) => { await this.prisma.$transaction(async (tx) => {
const user: Users = await tx.users.create({ const user: Users = await tx.users.create({
data: { data: {
@ -37,10 +38,10 @@ export class EmployeesCreateService {
return tx.employees.create({ return tx.employees.create({
data: { data: {
user_id: user.id, user_id: user.id,
external_payroll_id: dto.external_payroll_id,
company_code: company_code, company_code: company_code,
job_title: dto.job_title, job_title: dto.job_title,
first_work_day: dto.first_work_day, first_work_day: dto.first_work_day,
last_work_day: dto.last_work_day,
is_supervisor: dto.is_supervisor, is_supervisor: dto.is_supervisor,
supervisor_id: supervisor_id, supervisor_id: supervisor_id,
}, },

View File

@ -2,6 +2,7 @@ import { Injectable } from "@nestjs/common";
import { Result } from "src/common/errors/result-error.factory"; import { Result } from "src/common/errors/result-error.factory";
import { EmailToIdResolver } from "src/common/mappers/email-id.mapper"; import { EmailToIdResolver } from "src/common/mappers/email-id.mapper";
import { toBooleanFromString } from "src/common/mappers/module-access.mapper"; import { toBooleanFromString } from "src/common/mappers/module-access.mapper";
import { toDateFromString } from "src/common/utils/date-utils";
import { EmployeeDetailedDto } from "src/identity-and-account/employees/dtos/employee-detailed.dto"; import { EmployeeDetailedDto } from "src/identity-and-account/employees/dtos/employee-detailed.dto";
import { toCompanyCodeFromString } from "src/identity-and-account/employees/utils/employee.utils"; import { toCompanyCodeFromString } from "src/identity-and-account/employees/utils/employee.utils";
import { PrismaService } from "src/prisma/prisma.service"; import { PrismaService } from "src/prisma/prisma.service";
@ -13,8 +14,8 @@ export class EmployeesUpdateService {
private readonly emailResolver: EmailToIdResolver, private readonly emailResolver: EmailToIdResolver,
) { } ) { }
async updateEmployee(email: string, dto: EmployeeDetailedDto, employee_email?: string): Promise<Result<boolean, string>> { async updateEmployee(email: string, dto: EmployeeDetailedDto): Promise<Result<boolean, string>> {
const account_email = employee_email ?? email; const account_email = dto.email ?? email;
const user_id = await this.emailResolver.resolveUserIdWithEmail(account_email); const user_id = await this.emailResolver.resolveUserIdWithEmail(account_email);
if (!user_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND' } if (!user_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND' }
@ -31,16 +32,26 @@ export class EmployeesUpdateService {
email: dto.email, email: dto.email,
phone_number: dto.phone_number, phone_number: dto.phone_number,
residence: dto.residence, residence: dto.residence,
user_module_access: { },
update: { });
dashboard: normalized_access.dashboard, await tx.userModuleAccess.upsert({
employee_list: normalized_access.employee_list, where: { user_id: user_id.data },
employee_management: normalized_access.employee_management, update: {
personal_profile: normalized_access.personal_profile, dashboard: normalized_access.dashboard,
timesheets: normalized_access.timesheets, employee_list: normalized_access.employee_list,
timesheets_approval: normalized_access.timesheets_approval, employee_management: normalized_access.employee_management,
}, personal_profile: normalized_access.personal_profile,
}, timesheets: normalized_access.timesheets,
timesheets_approval: normalized_access.timesheets_approval,
},
create: {
user_id: user_id.data,
dashboard: normalized_access.dashboard,
employee_list: normalized_access.employee_list,
employee_management: normalized_access.employee_management,
personal_profile: normalized_access.personal_profile,
timesheets: normalized_access.timesheets,
timesheets_approval: normalized_access.timesheets_approval,
}, },
}); });
return tx.employees.update({ return tx.employees.update({
@ -48,7 +59,7 @@ export class EmployeesUpdateService {
data: { data: {
company_code: company_code, company_code: company_code,
job_title: dto.job_title, job_title: dto.job_title,
first_work_day: dto.first_work_day, first_work_day: toDateFromString(dto.first_work_day),
last_work_day: dto.last_work_day, last_work_day: dto.last_work_day,
is_supervisor: dto.is_supervisor, is_supervisor: dto.is_supervisor,
supervisor_id: supervisor_id, supervisor_id: supervisor_id,

View File

@ -8,7 +8,7 @@ export enum DisplayLanguage {
export class PreferencesDto { export class PreferencesDto {
@IsInt() id: number; @IsInt() id: number;
@IsBoolean() notifications: boolean; @IsBoolean() notifications: boolean;
@IsOptional() @IsBoolean() is_dark_mode?: boolean; @IsOptional() @IsBoolean() is_dark_mode?: boolean | null;
@IsEnum(DisplayLanguage) display_language: string; @IsEnum(DisplayLanguage) display_language: string;
@IsBoolean() is_lefty_mode: boolean; @IsBoolean() is_lefty_mode: boolean;
@IsBoolean() is_employee_list_grid: boolean; @IsBoolean() is_employee_list_grid: boolean;