From 69e0bac7b3af799cb113d476ed3dba4a45f15560 Mon Sep 17 00:00:00 2001 From: Evert Prants Date: Tue, 24 Jan 2023 22:37:45 +0200 Subject: [PATCH] search stored items --- src/app-storage/app-storage.controller.ts | 50 ++++++++++++++----- src/app-storage/app-storage.service.ts | 15 ++++++ .../dto/storage-item-request.dto.ts | 4 +- .../storage/entities/stored-item.entity.ts | 6 +-- src/objects/storage/storage.service.ts | 39 +++++++++++++++ 5 files changed, 98 insertions(+), 16 deletions(-) diff --git a/src/app-storage/app-storage.controller.ts b/src/app-storage/app-storage.controller.ts index 88d7ad6..79ab87b 100644 --- a/src/app-storage/app-storage.controller.ts +++ b/src/app-storage/app-storage.controller.ts @@ -149,17 +149,6 @@ export class AppStorageController { return this.service.removeFromSet(set, storage); } - @Get('room/:roomId') - @ApiParam({ name: 'roomId', description: 'Room ID' }) - @ApiOperation({ summary: 'Get storages in room' }) - @ApiOkResponse({ type: StorageResponseDto, isArray: true }) - async getStorages( - @CurrentRoom() room: Room, - @Query() { includeWithSets }: StorageWithSetsQueryDto, - ) { - return this.service.getStoragesInRoom(room.id, includeWithSets); - } - @Get('set/room/:roomId') @ApiParam({ name: 'roomId', description: 'Room ID' }) @ApiOperation({ summary: 'Get storage sets in room' }) @@ -181,6 +170,17 @@ export class AppStorageController { return this.service.createStorageSet(user, room, body); } + @Get('room/:roomId') + @ApiParam({ name: 'roomId', description: 'Room ID' }) + @ApiOperation({ summary: 'Get storages in room' }) + @ApiOkResponse({ type: StorageResponseDto, isArray: true }) + async getStorages( + @CurrentRoom() room: Room, + @Query() { includeWithSets }: StorageWithSetsQueryDto, + ) { + return this.service.getStoragesInRoom(room.id, includeWithSets); + } + @Post('room/:roomId') @ApiParam({ name: 'roomId', description: 'Room ID' }) @ApiBody({ type: StorageCreateRequestDto }) @@ -203,7 +203,33 @@ export class AppStorageController { return this.service.getExpiringOrExpiredItems(user); } - @Get('expiring/building/:buildingId') + @Get('search') + @ApiOperation({ + summary: 'Search for stored items', + }) + @ApiOkResponse({ type: StorageStoredItemResponseDto, isArray: true }) + async searchForStoredItems( + @LoggedInUser() user: User, + @Query() query: StorageItemRequestQueryDto, + ) { + return this.service.searchForStoredItems(query, user); + } + + @Get('building/:buildingId/search') + @ApiParam({ name: 'buildingId', description: 'Building ID' }) + @ApiOperation({ + summary: 'Search for stored items in building', + }) + @ApiOkResponse({ type: StorageStoredItemResponseDto, isArray: true }) + async searchForStoredItemsInBuilding( + @LoggedInUser() user: User, + @CurrentBuilding() building: Building, + @Query() query: StorageItemRequestQueryDto, + ) { + return this.service.searchForStoredItems(query, user, building.id); + } + + @Get('building/:buildingId/expiring') @ApiParam({ name: 'buildingId', description: 'Building ID' }) @ApiOperation({ summary: 'Get expiring and expired items in building' }) @ApiOkResponse({ type: StorageStoredItemResponseDto, isArray: true }) diff --git a/src/app-storage/app-storage.service.ts b/src/app-storage/app-storage.service.ts index 391b6f9..02ce327 100644 --- a/src/app-storage/app-storage.service.ts +++ b/src/app-storage/app-storage.service.ts @@ -159,6 +159,21 @@ export class AppStorageService { ); } + async searchForStoredItems( + search: StorageItemRequestQueryDto, + user: User, + buildingId?: number, + ) { + const foundItems = await this.storageService.searchForStoredItem( + search, + user.sub, + buildingId, + ); + return foundItems.map((storedItem) => + this.formatStoredItem(storedItem, true), + ); + } + async createStoredItem( user: User, item: Item, diff --git a/src/app-storage/dto/storage-item-request.dto.ts b/src/app-storage/dto/storage-item-request.dto.ts index 7835d96..757fab9 100644 --- a/src/app-storage/dto/storage-item-request.dto.ts +++ b/src/app-storage/dto/storage-item-request.dto.ts @@ -1,14 +1,16 @@ import { ApiPropertyOptional } from '@nestjs/swagger'; -import { IsString, ValidateIf } from 'class-validator'; +import { IsString, MinLength, ValidateIf } from 'class-validator'; export class StorageItemRequestQueryDto { @ApiPropertyOptional() @IsString() + @MinLength(2) @ValidateIf((obj) => !obj.barcode) searchTerm?: string; @ApiPropertyOptional() @IsString() + @MinLength(2) @ValidateIf((obj) => !obj.searchTerm) barcode?: string; } diff --git a/src/objects/storage/entities/stored-item.entity.ts b/src/objects/storage/entities/stored-item.entity.ts index 77c17b0..ca59c13 100644 --- a/src/objects/storage/entities/stored-item.entity.ts +++ b/src/objects/storage/entities/stored-item.entity.ts @@ -62,15 +62,15 @@ export class StoredItem { transactions?: StoredItemTransaction[]; @ApiPropertyOptional() - @Column({ nullable: true, type: 'datetime' }) + @Column({ nullable: true, type: 'datetime', default: null }) expiresAt?: Date; @ApiPropertyOptional() - @Column({ nullable: true, type: 'datetime' }) + @Column({ nullable: true, type: 'datetime', default: null }) acquiredAt?: Date; @ApiPropertyOptional() - @Column({ nullable: true, type: 'datetime' }) + @Column({ nullable: true, type: 'datetime', default: null }) consumedAt?: Date; @ApiProperty() diff --git a/src/objects/storage/storage.service.ts b/src/objects/storage/storage.service.ts index 9912f96..d820052 100644 --- a/src/objects/storage/storage.service.ts +++ b/src/objects/storage/storage.service.ts @@ -173,6 +173,7 @@ export class StorageService { async getItemsInStorage(storageId: number, relations = []) { return this.storedItemRepository.find({ where: { + consumedAt: null, storage: { id: storageId, }, @@ -181,6 +182,42 @@ export class StorageService { }); } + async searchForStoredItem( + search: { searchTerm?: string; barcode?: string }, + sub: string, + buildingId?: number, + ) { + return this.storedItemRepository.find({ + where: { + consumedAt: null, + item: { + [search.barcode ? 'barcode' : 'displayName']: + search.barcode || ILike(`%${search.searchTerm}%`), + }, + ...(buildingId + ? { + building: { id: buildingId }, + } + : { + building: { + groups: { + members: { + sub, + }, + }, + }, + }), + }, + take: 10, + relations: [ + 'item', + 'storage', + 'storage.room', + ...(!buildingId ? ['building'] : []), + ], + }); + } + async searchForItem(searchTerm: string, sub: string) { const displayName = ILike(`%${searchTerm}%`); return this.itemRepository.find({ @@ -283,6 +320,7 @@ export class StorageService { // 8 days return this.storedItemRepository.find({ where: { + consumedAt: null, expiresAt: LessThanOrEqual(new Date(Date.now() + 691200000)), building: { id: buildingId, @@ -300,6 +338,7 @@ export class StorageService { // 8 days return this.storedItemRepository.find({ where: { + consumedAt: null, expiresAt: LessThanOrEqual(new Date(Date.now() + 691200000)), building: { groups: {