DEV Community

Nucleo360
Nucleo360

Posted on

Integrar los datos de fichaje con el software de nóminas: el flujo real (export-validación-gestoría)

Desde el 12 de mayo de 2019, el Real Decreto-ley 8/2019 (BOE-A-2019-3481) obliga a todas las empresas en España a llevar un registro horario diario de su plantilla. Ese registro no vive aislado: cada mes, alguien tiene que convertir horas trabajadas, horas extra y ausencias en una nómina. Y ahí es donde muchas pymes pierden tiempo (y cometen errores).

En este artículo documentamos el flujo real para llevar los datos de fichaje de Nucleo360 hasta el software de nóminas o el gestor laboral, con un paso de validación intermedio que te puede ahorrar más de un disgusto.

Empecemos por la honestidad técnica

Nucleo360 no calcula nóminas. Es una decisión de producto deliberada: la plataforma cubre el registro horario, las vacaciones y ausencias, la gestión documental, el canal de denuncias y el resto de la gestión de RRHH de una pyme, y exporta la documentación y los datos al gestor laboral o al software de nóminas que ya usa la empresa. El cálculo de la nómina (convenios, cotizaciones, IRPF) lo hace quien mejor sabe hacerlo: tu asesoría o tu programa de nóminas.

Eso significa que la integración de la que hablamos aquí no es una sincronización mágica en tiempo real, sino un pipeline de datos clásico y robusto: exportar → validar → entregar. Es aburrido, y por eso funciona.

El flujo en tres pasos

Paso 1 · Exportar el periodo desde Nucleo360

Al cierre de cada mes (o del periodo que pacte tu gestoría), se exportan desde Nucleo360 los datos del registro horario del periodo: fichajes por empleado y día, con sus tramos de entrada y salida y los totales. El registro es inmutable y con trazabilidad (quién fichó, cuándo y desde dónde), así que lo que exportas refleja lo que realmente se registró, no una versión editada a posteriori.

Para nóminas, lo habitual es trabajar con el export en formato tabular (CSV) o con los informes del periodo, según lo que acepte tu gestor.

Paso 2 · Validar antes de enviar

Este es el paso que casi nadie hace y el que más errores evita. Antes de entregar los datos a quien hace la nómina, conviene comprobar tres cosas:

  1. Totales por empleado: que las horas del mes cuadran con lo esperado (jornada pactada ± extras).
  2. Huecos: días laborables sin ningún fichaje. Pueden ser vacaciones o ausencias legítimas (cotéjalo con el módulo de vacaciones), o pueden ser olvidos que hay que resolver antes de que lleguen a la nómina.
  3. Solapes: tramos que se pisan entre sí (entrada a las 9:00 y a las 9:30 sin salida intermedia). Suelen indicar un fichaje duplicado o mal cerrado.

Aquí tienes un ejemplo genérico en Python (solo librería estándar) que hace exactamente eso sobre un CSV de fichajes. No depende de ningún proveedor: ajusta los nombres de columna a los de tu export real.

#!/usr/bin/env python3
"""
EJEMPLO GENÉRICO de validación de un CSV de fichajes antes de
entregarlo al gestor laboral. Ajusta columnas y delimitador a tu export.

Formato esperado (una fila por tramo de fichaje):
    empleado_id;nombre;fecha;hora_entrada;hora_salida
    E001;Ana;2026-07-01;08:00;15:00
"""
import csv
import sys
from collections import defaultdict
from datetime import datetime, timedelta

FORMATO_FECHA = "%Y-%m-%d"
FORMATO_HORA = "%H:%M"


def cargar(ruta):
    tramos = defaultdict(list)   # (empleado_id, fecha) -> [(inicio, fin), ...]
    nombres = {}
    with open(ruta, newline="", encoding="utf-8") as f:
        for n_linea, fila in enumerate(csv.DictReader(f, delimiter=";"), start=2):
            try:
                dia = datetime.strptime(fila["fecha"], FORMATO_FECHA).date()
                entrada = datetime.combine(
                    dia, datetime.strptime(fila["hora_entrada"], FORMATO_HORA).time())
                salida = datetime.combine(
                    dia, datetime.strptime(fila["hora_salida"], FORMATO_HORA).time())
            except (KeyError, ValueError) as e:
                print(f"[ERROR] Línea {n_linea}: fila ilegible ({e})")
                continue
            if salida <= entrada:
                # Turno nocturno: la salida cae en el día siguiente
                salida += timedelta(days=1)
            tramos[(fila["empleado_id"], dia)].append((entrada, salida))
            nombres[fila["empleado_id"]] = fila.get("nombre", "")
    return tramos, nombres


