Stamp Nomina with Cfdi 4.0

This commit is contained in:
Mauricio Baeza 2022-06-04 21:52:28 -05:00
parent 1e824bd841
commit f8cd99084a
9 changed files with 67 additions and 31 deletions

View File

@ -1359,6 +1359,7 @@ class LIBO(object):
'codigo_postal', 'codigo_postal',
'notas', 'notas',
'correo', 'correo',
'regimen_fiscal',
) )
rows = tuple([dict(zip(fields, r)) for r in data[1:]]) rows = tuple([dict(zip(fields, r)) for r in data[1:]])
msg = 'Empleados importados correctamente' msg = 'Empleados importados correctamente'
@ -1561,8 +1562,9 @@ def to_pdf(data, emisor_rfc, ods=False, pdf_from='1'):
default = f'plantilla_factura_{version}.ods' default = f'plantilla_factura_{version}.ods'
if 'nomina' in data and data['nomina']: if 'nomina' in data and data['nomina']:
default = 'plantilla_nomina.ods' version_nomina = data['nomina']['version']
version = '{}_{}'.format(data['nomina']['version'], version) default = f'plantilla_nomina_{version}_{version_nomina}.ods'
version = f'{version}_cn_{version_nomina}'
if 'carta_porte' in data: if 'carta_porte' in data:
default = 'plantilla_factura_cp.ods' default = 'plantilla_factura_cp.ods'
@ -1576,14 +1578,16 @@ def to_pdf(data, emisor_rfc, ods=False, pdf_from='1'):
if pdf_from == '2': if pdf_from == '2':
return to_pdf_from_json(rfc, version, data) return to_pdf_from_json(rfc, version, data)
if APP_LIBO:
app = LIBO()
if app.is_running:
donativo = '' donativo = ''
if data['donativo']: if data['donativo']:
donativo = '_donativo' donativo = '_donativo'
name = '{}_{}{}{}.ods'.format(rfc.lower(), pagos, version, donativo)
path = get_template_ods(name, default) template_name = f'{rfc.lower()}_{version}.ods'
if APP_LIBO:
app = LIBO()
if app.is_running:
path = get_template_ods(template_name, default)
if path: if path:
return app.pdf(path, data, ods) return app.pdf(path, data, ods)
@ -2245,7 +2249,9 @@ def upload_file(rfc, opt, file_obj):
tmp = file_obj.filename.split('.') tmp = file_obj.filename.split('.')
ext = tmp[-1].lower() ext = tmp[-1].lower()
versions = ('_3.2.ods', '_3.3.ods', '_3.3_cp_2.0.ods', '_4.0.ods') versions = ('_3.2.ods',
'_3.3.ods', '_3.3_cn_1.2.ods', '_3.3_cp_2.0.ods',
'_4.0.ods', '_4.0_cn_1.2.ods')
if opt in versions: if opt in versions:
return save_template(rfc, opt, file_obj) return save_template(rfc, opt, file_obj)

View File

