Timbrado de Complemento de Pagos 2.0
This commit is contained in:
parent
acdb8f291e
commit
482e016fcd
|
@ -91,10 +91,10 @@ SAT = {
|
||||||
'schema': ' http://www.sat.gob.mx/iedu http://www.sat.gob.mx/sitio_internet/cfd/iedu/iedu.xsd',
|
'schema': ' http://www.sat.gob.mx/iedu http://www.sat.gob.mx/sitio_internet/cfd/iedu/iedu.xsd',
|
||||||
},
|
},
|
||||||
'pagos': {
|
'pagos': {
|
||||||
'version': '1.0',
|
'version': '2.0',
|
||||||
'prefix': 'pago10',
|
'prefix': 'pago20',
|
||||||
'xmlns': 'http://www.sat.gob.mx/Pagos',
|
'xmlns': 'http://www.sat.gob.mx/Pagos20',
|
||||||
'schema': ' http://www.sat.gob.mx/Pagos http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos10.xsd',
|
'schema': ' http://www.sat.gob.mx/Pagos20 http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos20.xsd',
|
||||||
},
|
},
|
||||||
'divisas': {
|
'divisas': {
|
||||||
'version': '1.0',
|
'version': '1.0',
|
||||||
|
@ -554,14 +554,41 @@ class CFDI(object):
|
||||||
|
|
||||||
if 'pagos' in datos:
|
if 'pagos' in datos:
|
||||||
datos = datos.pop('pagos')
|
datos = datos.pop('pagos')
|
||||||
|
totales = datos.pop('totales')
|
||||||
relacionados = datos.pop('relacionados')
|
relacionados = datos.pop('relacionados')
|
||||||
|
taxes_pay = datos.pop('taxes_pay')
|
||||||
pre = SAT['pagos']['prefix']
|
pre = SAT['pagos']['prefix']
|
||||||
|
|
||||||
attributes = {'Version': SAT['pagos']['version']}
|
attributes = {'Version': SAT['pagos']['version']}
|
||||||
pagos = ET.SubElement(
|
pagos = ET.SubElement(
|
||||||
self._complemento, '{}:Pagos'.format(pre), attributes)
|
self._complemento, '{}:Pagos'.format(pre), attributes)
|
||||||
|
|
||||||
|
ET.SubElement(pagos, '{}:Totales'.format(pre), totales)
|
||||||
|
|
||||||
node_pago = ET.SubElement(pagos, '{}:Pago'.format(pre), datos)
|
node_pago = ET.SubElement(pagos, '{}:Pago'.format(pre), datos)
|
||||||
for row in relacionados:
|
for row in relacionados:
|
||||||
ET.SubElement(node_pago, '{}:DoctoRelacionado'.format(pre), row)
|
taxes = row.pop('taxes')
|
||||||
|
node = ET.SubElement(node_pago, f'{pre}:DoctoRelacionado', row)
|
||||||
|
node_tax = ET.SubElement(node, f'{pre}:ImpuestosDR')
|
||||||
|
if taxes['retenciones']:
|
||||||
|
node = ET.SubElement(node_tax, f'{pre}:RetencionsDR')
|
||||||
|
for tax in taxes['retenciones']:
|
||||||
|
ET.SubElement(node, f'{pre}:RetencionDR', tax)
|
||||||
|
if taxes['traslados']:
|
||||||
|
node = ET.SubElement(node_tax, f'{pre}:TrasladosDR')
|
||||||
|
for tax in taxes['traslados']:
|
||||||
|
ET.SubElement(node, f'{pre}:TrasladoDR', tax)
|
||||||
|
|
||||||
|
node_tax = ET.SubElement(node_pago, f'{pre}:ImpuestosP')
|
||||||
|
if taxes_pay['retenciones']:
|
||||||
|
node = ET.SubElement(node_tax, f'{pre}:RetencionsP')
|
||||||
|
for key, importe in taxes_pay['retenciones'].items():
|
||||||
|
attr = {'ImpuestoP': key, 'ImporteP': importe}
|
||||||
|
ET.SubElement(node, f'{pre}:RetencionP', attr)
|
||||||
|
if taxes_pay['traslados']:
|
||||||
|
node = ET.SubElement(node_tax, f'{pre}:TrasladosP')
|
||||||
|
for key, tax in taxes_pay['traslados'].items():
|
||||||
|
ET.SubElement(node, f'{pre}:TrasladoP', tax)
|
||||||
|
|
||||||
if 'leyendas' in datos:
|
if 'leyendas' in datos:
|
||||||
pre = SAT['leyendas']['prefix']
|
pre = SAT['leyendas']['prefix']
|
||||||
|
|
|
@ -2760,6 +2760,7 @@ class Socios(BaseModel):
|
||||||
uso_cfdi = ForeignKeyField(SATUsoCfdi, null=True)
|
uso_cfdi = ForeignKeyField(SATUsoCfdi, null=True)
|
||||||
tags = ManyToManyField(Tags, related_name='socios_tags')
|
tags = ManyToManyField(Tags, related_name='socios_tags')
|
||||||
plantilla = TextField(default='')
|
plantilla = TextField(default='')
|
||||||
|
regimen_fiscal = TextField(default='')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
t = '{} ({})'
|
t = '{} ({})'
|
||||||
|
@ -7223,6 +7224,7 @@ class CfdiPagos(BaseModel):
|
||||||
error = TextField(default='')
|
error = TextField(default='')
|
||||||
cancelada = BooleanField(default=False)
|
cancelada = BooleanField(default=False)
|
||||||
fecha_cancelacion = DateTimeField(null=True)
|
fecha_cancelacion = DateTimeField(null=True)
|
||||||
|
receptor_regimen = TextField(default='')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
order_by = ('movimiento',)
|
order_by = ('movimiento',)
|
||||||
|
@ -7346,6 +7348,7 @@ class CfdiPagos(BaseModel):
|
||||||
|
|
||||||
partner = related[0].factura.cliente
|
partner = related[0].factura.cliente
|
||||||
partner_name = related[0].factura.cliente.nombre
|
partner_name = related[0].factura.cliente.nombre
|
||||||
|
receptor_regimen = related[0].factura.receptor_regimen
|
||||||
|
|
||||||
emisor = Emisor.select()[0]
|
emisor = Emisor.select()[0]
|
||||||
# ~ regimen_fiscal = related[0].factura.regimen_fiscal
|
# ~ regimen_fiscal = related[0].factura.regimen_fiscal
|
||||||
|
@ -7385,6 +7388,7 @@ class CfdiPagos(BaseModel):
|
||||||
fields['folio'] = self._get_folio(self, serie)
|
fields['folio'] = self._get_folio(self, serie)
|
||||||
fields['lugar_expedicion'] = emisor.cp_expedicion or emisor.codigo_postal
|
fields['lugar_expedicion'] = emisor.cp_expedicion or emisor.codigo_postal
|
||||||
fields['regimen_fiscal'] = regimen_fiscal
|
fields['regimen_fiscal'] = regimen_fiscal
|
||||||
|
fields['receptor_regimen'] = receptor_regimen
|
||||||
|
|
||||||
with database_proxy.atomic() as txn:
|
with database_proxy.atomic() as txn:
|
||||||
obj = CfdiPagos.create(**fields)
|
obj = CfdiPagos.create(**fields)
|
||||||
|
@ -7402,7 +7406,85 @@ class CfdiPagos(BaseModel):
|
||||||
data = {'ok': True, 'row': row, 'new': True}
|
data = {'ok': True, 'row': row, 'new': True}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def _get_taxes_by_pay(self, pay, taxes_pay):
|
||||||
|
# ~ print(pay['ImpPagado']
|
||||||
|
invoice = Facturas.get(Facturas.uuid==pay['IdDocumento'])
|
||||||
|
impuestos = {}
|
||||||
|
traslados = []
|
||||||
|
retenciones = []
|
||||||
|
|
||||||
|
where = (FacturasImpuestos.factura==invoice)
|
||||||
|
taxes = FacturasImpuestos.select().where(where)
|
||||||
|
|
||||||
|
for tax in taxes:
|
||||||
|
if tax.impuesto.key == '000':
|
||||||
|
# ~ tasa = str(round(tax.impuesto.tasa * 100, 2))
|
||||||
|
# ~ simporte = FORMAT.format(tax.importe)
|
||||||
|
# ~ if tax.impuesto.tipo == 'T':
|
||||||
|
# ~ traslado = {
|
||||||
|
# ~ 'ImpLocTrasladado': tax.impuesto.name,
|
||||||
|
# ~ 'TasadeTraslado': tasa,
|
||||||
|
# ~ 'Importe': simporte,
|
||||||
|
# ~ }
|
||||||
|
# ~ locales_trasladados.append(traslado)
|
||||||
|
# ~ total_locales_trasladados += tax.importe
|
||||||
|
# ~ else:
|
||||||
|
# ~ retencion = {
|
||||||
|
# ~ 'ImpLocRetenido': tax.impuesto.name,
|
||||||
|
# ~ 'TasadeRetencion': tasa,
|
||||||
|
# ~ 'Importe': simporte,
|
||||||
|
# ~ }
|
||||||
|
# ~ locales_retenciones.append(retencion)
|
||||||
|
# ~ total_locales_retenciones += tax.importe
|
||||||
|
continue
|
||||||
|
|
||||||
|
tipo_factor = 'Tasa'
|
||||||
|
if tax.impuesto.factor != 'T':
|
||||||
|
tipo_factor = 'Cuota'
|
||||||
|
|
||||||
|
# ~ if tax_decimals:
|
||||||
|
# ~ xml_importe = FORMAT_TAX.format(tax.importe)
|
||||||
|
# ~ xml_tax_base = FORMAT_TAX.format(tax.base)
|
||||||
|
# ~ else:
|
||||||
|
xml_importe = FORMAT.format(tax.importe)
|
||||||
|
xml_tax_base = FORMAT.format(tax.base)
|
||||||
|
|
||||||
|
values = {
|
||||||
|
"BaseDR": xml_tax_base,
|
||||||
|
"ImpuestoDR": tax.impuesto.key,
|
||||||
|
"TipoFactorDR": tipo_factor,
|
||||||
|
"TasaOCuotaDR": str(tax.impuesto.tasa),
|
||||||
|
"ImporteDR": xml_importe,
|
||||||
|
}
|
||||||
|
tax_key = tax.impuesto.key
|
||||||
|
if tax.impuesto.tipo == 'T':
|
||||||
|
traslados.append(values)
|
||||||
|
if tax_key in taxes_pay['traslados']:
|
||||||
|
taxes_pay['traslados'][tax_key]['ImporteP'] += tax.importe
|
||||||
|
else:
|
||||||
|
values = {
|
||||||
|
"BaseP": tax.base,
|
||||||
|
"ImpuestoP": tax.impuesto.key,
|
||||||
|
"TipoFactorP": tipo_factor,
|
||||||
|
"TasaOCuotaP": str(tax.impuesto.tasa),
|
||||||
|
"ImporteP": tax.importe,
|
||||||
|
}
|
||||||
|
taxes_pay['traslados'][tax_key] = values
|
||||||
|
else:
|
||||||
|
retenciones.append(values)
|
||||||
|
if tax_key in taxes_pay['retenciones']:
|
||||||
|
taxes_pay['retenciones'][tax_key] += tax.importe
|
||||||
|
else:
|
||||||
|
taxes_pay['retenciones'][tax_key] = tax.importe
|
||||||
|
|
||||||
|
impuestos['traslados'] = traslados
|
||||||
|
impuestos['retenciones'] = retenciones
|
||||||
|
|
||||||
|
return impuestos
|
||||||
|
|
||||||
def _get_related_xml(self, id_mov, currency):
|
def _get_related_xml(self, id_mov, currency):
|
||||||
|
TAX_IVA_16 = '002|0.160000'
|
||||||
|
|
||||||
filters = (FacturasPagos.movimiento==id_mov)
|
filters = (FacturasPagos.movimiento==id_mov)
|
||||||
related = tuple(FacturasPagos.select(
|
related = tuple(FacturasPagos.select(
|
||||||
Facturas.uuid.alias('IdDocumento'),
|
Facturas.uuid.alias('IdDocumento'),
|
||||||
|
@ -7419,13 +7501,21 @@ class CfdiPagos(BaseModel):
|
||||||
.where(filters)
|
.where(filters)
|
||||||
.dicts())
|
.dicts())
|
||||||
|
|
||||||
|
taxes_pay = {'retenciones': {}, 'traslados': {}, 'totales': {}}
|
||||||
|
|
||||||
for r in related:
|
for r in related:
|
||||||
|
r['taxes'] = self._get_taxes_by_pay(self, r, taxes_pay)
|
||||||
# ~ print('\n\nMONEDA', currency, r['MonedaDR'])
|
# ~ print('\n\nMONEDA', currency, r['MonedaDR'])
|
||||||
r['IdDocumento'] = str(r['IdDocumento'])
|
r['IdDocumento'] = str(r['IdDocumento'])
|
||||||
r['Folio'] = str(r['Folio'])
|
r['Folio'] = str(r['Folio'])
|
||||||
r['NumParcialidad'] = str(r['NumParcialidad'])
|
r['NumParcialidad'] = str(r['NumParcialidad'])
|
||||||
r['TipoCambioDR'] = FORMAT6.format(r['TipoCambioDR'])
|
r['TipoCambioDR'] = FORMAT6.format(r['TipoCambioDR'])
|
||||||
r['MetodoDePagoDR'] = DEFAULT_CFDIPAY['WAYPAY']
|
# ~ r['MetodoDePagoDR'] = DEFAULT_CFDIPAY['WAYPAY']
|
||||||
|
|
||||||
|
# REVISAR
|
||||||
|
r['EquivalenciaDR'] = '1'
|
||||||
|
r['ObjetoImpDR'] = '02'
|
||||||
|
|
||||||
r['ImpSaldoAnt'] = FORMAT.format(r['ImpSaldoAnt'])
|
r['ImpSaldoAnt'] = FORMAT.format(r['ImpSaldoAnt'])
|
||||||
r['ImpPagado'] = FORMAT.format(r['ImpPagado'])
|
r['ImpPagado'] = FORMAT.format(r['ImpPagado'])
|
||||||
if round(r['ImpSaldoInsoluto'], 2) == 0.0:
|
if round(r['ImpSaldoInsoluto'], 2) == 0.0:
|
||||||
|
@ -7437,7 +7527,28 @@ class CfdiPagos(BaseModel):
|
||||||
if not r['Serie']:
|
if not r['Serie']:
|
||||||
del r['Serie']
|
del r['Serie']
|
||||||
|
|
||||||
return related
|
total_tax_iva_16_base = 0
|
||||||
|
total_tax_iva_16_importe = 0
|
||||||
|
|
||||||
|
for key, importe in taxes_pay['retenciones'].items():
|
||||||
|
taxes_pay['retenciones'][key] = FORMAT.format(importe)
|
||||||
|
for k, tax in taxes_pay['traslados'].items():
|
||||||
|
tax_type = taxes_pay['traslados'][k]['ImpuestoP']
|
||||||
|
tax_tasa = taxes_pay['traslados'][k]['TasaOCuotaP']
|
||||||
|
tax_base = taxes_pay['traslados'][k]['BaseP']
|
||||||
|
importe = taxes_pay['traslados'][k]['ImporteP']
|
||||||
|
if f'{tax_type}|{tax_tasa}' == TAX_IVA_16:
|
||||||
|
total_tax_iva_16_base += tax_base
|
||||||
|
total_tax_iva_16_importe += importe
|
||||||
|
taxes_pay['traslados'][k]['BaseP'] = FORMAT.format(tax_base)
|
||||||
|
taxes_pay['traslados'][k]['ImporteP'] = FORMAT.format(importe)
|
||||||
|
|
||||||
|
taxes_pay['totales'] = {
|
||||||
|
'TotalTrasladosBaseIVA16': FORMAT.format(total_tax_iva_16_base),
|
||||||
|
'TotalTrasladosImpuestoIVA16': FORMAT.format(total_tax_iva_16_importe),
|
||||||
|
}
|
||||||
|
|
||||||
|
return related, taxes_pay
|
||||||
|
|
||||||
def _generate_xml(self, invoice):
|
def _generate_xml(self, invoice):
|
||||||
emisor = Emisor.select()[0]
|
emisor = Emisor.select()[0]
|
||||||
|
@ -7450,9 +7561,9 @@ class CfdiPagos(BaseModel):
|
||||||
cfdi['Folio'] = str(invoice.folio)
|
cfdi['Folio'] = str(invoice.folio)
|
||||||
cfdi['Fecha'] = invoice.fecha.isoformat()[:19]
|
cfdi['Fecha'] = invoice.fecha.isoformat()[:19]
|
||||||
cfdi['NoCertificado'] = certificado.serie
|
cfdi['NoCertificado'] = certificado.serie
|
||||||
# ~ cfdi['Certificado'] = cert.cer_txt
|
|
||||||
cfdi['SubTotal'] = '0'
|
cfdi['SubTotal'] = '0'
|
||||||
cfdi['Moneda'] = DEFAULT_CFDIPAY['CURRENCY']
|
cfdi['Moneda'] = DEFAULT_CFDIPAY['CURRENCY']
|
||||||
|
# ~ cfdi['TipoCambio'] = DEFAULT_CFDIPAY['TC']
|
||||||
cfdi['Total'] = '0'
|
cfdi['Total'] = '0'
|
||||||
cfdi['TipoDeComprobante'] = invoice.tipo_comprobante
|
cfdi['TipoDeComprobante'] = invoice.tipo_comprobante
|
||||||
cfdi['LugarExpedicion'] = invoice.lugar_expedicion
|
cfdi['LugarExpedicion'] = invoice.lugar_expedicion
|
||||||
|
@ -7473,6 +7584,8 @@ class CfdiPagos(BaseModel):
|
||||||
'Rfc': invoice.socio.rfc,
|
'Rfc': invoice.socio.rfc,
|
||||||
'Nombre': invoice.socio.nombre,
|
'Nombre': invoice.socio.nombre,
|
||||||
'UsoCFDI': DEFAULT_CFDIPAY['USED'],
|
'UsoCFDI': DEFAULT_CFDIPAY['USED'],
|
||||||
|
'DomicilioFiscalReceptor': invoice.socio.codigo_postal,
|
||||||
|
'RegimenFiscalReceptor': invoice.receptor_regimen
|
||||||
}
|
}
|
||||||
if invoice.socio.tipo_persona == 4:
|
if invoice.socio.tipo_persona == 4:
|
||||||
if invoice.socio.pais:
|
if invoice.socio.pais:
|
||||||
|
@ -7487,19 +7600,23 @@ class CfdiPagos(BaseModel):
|
||||||
'Descripcion': DEFAULT_CFDIPAY['DESCRIPTION'],
|
'Descripcion': DEFAULT_CFDIPAY['DESCRIPTION'],
|
||||||
'ValorUnitario': '0',
|
'ValorUnitario': '0',
|
||||||
'Importe': '0',
|
'Importe': '0',
|
||||||
|
'ObjetoImp': '01',
|
||||||
},)
|
},)
|
||||||
|
|
||||||
impuestos = {}
|
impuestos = {}
|
||||||
|
|
||||||
mov = invoice.movimiento
|
mov = invoice.movimiento
|
||||||
currency = mov.moneda
|
currency = mov.moneda
|
||||||
related_docs = self._get_related_xml(self, invoice.movimiento, currency)
|
related_docs, taxes_pay = self._get_related_xml(self, invoice.movimiento, currency)
|
||||||
|
totales = taxes_pay.pop('totales')
|
||||||
pagos = {
|
pagos = {
|
||||||
'FechaPago': mov.fecha.isoformat()[:19],
|
'FechaPago': mov.fecha.isoformat()[:19],
|
||||||
'FormaDePagoP': mov.forma_pago.key,
|
'FormaDePagoP': mov.forma_pago.key,
|
||||||
'MonedaP': currency,
|
'MonedaP': currency,
|
||||||
|
'TipoCambioP': '1',
|
||||||
'Monto': FORMAT.format(mov.deposito),
|
'Monto': FORMAT.format(mov.deposito),
|
||||||
'relacionados': related_docs,
|
'relacionados': related_docs,
|
||||||
|
'taxes_pay': taxes_pay,
|
||||||
}
|
}
|
||||||
if mov.numero_operacion:
|
if mov.numero_operacion:
|
||||||
pagos['NumOperacion'] = mov.numero_operacion
|
pagos['NumOperacion'] = mov.numero_operacion
|
||||||
|
@ -7514,10 +7631,12 @@ class CfdiPagos(BaseModel):
|
||||||
pagos['RfcEmisorCtaBen'] = mov.cuenta.banco.rfc
|
pagos['RfcEmisorCtaBen'] = mov.cuenta.banco.rfc
|
||||||
pagos['CtaBeneficiario'] = mov.cuenta.cuenta
|
pagos['CtaBeneficiario'] = mov.cuenta.cuenta
|
||||||
|
|
||||||
|
|
||||||
if currency != CURRENCY_MN:
|
if currency != CURRENCY_MN:
|
||||||
pagos['TipoCambioP'] = FORMAT_TAX.format(mov.tipo_cambio)
|
pagos['TipoCambioP'] = FORMAT_TAX.format(mov.tipo_cambio)
|
||||||
|
|
||||||
|
totales['MontoTotalPagos'] = pagos['Monto']
|
||||||
|
pagos['totales'] = totales
|
||||||
|
|
||||||
complementos = {'pagos': pagos}
|
complementos = {'pagos': pagos}
|
||||||
data = {
|
data = {
|
||||||
'comprobante': cfdi,
|
'comprobante': cfdi,
|
||||||
|
@ -10732,6 +10851,10 @@ def _migrate_tables(rfc=''):
|
||||||
correo_facturasp = TextField(default='')
|
correo_facturasp = TextField(default='')
|
||||||
migrations.append(
|
migrations.append(
|
||||||
migrator.add_column('socios', 'correo_facturasp', correo_facturasp))
|
migrator.add_column('socios', 'correo_facturasp', correo_facturasp))
|
||||||
|
if not 'regimen_fiscal' in columns:
|
||||||
|
regimen_fiscal = TextField(default='')
|
||||||
|
migrations.append(
|
||||||
|
migrator.add_column('socios', 'regimen_fiscal', regimen_fiscal))
|
||||||
|
|
||||||
columns = [c.name for c in database_proxy.get_columns('folios')]
|
columns = [c.name for c in database_proxy.get_columns('folios')]
|
||||||
if not 'plantilla' in columns:
|
if not 'plantilla' in columns:
|
||||||
|
@ -10781,6 +10904,9 @@ def _migrate_tables(rfc=''):
|
||||||
migrations.append(migrator.add_column('cfdipagos', 'socio_id', socio))
|
migrations.append(migrator.add_column('cfdipagos', 'socio_id', socio))
|
||||||
migrations.append(migrator.drop_column('cfdipagos', 'cancelado'))
|
migrations.append(migrator.drop_column('cfdipagos', 'cancelado'))
|
||||||
migrations.append(migrator.add_column('cfdipagos', 'cancelada', cancelada))
|
migrations.append(migrator.add_column('cfdipagos', 'cancelada', cancelada))
|
||||||
|
if not 'receptor_regimen' in columns:
|
||||||
|
receptor_regimen = TextField(default='')
|
||||||
|
migrations.append(migrator.add_column('cfdipagos', 'receptor_regimen', receptor_regimen))
|
||||||
|
|
||||||
if not 'fecha_cancelacion' in columns:
|
if not 'fecha_cancelacion' in columns:
|
||||||
fecha_cancelacion = DateTimeField(null=True)
|
fecha_cancelacion = DateTimeField(null=True)
|
||||||
|
|
|
@ -169,7 +169,8 @@ DEFAULT_CFDIPAY = {
|
||||||
'TYPE': 'P',
|
'TYPE': 'P',
|
||||||
'WAYPAY': 'PPD',
|
'WAYPAY': 'PPD',
|
||||||
'CURRENCY': 'XXX',
|
'CURRENCY': 'XXX',
|
||||||
'USED': 'P01',
|
'TC': '1',
|
||||||
|
'USED': 'CP01',
|
||||||
'KEYSAT': '84111506',
|
'KEYSAT': '84111506',
|
||||||
'UNITKEY': 'ACT',
|
'UNITKEY': 'ACT',
|
||||||
'DESCRIPTION': 'Pago',
|
'DESCRIPTION': 'Pago',
|
||||||
|
@ -182,7 +183,7 @@ PUBLIC = 'Público en general'
|
||||||
DEFAULT_SAT_NOMINA = {
|
DEFAULT_SAT_NOMINA = {
|
||||||
'SERIE': 'N',
|
'SERIE': 'N',
|
||||||
'FORMA_PAGO': '99',
|
'FORMA_PAGO': '99',
|
||||||
'USO_CFDI': 'P01',
|
'USO_CFDI': 'CN01',
|
||||||
'CLAVE': '84111505',
|
'CLAVE': '84111505',
|
||||||
'UNIDAD': 'ACT',
|
'UNIDAD': 'ACT',
|
||||||
'DESCRIPCION': 'Pago de nómina',
|
'DESCRIPCION': 'Pago de nómina',
|
||||||
|
|
Loading…
Reference in New Issue