Files
trackgo-be/src/modules/field/attendances/attendances-write.controller.ts
T
shancheas 365a37b8d2 Add attendance and visit management features with database schema updates
- Introduced new `attendances` and `visits` tables to manage employee attendance and customer visits, including relevant fields for check-in and check-out details.
- Updated `company_settings` to include a `check_in_radius_meters` column for attendance validation.
- Implemented foreign key constraints to ensure data integrity between `attendances`, `visits`, `employees`, `branches`, and other related entities.
- Created new services and controllers for handling attendance and visit operations, including check-in, check-out, and bulk actions.
- Enhanced DTOs for attendance and visit data transfer, including validation for input data.
- Added unit and integration tests to validate the new functionalities and ensure proper handling of attendance and visit records.
- Created migration scripts to apply the necessary database schema changes for the new features.
2026-09-01 12:27:51 +07:00

117 lines
3.5 KiB
TypeScript

import {
Body,
Controller,
Delete,
HttpCode,
Param,
ParseUUIDPipe,
Patch,
Post,
} from '@nestjs/common';
import {
ApiBearerAuth,
ApiCreatedResponse,
ApiForbiddenResponse,
ApiNoContentResponse,
ApiNotFoundResponse,
ApiOkResponse,
ApiOperation,
ApiTags,
ApiUnauthorizedResponse,
} from '@nestjs/swagger';
import { CurrentUser } from '../../../common/decorators/current-user.decorator';
import { RequirePrivilege } from '../../../common/decorators/require-privilege.decorator';
import { BEARER_AUTH_NAME } from '../../../common/swagger/setup-swagger';
import { FIELD_ATTENDANCE_PRIVILEGE_KEY } from '../shared/field-purpose';
import {
AttendanceCheckInDto,
AttendanceCheckOutDto,
AttendanceDto,
BulkIdsDto,
BulkStatusDto,
UpdateAttendanceStatusDto,
} from './dto/attendance.dto';
import { AttendancesService } from './attendances.service';
@ApiTags('attendances')
@ApiBearerAuth(BEARER_AUTH_NAME)
@Controller('attendances')
export class AttendancesWriteController {
constructor(private readonly attendancesService: AttendancesService) {}
@Post('check-in')
@RequirePrivilege(FIELD_ATTENDANCE_PRIVILEGE_KEY, 'create')
@ApiOperation({ summary: 'Check in at a branch' })
@ApiCreatedResponse({ type: AttendanceDto })
@ApiUnauthorizedResponse()
@ApiForbiddenResponse()
checkIn(
@Body() dto: AttendanceCheckInDto,
@CurrentUser('id') userId: string,
): Promise<AttendanceDto> {
return this.attendancesService.checkIn(dto, userId);
}
@Post('bulk-delete')
@HttpCode(200)
@RequirePrivilege(FIELD_ATTENDANCE_PRIVILEGE_KEY, 'delete')
@ApiOperation({ summary: 'Bulk delete attendances' })
@ApiOkResponse({ schema: { properties: { deleted: { type: 'number' } } } })
bulkDelete(@Body() dto: BulkIdsDto): Promise<{ deleted: number }> {
return this.attendancesService.bulkDelete(dto.ids);
}
@Post('bulk-status')
@HttpCode(200)
@RequirePrivilege(FIELD_ATTENDANCE_PRIVILEGE_KEY, 'update')
@ApiOperation({ summary: 'Bulk update attendance status' })
@ApiOkResponse({ schema: { properties: { updated: { type: 'number' } } } })
bulkStatus(
@Body() dto: BulkStatusDto,
@CurrentUser('id') userId: string,
): Promise<{ updated: number }> {
return this.attendancesService.bulkUpdateStatus(
dto.ids,
dto.status,
userId,
);
}
@Post(':id/check-out')
@RequirePrivilege(FIELD_ATTENDANCE_PRIVILEGE_KEY, 'update')
@ApiOperation({ summary: 'Check out from a branch shift' })
@ApiOkResponse({ type: AttendanceDto })
@ApiNotFoundResponse()
@ApiUnauthorizedResponse()
@ApiForbiddenResponse()
checkOut(
@Param('id', ParseUUIDPipe) id: string,
@Body() dto: AttendanceCheckOutDto,
@CurrentUser('id') userId: string,
): Promise<AttendanceDto> {
return this.attendancesService.checkOut(id, dto, userId);
}
@Patch(':id/status')
@RequirePrivilege(FIELD_ATTENDANCE_PRIVILEGE_KEY, 'update')
@ApiOperation({ summary: 'Update attendance status' })
@ApiOkResponse({ type: AttendanceDto })
updateStatus(
@Param('id', ParseUUIDPipe) id: string,
@Body() dto: UpdateAttendanceStatusDto,
@CurrentUser('id') userId: string,
): Promise<AttendanceDto> {
return this.attendancesService.updateStatus(id, dto.status, userId);
}
@Delete(':id')
@HttpCode(204)
@RequirePrivilege(FIELD_ATTENDANCE_PRIVILEGE_KEY, 'delete')
@ApiOperation({ summary: 'Delete attendance' })
@ApiNoContentResponse()
@ApiNotFoundResponse()
delete(@Param('id', ParseUUIDPipe) id: string): Promise<void> {
return this.attendancesService.delete(id);
}
}