import { Body, ClassSerializerInterceptor, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post, Query, UseGuards, UseInterceptors, } from '@nestjs/common'; import { ApiBearerAuth, ApiBody, ApiOkResponse, ApiOperation, ApiParam, ApiSecurity, ApiTags, } from '@nestjs/swagger'; import { Building } from 'src/objects/building/entities/building.entity'; import { Room } from 'src/objects/building/entities/room.entity'; import { StorageSet } from 'src/objects/storage/entities/storage-set.entity'; import { Storage } from 'src/objects/storage/entities/storage.entity'; import { User } from 'src/objects/user/user.entity'; import { CurrentBuilding } from 'src/shared/decorators/current-building.decorator'; import { CurrentRoom } from 'src/shared/decorators/current-room.decorator'; import { CurrentStorageSet } from 'src/shared/decorators/current-storage-set.decorator'; import { CurrentStorage } from 'src/shared/decorators/current-storage.decorator'; import { LoggedInUser } from 'src/shared/decorators/user.decorator'; import { AuthGuard } from 'src/shared/guards/auth.guard'; import { BuildingGuard } from 'src/shared/guards/building.guard'; import { RoomGuard } from 'src/shared/guards/room.guard'; import { StorageSetGuard } from 'src/shared/guards/storage-set.guard'; import { StorageGuard } from 'src/shared/guards/storage.guard'; import { AppStorageService } from './app-storage.service'; import { StorageAddExistingItemRequestDto, StorageAddItemRequestDto, StorageItemUpdateRequestDto, StorageStoredItemTransactionRequestDto, StorageStoredItemTransactionUpdateRequestDto, StorageStoredItemUpdateRequestDto, } from './dto/storage-add-item-request.dto'; import { StorageItemRequestQueryDto } from './dto/storage-item-request.dto'; import { StorageItemResponseDto, StorageItemSearchResponseDto, StorageStoredItemResponseDto, StorageTransactionResponseDto, StorageTransactionWithActorResponseDto, } from './dto/storage-item-response.dto'; import { StorageCreateRequestDto, StorageUpdateRequestDto, StorageWithSetsQueryDto, } from './dto/storage-request.dto'; import { StorageResponseDto, StorageResponseWithItemCountDto, } from './dto/storage-response.dto'; import { StorageSetCreateRequestDto, StorageSetUpdateRequestDto, } from './dto/storage-set-request.dto'; import { StorageSetResponseDto } from './dto/storage-set-response.dto'; @Controller({ path: 'storage', }) @ApiTags('storage') @ApiSecurity('Bearer token') @ApiBearerAuth('Bearer token') @UseInterceptors(ClassSerializerInterceptor) @UseGuards(AuthGuard, BuildingGuard, RoomGuard, StorageGuard) export class AppStorageController { constructor(private readonly service: AppStorageService) {} @Get('storages/:storageId') @ApiParam({ name: 'storageId', description: 'Storage ID' }) @ApiOperation({ summary: 'Get storage by ID' }) @ApiOkResponse({ type: StorageResponseWithItemCountDto }) async getStorage( @CurrentStorage() storage: Storage, ): Promise { return this.service.getStorageWithItems(storage); } @Patch('storages/:storageId') @ApiParam({ name: 'storageId', description: 'Storage ID' }) @ApiBody({ type: StorageUpdateRequestDto }) @ApiOperation({ summary: 'Update storage by ID' }) @ApiOkResponse({ type: StorageResponseDto }) async updateStorage( @CurrentStorage() storage: Storage, @Body() body: StorageUpdateRequestDto, ): Promise { return this.service.updateStorage(storage, body); } @UseGuards(StorageSetGuard) @Get('set/:storageSetId') @ApiParam({ name: 'storageSetId', description: 'Storage set ID' }) @ApiOperation({ summary: 'Get storage set' }) @ApiOkResponse({ type: StorageSetResponseDto }) async getStorageSet(@CurrentStorageSet() set: StorageSet) { return this.service.formatStorageSetNoItems(set); } @UseGuards(StorageSetGuard) @Patch('set/:storageSetId') @ApiParam({ name: 'storageSetId', description: 'Storage set ID' }) @ApiBody({ type: StorageSetUpdateRequestDto }) @ApiOperation({ summary: 'Update storage set by ID' }) @ApiOkResponse({ type: StorageSetResponseDto }) async updateStorageSet( @CurrentStorageSet() set: StorageSet, @Body() body: StorageSetUpdateRequestDto, ): Promise { return this.service.updateStorageSet(set, body); } @UseGuards(StorageSetGuard) @Post('set/:storageSetId/:storageId') @ApiParam({ name: 'storageSetId', description: 'Storage set ID' }) @ApiParam({ name: 'storageId', description: 'Storage ID' }) @ApiOperation({ summary: 'Move storage to storage set' }) @ApiOkResponse({ type: StorageSetResponseDto }) async moveStorage( @CurrentStorageSet() set: StorageSet, @CurrentStorage() storage: Storage, ): Promise { return this.service.moveStorage(set, storage); } @UseGuards(StorageSetGuard) @Delete('set/:storageSetId/:storageId') @ApiParam({ name: 'storageSetId', description: 'Storage set ID' }) @ApiParam({ name: 'storageId', description: 'Storage ID' }) @ApiOperation({ summary: 'Remove storage from storage set' }) @ApiOkResponse({ type: StorageSetResponseDto }) async removeStorageFromSet( @CurrentStorageSet() set: StorageSet, @CurrentStorage() storage: Storage, ): Promise { 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' }) @ApiOkResponse({ type: StorageSetResponseDto, isArray: true }) async getStorageSets(@CurrentRoom() room: Room) { return this.service.getStorageSetsInRoom(room.id); } @Post('set/room/:roomId') @ApiParam({ name: 'roomId', description: 'Room ID' }) @ApiBody({ type: StorageCreateRequestDto }) @ApiOperation({ summary: 'Create storage sets in room' }) @ApiOkResponse({ type: StorageSetResponseDto, isArray: true }) async createStorageSet( @LoggedInUser() user: User, @Body() body: StorageSetCreateRequestDto, @CurrentRoom() room: Room, ) { return this.service.createStorageSet(user, room, body); } @Post('room/:roomId') @ApiParam({ name: 'roomId', description: 'Room ID' }) @ApiBody({ type: StorageCreateRequestDto }) @ApiOperation({ summary: 'Add a new storage to room' }) @ApiOkResponse({ type: StorageResponseDto }) async addStorage( @LoggedInUser() user: User, @Body() body: StorageCreateRequestDto, @CurrentRoom() room: Room, ): Promise { return this.service.createStorage(user, room, body); } @Get('expiring') @ApiOperation({ summary: 'Get expiring and expired for user in all buildings', }) @ApiOkResponse({ type: StorageStoredItemResponseDto, isArray: true }) async getExpiringItemsForUser(@LoggedInUser() user: User) { return this.service.getExpiringOrExpiredItems(user); } @Get('expiring/building/:buildingId') @ApiParam({ name: 'buildingId', description: 'Building ID' }) @ApiOperation({ summary: 'Get expiring and expired items in building' }) @ApiOkResponse({ type: StorageStoredItemResponseDto, isArray: true }) async getExpiringItemsInBuilding(@CurrentBuilding() building: Building) { return this.service.getExpiringOrExpiredItemsInBuilding(building.id); } @Get('item') @ApiOperation({ summary: 'Search for an item' }) @ApiOkResponse({ type: StorageItemSearchResponseDto, isArray: true }) async searchForItem( @LoggedInUser() user: User, @Query() search: StorageItemRequestQueryDto, ) { return this.service.searchForItems(user, search); } @Post('item/:storageId') @ApiParam({ name: 'storageId', description: 'Storage ID' }) @ApiBody({ type: StorageAddItemRequestDto }) @ApiOperation({ summary: 'Add a new item to storage' }) @ApiOkResponse({ type: StorageStoredItemResponseDto }) async addItemToStorage( @LoggedInUser() user: User, @Body() body: StorageAddItemRequestDto, @CurrentStorage() storage: Storage, ) { return this.service.createNewItem(user, storage, body); } @Post('item/:storageId/:itemId') @ApiParam({ name: 'storageId', description: 'Storage ID' }) @ApiParam({ name: 'itemId', description: 'Existing item ID' }) @ApiBody({ type: StorageAddExistingItemRequestDto }) @ApiOperation({ summary: 'Add an instance of an existing item to storage' }) @ApiOkResponse({ type: StorageStoredItemResponseDto }) async addExistingItemToStorage( @Param('itemId', ParseIntPipe) itemId: number, @LoggedInUser() user: User, @Body() body: StorageAddExistingItemRequestDto, @CurrentStorage() storage: Storage, ) { return this.service.addExistingItemToStorage(user, storage, itemId, body); } @Patch('item/:storageId/:storedItemId') @ApiParam({ name: 'storedItemId', description: 'Stored Item ID' }) @ApiOperation({ summary: 'Update a stored items details' }) @ApiBody({ type: StorageStoredItemUpdateRequestDto }) @ApiOkResponse({ type: StorageStoredItemResponseDto }) async updateStoredItem( @Param('storedItemId', ParseIntPipe) storedItemId: number, @Body() body: StorageStoredItemUpdateRequestDto, @CurrentStorage() storage: Storage, ) { return this.service.updateStoredItemDetails(storage, storedItemId, body); } @Post('item/:storageId/:storedItemId/transactions') @ApiParam({ name: 'storedItemId', description: 'Stored Item ID' }) @ApiOperation({ summary: 'Create a new stored item transaction' }) @ApiBody({ type: StorageStoredItemTransactionRequestDto }) @ApiOkResponse({ type: StorageTransactionResponseDto }) async createStoredItemTransaction( @LoggedInUser() user: User, @Param('storedItemId', ParseIntPipe) storedItemId: number, @Body() body: StorageStoredItemTransactionRequestDto, @CurrentStorage() storage: Storage, ) { return this.service.createStoredItemTransaction( user, storage, storedItemId, body, ); } @Get('item/:storageId/:storedItemId/transactions') @ApiParam({ name: 'storedItemId', description: 'Stored Item ID' }) @ApiOperation({ summary: 'Get a stored items transactions' }) @ApiOkResponse({ type: StorageTransactionWithActorResponseDto, isArray: true, }) async getStoredItemTransactions( @Param('storedItemId', ParseIntPipe) storedItemId: number, @CurrentStorage() storage: Storage, ) { return this.service.getStoredItemTransaction(storage, storedItemId); } @Patch('item/:storageId/:storedItemId/transactions/:transactionId') @ApiParam({ name: 'storedItemId', description: 'Stored Item ID' }) @ApiOperation({ summary: 'Update a stored item transaction' }) @ApiBody({ type: StorageStoredItemTransactionUpdateRequestDto }) @ApiOkResponse({ type: StorageTransactionResponseDto }) async updateStoredItemTransaction( @LoggedInUser() user: User, @Param('storedItemId', ParseIntPipe) storedItemId: number, @Param('transactionId', ParseIntPipe) transactionId: number, @Body() body: StorageStoredItemTransactionUpdateRequestDto, ) { return this.service.updateStoredItemTransaction( user, storedItemId, transactionId, body, ); } @Get('item/:storageId/:storedItemId') @ApiParam({ name: 'storedItemId', description: 'Stored Item ID' }) @ApiOperation({ summary: 'Get a stored items details' }) @ApiOkResponse({ type: StorageStoredItemResponseDto }) async getStoredItem( @Param('storedItemId', ParseIntPipe) storedItemId: number, @CurrentStorage() storage: Storage, ) { return this.service.getStoredItemDetails(storage, storedItemId); } @Patch('item/:itemId') @ApiParam({ name: 'itemId', description: 'Item ID' }) @ApiBody({ type: StorageItemUpdateRequestDto }) @ApiOperation({ summary: 'Update an item owned by the current user' }) @ApiOkResponse({ type: StorageItemResponseDto }) async updateItem( @Param('itemId', ParseIntPipe) itemId: number, @LoggedInUser() user: User, @Body() body: StorageItemUpdateRequestDto, ) { return this.service.updateOwnedItem(user, itemId, body); } }