@ -263,6 +263,7 @@ class CfdiToDict(object):
'divisas': 'http://www.sat.gob.mx/divisas', 'divisas': 'http://www.sat.gob.mx/divisas',
'leyendasFisc': 'http://www.sat.gob.mx/leyendasFiscales', 'leyendasFisc': 'http://www.sat.gob.mx/leyendasFiscales',
'cartaporte20': 'http://www.sat.gob.mx/CartaPorte20', 'cartaporte20': 'http://www.sat.gob.mx/CartaPorte20',
'nomina12': 'http://www.sat.gob.mx/nomina12',
} }
tipo_figura = { tipo_figura = {
'01': '[01] Operador', '01': '[01] Operador',
@ -399,6 +400,14 @@ class CfdiToDict(object):
path = '//cfdi:Complemento' path = '//cfdi:Complemento'
complemento = self._root.xpath(path, namespaces=self.NS)[0] complemento = self._root.xpath(path, namespaces=self.NS)[0]
path = '//nomina12:Nomina'
nomina = complemento.xpath(path, namespaces=self.NS)
if nomina:
for node in nomina[0]:
if 'Receptor' in node.tag:
attr = CaseInsensitiveDict(node.attrib)
self._values['receptor'].update(attr)
path = '//divisas:Divisas' path = '//divisas:Divisas'
divisas = complemento.xpath(path, namespaces=self.NS) divisas = complemento.xpath(path, namespaces=self.NS)
if divisas: if divisas:

View File

@ -8934,6 +8934,7 @@ class Empleados(BaseModel):
codigo_postal = TextField(default='') codigo_postal = TextField(default='')
notas = TextField(default='') notas = TextField(default='')
correo = TextField(default='') correo = TextField(default='')
regimen_fiscal = TextField(default='')
class Meta: class Meta:
order_by = ('nombre_completo',) order_by = ('nombre_completo',)
@ -8985,10 +8986,10 @@ class Empleados(BaseModel):
obj = Empleados.create(**data) obj = Empleados.create(**data)
en += 1 en += 1
msg = 'Empleados encontrados: {}<BR>'.format(len(rows)) msg = 'Empleados:<BR><BR>Encontrados: {}<BR>'.format(len(rows))
msg += 'Empleados nuevos: {}<BR>'.format(en) msg += 'Nuevos: {}<BR>'.format(en)
msg += 'Empleados actualizados: {}<BR>'.format(ea) msg += 'Actualizados: {}<BR>'.format(ea)
msg += 'Empleados no importados: {}'.format(len(rows) - en - ea) msg += 'No importados: {}'.format(len(rows) - en - ea)
return {'ok': True, 'msg': msg} return {'ok': True, 'msg': msg}
def _get(self): def _get(self):
@ -9706,7 +9707,7 @@ class CfdiNomina(BaseModel):
comprobante['Serie'] = cfdi.serie comprobante['Serie'] = cfdi.serie
comprobante['Folio'] = str(cfdi.folio) comprobante['Folio'] = str(cfdi.folio)
comprobante['Fecha'] = cfdi.fecha.isoformat()[:19] comprobante['Fecha'] = cfdi.fecha.isoformat()[:19]
comprobante['FormaPago'] = cfdi.forma_pago # ~ comprobante['FormaPago'] = cfdi.forma_pago
comprobante['NoCertificado'] = certificado.serie comprobante['NoCertificado'] = certificado.serie
comprobante['Certificado'] = certificado.cer_txt comprobante['Certificado'] = certificado.cer_txt
comprobante['SubTotal'] = FORMAT.format(cfdi.subtotal) comprobante['SubTotal'] = FORMAT.format(cfdi.subtotal)
@ -9733,6 +9734,8 @@ class CfdiNomina(BaseModel):
receptor = { receptor = {
'Rfc': cfdi.empleado.rfc, 'Rfc': cfdi.empleado.rfc,
'Nombre': cfdi.empleado.nombre_completo, 'Nombre': cfdi.empleado.nombre_completo,
'DomicilioFiscalReceptor': cfdi.empleado.codigo_postal,
'RegimenFiscalReceptor': cfdi.empleado.regimen_fiscal,
'UsoCFDI': cfdi.uso_cfdi, 'UsoCFDI': cfdi.uso_cfdi,
} }
@ -9746,6 +9749,7 @@ class CfdiNomina(BaseModel):
'Descripcion': row.descripcion, 'Descripcion': row.descripcion,
'ValorUnitario': FORMAT.format(row.valor_unitario), 'ValorUnitario': FORMAT.format(row.valor_unitario),
'Importe': FORMAT.format(row.importe), 'Importe': FORMAT.format(row.importe),
'ObjetoImp': '01',
} }
if row.descuento: if row.descuento:
concepto['Descuento'] = FORMAT.format(row.descuento) concepto['Descuento'] = FORMAT.format(row.descuento)
@ -10106,7 +10110,11 @@ class CfdiNomina(BaseModel):
return b'', name return b'', name
values = cls._get_not_in_xml(cls, obj, emisor) values = cls._get_not_in_xml(cls, obj, emisor)
data = util.get_data_from_xml(obj, values) data = util.get_data_from_xml(obj, values)
data.update(utils.CfdiToDict(obj.xml).values)
doc = util.to_pdf(data, emisor.rfc) doc = util.to_pdf(data, emisor.rfc)
# ~ if sync: # ~ if sync:
@ -11058,6 +11066,13 @@ def _migrate_tables(rfc=''):
warehouse = ForeignKeyField(Almacenes, null=True, to_field=Almacenes.id) warehouse = ForeignKeyField(Almacenes, null=True, to_field=Almacenes.id)
migrations.append(migrator.add_column(table, field, warehouse)) migrations.append(migrator.add_column(table, field, warehouse))
table = 'empleados'
field = 'regimen_fiscal'
columns = [c.name for c in database_proxy.get_columns(table)]
if not field in columns:
regimen_fiscal = TextField(default='')
migrations.append(migrator.add_column(table, field, regimen_fiscal))
if migrations: if migrations:
with database_proxy.atomic() as txn: with database_proxy.atomic() as txn:
migrate(*migrations) migrate(*migrations)
@ -11065,7 +11080,7 @@ def _migrate_tables(rfc=''):
Configuracion.add({'version': VERSION}) Configuracion.add({'version': VERSION})
log.info('Tablas migradas correctamente...') log.info('Tablas migradas correctamente...')
_importar_valores('', rfc) # ~ _importar_valores('', rfc)
log.info('Actualizando valores...') log.info('Actualizando valores...')
try: try:
@ -11076,6 +11091,14 @@ def _migrate_tables(rfc=''):
else: else:
log.info('Valores actualizados...') log.info('Valores actualizados...')
try:
q = SATEstados.update(**{'key': 'CMX'}).where(SATEstados.key=='DIF')
q.execute()
except Exception as e:
log.error(e)
else:
log.info('Valores actualizados...')
return return

