ÍNDICE

01. Visión General

Debido a la actualización de la Facturación Electrónica con la Reforma Fiscal 2022; se modificó en el apartado Recibo de Nómina (dentro de la documentación técnica Factura Electrónica) del CFDI 4.0, se establece que la vigencia de esta nueva versión inicia a partir del 01 de enero del 2022, el complemento de nómina versión 1.2 se integra con la versión 4.0 del CFDI en su revisión C, siendo obligatorio a partir del 1 de julio de 2022.

Por tanto, será a partir del 1 de julio de 2022 que se deje de utilizar la versión 3.3 y se generalice la obligación de emitir la versión 4.0.


Para cumplir con dicha reforma fiscal, se modifica el esquema del CFDI con los siguientes cambios:

Para mayor información ver la documentación del Portal del SAT.


02. Rutinas Utilizadas

Para contar con la nueva funcionalidad de Recibo de Nómina para versión CFDI 4.0, es necesario tener actualizadas las siguientes rutinas:


GPER884.PRWRecibos de Nomina CFDI v 1.2
GPER884.INIGeneración de XML para recibos de Nómina 3.3
GPER88440.INIGeneración de XML para recibos de Nómina 4.0
GPTABMEX.PRXDefinición tablas alfanuméricas. 
GPCRGMEX.PRXMantenimiento tablas alfanuméricas. 
TIMBRERN.PRWTimbrado de CFDI con Complemento de Recibo de Nómina.
CANCTFD.PRWCancelación de CFDI con Complemento de Nómina.

Al contar con las versiones de las rutinas descritas anteriormente; en la rutina Recibos de Nómina CFDI Versión 1.2 (GPER884), si no se cuenta con la actualización del Diccionario de Datos mencionadas en el presente Documento Técnico, no se podrá utilizar la rutina. Se enviará un mensaje indicando que se debe actualizar el grupo de preguntas GPER884.

Lo anterior se agregó para evitar errores en el proceso de Timbrado y Cancelación.

03. Ejemplo de Utilización

Implementación

  1. Se debe tener implementada la solución de recibos de nómina 3.3 v1.2, para más detalle consultar el documento Recibo de Nómina CFDi versión 3.3: DT Recibo de Nómina CFDi 3.3 - México.

  2. Tener implementada la cancelación de CFDI Nómina con motivos de cancelación: 13481039 DNOMI-47 DT Cancelación CFDI de Nómina con Motivos de Cancelación MEX: verificar que se tenga actualizado el grupo de GPER884 y CANCTFD, creación de los campos RIW_MOTIVO y RIW_IDSUST.

  3. Configurar parámetro MV_CFDI40 igual a ".T." para activar la versión 4.0 del CFDI, verificar que se tenga creado el campo RA_FISCALI y la consulta MEX010; mencionadas en la sección 05. DICCIONARIO DE DATOS.
  4. Verificar que se tenga información del catálogo S010 - Régimen Fiscal (tablas F3H - Definición de catálogos y F3I - Catálogos del módulo de Facturación) para más detalle consultar el apartado 05. DICCIONARIO DE DATOS.
  5. Copiar el script de Generación de XML para recibos de Nómina 4.0 (GPER88440.INI), en la carpeta "system" del ambiente (con los ajustes mencionados anteriormente) y realizar la parametrización necesaria.
  6. Respaldar las tablas alfanuméricas (RCB y RCC), eliminar el contenido de la tabla S031 - Tipo concepto SAT.
  7. A través de la rutina “Definición Tablas” y “Mantenimiento Tab." en el menú SIGAGPE (Actualizaciones | Definic. de Cálculo), se debe entrar a las rutinas para que se cree la tabla alfanumérica.
  8. A través de la rutina Empleados en el módulo Gestión de Personal – SIGAGPE (Actualizaciones | Empleados), registrar un empleado que tenga informado el C.P. (RA_CEP) y el nuevo campo Rég.Fiscal (RA_FISCALI), además de todas las configuraciones ya usadas para el versión 3.3.

    Los campos correspondientes al Nombre, RFC, Código Postal y Régimen Fiscal; tanto para el Emisor como Receptor deben coincidir con los registrados ante el SAT.

  9. A través de la rutina “Conceptos” en el menú SIGAGPE (Actualizaciones | Definic. de Cálculo), se deben tener registros de conceptos.

  10. A través de la rutina "Empleados" en el módulo Gestión de Personal – SIGAGPE (Actualizaciones | Empleados), tener empleados registrados.

  11. A través de la rutina "Tipos. de Procedim." en el módulo Gestión de Personal – SIGAGPE (Actualizaciones | Definic. Cálculo), contar con un procedimiento de nómina.
  12. A través de la rutina "Procesos" en el módulo Gestión de Personal (Actualizaciones | Definic. Cálculo), tener un proceso.
  13. A través de la rutina "Periodos" en el módulo Gestión de Personal – SIGAGPE (Actualizaciones | Definic. Cálculo), tener un periodo abierto para el procedimiento y proceso definidos.

  14. Realizar el Cálculo de Nómina para el empleado previamente configurado; módulo Gestión de Personal (SIGAGPE), rutina Miscelánea | Cálculos | Por Procedimientos (GPEM020).
  15. Verificamos los Movimientos de Nómina (SRC) para el Periodo, Proceso y Procedimiento calculados. 

04. Timbrado de Recibos de Nómina

Descripción general del proceso de Generación, Timbrado, Impresión y Envío de Recibos de Nómina:

Ubicación

Menú

Gestión de Personal

Submenú

Informes | Empleados

Nombre de la Rutina

Recibo de Nómina CFDI V1.2

Programa

GPER884

Módulo

Gestión de Personal

Tipo

Función Protheus

Procedimiento

Recibo de Nómina CFDI v1.2 (GPER884.PRW):

  1. Ingresar al módulo Gestión de Personal (SIGAGPE), opción "Informes | Periódicos | Recibo de Nómina CFDI v1.2" (GPER884). Indicar los parámetros requeridos en base al cálculo realizado previamente:
    1. ¿Proceso?: Se debe definir el proceso para la generación de los recibos de nómina (teclear directamente o bien presionar la tecla F3 para la consulta de procesos - RCJ).
    2. ¿Procedimiento?: Se debe definir el procedimiento para la generación de los recibos de nómina (teclear el valor directamente o bien presionar la tecla F3 para consultar los procedimientos - SRY).
    3. ¿Periodo?: Se debe definir el periodo para la generación de los recibos de nómina (teclear directamente o bien presionar la tecla F3 para la consulta de periodos - RCH). Pueden ser periodos abiertos o cerrados.
    4. ¿Numero de Pago?: Se debe definir el número de pago para la generación de los recibos de nómina (teclear directamente o bien presionar la tecla F3 para consultar los números de pago – RCH01).
    5. ¿Pre-imp/Mail?: Se debe definir el tipo de generación de los recibos de nómina. Las opciones disponibles son “Impreso” e “E-mail”. Indicar la opción "Impreso"
    6. ¿De Sucursal / A Sucursal?: Se debe definir el rango de las sucursales para la generación de los recibos de nómina (teclear directamente o bien presionar la tecla F3 para consultar las sucursales – XM0).
    7. ¿De Matricula / A Matricula?: Se debe definir el rango de matrículas para la generación de los recibos de nómina (teclear directamente o bien presionar la tecla F3 para consultar las matrículas – SRA02).
    8. ¿De Nombre? / ¿A Nombre:? Se debe definir el rango de nombres para la generación de los recibos de nómina (teclearlo directamente).
    9. ¿De Nº de Tarj. sin Rel.? / ¿A Nº de Tarj. sin Rel.?: Se debe ingresar el número de tarjeta para la generación de los recibos de nómina (teclear directamente).
    10. ¿De Centro de Costo? / ¿A Centro de Costo?: Se debe definir el rango de centro de costos para la generación de los recibos de nómina (teclear directamente o bien presionar la tecla F3 para consultar los centros de costo - CTT).
    11. ¿De Departamento? / ¿A Departamento?: Se debe definir el rango de departamentos para la generación de los recibos de nómina (teclear directamente o bien presionar la tecla F3 para consultar departamentos - SQB).
    12. ¿Situaciones por Impr?.: Se debe definir las situaciones o estatus por imprimir para la generación de los recibos de nómina (teclear directamente).
    13. ¿Categorías por Impr.?: Se debe definir las categorías por imprimir para la generación de los recibos de nómina (teclear directamente).
    14. Mensaje 1 / Mensaje 2 / Mensaje 3/ Mensaje Pie de Pag.: Definir un mensaje para mostrar en la generación de los recibos de nómina (teclear directamente o bien presionar la tecla F3 para consultar mensajes – S018). Este mensaje se mostrara en la sección de mensajes del Recibo.
    15. ¿De Local Pago? / ¿A Local Pago?: Definir el rango de Localidades de Pago para la generación de los recibos de nómina (teclear directamente).
    16. ¿Sumariza Concepto?: Definir si el concepto será resumido. Las opciones disponibles son “Si” o “No”.
    17. ¿Envía Timbrar?: Definir si se envía a Timbrar o solo se imprimen. Las opciones disponibles son “Si” o “No”.
  2. Confirmar la generación del Recibo de Nómina.
  3. Verificar que el XML contenga los siguientes atributos en azul:

