Ejemplo Complemento de Pagos en CFDI 4.0

This commit is contained in:
el Mau 2022-09-12 19:26:23 -05:00
parent 5f91511266
commit 1972723d9e
2 changed files with 106 additions and 34 deletions

View File

@ -5,15 +5,20 @@
"TipoDeComprobante": "P",
"LugarExpedicion": "06850",
"SubTotal": "0",
"Total": "0"
"Total": "0",
"Exportacion": "01"
},
"emisor": {
"Rfc": "LAN7008173R5",
"Rfc": "EKU9003173C9",
"Nombre": "ESCUELA KEMPER URGATE",
"RegimenFiscal": "601"
},
"receptor": {
"Rfc": "BASM740115RW0",
"UsoCFDI": "P01"
"Nombre": "MAURICIO BAEZA SERVIN",
"DomicilioFiscalReceptor": "06850",
"RegimenFiscalReceptor": "612" ,
"UsoCFDI": "CP01"
},
"conceptos": [
{
@ -22,26 +27,58 @@
"ClaveUnidad": "ACT",
"Descripcion": "Pago",
"ValorUnitario": "0",
"Importe": "0"
"Importe": "0",
"ObjetoImp": "01"
}
],
"pagos": [
{
"FechaPago": "2020-08-07T12:00:00",
"FormaDePagoP": "03",
"MonedaP": "MXN",
"Monto": "6073.60",
"documentos": [
{
"IdDocumento": "5243138D-EE4B-4B1B-A648-320DCC4E3BD2",
"ImpPagado": "6073.60",
"ImpSaldoAnt": "6073.60",
"ImpSaldoInsoluto": "0.00",
"MetodoDePagoDR": "PPD",
"MonedaDR": "MXN",
"NumParcialidad": "1"
"pagos": {
"totales": {
"TotalTrasladosBaseIVA16": "1000.00",
"TotalTrasladosImpuestoIVA16": "160.00",
"MontoTotalPagos": "1160.00"
},
"pagos": [
{
"FechaPago": "2020-08-07T12:00:00",
"FormaDePagoP": "03",
"MonedaP": "MXN",
"TipoCambioP": "1",
"Monto": "1160.00",
"documentos": [
{
"IdDocumento": "5243138D-EE4B-4B1B-A648-320DCC4E3BD2",
"ImpPagado": "1160.00",
"ImpSaldoAnt": "1160.00",
"ImpSaldoInsoluto": "0.00",
"MonedaDR": "MXN",
"EquivalenciaDR": "1",
"NumParcialidad": "1",
"ObjetoImpDR": "02",
"impuestos": {
"traslados": [
{
"BaseDR": "1000.00",
"ImpuestoDR": "002",
"TipoFactorDR": "Tasa",
"TasaOCuotaDR": "0.160000",
"ImporteDR": "160.00"
}
]
}
}
],
"impuestos": {
"traslados": [
{
"BaseP": "1000.00",
"ImpuestoP": "002",
"TipoFactorP": "Tasa",
"TasaOCuotaP": "0.160000",
"ImporteP": "160.00"
}
]
}
]
}
]
}
]
}
}

View File

@ -26,7 +26,7 @@ log = logging.getLogger(__name__)
PACs = {
# ~ 'finkok': PACFinkok,
'finkok': PACFinkok,
'comercio': PACComercioDigital,
}
NS_CFDI = {
@ -56,12 +56,12 @@ class CFDI(object):
_prefix = 'cfdi'
_xmlns = 'http://www.sat.gob.mx/cfd/4'
schema = f'{_xmlns} http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd'
_pagos = 'http://www.sat.gob.mx/Pagos'
_pagos = 'http://www.sat.gob.mx/Pagos20'
PAGOS = {
'version': '1.0',
'version': '2.0',
'prefix': _pagos,
'ns': {'pago10': _pagos},
'schema': f' {_pagos} http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos10.xsd',
'ns': {'pago20': _pagos},
'schema': f' {_pagos} http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos20.xsd',
}
_nomina = 'http://www.sat.gob.mx/nomina12'
NOMINA = {
@ -237,16 +237,51 @@ class CFDI(object):
return
def _pagos(self, complemento, data):
node_name = f"{{{self.PAGOS['prefix']}}}Pagos"
pre = self.PAGOS['prefix']
totales = data['totales']
pagos = data['pagos']
node_name = f"{{{pre}}}Pagos"
attr = {'Version': self.PAGOS['version']}
node_pagos = ET.SubElement(complemento, node_name, attr)
for pago in data:
documentos = pago.pop('documentos')
node_name = f"{{{self.PAGOS['prefix']}}}Pago"
node_name = f"{{{pre}}}Totales"
ET.SubElement(node_pagos, node_name, totales)
for pago in pagos:
documents = pago.pop('documentos')
taxes_pago = pago.pop('impuestos')
node_name = f"{{{pre}}}Pago"
node_pago = ET.SubElement(node_pagos, node_name, pago)
node_name = f"{{{self.PAGOS['prefix']}}}DoctoRelacionado"
for doc in documentos:
ET.SubElement(node_pago, node_name, doc)
node_name = f"{{{pre}}}DoctoRelacionado"
for doc in documents:
taxes = doc.pop('impuestos', {})
traslados = taxes.get('traslados', [])
retenciones = taxes.get('retenciones', [])
node_doc = ET.SubElement(node_pago, node_name, doc)
if traslados or retenciones:
node_name = f"{{{pre}}}ImpuestosDR"
node_taxes = ET.SubElement(node_doc, node_name)
if traslados:
node_name = f"{{{pre}}}TrasladosDR"
node_tax = ET.SubElement(node_taxes, node_name)
for traslado in traslados:
node_name = f"{{{pre}}}TrasladoDR"
ET.SubElement(node_tax, node_name, traslado)
traslados = taxes_pago.get('traslados', [])
retenciones = taxes_pago.get('retenciones', [])
if traslados or retenciones:
node_name = f"{{{pre}}}ImpuestosP"
node_taxes = ET.SubElement(node_pago, node_name)
if traslados:
node_name = f"{{{pre}}}TrasladosP"
node_tax = ET.SubElement(node_taxes, node_name)
for traslado in traslados:
node_name = f"{{{pre}}}TrasladoP"
ET.SubElement(node_tax, node_name, traslado)
return
def _nomina(self, complemento, data):