refactor(utils): moved utils to shared utils folder
This commit is contained in:
parent
ac1eaabb5d
commit
5e49bc5df6
|
|
@ -1,20 +1,6 @@
|
||||||
{
|
{
|
||||||
"openapi": "3.0.0",
|
"openapi": "3.0.0",
|
||||||
"paths": {
|
"paths": {
|
||||||
"/": {
|
|
||||||
"get": {
|
|
||||||
"operationId": "AppController_getHello",
|
|
||||||
"parameters": [],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tags": [
|
|
||||||
"App"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/health": {
|
"/health": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "HealthController_check",
|
"operationId": "HealthController_check",
|
||||||
|
|
@ -319,16 +305,16 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/preferences/{email}": {
|
"/preferences": {
|
||||||
"patch": {
|
"patch": {
|
||||||
"operationId": "PreferencesController_updatePreferences",
|
"operationId": "PreferencesController_updatePreferences",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"name": "email",
|
"name": "PreferencesDto",
|
||||||
"required": true,
|
"required": true,
|
||||||
"in": "path",
|
"in": "body",
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string"
|
"$ref": "#/components/schemas/PreferencesDto"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -337,7 +323,7 @@
|
||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/PreferencesDto"
|
"type": "number"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,4 @@
|
||||||
import { Controller, Get } from '@nestjs/common';
|
import { Controller, Get } from '@nestjs/common';
|
||||||
import { AppService } from './app.service';
|
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
export class AppController {
|
export class AppController { }
|
||||||
constructor(private readonly appService: AppService) {}
|
|
||||||
|
|
||||||
@Get()
|
|
||||||
getHello(): string {
|
|
||||||
return this.appService.getHello();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AppService {
|
export class AppService { }
|
||||||
getHello(): string {
|
|
||||||
return 'Hello World!';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Body, Controller, Param, Patch } from "@nestjs/common";
|
import { Body, Controller, Patch } from "@nestjs/common";
|
||||||
import { PreferencesService } from "../services/preferences.service";
|
import { PreferencesService } from "../services/preferences.service";
|
||||||
import { PreferencesDto } from "../dtos/preferences.dto";
|
import { PreferencesDto } from "../dtos/preferences.dto";
|
||||||
|
|
||||||
|
|
@ -6,9 +6,12 @@ import { PreferencesDto } from "../dtos/preferences.dto";
|
||||||
export class PreferencesController {
|
export class PreferencesController {
|
||||||
constructor(private readonly service: PreferencesService){}
|
constructor(private readonly service: PreferencesService){}
|
||||||
|
|
||||||
@Patch(':email')
|
@Patch()
|
||||||
async updatePreferences(@Param('email') email: string, @Body()payload: PreferencesDto) {
|
async updatePreferences(
|
||||||
return this.service.updatePreferences(email, payload);
|
@Body() user_id: number,
|
||||||
|
@Body() payload: PreferencesDto
|
||||||
|
) {
|
||||||
|
return this.service.updatePreferences(user_id, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
import { Module } from "@nestjs/common";
|
|
||||||
import { PreferencesController } from "./controllers/preferences.controller";
|
import { PreferencesController } from "./controllers/preferences.controller";
|
||||||
import { PreferencesService } from "./services/preferences.service";
|
import { PreferencesService } from "./services/preferences.service";
|
||||||
import { SharedModule } from "../../time-and-attendance/modules/shared/shared.module";
|
import { Module } from "@nestjs/common";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [SharedModule],
|
|
||||||
controllers: [ PreferencesController ],
|
controllers: [ PreferencesController ],
|
||||||
providers: [ PreferencesService ],
|
providers: [ PreferencesService ],
|
||||||
exports: [ PreferencesService ],
|
exports: [ PreferencesService ],
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,15 @@
|
||||||
import { Injectable } from "@nestjs/common";
|
|
||||||
import { Preferences } from "@prisma/client";
|
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
|
||||||
import { PreferencesDto } from "../dtos/preferences.dto";
|
import { PreferencesDto } from "../dtos/preferences.dto";
|
||||||
import { EmailToIdResolver } from "src/time-and-attendance/modules/shared/utils/resolve-email-id.utils";
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
|
import { Preferences } from "@prisma/client";
|
||||||
|
import { Injectable } from "@nestjs/common";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PreferencesService {
|
export class PreferencesService {
|
||||||
constructor(
|
constructor( private readonly prisma: PrismaService ){}
|
||||||
private readonly prisma: PrismaService,
|
|
||||||
private readonly emailResolver: EmailToIdResolver ,
|
|
||||||
){}
|
|
||||||
|
|
||||||
async updatePreferences(email: string, dto: PreferencesDto ): Promise<Preferences> {
|
async updatePreferences(user_id: number, dto: PreferencesDto ): Promise<Preferences> {
|
||||||
const user_id = await this.emailResolver.resolveUserIdWithEmail(email);
|
|
||||||
return this.prisma.preferences.update({
|
return this.prisma.preferences.update({
|
||||||
where: { user_id },
|
where: { id: user_id },
|
||||||
data: {
|
data: {
|
||||||
notifications: dto.notifications,
|
notifications: dto.notifications,
|
||||||
dark_mode: dto.dark_mode,
|
dark_mode: dto.dark_mode,
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,15 @@
|
||||||
import { Module } from "@nestjs/common";
|
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
|
||||||
//import { AfterHoursService } from "./services/after-hours.service";
|
|
||||||
import { HolidayService } from "./services/holiday.service";
|
|
||||||
import { OvertimeService } from "./services/overtime.service";
|
|
||||||
import { SickLeaveService } from "./services/sick-leave.service";
|
import { SickLeaveService } from "./services/sick-leave.service";
|
||||||
|
import { OvertimeService } from "./services/overtime.service";
|
||||||
import { VacationService } from "./services/vacation.service";
|
import { VacationService } from "./services/vacation.service";
|
||||||
|
import { HolidayService } from "./services/holiday.service";
|
||||||
import { MileageService } from "./services/mileage.service";
|
import { MileageService } from "./services/mileage.service";
|
||||||
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
|
import { Module } from "@nestjs/common";
|
||||||
|
|
||||||
|
|
||||||
//AfterHours is not used, need to clarify infos before implementing into shifts.service
|
|
||||||
@Module({
|
@Module({
|
||||||
providers: [
|
providers: [
|
||||||
PrismaService,
|
PrismaService,
|
||||||
//AfterHoursService,
|
|
||||||
HolidayService,
|
HolidayService,
|
||||||
MileageService,
|
MileageService,
|
||||||
OvertimeService,
|
OvertimeService,
|
||||||
|
|
@ -20,7 +17,6 @@ import { MileageService } from "./services/mileage.service";
|
||||||
VacationService
|
VacationService
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
//AfterHoursService,
|
|
||||||
HolidayService,
|
HolidayService,
|
||||||
MileageService,
|
MileageService,
|
||||||
OvertimeService,
|
OvertimeService,
|
||||||
|
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
|
||||||
import { PrismaService } from "../../../prisma/prisma.service";
|
|
||||||
|
|
||||||
|
|
||||||
//THIS SERVICE IS NOT USED, RULES TO BE DETERMINED WITH MIKE/HR/ACCOUNTING
|
|
||||||
@Injectable()
|
|
||||||
export class AfterHoursService {
|
|
||||||
private readonly logger = new Logger(AfterHoursService.name);
|
|
||||||
private static readonly BUSINESS_START = 7;
|
|
||||||
private static readonly BUSINESS_END = 18;
|
|
||||||
private static readonly ROUND_MINUTES = 15;
|
|
||||||
|
|
||||||
constructor(private readonly prisma: PrismaService) {}
|
|
||||||
|
|
||||||
|
|
||||||
private getPreBusinessMinutes(start: Date, end: Date): number {
|
|
||||||
const biz_start = new Date(start);
|
|
||||||
biz_start.setHours(AfterHoursService.BUSINESS_START, 0,0,0);
|
|
||||||
|
|
||||||
if (end>= start || start >= biz_start) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const segment_end = end < biz_start ? end : biz_start;
|
|
||||||
const minutes = (segment_end.getTime() - start.getTime()) / 60000;
|
|
||||||
|
|
||||||
this.logger.debug(`getPreBusinessMintutes -> ${minutes.toFixed(1)}min`);
|
|
||||||
return minutes;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private getPostBusinessMinutes(start: Date, end: Date): number {
|
|
||||||
const biz_end = new Date(start);
|
|
||||||
biz_end.setHours(AfterHoursService.BUSINESS_END,0,0,0);
|
|
||||||
|
|
||||||
if( end <= biz_end ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const segment_start = start > biz_end ? start : biz_end;
|
|
||||||
const minutes = (end.getTime() - segment_start.getTime()) / 60000;
|
|
||||||
|
|
||||||
this.logger.debug(`getPostBusinessMintutes -> ${minutes.toFixed(1)}min`);
|
|
||||||
return minutes;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private roundToNearestQUarterMinute(minutes: number): number {
|
|
||||||
const rounded = Math.round(minutes / AfterHoursService.ROUND_MINUTES)
|
|
||||||
* AfterHoursService.ROUND_MINUTES;
|
|
||||||
this.logger.debug(`roundToNearestQuarterMinute -> raw=${minutes.toFixed(1)}min, rounded= ${rounded}min`);
|
|
||||||
return rounded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public computeAfterHours(start: Date, end:Date): number {
|
|
||||||
if(end.getTime() <= start.getTime()) {
|
|
||||||
throw new BadRequestException('The end cannot be before the starting of the shift');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start.toDateString() !== end.toDateString()) {
|
|
||||||
throw new BadRequestException('you cannot enter a shift that start in a day and end in the next' +
|
|
||||||
'You must create 2 instances, one on the first day and the second during the next day.');
|
|
||||||
}
|
|
||||||
|
|
||||||
const pre_min = this.getPreBusinessMinutes(start, end);
|
|
||||||
const post_min = this.getPostBusinessMinutes(start, end);
|
|
||||||
const raw_aftermin = pre_min + post_min;
|
|
||||||
|
|
||||||
const rounded_min = this.roundToNearestQUarterMinute(raw_aftermin);
|
|
||||||
|
|
||||||
const hours = rounded_min / 60;
|
|
||||||
const result = parseFloat(hours.toFixed(2));
|
|
||||||
|
|
||||||
this.logger.debug(`computeAfterHours -> raw_aftermin = ${raw_aftermin.toFixed(1)}min, +
|
|
||||||
rounded = ${rounded_min}min, hours = ${result.toFixed(2)}`);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,16 +1,12 @@
|
||||||
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post } from "@nestjs/common";
|
import { Body, Controller, Delete, Param, ParseIntPipe, Patch, Post } from "@nestjs/common";
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
|
||||||
import { ExpenseDto } from "../dtos/expense.dto";
|
|
||||||
import { CreateResult, ExpenseUpsertService, UpdateResult } from "../services/expense-upsert.service";
|
import { CreateResult, ExpenseUpsertService, UpdateResult } from "../services/expense-upsert.service";
|
||||||
import { updateExpenseDto } from "src/time-and-attendance/modules/expenses/dtos/update-expense.dto";
|
import { updateExpenseDto } from "src/time-and-attendance/modules/expenses/dtos/expense-update.dto";
|
||||||
|
import { ExpenseDto } from "../dtos/expense-create.dto";
|
||||||
|
|
||||||
|
|
||||||
@Controller('expense')
|
@Controller('expense')
|
||||||
export class ExpenseController {
|
export class ExpenseController {
|
||||||
constructor(
|
constructor( private readonly upsert_service: ExpenseUpsertService ){}
|
||||||
private readonly prisma: PrismaService,
|
|
||||||
private readonly upsert_service: ExpenseUpsertService,
|
|
||||||
){}
|
|
||||||
|
|
||||||
@Post(':timesheet_id')
|
@Post(':timesheet_id')
|
||||||
create(
|
create(
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { OmitType, PartialType } from "@nestjs/swagger";
|
import { OmitType, PartialType } from "@nestjs/swagger";
|
||||||
import { ExpenseDto } from "./expense.dto";
|
import { ExpenseDto } from "./expense-create.dto";
|
||||||
|
|
||||||
export class updateExpenseDto extends PartialType (
|
export class updateExpenseDto extends PartialType (
|
||||||
OmitType(ExpenseDto, ['is_approved', 'timesheet_id'] as const)
|
OmitType(ExpenseDto, ['is_approved', 'timesheet_id'] as const)
|
||||||
|
|
@ -2,14 +2,10 @@ import { ExpensesArchivalService } from "./services/expenses-archival.service";
|
||||||
import { ExpenseUpsertService } from "src/time-and-attendance/modules/expenses/services/expense-upsert.service";
|
import { ExpenseUpsertService } from "src/time-and-attendance/modules/expenses/services/expense-upsert.service";
|
||||||
import { ExpenseController } from "src/time-and-attendance/modules/expenses/controllers/expense.controller";
|
import { ExpenseController } from "src/time-and-attendance/modules/expenses/controllers/expense.controller";
|
||||||
import { Module } from "@nestjs/common";
|
import { Module } from "@nestjs/common";
|
||||||
import { BusinessLogicsModule } from "src/time-and-attendance/domains/business-logics.module";
|
|
||||||
import { SharedModule } from "src/time-and-attendance/modules/shared/shared.module";
|
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [ BusinessLogicsModule, SharedModule ],
|
|
||||||
controllers: [ ExpenseController ],
|
controllers: [ ExpenseController ],
|
||||||
providers: [ ExpenseUpsertService, ExpensesArchivalService ],
|
providers: [ ExpenseUpsertService, ExpensesArchivalService ],
|
||||||
exports: [ ExpensesArchivalService ],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export class ExpensesModule {}
|
export class ExpensesModule {}
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
export const toDateFromString = (ymd: string): Date => {
|
|
||||||
return new Date(`${ymd}T00:00:00:000Z`);
|
|
||||||
}
|
|
||||||
export const toStringFromDate = (date: Date) =>
|
|
||||||
date.toISOString().slice(0,10);
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
import { toDateFromString, toStringFromDate } from "../helpers/expenses-date-time-helpers";
|
|
||||||
|
import { toDateFromString, toStringFromDate } from "src/time-and-attendance/utils/date-time-helpers";
|
||||||
import { Injectable, NotFoundException } from "@nestjs/common";
|
import { Injectable, NotFoundException } from "@nestjs/common";
|
||||||
import { updateExpenseDto } from "../dtos/update-expense.dto";
|
import { updateExpenseDto } from "../dtos/expense-update.dto";
|
||||||
import { GetExpenseDto } from "../dtos/get-expense.dto";
|
import { GetExpenseDto } from "../dtos/expense-get.dto";
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
import { ExpenseDto } from "../dtos/expense.dto";
|
import { ExpenseDto } from "../dtos/expense-create.dto";
|
||||||
|
import { Prisma } from "@prisma/client";
|
||||||
|
|
||||||
type Normalized = { date: Date; comment: string; supervisor_comment?: string; };
|
type Normalized = { date: Date; comment: string; supervisor_comment?: string; };
|
||||||
|
|
||||||
|
|
@ -43,18 +45,7 @@ export class ExpenseUpsertService {
|
||||||
is_approved: dto.is_approved,
|
is_approved: dto.is_approved,
|
||||||
},
|
},
|
||||||
//return the newly created expense with id
|
//return the newly created expense with id
|
||||||
select: {
|
select: expense_select,
|
||||||
id: true,
|
|
||||||
timesheet_id: true,
|
|
||||||
bank_code_id: true,
|
|
||||||
attachment: true,
|
|
||||||
date: true,
|
|
||||||
amount: true,
|
|
||||||
mileage: true,
|
|
||||||
comment: true,
|
|
||||||
supervisor_comment: true,
|
|
||||||
is_approved: true,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//build an object to return to the frontend to display
|
//build an object to return to the frontend to display
|
||||||
|
|
@ -103,18 +94,7 @@ export class ExpenseUpsertService {
|
||||||
const expense = await this.prisma.expenses.update({
|
const expense = await this.prisma.expenses.update({
|
||||||
where: { id },
|
where: { id },
|
||||||
data,
|
data,
|
||||||
select: {
|
select: expense_select,
|
||||||
id: true,
|
|
||||||
timesheet_id: true,
|
|
||||||
bank_code_id: true,
|
|
||||||
attachment: true,
|
|
||||||
date: true,
|
|
||||||
amount: true,
|
|
||||||
mileage: true,
|
|
||||||
comment: true,
|
|
||||||
supervisor_comment: true,
|
|
||||||
is_approved: true,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const updated: GetExpenseDto = {
|
const updated: GetExpenseDto = {
|
||||||
|
|
@ -181,4 +161,21 @@ export class ExpenseUpsertService {
|
||||||
if (Number.isNaN(parsed)) throw new Error(`Invalid value : ${value} for ${field}`);
|
if (Number.isNaN(parsed)) throw new Error(`Invalid value : ${value} for ${field}`);
|
||||||
return parsed;
|
return parsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const expense_select = {
|
||||||
|
id: true,
|
||||||
|
timesheet_id: true,
|
||||||
|
bank_code_id: true,
|
||||||
|
attachment: true,
|
||||||
|
date: true,
|
||||||
|
amount: true,
|
||||||
|
mileage: true,
|
||||||
|
comment: true,
|
||||||
|
supervisor_comment: true,
|
||||||
|
is_approved: true,
|
||||||
|
} satisfies Prisma.ExpensesSelect;
|
||||||
|
|
@ -1,18 +1,17 @@
|
||||||
import { Module } from "@nestjs/common";
|
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
|
||||||
import { BusinessLogicsModule } from "src/time-and-attendance/domains/business-logics.module";
|
|
||||||
import { HolidayService } from "src/time-and-attendance/domains/services/holiday.service";
|
|
||||||
import { SickLeaveService } from "src/time-and-attendance/domains/services/sick-leave.service";
|
|
||||||
import { VacationService } from "src/time-and-attendance/domains/services/vacation.service";
|
|
||||||
import { LeaveRequestController } from "src/time-and-attendance/modules/leave-requests/controllers/leave-requests.controller";
|
import { LeaveRequestController } from "src/time-and-attendance/modules/leave-requests/controllers/leave-requests.controller";
|
||||||
import { LeaveRequestsService } from "src/time-and-attendance/modules/leave-requests/services/leave-request.service";
|
import { LeaveRequestsService } from "src/time-and-attendance/modules/leave-requests/services/leave-request.service";
|
||||||
|
import { BusinessLogicsModule } from "src/time-and-attendance/domains/business-logics.module";
|
||||||
import { LeaveRequestsUtils } from "src/time-and-attendance/modules/leave-requests/utils/leave-request.util";
|
import { LeaveRequestsUtils } from "src/time-and-attendance/modules/leave-requests/utils/leave-request.util";
|
||||||
import { SharedModule } from "src/time-and-attendance/modules/shared/shared.module";
|
import { SickLeaveService } from "src/time-and-attendance/domains/services/sick-leave.service";
|
||||||
|
import { VacationService } from "src/time-and-attendance/domains/services/vacation.service";
|
||||||
|
import { HolidayService } from "src/time-and-attendance/domains/services/holiday.service";
|
||||||
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
import { ShiftsModule } from "src/time-and-attendance/modules/time-tracker/shifts/shifts.module";
|
import { ShiftsModule } from "src/time-and-attendance/modules/time-tracker/shifts/shifts.module";
|
||||||
|
import { Module } from "@nestjs/common";
|
||||||
|
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [BusinessLogicsModule, ShiftsModule, SharedModule],
|
imports: [BusinessLogicsModule, ShiftsModule ],
|
||||||
controllers: [LeaveRequestController],
|
controllers: [LeaveRequestController],
|
||||||
providers: [
|
providers: [
|
||||||
VacationService,
|
VacationService,
|
||||||
|
|
@ -22,9 +21,6 @@ import { ShiftsModule } from "src/time-and-attendance/modules/time-tracker/shift
|
||||||
PrismaService,
|
PrismaService,
|
||||||
LeaveRequestsUtils,
|
LeaveRequestsUtils,
|
||||||
],
|
],
|
||||||
exports: [
|
|
||||||
LeaveRequestsService,
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export class LeaveRequestsModule {}
|
export class LeaveRequestsModule {}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
import { LeaveRequestViewDto } from "../dtos/leave-request-view.dto";
|
import { LeaveRequestViewDto } from "../dtos/leave-request-view.dto";
|
||||||
import { LeaveRequestRow } from "../utils/leave-requests.select";
|
import { LeaveRequestRow } from "src/time-and-attendance/utils/selects.utils";
|
||||||
|
|
||||||
const toNum = (value?: Prisma.Decimal | null) =>
|
const toNum = (value?: Prisma.Decimal | null) =>
|
||||||
value !== null && value !== undefined ? Number(value) : undefined;
|
value !== null && value !== undefined ? Number(value) : undefined;
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
import { Injectable, NotFoundException, BadRequestException } from "@nestjs/common";
|
import { Injectable, NotFoundException, BadRequestException } from "@nestjs/common";
|
||||||
import { LeaveTypes, LeaveApprovalStatus } from "@prisma/client";
|
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
|
||||||
import { HolidayService } from "src/time-and-attendance/domains/services/holiday.service";
|
|
||||||
import { LeaveRequestViewDto } from "src/time-and-attendance/modules/leave-requests/dtos/leave-request-view.dto";
|
|
||||||
import { UpsertLeaveRequestDto, UpsertResult } from "src/time-and-attendance/modules/leave-requests/dtos/upsert-leave-request.dto";
|
import { UpsertLeaveRequestDto, UpsertResult } from "src/time-and-attendance/modules/leave-requests/dtos/upsert-leave-request.dto";
|
||||||
import { mapRowToView } from "src/time-and-attendance/modules/leave-requests/mappers/leave-requests.mapper";
|
import { LeaveTypes, LeaveApprovalStatus } from "@prisma/client";
|
||||||
import { LeaveRequestsUtils } from "src/time-and-attendance/modules/leave-requests/utils/leave-request.util";
|
|
||||||
import { leaveRequestsSelect } from "src/time-and-attendance/modules/leave-requests/utils/leave-requests.select";
|
|
||||||
import { normalizeDates, toDateOnly } from "src/time-and-attendance/modules/shared/helpers/date-time.helpers";
|
import { normalizeDates, toDateOnly } from "src/time-and-attendance/modules/shared/helpers/date-time.helpers";
|
||||||
|
import { LeaveRequestViewDto } from "src/time-and-attendance/modules/leave-requests/dtos/leave-request-view.dto";
|
||||||
|
import { leaveRequestsSelect } from "src/time-and-attendance/utils/selects.utils";
|
||||||
|
import { LeaveRequestsUtils } from "src/time-and-attendance/modules/leave-requests/utils/leave-request.util";
|
||||||
import { BankCodesResolver } from "src/time-and-attendance/modules/shared/utils/resolve-bank-type-id.utils";
|
import { BankCodesResolver } from "src/time-and-attendance/modules/shared/utils/resolve-bank-type-id.utils";
|
||||||
import { EmailToIdResolver } from "src/time-and-attendance/modules/shared/utils/resolve-email-id.utils";
|
import { EmailToIdResolver } from "src/time-and-attendance/modules/shared/utils/resolve-email-id.utils";
|
||||||
|
import { HolidayService } from "src/time-and-attendance/domains/services/holiday.service";
|
||||||
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
|
import { mapRowToView } from "src/time-and-attendance/modules/leave-requests/mappers/leave-requests.mapper";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|
@ -26,8 +26,8 @@ export class HolidayLeaveRequestsService {
|
||||||
const email = dto.email.trim();
|
const email = dto.email.trim();
|
||||||
const employee_id = await this.emailResolver.findIdByEmail(email);
|
const employee_id = await this.emailResolver.findIdByEmail(email);
|
||||||
const bank_code = await this.typeResolver.findByType(LeaveTypes.HOLIDAY);
|
const bank_code = await this.typeResolver.findByType(LeaveTypes.HOLIDAY);
|
||||||
if(!bank_code) throw new NotFoundException(`bank_code not found`);
|
|
||||||
const dates = normalizeDates(dto.dates);
|
const dates = normalizeDates(dto.dates);
|
||||||
|
if (!bank_code) throw new NotFoundException(`bank_code not found`);
|
||||||
if (!dates.length) throw new BadRequestException('Dates array must not be empty');
|
if (!dates.length) throw new BadRequestException('Dates array must not be empty');
|
||||||
|
|
||||||
const created: LeaveRequestViewDto[] = [];
|
const created: LeaveRequestViewDto[] = [];
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import { roundToQuarterHour } from "src/common/utils/date-utils";
|
||||||
import { UpsertLeaveRequestDto, UpsertResult } from "../dtos/upsert-leave-request.dto";
|
import { UpsertLeaveRequestDto, UpsertResult } from "../dtos/upsert-leave-request.dto";
|
||||||
import { LeaveRequestViewDto } from "../dtos/leave-request-view.dto";
|
import { LeaveRequestViewDto } from "../dtos/leave-request-view.dto";
|
||||||
import { mapRowToView } from "../mappers/leave-requests.mapper";
|
import { mapRowToView } from "../mappers/leave-requests.mapper";
|
||||||
import { leaveRequestsSelect } from "../utils/leave-requests.select";
|
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
import { HolidayService } from "src/time-and-attendance/domains/services/holiday.service";
|
import { HolidayService } from "src/time-and-attendance/domains/services/holiday.service";
|
||||||
import { SickLeaveService } from "src/time-and-attendance/domains/services/sick-leave.service";
|
import { SickLeaveService } from "src/time-and-attendance/domains/services/sick-leave.service";
|
||||||
|
|
@ -13,14 +12,13 @@ import { normalizeDates, toDateOnly, toISODateKey } from "src/time-and-attendanc
|
||||||
import { BankCodesResolver } from "src/time-and-attendance/modules/shared/utils/resolve-bank-type-id.utils";
|
import { BankCodesResolver } from "src/time-and-attendance/modules/shared/utils/resolve-bank-type-id.utils";
|
||||||
import { EmailToIdResolver } from "src/time-and-attendance/modules/shared/utils/resolve-email-id.utils";
|
import { EmailToIdResolver } from "src/time-and-attendance/modules/shared/utils/resolve-email-id.utils";
|
||||||
import { LeaveRequestsUtils } from "src/time-and-attendance/modules/leave-requests/utils/leave-request.util";
|
import { LeaveRequestsUtils } from "src/time-and-attendance/modules/leave-requests/utils/leave-request.util";
|
||||||
|
import { leaveRequestsSelect } from "src/time-and-attendance/utils/selects.utils";
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LeaveRequestsService {
|
export class LeaveRequestsService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly prisma: PrismaService,
|
private readonly prisma: PrismaService,
|
||||||
private readonly holidayService: HolidayService,
|
private readonly holidayService: HolidayService,
|
||||||
private readonly sickLogic: SickLeaveService,
|
private readonly sickLogic: SickLeaveService,
|
||||||
private readonly sickLeaveService: SickLeaveService,
|
|
||||||
private readonly vacationService: VacationService,
|
|
||||||
private readonly vacationLogic: VacationService,
|
private readonly vacationLogic: VacationService,
|
||||||
private readonly leaveUtils: LeaveRequestsUtils,
|
private readonly leaveUtils: LeaveRequestsUtils,
|
||||||
private readonly emailResolver: EmailToIdResolver,
|
private readonly emailResolver: EmailToIdResolver,
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ import { LeaveRequestViewDto } from "src/time-and-attendance/modules/leave-reque
|
||||||
import { UpsertLeaveRequestDto, UpsertResult } from "src/time-and-attendance/modules/leave-requests/dtos/upsert-leave-request.dto";
|
import { UpsertLeaveRequestDto, UpsertResult } from "src/time-and-attendance/modules/leave-requests/dtos/upsert-leave-request.dto";
|
||||||
import { mapRowToView } from "src/time-and-attendance/modules/leave-requests/mappers/leave-requests.mapper";
|
import { mapRowToView } from "src/time-and-attendance/modules/leave-requests/mappers/leave-requests.mapper";
|
||||||
import { LeaveRequestsUtils } from "src/time-and-attendance/modules/leave-requests/utils/leave-request.util";
|
import { LeaveRequestsUtils } from "src/time-and-attendance/modules/leave-requests/utils/leave-request.util";
|
||||||
import { leaveRequestsSelect } from "src/time-and-attendance/modules/leave-requests/utils/leave-requests.select";
|
|
||||||
import { normalizeDates, toDateOnly } from "src/time-and-attendance/modules/shared/helpers/date-time.helpers";
|
import { normalizeDates, toDateOnly } from "src/time-and-attendance/modules/shared/helpers/date-time.helpers";
|
||||||
import { BankCodesResolver } from "src/time-and-attendance/modules/shared/utils/resolve-bank-type-id.utils";
|
import { BankCodesResolver } from "src/time-and-attendance/modules/shared/utils/resolve-bank-type-id.utils";
|
||||||
import { EmailToIdResolver } from "src/time-and-attendance/modules/shared/utils/resolve-email-id.utils";
|
import { EmailToIdResolver } from "src/time-and-attendance/modules/shared/utils/resolve-email-id.utils";
|
||||||
|
import { leaveRequestsSelect } from "src/time-and-attendance/utils/selects.utils";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|
@ -18,7 +18,6 @@ export class SickLeaveRequestsService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly prisma: PrismaService,
|
private readonly prisma: PrismaService,
|
||||||
private readonly sickService: SickLeaveService,
|
private readonly sickService: SickLeaveService,
|
||||||
private readonly leaveUtils: LeaveRequestsUtils,
|
|
||||||
private readonly emailResolver: EmailToIdResolver,
|
private readonly emailResolver: EmailToIdResolver,
|
||||||
private readonly typeResolver: BankCodesResolver,
|
private readonly typeResolver: BankCodesResolver,
|
||||||
) {}
|
) {}
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,10 @@ import { VacationService } from "src/time-and-attendance/domains/services/vacati
|
||||||
import { LeaveRequestViewDto } from "src/time-and-attendance/modules/leave-requests/dtos/leave-request-view.dto";
|
import { LeaveRequestViewDto } from "src/time-and-attendance/modules/leave-requests/dtos/leave-request-view.dto";
|
||||||
import { UpsertLeaveRequestDto, UpsertResult } from "src/time-and-attendance/modules/leave-requests/dtos/upsert-leave-request.dto";
|
import { UpsertLeaveRequestDto, UpsertResult } from "src/time-and-attendance/modules/leave-requests/dtos/upsert-leave-request.dto";
|
||||||
import { mapRowToView } from "src/time-and-attendance/modules/leave-requests/mappers/leave-requests.mapper";
|
import { mapRowToView } from "src/time-and-attendance/modules/leave-requests/mappers/leave-requests.mapper";
|
||||||
import { LeaveRequestsUtils } from "src/time-and-attendance/modules/leave-requests/utils/leave-request.util";
|
|
||||||
import { leaveRequestsSelect } from "src/time-and-attendance/modules/leave-requests/utils/leave-requests.select";
|
|
||||||
import { normalizeDates, toDateOnly } from "src/time-and-attendance/modules/shared/helpers/date-time.helpers";
|
import { normalizeDates, toDateOnly } from "src/time-and-attendance/modules/shared/helpers/date-time.helpers";
|
||||||
import { BankCodesResolver } from "src/time-and-attendance/modules/shared/utils/resolve-bank-type-id.utils";
|
import { BankCodesResolver } from "src/time-and-attendance/modules/shared/utils/resolve-bank-type-id.utils";
|
||||||
import { EmailToIdResolver } from "src/time-and-attendance/modules/shared/utils/resolve-email-id.utils";
|
import { EmailToIdResolver } from "src/time-and-attendance/modules/shared/utils/resolve-email-id.utils";
|
||||||
|
import { leaveRequestsSelect } from "src/time-and-attendance/utils/selects.utils";
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
|
@ -18,7 +17,6 @@ export class VacationLeaveRequestsService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly prisma: PrismaService,
|
private readonly prisma: PrismaService,
|
||||||
private readonly vacationService: VacationService,
|
private readonly vacationService: VacationService,
|
||||||
private readonly leaveUtils: LeaveRequestsUtils,
|
|
||||||
private readonly emailResolver: EmailToIdResolver,
|
private readonly emailResolver: EmailToIdResolver,
|
||||||
private readonly typeResolver: BankCodesResolver,
|
private readonly typeResolver: BankCodesResolver,
|
||||||
) {}
|
) {}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
|
import { LeaveRequestRow } from 'src/time-and-attendance/utils/selects.utils';
|
||||||
import { LeaveRequestViewDto } from '../dtos/leave-request-view.dto';
|
import { LeaveRequestViewDto } from '../dtos/leave-request-view.dto';
|
||||||
import { mapArchiveRowToView } from '../mappers/leave-requests-archive.mapper';
|
import { mapArchiveRowToView } from '../mappers/leave-requests-archive.mapper';
|
||||||
import { mapRowToView } from '../mappers/leave-requests.mapper';
|
import { mapRowToView } from '../mappers/leave-requests.mapper';
|
||||||
import { LeaveRequestArchiveRow } from './leave-requests-archive.select';
|
import { LeaveRequestArchiveRow } from './leave-requests-archive.select';
|
||||||
import { LeaveRequestRow } from './leave-requests.select';
|
|
||||||
|
|
||||||
/** Active (table leave_requests) : proxy to base mapper */
|
/** Active (table leave_requests) : proxy to base mapper */
|
||||||
export function mapRowToViewWithDays(row: LeaveRequestRow): LeaveRequestViewDto {
|
export function mapRowToViewWithDays(row: LeaveRequestRow): LeaveRequestViewDto {
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,16 @@
|
||||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
import { LeaveTypes } from "@prisma/client";
|
import { LeaveTypes } from "@prisma/client";
|
||||||
import { toDateOnly, toStringFromDate, hhmmFromLocal } from "src/time-and-attendance/modules/shared/helpers/date-time.helpers";
|
// import { toDateOnly, toStringFromDate } from "src/time-and-attendance/modules/shared/helpers/date-time.helpers";
|
||||||
import { UpsertAction } from "src/time-and-attendance/modules/shared/types/upsert-actions.types";
|
import { UpsertAction } from "src/time-and-attendance/modules/shared/types/upsert-actions.types";
|
||||||
import { ShiftsUpsertService } from "src/time-and-attendance/modules/time-tracker/shifts/services/shifts-upsert.service";
|
import { toDateFromString, toStringFromDate } from "src/time-and-attendance/utils/date-time-helpers";
|
||||||
|
// import { ShiftsUpsertService } from "src/time-and-attendance/modules/time-tracker/shifts/services/shifts-upsert.service";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LeaveRequestsUtils {
|
export class LeaveRequestsUtils {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly prisma: PrismaService,
|
private readonly prisma: PrismaService,
|
||||||
private readonly shiftsService: ShiftsUpsertService,
|
// private readonly shiftsService: ShiftsUpsertService,
|
||||||
){}
|
){}
|
||||||
|
|
||||||
async syncShift(
|
async syncShift(
|
||||||
|
|
@ -27,7 +28,7 @@ export class LeaveRequestsUtils {
|
||||||
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 = toDateOnly(date);
|
const date_only = toDateFromString(date);
|
||||||
const yyyy_mm_dd = toStringFromDate(date_only);
|
const yyyy_mm_dd = toStringFromDate(date_only);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -78,7 +79,7 @@ export class LeaveRequestsUtils {
|
||||||
iso_date: string,
|
iso_date: string,
|
||||||
type: LeaveTypes,
|
type: LeaveTypes,
|
||||||
) {
|
) {
|
||||||
const date_only = toDateOnly(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: {
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,14 @@
|
||||||
import { PayPeriodsQueryService } from "./services/pay-periods-query.service";
|
import { PayPeriodsQueryService } from "./services/pay-periods-query.service";
|
||||||
import { BusinessLogicsModule } from "src/time-and-attendance/domains/business-logics.module";
|
|
||||||
import { PayPeriodsController } from "./controllers/pay-periods.controller";
|
import { PayPeriodsController } from "./controllers/pay-periods.controller";
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
import { PrismaModule } from "src/prisma/prisma.module";
|
|
||||||
import { SharedModule } from "../shared/shared.module";
|
|
||||||
import { Module } from "@nestjs/common";
|
import { Module } from "@nestjs/common";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [PrismaModule, SharedModule, BusinessLogicsModule],
|
|
||||||
providers: [
|
providers: [
|
||||||
PayPeriodsQueryService,
|
PayPeriodsQueryService,
|
||||||
PrismaService,
|
PrismaService,
|
||||||
],
|
],
|
||||||
controllers: [PayPeriodsController],
|
controllers: [PayPeriodsController],
|
||||||
exports: [ PayPeriodsQueryService ],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export class PayperiodsModule {}
|
export class PayperiodsModule {}
|
||||||
|
|
@ -1,14 +1,10 @@
|
||||||
|
import { toStringFromDate, toUTCDate } from "src/time-and-attendance/utils/date-time-helpers";
|
||||||
|
|
||||||
export const ANCHOR_ISO = '2023-12-17'; // ancre date
|
export const ANCHOR_ISO = '2023-12-17'; // ancre date
|
||||||
const PERIOD_DAYS = 14;
|
const PERIOD_DAYS = 14;
|
||||||
const PERIODS_PER_YEAR = 26;
|
const PERIODS_PER_YEAR = 26;
|
||||||
const MS_PER_DAY = 86_400_000;
|
const MS_PER_DAY = 86_400_000;
|
||||||
|
|
||||||
const toUTCDate = (iso: string | Date) => {
|
|
||||||
const d = typeof iso === 'string' ? new Date(iso + 'T00:00:00.000Z') : iso;
|
|
||||||
return new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
|
|
||||||
};
|
|
||||||
export const toDateString = (d: Date) => d.toISOString().slice(0, 10);
|
|
||||||
|
|
||||||
export function payYearOfDate(date: string | Date, anchorISO = ANCHOR_ISO): number {
|
export function payYearOfDate(date: string | Date, anchorISO = ANCHOR_ISO): number {
|
||||||
const ANCHOR = toUTCDate(anchorISO);
|
const ANCHOR = toUTCDate(anchorISO);
|
||||||
const d = toUTCDate(date);
|
const d = toUTCDate(date);
|
||||||
|
|
@ -27,10 +23,10 @@ export function computePeriod(pay_year: number, period_no: number, anchorISO = A
|
||||||
return {
|
return {
|
||||||
period_no: period_no,
|
period_no: period_no,
|
||||||
pay_year: pay_year,
|
pay_year: pay_year,
|
||||||
payday: toDateString(pay),
|
payday: toStringFromDate(pay),
|
||||||
period_start: toDateString(start),
|
period_start: toStringFromDate(start),
|
||||||
period_end: toDateString(end),
|
period_end: toStringFromDate(end),
|
||||||
label: `${toDateString(start)}.${toDateString(end)}`,
|
label: `${toStringFromDate(start)}.${toStringFromDate(end)}`,
|
||||||
start, end,
|
start, end,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
export const MS_PER_DAY = 86_400_000;
|
|
||||||
export const MS_PER_HOUR = 3_600_000;
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
const HH_MM_REGEX = /^([01]\d|2[0-3]):[0-5]\d$/;
|
|
||||||
const DATE_ISO_FORMAT = /^\d{4}-\d{2}-\d{2}$/;
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export const COMMENT_MAX_LENGTH = 280;
|
|
||||||
|
|
@ -15,8 +15,8 @@ export const toDateOnly = (s: string): Date => {
|
||||||
return new Date(dt.getFullYear(), dt.getMonth(), dt.getDate(), 0,0,0,0);
|
return new Date(dt.getFullYear(), dt.getMonth(), dt.getDate(), 0,0,0,0);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const toStringFromDate = (d: Date) =>
|
// export const toStringFromDate = (d: Date) =>
|
||||||
`${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;
|
// `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;
|
||||||
|
|
||||||
|
|
||||||
export const toISOtoDateOnly = (iso: string): Date => {
|
export const toISOtoDateOnly = (iso: string): Date => {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Injectable, NotFoundException } from "@nestjs/common";
|
import { Injectable, NotFoundException } from "@nestjs/common";
|
||||||
import { Prisma, PrismaClient } from "@prisma/client";
|
import { Prisma, PrismaClient } from "@prisma/client";
|
||||||
import { weekStartSunday } from "src/time-and-attendance/modules/time-tracker/shifts/helpers/shifts-date-time-helpers";
|
import { weekStartSunday } from "src/time-and-attendance/utils/date-time-helpers";
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
import { EmailToIdResolver } from "./resolve-email-id.utils";
|
import { EmailToIdResolver } from "./resolve-email-id.utils";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,12 @@
|
||||||
import { BadRequestException, Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post, Query } from "@nestjs/common";
|
import { BadRequestException, Body, Controller, Delete, Param, ParseIntPipe, Patch, Post } from "@nestjs/common";
|
||||||
import { CreateResult, ShiftsUpsertService, UpdateResult } from "../services/shifts-upsert.service";
|
import { CreateResult, ShiftsUpsertService, UpdateResult } from "../services/shifts-upsert.service";
|
||||||
import { updateShiftDto } from "../dtos/update-shift.dto";
|
import { updateShiftDto } from "../dtos/shift-update.dto";
|
||||||
import { ShiftDto } from "../dtos/shift.dto";
|
import { ShiftDto } from "../dtos/shift-create.dto";
|
||||||
import { ShiftsGetService } from "../services/shifts-get.service";
|
|
||||||
|
|
||||||
|
|
||||||
@Controller('shift')
|
@Controller('shift')
|
||||||
export class ShiftController {
|
export class ShiftController {
|
||||||
constructor(
|
constructor( private readonly upsert_service: ShiftsUpsertService ){}
|
||||||
private readonly upsert_service: ShiftsUpsertService,
|
|
||||||
private readonly get_service: ShiftsGetService
|
|
||||||
){}
|
|
||||||
|
|
||||||
// @Get()
|
|
||||||
// async getShiftsByIds(
|
|
||||||
// @Query("shift_ids") shift_ids: string) {
|
|
||||||
// const parsed = shift_ids.split(/,\s*/).map(value => Number(value)).filter(Number.isFinite);
|
|
||||||
// return this.get_service.getShiftByShiftId(parsed);
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Post(':timesheet_id')
|
@Post(':timesheet_id')
|
||||||
createBatch(
|
createBatch(
|
||||||
|
|
@ -25,7 +14,6 @@ export class ShiftController {
|
||||||
@Body()dtos: ShiftDto[]): Promise<CreateResult[]> {
|
@Body()dtos: ShiftDto[]): Promise<CreateResult[]> {
|
||||||
const list = Array.isArray(dtos) ? dtos : [];
|
const list = Array.isArray(dtos) ? dtos : [];
|
||||||
if(list.length === 0) throw new BadRequestException('Body is missing or invalid (create shifts)')
|
if(list.length === 0) throw new BadRequestException('Body is missing or invalid (create shifts)')
|
||||||
|
|
||||||
return this.upsert_service.createShifts(timesheet_id, dtos)
|
return this.upsert_service.createShifts(timesheet_id, dtos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { PartialType, OmitType } from "@nestjs/swagger";
|
import { PartialType, OmitType } from "@nestjs/swagger";
|
||||||
import { ShiftDto } from "./shift.dto";
|
import { ShiftDto } from "./shift-create.dto";
|
||||||
|
|
||||||
export class updateShiftDto extends PartialType (
|
export class updateShiftDto extends PartialType (
|
||||||
//allows update using ShiftDto and preventing OmitType variables to be modified
|
//allows update using ShiftDto and preventing OmitType variables to be modified
|
||||||
|
|
@ -1,6 +1,19 @@
|
||||||
|
import { Injectable } from "@nestjs/common";
|
||||||
import { ShiftsArchive } from "@prisma/client";
|
import { ShiftsArchive } from "@prisma/client";
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _____________________________________________________________________________________
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This service is not used. Will be use to atrchive a list of shifts using a cron job.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* _____________________________________________________________________________________
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
export class ShiftsArchivalService {
|
export class ShiftsArchivalService {
|
||||||
constructor(private readonly prisma: PrismaService){}
|
constructor(private readonly prisma: PrismaService){}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,18 @@
|
||||||
import { Injectable, NotFoundException } from "@nestjs/common";
|
import { Injectable, NotFoundException } from "@nestjs/common";
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
import { GetShiftDto } from "../dtos/get-shift.dto";
|
import { GetShiftDto } from "../dtos/shift-get.dto";
|
||||||
import { toStringFromDate, toStringFromHHmm } from "../helpers/shifts-date-time-helpers";
|
import { toStringFromDate, toStringFromHHmm } from "../../../../utils/date-time-helpers";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _____________________________________________________________________________________
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This service is not used. Could be use to show a list of shifts.
|
||||||
|
*
|
||||||
|
* For the moment, the module Timesheets is used to display shifts, filtered by employee
|
||||||
|
*
|
||||||
|
* _____________________________________________________________________________________
|
||||||
|
*/
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ShiftsGetService {
|
export class ShiftsGetService {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { toDateFromString, toHHmmFromString, toStringFromDate, toStringFromHHmm } from "../helpers/shifts-date-time-helpers";
|
import { toDateFromString, toHHmmFromString, toStringFromDate, toStringFromHHmm } from "../../../../utils/date-time-helpers";
|
||||||
import { BadRequestException, ConflictException, Injectable, NotFoundException } from "@nestjs/common";
|
import { BadRequestException, ConflictException, Injectable, NotFoundException } from "@nestjs/common";
|
||||||
import { OvertimeService, WeekOvertimeSummary } from "src/time-and-attendance/domains/services/overtime.service";
|
import { OvertimeService, WeekOvertimeSummary } from "src/time-and-attendance/domains/services/overtime.service";
|
||||||
import { updateShiftDto } from "../dtos/update-shift.dto";
|
import { updateShiftDto } from "../dtos/shift-update.dto";
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
import { GetShiftDto } from "../dtos/get-shift.dto";
|
import { GetShiftDto } from "../dtos/shift-get.dto";
|
||||||
import { ShiftDto } from "../dtos/shift.dto";
|
import { ShiftDto } from "../dtos/shift-create.dto";
|
||||||
|
|
||||||
type Normalized = { date: Date; start_time: Date; end_time: Date; };
|
type Normalized = { date: Date; start_time: Date; end_time: Date; };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,13 @@
|
||||||
import { ShiftsArchivalService } from './services/shifts-archival.service';
|
|
||||||
import { BusinessLogicsModule } from 'src/time-and-attendance/domains/business-logics.module';
|
import { BusinessLogicsModule } from 'src/time-and-attendance/domains/business-logics.module';
|
||||||
import { NotificationsModule } from '../../../../modules/notifications/notifications.module';
|
|
||||||
import { ShiftsUpsertService } from './services/shifts-upsert.service';
|
import { ShiftsUpsertService } from './services/shifts-upsert.service';
|
||||||
import { ShiftsGetService } from './services/shifts-get.service';
|
import { ShiftsGetService } from './services/shifts-get.service';
|
||||||
import { ShiftController } from './controllers/shift.controller';
|
import { ShiftController } from './controllers/shift.controller';
|
||||||
import { SharedModule } from '../../shared/shared.module';
|
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [ BusinessLogicsModule ],
|
||||||
BusinessLogicsModule,
|
|
||||||
NotificationsModule,
|
|
||||||
SharedModule,
|
|
||||||
],
|
|
||||||
controllers: [ShiftController],
|
controllers: [ShiftController],
|
||||||
providers: [
|
providers: [ ShiftsGetService, ShiftsUpsertService ],
|
||||||
ShiftsArchivalService,
|
exports: [ ShiftsUpsertService ],
|
||||||
ShiftsGetService,
|
|
||||||
ShiftsUpsertService,
|
|
||||||
],
|
|
||||||
exports: [ ShiftsUpsertService, ShiftsGetService ],
|
|
||||||
})
|
})
|
||||||
export class ShiftsModule {}
|
export class ShiftsModule {}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
//ensures the week starts from sunday
|
||||||
export function weekStartSunday(date_local: Date): Date {
|
export function weekStartSunday(date_local: Date): Date {
|
||||||
const start = new Date(Date.UTC(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
|
||||||
|
|
@ -29,3 +30,8 @@ export const toHHmmFromString = (hhmm: string): Date => {
|
||||||
export const toDateFromString = (ymd: string): Date => {
|
export const toDateFromString = (ymd: string): Date => {
|
||||||
return new Date(`${ymd}T00:00:00:000Z`);
|
return new Date(`${ymd}T00:00:00:000Z`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const toUTCDate = (iso: string | Date) => {
|
||||||
|
const d = typeof iso === 'string' ? new Date(iso + 'T00:00:00.000Z') : iso;
|
||||||
|
return new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
|
||||||
|
};
|
||||||
|
|
@ -1,6 +1,20 @@
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
|
|
||||||
//custom prisma select to avoid employee_id exposure
|
|
||||||
|
export const expense_select = {
|
||||||
|
id: true,
|
||||||
|
timesheet_id: true,
|
||||||
|
bank_code_id: true,
|
||||||
|
attachment: true,
|
||||||
|
date: true,
|
||||||
|
amount: true,
|
||||||
|
mileage: true,
|
||||||
|
comment: true,
|
||||||
|
supervisor_comment: true,
|
||||||
|
is_approved: true,
|
||||||
|
} satisfies Prisma.ExpensesSelect;
|
||||||
|
|
||||||
|
|
||||||
export const leaveRequestsSelect = {
|
export const leaveRequestsSelect = {
|
||||||
id: true,
|
id: true,
|
||||||
bank_code_id: true,
|
bank_code_id: true,
|
||||||
79
src/~misc_deprecated-files/after-hours.service.ts
Normal file
79
src/~misc_deprecated-files/after-hours.service.ts
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
// import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
||||||
|
// import { PrismaService } from "../prisma/prisma.service";
|
||||||
|
|
||||||
|
|
||||||
|
// //THIS SERVICE IS NOT USED, RULES TO BE DETERMINED WITH MIKE/HR/ACCOUNTING
|
||||||
|
// @Injectable()
|
||||||
|
// export class AfterHoursService {
|
||||||
|
// private readonly logger = new Logger(AfterHoursService.name);
|
||||||
|
// private static readonly BUSINESS_START = 7;
|
||||||
|
// private static readonly BUSINESS_END = 18;
|
||||||
|
// private static readonly ROUND_MINUTES = 15;
|
||||||
|
|
||||||
|
// constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
|
|
||||||
|
// private getPreBusinessMinutes(start: Date, end: Date): number {
|
||||||
|
// const biz_start = new Date(start);
|
||||||
|
// biz_start.setHours(AfterHoursService.BUSINESS_START, 0,0,0);
|
||||||
|
|
||||||
|
// if (end>= start || start >= biz_start) {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const segment_end = end < biz_start ? end : biz_start;
|
||||||
|
// const minutes = (segment_end.getTime() - start.getTime()) / 60000;
|
||||||
|
|
||||||
|
// this.logger.debug(`getPreBusinessMintutes -> ${minutes.toFixed(1)}min`);
|
||||||
|
// return minutes;
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private getPostBusinessMinutes(start: Date, end: Date): number {
|
||||||
|
// const biz_end = new Date(start);
|
||||||
|
// biz_end.setHours(AfterHoursService.BUSINESS_END,0,0,0);
|
||||||
|
|
||||||
|
// if( end <= biz_end ) {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const segment_start = start > biz_end ? start : biz_end;
|
||||||
|
// const minutes = (end.getTime() - segment_start.getTime()) / 60000;
|
||||||
|
|
||||||
|
// this.logger.debug(`getPostBusinessMintutes -> ${minutes.toFixed(1)}min`);
|
||||||
|
// return minutes;
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private roundToNearestQUarterMinute(minutes: number): number {
|
||||||
|
// const rounded = Math.round(minutes / AfterHoursService.ROUND_MINUTES)
|
||||||
|
// * AfterHoursService.ROUND_MINUTES;
|
||||||
|
// this.logger.debug(`roundToNearestQuarterMinute -> raw=${minutes.toFixed(1)}min, rounded= ${rounded}min`);
|
||||||
|
// return rounded;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public computeAfterHours(start: Date, end:Date): number {
|
||||||
|
// if(end.getTime() <= start.getTime()) {
|
||||||
|
// throw new BadRequestException('The end cannot be before the starting of the shift');
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (start.toDateString() !== end.toDateString()) {
|
||||||
|
// throw new BadRequestException('you cannot enter a shift that start in a day and end in the next' +
|
||||||
|
// 'You must create 2 instances, one on the first day and the second during the next day.');
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const pre_min = this.getPreBusinessMinutes(start, end);
|
||||||
|
// const post_min = this.getPostBusinessMinutes(start, end);
|
||||||
|
// const raw_aftermin = pre_min + post_min;
|
||||||
|
|
||||||
|
// const rounded_min = this.roundToNearestQUarterMinute(raw_aftermin);
|
||||||
|
|
||||||
|
// const hours = rounded_min / 60;
|
||||||
|
// const result = parseFloat(hours.toFixed(2));
|
||||||
|
|
||||||
|
// this.logger.debug(`computeAfterHours -> raw_aftermin = ${raw_aftermin.toFixed(1)}min, +
|
||||||
|
// rounded = ${rounded_min}min, hours = ${result.toFixed(2)}`);
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
2
src/~misc_deprecated-files/date-time.constant.ts
Normal file
2
src/~misc_deprecated-files/date-time.constant.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
// export const MS_PER_DAY = 86_400_000;
|
||||||
|
// export const MS_PER_HOUR = 3_600_000;
|
||||||
23
src/~misc_deprecated-files/leave-requests.select.ts
Normal file
23
src/~misc_deprecated-files/leave-requests.select.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
// import { Prisma } from "@prisma/client";
|
||||||
|
|
||||||
|
// //custom prisma select to avoid employee_id exposure
|
||||||
|
// export const leaveRequestsSelect = {
|
||||||
|
// id: true,
|
||||||
|
// bank_code_id: true,
|
||||||
|
// leave_type: true,
|
||||||
|
// date: true,
|
||||||
|
// payable_hours: true,
|
||||||
|
// requested_hours: true,
|
||||||
|
// comment: true,
|
||||||
|
// approval_status: true,
|
||||||
|
// employee: { select: {
|
||||||
|
// id: true,
|
||||||
|
// user: { select: {
|
||||||
|
// email: true,
|
||||||
|
// first_name: true,
|
||||||
|
// last_name: true,
|
||||||
|
// }},
|
||||||
|
// }},
|
||||||
|
// } satisfies Prisma.LeaveRequestsSelect;
|
||||||
|
|
||||||
|
// export type LeaveRequestRow = Prisma.LeaveRequestsGetPayload<{ select: typeof leaveRequestsSelect}>;
|
||||||
2
src/~misc_deprecated-files/regex.constant.ts
Normal file
2
src/~misc_deprecated-files/regex.constant.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
// const HH_MM_REGEX = /^([01]\d|2[0-3]):[0-5]\d$/;
|
||||||
|
// const DATE_ISO_FORMAT = /^\d{4}-\d{2}-\d{2}$/;
|
||||||
1
src/~misc_deprecated-files/utils.constant.ts
Normal file
1
src/~misc_deprecated-files/utils.constant.ts
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
// export const COMMENT_MAX_LENGTH = 280;
|
||||||
Loading…
Reference in New Issue
Block a user