mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-07-10 15:17:41 +00:00
SP-1812: Task/booking-system/update-api (#456)
* add update bookable spaces API * add search to get bookable spaces API
This commit is contained in:
@ -83,6 +83,12 @@ export class ControllerRoute {
|
|||||||
|
|
||||||
public static readonly GET_ALL_BOOKABLE_SPACES_DESCRIPTION =
|
public static readonly GET_ALL_BOOKABLE_SPACES_DESCRIPTION =
|
||||||
'This endpoint retrieves all bookable spaces.';
|
'This endpoint retrieves all bookable spaces.';
|
||||||
|
|
||||||
|
public static readonly UPDATE_BOOKABLE_SPACES_SUMMARY =
|
||||||
|
'Update existing bookable spaces';
|
||||||
|
|
||||||
|
public static readonly UPDATE_BOOKABLE_SPACES_DESCRIPTION =
|
||||||
|
'This endpoint allows you to update existing bookable spaces by providing the required details.';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
static COMMUNITY = class {
|
static COMMUNITY = class {
|
||||||
|
@ -6,7 +6,9 @@ import {
|
|||||||
Body,
|
Body,
|
||||||
Controller,
|
Controller,
|
||||||
Get,
|
Get,
|
||||||
|
Param,
|
||||||
Post,
|
Post,
|
||||||
|
Put,
|
||||||
Query,
|
Query,
|
||||||
Req,
|
Req,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
@ -19,6 +21,7 @@ import { plainToInstance } from 'class-transformer';
|
|||||||
import { CreateBookableSpaceDto } from '../dtos';
|
import { CreateBookableSpaceDto } from '../dtos';
|
||||||
import { BookableSpaceRequestDto } from '../dtos/bookable-space-request.dto';
|
import { BookableSpaceRequestDto } from '../dtos/bookable-space-request.dto';
|
||||||
import { BookableSpaceResponseDto } from '../dtos/bookable-space-response.dto';
|
import { BookableSpaceResponseDto } from '../dtos/bookable-space-response.dto';
|
||||||
|
import { UpdateBookableSpaceDto } from '../dtos/update-bookable-space.dto';
|
||||||
import { BookableSpaceService } from '../services';
|
import { BookableSpaceService } from '../services';
|
||||||
|
|
||||||
@ApiTags('Booking Module')
|
@ApiTags('Booking Module')
|
||||||
@ -79,4 +82,25 @@ export class BookableSpaceController {
|
|||||||
pagination,
|
pagination,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Put(':spaceUuid')
|
||||||
|
@ApiOperation({
|
||||||
|
summary:
|
||||||
|
ControllerRoute.BOOKABLE_SPACES.ACTIONS.UPDATE_BOOKABLE_SPACES_SUMMARY,
|
||||||
|
description:
|
||||||
|
ControllerRoute.BOOKABLE_SPACES.ACTIONS
|
||||||
|
.UPDATE_BOOKABLE_SPACES_DESCRIPTION,
|
||||||
|
})
|
||||||
|
async update(
|
||||||
|
@Param('spaceUuid') spaceUuid: string,
|
||||||
|
@Body() dto: UpdateBookableSpaceDto,
|
||||||
|
): Promise<BaseResponseDto> {
|
||||||
|
const result = await this.bookableSpaceService.update(spaceUuid, dto);
|
||||||
|
return new SuccessResponseDto({
|
||||||
|
data: result,
|
||||||
|
message: 'Successfully updated bookable spaces',
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { BooleanValues } from '@app/common/constants/boolean-values.enum';
|
import { BooleanValues } from '@app/common/constants/boolean-values.enum';
|
||||||
import { PaginationRequestGetListDto } from '@app/common/dto/pagination.request.dto';
|
import { PaginationRequestWithSearchGetListDto } from '@app/common/dto/pagination-with-search.request.dto';
|
||||||
import { ApiProperty, OmitType } from '@nestjs/swagger';
|
import { ApiProperty, OmitType } from '@nestjs/swagger';
|
||||||
import { Transform } from 'class-transformer';
|
import { Transform } from 'class-transformer';
|
||||||
import { IsBoolean, IsNotEmpty, IsOptional } from 'class-validator';
|
import { IsBoolean, IsNotEmpty, IsOptional } from 'class-validator';
|
||||||
|
|
||||||
export class BookableSpaceRequestDto extends OmitType(
|
export class BookableSpaceRequestDto extends OmitType(
|
||||||
PaginationRequestGetListDto,
|
PaginationRequestWithSearchGetListDto,
|
||||||
['includeSpaces'],
|
['includeSpaces'],
|
||||||
) {
|
) {
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
// dtos/bookable-space.dto.ts
|
|
||||||
import { DaysEnum } from '@app/common/constants/days.enum';
|
import { DaysEnum } from '@app/common/constants/days.enum';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import {
|
import {
|
||||||
|
12
src/booking/dtos/update-bookable-space.dto.ts
Normal file
12
src/booking/dtos/update-bookable-space.dto.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { ApiProperty, OmitType, PartialType } from '@nestjs/swagger';
|
||||||
|
import { IsBoolean, IsOptional } from 'class-validator';
|
||||||
|
import { CreateBookableSpaceDto } from './create-bookable-space.dto';
|
||||||
|
|
||||||
|
export class UpdateBookableSpaceDto extends PartialType(
|
||||||
|
OmitType(CreateBookableSpaceDto, ['spaceUuids']),
|
||||||
|
) {
|
||||||
|
@ApiProperty({ type: Boolean })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
|
active?: boolean;
|
||||||
|
}
|
@ -14,6 +14,7 @@ import {
|
|||||||
import { In } from 'typeorm';
|
import { In } from 'typeorm';
|
||||||
import { CreateBookableSpaceDto } from '../dtos';
|
import { CreateBookableSpaceDto } from '../dtos';
|
||||||
import { BookableSpaceRequestDto } from '../dtos/bookable-space-request.dto';
|
import { BookableSpaceRequestDto } from '../dtos/bookable-space-request.dto';
|
||||||
|
import { UpdateBookableSpaceDto } from '../dtos/update-bookable-space.dto';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class BookableSpaceService {
|
export class BookableSpaceService {
|
||||||
@ -37,7 +38,7 @@ export class BookableSpaceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findAll(
|
async findAll(
|
||||||
{ active, page, size, configured }: BookableSpaceRequestDto,
|
{ active, page, size, configured, search }: BookableSpaceRequestDto,
|
||||||
project: string,
|
project: string,
|
||||||
): Promise<{
|
): Promise<{
|
||||||
data: BaseResponseDto['data'];
|
data: BaseResponseDto['data'];
|
||||||
@ -49,6 +50,12 @@ export class BookableSpaceService {
|
|||||||
.leftJoinAndSelect('space.community', 'community')
|
.leftJoinAndSelect('space.community', 'community')
|
||||||
.where('community.project = :project', { project });
|
.where('community.project = :project', { project });
|
||||||
|
|
||||||
|
if (search) {
|
||||||
|
qb = qb.andWhere(
|
||||||
|
'space.spaceName ILIKE :search OR community.name ILIKE :search OR parentSpace.spaceName ILIKE :search',
|
||||||
|
{ search: `%${search}%` },
|
||||||
|
);
|
||||||
|
}
|
||||||
if (configured) {
|
if (configured) {
|
||||||
qb = qb
|
qb = qb
|
||||||
.leftJoinAndSelect('space.bookableConfig', 'bookableConfig')
|
.leftJoinAndSelect('space.bookableConfig', 'bookableConfig')
|
||||||
@ -77,6 +84,30 @@ export class BookableSpaceService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* todo: if updating availability, send to the ones who have access to this space
|
||||||
|
* todo: if updating other fields, just send emails to all users who's bookings might be affected
|
||||||
|
*/
|
||||||
|
async update(spaceUuid: string, dto: UpdateBookableSpaceDto) {
|
||||||
|
// fetch spaces exist
|
||||||
|
const space = (await this.getSpacesOrFindMissing([spaceUuid]))[0];
|
||||||
|
|
||||||
|
if (!space.bookableConfig) {
|
||||||
|
throw new NotFoundException(
|
||||||
|
`Bookable configuration not found for space: ${spaceUuid}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (dto.startTime || dto.endTime) {
|
||||||
|
// Validate time slots first
|
||||||
|
this.validateTimeSlot(
|
||||||
|
dto.startTime || space.bookableConfig.startTime,
|
||||||
|
dto.endTime || space.bookableConfig.endTime,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Object.assign(space.bookableConfig, dto);
|
||||||
|
return this.bookableSpaceEntityRepository.save(space.bookableConfig);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch spaces by UUIDs and throw an error if any are missing
|
* Fetch spaces by UUIDs and throw an error if any are missing
|
||||||
*/
|
*/
|
||||||
@ -85,6 +116,7 @@ export class BookableSpaceService {
|
|||||||
): Promise<SpaceEntity[]> {
|
): Promise<SpaceEntity[]> {
|
||||||
const spaces = await this.spaceRepository.find({
|
const spaces = await this.spaceRepository.find({
|
||||||
where: { uuid: In(spaceUuids) },
|
where: { uuid: In(spaceUuids) },
|
||||||
|
relations: ['bookableConfig'],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (spaces.length !== spaceUuids.length) {
|
if (spaces.length !== spaceUuids.length) {
|
||||||
|
Reference in New Issue
Block a user