<?xml version="1.0" encoding="UTF-8"?>
<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:nomina12="http://www.sat.gob.mx/nomina12" xsi:schemaLocation="http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd http://www.sat.gob.mx/nomina12 http://www.sat.gob.mx/sitio_internet/cfd/nomina/nomina12.xsd" Version="4.0" Serie="000012D MG 01" Folio="020120200301" Fecha="2022-04-07T15:04:59" Sello="5mi2bys8eHtz2uXguxXWqyEfqjtCMDTQ==" NoCertificado="00001000000502636197" Certificado="MRS/CtUeOxXZxFgnV6luIS1kzu+7aj4WR+m3" SubTotal="14783.93" Descuento="1927.25" Moneda="MXN" Total="12856.68" TipoDeComprobante="N" Exportacion="01" MetodoPago="PUE" LugarExpedicion="76000">

    <cfdi:Emisor Rfc="TME031112BC0" Nombre="TOTVS MEXICO" RegimenFiscal="601"/>
    <cfdi:Receptor Rfc="GORM900830JN4" Nombre="MARCO AUGUSTO GONZALEZ RIVERA" DomicilioFiscalReceptor="76117" RegimenFiscalReceptor="605" UsoCFDI="CN01"/>
    <cfdi:Conceptos> 
        <cfdi:Concepto ClaveProdServ="84111505" Cantidad="1" ClaveUnidad="ACT" Descripcion="Pago de nómina" ValorUnitario="14783.93" Importe="14783.93" Descuento="1927.25" ObjetoImp="01"/>
    </cfdi:Conceptos>
    <cfdi:Complemento> 
    <nomina12:Nomina Version="1.2" TipoNomina="O" FechaPago="2020-03-15" FechaInicialPago="2020-03-01" FechaFinalPago="2020-03-15" NumDiasPagados="1" TotalPercepciones="14783.92" TotalDeducciones="1927.25" TotalOtrosPagos="0.01" >
        <nomina12:Emisor RegistroPatronal="TOV12312312345" RfcPatronOrigen="TME031112BC0"/>
        <nomina12:Receptor Curp="GUCJ711118HMCRRS01" NumSeguridadSocial="96907103020" FechaInicioRelLaboral="2020-01-01" Antigüedad="P10W"  TipoContrato="01" Sindicalizado="No" TipoJornada="01" TipoRegimen="02" NumEmpleado="000012" Departamento="DEPARTAMENTO 05" Puesto="ADMINISTRATIVO" RiesgoPuesto="1" PeriodicidadPago="04" Banco="030" CuentaBancaria="1234567891" SalarioBaseCotApor="7701.00" SalarioDiarioIntegrado="107.32" ClaveEntFed="QUE"/>
        <nomina12:Percepciones TotalSueldos="14783.92" TotalGravado="7701.00" TotalExento="7082.92">
            <nomina12:Percepcion TipoPercepcion="001" Clave="100" Concepto="Sueldo" ImporteGravado="7701.00" ImporteExento="0.00"/>
            <nomina12:Percepcion TipoPercepcion="004" Clave="705" Concepto="Neto Pagado" ImporteGravado="0.00" ImporteExento="7082.92"/>
        </nomina12:Percepciones>
        <nomina12:Deducciones TotalOtrasDeducciones="1309.17" TotalImpuestosRetenidos="618.08" >
            <nomina12:Deduccion TipoDeduccion="002" Clave="403" Concepto="ISR Neto" Importe="618.08"/>
            <nomina12:Deduccion TipoDeduccion="048" Clave="490" Concepto="Provision IETU" Importe="1309.17"/>
        </nomina12:Deducciones> 
        <nomina12:OtrosPagos>
            <nomina12:OtroPago TipoOtroPago="002" Clave="002" Concepto="Subsidio para el empleo (Efectivamente entregado al trabajador)." Importe="0.01" >
                <nomina12:SubsidioAlEmpleo SubsidioCausado="0.01"/>
            </nomina12:OtroPago>
        </nomina12:OtrosPagos>

    </nomina12:Nomina> 
</cfdi:Complemento>
</cfdi:Comprobante>

  • xlms:cfdi / xsi:schemaLocation = Contienen las URL's correspondientes a la versión 4.0 de CFDI.
  • Exportacion = Definido en la guía de llenado que debe llevar el valor "01".
  • RegimenFiscal (Emisor) = Código registrado ante el SAT.
  • DomicilioFiscalReceptor = Código Postal del Receptor, tomado del campo RA_CEP.
  • RegimenFiscalReceptor = Código registrado ante el SAT para el Empleado, tomado del campo RA_FISCALI.
  • UsoCFDI = Definido en la guía de llenado que debe levar el valor "CN01".
  • ObjetoImp = Definido en la guía de llenado que debe levar el valor "01"


05. Diccionario de Datos

Verificar que se tengan las siguientes configuraciones, en caso contrario, crearlas desde la opción Base de Datos (Base de Datos | Diccionario) el módulo del Configurador (SIGACFG).


Parámetros en el archivo SX6 – Parámetros:


Nombre de la Variable

MV_CFDI40

Tipo

Lógico

Descripción

Uso de CFDI versión 4.0

Valor Estándar.T.


Actualización Consulta Estándar en el archivo SXB – Consulta Estándar:


Alias

Tipo

SecuenciaColumnaDescripciónContenido

MEX010

1

01RERégimen fiscalF3I

MEX010

2

0101Régimen fiscalF812SXB("S010","RegiFiscal")

MEX010

5

01

VAR_IXB


En la Tabla SRA - Maestro de Empleados:

Se agregó el siguiente campo:

CampoRA_FISCALI
TipoC - Carácter
Tamaño3
Decimal0
Formato@!
ContextoReal
PropiedadModificar
Tit. EspañolRég. Fiscal
Desc. EspañolRégimen Fiscal
ValidaciónVazio() .Or. ValidF3I("S010",M->RA_FISCALI,1,3)
ObligatorioNo
ConsultaMEX010
UsadoSi
Exhibe en BrowseNo
Help

Atributo requerido para incorporar la clave del régimen fiscal del contribuyente receptor al que aplicará el efecto fiscal de este comprobante.

Las actualizaciones al Diccionario de Datos, se realizaron en los siguientes paquetes:

Código: 010082

Contenido: Crea del parámetro MV_CFDI40 y la consulta MEX010.


Código: 010339

Pacote: DNOMI-176 - Recibo de pago de nómina y su complemento versión 4.0 del CFDi.

Contenido: Crea el campo RA_FISCALI.


07. Archivo de Configuración (GPER884.INI)

Realizar las modificaciones resaltadas en azul, para el Script de Generación del Comprobante Fiscal del Recibo de Nómina, como se muestra a continuación:

/*GPER884.INI V1.2 - Modelo 2017 - 20/03/2017*/
[XXX POSICIONAMENTOS]

[XXX INICIALIZACION]   
(PRE) SRVPD->(DbSetOrder(1)) 
(PRE) _aTotal[072] := SRA->RA_FILIAL
(PRE) _aTotal[073] := SRA->RA_MAT
(PRE) _aTotal[074] := ""
(PRE) _aTotal[075] := CFDCarEsp(Alltrim(SM0->M0_NOMECOM))
(PRE) _aTotal[076] := StrZero(Year(Date()),4) + "-" + StrZero(Month(Date()),2) + "-" + StrZero(Day(Date()),2) + "T" + Time() 
(PRE) _aTotal[077] := Alltrim(MV_PAR01)+Alltrim(MV_PAR02)+Alltrim(MV_PAR03)+Alltrim(MV_PAR04)
(PRE) _aTotal[078] := Alltrim(SRA->RA_MAT)+Alltrim(SRA->RA_FILIAL)
(PRE) _aTotal[098] := "|"
(PRE) _aTotal[099] := "||"
(PRE) _aTotal[100] := ""

