erp-core-backend/src/modules/companies/companies.controller.ts
2025-12-12 14:39:29 -06:00

143 lines
4.4 KiB
TypeScript

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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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<void> {
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();