import { Controller, Get, Patch, Delete, Body, Param, Query, UseGuards, Request, ParseUUIDPipe, ParseIntPipe, DefaultValuePipe, } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiQuery, } from '@nestjs/swagger'; import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard'; import { InventoryService } from './inventory.service'; import { StoresService } from '../stores/stores.service'; import { UpdateInventoryItemDto } from './dto/update-inventory-item.dto'; import { AuthenticatedRequest } from '../../common/interfaces/authenticated-request.interface'; @ApiTags('inventory') @ApiBearerAuth() @UseGuards(JwtAuthGuard) @Controller('stores/:storeId/inventory') export class InventoryController { constructor( private readonly inventoryService: InventoryService, private readonly storesService: StoresService, ) {} @Get() @ApiOperation({ summary: 'Listar inventario de una tienda' }) @ApiResponse({ status: 200, description: 'Lista de productos' }) @ApiQuery({ name: 'page', required: false, type: Number }) @ApiQuery({ name: 'limit', required: false, type: Number }) async findAll( @Request() req: AuthenticatedRequest, @Param('storeId', ParseUUIDPipe) storeId: string, @Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number, @Query('limit', new DefaultValuePipe(50), ParseIntPipe) limit: number, ) { await this.storesService.verifyOwnership(storeId, req.user.id); const { items, total } = await this.inventoryService.findAllByStore( storeId, page, Math.min(limit, 100), ); return { items, total, page, limit, hasMore: page * limit < total, }; } @Get('statistics') @ApiOperation({ summary: 'Obtener estadisticas del inventario' }) @ApiResponse({ status: 200, description: 'Estadisticas' }) async getStatistics( @Request() req: AuthenticatedRequest, @Param('storeId', ParseUUIDPipe) storeId: string, ) { await this.storesService.verifyOwnership(storeId, req.user.id); return this.inventoryService.getStatistics(storeId); } @Get('low-stock') @ApiOperation({ summary: 'Obtener productos con bajo stock' }) @ApiResponse({ status: 200, description: 'Lista de productos con bajo stock' }) async getLowStock( @Request() req: AuthenticatedRequest, @Param('storeId', ParseUUIDPipe) storeId: string, ) { await this.storesService.verifyOwnership(storeId, req.user.id); return this.inventoryService.getLowStockItems(storeId); } @Get('categories') @ApiOperation({ summary: 'Obtener categorias del inventario' }) @ApiResponse({ status: 200, description: 'Lista de categorias' }) async getCategories( @Request() req: AuthenticatedRequest, @Param('storeId', ParseUUIDPipe) storeId: string, ) { await this.storesService.verifyOwnership(storeId, req.user.id); return this.inventoryService.getCategories(storeId); } @Get(':itemId') @ApiOperation({ summary: 'Obtener un producto' }) @ApiResponse({ status: 200, description: 'Producto encontrado' }) async findOne( @Request() req: AuthenticatedRequest, @Param('storeId', ParseUUIDPipe) storeId: string, @Param('itemId', ParseUUIDPipe) itemId: string, ) { await this.storesService.verifyOwnership(storeId, req.user.id); return this.inventoryService.findById(storeId, itemId); } @Patch(':itemId') @ApiOperation({ summary: 'Actualizar un producto' }) @ApiResponse({ status: 200, description: 'Producto actualizado' }) async update( @Request() req: AuthenticatedRequest, @Param('storeId', ParseUUIDPipe) storeId: string, @Param('itemId', ParseUUIDPipe) itemId: string, @Body() dto: UpdateInventoryItemDto, ) { await this.storesService.verifyOwnership(storeId, req.user.id); return this.inventoryService.update(storeId, itemId, dto, req.user.id); } @Delete(':itemId') @ApiOperation({ summary: 'Eliminar un producto' }) @ApiResponse({ status: 200, description: 'Producto eliminado' }) async delete( @Request() req: AuthenticatedRequest, @Param('storeId', ParseUUIDPipe) storeId: string, @Param('itemId', ParseUUIDPipe) itemId: string, ) { await this.storesService.verifyOwnership(storeId, req.user.id); return this.inventoryService.delete(storeId, itemId); } }