//CADENA  ORIGINAL
[SRA CADENAORIGINAL_SELLO]

//Variable utilizada para validar si es Regimen Asimilado
(PRE) lRegAsimil := SRA->RA_TIPREG $ "05|06|07|08|09|10|11"

//Cadena Original
(PRE) cCadOrig := _aTotal[099]
//Version
(PRE) cCadOrig += "3.3" + _aTotal[098]
//Serie
(PRE) cCadOrig += _aTotal[078] + _aTotal[098]
//Folio
(PRE) cCadOrig += _aTotal[077] + _aTotal[098]
//Fecha
(PRE) cCadOrig += Alltrim(_aTotal[076]) + _aTotal[098]
//Forma Pago
(PRE) cCadOrig += CFDCarEsp("99") + _aTotal[098]
//Num Certificado
(PRE) cCadOrig += SuperGetMv("MV_CFDI_CS",,"") + _aTotal[098]
//Subtotal
(PRE) cCadOrig += Alltrim(Transform(Round(nTotPGrav + nTotPExen + IIf(lRegAsimil, 0, nTotOtroP), 2), "99999999.99")) + _aTotal[098]
//Descuento
(PRE) cCadOrig += Alltrim(Transform(Round(nOtroDedu+nImpReten,2), "99999999.99")) + _aTotal[098]
//Moneda
(PRE) cCadOrig += Alltrim("MXN") + _aTotal[098]
//Total
(PRE) cCadOrig += Alltrim(Transform(Round(nTotPGrav + nTotPExen + IIf(lRegAsimil, 0, nTotOtroP) - (nOtroDedu + nImpReten), 2), "99999999.99")) + _aTotal[098]
//Tipo Comprobante
(PRE) cCadOrig += Alltrim("N") + _aTotal[098]
//Metodo Pago
(PRE) cCadOrig += Alltrim("PUE") + _aTotal[098]
//Lugar de expedición
(PRE) cCadOrig += CFDCarEsp(AllTrim(RGC->RGC_CODPOS)) + _aTotal[098] 
//Tipo Relacionados
(PRE) cCadOrig += NodoRelacc(3) 
//UUIDS Relacionados
(PRE) cCadOrig += NodoRelacc(1)

//COMPROBANTE:EMISOR
//:RFC
(PRE) cCadOrig += CFDCarEsp(Alltrim(SM0->M0_CGC)) + _aTotal[098]
//:Nombre
(PRE) cCadOrig += Alltrim(SM0->M0_NOMECOM) + _aTotal[098]
//:Regimen
(PRE) cCadOrig += cTipoReg + _aTotal[098]

//COMPROBANTE:RECEPTOR
//:RFC
(PRE) cCadOrig += CFDCarEsp(AllTrim(SRA->RA_CIC)) + _aTotal[098]
//:Nombre
(PRE) cCadOrig += CFDCarEsp(Alltrim(SRA->RA_NOME)) + _aTotal[098]
//:UsoCFDI
(PRE) cCadOrig += Alltrim("P01") + _aTotal[098]

//COMPROBANTE:CONCEPTOS
//Clave Servicio
(PRE) cCadOrig += AllTrim("84111505")+ _aTotal[098]
//:Cantidad
(PRE) cCadOrig += Alltrim("1")+ _aTotal[098]
//:Unidad de medida
(PRE) cCadOrig += Alltrim("ACT")+ _aTotal[098]
//:Descripcion
(PRE) cCadOrig += DECODEUTF8(AllTrim("Pago de nómina")) + _aTotal[098]
//:valorUnitario
(PRE) cCadOrig += AllTrim(Transform(Round(nTotPGrav + nTotPExen + IIf(lRegAsimil, 0, nTotOtroP),2), "99999999.99")) + _aTotal[098]
//Importe
(PRE) cCadOrig += AllTrim(Transform(Round(nTotPGrav + nTotPExen + IIf(lRegAsimil, 0, nTotOtroP),2), "99999999.99")) + _aTotal[098]
//TotalDeducciones
(PRE) cCadOrig += Alltrim(Transform(Round(nTotDGrav+nTotDExen,2), "99999999.99")) + _aTotal[098]

//NOMINA
//version
(PRE) cCadOrig += "1.2" + _aTotal[098]
//TipoNomina
(PRE) cCadOrig += IIf(SRY->RY_TIPO == "1" .And. !lImprIndem, "O", "E") + _aTotal[098]
//FechaPago
(PRE) cCadOrig += Alltrim(STR(YEAR(dFchPag)))+"-"+ STRZERO(MONTH(dFchPag),2) +"-"+STRZERO(DAY(dFchPag),2) + _aTotal[098]
//FechaInicialPago
(PRE) cCadOrig += Alltrim(STR(YEAR(dFchInPag)))+"-"+ STRZERO(MONTH(dFchInPag),2) +"-"+STRZERO(DAY(dFchInPag),2) + _aTotal[098]
//FechaFinalPago
(PRE) cCadOrig += Alltrim(STR(YEAR(dFchFiPag)))+"-"+ STRZERO(MONTH(dFchFiPag),2) +"-"+STRZERO(DAY(dFchFiPag),2) + _aTotal[098]
//NumDiasPagados
(PRE) cCadOrig += Alltrim(Str(IIf(nDiasPag == 0, 1, nDiasPag))) + _aTotal[098]
//TotalPercepciones
(PRE) cCadOrig += IIf(nTotPGrav+nTotPExen <> 0, Alltrim(Transform(Round(nTotPGrav+nTotPExen,2), "99999999.99")) + _aTotal[098], "")
//TotalDeducciones
(PRE) cCadOrig += IIf(nTotDGrav+nTotDExen <> 0, Alltrim(Transform(Round(nTotDGrav+nTotDExen,2), "99999999.99")) + _aTotal[098], "")
//TotalOtrosPagos
(PRE) cCadOrig += IIf(nTotOtroP <> 0 .And. !lRegAsimil, AllTrim(Transform(Round(nTotOtroP,2), "99999999.99")) + _aTotal[098], "")

//EMISOR
//RegistroPatronal
(PRE) cCadOrig += IIf(SRA->RA_CATFUNC <> 'A' .And. !lRegAsimil .And. !lImprIndem, AllTrim(cRegPatr) + _aTotal[098], "")
//RfcPatronOrigen
(PRE) cCadOrig += CFDCarEsp(Alltrim(SM0->M0_CGC)) + _aTotal[098]

//EntidadSNCF
(PRE) IIf(!Empty(cOrigRecur), cCadOrig += Alltrim(cOrigRecur) + _aTotal[098], "")
(PRE) IIf(!Empty(cOrigRecur), cCadOrig += Alltrim(Transform(Round(nTotPGrav+nTotPExen,2), "99999999.99")) + _aTotal[098], "")

