feat(pay-period): added approval of timesheets, shifts and expenses by bulk. added route to controller
This commit is contained in:
parent
5268737bd1
commit
bdbec4f68c
|
|
@ -162,7 +162,31 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/pay-periods/{year}/{periodNumber}/{email}": {
|
"/pay-periods/crew/pay-period-approval": {
|
||||||
|
"patch": {
|
||||||
|
"operationId": "PayPeriodsController_bulkApproval",
|
||||||
|
"parameters": [],
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/BulkCrewApprovalDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"PayPeriods"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/pay-periods/crew/{year}/{periodNumber}": {
|
||||||
"get": {
|
"get": {
|
||||||
"operationId": "PayPeriodsController_getCrewOverview",
|
"operationId": "PayPeriodsController_getCrewOverview",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
|
|
@ -224,6 +248,37 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/timesheets": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "TimesheetController_getTimesheetByIds",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "year",
|
||||||
|
"required": true,
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "period_number",
|
||||||
|
"required": true,
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"Timesheet"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"/preferences": {
|
"/preferences": {
|
||||||
"patch": {
|
"patch": {
|
||||||
"operationId": "PreferencesController_updatePreferences",
|
"operationId": "PreferencesController_updatePreferences",
|
||||||
|
|
@ -257,37 +312,6 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/timesheets": {
|
|
||||||
"get": {
|
|
||||||
"operationId": "TimesheetController_getTimesheetByIds",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"name": "year",
|
|
||||||
"required": true,
|
|
||||||
"in": "query",
|
|
||||||
"schema": {
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "period_number",
|
|
||||||
"required": true,
|
|
||||||
"in": "query",
|
|
||||||
"schema": {
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tags": [
|
|
||||||
"Timesheet"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/shift/create": {
|
"/shift/create": {
|
||||||
"post": {
|
"post": {
|
||||||
"operationId": "ShiftController_createBatch",
|
"operationId": "ShiftController_createBatch",
|
||||||
|
|
@ -609,6 +633,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"schemas": {
|
"schemas": {
|
||||||
|
"BulkCrewApprovalDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {}
|
||||||
|
},
|
||||||
"PreferencesDto": {
|
"PreferencesDto": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {}
|
"properties": {}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
import { CreateExpenseResult, UpdateExpensePayload, UpdateExpenseResult, DeleteExpenseResult, NormalizedExpense } from "src/time-and-attendance/utils/type.utils";
|
import { CreateExpenseResult, UpdateExpensePayload, UpdateExpenseResult, DeleteExpenseResult, NormalizedExpense } from "src/time-and-attendance/utils/type.utils";
|
||||||
import { toDateFromString, toStringFromDate, weekStartSunday } from "src/time-and-attendance/utils/date-time.utils";
|
import { toDateFromString, toStringFromDate, weekStartSunday } from "src/time-and-attendance/utils/date-time.utils";
|
||||||
import { Injectable, NotFoundException, Req } from "@nestjs/common";
|
import { Injectable, NotFoundException } from "@nestjs/common";
|
||||||
import { expense_select } from "src/time-and-attendance/utils/selects.utils";
|
import { expense_select } from "src/time-and-attendance/utils/selects.utils";
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
import { ExpenseDto } from "src/time-and-attendance/expenses/dtos/expense-create.dto";
|
import { ExpenseDto } from "src/time-and-attendance/expenses/dtos/expense-create.dto";
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import { Controller, Get, Param, ParseBoolPipe, ParseIntPipe, Query, Req } from "@nestjs/common";
|
import { Body, Controller, Get, Param, ParseBoolPipe, ParseIntPipe, Patch, Query, Req, UnauthorizedException } from "@nestjs/common";
|
||||||
import { PayPeriodDto } from "../dtos/pay-period.dto";
|
|
||||||
import { PayPeriodOverviewDto } from "../dtos/overview-pay-period.dto";
|
import { PayPeriodOverviewDto } from "../dtos/overview-pay-period.dto";
|
||||||
import { PayPeriodsQueryService } from "../services/pay-periods-query.service";
|
import { PayPeriodsQueryService } from "../services/pay-periods-query.service";
|
||||||
import { RolesAllowed } from "src/common/decorators/roles.decorators";
|
import { RolesAllowed } from "src/common/decorators/roles.decorators";
|
||||||
import { Roles as RoleEnum } from '.prisma/client';
|
import { Roles as RoleEnum } from '.prisma/client';
|
||||||
// import { PayPeriodsCommandService } from "../services/pay-periods-command.service";
|
import { PayPeriodsCommandService } from "../services/pay-periods-command.service";
|
||||||
import { PayPeriodBundleDto } from "../dtos/bundle-pay-period.dto";
|
import { PayPeriodBundleDto } from "../dtos/bundle-pay-period.dto";
|
||||||
import { BulkCrewApprovalDto } from "../dtos/bulk-crew-approval.dto";
|
import { BulkCrewApprovalDto } from "../dtos/bulk-crew-approval.dto";
|
||||||
|
|
||||||
|
|
@ -14,8 +13,8 @@ export class PayPeriodsController {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly queryService: PayPeriodsQueryService,
|
private readonly queryService: PayPeriodsQueryService,
|
||||||
// private readonly commandService: PayPeriodsCommandService,
|
private readonly commandService: PayPeriodsCommandService,
|
||||||
) {}
|
) { }
|
||||||
|
|
||||||
@Get('current-and-all')
|
@Get('current-and-all')
|
||||||
async getCurrentAndAll(@Query('date') date?: string): Promise<PayPeriodBundleDto> {
|
async getCurrentAndAll(@Query('date') date?: string): Promise<PayPeriodBundleDto> {
|
||||||
|
|
@ -39,42 +38,32 @@ export class PayPeriodsController {
|
||||||
return this.queryService.findOneByYearPeriod(year, period_no);
|
return this.queryService.findOneByYearPeriod(year, period_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Patch("crew/bulk-approval")
|
@Patch("crew/pay-period-approval")
|
||||||
// //@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||||
// @ApiOperation({ summary: "Approve all selected timesheets in the period" })
|
async bulkApproval(@Req() req, @Body() dto: BulkCrewApprovalDto) {
|
||||||
// @ApiResponse({ status: 200, description: "Pay period approved" })
|
const email = req.user?.email;
|
||||||
// async bulkApproval(@Body() dto: BulkCrewApprovalDto) {
|
if(!email) throw new UnauthorizedException(`Session infos not found`);
|
||||||
// return this.commandService.bulkApproveCrew(dto);
|
return this.commandService.bulkApproveCrew(email, dto);
|
||||||
// }
|
}
|
||||||
|
|
||||||
@Get(':year/:periodNumber/:email')
|
@Get('crew/:year/:periodNumber')
|
||||||
//@RolesAllowed(RoleEnum.SUPERVISOR)
|
@RolesAllowed(RoleEnum.SUPERVISOR)
|
||||||
async getCrewOverview( @Req() req,
|
async getCrewOverview(@Req() req,
|
||||||
@Param('year', ParseIntPipe) year: number,
|
@Param('year', ParseIntPipe) year: number,
|
||||||
@Param('periodNumber', ParseIntPipe) period_no: number,
|
@Param('periodNumber', ParseIntPipe) period_no: number,
|
||||||
@Query('includeSubtree', new ParseBoolPipe({ optional: true })) include_subtree = false,
|
@Query('includeSubtree', new ParseBoolPipe({ optional: true })) include_subtree = false,
|
||||||
): Promise<PayPeriodOverviewDto> {
|
): Promise<PayPeriodOverviewDto> {
|
||||||
const email = req.user?.email;
|
const email = req.user?.email;
|
||||||
|
if(!email) throw new UnauthorizedException(`Session infos not found`);
|
||||||
return this.queryService.getCrewOverview(year, period_no, email, include_subtree);
|
return this.queryService.getCrewOverview(year, period_no, email, include_subtree);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('overview/:year/:periodNumber')
|
@Get('overview/:year/:periodNumber')
|
||||||
|
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.ADMIN, RoleEnum.HR, RoleEnum.SUPERVISOR)
|
||||||
async getOverviewByYear(
|
async getOverviewByYear(
|
||||||
@Param('year', ParseIntPipe) year: number,
|
@Param('year', ParseIntPipe) year: number,
|
||||||
@Param('periodNumber', ParseIntPipe) period_no: number,
|
@Param('periodNumber', ParseIntPipe) period_no: number,
|
||||||
): Promise<PayPeriodOverviewDto> {
|
): Promise<PayPeriodOverviewDto> {
|
||||||
return this.queryService.getOverviewByYearPeriod(year, period_no);
|
return this.queryService.getOverviewByYearPeriod(year, period_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//_____________________________________________________________________________________________
|
|
||||||
// Deprecated or unused methods
|
|
||||||
//_____________________________________________________________________________________________
|
|
||||||
|
|
||||||
// @Get()
|
|
||||||
// @ApiOperation({ summary: 'Find all pay period' })
|
|
||||||
// @ApiResponse({status: 200,description: 'List of pay period found', type: PayPeriodDto, isArray: true })
|
|
||||||
// async findAll(): Promise<PayPeriodDto[]> {
|
|
||||||
// return this.queryService.findAll();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,6 @@ export class BulkCrewApprovalItemDto {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BulkCrewApprovalDto {
|
export class BulkCrewApprovalDto {
|
||||||
@IsEmail()
|
|
||||||
supervisor_email: string;
|
|
||||||
|
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
include_subtree: boolean = false;
|
include_subtree: boolean = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,20 @@
|
||||||
import { PayPeriodsQueryService } from "./services/pay-periods-query.service";
|
import { PayPeriodsQueryService } from "./services/pay-periods-query.service";
|
||||||
import { PayPeriodsController } from "./controllers/pay-periods.controller";
|
import { PayPeriodsController } from "./controllers/pay-periods.controller";
|
||||||
import { Module } from "@nestjs/common";
|
import { Module } from "@nestjs/common";
|
||||||
|
import { PayPeriodsCommandService } from "src/time-and-attendance/pay-period/services/pay-periods-command.service";
|
||||||
|
import { TimesheetsModule } from "src/time-and-attendance/time-tracker/timesheets/timesheets.module";
|
||||||
|
import { EmailToIdResolver } from "src/time-and-attendance/utils/resolve-email-id.utils";
|
||||||
|
import { TimesheetApprovalService } from "src/time-and-attendance/time-tracker/timesheets/services/timesheet-approval.service";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
imports:[TimesheetsModule],
|
||||||
controllers: [PayPeriodsController],
|
controllers: [PayPeriodsController],
|
||||||
providers: [PayPeriodsQueryService],
|
providers: [
|
||||||
|
PayPeriodsQueryService,
|
||||||
|
PayPeriodsCommandService,
|
||||||
|
EmailToIdResolver,
|
||||||
|
TimesheetApprovalService,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
export class PayperiodsModule {}
|
export class PayperiodsModule {}
|
||||||
|
|
@ -1,71 +1,72 @@
|
||||||
// import { BadRequestException, ForbiddenException, Injectable, NotFoundException } from "@nestjs/common";
|
import { BadRequestException, ForbiddenException, Injectable, NotFoundException } from "@nestjs/common";
|
||||||
// import { PrismaService } from "src/prisma/prisma.service";
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
// import { BulkCrewApprovalDto } from "../dtos/bulk-crew-approval.dto";
|
import { BulkCrewApprovalDto } from "../dtos/bulk-crew-approval.dto";
|
||||||
// import { PayPeriodsQueryService } from "./pay-periods-query.service";
|
import { PayPeriodsQueryService } from "./pay-periods-query.service";
|
||||||
// import { TimesheetApprovalService } from "src/modules/timesheets/services/timesheet-approval.service";
|
import { TimesheetApprovalService } from "src/time-and-attendance/time-tracker/timesheets/services/timesheet-approval.service";
|
||||||
|
|
||||||
// @Injectable()
|
@Injectable()
|
||||||
// export class PayPeriodsCommandService {
|
export class PayPeriodsCommandService {
|
||||||
// constructor(
|
constructor(
|
||||||
// private readonly prisma: PrismaService,
|
private readonly prisma: PrismaService,
|
||||||
// private readonly timesheets_approval: TimesheetApprovalService,
|
private readonly timesheets_approval: TimesheetApprovalService,
|
||||||
// private readonly query: PayPeriodsQueryService,
|
private readonly query: PayPeriodsQueryService,
|
||||||
// ) {}
|
) {}
|
||||||
|
|
||||||
// //function to approve pay-periods according to selected crew members
|
//function to approve pay-periods according to selected crew members
|
||||||
// async bulkApproveCrew(dto:BulkCrewApprovalDto): Promise<{updated: number}> {
|
async bulkApproveCrew(email: string, dto:BulkCrewApprovalDto): Promise<{updated: number}> {
|
||||||
// const { supervisor_email, include_subtree, items } = dto;
|
const { include_subtree, items } = dto;
|
||||||
// if(!items?.length) throw new BadRequestException('no items to process');
|
if(!items?.length) throw new BadRequestException('no items to process');
|
||||||
|
|
||||||
// //fetch and validate supervisor status
|
//fetch and validate supervisor status
|
||||||
// const supervisor = await this.query.getSupervisor(supervisor_email);
|
const supervisor = await this.query.getSupervisor(email);
|
||||||
// if(!supervisor) throw new NotFoundException('No employee record linked to current user');
|
if(!supervisor) throw new NotFoundException('No employee record linked to current user');
|
||||||
// if(!supervisor.is_supervisor) throw new ForbiddenException('Employee is not a supervisor');
|
if(!supervisor.is_supervisor) throw new ForbiddenException('Employee is not a supervisor');
|
||||||
|
|
||||||
// //fetches emails of crew members linked to supervisor
|
//fetches emails of crew members linked to supervisor
|
||||||
// const crew_emails = await this.query.resolveCrewEmails(supervisor.id, include_subtree);
|
const crew_emails = await this.query.resolveCrewEmails(supervisor.id, include_subtree);
|
||||||
|
|
||||||
|
|
||||||
// for(const item of items) {
|
for(const item of items) {
|
||||||
// if(!crew_emails.has(item.employee_email)) {
|
if(!crew_emails.has(item.employee_email)) {
|
||||||
// throw new ForbiddenException(`Employee ${item.employee_email} not in supervisor crew`);
|
throw new ForbiddenException(`Employee ${item.employee_email} not in supervisor crew`);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// const period_cache = new Map<string, {period_start: Date, period_end: Date}>();
|
const period_cache = new Map<string, {period_start: Date, period_end: Date}>();
|
||||||
// const getPeriod = async (y:number, no: number) => {
|
const getPeriod = async (year:number, period_no: number) => {
|
||||||
// const key = `${y}-${no}`;
|
const key = `${year}-${period_no}`;
|
||||||
// if(!period_cache.has(key)) return period_cache.get(key)!;
|
if(period_cache.has(key)) return period_cache.get(key)!;
|
||||||
// const period = await this.query.getPeriodWindow(y,no);
|
|
||||||
// if(!period) throw new NotFoundException(`Pay period ${y}-${no} not found`);
|
|
||||||
// period_cache.set(key, period);
|
|
||||||
// return period;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let updated = 0;
|
const period = await this.query.getPeriodWindow(year,period_no);
|
||||||
|
if(!period) throw new NotFoundException(`Pay period ${year}-${period_no} not found`);
|
||||||
|
period_cache.set(key, period);
|
||||||
|
return period;
|
||||||
|
};
|
||||||
|
|
||||||
// await this.prisma.$transaction(async (transaction) => {
|
let updated = 0;
|
||||||
// for(const item of items) {
|
|
||||||
// const { period_start, period_end } = await getPeriod(item.pay_year, item.period_no);
|
|
||||||
|
|
||||||
// const t_sheets = await transaction.timesheets.findMany({
|
await this.prisma.$transaction(async (transaction) => {
|
||||||
// where: {
|
for(const item of items) {
|
||||||
// employee: { user: { email: item.employee_email } },
|
const { period_start, period_end } = await getPeriod(item.pay_year, item.period_no);
|
||||||
// OR: [
|
|
||||||
// {shift : { some: { date: { gte: period_start, lte: period_end } } } },
|
|
||||||
// {expense: { some: { date: { gte: period_start, lte: period_end } } } },
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
// select: { id: true },
|
|
||||||
// });
|
|
||||||
|
|
||||||
// for(const { id } of t_sheets) {
|
const t_sheets = await transaction.timesheets.findMany({
|
||||||
// await this.timesheets_approval.updateApprovalWithTransaction(transaction, id, item.approve);
|
where: {
|
||||||
// updated++;
|
employee: { user: { email: item.employee_email } },
|
||||||
// }
|
OR: [
|
||||||
|
{shift : { some: { date: { gte: period_start, lte: period_end } } } },
|
||||||
|
{expense: { some: { date: { gte: period_start, lte: period_end } } } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
// }
|
for(const { id } of t_sheets) {
|
||||||
// });
|
await this.timesheets_approval.cascadeApprovalWithtx(transaction, id, item.approve);
|
||||||
// return {updated};
|
updated++;
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return {updated};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import { Controller, Param, Query, Body, Get, Post, BadRequestException, ParseIntPipe, Delete, Patch, Req } from "@nestjs/common";
|
import { Controller, Param, Query, Body, Get, Post, BadRequestException, ParseIntPipe, Delete, Patch, Req } from "@nestjs/common";
|
||||||
|
import { RolesAllowed } from "src/common/decorators/roles.decorators";
|
||||||
import { SchedulePresetsDto } from "src/time-and-attendance/time-tracker/schedule-presets/dtos/create-schedule-presets.dto";
|
import { SchedulePresetsDto } from "src/time-and-attendance/time-tracker/schedule-presets/dtos/create-schedule-presets.dto";
|
||||||
import { SchedulePresetsUpdateDto } from "src/time-and-attendance/time-tracker/schedule-presets/dtos/update-schedule-presets.dto";
|
import { SchedulePresetsUpdateDto } from "src/time-and-attendance/time-tracker/schedule-presets/dtos/update-schedule-presets.dto";
|
||||||
import { SchedulePresetsApplyService } from "src/time-and-attendance/time-tracker/schedule-presets/services/schedule-presets-apply.service";
|
import { SchedulePresetsApplyService } from "src/time-and-attendance/time-tracker/schedule-presets/services/schedule-presets-apply.service";
|
||||||
import { SchedulePresetsGetService } from "src/time-and-attendance/time-tracker/schedule-presets/services/schedule-presets-get.service";
|
import { SchedulePresetsGetService } from "src/time-and-attendance/time-tracker/schedule-presets/services/schedule-presets-get.service";
|
||||||
import { SchedulePresetsUpsertService } from "src/time-and-attendance/time-tracker/schedule-presets/services/schedule-presets-upsert.service";
|
import { SchedulePresetsUpsertService } from "src/time-and-attendance/time-tracker/schedule-presets/services/schedule-presets-upsert.service";
|
||||||
|
import { Roles as RoleEnum } from '.prisma/client';
|
||||||
|
|
||||||
@Controller('schedule-presets')
|
@Controller('schedule-presets')
|
||||||
export class SchedulePresetsController {
|
export class SchedulePresetsController {
|
||||||
|
|
@ -16,45 +17,39 @@ export class SchedulePresetsController {
|
||||||
|
|
||||||
//used to create a schedule preset
|
//used to create a schedule preset
|
||||||
@Post('create')
|
@Post('create')
|
||||||
async createPreset( @Req() req,
|
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.HR, RoleEnum.SUPERVISOR, RoleEnum.ADMIN)
|
||||||
@Body() dto: SchedulePresetsDto,
|
async createPreset( @Req() req, @Body() dto: SchedulePresetsDto ) {
|
||||||
) {
|
|
||||||
const email = req.user?.email;
|
const email = req.user?.email;
|
||||||
return await this.upsertService.createPreset(email, dto);
|
return await this.upsertService.createPreset(email, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
//used to update an already existing schedule preset
|
//used to update an already existing schedule preset
|
||||||
@Patch('update/:preset_id')
|
@Patch('update/:preset_id')
|
||||||
async updatePreset(
|
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.HR, RoleEnum.SUPERVISOR, RoleEnum.ADMIN)
|
||||||
@Param('preset_id', ParseIntPipe) preset_id: number,
|
async updatePreset( @Param('preset_id', ParseIntPipe) preset_id: number,@Body() dto: SchedulePresetsUpdateDto ) {
|
||||||
@Body() dto: SchedulePresetsUpdateDto,
|
|
||||||
) {
|
|
||||||
return await this.upsertService.updatePreset(preset_id, dto);
|
return await this.upsertService.updatePreset(preset_id, dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
//used to delete a schedule preset
|
//used to delete a schedule preset
|
||||||
@Delete('delete/:preset_id')
|
@Delete('delete/:preset_id')
|
||||||
async deletePreset(
|
@RolesAllowed(RoleEnum.ADMIN)
|
||||||
@Param('preset_id') preset_id: number,
|
async deletePreset( @Param('preset_id') preset_id: number ) {
|
||||||
) {
|
|
||||||
return await this.upsertService.deletePreset(preset_id);
|
return await this.upsertService.deletePreset(preset_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//used to show the list of available schedule presets
|
//used to show the list of available schedule presets
|
||||||
@Get('find-list')
|
@Get('find-list')
|
||||||
|
@RolesAllowed(RoleEnum.ACCOUNTING, RoleEnum.HR, RoleEnum.SUPERVISOR, RoleEnum.ADMIN)
|
||||||
async findListById( @Req() req) {
|
async findListById( @Req() req) {
|
||||||
const email = req.user?.email;
|
const email = req.user?.email;
|
||||||
return this.getService.getSchedulePresets(email);
|
return this.getService.getSchedulePresets(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//used to apply a preset to a timesheet
|
//used to apply a preset to a timesheet
|
||||||
@Post('apply-presets')
|
@Post('apply-presets')
|
||||||
async applyPresets( @Req() req,
|
@RolesAllowed(RoleEnum.EMPLOYEE, RoleEnum.ACCOUNTING, RoleEnum.HR, RoleEnum.SUPERVISOR, RoleEnum.ADMIN)
|
||||||
@Query('preset') preset_name: string,
|
async applyPresets( @Req() req, @Query('preset') preset_name: string, @Query('start') start_date: string ) {
|
||||||
@Query('start') start_date: string,
|
|
||||||
) {
|
|
||||||
const email = req.user?.email;
|
const email = req.user?.email;
|
||||||
if(!preset_name?.trim()) throw new BadRequestException('Query "preset" is required');
|
if(!preset_name?.trim()) throw new BadRequestException('Query "preset" is required');
|
||||||
if(!start_date?.trim()) throw new BadRequestException('Query "start" is required YYYY-MM-DD');
|
if(!start_date?.trim()) throw new BadRequestException('Query "start" is required YYYY-MM-DD');
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,16 @@ import { ShiftDto } from "src/time-and-attendance/time-tracker/shifts/dtos/shift
|
||||||
import { UpdateShiftDto } from "src/time-and-attendance/time-tracker/shifts/dtos/shift-update.dto";
|
import { UpdateShiftDto } from "src/time-and-attendance/time-tracker/shifts/dtos/shift-update.dto";
|
||||||
import { ShiftsUpsertService } from "src/time-and-attendance/time-tracker/shifts/services/shifts-upsert.service";
|
import { ShiftsUpsertService } from "src/time-and-attendance/time-tracker/shifts/services/shifts-upsert.service";
|
||||||
import { CreateShiftResult, UpdateShiftResult } from "src/time-and-attendance/utils/type.utils";
|
import { CreateShiftResult, UpdateShiftResult } from "src/time-and-attendance/utils/type.utils";
|
||||||
|
import { Roles as RoleEnum } from '.prisma/client';
|
||||||
|
import { RolesAllowed } from "src/common/decorators/roles.decorators";
|
||||||
|
|
||||||
@Controller('shift')
|
@Controller('shift')
|
||||||
export class ShiftController {
|
export class ShiftController {
|
||||||
constructor( private readonly upsert_service: ShiftsUpsertService ){}
|
constructor( private readonly upsert_service: ShiftsUpsertService ){}
|
||||||
|
|
||||||
@Post('create')
|
@Post('create')
|
||||||
createBatch(
|
@RolesAllowed(RoleEnum.EMPLOYEE, RoleEnum.ACCOUNTING, RoleEnum.HR, RoleEnum.SUPERVISOR, RoleEnum.ADMIN)
|
||||||
@Req() req,
|
createBatch( @Req() req, @Body()dtos: ShiftDto[]): Promise<CreateShiftResult[]> {
|
||||||
@Body()dtos: ShiftDto[]): Promise<CreateShiftResult[]> {
|
|
||||||
const email = req.user?.email;
|
const email = req.user?.email;
|
||||||
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)');
|
||||||
|
|
@ -22,14 +22,15 @@ export class ShiftController {
|
||||||
|
|
||||||
//change Body to receive dtos
|
//change Body to receive dtos
|
||||||
@Patch('update')
|
@Patch('update')
|
||||||
updateBatch(
|
@RolesAllowed(RoleEnum.EMPLOYEE, RoleEnum.ACCOUNTING, RoleEnum.HR, RoleEnum.SUPERVISOR, RoleEnum.ADMIN)
|
||||||
@Body() dtos: UpdateShiftDto[]): Promise<UpdateShiftResult[]>{
|
updateBatch( @Body() dtos: UpdateShiftDto[]): Promise<UpdateShiftResult[]>{
|
||||||
const list = Array.isArray(dtos) ? dtos: [];
|
const list = Array.isArray(dtos) ? dtos: [];
|
||||||
if(list.length === 0) throw new BadRequestException('Body is missing or invalid (update shifts)');
|
if(list.length === 0) throw new BadRequestException('Body is missing or invalid (update shifts)');
|
||||||
return this.upsert_service.updateShifts(dtos);
|
return this.upsert_service.updateShifts(dtos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete(':shift_id')
|
@Delete(':shift_id')
|
||||||
|
@RolesAllowed(RoleEnum.EMPLOYEE, RoleEnum.ACCOUNTING, RoleEnum.HR, RoleEnum.SUPERVISOR, RoleEnum.ADMIN)
|
||||||
remove(@Param('shift_id') shift_id: number ) {
|
remove(@Param('shift_id') shift_id: number ) {
|
||||||
return this.upsert_service.deleteShift(shift_id);
|
return this.upsert_service.deleteShift(shift_id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,9 @@ export class TimesheetController {
|
||||||
@Get()
|
@Get()
|
||||||
@RolesAllowed(RoleEnum.SUPERVISOR, RoleEnum.HR, RoleEnum.ACCOUNTING, RoleEnum.ADMIN)
|
@RolesAllowed(RoleEnum.SUPERVISOR, RoleEnum.HR, RoleEnum.ACCOUNTING, RoleEnum.ADMIN)
|
||||||
async getTimesheetByIds(
|
async getTimesheetByIds(
|
||||||
@Req() req,
|
@Req() req, @Query('year', ParseIntPipe) year:number, @Query('period_number', ParseIntPipe) period_number: number) {
|
||||||
@Query('year', ParseIntPipe) year: number,
|
|
||||||
@Query('period_number', ParseIntPipe) period_number: number,
|
|
||||||
) {
|
|
||||||
const email = req.user?.email;
|
const email = req.user?.email;
|
||||||
if(!email) throw new UnauthorizedException('Unauthorized User');
|
if(!email) throw new UnauthorizedException('Unauthorized User');
|
||||||
return this.timesheetOverview.getTimesheetsForEmployeeByPeriod(email, year, period_number);
|
return this.timesheetOverview.getTimesheetsForEmployeeByPeriod(email, year, period_number);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,19 @@
|
||||||
|
|
||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { TimesheetController } from 'src/time-and-attendance/time-tracker/timesheets/controllers/timesheet.controller';
|
import { TimesheetController } from 'src/time-and-attendance/time-tracker/timesheets/controllers/timesheet.controller';
|
||||||
|
import { TimesheetApprovalService } from 'src/time-and-attendance/time-tracker/timesheets/services/timesheet-approval.service';
|
||||||
import { TimesheetArchiveService } from 'src/time-and-attendance/time-tracker/timesheets/services/timesheet-archive.service';
|
import { TimesheetArchiveService } from 'src/time-and-attendance/time-tracker/timesheets/services/timesheet-archive.service';
|
||||||
import { GetTimesheetsOverviewService } from 'src/time-and-attendance/time-tracker/timesheets/services/timesheet-get-overview.service';
|
import { GetTimesheetsOverviewService } from 'src/time-and-attendance/time-tracker/timesheets/services/timesheet-get-overview.service';
|
||||||
|
import { EmailToIdResolver } from 'src/time-and-attendance/utils/resolve-email-id.utils';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
|
||||||
controllers: [TimesheetController],
|
controllers: [TimesheetController],
|
||||||
providers: [
|
providers: [
|
||||||
TimesheetArchiveService,
|
TimesheetArchiveService,
|
||||||
GetTimesheetsOverviewService,
|
GetTimesheetsOverviewService,
|
||||||
|
TimesheetApprovalService,
|
||||||
|
EmailToIdResolver,
|
||||||
],
|
],
|
||||||
exports: [],
|
exports: [],
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user