refactor(shared): centralized some small logics
This commit is contained in:
parent
cefba7a2dd
commit
06ad34a4c8
|
|
@ -5,7 +5,7 @@ import { UpsertExpenseDto } from "../dtos/upsert-expense.dto";
|
||||||
import { BankCodesResolver } from "src/modules/shared/utils/resolve-bank-type-id.utils";
|
import { BankCodesResolver } from "src/modules/shared/utils/resolve-bank-type-id.utils";
|
||||||
import { ExpenseResponse, UpsertAction } from "../types and interfaces/expenses.types.interfaces";
|
import { ExpenseResponse, UpsertAction } from "../types and interfaces/expenses.types.interfaces";
|
||||||
import { EmailToIdResolver } from "src/modules/shared/utils/resolve-email-id.utils";
|
import { EmailToIdResolver } from "src/modules/shared/utils/resolve-email-id.utils";
|
||||||
import { EmployeeTimesheetResolver } from "src/modules/shared/utils/resolve-employee-timesheet.utils";
|
import { EmployeeTimesheetResolver } from "src/modules/shared/utils/resolve-timesheet.utils";
|
||||||
import {
|
import {
|
||||||
BadRequestException,
|
BadRequestException,
|
||||||
Injectable,
|
Injectable,
|
||||||
|
|
@ -66,7 +66,7 @@ export class ExpensesCommandService extends BaseApprovalService<Expenses> {
|
||||||
const employee_id = await this.emailResolver.findIdByEmail(email);
|
const employee_id = await this.emailResolver.findIdByEmail(email);
|
||||||
|
|
||||||
//make sure a timesheet existes
|
//make sure a timesheet existes
|
||||||
const timesheet_id = await this.timesheetsResolver.ensureForDate(employee_id, date_only);
|
const timesheet_id = await this.timesheetsResolver.findTimesheetIdByEmail(email, date_only);
|
||||||
if(!timesheet_id) throw new NotFoundException(`no timesheet found for employee #${employee_id}`)
|
if(!timesheet_id) throw new NotFoundException(`no timesheet found for employee #${employee_id}`)
|
||||||
const {id} = timesheet_id;
|
const {id} = timesheet_id;
|
||||||
|
|
||||||
|
|
|
||||||
9
src/modules/shared/interfaces/shifts.interface.ts
Normal file
9
src/modules/shared/interfaces/shifts.interface.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
export interface ShiftKey {
|
||||||
|
timesheet_id: number;
|
||||||
|
date: Date;
|
||||||
|
start_time: Date;
|
||||||
|
end_time: Date;
|
||||||
|
bank_code_id: number;
|
||||||
|
is_remote: boolean;
|
||||||
|
comment?: string | null;
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Module } from "@nestjs/common";
|
import { Module } from "@nestjs/common";
|
||||||
import { EmailToIdResolver } from "./utils/resolve-email-id.utils";
|
import { EmailToIdResolver } from "./utils/resolve-email-id.utils";
|
||||||
import { EmployeeTimesheetResolver } from "./utils/resolve-employee-timesheet.utils";
|
import { EmployeeTimesheetResolver } from "./utils/resolve-timesheet.utils";
|
||||||
import { FullNameResolver } from "./utils/resolve-full-name.utils";
|
import { FullNameResolver } from "./utils/resolve-full-name.utils";
|
||||||
import { BankCodesResolver } from "./utils/resolve-bank-type-id.utils";
|
import { BankCodesResolver } from "./utils/resolve-bank-type-id.utils";
|
||||||
import { PrismaModule } from "src/prisma/prisma.module";
|
import { PrismaModule } from "src/prisma/prisma.module";
|
||||||
|
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
import { Injectable } from "@nestjs/common";
|
|
||||||
import { Prisma, PrismaClient } from "@prisma/client";
|
|
||||||
import { weekStartSunday } from "src/modules/shifts/helpers/shifts-date-time-helpers";
|
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
|
||||||
|
|
||||||
|
|
||||||
type Tx = Prisma.TransactionClient | PrismaClient;
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class EmployeeTimesheetResolver {
|
|
||||||
constructor(private readonly prisma: PrismaService) {}
|
|
||||||
|
|
||||||
//find an existing timesheet linked to the employee
|
|
||||||
readonly ensureForDate = async (employee_id: number, date: Date, client?: Tx,
|
|
||||||
): Promise<{id: number; start_date: Date }> => {
|
|
||||||
const db = client ?? this.prisma;
|
|
||||||
const startOfWeek = weekStartSunday(date);
|
|
||||||
const existing = await db.timesheets.findFirst({
|
|
||||||
where: {
|
|
||||||
employee_id: employee_id,
|
|
||||||
start_date: startOfWeek,
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
start_date: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if(existing) return existing;
|
|
||||||
|
|
||||||
const created = await db.timesheets.create({
|
|
||||||
data: {
|
|
||||||
employee_id: employee_id,
|
|
||||||
start_date: startOfWeek,
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
start_date: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return created;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
29
src/modules/shared/utils/resolve-shifts-id.utils.ts
Normal file
29
src/modules/shared/utils/resolve-shifts-id.utils.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { Prisma, PrismaClient } from "@prisma/client";
|
||||||
|
import { NotFoundException } from "@nestjs/common";
|
||||||
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
|
import { ShiftKey } from "../interfaces/shifts.interface";
|
||||||
|
|
||||||
|
type Tx = Prisma.TransactionClient | PrismaClient;
|
||||||
|
|
||||||
|
export class ShiftIdResolver {
|
||||||
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
|
readonly findShiftIdByData = async ( key: ShiftKey, client?: Tx ): Promise<{id:number}> => {
|
||||||
|
const db = client ?? this.prisma;
|
||||||
|
const shift = await db.shifts.findFirst({
|
||||||
|
where: {
|
||||||
|
timesheet_id: key.timesheet_id,
|
||||||
|
bank_code_id: key.bank_code_id,
|
||||||
|
date: key.date,
|
||||||
|
start_time: key.start_time,
|
||||||
|
end_time: key.end_time,
|
||||||
|
is_remote: key.is_remote,
|
||||||
|
comment: key.comment,
|
||||||
|
},
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!shift) throw new NotFoundException(`shift not found`);
|
||||||
|
return { id: shift.id };
|
||||||
|
};
|
||||||
|
}
|
||||||
28
src/modules/shared/utils/resolve-timesheet.utils.ts
Normal file
28
src/modules/shared/utils/resolve-timesheet.utils.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { Injectable, NotFoundException } from "@nestjs/common";
|
||||||
|
import { Prisma, PrismaClient } from "@prisma/client";
|
||||||
|
import { weekStartSunday } from "src/modules/shifts/helpers/shifts-date-time-helpers";
|
||||||
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
|
import { EmailToIdResolver } from "./resolve-email-id.utils";
|
||||||
|
|
||||||
|
|
||||||
|
type Tx = Prisma.TransactionClient | PrismaClient;
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class EmployeeTimesheetResolver {
|
||||||
|
constructor(
|
||||||
|
private readonly prisma: PrismaService,
|
||||||
|
private readonly emailResolver: EmailToIdResolver,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
readonly findTimesheetIdByEmail = async (email: string, date: Date, client?: Tx): Promise<{id: number}> => {
|
||||||
|
const db = client ?? this.prisma;
|
||||||
|
const employee_id = await this.emailResolver.findIdByEmail(email);
|
||||||
|
const start_date = weekStartSunday(date);
|
||||||
|
const timesheet = await db.timesheets.findFirst({
|
||||||
|
where: { employee_id : employee_id, start_date: start_date },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
if(!timesheet) throw new NotFoundException(`timesheet not found`);
|
||||||
|
return { id: timesheet.id };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,7 @@ export function toDateOnly(ymd: string): Date {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function weekStartSunday(date_local: Date): Date {
|
export function weekStartSunday(date_local: Date): Date {
|
||||||
const start = new Date(date_local.getFullYear(), date_local.getMonth(), date_local.getDate());
|
const start = new Date(Date.UTC(date_local.getFullYear(), date_local.getMonth(), date_local.getDate()));
|
||||||
const dow = start.getDay(); // 0 = dimanche
|
const dow = start.getDay(); // 0 = dimanche
|
||||||
start.setDate(start.getDate() - dow);
|
start.setDate(start.getDate() - dow);
|
||||||
start.setHours(0, 0, 0, 0);
|
start.setHours(0, 0, 0, 0);
|
||||||
|
|
|
||||||
|
|
@ -114,10 +114,13 @@ export class ShiftsHelpersService {
|
||||||
async afterWriteOvertimeAndLog(tx: Tx, employee_id: number, date_only: Date) {
|
async afterWriteOvertimeAndLog(tx: Tx, employee_id: number, date_only: Date) {
|
||||||
// Switch regular → weekly overtime si > 40h
|
// Switch regular → weekly overtime si > 40h
|
||||||
await this.overtimeService.transformRegularHoursToWeeklyOvertime(employee_id, date_only, tx);
|
await this.overtimeService.transformRegularHoursToWeeklyOvertime(employee_id, date_only, tx);
|
||||||
const [daily, weekly] = await Promise.all([
|
const daily = await this.overtimeService.getDailyOvertimeHoursForDay(employee_id, date_only);
|
||||||
this.overtimeService.getDailyOvertimeHoursForDay(employee_id, date_only),
|
const weekly = await this.overtimeService.getWeeklyOvertimeHours(employee_id, date_only);
|
||||||
this.overtimeService.getWeeklyOvertimeHours(employee_id, date_only),
|
// const [daily, weekly] = await Promise.all([
|
||||||
]);
|
// this.overtimeService.getDailyOvertimeHoursForDay(employee_id, date_only),
|
||||||
|
// this.overtimeService.getWeeklyOvertimeHours(employee_id, date_only),
|
||||||
|
// ]);
|
||||||
|
return { daily, weekly };
|
||||||
}
|
}
|
||||||
|
|
||||||
async mapDay(
|
async mapDay(
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common";
|
import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common";
|
||||||
import { EmployeeTimesheetResolver } from "src/modules/shared/utils/resolve-employee-timesheet.utils";
|
import { EmployeeTimesheetResolver } from "src/modules/shared/utils/resolve-timesheet.utils";
|
||||||
import { getWeekEnd, getWeekStart } from "src/common/utils/date-utils";
|
import { getWeekEnd, getWeekStart } from "src/common/utils/date-utils";
|
||||||
import { parseISODate, parseHHmm } from "../utils-helpers-others/timesheet.helpers";
|
import { parseISODate, parseHHmm } from "../utils-helpers-others/timesheet.helpers";
|
||||||
import { TimesheetsQueryService } from "./timesheets-query.service";
|
import { TimesheetsQueryService } from "./timesheets-query.service";
|
||||||
|
|
@ -69,7 +69,7 @@ export class TimesheetsCommandService extends BaseApprovalService<Timesheets>{
|
||||||
const start_week = getWeekStart(base, 0);
|
const start_week = getWeekStart(base, 0);
|
||||||
const end_week = getWeekEnd(start_week);
|
const end_week = getWeekEnd(start_week);
|
||||||
|
|
||||||
const timesheet = await this.timesheetResolver.ensureForDate(employee_id, base)
|
const timesheet = await this.timesheetResolver.findTimesheetIdByEmail(email, base)
|
||||||
if(!timesheet) throw new NotFoundException(`no timesheet found for employe ${employee_id}`);
|
if(!timesheet) throw new NotFoundException(`no timesheet found for employe ${employee_id}`);
|
||||||
|
|
||||||
//validations and insertions
|
//validations and insertions
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user