//RECEPTOR
//Curp
(PRE) cCadOrig += Alltrim(SRA->RA_CURP) + _aTotal[098]
//NumSeguridadSocial
(PRE) IIf(SRA->RA_CATFUNC <> 'A' .And. !lRegAsimil .And. !lImprIndem, cCadOrig += AllTrim(SRA->RA_RG) + _aTotal[098], "")
//FechaInicioRelLaboral
(PRE) IIf(SRA->RA_CATFUNC <> 'A' .And. !lRegAsimil .And. !lImprIndem, cCadOrig += AllTrim(Str(Year(dFchInLab))) + "-" + StrZero(Month(dFchInLab),2) + "-" + StrZero(Day(dFchInLab),2) + _aTotal[098], "")
//Antigüedad
(PRE) IIf(SRA->RA_CATFUNC <> 'A' .And. !lRegAsimil .And. !lImprIndem, cCadOrig += 'P' + AllTrim(Str(nAntigue)) + 'W' + _aTotal[098], "")
//TipoContrato
(PRE) cCadOrig += IIf(lImprIndem,"99", Alltrim(SRA->RA_TIPCON)) + _aTotal[098]
//Sindicalizado
(PRE) IIf(SRA->RA_CATFUNC <> 'A', cCadOrig += IIf(!Empty(SRA->RA_SINDICA) .And. !lRegAsimil, "Sí", "No") + _aTotal[098], "")
//TipoJornada
(PRE) IIf(SRA->RA_CATFUNC <> 'A' .And. !lRegAsimil, cCadOrig += AllTrim(cTipJorn) + _aTotal[098], "")
//TipoRegimen
(PRE) cCadOrig += IIf(lImprIndem,"13",AllTrim(SRA->RA_TIPREG)) + _aTotal[098]
//NumEmpleado
(PRE) cCadOrig += AllTrim(SRA->RA_MAT) + _aTotal[098]
//Departamento
//MOD (PRE) cCadOrig += IIf(!Empty(cDeptoIm), AllTrim(cDeptoIm), "") + _aTotal[098]
(PRE) cCadOrig += IIf(!Empty(cDeptoIm), AllTrim(cDeptoIm) + _aTotal[098], "")
//Puesto
(PRE) cCadOrig += IIf(!Empty(cPuesCfdi), AllTrim(cPuesCfdi) + _aTotal[098], "")
//RiesgoPuesto
(PRE) cCadOrig += IIf(!lRegAsimil .AND. !lImprIndem, IIf(SRA->RA_CATFUNC <> 'A', AllTrim(cRiegCFDi), AllTrim("99"))  + _aTotal[098], "")
//PeriodicidadPago
(PRE) cCadOrig += CFDCarEsp(Alltrim(IIf(SRY->RY_TIPO == "1",cPerCFDi, "99"))) + _aTotal[098]
//Banco
(PRE) IIf(!Empty(SRA->RA_CLABE),,cCadOrig += IIf(!Empty(cBcoCfdi), Alltrim(cBcoCfdi) + _aTotal[098], ""))
//CLABE
(PRE) cCadOrig += IIf(!Empty(SRA->RA_CLABE), Alltrim(SRA->RA_CLABE), Alltrim(SRA->RA_CTDEPSA)) + _aTotal[098]
//SalarioBaseCotApor
(PRE) IIf(SRA->RA_CATFUNC <> 'A', cCadOrig += Alltrim(Transform(Round(nSalBasAp,2), "99999999.99")) + _aTotal[098], "")
//SalarioDiarioIntegrado
(PRE) IIf(SRA->RA_CATFUNC <> 'A' .And. !lRegAsimil .And. !lImprIndem, cCadOrig += AllTrim(Transform(Round(SRA->RA_SALINT,2), "99999999.99")) + _aTotal[098], "")
//ClaveEntFed
(PRE) cCadOrig += Alltrim(cEntFed) + _aTotal[098]

//SUBCONTRATACION
//RfcLabora
(PRE) cCadOrig += IIf(SRA->RA_PORSUB <> 0, Alltrim(SRA->RA_RFCLAB) + _aTotal[098], "")
//PorcentajeTiempo
(PRE) cCadOrig += IIf(SRA->RA_PORSUB <> 0, Alltrim(Str(SRA->RA_PORSUB)) + _aTotal[098], "")

//PERCEPCIONES
//TotalSueldos
(PRE) IIf(nTotSueld <> 0, cCadOrig += Alltrim(Transform(Round(nTotSueld,2), "99999999.99")) + _aTotal[098], "")
//TotalSeparacionIndemnizacion
(PRE) IIf(nTotIndem <> 0, cCadOrig += Alltrim(Transform(Round(nTotIndem,2), "99999999.99")) + _aTotal[098], "")
//TotalJubilacionPensionRetiro
(PRE) IIf(nTotJubil <> 0, cCadOrig += Alltrim(Transform(Round(nTotJubil,2), "99999999.99")) + _aTotal[098], "")
//TotalGravado
(PRE) cCadOrig += Alltrim(Transform(Round(nTotPGrav,2), "99999999.99")) + _aTotal[098]
//TotalExento
(PRE) cCadOrig += Alltrim(Transform(Round(nTotPExen,2), "99999999.99")) + _aTotal[098]
//PERCEPCION (AccionesOTitulos y/o Horas Extras)
(PRE) VldCad884("1")

//JubilacionPensionRetiro
//TotalUnaExhibicion
(PRE) IIf(nTotUnaEx <> 0, cCadOrig += Alltrim(Transform(Round(nTotUnaEx,2), "99999999.99")) + _aTotal[098], "")
//TotalParcialidad
(PRE) IIf(nTotParci <> 0, cCadOrig += Alltrim(Transform(Round(nTotParci,2), "99999999.99")) + _aTotal[098], "")
//MontoDiario
(PRE) IIf(nTotParci <> 0, cCadOrig += Alltrim(Transform(Round(nTotDiari,2), "99999999.99")) + _aTotal[098], "")
//IngresoAcumulable
(PRE) IIf(nTotUnaEx+nTotParci <> 0, cCadOrig += Alltrim(Transform(Round(nTotIAcum,2), "99999999.99")) + _aTotal[098], "")
//IngresoNoAcumulable
(PRE) IIf(nTotUnaEx+nTotParci <> 0, cCadOrig += Alltrim(Transform(Round(NTotNAcum,2), "99999999.99")) + _aTotal[098], "")

//SeparacionIndemnizacion 
//TotalPagado
(PRE) IIf(nTotPagad <> 0, cCadOrig += Alltrim(Transform(Round(nTotPagad,2), "99999999.99")) + _aTotal[098], "")
//NumAñosServicio
(PRE) IIf(nTotPagad <> 0, cCadOrig += Alltrim(Str(IIf(nNumAnios==0, 1, nNumAnios))) + _aTotal[098], "")
//UltimoSueldoMensOrd
(PRE) IIf(nTotPagad <> 0, cCadOrig += Alltrim(Transform(Round(nUltSuelM,2), "99999999.99")) + _aTotal[098], "")
//IngresoAcumulable
(PRE) IIf(nTotPagad <> 0, cCadOrig += Alltrim(Transform(Round(nIngrAcum,2), "99999999.99")) + _aTotal[098], "")
//IngresoNoAcumulable
(PRE) IIf(nTotPagad <> 0, cCadOrig += Alltrim(Transform(Round(nIngrNAcu,2), "99999999.99")) + _aTotal[098], "")

//DEDUCCIONES
//TotalOtrasDeducciones
(PRE) IIf(nOtroDedu <> 0, cCadOrig += Alltrim(Transform(Round(nOtroDedu,2), "99999999.99")) + _aTotal[098], "")
//TotalImpuestosRetenidos
(PRE) IIf(nImpReten <> 0, cCadOrig += Alltrim(Transform(Round(nImpReten,2), "99999999.99")) + _aTotal[098], "")
//DEDUCCION
(PRE) VldCad884("2")

//OtroPago
//TipoOtroPago (SubsidioAlEmpleo - CompensacionSaldosAFavor)
(PRE) IIf(!lRegAsimil, VldCad884("3"), .T.)

//Incapacidad
(PRE) VldCad884("4")  

(PRE) cCadOrig += _aTotal[098]
(POS) _aTotal[074] := ENCODEUTF8(cCadOrig)
(POS) cCadOrig := ENCODEUTF8(cCadOrig)
//Sello
(POS) _aTotal[100] := LjHex2Asc(SHA256(cCadOrig,2))
(POS) _aTotal[100] := PrivSignRSA(&(SuperGetMv("MV_CFDDIRS",,""))+SuperGetMv("MV_CFDI_KP",,""),_aTotal[100],6,"assinatura")
(POS) _aTotal[100] := ENCODE64(_aTotal[100])

//                                          C O N F I G U R A C I O N    D E L    A R C H I V O :    R E C N O M . INI
[XXX CABECERA]
Linha1     C 041 0 Chr(239) + Chr(187) + Chr(191) + '<?xml version="1.0" encoding="UTF-8"?>'

//CFDI:  CFDI:COMPROBANTE
[XXX CFDI]

//Variable utilizada para validar si es Regimen Asimilado
(PRE) lRegAsimil := SRA->RA_TIPREG $ "05|06|07|08|09|10|11"

