Files
HoruxDespachosNuevo/apps/api/src/controllers/contribuyente-config.controller.ts

96 lines
4.0 KiB
TypeScript

import type { Request, Response, NextFunction } from 'express';
import { AppError } from '../middlewares/error.middleware.js';
import * as fielService from '../services/contribuyente-fiel.service.js';
import * as facturapiService from '../services/contribuyente-facturapi.service.js';
import { getContribuyenteById } from '../services/contribuyente.service.js';
// ========== FIEL ==========
export async function uploadFiel(req: Request, res: Response, next: NextFunction) {
try {
const { cerFile, keyFile, password } = req.body;
if (!cerFile || !keyFile || !password) {
return next(new AppError(400, 'cerFile, keyFile y password son requeridos'));
}
const contribuyenteId = String(req.params.id);
const contrib = await getContribuyenteById(req.tenantPool!, contribuyenteId);
if (!contrib) return next(new AppError(404, 'Contribuyente no encontrado'));
const result = await fielService.uploadFielContribuyente(req.tenantPool!, contribuyenteId, cerFile, keyFile, password);
if (!result.success) {
console.error('[FIEL Upload] Failed:', result.message);
return res.status(400).json({ message: result.message });
}
return res.json(result);
} catch (err: any) {
console.error('[FIEL Upload] Exception:', err.message || err);
return next(err);
}
}
export async function fielStatus(req: Request, res: Response, next: NextFunction) {
try {
const contribuyenteId = String(req.params.id);
const status = await fielService.getFielStatusContribuyente(req.tenantPool!, contribuyenteId);
return res.json(status);
} catch (err) { return next(err); }
}
export async function deleteFiel(req: Request, res: Response, next: NextFunction) {
try {
const contribuyenteId = String(req.params.id);
// Delete from per-contribuyente table (tenant BD)
await req.tenantPool!.query(
'UPDATE fiel_contribuyente SET is_active = false WHERE contribuyente_id = $1',
[contribuyenteId]
);
// Also try to deactivate legacy FIEL if it matches this contribuyente's RFC
const { rows } = await req.tenantPool!.query('SELECT rfc FROM contribuyentes WHERE entidad_id = $1', [contribuyenteId]);
if (rows[0]?.rfc) {
const { prisma } = await import('../config/database.js');
await prisma.fielCredential.updateMany({
where: { rfc: rows[0].rfc },
data: { isActive: false },
}).catch(() => {});
}
return res.json({ message: 'FIEL eliminada' });
} catch (err) { return next(err); }
}
// ========== FACTURAPI ==========
export async function createOrg(req: Request, res: Response, next: NextFunction) {
try {
const contribuyenteId = String(req.params.id);
const contrib = await getContribuyenteById(req.tenantPool!, contribuyenteId);
if (!contrib) return next(new AppError(404, 'Contribuyente no encontrado'));
const result = await facturapiService.createOrgContribuyente(req.tenantPool!, contribuyenteId, contrib.nombre);
return res.status(201).json(result);
} catch (err: any) {
if (err.message?.includes('ya tiene')) return next(new AppError(409, err.message));
return next(err);
}
}
export async function orgStatus(req: Request, res: Response, next: NextFunction) {
try {
const contribuyenteId = String(req.params.id);
const status = await facturapiService.getOrgStatusContribuyente(req.tenantPool!, contribuyenteId);
return res.json(status);
} catch (err) { return next(err); }
}
export async function uploadCsd(req: Request, res: Response, next: NextFunction) {
try {
const { cerFile, keyFile, password } = req.body;
if (!cerFile || !keyFile || !password) {
return next(new AppError(400, 'cerFile, keyFile y password son requeridos'));
}
const contribuyenteId = String(req.params.id);
const result = await facturapiService.uploadCsdContribuyente(req.tenantPool!, contribuyenteId, cerFile, keyFile, password);
if (!result.success) return res.status(400).json({ message: result.message });
return res.json(result);
} catch (err) { return next(err); }
}