import type { Request, Response, NextFunction } from 'express'; import { z } from 'zod'; import { AppError } from '../middlewares/error.middleware.js'; import * as activosFijosService from '../services/activos-fijos.service.js'; function effectiveTenantId(req: Request): string { return req.viewingTenantId || req.user!.tenantId; } const listSchema = z.object({ año: z.string().regex(/^\d{4}$/), mes: z.string().regex(/^\d{1,2}$/), contribuyenteId: z.string().uuid().optional(), estado: z.enum(['todos', 'activos', 'baja', 'agotados']).optional(), }); export async function list(req: Request, res: Response, next: NextFunction) { try { const q = listSchema.parse(req.query); const data = await activosFijosService.listActivosFijos( req.tenantPool!, effectiveTenantId(req), parseInt(q.año, 10), parseInt(q.mes, 10), q.contribuyenteId ?? null, q.estado, ); res.json(data); } catch (error) { if (error instanceof z.ZodError) return next(new AppError(400, error.errors[0].message)); next(error); } } const bajaSchema = z.object({ fechaBaja: z.string().regex(/^\d{4}-\d{2}-\d{2}$/), motivo: z.enum(['venta', 'desecho', 'otro']), comentario: z.string().max(2000).nullable().optional(), }); export async function darDeBaja(req: Request, res: Response, next: NextFunction) { try { const cfdiId = parseInt(String(req.params.cfdiId), 10); if (isNaN(cfdiId)) return next(new AppError(400, 'cfdiId inválido')); const data = bajaSchema.parse(req.body); await activosFijosService.darDeBaja( req.tenantPool!, cfdiId, data.fechaBaja, data.motivo, req.user!.userId, data.comentario ?? null, ); res.status(201).json({ ok: true }); } catch (error) { if (error instanceof z.ZodError) return next(new AppError(400, error.errors[0].message)); next(error); } } const usosExcluidosSchema = z.object({ contribuyenteId: z.string().uuid(), usos: z.array(z.string().regex(/^I0[1-8]$/)), }); export async function setUsosExcluidos(req: Request, res: Response, next: NextFunction) { try { const { contribuyenteId, usos } = usosExcluidosSchema.parse(req.body); const saved = await activosFijosService.setUsosExcluidos(req.tenantPool!, contribuyenteId, usos); res.json({ usosExcluidos: saved }); } catch (error) { if (error instanceof z.ZodError) return next(new AppError(400, error.errors[0].message)); next(error); } } export async function revertirBaja(req: Request, res: Response, next: NextFunction) { try { const cfdiId = parseInt(String(req.params.cfdiId), 10); if (isNaN(cfdiId)) return next(new AppError(400, 'cfdiId inválido')); const ok = await activosFijosService.revertirBaja(req.tenantPool!, cfdiId); if (!ok) return next(new AppError(404, 'Activo no estaba dado de baja')); res.status(204).send(); } catch (error) { next(error); } }