//Certificado
//CSD_XIA190128J61c.pem XIA190128J61 - pruebas SAT
(PRE) cCert01 := "MIIFyDCCA7CgAwIBAgIUMzAwMDEwMDAwMDA0MDAwMDI0NDMwDQYJKoZIhvcNAQEL"
(PRE) cCert01 += "BQAwggErMQ8wDQYDVQQDDAZBQyBVQVQxLjAsBgNVBAoMJVNFUlZJQ0lPIERFIEFE"
(PRE) cCert01 += "TUlOSVNUUkFDSU9OIFRSSUJVVEFSSUExGjAYBgNVBAsMEVNBVC1JRVMgQXV0aG9y"
(PRE) cCert01 += "aXR5MSgwJgYJKoZIhvcNAQkBFhlvc2Nhci5tYXJ0aW5lekBzYXQuZ29iLm14MR0w"
(PRE) cCert01 += "GwYDVQQJDBQzcmEgY2VycmFkYSBkZSBjYWRpejEOMAwGA1UEEQwFMDYzNzAxCzAJ"
(PRE) cCert01 += "BgNVBAYTAk1YMRkwFwYDVQQIDBBDSVVEQUQgREUgTUVYSUNPMREwDwYDVQQHDAhD"
(PRE) cCert01 += "T1lPQUNBTjERMA8GA1UELRMIMi41LjQuNDUxJTAjBgkqhkiG9w0BCQITFnJlc3Bv"
(PRE) cCert01 += "bnNhYmxlOiBBQ0RNQS1TQVQwHhcNMTkwNjE3MjA0MDUxWhcNMjMwNjE3MjA0MDUx"
(PRE) cCert01 += "WjCB7zEqMCgGA1UEAxMhWEVOT04gSU5EVVNUUklBTCBBUlRJQ0xFUyBTIERFIENW"
(PRE) cCert01 += "MSowKAYDVQQpEyFYRU5PTiBJTkRVU1RSSUFMIEFSVElDTEVTIFMgREUgQ1YxKjAo"
(PRE) cCert01 += "BgNVBAoTIVhFTk9OIElORFVTVFJJQUwgQVJUSUNMRVMgUyBERSBDVjElMCMGA1UE"
(PRE) cCert01 += "LRMcWElBMTkwMTI4SjYxIC8gS0FITzY0MTEwMUIzOTEeMBwGA1UEBRMVIC8gS0FI"
(PRE) cCert01 += "TzY0MTEwMUhOVExLUzA2MSIwIAYDVQQLExlYZW5vbiBJbmR1c3RyaWFsIEFydGlj"
(PRE) cCert01 += "bGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiJQ5YcSgjwsGf29+"
(PRE) cCert01 += "3go7VGdtMZCcH9wUpn46ZMAlFwUojnCPTvwJ3+cSwjqJnw8ahr3DuRwekvGR4BJA"
(PRE) cCert01 += "b5b9Xi8kyoiWtwcGOSWxO38Bp9J1e/BO9HMbQBPAtLDuG47oqnH8zWLOeaoYRJDp"
(PRE) cCert01 += "ARw4RX1ko2+9tbj0ntBtM7Vk1E8EWiA/h2Meq0LIv1+ySGTUrEW46FM01J5pzELv"
(PRE) cCert01 += "5XupBghuJxR5DG9fiOW7u3dR5s3tZoVLwA1KdjJtY0mmnfCwxg6i5AqhvY+FAI5D"
(PRE) cCert01 += "6CF6/lHA8PWg63WasvrhuIv70xCLjgPT/j00ZcPrLvBf1DefGVic980Ch/SDvC+M"
(PRE) cCert01 += "dJ1F5wIDAQABox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQEAwIGwDANBgkqhkiG"
(PRE) cCert01 += "9w0BAQsFAAOCAgEACjfTPoKY2N5MxjmAMltd5XZCV1vgAwEtrIRYTodhE8R0Tp1Q"
(PRE) cCert01 += "anAXb0luPyBv5hIXWK4VqAI4fcTtP+n7kkrwfha6ErkPWFNJWJm8ZsMmby/3WgVo"
(PRE) cCert01 += "JkOFyRYQqr5Il3N6wMa5kiDBtDRbqB3iEXmvtrvjWSHyxAER+zo3jWGFlhBZ0nQN"
(PRE) cCert01 += "Rtjx8sPFihVc5TUH682HJiU4oWvT63Dnra8ncqiW/uCuY86crnUq0fW7Lw/3+PY5"
(PRE) cCert01 += "xXjNxR/Hh3sUPITfJrGaLWurD1J9npr9yGAJ6t9zrhhZnepIC0DUMc5+j4pg1DrO"
(PRE) cCert01 += "32jzwUOLQqErDizh84NoJCWwbg+US8wi3zD0ZKiDv7XsTNWAW2Ap2JkzykKHjFTZ"
(PRE) cCert01 += "iEm3uZOkJNfcu3o+kefr5HfXFT+iN9K5FUEhaQwgUeZBRJ8V5F6gmhz3d6ixVbiZ"
(PRE) cCert01 += "oFNhYR8e2k8gF9gGrVMrEbJGQrl+6+ZYQLFiauXeG7fu1svk19PuyredRJGnseJq"
(PRE) cCert01 += "yV4RzcRGhJA+cLnmpdDOTEhignnvnhEuY6HVRYYXhOTyeeluET7KRCxbJGqO7TdW"
(PRE) cCert01 += "gjrHL3HRbNE4NY5GAdOZuLaWxElG5ZVCHqtG0Nh7UQAhcz+EKyZBAewv5XuH0Oom"
(PRE) cCert01 += "ZXw6mM2mY2soL6z1224NusM8/BbJcYTQUlAEKblEChhGK1XlxiVOU2nc9KE="

(PRE) if (SM0->M0_CODIGO == '01', cCert := cCert01,cCert := cCert01)

(PRE) _aTotal[001] := '<cfdi:Comprobante'
(PRE) _aTotal[001] += ' xmlns:cfdi="http://www.sat.gob.mx/cfd/3"'
(PRE) _aTotal[001] += ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
(PRE) _aTotal[001] += ' xmlns:nomina12="http://www.sat.gob.mx/nomina12"'
(PRE) _aTotal[001] += ' xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd http://www.sat.gob.mx/nomina12 http://www.sat.gob.mx/sitio_internet/cfd/nomina/nomina12.xsd"'
(PRE) _aTotal[001] += ' Version="3.3"'
(PRE) _aTotal[001] += ' Serie="' + _aTotal[078] + '"'
(PRE) _aTotal[001] += ' Folio="' + _aTotal[077] + '"'
(PRE) _aTotal[001] += ' Fecha="' + _aTotal[076]+ '"'  
(PRE) _aTotal[001] += ' Sello="' + Alltrim(_aTotal[100]) + '"'
(PRE) _aTotal[001] += ' FormaPago="' + CFDCarEsp("99")+ '"'
(PRE) _aTotal[001] += ' NoCertificado="' + SuperGetMv("MV_CFDI_CS",,"") + '"'   
(PRE) _aTotal[001] += ' Certificado="' + cCert + '"'
(PRE) _aTotal[001] += ' SubTotal="' + AllTrim(Transform(Round(nTotPGrav + nTotPExen + IIf(lRegAsimil, 0, nTotOtroP), 2), "99999999.99")) + '"'
(PRE) _aTotal[001] += ' Descuento="' + Alltrim(Transform(Round(nOtroDedu+nImpReten,2), "99999999.99")) + '"'
(PRE) _aTotal[001] += ' Moneda="' + Alltrim("MXN") + '"'
(PRE) _aTotal[001] += ' Total="' + AllTrim(Transform(Round(nTotPGrav + nTotPExen + IIf(lRegAsimil, 0, nTotOtroP) - (nOtroDedu + nImpReten), 2), "99999999.99")) + '"'
(PRE) _aTotal[001] += ' TipoDeComprobante="' + AllTrim("N") + '"'
(PRE) _aTotal[001] += ' MetodoPago="' + Alltrim("PUE") + '"'
(PRE) _aTotal[001] += ' LugarExpedicion="' + CFDCarEsp(AllTrim(RGC->RGC_CODPOS)) + '"'
(PRE) _aTotal[001] += '>'
(PRE) _aTotal[001] := ENCODEUTF8(_aTotal[001])
(PREREG) _aTotal[001]

//COMPROBANTE: CFDI:CfdiRelacionado
[XXX CfdiRelacionados]
(PRE) _aTotal[001] := NodoRelacc(2)
(PRE) _aTotal[001] := ENCODEUTF8(_aTotal[001])
(PREREG) _aTotal[001]