View File

@ -731,7 +731,7 @@
"pais": "MEX" "pais": "MEX"
}, },
{ {
"key": "DIF", "key": "CMX",
"name": "Ciudad de M\u00e9xico", "name": "Ciudad de M\u00e9xico",
"pais": "MEX" "pais": "MEX"
}, },

View File

@ -81,7 +81,7 @@ var controllers = {
$$('txt_plantilla_factura_css').attachEvent('onItemClick', txt_plantilla_factura_css_click) $$('txt_plantilla_factura_css').attachEvent('onItemClick', txt_plantilla_factura_css_click)
$$('txt_plantilla_ticket').attachEvent('onItemClick', txt_plantilla_ticket_click) $$('txt_plantilla_ticket').attachEvent('onItemClick', txt_plantilla_ticket_click)
$$('txt_plantilla_donataria').attachEvent('onItemClick', txt_plantilla_donataria_click) $$('txt_plantilla_donataria').attachEvent('onItemClick', txt_plantilla_donataria_click)
$$('txt_plantilla_nomina1233').attachEvent('onItemClick', txt_plantilla_nomina1233_click) //~ $$('txt_plantilla_nomina1233').attachEvent('onItemClick', txt_plantilla_nomina1233_click)
$$('txt_plantilla_pagos10').attachEvent('onItemClick', txt_plantilla_pagos10_click) $$('txt_plantilla_pagos10').attachEvent('onItemClick', txt_plantilla_pagos10_click)
$$('make_pdf_from').attachEvent('onChange', opt_make_pdf_from_on_change) $$('make_pdf_from').attachEvent('onChange', opt_make_pdf_from_on_change)
$$('cmd_template_upload').attachEvent('onItemClick', cmd_template_upload_click) $$('cmd_template_upload').attachEvent('onItemClick', cmd_template_upload_click)

View File

@ -598,8 +598,10 @@ var type_make_pdf = [
var opt_templates_cfdi = [ var opt_templates_cfdi = [
{id: '_4.0.ods', value: 'CFDI v4.0'}, {id: '_4.0.ods', value: 'CFDI v4.0'},
{id: '_4.0_cn_1.2.ods', value: 'CFDI v4.0 - Nómina v1.2'},
{id: '_3.3.ods', value: 'CFDI v3.3'}, {id: '_3.3.ods', value: 'CFDI v3.3'},
{id: '_3.3_cp_2.0.ods', value: 'CFDI v3.3 - Carta Porte 2.0'}, {id: '_3.3_cn_1.2.ods', value: 'CFDI v3.3 - Nómina v1.2'},
{id: '_3.3_cp_2.0.ods', value: 'CFDI v3.3 - Carta Porte v2.0'},
{id: '_3.2.ods', value: 'CFDI v3.2'}, {id: '_3.2.ods', value: 'CFDI v3.2'},
] ]
@ -629,11 +631,6 @@ var options_templates = [
{}, {maxWidth: 20} ]}, {}, {maxWidth: 20} ]},
{maxHeight: 20}, {maxHeight: 20},
{cols: [{maxWidth: 20},
{view: 'search', id: 'txt_plantilla_nomina1233', name: 'plantilla_nomina1233',
label: 'Plantilla Nomina v1.2 - Cfdi 3.3 (ODS): ', labelPosition: 'top',
icon: 'file'}, {maxWidth: 40}, {}]},
{maxHeight: 20},
{cols: [{maxWidth: 20}, {cols: [{maxWidth: 20},
{view: 'search', id: 'txt_plantilla_pagos10', name: 'plantilla_pagos10', {view: 'search', id: 'txt_plantilla_pagos10', name: 'plantilla_pagos10',
label: 'Plantilla Factura de Pagos v1.0 - Cfdi 3.3 (ODS): ', label: 'Plantilla Factura de Pagos v1.0 - Cfdi 3.3 (ODS): ',
@ -827,7 +824,7 @@ var options_admin_products = [
var options_admin_complements = [ var options_admin_complements = [
{maxHeight: 20}, {maxHeight: 10},
{template: 'Complemento de Nómina', type: 'section'}, {template: 'Complemento de Nómina', type: 'section'},
{cols: [{maxWidth: 15}, {cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_usar_nomina', labelWidth: 0, {view: 'checkbox', id: 'chk_usar_nomina', labelWidth: 0,
@ -837,7 +834,7 @@ var options_admin_complements = [
{view: 'text', id: 'txt_config_nomina_folio', name: 'config_nomina_folio', {view: 'text', id: 'txt_config_nomina_folio', name: 'config_nomina_folio',
label: 'Folio', labelWidth: 50, labelAlign: 'right'}, label: 'Folio', labelWidth: 50, labelAlign: 'right'},
{maxWidth: 15}]}, {maxWidth: 15}]},
{maxHeight: 20}, {maxHeight: 10},
{template: 'Complemento de Pagos', type: 'section'}, {template: 'Complemento de Pagos', type: 'section'},
{cols: [{maxWidth: 15}, {cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_config_pagos', labelWidth: 0, {view: 'checkbox', id: 'chk_config_pagos', labelWidth: 0,
@ -849,25 +846,25 @@ var options_admin_complements = [
{view: 'text', id: 'txt_config_cfdipay_folio', name: 'txt_config_cfdipay_serie', {view: 'text', id: 'txt_config_cfdipay_folio', name: 'txt_config_cfdipay_serie',
label: 'Folio', labelWidth: 50, labelAlign: 'right'}, label: 'Folio', labelWidth: 50, labelAlign: 'right'},
{maxWidth: 15}]}, {maxWidth: 15}]},
{maxHeight: 20}, {maxHeight: 10},
{template: 'Complemento de Divisas', type: 'section'}, {template: 'Complemento de Divisas', type: 'section'},
{cols: [{maxWidth: 15}, {cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_config_divisas', labelWidth: 0, {view: 'checkbox', id: 'chk_config_divisas', labelWidth: 0,
labelRight: 'Usar complemento de divisas'}, labelRight: 'Usar complemento de divisas'},
{maxWidth: 15}]}, {maxWidth: 15}]},
{maxHeight: 20}, {maxHeight: 10},
{template: 'Complemento INE', type: 'section'}, {template: 'Complemento INE', type: 'section'},
{cols: [{maxWidth: 15}, {cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_config_ine', labelWidth: 0, {view: 'checkbox', id: 'chk_config_ine', labelWidth: 0,
labelRight: 'Usar el complemento INE'}, labelRight: 'Usar el complemento INE'},
{maxWidth: 15}]}, {maxWidth: 15}]},
{maxHeight: 20}, {maxHeight: 10},
{template: 'Complemento para escuelas EDU', type: 'section'}, {template: 'Complemento para escuelas EDU', type: 'section'},
{cols: [{maxWidth: 15}, {cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_config_edu', labelWidth: 0, {view: 'checkbox', id: 'chk_config_edu', labelWidth: 0,
labelRight: 'Usar el complemento EDU'}, labelRight: 'Usar el complemento EDU'},
{maxWidth: 15}]}, {maxWidth: 15}]},
{maxHeight: 20}, {maxHeight: 10},
{template: 'Complemento Leyendas Fiscales', type: 'section'}, {template: 'Complemento Leyendas Fiscales', type: 'section'},
{cols: [{maxWidth: 15}, {cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_config_leyendas_fiscales', labelWidth: 0, {view: 'checkbox', id: 'chk_config_leyendas_fiscales', labelWidth: 0,
@ -876,7 +873,7 @@ var options_admin_complements = [
type: 'form', align: 'center', autowidth: true, disabled: true}, type: 'form', align: 'center', autowidth: true, disabled: true},
{}, {maxWidth: 15} {}, {maxWidth: 15}
]}, ]},
{maxHeight: 20}, {maxHeight: 10},
{template: 'Complemento para Carta Porte', type: 'section'}, {template: 'Complemento para Carta Porte', type: 'section'},
{cols: [{maxWidth: 15}, {cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_config_carta_porte', labelWidth: 0, {view: 'checkbox', id: 'chk_config_carta_porte', labelWidth: 0,

Binary file not shown.

View File

@ -5,16 +5,17 @@
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/> <xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
<xsl:include href="utilerias.xslt"/> <xsl:include href="utilerias.xslt"/>
<xsl:include href="nomina12.xslt"/>
<!--
<xsl:include href="cartaporte20.xslt"/> <xsl:include href="cartaporte20.xslt"/>
<xsl:include href="pagos20.xslt"/> <xsl:include href="pagos20.xslt"/>
<!--
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/donat/donat11.xslt"/> <xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/donat/donat11.xslt"/>
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/divisas/divisas.xslt"/> <xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/divisas/divisas.xslt"/>
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/implocal/implocal.xslt"/> <xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/implocal/implocal.xslt"/>
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xslt"/> <xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xslt"/>
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/pfic/pfic.xslt"/> <xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/pfic/pfic.xslt"/>
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/TuristaPasajeroExtranjero/TuristaPasajeroExtranjero.xslt"/> <xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/TuristaPasajeroExtranjero/TuristaPasajeroExtranjero.xslt"/>
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/nomina/nomina12.xslt"/>
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/cfdiregistrofiscal/cfdiregistrofiscal.xslt"/> <xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/cfdiregistrofiscal/cfdiregistrofiscal.xslt"/>
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/pagoenespecie/pagoenespecie.xslt"/> <xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/pagoenespecie/pagoenespecie.xslt"/>
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/aerolineas/aerolineas.xslt"/> <xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/aerolineas/aerolineas.xslt"/>