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

This commit is contained in:
Nicolas Drolet 2025-12-12 13:33:31 -05:00
commit 01e407f803
9 changed files with 66 additions and 58 deletions

View File

@ -553,7 +553,7 @@
"required": true,
"in": "query",
"schema": {
"type": "boolean"
"type": "string"
}
},
{
@ -561,7 +561,7 @@
"required": true,
"in": "query",
"schema": {
"type": "boolean"
"type": "string"
}
},
{
@ -569,7 +569,7 @@
"required": true,
"in": "query",
"schema": {
"type": "boolean"
"type": "string"
}
},
{
@ -577,7 +577,7 @@
"required": true,
"in": "query",
"schema": {
"type": "boolean"
"type": "string"
}
},
{
@ -585,7 +585,7 @@
"required": true,
"in": "query",
"schema": {
"type": "boolean"
"type": "string"
}
},
{
@ -593,7 +593,7 @@
"required": true,
"in": "query",
"schema": {
"type": "boolean"
"type": "string"
}
},
{
@ -601,7 +601,7 @@
"required": true,
"in": "query",
"schema": {
"type": "boolean"
"type": "string"
}
},
{

View File

@ -1,3 +1,5 @@
export type Modules =
| 'timesheets'
| 'timesheets_approval'
@ -13,30 +15,4 @@ export const module_list = [
'employee_management',
'personal_profile',
'dashboard',
] as const;
const createDefaultModuleAccess = (): Record<Modules, boolean> =>
module_list.reduce((acc, mod) => {
acc[mod] = false;
return acc;
}, {} as Record<Modules, boolean>);
export const toBooleanFromString = (arr?: readonly string[] | null): Record<Modules, boolean> => {
const result = createDefaultModuleAccess();
if (!arr || !Array.isArray(arr)) return result;
for (const item of arr) {
if (typeof item !== 'string') continue;
const trimmed = item.trim();
if ((module_list as readonly string[]).includes(trimmed)) {
result[trimmed as Modules] = true;
}
}
return result;
}
export const toStringFromBoolean = (boolean_module_access: Record<Modules, boolean>): Modules[] => {
const access_array = Object.entries(boolean_module_access);
const allowed_accesses = access_array.filter(([_key, value]) => value === true);
return allowed_accesses.map(([key]) => key as Modules);
}
] as const;

View File

@ -0,0 +1,25 @@
export const createDefaultBooleanValue = <T extends PropertyKey>(keys_list: PropertyKey[]): Record<T, boolean> =>
keys_list.reduce((acc, mod) => {
acc[mod] = false;
return acc;
}, {} as Record<T, boolean>);
export const toBooleanFromKeys = <T extends PropertyKey>(keys_list: PropertyKey[], arr?: readonly PropertyKey[] | null): Record<T, boolean> => {
const result = createDefaultBooleanValue(keys_list);
if (!arr || !Array.isArray(arr)) return result;
for (const item of arr) {
if (typeof item !== 'string') continue;
const trimmed = item.trim();
if ((keys_list as readonly PropertyKey[]).includes(trimmed)) {
result[trimmed as T] = true;
}
}
return result;
}
export const toKeysFromBoolean = <T extends PropertyKey>(boolean_values: Record<T, boolean>): T[] => {
const values_array = Object.entries(boolean_values);
const values = values_array.filter(([_key, value]) => value === true);
return values.map(([key]) => key as T);
}

View File

