feat(facturacion): fecha de emisión personalizable para I, E, T

- Frontend: input datetime-local visible solo para tipos I, E, T
  (no P). Default al día actual a las 12:00. Se resetea al cambiar tipo.
- Frontend: validación en handleSubmit: fecha ≤ ahora y ≥ ahora-72h
- Backend controller: validación idéntica antes de consumir timbre
- Backend servicios: pasa campo 'date' al payload de Facturapi
  cuando viene 'fechaEmision' en el body
- Build y deploy exitosos
This commit is contained in:
Horux Dev
2026-05-22 20:11:03 +00:00
parent 5ba31b7291
commit 1bde570035
5 changed files with 48 additions and 0 deletions

View File

@@ -138,6 +138,17 @@ export async function emitir(req: Request, res: Response, next: NextFunction) {
}
}
// ── Validar fecha de emisión (solo I, E, T) ──
const tipo = req.body.type || 'I';
if (tipo !== 'P' && req.body.fechaEmision) {
const fecha = new Date(req.body.fechaEmision);
const now = new Date();
const minDate = new Date(now.getTime() - 72 * 60 * 60 * 1000);
if (isNaN(fecha.getTime()) || fecha > now || fecha < minDate) {
throw new AppError(400, 'La fecha de emisión debe estar entre 72 horas en el pasado y el momento actual');
}
}
// Reservar timbre — si falla emisión en Facturapi, revertimos abajo
const consumedTimbre = await facturapiService.consumeTimbre(tenantId);

View File

@@ -457,6 +457,7 @@ export async function createInvoiceContribuyente(
if (data.series) invoicePayload.series = data.series;
if (data.folioNumber) invoicePayload.folio_number = data.folioNumber;
if (data.fechaEmision) invoicePayload.date = data.fechaEmision;
if (data.relatedDocuments?.length) {
// Estructura SAT 4.0: agrupa N uuids por tipo de relación. Acepta tanto

View File

@@ -340,6 +340,7 @@ export async function createInvoice(
if (data.series) invoiceData.series = data.series;
if (data.folioNumber) invoiceData.folio_number = data.folioNumber;
if ((data as any).fechaEmision) invoiceData.date = (data as any).fechaEmision;
// Documentos relacionados (Ingreso / Egreso / Pago / Traslado).
if (data.relatedDocuments?.length) {