Skip to content

Nota de Ajuste - Eliminación

Anulación TipoNota: 2

¿Qué es una Nota de Ajuste de Eliminación?

Section titled “¿Qué es una Nota de Ajuste de Eliminación?”

La Nota de Ajuste de Eliminación se utiliza para anular completamente un documento de nómina electrónica previamente emitido. Una vez eliminado, el documento pierde validez legal.


Emisión Errónea

  • Nómina generada al empleado equivocado
  • Período incorrecto
  • Documento duplicado
  • Empleado ya no trabaja en la empresa

Cambios Administrativos

  • Revocación de pago
  • Cambio de modalidad de pago
  • Decisión administrativa
  • Error grave no corregible

Situaciones Legales

  • Orden judicial de anulación
  • Litigio laboral
  • Fraude detectado
  • Inconsistencias irreconciliables

Proceso Interno

  • Cancelación de liquidación
  • Cambio total de estructura
  • Migración de sistema
  • Corrección requiere re-emisión completa

  1. Nodo raíz: NominaIndividualDeAjuste (igual que Reemplazo)
  2. TipoNota: 2 (Eliminación)
  3. Contenido mínimo: Solo datos de referencia, NO el documento completo
  4. Efecto: El documento original queda anulado legalmente
Nota de Ajuste de Eliminación - Estructura
<?xml version="1.0" encoding="UTF-8"?>
<NominaIndividualDeAjuste
xmlns="dian:gov:co:facturaelectronica:NominaIndividualDeAjuste"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:xades="http://uri.etsi.org/01903/v1.3.2#"
xmlns:xades141="http://uri.etsi.org/01903/v1.4.1#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
SchemaLocation=""
xsi:schemaLocation="dian:gov:co:facturaelectronica:NominaIndividualDeAjuste NominaIndividualDeAjusteElectronicaXSD.xsd">
<ext:UBLExtensions/>
<!-- TipoNota: 2 = Eliminación -->
<TipoNota>2</TipoNota>
<Eliminar>
<!-- Referencia al documento a eliminar -->
<EliminandoPredecesor
NumeroPred="NOM35921"
CUNEPred="a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2"
FechaGenPred="2024-11-20"/>
<!-- Nuevo consecutivo para la eliminación -->
<NumeroSecuenciaXML
CodigoTrabajador="001"
Prefijo="DEL"
Consecutivo="00001"
Numero="DEL00001"/>
<LugarGeneracionXML
Pais="CO"
DepartamentoEstado="68"
MunicipioCiudad="68001"
Idioma="es"/>
<InformacionGeneral
Version="V1.0: Documento Soporte de Pago de Nómina Electrónica"
Ambiente="2"
TipoXML="103"
CUNE=""
EncripCUNE=""
FechaGen="2024-11-27"
HoraGen="14:30:00-05:00"
PeriodoNomina="5"
TipoMoneda="COP"
TRM="1"/>
<Notas>Anulación de nómina NOM35921 por emisión al empleado incorrecto. Autorizado por: Gerencia de RRHH. Motivo: Error administrativo.</Notas>
<!-- Datos del empleador (obligatorio) -->
<Empleador
RazonSocial="MI EMPRESA SAS"
NIT="901143311"
DV="8"
Pais="CO"
DepartamentoEstado="68"
MunicipioCiudad="68001"
Direccion="Calle 123 # 45-67"/>
</Eliminar>
</NominaIndividualDeAjuste>

