feat(business-logic): implementation of business-logics services into their respective modules.
This commit is contained in:
parent
5766715d77
commit
2d69cfdb86
|
|
@ -17,25 +17,27 @@ import { PayperiodsModule } from './modules/pay-periods/pay-periods.module';
|
|||
import { ScheduleModule } from '@nestjs/schedule';
|
||||
import { ArchivalModule } from './modules/archival/archival.module';
|
||||
import { BankCodesModule } from './modules/bank-codes/bank-codes.module';
|
||||
import { OvertimeService } from './business-logic/overtime.service';
|
||||
import { OvertimeService } from './business-logics/services/overtime.service';
|
||||
import { BusinessLogicsModule } from './business-logics/business-logics.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
ScheduleModule.forRoot(),
|
||||
BankCodesModule,
|
||||
ArchivalModule,
|
||||
PrismaModule,
|
||||
HealthModule,
|
||||
UsersModule,
|
||||
OauthAccessTokensModule,
|
||||
AuthenticationModule,
|
||||
BankCodesModule,
|
||||
BusinessLogicsModule,
|
||||
CustomersModule,
|
||||
EmployeesModule,
|
||||
LeaveRequestsModule,
|
||||
ExpensesModule,
|
||||
HealthModule,
|
||||
LeaveRequestsModule,
|
||||
OauthAccessTokensModule,
|
||||
PayperiodsModule,
|
||||
PrismaModule,
|
||||
ShiftsModule,
|
||||
TimesheetsModule,
|
||||
AuthenticationModule,
|
||||
PayperiodsModule,
|
||||
UsersModule,
|
||||
],
|
||||
controllers: [AppController, HealthController],
|
||||
providers: [AppService, OvertimeService],
|
||||
|
|
|
|||
32
src/business-logics/business-logics.module.ts
Normal file
32
src/business-logics/business-logics.module.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
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 { VacationService } from "./services/vacation.service";
|
||||
import { MileageService } from "./services/mileage.service";
|
||||
|
||||
|
||||
//AfterHours is not used, need to clarify infos before implementing into shifts.service
|
||||
@Module({
|
||||
providers: [
|
||||
PrismaService,
|
||||
//AfterHoursService,
|
||||
HolidayService,
|
||||
MileageService,
|
||||
OvertimeService,
|
||||
SickLeaveService,
|
||||
VacationService
|
||||
],
|
||||
exports: [
|
||||
//AfterHoursService,
|
||||
HolidayService,
|
||||
MileageService,
|
||||
OvertimeService,
|
||||
SickLeaveService,
|
||||
VacationService,
|
||||
],
|
||||
})
|
||||
|
||||
export class BusinessLogicsModule {}
|
||||
79
src/business-logics/services/after-hours.service.ts
Normal file
79
src/business-logics/services/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 bizStart = new Date(start);
|
||||
bizStart.setHours(AfterHoursService.BUSINESS_START, 0,0,0);
|
||||
|
||||
if (end>= start || start >= bizStart) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const segmentEnd = end < bizStart ? end : bizStart;
|
||||
const minutes = (segmentEnd.getTime() - start.getTime()) / 60000;
|
||||
|
||||
this.logger.debug(`getPreBusinessMintutes -> ${minutes.toFixed(1)}min`);
|
||||
return minutes;
|
||||
|
||||
}
|
||||
|
||||
private getPostBusinessMinutes(start: Date, end: Date): number {
|
||||
const bizEnd = new Date(start);
|
||||
bizEnd.setHours(AfterHoursService.BUSINESS_END,0,0,0);
|
||||
|
||||
if( end <= bizEnd ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const segmentStart = start > bizEnd ? start : bizEnd;
|
||||
const minutes = (end.getTime() - segmentStart.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 preMin = this.getPreBusinessMinutes(start, end);
|
||||
const postMin = this.getPostBusinessMinutes(start, end);
|
||||
const rawAftermin = preMin + postMin;
|
||||
|
||||
const roundedMin = this.roundToNearestQUarterMinute(rawAftermin);
|
||||
|
||||
const hours = roundedMin / 60;
|
||||
const result = parseFloat(hours.toFixed(2));
|
||||
|
||||
this.logger.debug(`computeAfterHours -> rawAfterMin= ${rawAftermin.toFixed(1)}min, +
|
||||
rounded = ${roundedMin}min, hours = ${result.toFixed(2)}`);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { Injectable, Logger } from "@nestjs/common";
|
||||
import { PrismaService } from "src/prisma/prisma.service";
|
||||
import { PrismaService } from "../../prisma/prisma.service";
|
||||
|
||||
@Injectable()
|
||||
export class HolidayService {
|
||||
36
src/business-logics/services/mileage.service.ts
Normal file
36
src/business-logics/services/mileage.service.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
||||
import { PrismaService } from "../../prisma/prisma.service";
|
||||
import { Decimal } from "@prisma/client/runtime/library";
|
||||
|
||||
@Injectable()
|
||||
export class MileageService {
|
||||
private readonly logger = new Logger(MileageService.name);
|
||||
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
public async calculateReimbursement(amount: number, bankCodeId: number): Promise<number> {
|
||||
if(amount < 0) {
|
||||
throw new BadRequestException(`The amount most be higher than 0`);
|
||||
}
|
||||
|
||||
//fetch modifier
|
||||
const bankCode = await this.prisma.bankCodes.findUnique({
|
||||
where: { id: bankCodeId },
|
||||
select: { modifier: true, type: true },
|
||||
});
|
||||
|
||||
if(!bankCode) {
|
||||
throw new BadRequestException(`bank_code ${bankCodeId} not found`);
|
||||
}
|
||||
if(bankCode.type !== 'mileage') {
|
||||
this.logger.warn(`bank_code ${bankCodeId} of type ${bankCode.type} is used for mileage`)
|
||||
}
|
||||
|
||||
//calculate total amount to reimburs
|
||||
const reimboursement = amount * bankCode.modifier;
|
||||
const result = parseFloat(reimboursement.toFixed(2));
|
||||
this.logger.debug(`calculateReimbursement -> amount= ${amount}, modifier= ${bankCode.modifier}, total= ${result}`);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { PrismaService } from 'src/prisma/prisma.service';
|
||||
import { PrismaService } from '../../prisma/prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class OvertimeService {
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { Injectable, Logger } from "@nestjs/common";
|
||||
import { PrismaService } from "src/prisma/prisma.service";
|
||||
import { PrismaService } from "../../prisma/prisma.service";
|
||||
|
||||
@Injectable()
|
||||
export class SickLeaveService {
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
import { Injectable, Logger, NotFoundException } from "@nestjs/common";
|
||||
import { PrismaService } from "src/prisma/prisma.service";
|
||||
import { PrismaService } from "../../prisma/prisma.service";
|
||||
|
||||
@Injectable()
|
||||
export class VacationService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
private readonly logger = new Logger(VacationService.name);
|
||||
/**
|
||||
|
||||
/**
|
||||
* Calculate the ammount allowed for vacation days.
|
||||
*
|
||||
* @param employeeId employee ID
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import { Module } from "@nestjs/common";
|
||||
|
||||
import { PrismaService } from "src/prisma/prisma.service";
|
||||
import { BankCodesControllers } from "./controllers/bank-codes.controller";
|
||||
import { BankCodesService } from "./services/bank-codes.services";
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ import { PrismaService } from "src/prisma/prisma.service";
|
|||
import { ExpensesController } from "./controllers/expenses.controller";
|
||||
import { Module } from "@nestjs/common";
|
||||
import { ExpensesService } from "./services/expenses.service";
|
||||
import { BusinessLogicsModule } from "src/business-logics/business-logics.module";
|
||||
|
||||
@Module({
|
||||
imports: [BusinessLogicsModule],
|
||||
controllers: [ExpensesController],
|
||||
providers: [ExpensesService, PrismaService],
|
||||
providers: [ExpensesService],
|
||||
exports: [ ExpensesService ],
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -3,48 +3,55 @@ import { PrismaService } from "src/prisma/prisma.service";
|
|||
import { CreateExpenseDto } from "../dtos/create-expense";
|
||||
import { Expenses, ExpensesArchive } from "@prisma/client";
|
||||
import { UpdateExpenseDto } from "../dtos/update-expense";
|
||||
import { MileageService } from "src/business-logics/services/mileage.service";
|
||||
|
||||
@Injectable()
|
||||
export class ExpensesService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
constructor(
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly mileageService: MileageService,
|
||||
) {}
|
||||
|
||||
async create(dto: CreateExpenseDto): Promise<Expenses> {
|
||||
const { timesheet_id, bank_code_id, date, amount,
|
||||
const { timesheet_id, bank_code_id, date, amount:rawAmount,
|
||||
description, is_approved,supervisor_comment} = dto;
|
||||
return this.prisma.expenses.create({
|
||||
data: { timesheet_id, bank_code_id,date,amount,description,is_approved,supervisor_comment},
|
||||
include: {
|
||||
timesheet: {
|
||||
include: {
|
||||
employee: { include: { user: true } },
|
||||
},
|
||||
},
|
||||
bank_code: true,
|
||||
},
|
||||
|
||||
|
||||
//fetches type and modifier
|
||||
const bankCode = await this.prisma.bankCodes.findUnique({
|
||||
where: { id: bank_code_id },
|
||||
select: { type: true, modifier: true },
|
||||
});
|
||||
if(!bankCode) {
|
||||
throw new NotFoundException(`bank_code #${bank_code_id} not found`)
|
||||
}
|
||||
|
||||
//if mileage -> service, otherwise the ratio is amount:1
|
||||
let finalAmount: number;
|
||||
if(bankCode.type === 'mileage') {
|
||||
finalAmount = await this.mileageService.calculateReimbursement(rawAmount, bank_code_id);
|
||||
}else {
|
||||
finalAmount = parseFloat( (rawAmount * bankCode.modifier).toFixed(2));
|
||||
}
|
||||
|
||||
return this.prisma.expenses.create({
|
||||
data: { timesheet_id, bank_code_id, date, amount: finalAmount, description, is_approved, supervisor_comment},
|
||||
include: { timesheet: { include: { employee: { include: { user: true }}}},
|
||||
bank_code: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
findAll(): Promise<Expenses[]> {
|
||||
return this.prisma.expenses.findMany({
|
||||
include: {
|
||||
timesheet: {
|
||||
include: {
|
||||
employee: { include: { user: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
include: { timesheet: { include: { employee: { include: { user: true } } } } },
|
||||
});
|
||||
}
|
||||
|
||||
async findOne(id: number): Promise<Expenses> {
|
||||
const expense = await this.prisma.expenses.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
timesheet: {
|
||||
include: {
|
||||
employee: { include: { user:true } },
|
||||
},
|
||||
},
|
||||
include: { timesheet: { include: { employee: { include: { user:true } } } },
|
||||
bank_code: true,
|
||||
},
|
||||
});
|
||||
|
|
@ -69,14 +76,7 @@ export class ExpensesService {
|
|||
...(is_approved !== undefined && { is_approved }),
|
||||
...(supervisor_comment !== undefined && { supervisor_comment }),
|
||||
},
|
||||
include: {
|
||||
timesheet: {
|
||||
include: {
|
||||
employee: {
|
||||
include: { user: true }
|
||||
},
|
||||
},
|
||||
},
|
||||
include: { timesheet: { include: { employee: { include: { user: true } } } },
|
||||
bank_code: true,
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,21 +1,13 @@
|
|||
import { PrismaService } from "src/prisma/prisma.service";
|
||||
import { LeaveRequestController } from "./controllers/leave-requests.controller";
|
||||
import { LeaveRequestsService } from "./services/leave-requests.service";
|
||||
import { Module } from "@nestjs/common";
|
||||
import { HolidayService } from "src/business-logic/holiday.service";
|
||||
import { VacationService } from "src/business-logic/vacation.service";
|
||||
import { SickLeaveService } from "src/business-logic/sick-leave.service";
|
||||
import { BusinessLogicsModule } from "src/business-logics/business-logics.module";
|
||||
|
||||
@Module({
|
||||
imports: [BusinessLogicsModule],
|
||||
controllers: [LeaveRequestController],
|
||||
providers: [
|
||||
LeaveRequestsService,
|
||||
PrismaService,
|
||||
HolidayService,
|
||||
VacationService,
|
||||
SickLeaveService,
|
||||
],
|
||||
exports: [ LeaveRequestsService],
|
||||
providers: [LeaveRequestsService],
|
||||
exports: [LeaveRequestsService],
|
||||
})
|
||||
|
||||
export class LeaveRequestsModule {}
|
||||
|
|
@ -3,9 +3,9 @@ import { PrismaService } from "src/prisma/prisma.service";
|
|||
import { CreateLeaveRequestsDto } from "../dtos/create-leave-requests.dto";
|
||||
import { LeaveRequests, LeaveRequestsArchive } from "@prisma/client";
|
||||
import { UpdateLeaveRequestsDto } from "../dtos/update-leave-requests.dto";
|
||||
import { HolidayService } from "src/business-logic/holiday.service";
|
||||
import { VacationService } from "src/business-logic/vacation.service";
|
||||
import { SickLeaveService } from "src/business-logic/sick-leave.service";
|
||||
import { HolidayService } from "src/business-logics/services/holiday.service";
|
||||
import { SickLeaveService } from "src/business-logics/services/sick-leave.service";
|
||||
import { VacationService } from "src/business-logics/services/vacation.service";
|
||||
|
||||
@Injectable()
|
||||
export class LeaveRequestsService {
|
||||
|
|
|
|||
|
|
@ -12,12 +12,7 @@ export class ShiftsService {
|
|||
const { timesheet_id, bank_code_id, date, start_time, end_time } = dto;
|
||||
return this.prisma.shifts.create({
|
||||
data: { timesheet_id, bank_code_id, date, start_time, end_time },
|
||||
include: {
|
||||
timesheet: {
|
||||
include: {
|
||||
employee: { include: { user: true } },
|
||||
},
|
||||
},
|
||||
include: { timesheet: { include: { employee: { include: { user: true } } } },
|
||||
bank_code: true,
|
||||
},
|
||||
});
|
||||
|
|
@ -25,29 +20,14 @@ export class ShiftsService {
|
|||
|
||||
findAll(): Promise<Shifts[]> {
|
||||
return this.prisma.shifts.findMany({
|
||||
include: {
|
||||
timesheet: {
|
||||
include: {
|
||||
employee: {
|
||||
include: { user:true }
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
include: { timesheet: { include: { employee: { include: { user:true } } } } },
|
||||
});
|
||||
}
|
||||
|
||||
async findOne(id: number): Promise<Shifts> {
|
||||
const shift = await this.prisma.shifts.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
timesheet: {
|
||||
include: {
|
||||
employee: {
|
||||
include: { user: true }
|
||||
},
|
||||
},
|
||||
},
|
||||
include: { timesheet: { include: { employee: { include: { user: true } } } },
|
||||
bank_code: true,
|
||||
},
|
||||
});
|
||||
|
|
@ -69,14 +49,7 @@ export class ShiftsService {
|
|||
...(start_time !== undefined && { start_time }),
|
||||
...(end_time !== undefined && { end_time }),
|
||||
},
|
||||
include: {
|
||||
timesheet: {
|
||||
include: {
|
||||
employee: {
|
||||
include: { user: true }
|
||||
},
|
||||
},
|
||||
},
|
||||
include: { timesheet: { include: { employee: { include: { user: true } } } },
|
||||
bank_code: true,
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { ShiftsController } from './controllers/shifts.controller';
|
||||
import { ShiftsService } from './services/shifts.service';
|
||||
import { PrismaService } from 'src/prisma/prisma.service';
|
||||
import { BusinessLogicsModule } from 'src/business-logics/business-logics.module';
|
||||
|
||||
@Module({
|
||||
imports: [BusinessLogicsModule],
|
||||
controllers: [ShiftsController],
|
||||
providers: [ShiftsService, PrismaService],
|
||||
providers: [ShiftsService],
|
||||
exports: [ShiftsService],
|
||||
})
|
||||
export class ShiftsModule {}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { PrismaService } from 'src/prisma/prisma.service';
|
|||
import { CreateTimesheetDto } from '../dtos/create-timesheet.dto';
|
||||
import { Timesheets, TimesheetsArchive } from '@prisma/client';
|
||||
import { UpdateTimesheetDto } from '../dtos/update-timesheet.dto';
|
||||
import { OvertimeService } from 'src/business-logic/overtime.service';
|
||||
import { OvertimeService } from 'src/business-logics/services/overtime.service';
|
||||
|
||||
@Injectable()
|
||||
export class TimesheetsService {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { TimesheetsController } from './controllers/timesheets.controller';
|
||||
import { TimesheetsService } from './services/timesheets.service';
|
||||
import { OvertimeService } from 'src/business-logic/overtime.service';
|
||||
import { BusinessLogicsModule } from 'src/business-logics/business-logics.module';
|
||||
|
||||
@Module({
|
||||
imports: [BusinessLogicsModule],
|
||||
controllers: [TimesheetsController],
|
||||
providers: [
|
||||
TimesheetsService,
|
||||
OvertimeService,
|
||||
],
|
||||
providers: [ TimesheetsService ],
|
||||
exports: [TimesheetsService],
|
||||
})
|
||||
export class TimesheetsModule {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user