@ -1,7 +1,8 @@
import { Injectable } from "@nestjs/common";
import { Users } from "@prisma/client";
import { Result } from "src/common/errors/result-error.factory";
import { toBooleanFromString } from "src/common/mappers/module-access.mapper";
import { Modules } from "src/common/mappers/module-access.mapper";
import { toBooleanFromKeys } from "src/common/utils/boolean-utils";
import { toDateFromString } from "src/common/utils/date-utils";
import { EmployeeDetailedDto } from "src/identity-and-account/employees/employee-detailed.dto";
import { toCompanyCodeFromString } from "src/identity-and-account/employees/employee.utils";
@ -12,7 +13,7 @@ export class EmployeesCreateService {
constructor(private readonly prisma: PrismaService) { }
async createEmployee(dto: EmployeeDetailedDto): Promise<Result<boolean, string>> {
const normalized_access = toBooleanFromString(dto.user_module_access);
const normalized_access = toBooleanFromKeys<Modules>(dto.user_module_access);
const supervisor_id = await this.toIdFromFullName(dto.supervisor_full_name);
const company_code = toCompanyCodeFromString(dto.company_name);
const first_work_day = toDateFromString(dto.first_work_day);

View File

@ -1,13 +1,14 @@
import { Injectable } from "@nestjs/common";
import { PrismaService } from "src/prisma/prisma.service";
import { Modules, toStringFromBoolean } from "src/common/mappers/module-access.mapper";
import { Modules } from "src/common/mappers/module-access.mapper";
import { EmailToIdResolver } from "src/common/mappers/email-id.mapper";
import { toStringFromDate } from "src/common/utils/date-utils";
import { Result } from "src/common/errors/result-error.factory";
import { toStringFromCompanyCode } from "src/identity-and-account/employees/employee.utils";
import { EmployeeDetailedDto } from "src/identity-and-account/employees/employee-detailed.dto";
import { toKeysFromBoolean } from "src/common/utils/boolean-utils";
@Injectable()
export class EmployeesGetService {
@ -59,6 +60,7 @@ export class EmployeesGetService {
last_work_day: r.last_work_day ? toStringFromDate(r.last_work_day) : null,
preset_id: r.schedule_preset_id ?? undefined,
})));
console.log('Employee_list', employee_list);
return { success: true, data: employee_list };
};
@ -174,7 +176,7 @@ export class EmployeesGetService {
let module_access_array: Modules[] = [];
if (employee.user.user_module_access) {
module_access_array = toStringFromBoolean(employee.user.user_module_access);
module_access_array = toKeysFromBoolean(employee.user.user_module_access);
}
const company_name = toStringFromCompanyCode(employee.company_code);

View File

@ -1,13 +1,14 @@
import { Injectable } from "@nestjs/common";
import { PrismaService } from "src/prisma/prisma.service";
import { toBooleanFromString } from "src/common/mappers/module-access.mapper";
import { Modules } from "src/common/mappers/module-access.mapper";
import { EmailToIdResolver } from "src/common/mappers/email-id.mapper";
import { toDateFromString } from "src/common/utils/date-utils";
import { Result } from "src/common/errors/result-error.factory";
import { toCompanyCodeFromString } from "src/identity-and-account/employees/employee.utils";
import { EmployeeDetailedDto } from "src/identity-and-account/employees/employee-detailed.dto";
import { toBooleanFromKeys } from "src/common/utils/boolean-utils";
@Injectable()
export class EmployeesUpdateService {
@ -22,7 +23,7 @@ export class EmployeesUpdateService {
const company_code = toCompanyCodeFromString(dto.company_name);
const supervisor_id = await this.toIdFromFullName(dto.supervisor_full_name);
const normalized_access = await toBooleanFromString(dto.user_module_access);
const normalized_access = toBooleanFromKeys<Modules>(dto.user_module_access);
const last_work_day = dto.last_work_day ? toDateFromString(dto.last_work_day) : null;
await this.prisma.$transaction(async (tx) => {

View File

@ -1,6 +1,6 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { Modules, Users } from '@prisma/client';
import { toStringFromBoolean } from 'src/common/mappers/module-access.mapper';
import { toKeysFromBoolean } from 'src/common/utils/boolean-utils';
import { PrismaService } from 'src/prisma/prisma.service';
@Injectable()
@ -29,7 +29,7 @@ export abstract class AbstractUserService {
}
let module_access: Modules[] = [];
if (user.user_module_access !== null) module_access = toStringFromBoolean(user.user_module_access);
if (user.user_module_access !== null) module_access = toKeysFromBoolean(user.user_module_access);
const clean_user = {
first_name: user.first_name,

View File

@ -11,31 +11,32 @@ export class CsvExportController {
@Get('csv/:year/:period_no')
@ModuleAccessAllowed(ModulesEnum.employee_management)
async exportCsv(
@Query('approved') approved: boolean,
@Query('shifts') shifts: boolean,
@Query('expenses') expenses: boolean,
@Query('holiday') holiday: boolean,
@Query('vacation') vacation: boolean,
@Query('targo') targo: boolean,
@Query('solucom') solucom: boolean,
@Query('approved') approved: string,
@Query('shifts') shifts: string,
@Query('expenses') expenses: string,
@Query('holiday') holiday: string,
@Query('vacation') vacation: string,
@Query('targo') targo: string,
@Query('solucom') solucom: string,
@Param('year') year: number,
@Param('period_no') period_no: number,
@Res() response: Response,
): Promise<void> {
console.log({ targo, solucom });
const rows = await this.csvService.collectTransaction(
year,
period_no,
{
approved: approved ?? false,
approved: approved === 'true',
types: {
shifts: shifts ?? false,
expenses: expenses ?? false,
holiday: holiday ?? false,
vacation: vacation ?? false,
shifts: shifts === 'true',
expenses: expenses === 'true',
holiday: holiday === 'true',
vacation: vacation === 'true',
},
companies: {
targo: targo ?? false,
solucom: solucom ?? false,
targo: targo === 'true',
solucom: solucom === 'true',
},
}
);

View File

@ -15,6 +15,7 @@ export class CsvExportService {
filters: Filters,
// approved: boolean = true
): Promise<CsvRow[]> {
console.log('data received: ', filters)
//fetch period
const period = await this.prisma.payPeriods.findFirst({
where: { pay_year: year, pay_period_no: period_no },
@ -25,7 +26,7 @@ export class CsvExportService {
const start = period.period_start;
const end = period.period_end;
//fetch company codes from .env
//fetch company codes
const company_codes = this.resolveCompanyCodes(filters.companies);
if (company_codes.length === 0) throw new BadRequestException('No company selected');
@ -272,9 +273,10 @@ export class CsvExportService {
out.push(code_no);
}
if (companies.solucom) {
const code_no = 251585;
const code_no = 271585;
out.push(code_no);
}
console.log('company codes = ', out);
return out;
}