//COMPROBANTE:  CFDI:EMISOR
[XXX EMISOR]
(PRE) _aTotal[001] := '    <cfdi:Emisor'
(PRE) _aTotal[001] += ' Rfc="' + CFDCarEsp(Alltrim(SM0->M0_CGC)) + '"'
(PRE) _aTotal[001] += ' Nombre="' + _aTotal[075] + '"'
(PRE) _aTotal[001] += ' RegimenFiscal="' + cTipoReg + '"'
(PRE) _aTotal[001] += '/>'
(PRE) _aTotal[001] := ENCODEUTF8(_aTotal[001])
(PREREG) _aTotal[001]

//COMPROBANTE:  CFDI:RECEPTOR
[XXX RECEPTOR]
(PREREG) (_aTotal[001] := '    <cfdi:Receptor' , .T.)
(PREREG) (_aTotal[001] += ' Rfc="' + CFDCarEsp(AllTrim(SRA->RA_CIC)) + '"' , .T.)
(PREREG) (_aTotal[001] += ' Nombre="' + CFDCarEsp(Alltrim(SRA->RA_NOME)) + '"' , .T.)
(PREREG) (_aTotal[001] += ' UsoCFDI="' + CFDCarEsp( "P01") + '"' , .T.)
(PREREG) (_aTotal[001] += '/>' ,.T.)
(PREREG) (_aTotal[001] := ENCODEUTF8(_aTotal[001]) , .T.)
(PREREG) _aTotal[001]

//COMPROBANTE:  CFDI:COCEPTOS
[XXX CONCEPTOS]
CONCEPTOS  C 021 0 ENCODEUTF8(XMLConv("",,,"cfdi:Conceptos",.T.,.F.,4))

[XXX CONCEPTO]

//Variable utilizada para validar si es Regimen Asimilado
(PRE) lRegAsimil := SRA->RA_TIPREG $ "05|06|07|08|09|10|11"

(PREREG) (_aTotal[002] := '        <cfdi:Concepto',.T.)
(PREREG) (_aTotal[002] += ' ClaveProdServ="'+AllTrim("84111505")+'"',.T.)
(PREREG) (_aTotal[002] += ' Cantidad="' + Alltrim("1") + '"',.T.)
(PREREG) (_aTotal[002] += ' ClaveUnidad="' + Alltrim("ACT") + '"',.T.)
(PREREG) (_aTotal[002] += ' Descripcion="' + DECODEUTF8(AllTrim("Pago de nómina")) + '"',.T.)
(PREREG) (_aTotal[002] += ' ValorUnitario="' + Alltrim(Transform(Round(nTotPGrav + nTotPExen + IIf(lRegAsimil, 0, nTotOtroP),2), "99999999.99")) + '"',.T.)
(PREREG) (_aTotal[002] += ' Importe="' + Alltrim(Transform(Round(nTotPGrav + nTotPExen + IIf(lRegAsimil, 0, nTotOtroP),2), "99999999.99")) + '"',.T.)
(PREREG) (_aTotal[002] += ' Descuento="' + Alltrim(Transform(Round(nTotDGrav+nTotDExen,2), "99999999.99")) + '"',.T.)
(PREREG) (_aTotal[002] += '/>',.T.)
(PREREG) (_aTotal[078] ++,.T.)
(PREREG) ENCODEUTF8(_aTotal[002])

[XXX CONCEPTOS]
CONCEPTOS  C 021 0 ENCODEUTF8(XMLConv("",,,"cfdi:Conceptos",.F.,.T.,4))

//COMPLEMENTO:  CFDI:COMPLEMENTO
[XXX COMPLEM]
COMPLEM    C 023 0 ENCODEUTF8(XMLConv("",,,"cfdi:Complemento",.T.,.F.,4))

//COMPLEMENTO:  NOMINA:NOMINA
[XXX NOMINA]

//Variable utilizada para validar si es Regimen Asimilado
(PRE) lRegAsimil := SRA->RA_TIPREG $ "05|06|07|08|09|10|11"

(PRE) _aTotal[001] := '    <nomina12:Nomina'
(PRE) _aTotal[001] += ' Version="1.2"'
(PRE) _aTotal[001] += ' TipoNomina="' + IIf(SRY->RY_TIPO == "1" .And. !lImprIndem, "O", "E") + '"'
(PRE) _aTotal[001] += ' FechaPago="' + Alltrim(STR(YEAR(dFchPag)))+"-"+ STRZERO(MONTH(dFchPag),2) +"-"+STRZERO(DAY(dFchPag),2)+ '"'        
(PRE) _aTotal[001] += ' FechaInicialPago="' + Alltrim(STR(YEAR(dFchInPag)))+"-"+ STRZERO(MONTH(dFchInPag),2) +"-"+STRZERO(DAY(dFchInPag),2)+ '"'
(PRE) _aTotal[001] += ' FechaFinalPago="' + Alltrim(STR(YEAR(dFchFiPag)))+"-"+ STRZERO(MONTH(dFchFiPag),2) +"-"+STRZERO(DAY(dFchFiPag),2)+ '"'
(PRE) _aTotal[001] += ' NumDiasPagados="' + Alltrim(Str(IIf(nDiasPag == 0, 1, nDiasPag))) + '"'
(PRE) _aTotal[001] += IIf(nTotPGrav+nTotPExen <> 0, ' TotalPercepciones="' + Alltrim(Transform(Round(nTotPGrav+nTotPExen,2), "99999999.99")) + '"', "")
(PRE) _aTotal[001] += IIf(nTotDGrav+nTotDExen <> 0, ' TotalDeducciones="' + Alltrim(Transform(Round(nTotDGrav+nTotDExen,2), "99999999.99")) + '"', "")
(PRE) _aTotal[001] += IIf(nTotOtroP <> 0 .And. !lRegAsimil, ' TotalOtrosPagos="' + Alltrim(Transform(Round(nTotOtroP,2), "99999999.99")) + '" ', "")
(PRE) _aTotal[001] += '>'
(PRE) _aTotal[001] := ENCODEUTF8(_aTotal[001])
(PREREG) _aTotal[001]

[XXX EMISOR]

//Variable utilizada para validar si es Regimen Asimilado
(PRE) lRegAsimil := SRA->RA_TIPREG $ "05|06|07|08|09|10|11"

(PREREG) (NodOpcion(6),.T.)
(PRE) _aTotal[001] := '        <nomina12:Emisor'
(PRE) _aTotal[001] += IIf(SRA->RA_CATFUNC <> 'A' .And. !lRegAsimil .And. !lImprIndem, ' RegistroPatronal="' + Alltrim(cRegPatr) +'"', "")
(PRE) _aTotal[001] += ' RfcPatronOrigen="' + CFDCarEsp(Alltrim(SM0->M0_CGC)) +  '"'
(PREREG) (_aTotal[001] += IIf(Alltrim(cOrigRecur) == "", '/>', '>'),.T.)
(PREREG) (_aTotal[001] += IIf(Alltrim(cOrigRecur) == "", "", cCRLF + cNodoSNCF),.T.)
(PREREG) ENCODEUTF8(_aTotal[001])
(PREREG) ( Iif ((cOrigRecur <> ""),.T.,.F.))
EMISOR     C 026 0 ENCODEUTF8(XMLConv("",,,"nomina12:Emisor",.F.,.T.,8))

//COMPROBANTE:  CFDI:RECEPTOR
[XXX RECEPTOR]

//Variable utilizada para validar si es Regimen Asimilado
(PRE) lRegAsimil := SRA->RA_TIPREG $ "05|06|07|08|09|10|11"

