fix(Prisma): Fix prisma queries around the whole app to match new structure of many instance of clients/services files. added scripts to manage more than one schema at a time
This commit is contained in:
parent
a3bdd41648
commit
b269062816
3
prisma/mariadb/mariadb.client.ts
Normal file
3
prisma/mariadb/mariadb.client.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
|
||||||
|
export const mariadbClient = new PrismaClient();
|
||||||
|
|
@ -7,4 +7,4 @@ import { PrismaMariaDbService } from 'prisma/mariadb/prisma-mariadb.service';
|
||||||
providers: [PrismaMariaDbService],
|
providers: [PrismaMariaDbService],
|
||||||
exports: [PrismaMariaDbService],
|
exports: [PrismaMariaDbService],
|
||||||
})
|
})
|
||||||
export class PrismaPostgresModule {}
|
export class PrismaMariadbModule {}
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,20 @@ import { adapterMariaDb } from 'prisma.config.mariadb';
|
||||||
import { PrismaClient } from 'prisma/generated/mariadb/client';
|
import { PrismaClient } from 'prisma/generated/mariadb/client';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PrismaMariaDbService extends PrismaClient
|
export class PrismaMariaDbService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
|
||||||
implements OnModuleInit, OnModuleDestroy {
|
|
||||||
|
readonly client: PrismaClient;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super({ adapter: adapterMariaDb })
|
super({ adapter: adapterMariaDb }),
|
||||||
|
this.client = new PrismaClient({ adapter: adapterMariaDb });
|
||||||
}
|
}
|
||||||
|
|
||||||
async onModuleInit() {
|
async onModuleInit() {
|
||||||
await this.$connect();
|
await this.client.$connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
async onModuleDestroy() {
|
async onModuleDestroy() {
|
||||||
await this.$disconnect();
|
await this.client.$disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client"
|
provider = "prisma-client"
|
||||||
output = "../generated/mariadb"
|
output = "../node_modules/@prisma/client/mariadb"
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
# TARGO-BACKEND prisma
|
# TARGO-BACKEND prisma
|
||||||
|
|
||||||
|
# *******************************************************************************************************
|
||||||
|
# MAJOR PRISMA UPDATE 2026-02-04 => from 6.13 to 7.3. A lot has changed and this read me needs updating.|
|
||||||
|
# added functionnalities to manage many schema files with many instance of clients and services |
|
||||||
|
# added scripts to generate, migrate and manage one or many database at once |
|
||||||
|
# *******************************************************************************************************
|
||||||
|
|
||||||
Ce document court présente la configuration de Prisma et les conventions à respecter dans `prisma/schema.prisma`.
|
Ce document court présente la configuration de Prisma et les conventions à respecter dans `prisma/schema.prisma`.
|
||||||
<source> http://prisma.io/docs/orm/prisma-schema
|
<source> http://prisma.io/docs/orm/prisma-schema
|
||||||
|
|
||||||
|
|
|
||||||
11
prisma/postgres/postgres.client.ts
Normal file
11
prisma/postgres/postgres.client.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
import { PrismaPg } from '@prisma/adapter-pg';
|
||||||
|
import { Pool } from 'pg';
|
||||||
|
|
||||||
|
const pool = new Pool({
|
||||||
|
connectionString: process.env.DATABASE_URL_STAGING,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const postgresClient = new PrismaClient({
|
||||||
|
adapter: new PrismaPg(pool),
|
||||||
|
});
|
||||||
|
|
@ -1,19 +1,22 @@
|
||||||
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
||||||
|
import { PrismaClient } from '@prisma/client';
|
||||||
import { adapterPostgres } from 'prisma.config.postgres';
|
import { adapterPostgres } from 'prisma.config.postgres';
|
||||||
import { PrismaClient } from 'prisma/generated/postgres/client';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PrismaPostgresService extends PrismaClient
|
export class PrismaPostgresService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
|
||||||
implements OnModuleInit, OnModuleDestroy {
|
|
||||||
|
readonly client: PrismaClient;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super({ adapter: adapterPostgres })
|
super({ adapter: adapterPostgres }),
|
||||||
|
this.client = new PrismaClient({ adapter: adapterPostgres });
|
||||||
}
|
}
|
||||||
|
|
||||||
async onModuleInit() {
|
async onModuleInit() {
|
||||||
await this.$connect();
|
await this.client.$connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
async onModuleDestroy() {
|
async onModuleDestroy() {
|
||||||
await this.$disconnect();
|
await this.client.$disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client"
|
provider = "prisma-client"
|
||||||
output = "../generated/postgres"
|
output = "../node_modules/@prisma/client/postgres"
|
||||||
previewFeatures = ["views"]
|
previewFeatures = ["views"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
11
prisma/prisma-legacy/legacy.client.ts
Normal file
11
prisma/prisma-legacy/legacy.client.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
import { PrismaPg } from '@prisma/adapter-pg';
|
||||||
|
import { Pool } from 'pg';
|
||||||
|
|
||||||
|
const pool = new Pool({
|
||||||
|
connectionString: process.env.DATABASE_URL_MARIADB,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const legacyClient = new PrismaClient({
|
||||||
|
adapter: new PrismaPg(pool),
|
||||||
|
});
|
||||||
|
|
@ -7,4 +7,4 @@ import { PrismaLegacyService } from 'prisma/prisma-legacy/prisma-legacy.service'
|
||||||
providers: [PrismaLegacyService],
|
providers: [PrismaLegacyService],
|
||||||
exports: [PrismaLegacyService],
|
exports: [PrismaLegacyService],
|
||||||
})
|
})
|
||||||
export class PrismaPostgresModule {}
|
export class PrismaLegacyModule {}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,21 @@
|
||||||
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
||||||
|
import { PrismaClient } from '@prisma/client';
|
||||||
import { adapterLegacy } from 'prisma.config.legacy';
|
import { adapterLegacy } from 'prisma.config.legacy';
|
||||||
import { PrismaClient } from 'prisma/generated/legacy/client';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PrismaLegacyService extends PrismaClient
|
export class PrismaLegacyService implements OnModuleInit, OnModuleDestroy {
|
||||||
implements OnModuleInit, OnModuleDestroy {
|
|
||||||
|
readonly client: PrismaClient;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super({ adapter: adapterLegacy })
|
this.client = new PrismaClient({adapter: adapterLegacy })
|
||||||
}
|
}
|
||||||
|
|
||||||
async onModuleInit() {
|
async onModuleInit() {
|
||||||
await this.$connect();
|
await this.client.$connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
async onModuleDestroy() {
|
async onModuleDestroy() {
|
||||||
await this.$disconnect();
|
await this.client.$disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client"
|
provider = "prisma-client"
|
||||||
output = "../generated/legacy"
|
output = "../node_modules/@prisma/client/legacy"
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@ import { ValidationError } from 'class-validator';
|
||||||
import { TimeAndAttendanceModule } from 'src/time-and-attendance/time-and-attendance.module';
|
import { TimeAndAttendanceModule } from 'src/time-and-attendance/time-and-attendance.module';
|
||||||
import { AuthenticationModule } from 'src/identity-and-account/authentication/auth.module';
|
import { AuthenticationModule } from 'src/identity-and-account/authentication/auth.module';
|
||||||
import { IdentityAndAccountModule } from 'src/identity-and-account/identity-and-account.module';
|
import { IdentityAndAccountModule } from 'src/identity-and-account/identity-and-account.module';
|
||||||
import { PrismaLegacyModule } from 'src/prisma-legacy/prisma.module';
|
|
||||||
import { ChatbotModule } from 'src/chatbot/chatbot.module';
|
import { ChatbotModule } from 'src/chatbot/chatbot.module';
|
||||||
import { PrismaMariaDbService } from 'prisma/mariadb/prisma-mariadb.service';
|
import { PrismaMariadbModule } from 'prisma/mariadb/prisma-mariadb.module';
|
||||||
|
import { PrismaLegacyModule } from 'prisma/prisma-legacy/prisma-legacy.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
|
@ -22,7 +22,7 @@ import { PrismaMariaDbService } from 'prisma/mariadb/prisma-mariadb.service';
|
||||||
ScheduleModule.forRoot(), //cronjobs
|
ScheduleModule.forRoot(), //cronjobs
|
||||||
NotificationsModule,
|
NotificationsModule,
|
||||||
PrismaPostgresModule,
|
PrismaPostgresModule,
|
||||||
PrismaMariaDbService,
|
PrismaMariadbModule,
|
||||||
PrismaLegacyModule,
|
PrismaLegacyModule,
|
||||||
TimeAndAttendanceModule,
|
TimeAndAttendanceModule,
|
||||||
IdentityAndAccountModule,
|
IdentityAndAccountModule,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { NotFoundException } from "@nestjs/common";
|
import { NotFoundException } from "@nestjs/common";
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma, PrismaClient } from "@prisma/client";
|
||||||
import { PrismaClientKnownRequestError } from "@prisma/client/runtime/client";
|
import { PrismaClientKnownRequestError } from "@prisma/client/runtime/client";
|
||||||
import { PrismaPostgresService } from "prisma/postgres/prisma-postgres.service";
|
import { PrismaPostgresService } from "prisma/postgres/prisma-postgres.service";
|
||||||
|
|
||||||
|
|
@ -18,7 +18,7 @@ export abstract class BaseApprovalService<T> {
|
||||||
//returns the corresponding Prisma delegate
|
//returns the corresponding Prisma delegate
|
||||||
protected abstract get delegate(): UpdatableDelegate<T>;
|
protected abstract get delegate(): UpdatableDelegate<T>;
|
||||||
|
|
||||||
protected abstract delegateFor(tx: Prisma.TransactionClient): UpdatableDelegate<T>;
|
protected abstract delegateFor(tx: Prisma.TransactionClient | PrismaClient): UpdatableDelegate<T>;
|
||||||
|
|
||||||
//standard update Aproval
|
//standard update Aproval
|
||||||
async updateApproval(id: number, is_approved: boolean): Promise<T> {
|
async updateApproval(id: number, is_approved: boolean): Promise<T> {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env ts-node
|
#!/usr/bin/env ts-node
|
||||||
|
|
||||||
import { adapterMariaDb } from 'prisma.config.mariadb';
|
import { adapterMariaDb } from '../../../prisma.config.mariadb';
|
||||||
import { PrismaClient as MariaDbPrismaClient } from 'prisma/generated/mariadb/client';
|
import { PrismaClient as MariaDbPrismaClient } from 'prisma/generated/mariadb/client';
|
||||||
import { AccountService } from 'src/customer-support/accounts/account.service';
|
import { AccountService } from 'src/customer-support/accounts/account.service';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import { Strategy as OIDCStrategy, Profile, VerifyCallback } from 'passport-open
|
||||||
import { PassportStrategy } from '@nestjs/passport';
|
import { PassportStrategy } from '@nestjs/passport';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { AuthentikAuthService } from '../services/authentik-auth.service';
|
import { AuthentikAuthService } from '../services/authentik-auth.service';
|
||||||
import { ValidationError } from 'class-validator';
|
|
||||||
|
|
||||||
export interface AuthentikPayload {
|
export interface AuthentikPayload {
|
||||||
iss: string; // Issuer
|
iss: string; // Issuer
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
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 { Modules as ModulesEnum } from "@prisma/client";
|
||||||
import { ModuleAccessAllowed } from "src/common/decorators/modules-guard.decorators";
|
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";
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ export class EmployeesCreateService {
|
||||||
const company_code = toCompanyCodeFromString(dto.company_name);
|
const company_code = toCompanyCodeFromString(dto.company_name);
|
||||||
const first_work_day = toDateFromString(dto.first_work_day);
|
const first_work_day = toDateFromString(dto.first_work_day);
|
||||||
|
|
||||||
await this.prisma.$transaction(async (tx) => {
|
await this.prisma.client.$transaction(async (tx) => {
|
||||||
const user: Users = await tx.users.create({
|
const user: Users = await tx.users.create({
|
||||||
data: {
|
data: {
|
||||||
first_name: dto.first_name,
|
first_name: dto.first_name,
|
||||||
|
|
@ -56,7 +56,7 @@ export class EmployeesCreateService {
|
||||||
|
|
||||||
private toIdFromFullName = async (full_name: string) => {
|
private toIdFromFullName = async (full_name: string) => {
|
||||||
const [first_name, last_name] = full_name.split(' ', 2);
|
const [first_name, last_name] = full_name.split(' ', 2);
|
||||||
let supervisor = await this.prisma.users.findFirst({
|
let supervisor = await this.prisma.client.users.findFirst({
|
||||||
where: { first_name, last_name },
|
where: { first_name, last_name },
|
||||||
select: { employee: { select: { id: true } } }
|
select: { employee: { select: { id: true } } }
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ export class EmployeesGetService {
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
async findListEmployees(): Promise<Result<Partial<EmployeeDetailedDto>[], string>> {
|
async findListEmployees(): Promise<Result<Partial<EmployeeDetailedDto>[], string>> {
|
||||||
const employee_list = await this.prisma.employees.findMany({
|
const employee_list = await this.prisma.client.employees.findMany({
|
||||||
select: {
|
select: {
|
||||||
user: {
|
user: {
|
||||||
select: {
|
select: {
|
||||||
|
|
@ -71,7 +71,7 @@ export class EmployeesGetService {
|
||||||
const user_id = await this.emailResolver.resolveUserIdWithEmail(email);
|
const user_id = await this.emailResolver.resolveUserIdWithEmail(email);
|
||||||
if (!user_id.success) return { success: false, error: 'INVALID_USER' };
|
if (!user_id.success) return { success: false, error: 'INVALID_USER' };
|
||||||
|
|
||||||
const existing_profile = await this.prisma.employees.findUnique({
|
const existing_profile = await this.prisma.client.employees.findUnique({
|
||||||
where: { user_id: user_id.data },
|
where: { user_id: user_id.data },
|
||||||
select: {
|
select: {
|
||||||
user: {
|
user: {
|
||||||
|
|
@ -136,7 +136,7 @@ export class EmployeesGetService {
|
||||||
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: 'INVALID_USER' };
|
if (!user_id.success) return { success: false, error: 'INVALID_USER' };
|
||||||
|
|
||||||
const employee = await this.prisma.employees.findUnique({
|
const employee = await this.prisma.client.employees.findUnique({
|
||||||
where: { user_id: user_id.data },
|
where: { user_id: user_id.data },
|
||||||
select: {
|
select: {
|
||||||
user: {
|
user: {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ export class EmployeesUpdateService {
|
||||||
const user_id = await this.emailResolver.resolveUserIdWithEmail(dto.email);
|
const user_id = await this.emailResolver.resolveUserIdWithEmail(dto.email);
|
||||||
if (!user_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND'}
|
if (!user_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND'}
|
||||||
|
|
||||||
const employee = await this.prisma.employees.findFirst({
|
const employee = await this.prisma.client.employees.findFirst({
|
||||||
where: { user_id: user_id.data },
|
where: { user_id: user_id.data },
|
||||||
select: { id: true },
|
select: { id: true },
|
||||||
})
|
})
|
||||||
|
|
@ -32,7 +32,7 @@ export class EmployeesUpdateService {
|
||||||
const normalized_access = toBooleanFromString(dto.user_module_access);
|
const normalized_access = toBooleanFromString(dto.user_module_access);
|
||||||
const last_work_day = dto.last_work_day ? toDateFromString(dto.last_work_day) : null;
|
const last_work_day = dto.last_work_day ? toDateFromString(dto.last_work_day) : null;
|
||||||
|
|
||||||
await this.prisma.$transaction(async (tx) => {
|
await this.prisma.client.$transaction(async (tx) => {
|
||||||
await tx.users.update({
|
await tx.users.update({
|
||||||
where: { id: user_id.data },
|
where: { id: user_id.data },
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -109,7 +109,7 @@ export class EmployeesUpdateService {
|
||||||
|
|
||||||
private toIdFromFullName = async (full_name: string) => {
|
private toIdFromFullName = async (full_name: string) => {
|
||||||
const [first_name, last_name] = full_name.split(' ', 2);
|
const [first_name, last_name] = full_name.split(' ', 2);
|
||||||
let supervisor = await this.prisma.users.findFirst({
|
let supervisor = await this.prisma.client.users.findFirst({
|
||||||
where: { first_name, last_name },
|
where: { first_name, last_name },
|
||||||
select: { employee: { select: { id: true } } }
|
select: { employee: { select: { id: true } } }
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Controller, Get } from "@nestjs/common";
|
import { Controller, Get } from "@nestjs/common";
|
||||||
import { ModuleAccessAllowed } from "src/common/decorators/modules-guard.decorators";
|
import { ModuleAccessAllowed } from "src/common/decorators/modules-guard.decorators";
|
||||||
import { HomePageService } from "src/identity-and-account/help/help-page.service";
|
import { HomePageService } from "src/identity-and-account/help/help-page.service";
|
||||||
import { Modules as ModulesEnum } from ".prisma/client";
|
import { Modules as ModulesEnum } from "@prisma/client";
|
||||||
import { Access } from "src/common/decorators/module-access.decorators";
|
import { Access } from "src/common/decorators/module-access.decorators";
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ export class HomePageService {
|
||||||
const user_id = await this.emailresolver.resolveUserIdWithEmail(email);
|
const user_id = await this.emailresolver.resolveUserIdWithEmail(email);
|
||||||
if (!user_id.success) return { success: false, error: 'INVALID_EMAIL' };
|
if (!user_id.success) return { success: false, error: 'INVALID_EMAIL' };
|
||||||
|
|
||||||
const module_access = await this.prisma.userModuleAccess.findUnique({
|
const module_access = await this.prisma.client.userModuleAccess.findUnique({
|
||||||
where: { user_id: user_id.data },
|
where: { user_id: user_id.data },
|
||||||
select: {
|
select: {
|
||||||
dashboard: true,
|
dashboard: true,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { PreferencesDto } from "./preferences.dto";
|
||||||
import { Result } from "src/common/errors/result-error.factory";
|
import { Result } from "src/common/errors/result-error.factory";
|
||||||
import { Access } from "src/common/decorators/module-access.decorators";
|
import { Access } from "src/common/decorators/module-access.decorators";
|
||||||
import { ModuleAccessAllowed } from "src/common/decorators/modules-guard.decorators";
|
import { ModuleAccessAllowed } from "src/common/decorators/modules-guard.decorators";
|
||||||
import { Modules as ModulesEnum } from ".prisma/client";
|
import { Modules as ModulesEnum } from "@prisma/client";
|
||||||
|
|
||||||
@Controller('preferences')
|
@Controller('preferences')
|
||||||
export class PreferencesController {
|
export class PreferencesController {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export class PreferencesService {
|
||||||
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' };
|
||||||
|
|
||||||
const user_preferences = await this.prisma.preferences.findUnique({
|
const user_preferences = await this.prisma.client.preferences.findUnique({
|
||||||
where: { user_id: user_id.data },
|
where: { user_id: user_id.data },
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
|
|
@ -46,7 +46,7 @@ export class PreferencesService {
|
||||||
const user_id = await this.emailResolver.resolveUserIdWithEmail(email);
|
const user_id = await this.emailResolver.resolveUserIdWithEmail(email);
|
||||||
if (!user_id.success) return { success: false, error: user_id.error }
|
if (!user_id.success) return { success: false, error: user_id.error }
|
||||||
|
|
||||||
const updated_preferences: PreferencesDto = await this.prisma.preferences.update({
|
const updated_preferences: PreferencesDto = await this.prisma.client.preferences.update({
|
||||||
where: { user_id: user_id.data },
|
where: { user_id: user_id.data },
|
||||||
data: {
|
data: {
|
||||||
notifications: dto.notifications,
|
notifications: dto.notifications,
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ export class AccessGetService {
|
||||||
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' };
|
||||||
|
|
||||||
const access = await this.prisma.userModuleAccess.findUnique({
|
const access = await this.prisma.client.userModuleAccess.findUnique({
|
||||||
where: { user_id: user_id.data },
|
where: { user_id: user_id.data },
|
||||||
select: {
|
select: {
|
||||||
timesheets: true,
|
timesheets: true,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export class AccessUpdateService {
|
||||||
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' };
|
||||||
|
|
||||||
const orignal_access = await this.prisma.userModuleAccess.findUnique({
|
const orignal_access = await this.prisma.client.userModuleAccess.findUnique({
|
||||||
where: { user_id: user_id.data },
|
where: { user_id: user_id.data },
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
|
|
@ -30,7 +30,7 @@ export class AccessUpdateService {
|
||||||
});
|
});
|
||||||
if (!orignal_access) return { success: false, error: 'MODULE_ACCESS_NOT_FOUND' };
|
if (!orignal_access) return { success: false, error: 'MODULE_ACCESS_NOT_FOUND' };
|
||||||
|
|
||||||
const updated_access:ModuleAccess = await this.prisma.userModuleAccess.update({
|
const updated_access:ModuleAccess = await this.prisma.client.userModuleAccess.update({
|
||||||
where: { id: orignal_access.id },
|
where: { id: orignal_access.id },
|
||||||
data: {
|
data: {
|
||||||
timesheets: dto.timesheets,
|
timesheets: dto.timesheets,
|
||||||
|
|
@ -57,13 +57,13 @@ export class AccessUpdateService {
|
||||||
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' };
|
||||||
|
|
||||||
const access = await this.prisma.userModuleAccess.findUnique({
|
const access = await this.prisma.client.userModuleAccess.findUnique({
|
||||||
where: { user_id: user_id.data },
|
where: { user_id: user_id.data },
|
||||||
select: { id: true },
|
select: { id: true },
|
||||||
});
|
});
|
||||||
if (!access) return { success: false, error: 'MODULE_ACCESS_NOT_FOUND' };
|
if (!access) return { success: false, error: 'MODULE_ACCESS_NOT_FOUND' };
|
||||||
|
|
||||||
const revoked_access: ModuleAccess = await this.prisma.userModuleAccess.update({
|
const revoked_access: ModuleAccess = await this.prisma.client.userModuleAccess.update({
|
||||||
where: { id: access.id },
|
where: { id: access.id },
|
||||||
data: {
|
data: {
|
||||||
timesheets: false,
|
timesheets: false,
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export abstract class AbstractUserService {
|
||||||
constructor(protected readonly prisma: PrismaPostgresService) { }
|
constructor(protected readonly prisma: PrismaPostgresService) { }
|
||||||
|
|
||||||
async findOneByEmail(email: string): Promise<Partial<Users>> {
|
async findOneByEmail(email: string): Promise<Partial<Users>> {
|
||||||
const user = await this.prisma.users.findUnique({
|
const user = await this.prisma.client.users.findUnique({
|
||||||
where: { email },
|
where: { email },
|
||||||
include: {
|
include: {
|
||||||
user_module_access: {
|
user_module_access: {
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ import { ModulesGuard } from './common/guards/modules.guard';
|
||||||
// import { writeFileSync } from 'fs';
|
// import { writeFileSync } from 'fs';
|
||||||
import * as session from 'express-session';
|
import * as session from 'express-session';
|
||||||
import * as passport from 'passport';
|
import * as passport from 'passport';
|
||||||
import { PrismaPostgresService } from 'prisma/postgres/prisma-postgres.service';
|
|
||||||
import { PrismaSessionStore } from '@quixo3/prisma-session-store';
|
import { PrismaSessionStore } from '@quixo3/prisma-session-store';
|
||||||
|
import { PrismaPostgresService } from 'prisma/postgres/prisma-postgres.service';
|
||||||
// import { initSupervisor } from 'scripts/init-supervisor';
|
// import { initSupervisor } from 'scripts/init-supervisor';
|
||||||
// import { initializePaidTimeOff } from 'scripts/init-paid-time-off';
|
// import { initializePaidTimeOff } from 'scripts/init-paid-time-off';
|
||||||
// import { initializePreferences } from 'scripts/init-preferences-access';
|
// import { initializePreferences } from 'scripts/init-preferences-access';
|
||||||
|
|
@ -25,7 +25,7 @@ const SESSION_TOKEN_DURATION_MINUTES = 180
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
const prisma_service = app.get(PrismaPostgresService);
|
const prisma = app.get(PrismaPostgresService);
|
||||||
|
|
||||||
const reflector = app.get(Reflector);
|
const reflector = app.get(Reflector);
|
||||||
|
|
||||||
|
|
@ -44,7 +44,7 @@ async function bootstrap() {
|
||||||
maxAge: SESSION_TOKEN_DURATION_MINUTES * 60 * 1000, // property maxAge requires milliseconds
|
maxAge: SESSION_TOKEN_DURATION_MINUTES * 60 * 1000, // property maxAge requires milliseconds
|
||||||
httpOnly: true,
|
httpOnly: true,
|
||||||
},
|
},
|
||||||
store: new PrismaSessionStore(prisma_service, {
|
store: new PrismaSessionStore(prisma, {
|
||||||
sessionModelName: 'sessions',
|
sessionModelName: 'sessions',
|
||||||
checkPeriod: SESSION_TOKEN_DURATION_MINUTES * 60 * 1000, //ms
|
checkPeriod: SESSION_TOKEN_DURATION_MINUTES * 60 * 1000, //ms
|
||||||
dbRecordIdIsSessionId: true,
|
dbRecordIdIsSessionId: true,
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
import { Global, Module } from '@nestjs/common';
|
|
||||||
import { PrismaLegacyService } from './prisma.service';
|
|
||||||
|
|
||||||
@Global()
|
|
||||||
@Module({
|
|
||||||
providers: [PrismaLegacyService],
|
|
||||||
exports: [PrismaLegacyService],
|
|
||||||
})
|
|
||||||
export class PrismaLegacyModule {}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
|
||||||
import { PrismaClient as PrismaLegacyClient } from '@prisma/client';
|
|
||||||
|
|
||||||
//Gestion des connections à la DB
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class PrismaLegacyService
|
|
||||||
extends PrismaLegacyClient
|
|
||||||
implements OnModuleInit, OnModuleDestroy
|
|
||||||
{
|
|
||||||
async onModuleInit() {
|
|
||||||
await this.$connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
async onModuleDestroy() {
|
|
||||||
await this.$disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -35,7 +35,7 @@ export class AttachmentArchivalService {
|
||||||
|
|
||||||
//only moves table content to archive and not blobs.
|
//only moves table content to archive and not blobs.
|
||||||
private async archiveBatch(cutoff: Date, batch_size: number): Promise<number> {
|
private async archiveBatch(cutoff: Date, batch_size: number): Promise<number> {
|
||||||
const moved = await this.prisma.$executeRaw `
|
const moved = await this.prisma.client.$executeRaw `
|
||||||
WITH moved AS (
|
WITH moved AS (
|
||||||
DELETE FROM "attachments"
|
DELETE FROM "attachments"
|
||||||
WHERE id IN (
|
WHERE id IN (
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ export class AttachmentDeleteService {
|
||||||
constructor(private readonly prisma: PrismaPostgresService) { }
|
constructor(private readonly prisma: PrismaPostgresService) { }
|
||||||
|
|
||||||
async deleteAttachment(id: string): Promise<Result<boolean, string>> {
|
async deleteAttachment(id: string): Promise<Result<boolean, string>> {
|
||||||
await this.prisma.$transaction(async (tx) => {
|
await this.prisma.client.$transaction(async (tx) => {
|
||||||
const attachment = await tx.attachments.findUnique({ where: { id: Number(id) } });
|
const attachment = await tx.attachments.findUnique({ where: { id: Number(id) } });
|
||||||
if (!attachment) return { success: false, error: 'ATTACHMENT_NOT_FOUND' };
|
if (!attachment) return { success: false, error: 'ATTACHMENT_NOT_FOUND' };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ export class AttachmentGetService {
|
||||||
async getListVariants(id: string): Promise<Result<any, string>> {
|
async getListVariants(id: string): Promise<Result<any, string>> {
|
||||||
const num_id = Number(id);
|
const num_id = Number(id);
|
||||||
if (!Number.isFinite(num_id)) return { success: false, error: 'INVALID_ATTACHMENTS' };
|
if (!Number.isFinite(num_id)) return { success: false, error: 'INVALID_ATTACHMENTS' };
|
||||||
const variants = await this.prisma.attachmentVariants.findMany({
|
const variants = await this.prisma.client.attachmentVariants.findMany({
|
||||||
where: { attachment_id: num_id },
|
where: { attachment_id: num_id },
|
||||||
orderBy: { variant: 'asc' },
|
orderBy: { variant: 'asc' },
|
||||||
select: { variant: true, bytes: true, width: true, height: true, path: true, created_at: true },
|
select: { variant: true, bytes: true, width: true, height: true, path: true, created_at: true },
|
||||||
|
|
@ -43,8 +43,8 @@ export class AttachmentGetService {
|
||||||
const skip = (page - 1) * page_size;
|
const skip = (page - 1) * page_size;
|
||||||
const take = page_size;
|
const take = page_size;
|
||||||
|
|
||||||
const [items, total] = await this.prisma.$transaction([
|
const [items, total] = await this.prisma.client.$transaction([
|
||||||
this.prisma.attachments.findMany({
|
this.prisma.client.attachments.findMany({
|
||||||
where,
|
where,
|
||||||
orderBy: { created_at: 'desc' },
|
orderBy: { created_at: 'desc' },
|
||||||
skip, take,
|
skip, take,
|
||||||
|
|
@ -54,7 +54,7 @@ export class AttachmentGetService {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
this.prisma.attachments.count({ where }),
|
this.prisma.client.attachments.count({ where }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return { success: true, data: { page, page_size: take, total, items } };
|
return { success: true, data: { page, page_size: take, total, items } };
|
||||||
|
|
@ -65,7 +65,7 @@ export class AttachmentGetService {
|
||||||
const num_id = Number(id);
|
const num_id = Number(id);
|
||||||
if (!Number.isFinite(num_id)) return { success: false, error: 'INVALID_ATTACHMENTS' };
|
if (!Number.isFinite(num_id)) return { success: false, error: 'INVALID_ATTACHMENTS' };
|
||||||
|
|
||||||
const attachment = await this.prisma.attachments.findUnique({
|
const attachment = await this.prisma.client.attachments.findUnique({
|
||||||
where: { id: num_id },
|
where: { id: num_id },
|
||||||
include: { blob: true },
|
include: { blob: true },
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ export class AttachmentUploadService {
|
||||||
const { sha256, storage_path, size } = await this.disk.saveStreamAndHash(stream);
|
const { sha256, storage_path, size } = await this.disk.saveStreamAndHash(stream);
|
||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const attachment = await this.prisma.$transaction(async (tx) => {
|
const attachment = await this.prisma.client.$transaction(async (tx) => {
|
||||||
//upsert blob: +1 ref
|
//upsert blob: +1 ref
|
||||||
await tx.blobs.upsert({
|
await tx.blobs.upsert({
|
||||||
where: { sha256 },
|
where: { sha256 },
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ export class GarbargeCollectorService {
|
||||||
|
|
||||||
//Manage a single lot of orphan blobs
|
//Manage a single lot of orphan blobs
|
||||||
private async collectBatch(): Promise<number> {
|
private async collectBatch(): Promise<number> {
|
||||||
const blobs = await this.prisma.blobs.findMany({
|
const blobs = await this.prisma.client.blobs.findMany({
|
||||||
where: { refcount: { lte: 0 } },
|
where: { refcount: { lte: 0 } },
|
||||||
select: { sha256: true, storage_path: true },
|
select: { sha256: true, storage_path: true },
|
||||||
take: this.batch_size,
|
take: this.batch_size,
|
||||||
|
|
@ -67,7 +67,7 @@ export class GarbargeCollectorService {
|
||||||
);
|
);
|
||||||
//deletes blobs lignes if file is deleted
|
//deletes blobs lignes if file is deleted
|
||||||
const hashes = blobs.map(blob => blob.sha256);
|
const hashes = blobs.map(blob => blob.sha256);
|
||||||
await this.prisma.blobs.deleteMany({ where: { sha256: { in: hashes } } });
|
await this.prisma.client.blobs.deleteMany({ where: { sha256: { in: hashes } } });
|
||||||
return blobs.length;
|
return blobs.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ export class BankCodesService {
|
||||||
|
|
||||||
async create(dto: Prisma.BankCodesCreateInput): Promise<Result<boolean, string>> {
|
async create(dto: Prisma.BankCodesCreateInput): Promise<Result<boolean, string>> {
|
||||||
try {
|
try {
|
||||||
await this.prisma.bankCodes.create({
|
await this.prisma.client.bankCodes.create({
|
||||||
data: {
|
data: {
|
||||||
type: dto.type,
|
type: dto.type,
|
||||||
categorie: dto.categorie,
|
categorie: dto.categorie,
|
||||||
|
|
@ -24,12 +24,12 @@ export class BankCodesService {
|
||||||
}
|
}
|
||||||
|
|
||||||
findAll() {
|
findAll() {
|
||||||
return this.prisma.bankCodes.findMany();
|
return this.prisma.client.bankCodes.findMany();
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(id: number, dto: Prisma.BankCodesUpdateInput): Promise<Result<boolean, string>> {
|
async update(id: number, dto: Prisma.BankCodesUpdateInput): Promise<Result<boolean, string>> {
|
||||||
try {
|
try {
|
||||||
await this.prisma.bankCodes.update({
|
await this.prisma.client.bankCodes.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
data: {
|
data: {
|
||||||
type: dto.type,
|
type: dto.type,
|
||||||
|
|
@ -46,7 +46,7 @@ export class BankCodesService {
|
||||||
|
|
||||||
async delete(id: number): Promise<Result<boolean, string>> {
|
async delete(id: number): Promise<Result<boolean, string>> {
|
||||||
try {
|
try {
|
||||||
await this.prisma.bankCodes.delete({
|
await this.prisma.client.bankCodes.delete({
|
||||||
where: { id },
|
where: { id },
|
||||||
});
|
});
|
||||||
return { success: true, data: true };
|
return { success: true, data: true };
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ export class BankedHoursService {
|
||||||
if (asked_hours <= 0) return { success: false, error: 'INVALID_BANKING_HOURS' };
|
if (asked_hours <= 0) return { success: false, error: 'INVALID_BANKING_HOURS' };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await this.prisma.$transaction(async (tx) => {
|
const result = await this.prisma.client.$transaction(async (tx) => {
|
||||||
const employee = await this.prisma.employees.findUnique({
|
const employee = await this.prisma.client.employees.findUnique({
|
||||||
where: { id: employee_id },
|
where: { id: employee_id },
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ export class HolidayService {
|
||||||
const window_end = new Date(holiday_week_start.getTime() - 1);
|
const window_end = new Date(holiday_week_start.getTime() - 1);
|
||||||
|
|
||||||
const valid_codes = ['G1', 'G43', 'G56', 'G104', 'G105', 'G305', 'G700', 'G720'];
|
const valid_codes = ['G1', 'G43', 'G56', 'G104', 'G105', 'G305', 'G700', 'G720'];
|
||||||
const shifts = await this.prisma.shifts.findMany({
|
const shifts = await this.prisma.client.shifts.findMany({
|
||||||
where: {
|
where: {
|
||||||
timesheet: { employee_id: employee_id },
|
timesheet: { employee_id: employee_id },
|
||||||
date: { gte: window_start, lte: window_end },
|
date: { gte: window_start, lte: window_end },
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ export class MileageService {
|
||||||
if (amount < 0) return { success: false, error: 'The amount must be higher than 0' };
|
if (amount < 0) return { success: false, error: 'The amount must be higher than 0' };
|
||||||
|
|
||||||
//fetch modifier
|
//fetch modifier
|
||||||
const bank_code = await this.prisma.bankCodes.findUnique({
|
const bank_code = await this.prisma.client.bankCodes.findUnique({
|
||||||
where: { id: bank_code_id },
|
where: { id: bank_code_id },
|
||||||
select: { modifier: true, type: true },
|
select: { modifier: true, type: true },
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Prisma, PrismaClient } from 'prisma/generated/postgres/client';
|
import { Prisma, PrismaClient } from '@prisma/client';
|
||||||
import { getWeekStart, getWeekEnd, computeHours } from 'src/common/utils/date-utils';
|
import { getWeekStart, getWeekEnd, computeHours } from 'src/common/utils/date-utils';
|
||||||
import { PrismaPostgresService } from 'prisma/postgres/prisma-postgres.service';
|
import { PrismaPostgresService } from 'prisma/postgres/prisma-postgres.service';
|
||||||
import { DAILY_LIMIT_HOURS, WEEKLY_LIMIT_HOURS } from 'src/common/utils/constants.utils';
|
import { DAILY_LIMIT_HOURS, WEEKLY_LIMIT_HOURS } from 'src/common/utils/constants.utils';
|
||||||
|
|
@ -32,7 +32,7 @@ export class OvertimeService {
|
||||||
constructor(private prisma: PrismaPostgresService) { }
|
constructor(private prisma: PrismaPostgresService) { }
|
||||||
|
|
||||||
async getWeekOvertimeSummary(timesheet_id: number, date: Date, tx?: Tx): Promise<Result<WeekOvertimeSummary, string>> {
|
async getWeekOvertimeSummary(timesheet_id: number, date: Date, tx?: Tx): Promise<Result<WeekOvertimeSummary, string>> {
|
||||||
const db = (tx ?? this.prisma) as PrismaClient;
|
const db = (tx ?? this.prisma.client) as PrismaClient;
|
||||||
|
|
||||||
const week_start = getWeekStart(date);
|
const week_start = getWeekStart(date);
|
||||||
const week_end = getWeekEnd(week_start);
|
const week_end = getWeekEnd(week_start);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ export class SickLeaveService {
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
|
|
||||||
// get employee info
|
// get employee info
|
||||||
const employee = await this.prisma.employees.findUnique({
|
const employee = await this.prisma.client.employees.findUnique({
|
||||||
where: { id: employee_id },
|
where: { id: employee_id },
|
||||||
select: {
|
select: {
|
||||||
first_work_day: true,
|
first_work_day: true,
|
||||||
|
|
@ -32,9 +32,9 @@ export class SickLeaveService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get employee's PTO info, or create new details if not yet existing
|
// get employee's PTO info, or create new details if not yet existing
|
||||||
let pto_details: Prisma.Result<typeof this.prisma.paidTimeOff, Prisma.PaidTimeOffDefaultArgs, 'findUnique' | 'create'>;
|
let pto_details: Prisma.Result<typeof this.prisma.client.paidTimeOff, Prisma.PaidTimeOffDefaultArgs, 'findUnique' | 'create'>;
|
||||||
|
|
||||||
pto_details = await this.prisma.paidTimeOff.findUnique({
|
pto_details = await this.prisma.client.paidTimeOff.findUnique({
|
||||||
where: { employee_id: employee.id },
|
where: { employee_id: employee.id },
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -68,9 +68,9 @@ export class SickLeaveService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new PTO row
|
// create a new PTO row
|
||||||
async createNewPTORow(employee_id: number, today: Date): Promise<Result<Prisma.Result<typeof this.prisma.paidTimeOff, Prisma.PaidTimeOffDefaultArgs, 'findUnique' | 'create'>, string>> {
|
async createNewPTORow(employee_id: number, today: Date): Promise<Result<Prisma.Result<typeof this.prisma.client.paidTimeOff, Prisma.PaidTimeOffDefaultArgs, 'findUnique' | 'create'>, string>> {
|
||||||
try {
|
try {
|
||||||
const new_pto_entry = await this.prisma.paidTimeOff.create({
|
const new_pto_entry = await this.prisma.client.paidTimeOff.create({
|
||||||
data: {
|
data: {
|
||||||
employee_id: employee_id,
|
employee_id: employee_id,
|
||||||
last_updated: today,
|
last_updated: today,
|
||||||
|
|
@ -94,7 +94,7 @@ export class SickLeaveService {
|
||||||
// add n number of sick PTO hours to employee PTO
|
// add n number of sick PTO hours to employee PTO
|
||||||
async addHoursToPTO(sick_hours: number, employee_id: number, last_updated: Date) {
|
async addHoursToPTO(sick_hours: number, employee_id: number, last_updated: Date) {
|
||||||
try {
|
try {
|
||||||
const update_pto = await this.prisma.paidTimeOff.update({
|
const update_pto = await this.prisma.client.paidTimeOff.update({
|
||||||
where: {
|
where: {
|
||||||
employee_id,
|
employee_id,
|
||||||
},
|
},
|
||||||
|
|
@ -114,8 +114,8 @@ export class SickLeaveService {
|
||||||
if (asked_hours <= 0) return { success: false, error: 'INVALID_BANKING_HOURS' };
|
if (asked_hours <= 0) return { success: false, error: 'INVALID_BANKING_HOURS' };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await this.prisma.$transaction(async (tx) => {
|
const result = await this.prisma.client.$transaction(async (tx) => {
|
||||||
const employee = await this.prisma.employees.findUnique({
|
const employee = await this.prisma.client.employees.findUnique({
|
||||||
where: { id: employee_id },
|
where: { id: employee_id },
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
|
|
@ -176,7 +176,7 @@ export class SickLeaveService {
|
||||||
// const period_end = reference_date;
|
// const period_end = reference_date;
|
||||||
|
|
||||||
// //fetches all shifts of a selected employee
|
// //fetches all shifts of a selected employee
|
||||||
// const shifts = await this.prisma.shifts.findMany({
|
// const shifts = await this.prisma.client.shifts.findMany({
|
||||||
// where: {
|
// where: {
|
||||||
// timesheet: { employee_id: employee_id },
|
// timesheet: { employee_id: employee_id },
|
||||||
// date: { gte: period_start, lte: period_end },
|
// date: { gte: period_start, lte: period_end },
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export class VacationService {
|
||||||
if (!employee_id.success) return { success: false, error: employee_id.error }
|
if (!employee_id.success) return { success: false, error: employee_id.error }
|
||||||
|
|
||||||
//fetch hiring date
|
//fetch hiring date
|
||||||
const employee = await this.prisma.employees.findUnique({
|
const employee = await this.prisma.client.employees.findUnique({
|
||||||
where: { id: employee_id.data },
|
where: { id: employee_id.data },
|
||||||
select: { first_work_day: true },
|
select: { first_work_day: true },
|
||||||
});
|
});
|
||||||
|
|
@ -77,7 +77,7 @@ export class VacationService {
|
||||||
if (asked_hours <= 0) return { success: false, error: 'INVALID_VACATION_SHIFT' };
|
if (asked_hours <= 0) return { success: false, error: 'INVALID_VACATION_SHIFT' };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await this.prisma.$transaction(async (tx) => {
|
const result = await this.prisma.client.$transaction(async (tx) => {
|
||||||
//checks for remaining hours in vacation bank
|
//checks for remaining hours in vacation bank
|
||||||
const employee = await tx.employees.findUnique({
|
const employee = await tx.employees.findUnique({
|
||||||
where: { id: employee_id },
|
where: { id: employee_id },
|
||||||
|
|
|
||||||
|
|
@ -37,14 +37,14 @@ export class ExpenseCreateService {
|
||||||
//finds the timesheet using expense.date by finding the sunday
|
//finds the timesheet using expense.date by finding the sunday
|
||||||
const start_date = weekStartSunday(normed_expense.data.date);
|
const start_date = weekStartSunday(normed_expense.data.date);
|
||||||
|
|
||||||
const timesheet = await this.prisma.timesheets.findFirst({
|
const timesheet = await this.prisma.client.timesheets.findFirst({
|
||||||
where: { start_date, employee_id: employee_id.data },
|
where: { start_date, employee_id: employee_id.data },
|
||||||
select: { id: true, employee_id: true },
|
select: { id: true, employee_id: true },
|
||||||
});
|
});
|
||||||
if (!timesheet) return { success: false, error: `TIMESHEET_NOT_FOUND` };
|
if (!timesheet) return { success: false, error: `TIMESHEET_NOT_FOUND` };
|
||||||
|
|
||||||
//create a new expense
|
//create a new expense
|
||||||
const expense = await this.prisma.expenses.create({
|
const expense = await this.prisma.client.expenses.create({
|
||||||
data: {
|
data: {
|
||||||
...normed_expense.data,
|
...normed_expense.data,
|
||||||
bank_code_id: type.data,
|
bank_code_id: type.data,
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ export class ExpenseDeleteService {
|
||||||
if (!employee.success) return employee;
|
if (!employee.success) return employee;
|
||||||
|
|
||||||
// confirm ownership of expense to employee who made request
|
// confirm ownership of expense to employee who made request
|
||||||
const expense = await this.prisma.expenses.findUnique({
|
const expense = await this.prisma.client.expenses.findUnique({
|
||||||
where: { id: expense_id},
|
where: { id: expense_id},
|
||||||
select: {
|
select: {
|
||||||
timesheet: {
|
timesheet: {
|
||||||
|
|
@ -36,7 +36,7 @@ export class ExpenseDeleteService {
|
||||||
if (!expense || expense.timesheet.employee_id !== employee.data) return { success: false, error: 'EXPENSE_NOT_FOUND'};
|
if (!expense || expense.timesheet.employee_id !== employee.data) return { success: false, error: 'EXPENSE_NOT_FOUND'};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.prisma.$transaction(async (tx) => {
|
await this.prisma.client.$transaction(async (tx) => {
|
||||||
const expense = await tx.expenses.findUnique({
|
const expense = await tx.expenses.findUnique({
|
||||||
where: { id: expense_id },
|
where: { id: expense_id },
|
||||||
select: { id: true },
|
select: { id: true },
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ export class ExpenseUpdateService {
|
||||||
//added timesheet_id modification check according to the new date
|
//added timesheet_id modification check according to the new date
|
||||||
const new_timesheet_start_date = weekStartSunday(toDateFromString(dto.date));
|
const new_timesheet_start_date = weekStartSunday(toDateFromString(dto.date));
|
||||||
|
|
||||||
const timesheet = await this.prisma.timesheets.findFirst({
|
const timesheet = await this.prisma.client.timesheets.findFirst({
|
||||||
where: { start_date: new_timesheet_start_date, employee_id: employee_id.data },
|
where: { start_date: new_timesheet_start_date, employee_id: employee_id.data },
|
||||||
select: timesheet_select,
|
select: timesheet_select,
|
||||||
});
|
});
|
||||||
|
|
@ -44,13 +44,13 @@ export class ExpenseUpdateService {
|
||||||
//checks for modifications
|
//checks for modifications
|
||||||
const data = {
|
const data = {
|
||||||
...normed_expense.data,
|
...normed_expense.data,
|
||||||
bank_code: { connect: { id: type.data } },
|
bank_code_id: type.data,
|
||||||
is_approved: dto.is_approved,
|
is_approved: dto.is_approved,
|
||||||
};
|
};
|
||||||
if (!data) return { success: false, error: `INVALID_EXPENSE` }
|
if (!data) return { success: false, error: `INVALID_EXPENSE` }
|
||||||
|
|
||||||
//push updates and get updated datas
|
//push updates and get updated datas
|
||||||
const expense = await this.prisma.expenses.update({
|
const expense = await this.prisma.client.expenses.update({
|
||||||
where: { id: dto.id, timesheet_id: timesheet.id },
|
where: { id: dto.id, timesheet_id: timesheet.id },
|
||||||
data,
|
data,
|
||||||
select: expense_select,
|
select: expense_select,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Controller, Get, Param, Query, Res } from "@nestjs/common";
|
import { Controller, Get, Param, Query, Res } from "@nestjs/common";
|
||||||
import { CsvExportService } from "./services/csv-exports.service";
|
import { CsvExportService } from "./services/csv-exports.service";
|
||||||
import { ModuleAccessAllowed } from "src/common/decorators/modules-guard.decorators";
|
import { ModuleAccessAllowed } from "src/common/decorators/modules-guard.decorators";
|
||||||
import { Modules as ModulesEnum } from "prisma/generated/postgres/client";
|
import { Modules as ModulesEnum } from "@prisma/client";
|
||||||
import { Response } from "express";
|
import { Response } from "express";
|
||||||
import { CsvGeneratorService } from "src/time-and-attendance/exports/services/csv-builder.service";
|
import { CsvGeneratorService } from "src/time-and-attendance/exports/services/csv-builder.service";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ export class CsvExportService {
|
||||||
// approved: boolean = true
|
// approved: boolean = true
|
||||||
): Promise<CsvRow[]> {
|
): Promise<CsvRow[]> {
|
||||||
//fetch period
|
//fetch period
|
||||||
const period = await this.prisma.payPeriods.findFirst({
|
const period = await this.prisma.client.payPeriods.findFirst({
|
||||||
where: { pay_year: year, pay_period_no: period_no },
|
where: { pay_year: year, pay_period_no: period_no },
|
||||||
select: { period_start: true, period_end: true },
|
select: { period_start: true, period_end: true },
|
||||||
});
|
});
|
||||||
|
|
@ -50,7 +50,7 @@ export class CsvExportService {
|
||||||
const promises: Array<Promise<any[]>> = [];
|
const promises: Array<Promise<any[]>> = [];
|
||||||
|
|
||||||
if (want_shifts) {
|
if (want_shifts) {
|
||||||
promises.push(this.prisma.shifts.findMany({
|
promises.push(this.prisma.client.shifts.findMany({
|
||||||
where: {
|
where: {
|
||||||
date: { gte: start, lte: end },
|
date: { gte: start, lte: end },
|
||||||
...approved_filter,
|
...approved_filter,
|
||||||
|
|
@ -81,7 +81,7 @@ export class CsvExportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (want_holiday) {
|
if (want_holiday) {
|
||||||
promises.push(this.prisma.shifts.findMany({
|
promises.push(this.prisma.client.shifts.findMany({
|
||||||
where: {
|
where: {
|
||||||
date: { gte: start, lte: end },
|
date: { gte: start, lte: end },
|
||||||
...approved_filter,
|
...approved_filter,
|
||||||
|
|
@ -112,7 +112,7 @@ export class CsvExportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (want_vacation) {
|
if (want_vacation) {
|
||||||
promises.push(this.prisma.shifts.findMany({
|
promises.push(this.prisma.client.shifts.findMany({
|
||||||
where: {
|
where: {
|
||||||
date: { gte: start, lte: end },
|
date: { gte: start, lte: end },
|
||||||
...approved_filter,
|
...approved_filter,
|
||||||
|
|
@ -143,7 +143,7 @@ export class CsvExportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (want_expense) {
|
if (want_expense) {
|
||||||
promises.push(this.prisma.expenses.findMany({
|
promises.push(this.prisma.client.expenses.findMany({
|
||||||
where: {
|
where: {
|
||||||
date: { gte: start, lte: end },
|
date: { gte: start, lte: end },
|
||||||
...approved_filter,
|
...approved_filter,
|
||||||
|
|
@ -244,7 +244,7 @@ export class CsvExportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveHolidayTypeCode = async (holiday: string): Promise<string> => {
|
resolveHolidayTypeCode = async (holiday: string): Promise<string> => {
|
||||||
const holiday_code = await this.prisma.bankCodes.findFirst({
|
const holiday_code = await this.prisma.client.bankCodes.findFirst({
|
||||||
where: { type: holiday },
|
where: { type: holiday },
|
||||||
select: {
|
select: {
|
||||||
bank_code: true,
|
bank_code: true,
|
||||||
|
|
@ -261,7 +261,7 @@ export class CsvExportService {
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveVacationTypeCode = async (vacation: string): Promise<string> => {
|
resolveVacationTypeCode = async (vacation: string): Promise<string> => {
|
||||||
const vacation_code = await this.prisma.bankCodes.findFirst({
|
const vacation_code = await this.prisma.client.bankCodes.findFirst({
|
||||||
where: { type: vacation },
|
where: { type: vacation },
|
||||||
select: {
|
select: {
|
||||||
bank_code: true,
|
bank_code: true,
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,43 @@
|
||||||
import { IsEmail, IsArray, IsOptional, IsString, IsNumber, IsEnum, IsDateString } from "class-validator";
|
// import { IsEmail, IsArray, IsOptional, IsString, IsNumber, IsEnum, IsDateString } from "class-validator";
|
||||||
import { LeaveApprovalStatus, LeaveTypes } from "prisma/generated/postgres/client";
|
// import { LeaveApprovalStatus, LeaveTypes } from "prisma/generated/postgres/client";
|
||||||
import { Type } from "class-transformer";
|
// import { Type } from "class-transformer";
|
||||||
|
|
||||||
//sets wich types to use
|
// //sets wich types to use
|
||||||
export const REQUEST_TYPES = Object.values(LeaveTypes) as readonly LeaveTypes[];
|
// export const REQUEST_TYPES = Object.values(LeaveTypes) as readonly LeaveTypes[];
|
||||||
export type RequestTypes = (typeof REQUEST_TYPES)[number];
|
// export type RequestTypes = (typeof REQUEST_TYPES)[number];
|
||||||
|
|
||||||
export class LeaveRequestDto {
|
// export class LeaveRequestDto {
|
||||||
@IsEmail() @IsString()
|
// @IsEmail() @IsString()
|
||||||
email!: string;
|
// email!: string;
|
||||||
|
|
||||||
@IsArray()
|
// @IsArray()
|
||||||
@IsDateString()
|
// @IsDateString()
|
||||||
dates!: string[];
|
// dates!: string[];
|
||||||
|
|
||||||
@IsEnum(LeaveTypes)
|
// @IsEnum(LeaveTypes)
|
||||||
type!: string;
|
// type!: string;
|
||||||
|
|
||||||
@IsString()
|
// @IsString()
|
||||||
comment!: string;
|
// comment!: string;
|
||||||
|
|
||||||
@IsOptional()
|
// @IsOptional()
|
||||||
@Type(() => Number)
|
// @Type(() => Number)
|
||||||
@IsNumber({ maxDecimalPlaces: 2 })
|
// @IsNumber({ maxDecimalPlaces: 2 })
|
||||||
requested_hours?: number;
|
// requested_hours?: number;
|
||||||
|
|
||||||
@IsEnum(LeaveApprovalStatus)
|
// @IsEnum(LeaveApprovalStatus)
|
||||||
approval_status?: LeaveApprovalStatus
|
// approval_status?: LeaveApprovalStatus
|
||||||
}
|
// }
|
||||||
|
|
||||||
export class LeaveRequestViewDto {
|
// export class LeaveRequestViewDto {
|
||||||
id: number;
|
// id: number;
|
||||||
leave_type!: LeaveTypes;
|
// leave_type!: LeaveTypes;
|
||||||
date!: string;
|
// date!: string;
|
||||||
comment!: string;
|
// comment!: string;
|
||||||
approval_status: LeaveApprovalStatus;
|
// approval_status: LeaveApprovalStatus;
|
||||||
email!: string;
|
// email!: string;
|
||||||
employee_full_name!: string;
|
// employee_full_name!: string;
|
||||||
payable_hours?: number;
|
// payable_hours?: number;
|
||||||
requested_hours?: number;
|
// requested_hours?: number;
|
||||||
action?: 'create' | 'update' | 'delete';
|
// action?: 'create' | 'update' | 'delete';
|
||||||
}
|
// }
|
||||||
|
|
@ -1,24 +1,23 @@
|
||||||
|
// import { Prisma } from "@prisma/client";
|
||||||
|
// import { LeaveRequestViewDto } from "src/time-and-attendance/leave-requests/leave-request.dto";
|
||||||
|
// import { LeaveRequestArchiveRow } from "src/time-and-attendance/leave-requests/utils/leave-requests-archive.select";
|
||||||
|
|
||||||
import { Prisma } from "prisma/generated/postgres/client";
|
// const toNum = (value?: Prisma.Decimal | null) => value ? Number(value) : undefined;
|
||||||
import { LeaveRequestViewDto } from "src/time-and-attendance/leave-requests/leave-request.dto";
|
|
||||||
import { LeaveRequestArchiveRow } from "src/time-and-attendance/leave-requests/utils/leave-requests-archive.select";
|
|
||||||
|
|
||||||
const toNum = (value?: Prisma.Decimal | null) => value ? Number(value) : undefined;
|
// export function mapArchiveRowToView(row: LeaveRequestArchiveRow, email: string, employee_full_name:string): LeaveRequestViewDto {
|
||||||
|
// const isoDate = row.date?.toISOString().slice(0, 10);
|
||||||
export function mapArchiveRowToView(row: LeaveRequestArchiveRow, email: string, employee_full_name:string): LeaveRequestViewDto {
|
// if (!isoDate) {
|
||||||
const isoDate = row.date?.toISOString().slice(0, 10);
|
// throw new Error(`Leave request #${row.id} has no date set.`);
|
||||||
if (!isoDate) {
|
// }
|
||||||
throw new Error(`Leave request #${row.id} has no date set.`);
|
// return {
|
||||||
}
|
// id: row.id,
|
||||||
return {
|
// leave_type: row.leave_type,
|
||||||
id: row.id,
|
// date: isoDate,
|
||||||
leave_type: row.leave_type,
|
// payable_hours: toNum(row.payable_hours),
|
||||||
date: isoDate,
|
// requested_hours: toNum(row.requested_hours),
|
||||||
payable_hours: toNum(row.payable_hours),
|
// comment: row.comment,
|
||||||
requested_hours: toNum(row.requested_hours),
|
// approval_status: row.approval_status,
|
||||||
comment: row.comment,
|
// email,
|
||||||
approval_status: row.approval_status,
|
// employee_full_name,
|
||||||
email,
|
// }
|
||||||
employee_full_name,
|
// }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +1,28 @@
|
||||||
import { Body, Controller, Delete, Patch, Post, Req } from "@nestjs/common";
|
// import { Body, Controller, Delete, Patch, Post, Req } from "@nestjs/common";
|
||||||
// import { LeaveRequestDto } from "../dtos/leave-request.dto";
|
// // import { LeaveRequestDto } from "../dtos/leave-request.dto";
|
||||||
import { LeaveRequestsService } from "src/time-and-attendance/leave-requests/services/leave-request.service";
|
// import { LeaveRequestsService } from "src/time-and-attendance/leave-requests/services/leave-request.service";
|
||||||
|
|
||||||
@Controller('leave-requests')
|
// @Controller('leave-requests')
|
||||||
export class LeaveRequestController {
|
// export class LeaveRequestController {
|
||||||
constructor(private readonly leave_service: LeaveRequestsService) { }
|
// constructor(private readonly leave_service: LeaveRequestsService) { }
|
||||||
|
|
||||||
// @Post('create')
|
// // @Post('create')
|
||||||
// async create(@Req() req, @Body() dto: LeaveRequestDto) {
|
// // async create(@Req() req, @Body() dto: LeaveRequestDto) {
|
||||||
// const email = req.user?.email;
|
// // const email = req.user?.email;
|
||||||
// return await this.leave_service.create(email, dto);
|
// // return await this.leave_service.create(email, dto);
|
||||||
// }
|
// // }
|
||||||
|
|
||||||
// @Delete('delete')
|
// // @Delete('delete')
|
||||||
// async delete(@Req() req, @Body() leave_request_id: number) {
|
// // async delete(@Req() req, @Body() leave_request_id: number) {
|
||||||
// const email = req.user?.email;
|
// // const email = req.user?.email;
|
||||||
// return await this.leave_service.delete(email, leave_request_id);
|
// // return await this.leave_service.delete(email, leave_request_id);
|
||||||
// }
|
// // }
|
||||||
|
|
||||||
// @Patch('update')
|
// // @Patch('update')
|
||||||
// async update(@Req() req, @Body() request_id: number, approval_status: string) {
|
// // async update(@Req() req, @Body() request_id: number, approval_status: string) {
|
||||||
// const email = req.user?.email;
|
// // const email = req.user?.email;
|
||||||
// return await this.leave_service.update(email, request_id, approval_status);
|
// // return await this.leave_service.update(email, request_id, approval_status);
|
||||||
// }
|
// // }
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,186 +1,186 @@
|
||||||
import { EmployeeTimesheetResolver } from "src/common/mappers/timesheet.mapper";
|
// import { EmployeeTimesheetResolver } from "src/common/mappers/timesheet.mapper";
|
||||||
import { EmailToIdResolver } from "src/common/mappers/email-id.mapper";
|
// import { EmailToIdResolver } from "src/common/mappers/email-id.mapper";
|
||||||
import { BankCodesResolver } from "src/common/mappers/bank-type-id.mapper";
|
// import { BankCodesResolver } from "src/common/mappers/bank-type-id.mapper";
|
||||||
import { LeaveApprovalStatus, LeaveRequests, LeaveTypes, Prisma, Shifts } from "@prisma/client";
|
// import { LeaveApprovalStatus, LeaveRequests, LeaveTypes, Prisma, Shifts } from "@prisma/client";
|
||||||
import { PrismaPostgresService } from "prisma/postgres/prisma-postgres.service";
|
// import { PrismaPostgresService } from "prisma/postgres/prisma-postgres.service";
|
||||||
import { Result } from "src/common/errors/result-error.factory";
|
// import { Result } from "src/common/errors/result-error.factory";
|
||||||
import { Injectable } from "@nestjs/common";
|
// import { Injectable } from "@nestjs/common";
|
||||||
import { LeaveRequestDto } from "src/time-and-attendance/leave-requests/leave-request.dto";
|
// import { LeaveRequestDto } from "src/time-and-attendance/leave-requests/leave-request.dto";
|
||||||
import { leave_requests_select } from "src/time-and-attendance/utils/selects.utils";
|
// import { leave_requests_select } from "src/time-and-attendance/utils/selects.utils";
|
||||||
import { toDateFromString, toStringFromDate } from "src/common/utils/date-utils";
|
// import { toDateFromString, toStringFromDate } from "src/common/utils/date-utils";
|
||||||
import { NormalizedLeaveRequest } from "src/time-and-attendance/utils/type.utils";
|
// import { NormalizedLeaveRequest } from "src/time-and-attendance/utils/type.utils";
|
||||||
|
|
||||||
@Injectable()
|
// @Injectable()
|
||||||
export class LeaveRequestsService {
|
// export class LeaveRequestsService {
|
||||||
// constructor(
|
// // constructor(
|
||||||
// private readonly prisma: PrismaPostgresService,
|
// // private readonly prisma: PrismaPostgresService,
|
||||||
// private readonly timesheetResolver: EmployeeTimesheetResolver,
|
// // private readonly timesheetResolver: EmployeeTimesheetResolver,
|
||||||
// private readonly emailResolver: EmailToIdResolver,
|
// // private readonly emailResolver: EmailToIdResolver,
|
||||||
// private readonly typeResolver: BankCodesResolver,
|
// // private readonly typeResolver: BankCodesResolver,
|
||||||
// ) { }
|
// // ) { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// async create(email: string, dto: LeaveRequestDto): Promise<Result<LeaveRequestDto, string>> {
|
// // async create(email: string, dto: LeaveRequestDto): Promise<Result<LeaveRequestDto, string>> {
|
||||||
// try {
|
// // try {
|
||||||
// //verify if array is empty or not
|
// // //verify if array is empty or not
|
||||||
// if (!Array.isArray(dto.dates) || dto.dates.length === 0) return { success: false, error: 'no data received' };
|
// // if (!Array.isArray(dto.dates) || dto.dates.length === 0) return { success: false, error: 'no data received' };
|
||||||
// //verify if email is valid or not
|
// // //verify if email is valid or not
|
||||||
// const employee = await this.emailResolver.findIdByEmail(email);
|
// // const employee = await this.emailResolver.findIdByEmail(email);
|
||||||
// if (!employee.success) return { success: false, error: employee.error }
|
// // if (!employee.success) return { success: false, error: employee.error }
|
||||||
// //normalized dto datas to match DB's
|
// // //normalized dto datas to match DB's
|
||||||
// const normed_request = await this.normalizeRequest(dto);
|
// // const normed_request = await this.normalizeRequest(dto);
|
||||||
// if (!normed_request.success) return { success: false, error: normed_request.error }
|
// // if (!normed_request.success) return { success: false, error: normed_request.error }
|
||||||
|
|
||||||
// //creates the requests
|
// // //creates the requests
|
||||||
// const request_day = await this.prisma.leaveRequests.create({
|
// // const request_day = await this.prisma.leaveRequests.create({
|
||||||
// data: {
|
// // data: {
|
||||||
// employee_id: employee.data,
|
// // employee_id: employee.data,
|
||||||
// bank_code_id: normed_request.data.bank_code_id,
|
// // bank_code_id: normed_request.data.bank_code_id,
|
||||||
// comment: normed_request.data.comment,
|
// // comment: normed_request.data.comment,
|
||||||
// dates: normed_request.data.dates,
|
// // dates: normed_request.data.dates,
|
||||||
// approval_status: dto.approval_status,
|
// // approval_status: dto.approval_status,
|
||||||
// requested_hours: dto.requested_hours,
|
// // requested_hours: dto.requested_hours,
|
||||||
// leave_type: normed_request.data.leave_type,
|
// // leave_type: normed_request.data.leave_type,
|
||||||
// },
|
// // },
|
||||||
// select: leave_requests_select,
|
// // select: leave_requests_select,
|
||||||
// });
|
// // });
|
||||||
// if (!request_day) return { success: false, error: 'An error occured during creation. Leave-Request is invalid' }
|
// // if (!request_day) return { success: false, error: 'An error occured during creation. Leave-Request is invalid' }
|
||||||
|
|
||||||
// const created_request: LeaveRequestDto = {
|
// // const created_request: LeaveRequestDto = {
|
||||||
// email: dto.email,
|
// // email: dto.email,
|
||||||
// type: request_day.leave_type.toString(),
|
// // type: request_day.leave_type.toString(),
|
||||||
// dates: dto.dates,
|
// // dates: dto.dates,
|
||||||
// comment: normed_request.data.comment,
|
// // comment: normed_request.data.comment,
|
||||||
// approval_status: 'PENDING',
|
// // approval_status: 'PENDING',
|
||||||
// requested_hours: dto.requested_hours,
|
// // requested_hours: dto.requested_hours,
|
||||||
// };
|
// // };
|
||||||
|
|
||||||
// return { success: true, data: created_request };
|
// // return { success: true, data: created_request };
|
||||||
// } catch (error) {
|
// // } catch (error) {
|
||||||
// return { success: false, error: `An error occured during creation, invalid data` }
|
// // return { success: false, error: `An error occured during creation, invalid data` }
|
||||||
// }
|
// // }
|
||||||
// }
|
// // }
|
||||||
|
|
||||||
// async update(email: string, request_id: number, dto: LeaveRequestDto): Promise<Result<LeaveRequestDto, string>> {
|
// // async update(email: string, request_id: number, dto: LeaveRequestDto): Promise<Result<LeaveRequestDto, string>> {
|
||||||
// try {
|
// // try {
|
||||||
// const employee = await this.emailResolver.findIdByEmail(email);
|
// // const employee = await this.emailResolver.findIdByEmail(email);
|
||||||
// if (!employee.success) return { success: false, error: employee.error }
|
// // if (!employee.success) return { success: false, error: employee.error }
|
||||||
|
|
||||||
// switch (dto.approval_status) {
|
// // switch (dto.approval_status) {
|
||||||
// case 'APPROVED': //creation of shifts and returns void
|
// // case 'APPROVED': //creation of shifts and returns void
|
||||||
// break;
|
// // break;
|
||||||
// case 'DENIED': //simple update and returns void
|
// // case 'DENIED': //simple update and returns void
|
||||||
// break;
|
// // break;
|
||||||
// case 'CANCELLED': //CANCELLED, simple update and returns void
|
// // case 'CANCELLED': //CANCELLED, simple update and returns void
|
||||||
// break;
|
// // break;
|
||||||
// case 'PENDING': this.updatePendingRequest(dto)
|
// // case 'PENDING': this.updatePendingRequest(dto)
|
||||||
// break;
|
// // break;
|
||||||
// default: return { success: false, error: `invalid approval_status` };
|
// // default: return { success: false, error: `invalid approval_status` };
|
||||||
// }
|
// // }
|
||||||
|
|
||||||
// // const updated_request: LeaveRequestDto = {
|
// // // const updated_request: LeaveRequestDto = {
|
||||||
// // email: dto.email,
|
// // // email: dto.email,
|
||||||
// // type: request_day.leave_type.toString(),
|
// // // type: request_day.leave_type.toString(),
|
||||||
// // dates: dto.dates,
|
// // // dates: dto.dates,
|
||||||
// // comment: normed_request.data.comment,
|
// // // comment: normed_request.data.comment,
|
||||||
// // approval_status: dto.approval_status,
|
// // // approval_status: dto.approval_status,
|
||||||
// // requested_hours: dto.requested_hours,
|
// // // requested_hours: dto.requested_hours,
|
||||||
// // }
|
// // // }
|
||||||
|
|
||||||
// } catch (error) {
|
// // } catch (error) {
|
||||||
// return { success: false, error: ' An error occured during update, Invalid Leave-Request data' }
|
// // return { success: false, error: ' An error occured during update, Invalid Leave-Request data' }
|
||||||
// }
|
// // }
|
||||||
// return { success: true, data: updated_request };
|
// // return { success: true, data: updated_request };
|
||||||
// }
|
// // }
|
||||||
|
|
||||||
// async delete(email: string, request_id: number): Promise<Result<number, string>> {
|
// // async delete(email: string, request_id: number): Promise<Result<number, string>> {
|
||||||
// try {
|
// // try {
|
||||||
// const employee = await this.emailResolver.findIdByEmail(email);
|
// // const employee = await this.emailResolver.findIdByEmail(email);
|
||||||
// if (!employee.success) return { success: false, error: employee.error }
|
// // if (!employee.success) return { success: false, error: employee.error }
|
||||||
|
|
||||||
// const deleted = await this.prisma.leaveRequests.findUnique({
|
// // const deleted = await this.prisma.leaveRequests.findUnique({
|
||||||
// where: { id: request_id, employee_id: employee.data },
|
// // where: { id: request_id, employee_id: employee.data },
|
||||||
// select: { id: true, dates: true },
|
// // select: { id: true, dates: true },
|
||||||
// });
|
// // });
|
||||||
// if (!deleted) return { success: false, error: `Leave Request with id ${request_id} not found ` };
|
// // if (!deleted) return { success: false, error: `Leave Request with id ${request_id} not found ` };
|
||||||
// return { success: true, data: deleted.id };
|
// // return { success: true, data: deleted.id };
|
||||||
|
|
||||||
// } catch (error) {
|
// // } catch (error) {
|
||||||
// return { success: false, error: `INVALID_REQUEST, leave-request with id ${request_id} not found` }
|
// // return { success: false, error: `INVALID_REQUEST, leave-request with id ${request_id} not found` }
|
||||||
// }
|
// // }
|
||||||
// }
|
// // }
|
||||||
|
|
||||||
// private normalizeRequest = async (dto: LeaveRequestDto): Promise<Result<NormalizedLeaveRequest, string>> => {
|
// // private normalizeRequest = async (dto: LeaveRequestDto): Promise<Result<NormalizedLeaveRequest, string>> => {
|
||||||
// const bank_code = await this.typeResolver.findBankCodeIDByType(dto.type);
|
// // const bank_code = await this.typeResolver.findBankCodeIDByType(dto.type);
|
||||||
// if (!bank_code.success) return { success: false, error: bank_code.error };
|
// // if (!bank_code.success) return { success: false, error: bank_code.error };
|
||||||
// const comment = this.truncate280(dto.comment);
|
// // const comment = this.truncate280(dto.comment);
|
||||||
// //maps enum, check if dto.type is include in the list and return a valid type
|
// // //maps enum, check if dto.type is include in the list and return a valid type
|
||||||
// const leave_type_list = Object.values(LeaveTypes);
|
// // const leave_type_list = Object.values(LeaveTypes);
|
||||||
// const leave_type = leave_type_list.includes(dto.type.toUpperCase() as LeaveTypes);
|
// // const leave_type = leave_type_list.includes(dto.type.toUpperCase() as LeaveTypes);
|
||||||
// if (!leave_type) return { success: false, error: `Leave Request of type ${dto.type} is invalid` }
|
// // if (!leave_type) return { success: false, error: `Leave Request of type ${dto.type} is invalid` }
|
||||||
// const valid_leave_type = dto.type.toUpperCase() as LeaveTypes;
|
// // const valid_leave_type = dto.type.toUpperCase() as LeaveTypes;
|
||||||
|
|
||||||
// //map of all dates in string format
|
// // //map of all dates in string format
|
||||||
// const dates = dto.dates.map(toDateFromString);
|
// // const dates = dto.dates.map(toDateFromString);
|
||||||
// if (!dates) return { success: false, error: 'Bad date' }
|
// // if (!dates) return { success: false, error: 'Bad date' }
|
||||||
|
|
||||||
// return { success: true, data: { comment, dates, leave_type: valid_leave_type, bank_code_id: bank_code.data } };
|
// // return { success: true, data: { comment, dates, leave_type: valid_leave_type, bank_code_id: bank_code.data } };
|
||||||
// }
|
// // }
|
||||||
|
|
||||||
// //makes sure that a string cannot exceed 280 chars
|
// // //makes sure that a string cannot exceed 280 chars
|
||||||
// private truncate280 = (input: string): string => {
|
// // private truncate280 = (input: string): string => {
|
||||||
// return input.length > 280 ? input.slice(0, 280) : input;
|
// // return input.length > 280 ? input.slice(0, 280) : input;
|
||||||
// }
|
// // }
|
||||||
|
|
||||||
// private updatePendingRequest = async (request_id: number, dto: LeaveRequestDto): Promise<Result<LeaveRequestDto, string>> => {
|
// // private updatePendingRequest = async (request_id: number, dto: LeaveRequestDto): Promise<Result<LeaveRequestDto, string>> => {
|
||||||
// const normed_dto = await this.normalizeRequest(dto);
|
// // const normed_dto = await this.normalizeRequest(dto);
|
||||||
// if (!normed_dto.success) return { success: false, error: normed_dto.error }
|
// // if (!normed_dto.success) return { success: false, error: normed_dto.error }
|
||||||
|
|
||||||
// const leave_request = await this.prisma.leaveRequests.findUnique({
|
// // const leave_request = await this.prisma.leaveRequests.findUnique({
|
||||||
// where: { id: request_id },
|
// // where: { id: request_id },
|
||||||
// select: leave_requests_select,
|
// // select: leave_requests_select,
|
||||||
// });
|
// // });
|
||||||
// if (!leave_request) return { success: false, error: `Leave Request with id: ${request_id} not found` }
|
// // if (!leave_request) return { success: false, error: `Leave Request with id: ${request_id} not found` }
|
||||||
|
|
||||||
// const update = await this.prisma.leaveRequests.update({
|
// // const update = await this.prisma.leaveRequests.update({
|
||||||
// where: { id: request_id },
|
// // where: { id: request_id },
|
||||||
// data: {
|
// // data: {
|
||||||
// bank_code_id: normed_dto.data.bank_code_id,
|
// // bank_code_id: normed_dto.data.bank_code_id,
|
||||||
// leave_type: normed_dto.data.leave_type,
|
// // leave_type: normed_dto.data.leave_type,
|
||||||
// comment: normed_dto.data.comment,
|
// // comment: normed_dto.data.comment,
|
||||||
// dates: normed_dto.data.dates,
|
// // dates: normed_dto.data.dates,
|
||||||
// requested_hours: dto.requested_hours ?? 0,
|
// // requested_hours: dto.requested_hours ?? 0,
|
||||||
// }
|
// // }
|
||||||
// })
|
// // })
|
||||||
// // (alias) class LeaveRequestDto {
|
// // // (alias) class LeaveRequestDto {
|
||||||
// // email: string;
|
// // // email: string;
|
||||||
// // dates: string[];
|
// // // dates: string[];
|
||||||
// // type: string;
|
// // // type: string;
|
||||||
// // comment: string;
|
// // // comment: string;
|
||||||
// // requested_hours?: number | undefined;
|
// // // requested_hours?: number | undefined;
|
||||||
// // approval_status?: $Enums.LeaveApprovalStatus | undefined;
|
// // // approval_status?: $Enums.LeaveApprovalStatus | undefined;
|
||||||
// // }
|
// // // }
|
||||||
// // const dates_string = update.dates.map(toStringFromDate);
|
// // // const dates_string = update.dates.map(toStringFromDate);
|
||||||
// // const updated_request: LeaveRequestDto = {
|
// // // const updated_request: LeaveRequestDto = {
|
||||||
// // email: leave_request,
|
// // // email: leave_request,
|
||||||
// // type: update.leave_type,
|
// // // type: update.leave_type,
|
||||||
|
|
||||||
// // }
|
// // // }
|
||||||
|
|
||||||
// return { success: true, data: updated_request }
|
// // return { success: true, data: updated_request }
|
||||||
// }
|
// // }
|
||||||
}
|
// }
|
||||||
|
|
||||||
type leaveRequests = {
|
// type leaveRequests = {
|
||||||
id: number;
|
// id: number;
|
||||||
bank_code_id: number;
|
// bank_code_id: number;
|
||||||
comment: string;
|
// comment: string;
|
||||||
dates: Date[];
|
// dates: Date[];
|
||||||
payable_hours: Prisma.Decimal | null;
|
// payable_hours: Prisma.Decimal | null;
|
||||||
requested_hours: Prisma.Decimal | null;
|
// requested_hours: Prisma.Decimal | null;
|
||||||
approval_status: LeaveApprovalStatus;
|
// approval_status: LeaveApprovalStatus;
|
||||||
leave_type: LeaveTypes;
|
// leave_type: LeaveTypes;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,102 +1,102 @@
|
||||||
|
|
||||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
// import { BadRequestException, Injectable } from "@nestjs/common";
|
||||||
import { PrismaPostgresService } from "prisma/postgres/prisma-postgres.service";
|
// import { PrismaPostgresService } from "prisma/postgres/prisma-postgres.service";
|
||||||
import { LeaveTypes } from "prisma/generated/postgres/client";
|
// import { LeaveTypes } from "prisma/generated/postgres/client";
|
||||||
import { toDateFromString, toStringFromDate } from "src/common/utils/date-utils";
|
// import { toDateFromString, toStringFromDate } from "src/common/utils/date-utils";
|
||||||
@Injectable()
|
// @Injectable()
|
||||||
export class LeaveRequestsUtils {
|
// export class LeaveRequestsUtils {
|
||||||
constructor(
|
// constructor(
|
||||||
private readonly prisma: PrismaPostgresService,
|
// private readonly prisma: PrismaPostgresService,
|
||||||
) { }
|
// ) { }
|
||||||
|
|
||||||
|
|
||||||
async syncShift(
|
// async syncShift(
|
||||||
email: string,
|
// email: string,
|
||||||
employee_id: number,
|
// employee_id: number,
|
||||||
date: string,
|
// date: string,
|
||||||
hours: number,
|
// hours: number,
|
||||||
type: LeaveTypes,
|
// type: LeaveTypes,
|
||||||
comment?: string,
|
// comment?: string,
|
||||||
) {
|
// ) {
|
||||||
if (hours <= 0) return;
|
// if (hours <= 0) return;
|
||||||
|
|
||||||
const duration_minutes = Math.round(hours * 60);
|
// const duration_minutes = Math.round(hours * 60);
|
||||||
if (duration_minutes > 8 * 60) {
|
// if (duration_minutes > 8 * 60) {
|
||||||
throw new BadRequestException("Amount of hours cannot exceed 8 hours per day.");
|
// throw new BadRequestException("Amount of hours cannot exceed 8 hours per day.");
|
||||||
}
|
// }
|
||||||
const date_only = toDateFromString(date);
|
// const date_only = toDateFromString(date);
|
||||||
const yyyy_mm_dd = toStringFromDate(date_only);
|
// const yyyy_mm_dd = toStringFromDate(date_only);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const start_minutes = 8 * 60;
|
// const start_minutes = 8 * 60;
|
||||||
const end_minutes = start_minutes + duration_minutes;
|
// const end_minutes = start_minutes + duration_minutes;
|
||||||
const toHHmm = (total: number) =>
|
// const toHHmm = (total: number) =>
|
||||||
`${String(Math.floor(total / 60)).padStart(2, "0")}:${String(total % 60).padStart(2, "0")}`;
|
// `${String(Math.floor(total / 60)).padStart(2, "0")}:${String(total % 60).padStart(2, "0")}`;
|
||||||
|
|
||||||
const existing = await this.prisma.shifts.findFirst({
|
// const existing = await this.prisma.shifts.findFirst({
|
||||||
where: {
|
// where: {
|
||||||
date: date_only,
|
// date: date_only,
|
||||||
bank_code: { type },
|
// bank_code: { type },
|
||||||
timesheet: { employee_id: employee_id },
|
// timesheet: { employee_id: employee_id },
|
||||||
},
|
// },
|
||||||
include: { bank_code: true },
|
// include: { bank_code: true },
|
||||||
});
|
// });
|
||||||
|
|
||||||
|
|
||||||
// await this.shiftsService.upsertShifts(email, action, {
|
// // await this.shiftsService.upsertShifts(email, action, {
|
||||||
// old_shift: existing
|
// // old_shift: existing
|
||||||
// ? {
|
// // ? {
|
||||||
// date: yyyy_mm_dd,
|
// // date: yyyy_mm_dd,
|
||||||
// start_time: existing.start_time.toISOString().slice(11, 16),
|
// // start_time: existing.start_time.toISOString().slice(11, 16),
|
||||||
// end_time: existing.end_time.toISOString().slice(11, 16),
|
// // end_time: existing.end_time.toISOString().slice(11, 16),
|
||||||
// type: existing.bank_code?.type ?? type,
|
// // type: existing.bank_code?.type ?? type,
|
||||||
// is_remote: existing.is_remote,
|
// // is_remote: existing.is_remote,
|
||||||
// is_approved:existing.is_approved,
|
// // is_approved:existing.is_approved,
|
||||||
// comment: existing.comment ?? undefined,
|
// // comment: existing.comment ?? undefined,
|
||||||
// }
|
// // }
|
||||||
// : undefined,
|
// // : undefined,
|
||||||
// new_shift: {
|
// // new_shift: {
|
||||||
// date: yyyy_mm_dd,
|
// // date: yyyy_mm_dd,
|
||||||
// start_time: toHHmm(start_minutes),
|
// // start_time: toHHmm(start_minutes),
|
||||||
// end_time: toHHmm(end_minutes),
|
// // end_time: toHHmm(end_minutes),
|
||||||
// is_remote: existing?.is_remote ?? false,
|
// // is_remote: existing?.is_remote ?? false,
|
||||||
// is_approved:existing?.is_approved ?? false,
|
// // is_approved:existing?.is_approved ?? false,
|
||||||
// comment: comment ?? existing?.comment ?? "",
|
// // comment: comment ?? existing?.comment ?? "",
|
||||||
// type: type,
|
// // type: type,
|
||||||
// },
|
// // },
|
||||||
// });
|
// // });
|
||||||
}
|
// }
|
||||||
|
|
||||||
async removeShift(
|
// async removeShift(
|
||||||
email: string,
|
// email: string,
|
||||||
employee_id: number,
|
// employee_id: number,
|
||||||
iso_date: string,
|
// iso_date: string,
|
||||||
type: LeaveTypes,
|
// type: LeaveTypes,
|
||||||
) {
|
// ) {
|
||||||
const date_only = toDateFromString(iso_date);
|
// const date_only = toDateFromString(iso_date);
|
||||||
const yyyy_mm_dd = toStringFromDate(date_only);
|
// const yyyy_mm_dd = toStringFromDate(date_only);
|
||||||
const existing = await this.prisma.shifts.findFirst({
|
// const existing = await this.prisma.shifts.findFirst({
|
||||||
where: {
|
// where: {
|
||||||
date: date_only,
|
// date: date_only,
|
||||||
bank_code: { type },
|
// bank_code: { type },
|
||||||
timesheet: { employee_id: employee_id },
|
// timesheet: { employee_id: employee_id },
|
||||||
},
|
// },
|
||||||
include: { bank_code: true },
|
// include: { bank_code: true },
|
||||||
});
|
// });
|
||||||
if (!existing) return;
|
// if (!existing) return;
|
||||||
|
|
||||||
// await this.shiftsService.upsertShifts(email, 'delete', {
|
// // await this.shiftsService.upsertShifts(email, 'delete', {
|
||||||
// old_shift: {
|
// // old_shift: {
|
||||||
// date: yyyy_mm_dd,
|
// // date: yyyy_mm_dd,
|
||||||
// start_time: hhmmFromLocal(existing.start_time),
|
// // start_time: hhmmFromLocal(existing.start_time),
|
||||||
// end_time: hhmmFromLocal(existing.end_time),
|
// // end_time: hhmmFromLocal(existing.end_time),
|
||||||
// type: existing.bank_code?.type ?? type,
|
// // type: existing.bank_code?.type ?? type,
|
||||||
// is_remote: existing.is_remote,
|
// // is_remote: existing.is_remote,
|
||||||
// is_approved:existing.is_approved,
|
// // is_approved:existing.is_approved,
|
||||||
// comment: existing.comment ?? undefined,
|
// // comment: existing.comment ?? undefined,
|
||||||
// },
|
// // },
|
||||||
// });
|
// // });
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
import { Prisma } from "prisma/generated/postgres/client";
|
// import { Prisma } from "prisma/generated/postgres/client";
|
||||||
|
|
||||||
export const leaveRequestsArchiveSelect = {
|
// export const leaveRequestsArchiveSelect = {
|
||||||
id: true,
|
// id: true,
|
||||||
leave_request_id: true,
|
// leave_request_id: true,
|
||||||
archived_at: true,
|
// archived_at: true,
|
||||||
employee_id: true,
|
// employee_id: true,
|
||||||
leave_type: true,
|
// leave_type: true,
|
||||||
date: true,
|
// date: true,
|
||||||
payable_hours: true,
|
// payable_hours: true,
|
||||||
requested_hours: true,
|
// requested_hours: true,
|
||||||
comment: true,
|
// comment: true,
|
||||||
approval_status: true,
|
// approval_status: true,
|
||||||
} satisfies Prisma.LeaveRequestsArchiveSelect;
|
// } satisfies Prisma.LeaveRequestsArchiveSelect;
|
||||||
|
|
||||||
export type LeaveRequestArchiveRow = Prisma.LeaveRequestsArchiveGetPayload<{ select: typeof leaveRequestsArchiveSelect}>;
|
// export type LeaveRequestArchiveRow = Prisma.LeaveRequestsArchiveGetPayload<{ select: typeof leaveRequestsArchiveSelect}>;
|
||||||
|
|
@ -73,7 +73,7 @@ export class PaidTimeOFfBankHoursService {
|
||||||
if (!config) return { success: false, error: 'INVALID_PAID_TIME_OFF_TYPE' }
|
if (!config) return { success: false, error: 'INVALID_PAID_TIME_OFF_TYPE' }
|
||||||
const operation = config.invert_logic ? 'decrement' : 'increment';
|
const operation = config.invert_logic ? 'decrement' : 'increment';
|
||||||
|
|
||||||
await this.prisma.paidTimeOff.update({
|
await this.prisma.client.paidTimeOff.update({
|
||||||
where: { employee_id },
|
where: { employee_id },
|
||||||
data: {
|
data: {
|
||||||
[config.field]: { [operation]: hours },
|
[config.field]: { [operation]: hours },
|
||||||
|
|
@ -100,7 +100,7 @@ export class PaidTimeOFfBankHoursService {
|
||||||
|
|
||||||
const last_updated = new Date();
|
const last_updated = new Date();
|
||||||
|
|
||||||
await this.prisma.paidTimeOff.update({
|
await this.prisma.client.paidTimeOff.update({
|
||||||
where: { employee_id },
|
where: { employee_id },
|
||||||
data: {
|
data: {
|
||||||
[config.field]: { [config.operation]: ajusted_hours },
|
[config.field]: { [config.operation]: ajusted_hours },
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ export class GetOverviewService {
|
||||||
}
|
}
|
||||||
|
|
||||||
async buildOverview(overview: Overview): Promise<Result<PayPeriodOverviewDto, string>> {
|
async buildOverview(overview: Overview): Promise<Result<PayPeriodOverviewDto, string>> {
|
||||||
const employee_overviews = await this.prisma.employees.findMany({
|
const employee_overviews = await this.prisma.client.employees.findMany({
|
||||||
where: {
|
where: {
|
||||||
OR: [
|
OR: [
|
||||||
{ last_work_day: { gte: toDateFromString(overview.period_start) } },
|
{ last_work_day: { gte: toDateFromString(overview.period_start) } },
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export class PayPeriodsCommandService {
|
||||||
if (!employee_id.success) return { success: false, error: employee_id.error }
|
if (!employee_id.success) return { success: false, error: employee_id.error }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
shifts = await this.prisma.shifts.updateMany({
|
shifts = await this.prisma.client.shifts.updateMany({
|
||||||
where: {
|
where: {
|
||||||
timesheet: {
|
timesheet: {
|
||||||
id: { in: timesheet_ids },
|
id: { in: timesheet_ids },
|
||||||
|
|
@ -35,7 +35,7 @@ export class PayPeriodsCommandService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
expenses = await this.prisma.expenses.updateMany({
|
expenses = await this.prisma.client.expenses.updateMany({
|
||||||
where: {
|
where: {
|
||||||
timesheet: {
|
timesheet: {
|
||||||
id: { in: timesheet_ids },
|
id: { in: timesheet_ids },
|
||||||
|
|
@ -47,7 +47,7 @@ export class PayPeriodsCommandService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.prisma.timesheets.updateMany({
|
await this.prisma.client.timesheets.updateMany({
|
||||||
where: {
|
where: {
|
||||||
id: { in: timesheet_ids},
|
id: { in: timesheet_ids},
|
||||||
employee_id: employee_id.data,
|
employee_id: employee_id.data,
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ export class PayPeriodsQueryService {
|
||||||
private readonly prisma: PrismaPostgresService) { }
|
private readonly prisma: PrismaPostgresService) { }
|
||||||
|
|
||||||
async findOneByYearPeriod(pay_year: number, period_no: number): Promise<Result<PayPeriodDto, string>> {
|
async findOneByYearPeriod(pay_year: number, period_no: number): Promise<Result<PayPeriodDto, string>> {
|
||||||
const row = await this.prisma.payPeriods.findFirst({
|
const row = await this.prisma.client.payPeriods.findFirst({
|
||||||
where: { pay_year, pay_period_no: period_no },
|
where: { pay_year, pay_period_no: period_no },
|
||||||
});
|
});
|
||||||
if (row) return { success: true, data: mapPayPeriodToDto(row) };
|
if (row) return { success: true, data: mapPayPeriodToDto(row) };
|
||||||
|
|
@ -34,7 +34,7 @@ export class PayPeriodsQueryService {
|
||||||
//function to cherry pick a Date to find a period
|
//function to cherry pick a Date to find a period
|
||||||
async findByDate(date: string): Promise<Result<PayPeriodDto, string>> {
|
async findByDate(date: string): Promise<Result<PayPeriodDto, string>> {
|
||||||
const dt = new Date(date);
|
const dt = new Date(date);
|
||||||
const row = await this.prisma.payPeriods.findFirst({
|
const row = await this.prisma.client.payPeriods.findFirst({
|
||||||
where: { period_start: { lte: dt }, period_end: { gte: dt } },
|
where: { period_start: { lte: dt }, period_end: { gte: dt } },
|
||||||
});
|
});
|
||||||
if (row) return { success: true, data: mapPayPeriodToDto(row) };
|
if (row) return { success: true, data: mapPayPeriodToDto(row) };
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export class SchedulePresetsApplyService {
|
||||||
const employee_id = await this.emailResolver.findIdByEmail(user_email);
|
const employee_id = await this.emailResolver.findIdByEmail(user_email);
|
||||||
if (!employee_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND' };
|
if (!employee_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND' };
|
||||||
|
|
||||||
const employee_default_schedule_preset = await this.prisma.employees.findFirst({
|
const employee_default_schedule_preset = await this.prisma.client.employees.findFirst({
|
||||||
where: { id: employee_id.data },
|
where: { id: employee_id.data },
|
||||||
select: {
|
select: {
|
||||||
schedule_preset: {
|
schedule_preset: {
|
||||||
|
|
@ -43,7 +43,7 @@ export class SchedulePresetsApplyService {
|
||||||
if (!employee_default_schedule_preset) return { success: false, error: 'EMPLOYEE_NOT_FOUND' };
|
if (!employee_default_schedule_preset) return { success: false, error: 'EMPLOYEE_NOT_FOUND' };
|
||||||
if (!employee_default_schedule_preset.schedule_preset) return { success: false, error: 'SCHEDULE_PRESET_NOT_FOUND' };
|
if (!employee_default_schedule_preset.schedule_preset) return { success: false, error: 'SCHEDULE_PRESET_NOT_FOUND' };
|
||||||
|
|
||||||
const default_preset_shifts = await this.prisma.schedulePresetShifts.findMany({
|
const default_preset_shifts = await this.prisma.client.schedulePresetShifts.findMany({
|
||||||
where: { preset_id: employee_default_schedule_preset.schedule_preset.id },
|
where: { preset_id: employee_default_schedule_preset.schedule_preset.id },
|
||||||
select: {
|
select: {
|
||||||
bank_code_id: true,
|
bank_code_id: true,
|
||||||
|
|
@ -55,7 +55,7 @@ export class SchedulePresetsApplyService {
|
||||||
});
|
});
|
||||||
if (default_preset_shifts.length <= 0) return { success: false, error: 'INVALID_SCHEDULE_PRESET' };
|
if (default_preset_shifts.length <= 0) return { success: false, error: 'INVALID_SCHEDULE_PRESET' };
|
||||||
|
|
||||||
const timesheet = await this.prisma.timesheets.findUnique({
|
const timesheet = await this.prisma.client.timesheets.findUnique({
|
||||||
where: { id: timesheet_id },
|
where: { id: timesheet_id },
|
||||||
select: timesheet_select,
|
select: timesheet_select,
|
||||||
});
|
});
|
||||||
|
|
@ -101,7 +101,7 @@ export class SchedulePresetsApplyService {
|
||||||
if (!employee_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND' };
|
if (!employee_id.success) return { success: false, error: 'EMPLOYEE_NOT_FOUND' };
|
||||||
const week_day = Object.keys(WEEKDAY_MAP)[week_day_index];
|
const week_day = Object.keys(WEEKDAY_MAP)[week_day_index];
|
||||||
|
|
||||||
const preset_shift = await this.prisma.employees.findFirst({
|
const preset_shift = await this.prisma.client.employees.findFirst({
|
||||||
where: { id: employee_id.data, },
|
where: { id: employee_id.data, },
|
||||||
select: {
|
select: {
|
||||||
schedule_preset: {
|
schedule_preset: {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ export class SchedulePresetsCreateService {
|
||||||
async createPreset(dto: SchedulePresetsDto): Promise<Result<boolean, string>> {
|
async createPreset(dto: SchedulePresetsDto): Promise<Result<boolean, string>> {
|
||||||
try {
|
try {
|
||||||
//validate new unique name
|
//validate new unique name
|
||||||
const existing = await this.prisma.schedulePresets.findFirst({
|
const existing = await this.prisma.client.schedulePresets.findFirst({
|
||||||
where: { name: dto.name },
|
where: { name: dto.name },
|
||||||
select: { name: true },
|
select: { name: true },
|
||||||
});
|
});
|
||||||
|
|
@ -54,7 +54,7 @@ export class SchedulePresetsCreateService {
|
||||||
if (!result.success) return { success: false, error: 'INVALID_SCHEDULE_PRESET' }
|
if (!result.success) return { success: false, error: 'INVALID_SCHEDULE_PRESET' }
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.prisma.$transaction(async (tx) => {
|
await this.prisma.client.$transaction(async (tx) => {
|
||||||
await tx.schedulePresets.create({
|
await tx.schedulePresets.create({
|
||||||
data: {
|
data: {
|
||||||
name: dto.name,
|
name: dto.name,
|
||||||
|
|
|
||||||
|
|
@ -11,20 +11,20 @@ export class SchedulePresetDeleteService {
|
||||||
//_________________________________________________________________
|
//_________________________________________________________________
|
||||||
async deletePreset(preset_id: number): Promise<Result<boolean, string>> {
|
async deletePreset(preset_id: number): Promise<Result<boolean, string>> {
|
||||||
|
|
||||||
const preset = await this.prisma.schedulePresets.findUnique({
|
const preset = await this.prisma.client.schedulePresets.findUnique({
|
||||||
where: { id: preset_id },
|
where: { id: preset_id },
|
||||||
select: { id: true },
|
select: { id: true },
|
||||||
});
|
});
|
||||||
if (!preset) return { success: false, error: `SCHEDULE_PRESET_NOT_FOUND` };
|
if (!preset) return { success: false, error: `SCHEDULE_PRESET_NOT_FOUND` };
|
||||||
|
|
||||||
const updated_employees = await this.prisma.employees.updateMany({
|
const updated_employees = await this.prisma.client.employees.updateMany({
|
||||||
where: { schedule_preset_id: preset_id },
|
where: { schedule_preset_id: preset_id },
|
||||||
data: {
|
data: {
|
||||||
schedule_preset_id: 0,
|
schedule_preset_id: 0,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.prisma.$transaction(async (tx) => {
|
await this.prisma.client.$transaction(async (tx) => {
|
||||||
await tx.schedulePresetShifts.deleteMany({ where: { preset_id: preset_id } });
|
await tx.schedulePresetShifts.deleteMany({ where: { preset_id: preset_id } });
|
||||||
await tx.schedulePresets.delete({ where: { id: preset_id } });
|
await tx.schedulePresets.delete({ where: { id: preset_id } });
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ export class SchedulePresetsGetService {
|
||||||
|
|
||||||
async getSchedulePresets(): Promise<Result<SchedulePresetsDto[], string>> {
|
async getSchedulePresets(): Promise<Result<SchedulePresetsDto[], string>> {
|
||||||
try {
|
try {
|
||||||
const presets = await this.prisma.schedulePresets.findMany({
|
const presets = await this.prisma.client.schedulePresets.findMany({
|
||||||
orderBy: [{ name: 'asc' }],
|
orderBy: [{ name: 'asc' }],
|
||||||
include: {
|
include: {
|
||||||
shifts: {
|
shifts: {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ export class SchedulePresetUpdateService {
|
||||||
// UPDATE
|
// UPDATE
|
||||||
//_________________________________________________________________
|
//_________________________________________________________________
|
||||||
async updatePreset(dto: SchedulePresetsDto): Promise<Result<boolean, string>> {
|
async updatePreset(dto: SchedulePresetsDto): Promise<Result<boolean, string>> {
|
||||||
const existing = await this.prisma.schedulePresets.findFirst({
|
const existing = await this.prisma.client.schedulePresets.findFirst({
|
||||||
where: { id: dto.id },
|
where: { id: dto.id },
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
|
|
@ -50,7 +50,7 @@ export class SchedulePresetUpdateService {
|
||||||
if (!result.success) return { success: false, error: 'INVALID_SCHEDULE_PRESET' }
|
if (!result.success) return { success: false, error: 'INVALID_SCHEDULE_PRESET' }
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.prisma.$transaction(async (tx) => {
|
await this.prisma.client.$transaction(async (tx) => {
|
||||||
await tx.schedulePresetShifts.deleteMany({ where: { preset_id: existing.id } });
|
await tx.schedulePresetShifts.deleteMany({ where: { preset_id: existing.id } });
|
||||||
|
|
||||||
await tx.schedulePresets.update({
|
await tx.schedulePresets.update({
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ export class ShiftsCreateService {
|
||||||
if (!normed_shift.success) return { success: false, error: normed_shift.error };
|
if (!normed_shift.success) return { success: false, error: normed_shift.error };
|
||||||
if (normed_shift.data.end_time <= normed_shift.data.start_time) return { success: false, error: `INVALID_SHIFT_TIME` };
|
if (normed_shift.data.end_time <= normed_shift.data.start_time) return { success: false, error: `INVALID_SHIFT_TIME` };
|
||||||
//fetch the right timesheet
|
//fetch the right timesheet
|
||||||
const timesheet = await this.prisma.timesheets.findUnique({
|
const timesheet = await this.prisma.client.timesheets.findUnique({
|
||||||
where: { id: dto.timesheet_id, employee_id },
|
where: { id: dto.timesheet_id, employee_id },
|
||||||
select: timesheet_select,
|
select: timesheet_select,
|
||||||
});
|
});
|
||||||
|
|
@ -94,7 +94,7 @@ export class ShiftsCreateService {
|
||||||
if (!bank_code_id.success) return { success: false, error: bank_code_id.error };
|
if (!bank_code_id.success) return { success: false, error: bank_code_id.error };
|
||||||
|
|
||||||
//fetchs existing shifts from DB to check for overlaps
|
//fetchs existing shifts from DB to check for overlaps
|
||||||
const existing_shifts = await this.prisma.shifts.findMany({
|
const existing_shifts = await this.prisma.client.shifts.findMany({
|
||||||
where: { timesheet_id: timesheet.id, date: normed_shift.data.date },
|
where: { timesheet_id: timesheet.id, date: normed_shift.data.date },
|
||||||
select: { id: true, date: true, start_time: true, end_time: true },
|
select: { id: true, date: true, start_time: true, end_time: true },
|
||||||
});
|
});
|
||||||
|
|
@ -149,7 +149,7 @@ export class ShiftsCreateService {
|
||||||
}
|
}
|
||||||
|
|
||||||
//sends data for creation of a shift in db
|
//sends data for creation of a shift in db
|
||||||
const created_shift = await this.prisma.shifts.create({
|
const created_shift = await this.prisma.client.shifts.create({
|
||||||
data: {
|
data: {
|
||||||
timesheet_id: timesheet.id,
|
timesheet_id: timesheet.id,
|
||||||
bank_code_id: bank_code_id.data,
|
bank_code_id: bank_code_id.data,
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ export class ShiftsDeleteService {
|
||||||
if (!employee_id.success) return { success: false, error: employee_id.error };
|
if (!employee_id.success) return { success: false, error: employee_id.error };
|
||||||
|
|
||||||
// check if shift actually belongs to employee
|
// check if shift actually belongs to employee
|
||||||
const shift = await this.prisma.shifts.findUnique({
|
const shift = await this.prisma.client.shifts.findUnique({
|
||||||
where: { id: shift_id },
|
where: { id: shift_id },
|
||||||
select: {
|
select: {
|
||||||
timesheet: {
|
timesheet: {
|
||||||
|
|
@ -42,7 +42,7 @@ export class ShiftsDeleteService {
|
||||||
return { success: false, error: 'SHIFT_NOT_FOUND'}
|
return { success: false, error: 'SHIFT_NOT_FOUND'}
|
||||||
|
|
||||||
// return deletion result
|
// return deletion result
|
||||||
return await this.prisma.$transaction(async (tx) => {
|
return await this.prisma.client.$transaction(async (tx) => {
|
||||||
const shift = await tx.shifts.findUnique({
|
const shift = await tx.shifts.findUnique({
|
||||||
where: { id: shift_id },
|
where: { id: shift_id },
|
||||||
select: {
|
select: {
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ export class ShiftsUpdateService {
|
||||||
const employee = await this.emailResolver.findIdByEmail(email);
|
const employee = await this.emailResolver.findIdByEmail(email);
|
||||||
if (!employee.success) return { success: false, error: employee.error };
|
if (!employee.success) return { success: false, error: employee.error };
|
||||||
//finds original shift
|
//finds original shift
|
||||||
const original = await this.prisma.shifts.findFirst({
|
const original = await this.prisma.client.shifts.findFirst({
|
||||||
where: { id: dto.id, timesheet_id: timesheet.data.id },
|
where: { id: dto.id, timesheet_id: timesheet.data.id },
|
||||||
select: shift_select,
|
select: shift_select,
|
||||||
});
|
});
|
||||||
|
|
@ -134,7 +134,7 @@ export class ShiftsUpdateService {
|
||||||
}
|
}
|
||||||
|
|
||||||
//updates sent to DB
|
//updates sent to DB
|
||||||
const updated = await this.prisma.shifts.update({
|
const updated = await this.prisma.client.shifts.update({
|
||||||
where: { id: original.id },
|
where: { id: original.id },
|
||||||
data: {
|
data: {
|
||||||
date: normed_shift.data.date,
|
date: normed_shift.data.date,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { BaseApprovalService } from "src/common/shared/base-approval.service";
|
|
||||||
import { PrismaPostgresService } from "prisma/postgres/prisma-postgres.service";
|
|
||||||
import { Injectable, NotFoundException } from "@nestjs/common";
|
import { Injectable, NotFoundException } from "@nestjs/common";
|
||||||
|
import { Prisma, PrismaClient, Timesheets } from "@prisma/client";
|
||||||
|
import { PrismaPostgresService } from "prisma/postgres/prisma-postgres.service";
|
||||||
|
import { BaseApprovalService } from "src/common/shared/base-approval.service";
|
||||||
import { timesheet_select } from "src/time-and-attendance/utils/selects.utils";
|
import { timesheet_select } from "src/time-and-attendance/utils/selects.utils";
|
||||||
import { Prisma, Timesheets } from "prisma/generated/postgres/client";
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TimesheetApprovalService extends BaseApprovalService<Timesheets>{
|
export class TimesheetApprovalService extends BaseApprovalService<Timesheets>{
|
||||||
|
|
@ -14,15 +14,15 @@ import { Prisma, Timesheets } from "prisma/generated/postgres/client";
|
||||||
// APPROVAL AND DELEGATE METHODS
|
// APPROVAL AND DELEGATE METHODS
|
||||||
//_____________________________________________________________________________________________
|
//_____________________________________________________________________________________________
|
||||||
protected get delegate() {
|
protected get delegate() {
|
||||||
return this.prisma.timesheets;
|
return this.prisma.client.timesheets;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected delegateFor(tx: Prisma.TransactionClient) {
|
protected delegateFor(tx: Prisma.TransactionClient | PrismaClient) {
|
||||||
return tx.timesheets;
|
return tx.timesheets;
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateApproval(id: number, is_approved: boolean): Promise<Timesheets> {
|
async updateApproval(id: number, is_approved: boolean): Promise<Timesheets> {
|
||||||
return this.prisma.$transaction((tx) =>
|
return this.prisma.client.$transaction((tx) =>
|
||||||
this.updateApprovalWithTransaction(tx, id, is_approved),
|
this.updateApprovalWithTransaction(tx, id, is_approved),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +41,7 @@ import { Prisma, Timesheets } from "prisma/generated/postgres/client";
|
||||||
}
|
}
|
||||||
|
|
||||||
async approveTimesheetById( timesheet_id: number, is_approved: boolean){
|
async approveTimesheetById( timesheet_id: number, is_approved: boolean){
|
||||||
return this.prisma.$transaction(async (tx) => {
|
return this.prisma.client.$transaction(async (tx) => {
|
||||||
const timesheet = await tx.timesheets.findUnique({
|
const timesheet = await tx.timesheets.findUnique({
|
||||||
where: { id: timesheet_id },
|
where: { id: timesheet_id },
|
||||||
select: { id: true },
|
select: { id: true },
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export class GetTimesheetsOverviewService {
|
||||||
const account_email = employee_email ?? email;
|
const account_email = employee_email ?? email;
|
||||||
|
|
||||||
//find period using year and period_no
|
//find period using year and period_no
|
||||||
const period = await this.prisma.payPeriods.findFirst({ where: { pay_year, pay_period_no } });
|
const period = await this.prisma.client.payPeriods.findFirst({ where: { pay_year, pay_period_no } });
|
||||||
if (!period) return { success: false, error: `PAY_PERIOD_NOT_FOUND` };
|
if (!period) return { success: false, error: `PAY_PERIOD_NOT_FOUND` };
|
||||||
|
|
||||||
//fetch the employee_id using the email
|
//fetch the employee_id using the email
|
||||||
|
|
@ -52,7 +52,7 @@ export class GetTimesheetsOverviewService {
|
||||||
rows = await this.loadTimesheets(employee_id.data, period.period_start, period.period_end);
|
rows = await this.loadTimesheets(employee_id.data, period.period_start, period.period_end);
|
||||||
|
|
||||||
//find user infos using the employee_id
|
//find user infos using the employee_id
|
||||||
const employee = await this.prisma.employees.findUnique({
|
const employee = await this.prisma.client.employees.findUnique({
|
||||||
where: { id: employee_id.data },
|
where: { id: employee_id.data },
|
||||||
include: { schedule_preset: true, user: true },
|
include: { schedule_preset: true, user: true },
|
||||||
});
|
});
|
||||||
|
|
@ -79,7 +79,7 @@ export class GetTimesheetsOverviewService {
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
//fetch timesheet's infos
|
//fetch timesheet's infos
|
||||||
private async loadTimesheets(employee_id: number, period_start: Date, period_end: Date) {
|
private async loadTimesheets(employee_id: number, period_start: Date, period_end: Date) {
|
||||||
return this.prisma.timesheets.findMany({
|
return this.prisma.client.timesheets.findMany({
|
||||||
where: { employee_id, start_date: { gte: period_start, lte: period_end } },
|
where: { employee_id, start_date: { gte: period_start, lte: period_end } },
|
||||||
include: {
|
include: {
|
||||||
employee: { include: { user: true } },
|
employee: { include: { user: true } },
|
||||||
|
|
@ -93,7 +93,7 @@ export class GetTimesheetsOverviewService {
|
||||||
private ensureTimesheet = async (employee_id: number, start_date: Date | string) => {
|
private ensureTimesheet = async (employee_id: number, start_date: Date | string) => {
|
||||||
const start = toDateFromString(start_date);
|
const start = toDateFromString(start_date);
|
||||||
|
|
||||||
let row = await this.prisma.timesheets.findFirst({
|
let row = await this.prisma.client.timesheets.findFirst({
|
||||||
where: { employee_id, start_date: start },
|
where: { employee_id, start_date: start },
|
||||||
include: {
|
include: {
|
||||||
employee: { include: { user: true } },
|
employee: { include: { user: true } },
|
||||||
|
|
@ -103,7 +103,7 @@ export class GetTimesheetsOverviewService {
|
||||||
});
|
});
|
||||||
if (row) return row;
|
if (row) return row;
|
||||||
|
|
||||||
await this.prisma.timesheets.create({
|
await this.prisma.client.timesheets.create({
|
||||||
data: {
|
data: {
|
||||||
employee_id,
|
employee_id,
|
||||||
start_date: start,
|
start_date: start,
|
||||||
|
|
@ -111,7 +111,7 @@ export class GetTimesheetsOverviewService {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
row = await this.prisma.timesheets.findFirst({
|
row = await this.prisma.client.timesheets.findFirst({
|
||||||
where: { employee_id, start_date: start },
|
where: { employee_id, start_date: start },
|
||||||
include: {
|
include: {
|
||||||
employee: { include: { user: true } },
|
employee: { include: { user: true } },
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { Prisma } from "prisma/generated/postgres/client";
|
|
||||||
|
import { Prisma } from "@prisma/client";
|
||||||
import { toDateFromString, sevenDaysFrom, toStringFromDate, toHHmmFromDate } from "src/common/utils/date-utils";
|
import { toDateFromString, sevenDaysFrom, toStringFromDate, toHHmmFromDate } from "src/common/utils/date-utils";
|
||||||
import { Timesheet } from "src/time-and-attendance/timesheets/timesheet.dto";
|
import { Timesheet } from "src/time-and-attendance/timesheets/timesheet.dto";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { Prisma } from "prisma/generated/postgres/client";
|
import { Prisma } from "@prisma/client";
|
||||||
|
|
||||||
|
|
||||||
export const expense_select = {
|
export const expense_select = {
|
||||||
id: true,
|
id: true,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { LeaveTypes, Prisma } from "prisma/generated/postgres/client";
|
import { LeaveTypes, Prisma } from "@prisma/client";
|
||||||
|
|
||||||
|
|
||||||
export type Normalized = {
|
export type Normalized = {
|
||||||
date: Date;
|
date: Date;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user