import { Response, NextFunction } from 'express'; import { z } from 'zod'; import { companiesService, CreateCompanyDto, UpdateCompanyDto, CompanyFilters } from './companies.service.js'; import { AuthenticatedRequest } from '../../shared/middleware/auth.middleware.js'; import { ValidationError } from '../../shared/errors/index.js'; const createCompanySchema = z.object({ name: z.string().min(1, 'El nombre es requerido').max(255), legal_name: z.string().max(255).optional(), tax_id: z.string().max(50).optional(), currency_id: z.string().uuid().optional(), parent_company_id: z.string().uuid().optional(), settings: z.record(z.any()).optional(), }); const updateCompanySchema = z.object({ name: z.string().min(1).max(255).optional(), legal_name: z.string().max(255).optional().nullable(), tax_id: z.string().max(50).optional().nullable(), currency_id: z.string().uuid().optional().nullable(), parent_company_id: z.string().uuid().optional().nullable(), settings: z.record(z.any()).optional(), }); const querySchema = z.object({ search: z.string().optional(), parent_company_id: z.string().uuid().optional(), page: z.coerce.number().int().positive().default(1), limit: z.coerce.number().int().positive().max(100).default(20), }); class CompaniesController { async findAll(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const queryResult = querySchema.safeParse(req.query); if (!queryResult.success) { throw new ValidationError('Parámetros de consulta inválidos', queryResult.error.errors); } const filters: CompanyFilters = queryResult.data; const result = await companiesService.findAll(req.tenantId!, filters); res.json({ success: true, data: result.data, meta: { total: result.total, page: filters.page, limit: filters.limit, totalPages: Math.ceil(result.total / (filters.limit || 20)), }, }); } catch (error) { next(error); } } async findById(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const { id } = req.params; const company = await companiesService.findById(id, req.tenantId!); res.json({ success: true, data: company, }); } catch (error) { next(error); } } async create(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const parseResult = createCompanySchema.safeParse(req.body); if (!parseResult.success) { throw new ValidationError('Datos de empresa inválidos', parseResult.error.errors); } const dto: CreateCompanyDto = parseResult.data; const company = await companiesService.create(dto, req.tenantId!, req.user!.userId); res.status(201).json({ success: true, data: company, message: 'Empresa creada exitosamente', }); } catch (error) { next(error); } } async update(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const { id } = req.params; const parseResult = updateCompanySchema.safeParse(req.body); if (!parseResult.success) { throw new ValidationError('Datos de empresa inválidos', parseResult.error.errors); } const dto: UpdateCompanyDto = parseResult.data; const company = await companiesService.update(id, dto, req.tenantId!, req.user!.userId); res.json({ success: true, data: company, message: 'Empresa actualizada exitosamente', }); } catch (error) { next(error); } } async delete(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const { id } = req.params; await companiesService.delete(id, req.tenantId!, req.user!.userId); res.json({ success: true, message: 'Empresa eliminada exitosamente', }); } catch (error) { next(error); } } async getUsers(req: AuthenticatedRequest, res: Response, next: NextFunction): Promise { try { const { id } = req.params; const users = await companiesService.getUsers(id, req.tenantId!); res.json({ success: true, data: users, }); } catch (error) { next(error); } } } export const companiesController = new CompaniesController();