import prisma from '../config/database'; import { ApiError } from '../middleware/errorHandler'; import logger from '../config/logger'; export interface CreateBonusPackInput { name: string; description?: string; numberOfBookings: number; price: number; validityDays: number; } export interface UpdateBonusPackInput { name?: string; description?: string; numberOfBookings?: number; price?: number; validityDays?: number; isActive?: boolean; } export class BonusPackService { // Crear un tipo de bono (admin) static async createBonusPack(adminId: string, data: CreateBonusPackInput) { // Validar que el precio sea positivo if (data.price < 0) { throw new ApiError('El precio no puede ser negativo', 400); } // Validar que la cantidad de reservas sea positiva if (data.numberOfBookings <= 0) { throw new ApiError('La cantidad de reservas debe ser mayor a 0', 400); } // Validar que los días de validez sean positivos if (data.validityDays <= 0) { throw new ApiError('Los días de validez deben ser mayor a 0', 400); } const bonusPack = await prisma.bonusPack.create({ data: { name: data.name, description: data.description, numberOfBookings: data.numberOfBookings, price: data.price, validityDays: data.validityDays, isActive: true, }, }); logger.info(`BonusPack creado: ${bonusPack.id} por admin: ${adminId}`); return bonusPack; } // Obtener todos los bonos activos (público) static async getBonusPacks(includeInactive = false) { const where = includeInactive ? {} : { isActive: true }; return prisma.bonusPack.findMany({ where, orderBy: { price: 'asc', }, }); } // Obtener un bono por ID static async getBonusPackById(id: string) { const bonusPack = await prisma.bonusPack.findUnique({ where: { id }, }); if (!bonusPack) { throw new ApiError('Pack de bonos no encontrado', 404); } return bonusPack; } // Actualizar un tipo de bono (admin) static async updateBonusPack(id: string, adminId: string, data: UpdateBonusPackInput) { const bonusPack = await prisma.bonusPack.findUnique({ where: { id }, }); if (!bonusPack) { throw new ApiError('Pack de bonos no encontrado', 404); } // Validaciones si se actualizan ciertos campos if (data.price !== undefined && data.price < 0) { throw new ApiError('El precio no puede ser negativo', 400); } if (data.numberOfBookings !== undefined && data.numberOfBookings <= 0) { throw new ApiError('La cantidad de reservas debe ser mayor a 0', 400); } if (data.validityDays !== undefined && data.validityDays <= 0) { throw new ApiError('Los días de validez deben ser mayor a 0', 400); } const updated = await prisma.bonusPack.update({ where: { id }, data, }); logger.info(`BonusPack actualizado: ${id} por admin: ${adminId}`); return updated; } // Eliminar (desactivar) un tipo de bono (admin) static async deleteBonusPack(id: string, adminId: string) { const bonusPack = await prisma.bonusPack.findUnique({ where: { id }, }); if (!bonusPack) { throw new ApiError('Pack de bonos no encontrado', 404); } // Desactivar en lugar de eliminar físicamente const updated = await prisma.bonusPack.update({ where: { id }, data: { isActive: false }, }); logger.info(`BonusPack desactivado: ${id} por admin: ${adminId}`); return updated; } } export default BonusPackService;