(PREREG) (NodOpcion(5),.T.)
(PRE) _aTotal[001] := '        <nomina12:Receptor'
(PRE) _aTotal[001] += ' Curp="' + Alltrim(SRA->RA_CURP) + '"'
(PRE) _aTotal[001] += IIf(SRA->RA_CATFUNC <> 'A' .And. !lRegAsimil .And. !lImprIndem, ' NumSeguridadSocial="' + AllTrim(SRA->RA_RG) +'"', "")
(PRE) _aTotal[001] += IIf(SRA->RA_CATFUNC <> 'A' .And. !lRegAsimil .And. !lImprIndem, ' FechaInicioRelLaboral="' + AllTrim(Str(Year(dFchInLab))) + "-" + StrZero(Month(dFchInLab),2) + "-" + StrZero(Day(dFchInLab),2) + '"', "")
(PRE) _aTotal[001] += IIf(SRA->RA_CATFUNC <> 'A' .And. !lRegAsimil .And. !lImprIndem, DecodeUTF8(' Antigüedad="') + 'P' + AllTrim(Str(nAntigue)) + 'W' + '" ', "")
(PRE) _aTotal[001] += ' TipoContrato="' + Iif(lImprIndem,"99",Alltrim(SRA->RA_TIPCON)) + '"'
(PRE) _aTotal[001] += IIf(SRA->RA_CATFUNC <> 'A', ' Sindicalizado="' + IIf(!Empty(SRA->RA_SINDICA) .And. !lRegAsimil, "S�", "No") + '"', "")
(PRE) _aTotal[001] += IIf(SRA->RA_CATFUNC <> 'A' .And. !lRegAsimil, ' TipoJornada="' + AllTrim(cTipJorn) + '"', "")
(PRE) _aTotal[001] += ' TipoRegimen="' + Iif(lImprIndem,"13",Alltrim(SRA->RA_TIPREG)) + '"'
(PRE) _aTotal[001] += ' NumEmpleado="' + Alltrim(SRA->RA_MAT) +'"'
(PRE) _aTotal[001] += ' Departamento="' + Alltrim(cDeptoIm) + '"'
(PRE) _aTotal[001] += ' Puesto="' + Alltrim(cPuesCfdi) + '"'
(PRE) IIf(!lRegAsimil .AND. !lImprIndem, _aTotal[001] += IIf(SRA->RA_CATFUNC <> 'A', ' RiesgoPuesto="' + AllTrim(cRiegCFDi) + '"', ' RiesgoPuesto="' + AllTrim("99") + '"'), .T.)
(PRE) _aTotal[001] += ' PeriodicidadPago="' + CFDCarEsp(Alltrim(IIf(SRY->RY_TIPO == "1",cPerCFDi, "99"))) + '"'
(PRE) IIf(!Empty(SRA->RA_CLABE), ,_aTotal[001] += ' Banco="' + Alltrim(cBcoCfdi) + '"')
(PRE) _aTotal[001] += ' CuentaBancaria="' + IIf(!Empty(SRA->RA_CLABE), Alltrim(SRA->RA_CLABE), Alltrim(SRA->RA_CTDEPSA)) + '"'
(PRE) _aTotal[001] += IIf(SRA->RA_CATFUNC <> 'A', ' SalarioBaseCotApor="' + Alltrim(Transform(Round(nSalBasAp,2), "99999999.99")) + '"', "")
(PRE) _aTotal[001] += IIf(SRA->RA_CATFUNC <> 'A' .And. !lRegAsimil .And. !lImprIndem, ' SalarioDiarioIntegrado="' + Alltrim(Transform(Round(SRA->RA_SALINT,2), "99999999.99")) + '"', "")
(PRE) _aTotal[001] += ' ClaveEntFed="' + Alltrim(cEntFed) + '"'
(PREREG) (_aTotal[001] += IIf(cNodoSubC <> "", '>', '/>'),.T.)
(PREREG) (_aTotal[001] += IIf(cNodoSubC == "", "", cCRLF + cNodoSubC),.T.)
(PREREG) ENCODEUTF8(_aTotal[001])
(PREREG) ( Iif ((cNodoSubC <> ""),.T.,.F.))
RECEPTOR   C 028 0 ENCODEUTF8(XMLConv("",,,"nomina12:Receptor",.F.,.T.,8))

//COMPLEMENTO:  NOMINA:PERCEPCIONES
[XXX PERCEPCION]    
(PRE) DBSELECTAREA("SRVPD")
(PRE) SRVPD->(DbGotop())
(PREREG) ( Iif ((Alltrim(SRVPD->RV_TIPO) =="1"),.T.,.F.))
(PRE) _aTotal[002] := '        <nomina12:Percepciones'
(PRE) _aTotal[002] += IIf(nTotSueld<>0, ' TotalSueldos="' + Alltrim(Transform(Round(nTotSueld,2), "99999999.99")) + '"', "")
(PRE) _aTotal[002] += IIf(nTotIndem<>0, ' TotalSeparacionIndemnizacion="' + Alltrim(Transform(Round(nTotIndem,2), "99999999.99")) + '"', "")
(PRE) _aTotal[002] += IIf(nTotJubil<>0, ' TotalJubilacionPensionRetiro="' + Alltrim(Transform(Round(nTotJubil,2), "99999999.99")) + '"', "")
(PRE) _aTotal[002] += ' TotalGravado="' + Alltrim(Transform(Round(nTotPGrav,2), "99999999.99")) + '"'
(PRE) _aTotal[002] += ' TotalExento="' + Alltrim(Transform(Round(nTotPExen,2), "99999999.99")) + '"'
(PRE) _aTotal[002] += '>'
(PRE) _aTotal[002] := ENCODEUTF8(_aTotal[002])
(PREREG) _aTotal[002]

[SRVPD PERCEPCION]
(PRE) SRVPD->(DbGotop())
(PREREG) ( Iif ((Alltrim(SRVPD->RV_TIPO) =="1"),.T.,.F.))
(PREREG) NodOpcion(1)
(PREREG) NodOpcion(2)
(PREREG) (_aTotal[002] := '            <nomina12:Percepcion',.T.)
(PREREG) (_aTotal[002] += ' TipoPercepcion="' + Alltrim(Substr(SRVPD->RV_TIPSAT,1,3)) + '"',.T.)
(PREREG) (_aTotal[002] += ' Clave="' + Alltrim(SRVPD->RV_COD) + '"',.T.)
(PREREG) (_aTotal[002] += ' Concepto="' + Alltrim(SRVPD->RV_DESCDET) + '"',.T.)
(PREREG) (_aTotal[002] += ' ImporteGravado="' + Alltrim(Transform(Round(SRVPD->RC_VALORGV,2), "99999999.99")) + '"',.T.)
(PREREG) (_aTotal[002] += ' ImporteExento="' + Alltrim(Transform(Round(SRVPD->RC_VALOREX,2), "99999999.99")) + '"',.T.)
(PREREG) (_aTotal[002] += IIf(cNodoAccT <> "" .Or. cNodoHExt <> "", '>', '/>'),.T.)
(PREREG) (_aTotal[002] += IIf(cNodoAccT == "", "", cCRLF + cNodoAccT),.T.)
(PREREG) (_aTotal[002] += IIf(cNodoHExt == "", "", cCRLF + cNodoHExt),.T.)
(PREREG) ENCODEUTF8(_aTotal[002])
(PREREG) ( Iif ((cNodoAccT <> "" .Or. cNodoHExt <> ""),.T.,.F.))
PERCEPCION C 036 0 ENCODEUTF8(XMLConv("",,,"nomina12:Percepcion",.F.,.T.,12))

[SRVPD JUBILACION]
(PREREG) Iif((nTotUnaEx+nTotParci+nTotDiari+nTotIAcum+NTotNAcum<>0),.T.,.F. )
(PRE) _aTotal[002] := '                <nomina12:JubilacionPensionRetiro'
(PRE) _aTotal[002] += IIf(nTotUnaEx <> 0, ' TotalUnaExhibicion="' + Alltrim(Transform(Round(nTotUnaEx,2), "99999999.99")) + '"', "")
(PRE) _aTotal[002] += IIf(nTotParci <> 0, ' TotalParcialidad="' + Alltrim(Transform(Round(nTotParci,2), "99999999.99")) + '"', "")
(PRE) _aTotal[002] += IIf(nTotParci <> 0, ' MontoDiario="' + Alltrim(Transform(Round(nTotDiari,2), "99999999.99")) + '"', "")
(PRE) _aTotal[002] += IIf(nTotUnaEx+nTotParci <> 0, ' IngresoAcumulable="' + Alltrim(Transform(Round(nTotIAcum,2), "99999999.99")) + '"', "")
(PRE) _aTotal[002] += IIf(nTotUnaEx+nTotParci <> 0, ' IngresoNoAcumulable="' + Alltrim(Transform(Round(NTotNAcum,2), "99999999.99")) + '"', "")
(PRE) _aTotal[002] += '/>'
(PREREG) ENCODEUTF8(_aTotal[002])
(PREREG) VldNodJub()