def validar(tramos, nombres):
    total = defaultdict(timedelta)
    dias = defaultdict(set)
    incidencias = 0

    for (emp, dia), lista in sorted(tramos.items()):
        lista.sort()
        # Solapes dentro del mismo día
        for (ini_a, fin_a), (ini_b, fin_b) in zip(lista, lista[1:]):
            if ini_b < fin_a:
                print(f"[SOLAPE] {emp} {dia}: "
                      f"{ini_a:%H:%M}-{fin_a:%H:%M} se pisa con {ini_b:%H:%M}-{fin_b:%H:%M}")
                incidencias += 1
        for ini, fin in lista:
            total[emp] += fin - ini
        dias[emp].add(dia)

    # Huecos: días laborables (L-V) sin fichajes dentro del rango del archivo.
    # OJO: pueden ser vacaciones o ausencias legítimas; esto solo los señala.
    for emp, fechas in dias.items():
        d, ultimo = min(fechas), max(fechas)
        while d <= ultimo:
            if d.weekday() < 5 and d not in fechas:
                print(f"[HUECO] {emp} ({nombres[emp]}): sin fichajes el {d} "
                      f"(¿vacaciones/ausencia sin cotejar?)")
                incidencias += 1
            d += timedelta(days=1)

    print("\n--- Totales por empleado ---")
    for emp, t in sorted(total.items()):
        horas = t.total_seconds() / 3600
        print(f"{emp} {nombres[emp]:<20} {horas:6.2f} h en {len(dias[emp])} días")
    return incidencias


if __name__ == "__main__":
    if len(sys.argv) != 2:
        sys.exit("Uso: python valida_fichajes.py fichajes.csv")
    tramos, nombres = cargar(sys.argv[1])
    n = validar(tramos, nombres)
    print(f"\n{n} incidencias detectadas.")
    sys.exit(1 if n else 0)
Enter fullscreen mode Exit fullscreen mode

El script devuelve código de salida distinto de cero si hay incidencias, así que puedes encadenarlo en cualquier automatización: si algo no cuadra, el archivo no sigue viaje hacia la nómina.

Paso 3 · Entregar al gestor (bien empaquetado)

La entrega falla casi siempre por detalles tontos de formato, no por los datos. Pacta con tu gestoría o con quien opere el software de nóminas, una sola vez y por escrito:

  • Columnas y su orden (una tabla de mapeo de dos columnas es suficiente).
  • Codificación: UTF-8. Los nombres con tildes y eñes lo agradecerán.
  • Delimitador (; es lo habitual en España, porque la coma decimal rompe los CSV con ,).
  • Formato de fecha: ISO 8601 (2026-07-01) evita el clásico baile día/mes.
  • Fecha de corte: qué día del mes se exporta, para que la nómina no espere.

Y conserva una copia de lo entregado: el registro horario debe conservarse 4 años (art. 34.9 del Estatuto de los Trabajadores).

¿Y la integración directa por API?

Pregunta legítima de cualquier perfil técnico: «¿puedo saltarme el CSV y tirar de API?».

Respuesta honesta: a fecha de este artículo, la integración directa vía API con sistemas de nóminas está [PENDIENTE DE CONFIRMAR CON CLIENTE] — no hay una API pública documentada que podamos enseñarte aquí, y preferimos no inventárnosla. El flujo soportado y probado es el que acabas de leer: export, validación y entrega.

¿Se integra directamente con algún programa de nóminas concreto?

Misma honestidad: no hay integraciones directas confirmadas con programas concretos de nóminas ni con gestorías [PENDIENTE DE CONFIRMAR CON CLIENTE]. Lo que sí funciona hoy es el puente universal: la mayoría de software de nóminas y gestorías aceptan importación de datos tabulares (CSV) o trabajan directamente con los informes del periodo. Pregunta a tu gestor qué formato de importación acepta su herramienta y pacta el mapeo de columnas del Paso 3.

¿Menos glamuroso que un webhook? Sí. ¿Funciona con cualquier gestoría de España sin depender de que dos proveedores se pongan de acuerdo? También.

En resumen

  • Nucleo360 registra la jornada (registro inmutable, con trazabilidad) y exporta; la nómina la calcula tu gestor o tu software de nóminas.
  • Valida siempre antes de entregar: totales, huecos y solapes. El script de arriba es un punto de partida.
  • Pacta el formato con tu gestoría una vez y por escrito; UTF-8, ; e ISO 8601 te evitan el 90 % de los problemas.
  • API pública e integraciones directas con programas concretos: pendientes de confirmar; hoy el camino es el export.

Si quieres ver el módulo de registro horario en detalle (el plan Basic es gratuito y sin permanencia), tienes toda la información en nucleo360.com.


Última actualización: julio de 2026.

Nucleo360.com

Top comments (0)