Logo de starlight
GenerarNotaDeEliminacion.php
<?php
class Nomina_Service_EliminacionGenerator
{
private $db;
public function __construct()
{
$this->db = Zend_Db_Table::getDefaultAdapter();
}
/**
* Genera XML de Nota de Ajuste - Eliminación
*
* @param int $nominaOriginalId ID de la nómina a eliminar
* @param string $motivo Motivo de la eliminación
* @param string $autorizadoPor Persona que autoriza
* @return string XML de eliminación
*/
public function generarEliminacion(
$nominaOriginalId,
$motivo,
$autorizadoPor
) {
// 1. Obtener nómina original
$nominaOriginal = $this->obtenerNomina($nominaOriginalId);
if (!$nominaOriginal) {
throw new Exception("Nómina no encontrada");
}
// 2. Verificar estado autorizado
if ($nominaOriginal['estado'] !== 'AUTORIZADO') {
throw new Exception("Solo se pueden eliminar nóminas autorizadas");
}
// 3. Verificar CUNE
if (empty($nominaOriginal['cune'])) {
throw new Exception("La nómina no tiene CUNE");
}
// 4. Verificar que no está ya eliminada
if ($nominaOriginal['eliminada']) {
throw new Exception("Esta nómina ya fue eliminada");
}
// 5. Generar XML
$xml = $this->generarXMLEliminacion(
$nominaOriginal,
$motivo,
$autorizadoPor
);
// 6. Validar
$validator = new Nomina_Service_XMLValidator();
if (!$validator->validar($xml)) {
throw new Exception(
'XML de eliminación inválido: ' .
implode(', ', $validator->getErrores())
);
}
return $xml;
}
private function generarXMLEliminacion($original, $motivo, $autorizado)
{
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->formatOutput = true;
// Nodo raíz
$root = $dom->createElementNS(
'dian:gov:co:facturaelectronica:NominaIndividualDeAjuste',
'NominaIndividualDeAjuste'
);
// Namespaces...
$dom->appendChild($root);
// UBLExtensions
$ext = $dom->createElement('ext:UBLExtensions');
$root->appendChild($ext);
// TipoNota = 2 (Eliminación)
$tipoNota = $dom->createElement('TipoNota', '2');
$root->appendChild($tipoNota);
// Nodo Eliminar
$eliminar = $dom->createElement('Eliminar');
$root->appendChild($eliminar);
// EliminandoPredecesor
$predecesor = $dom->createElement('EliminandoPredecesor');
$predecesor->setAttribute('NumeroPred', $original['numero']);
$predecesor->setAttribute('CUNEPred', $original['cune']);
$predecesor->setAttribute('FechaGenPred', $original['fecha_generacion']);
$eliminar->appendChild($predecesor);
// NumeroSecuenciaXML (nuevo consecutivo)
$nuevoConsecutivo = $this->obtenerSiguienteConsecutivo('DEL');
$numSecuencia = $dom->createElement('NumeroSecuenciaXML');
$numSecuencia->setAttribute('CodigoTrabajador', $original['codigo_trabajador']);
$numSecuencia->setAttribute('Prefijo', 'DEL');
$numSecuencia->setAttribute('Consecutivo', $nuevoConsecutivo);
$numSecuencia->setAttribute('Numero', 'DEL' . $nuevoConsecutivo);
$eliminar->appendChild($numSecuencia);
// LugarGeneracionXML
$lugar = $dom->createElement('LugarGeneracionXML');
$lugar->setAttribute('Pais', 'CO');
$lugar->setAttribute('DepartamentoEstado', $original['departamento']);
$lugar->setAttribute('MunicipioCiudad', $original['municipio']);
$lugar->setAttribute('Idioma', 'es');
$eliminar->appendChild($lugar);
// InformacionGeneral
$infoGeneral = $dom->createElement('InformacionGeneral');
$infoGeneral->setAttribute('Version', 'V1.0: Documento Soporte de Pago de Nómina Electrónica');
$infoGeneral->setAttribute('Ambiente', '2');
$infoGeneral->setAttribute('TipoXML', '103');
$infoGeneral->setAttribute('CUNE', '');
$infoGeneral->setAttribute('EncripCUNE', '');
$infoGeneral->setAttribute('FechaGen', date('Y-m-d'));
$infoGeneral->setAttribute('HoraGen', date('H:i:s-05:00'));
$infoGeneral->setAttribute('PeriodoNomina', $original['periodo_nomina']);
$infoGeneral->setAttribute('TipoMoneda', 'COP');
$infoGeneral->setAttribute('TRM', '1');
$eliminar->appendChild($infoGeneral);
// Notas (justificación)
$notas = $dom->createElement(
'Notas',
sprintf(
'Anulación de nómina %s. Motivo: %s. Autorizado por: %s. Fecha: %s',
$original['numero'],
$motivo,
$autorizado,
date('Y-m-d H:i:s')
)
);
$eliminar->appendChild($notas);
// Empleador
$empleador = $this->crearNodoEmpleador($dom, $original);
$eliminar->appendChild($empleador);
return $dom->saveXML();
}
private function crearNodoEmpleador($dom, $datos)
{
$empleador = $dom->createElement('Empleador');
$empleador->setAttribute('RazonSocial', $datos['empleador_razon_social']);
$empleador->setAttribute('NIT', $datos['empleador_nit']);
$empleador->setAttribute('DV', $datos['empleador_dv']);
$empleador->setAttribute('Pais', 'CO');
$empleador->setAttribute('DepartamentoEstado', $datos['empleador_departamento']);
$empleador->setAttribute('MunicipioCiudad', $datos['empleador_municipio']);
$empleador->setAttribute('Direccion', $datos['empleador_direccion']);
return $empleador;
}
private function obtenerSiguienteConsecutivo($prefijo)
{
$ultimo = $this->db->fetchOne("
SELECT MAX(CAST(consecutivo AS UNSIGNED))
FROM nomina_electronica
WHERE prefijo = ?
", [$prefijo]);
return str_pad((int)$ultimo + 1, 5, '0', STR_PAD_LEFT);
}
}

Tabla de auditoría
CREATE TABLE nomina_auditoria (
id INT PRIMARY KEY AUTO_INCREMENT,
nomina_id INT NOT NULL,
eliminacion_id INT,
accion ENUM('CREACION', 'MODIFICACION', 'ELIMINACION', 'DESCARGA') NOT NULL,
motivo TEXT,
autorizado_por VARCHAR(255),
usuario_id INT,
ip_address VARCHAR(45),
user_agent TEXT,
fecha TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
observaciones TEXT,
INDEX idx_nomina (nomina_id),
INDEX idx_usuario (usuario_id),
INDEX idx_fecha (fecha),
INDEX idx_accion (accion),
FOREIGN KEY (nomina_id) REFERENCES nomina_electronica(id),
FOREIGN KEY (eliminacion_id) REFERENCES nomina_electronica(id),
FOREIGN KEY (usuario_id) REFERENCES usuarios(id)
) ENGINE=InnoDB;

  • Verificar que el motivo es válido
  • Obtener autorización de supervisor
  • Documentar claramente la razón
  • Verificar que la nómina está autorizada
  • Confirmar que no está ya eliminada
  • Evaluar si se puede corregir en lugar de eliminar
  • TipoNota = 2
  • Nodo Eliminar presente
  • EliminandoPredecesor correcto
  • Nuevo consecutivo DEL
  • Notas justificativas detalladas
  • Solo datos mínimos incluidos
  • Registrar en auditoría
  • Actualizar estado en BD
  • Notificar al empleado
  • Ajustar registros contables
  • Documentar en expediente
  • Verificar autorización DIAN