[SRVPD INDEMNIZACION]
(PREREG) Iif((nTotPagad+nNumAnios+nUltSuelM+nIngrAcum+nIngrNAcu<>0),.T.,.F. )
(PRE) _aTotal[002] := '                <nomina12:SeparacionIndemnizacion'
(PRE) _aTotal[002] += ' TotalPagado="' + Alltrim(Transform(Round(nTotPagad,2), "99999999.99")) + '"'
(PRE) _aTotal[002] += ' NumAñosServicio="' + Alltrim(Str(IIf(nNumAnios==0, 1, nNumAnios))) + '"'
(PRE) _aTotal[002] += ' UltimoSueldoMensOrd="' + Alltrim(Transform(Round(nUltSuelM,2), "99999999.99")) + '"'
(PRE) _aTotal[002] += ' IngresoAcumulable="' + Alltrim(Transform(Round(nIngrAcum,2), "99999999.99")) + '"'
(PRE) _aTotal[002] += ' IngresoNoAcumulable="' + Alltrim(Transform(Round(nIngrNAcu,2), "99999999.99")) + '"'
(PRE) _aTotal[002] += '/>'
(PREREG) ENCODEUTF8(_aTotal[002])
(PREREG) VldNodInde()

[XXX PERCEPCION] 
(PRE) SRVPD->(DbGotop())
(PREREG) ( Iif ((Alltrim(SRVPD->RV_TIPO) =="1"),.T.,.F.))
PERCEPCION C 032 0 ENCODEUTF8(XMLConv("",,,"nomina12:Percepciones",.F.,.T.,8))

//COMPLEMENTO:  NOMINA:DEDUCCIONES
[XXX DEDUCCIONS]
(PRE) DBSELECTAREA("SRVPD")
(PRE) SRVPD->(DbGotop()) 
(PRE) DbSeek(_aTotal[072]+_aTotal[073]+"2") 
(PREREG) ( Iif ((Alltrim(SRVPD->RV_TIPO) =="2"),.T.,.F.))
(PRE) _aTotal[002] := '        <nomina12:Deducciones'
(PRE) _aTotal[002] += IIf(nOtroDedu <> 0, ' TotalOtrasDeducciones="' + Alltrim(Transform(Round(nOtroDedu,2), "99999999.99")) + '"', "")
(PRE) _aTotal[002] += IIf(nImpReten <> 0, ' TotalImpuestosRetenidos="' + Alltrim(Transform(Round(nImpReten,2), "99999999.99")) + '" ', "")
(PRE) _aTotal[002] += '>'
(PREREG) ENCODEUTF8(_aTotal[002])

[SRVPD DEDUCCION]  
(PREREG) ( Iif ((Alltrim(SRVPD->RV_TIPO) =="2"),.T.,.F.))
(PREREG) (_aTotal[002] := '            <nomina12:Deduccion',.T.)
(PREREG) (_aTotal[002] += ' TipoDeduccion="' + Alltrim(Substr(SRVPD->RV_TIPSAT,1,3)) + '"',.T.)
(PREREG) (_aTotal[002] += ' Clave="' + Alltrim(SRVPD->RV_COD) + '"',.T.)
(PREREG) (_aTotal[002] += ' Concepto="' + Alltrim(SRVPD->RV_DESCDET) + '"',.T.)
(PREREG) (_aTotal[002] += ' Importe="' + Alltrim(Transform(Round(SRVPD->RC_VALORGV + SRVPD->RC_VALOREX,2), "99999999.99")) + '"',.T.)
(PREREG) (_aTotal[002] += '/>',.T.)
(PREREG) ENCODEUTF8(_aTotal[002]) 

[XXX DEDUCCIONS] 
(PRE) DBSELECTAREA("SRVPD")
(PRE) SRVPD->(DbGotop()) 
(PRE) DbSeek(_aTotal[072]+_aTotal[073]+"2")  
(PREREG) ( Iif ((Alltrim(SRVPD->RV_TIPO) =="2"),.T.,.F.))
DEDUCCIONS C 032 0 ENCODEUTF8(XMLConv("",,,"nomina12:Deducciones",.F.,.T.,8))

//COMPLEMENTO:  NOMINA:OTROSPAGOS
[XXX OTROSPAGOS]

//Variable utilizada para validar si es Regimen Asimilado
(PRE) lRegAsimil := SRA->RA_TIPREG $ "05|06|07|08|09|10|11"

(PREREG) !lRegAsimil
(PREREG) _aTotal[002] := ''
(PREREG) _aTotal[002] := fOtrosPag()
(PREREG) ENCODEUTF8(_aTotal[002])

[XXX INCAPACIDS] 
(PRE) SRCIN->(DbGotop()) 
(PREREG) Iif(!SRCIN->(Eof()),.T.,.F. )
(PRE) _aTotal[001] := '        <nomina12:Incapacidades>'
(PREREG) ENCODEUTF8(_aTotal[001])

//COMPLEMENTO:  NOMINA:INCAPACIDAD
[SRCIN INCAPACIDAD]
(PRE) SRCIN->(DbGotop())
(PREREG) (_aTotal[002] := '            <nomina12:Incapacidad',.T.)
(PREREG) (_aTotal[002] += ' DiasIncapacidad="' + Alltrim(Str(SRCIN->RC_HORAS)) + '"',.T.)
(PREREG) (_aTotal[002] += ' TipoIncapacidad="' + Alltrim(SRCIN->RCM_TIPSAT) + '"',.T.)
(PREREG) (_aTotal[002] += ' ImporteMonetario="' + Alltrim(Transform(Round(SRCIN->RC_VALOR,2), "99999999.99")) + '"',.T.)
(PREREG) (_aTotal[002] += '/>',.T.)
(PREREG) ENCODEUTF8(_aTotal[002])

[XXX INCAPACIDAD]  
(PRE) SRCIN->(DbGotop()) 
(PREREG) Iif(!SRCIN->(Eof()),.T.,.F. )
INCAPACIDAD C 030 0 ENCODEUTF8(XMLConv("",,,"nomina12:Incapacidad",.F.,.T.,8))

[XXX INCAPACIDS] 
(PRE) SRCIN->(DbGotop()) 
(PREREG) Iif(!SRCIN->(Eof()),.T.,.F. )
INCAPACIDS C 033 0 ENCODEUTF8(XMLConv("",,,"nomina12:Incapacidades",.F.,.T.,8))

[XXX NOMINA]  
NOMINA     C 023 0 ENCODEUTF8(XMLConv("",,,"nomina12:Nomina",.F.,.T.,4))

//COMPLEMENTO:  CFDI:COMPLEMENTO
[XXX COMPLEM]  
COMPLEM    C 023 0 ENCODEUTF8(XMLConv("",,,"cfdi:Complemento",.F.,.T.,4))  

[XXX ADDENDA]
ADDENDA    C 019 0 ENCODEUTF8(XMLConv("",,,"cfdi:Addenda",.T.,.F.,4))

[XXX ADDENDA1]
(PREREG) (_aTotal[003] := '        <cfdi:t_obs',.T.)
(PREREG) (_aTotal[003] += ' CadenaOrig="' + Alltrim(_aTotal[074]) + '"',.T.)
(PREREG) (_aTotal[003] += ' Sucursal="' + SRA->RA_FILIAL + '"',.T.)
(PREREG) (_aTotal[003] += '/>',.T.)
(PREREG) _aTotal[003]
(POS) DelATbr884()

[XXX ADDENDA]
ADDENDA    C 019 0 ENCODEUTF8(XMLConv("",,,"cfdi:Addenda",.F.,.T.,4))

[XXX CFDI]
CFDI       C 019 0 ENCODEUTF8(XMLConv("",,,"cfdi:Comprobante",.F.,.T.,0))

06. Tablas Utilizadas

7. Información Adicional

http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/Guia_llenado_Nomina.pdf 

Aplicable para la versión 4.0 del CFDI y el complemento de nómina versión 1.2

http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/29122021_Matriz_ErroresNomina_v12_RevC.xls 

DT Recibo de Nómina CFDi 3.3 - México

13481039 DNOMI-47 DT Cancelación CFDI de Nómina con Motivos de Cancelación MEX

DT Cancelación y Timbrado de Complemento de Nómina con Motivos de Cancelación MEX