Impuestos locales
This commit is contained in:
parent
ff21b3c8bc
commit
9b430b882b
|
@ -39,6 +39,12 @@ SAT = {
|
|||
'xmlns': 'http://www.sat.gob.mx/nomina12',
|
||||
'schema': 'http://www.sat.gob.mx/nomina12 http://www.sat.gob.mx/sitio_internet/cfd/nomina/nomina12.xsd',
|
||||
},
|
||||
'locales': {
|
||||
'version': '1.0',
|
||||
'prefix': 'implocal',
|
||||
'xmlns': 'http://www.sat.gob.mx/implocal',
|
||||
'schema': ' http://www.sat.gob.mx/implocal http://www.sat.gob.mx/sitio_internet/cfd/implocal/implocal.xsd',
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
@ -49,6 +55,8 @@ class CFDI(object):
|
|||
self._xsi = SAT['xsi']
|
||||
self._pre = self._sat_cfdi['prefix']
|
||||
self._cfdi = None
|
||||
self._complemento = None
|
||||
self._impuestos_locales = False
|
||||
self.error = ''
|
||||
|
||||
def _now(self):
|
||||
|
@ -68,6 +76,7 @@ class CFDI(object):
|
|||
self._nomina(datos['nomina'])
|
||||
if 'complementos' in datos:
|
||||
self._complementos(datos['complementos'])
|
||||
self._locales(datos['impuestos'])
|
||||
return self._to_pretty_xml(ET.tostring(self._cfdi, encoding='utf-8'))
|
||||
|
||||
def add_sello(self, sello):
|
||||
|
@ -80,6 +89,10 @@ class CFDI(object):
|
|||
return xml
|
||||
|
||||
def _validate(self, datos):
|
||||
if datos['impuestos']['total_locales_trasladados'] or \
|
||||
datos['impuestos']['total_locales_retenciones']:
|
||||
self._impuestos_locales = True
|
||||
|
||||
if 'nomina' in datos:
|
||||
return self._validate_nomina(datos)
|
||||
return True
|
||||
|
@ -105,7 +118,15 @@ class CFDI(object):
|
|||
attributes = {}
|
||||
attributes['xmlns:{}'.format(self._pre)] = self._sat_cfdi['xmlns']
|
||||
attributes['xmlns:xsi'] = self._xsi
|
||||
attributes['xsi:schemaLocation'] = self._sat_cfdi['schema']
|
||||
|
||||
shema_locales = ''
|
||||
if self._impuestos_locales:
|
||||
name = 'xmlns:{}'.format(SAT['locales']['prefix'])
|
||||
attributes[name] = SAT['locales']['xmlns']
|
||||
shema_locales = SAT['locales']['schema']
|
||||
|
||||
attributes['xsi:schemaLocation'] = self._sat_cfdi['schema'] + \
|
||||
shema_locales
|
||||
attributes.update(datos)
|
||||
|
||||
if not 'Version' in attributes:
|
||||
|
@ -257,8 +278,31 @@ class CFDI(object):
|
|||
ET.SubElement(deducciones, '{}:Deduccion'.format(pre), row)
|
||||
return
|
||||
|
||||
def _locales(self, datos):
|
||||
if not self._impuestos_locales:
|
||||
return
|
||||
|
||||
if self._complemento is None:
|
||||
self._complemento = ET.SubElement(
|
||||
self._cfdi, '{}:Complemento'.format(self._pre))
|
||||
|
||||
attributes = {}
|
||||
attributes['version'] = SAT['locales']['version']
|
||||
attributes['TotaldeTraslados'] = datos['total_locales_trasladados']
|
||||
attributes['TotaldeRetenciones'] = datos['total_locales_retenciones']
|
||||
|
||||
node = ET.SubElement(
|
||||
self._complemento, 'implocal:ImpuestosLocales', attributes)
|
||||
|
||||
for retencion in datos['locales_retenciones']:
|
||||
ET.SubElement(node, 'implocal:RetencionesLocales', retencion)
|
||||
for traslado in datos['locales_trasladados']:
|
||||
ET.SubElement(node, 'implocal:TrasladosLocales', traslado)
|
||||
return
|
||||
|
||||
def _complementos(self, datos):
|
||||
complemento = ET.SubElement(self._cfdi, '{}:Complemento'.format(self._pre))
|
||||
self._complemento = ET.SubElement(
|
||||
self._cfdi, '{}:Complemento'.format(self._pre))
|
||||
if 'ce' in datos:
|
||||
pre = 'cce11'
|
||||
datos = datos.pop('ce')
|
||||
|
|
|
@ -1443,6 +1443,7 @@ class Productos(BaseModel):
|
|||
.select(
|
||||
Productos.id,
|
||||
Productos.clave,
|
||||
Productos.clave_sat,
|
||||
Productos.descripcion,
|
||||
SATUnidades.name.alias('unidad'),
|
||||
Productos.valor_unitario,
|
||||
|
@ -1463,8 +1464,12 @@ class Productos(BaseModel):
|
|||
if name:
|
||||
rows = (Productos
|
||||
.select(
|
||||
Productos.id, Productos.clave, Productos.descripcion,
|
||||
SATUnidades.name.alias('unidad'), Productos.valor_unitario)
|
||||
Productos.id,
|
||||
Productos.clave,
|
||||
Productos.clave_sat,
|
||||
Productos.descripcion,
|
||||
SATUnidades.name.alias('unidad'),
|
||||
Productos.valor_unitario)
|
||||
.join(SATUnidades)
|
||||
.switch(Productos)
|
||||
.where(Productos.descripcion.contains(name))
|
||||
|
@ -1984,6 +1989,8 @@ class Facturas(BaseModel):
|
|||
total_trasladados = None
|
||||
total_retenciones = None
|
||||
total_iva = 0
|
||||
locales_traslados = 0
|
||||
locales_retenciones = 0
|
||||
|
||||
for product in products:
|
||||
id_product = product.pop('id')
|
||||
|
@ -2015,10 +2022,8 @@ class Facturas(BaseModel):
|
|||
|
||||
for tax in p.impuestos:
|
||||
if tax.id in totals_tax:
|
||||
#~ totals_tax[tax.id].importe += product['importe']
|
||||
totals_tax[tax.id].importe += importe
|
||||
else:
|
||||
#~ tax.importe = product['importe']
|
||||
tax.importe = importe
|
||||
totals_tax[tax.id] = tax
|
||||
|
||||
|
@ -2027,7 +2032,10 @@ class Facturas(BaseModel):
|
|||
continue
|
||||
|
||||
import_tax = round(float(tax.tasa) * tax.importe, DECIMALES)
|
||||
total_trasladados = (total_trasladados or 0) + import_tax
|
||||
if tax.key == '000':
|
||||
locales_traslados += import_tax
|
||||
else:
|
||||
total_trasladados = (total_trasladados or 0) + import_tax
|
||||
if tax.name == 'IVA':
|
||||
total_iva += import_tax
|
||||
|
||||
|
@ -2046,7 +2054,10 @@ class Facturas(BaseModel):
|
|||
import_tax = round(float(tax.tasa) * total_iva, DECIMALES)
|
||||
else:
|
||||
import_tax = round(float(tax.tasa) * tax.importe, DECIMALES)
|
||||
total_retenciones = (total_retenciones or 0) + import_tax
|
||||
if tax.key == '000':
|
||||
locales_retenciones += import_tax
|
||||
else:
|
||||
total_retenciones = (total_retenciones or 0) + import_tax
|
||||
|
||||
invoice_tax = {
|
||||
'factura': invoice.id,
|
||||
|
@ -2056,7 +2067,9 @@ class Facturas(BaseModel):
|
|||
}
|
||||
FacturasImpuestos.create(**invoice_tax)
|
||||
|
||||
total = subtotal + (total_trasladados or 0) - (total_retenciones or 0)
|
||||
total = subtotal + \
|
||||
(total_trasladados or 0) - (total_retenciones or 0) \
|
||||
+ locales_traslados - locales_retenciones
|
||||
total_mn = round(total * invoice.tipo_cambio, DECIMALES)
|
||||
data = {
|
||||
'subtotal': subtotal + descuento,
|
||||
|
@ -2163,6 +2176,7 @@ class Facturas(BaseModel):
|
|||
}
|
||||
|
||||
#~ descuento = 0
|
||||
#~ tax_locales = False
|
||||
conceptos = []
|
||||
rows = FacturasDetalle.select().where(FacturasDetalle.factura==invoice)
|
||||
for row in rows:
|
||||
|
@ -2187,6 +2201,11 @@ class Facturas(BaseModel):
|
|||
for impuesto in row.producto.impuestos:
|
||||
if impuesto.tipo == 'E':
|
||||
continue
|
||||
|
||||
if impuesto.key == '000':
|
||||
#~ tax_locales = True
|
||||
continue
|
||||
|
||||
base = row.importe - row.descuento
|
||||
import_tax = round(impuesto.tasa * base, DECIMALES)
|
||||
tipo_factor = 'Tasa'
|
||||
|
@ -2211,12 +2230,13 @@ class Facturas(BaseModel):
|
|||
concepto['impuestos'] = taxes
|
||||
conceptos.append(concepto)
|
||||
|
||||
#~ if descuento:
|
||||
#~ comprobante['Descuento'] = FORMAT.format(descuento)
|
||||
|
||||
impuestos = {}
|
||||
traslados = []
|
||||
retenciones = []
|
||||
total_locales_trasladados = 0
|
||||
total_locales_retenciones = 0
|
||||
locales_trasladados = []
|
||||
locales_retenciones = []
|
||||
if not invoice.total_trasladados is None:
|
||||
impuestos['TotalImpuestosTrasladados'] = \
|
||||
FORMAT.format(invoice.total_trasladados)
|
||||
|
@ -2228,6 +2248,25 @@ class Facturas(BaseModel):
|
|||
.select()
|
||||
.where(FacturasImpuestos.factura==invoice))
|
||||
for tax in taxes:
|
||||
if tax.impuesto.key == '000':
|
||||
if tax.impuesto.tipo == 'T':
|
||||
traslado = {
|
||||
'ImpLocTrasladado': tax.impuesto.name,
|
||||
'TasadeTraslado': str(round(tax.impuesto.tasa, 2)),
|
||||
'Importe': FORMAT.format(tax.importe),
|
||||
}
|
||||
locales_trasladados.append(traslado)
|
||||
total_locales_trasladados += tax.importe
|
||||
else:
|
||||
retencion = {
|
||||
'ImpLocRetenido': tax.impuesto.name,
|
||||
'TasadeRetencion': str(round(tax.impuesto.tasa, 2)),
|
||||
'Importe': FORMAT.format(tax.importe),
|
||||
}
|
||||
locales_retenciones.append(retencion)
|
||||
total_locales_retenciones += tax.importe
|
||||
continue
|
||||
|
||||
tipo_factor = 'Tasa'
|
||||
if tax.impuesto.factor != 'T':
|
||||
tipo_factor = 'Cuota'
|
||||
|
@ -2248,6 +2287,12 @@ class Facturas(BaseModel):
|
|||
|
||||
impuestos['traslados'] = traslados
|
||||
impuestos['retenciones'] = retenciones
|
||||
impuestos['total_locales_trasladados'] = \
|
||||
FORMAT.format(total_locales_trasladados)
|
||||
impuestos['total_locales_retenciones'] = \
|
||||
FORMAT.format(total_locales_retenciones)
|
||||
impuestos['locales_trasladados'] = locales_trasladados
|
||||
impuestos['locales_retenciones'] = locales_retenciones
|
||||
|
||||
data = {
|
||||
'comprobante': comprobante,
|
||||
|
|
|
@ -260,6 +260,13 @@ function validate_invoice(values){
|
|||
return false
|
||||
}
|
||||
|
||||
var r = grid.data.getRange()
|
||||
if(r[0].clave_sat != CLAVE_ANTICIPOS){
|
||||
msg = 'La clave del SAT para anticipos debe ser: ' + CLAVE_ANTICIPOS
|
||||
msg_error(msg)
|
||||
return false
|
||||
}
|
||||
|
||||
query = table_relaciones.chain().data()
|
||||
if(query.length > 0){
|
||||
msg = 'Los anticipos no deben llevar CFDI relacionados'
|
||||
|
@ -419,6 +426,7 @@ function guardar_y_timbrar(values){
|
|||
for (i = 0; i < rows.length; i++) {
|
||||
delete rows[i]['delete']
|
||||
delete rows[i]['clave']
|
||||
delete rows[i]['clave_sat']
|
||||
delete rows[i]['unidad']
|
||||
delete rows[i]['importe']
|
||||
rows[i]['valor_unitario'] = parseFloat(rows[i]['valor_unitario'])
|
||||
|
@ -639,7 +647,7 @@ function set_product(values){
|
|||
values['importe'] = (precio_final * values['cantidad']).round(DECIMALES)
|
||||
grid.updateItem(row.id, values)
|
||||
}
|
||||
form.setValues({search_product_id:'', search_product_name:''}, true)
|
||||
form.setValues({search_product_id: '', search_product_name: ''}, true)
|
||||
|
||||
for(var v of taxes){
|
||||
var pt = table_pt.findOne(v)
|
||||
|
|
|
@ -3,6 +3,7 @@ var RFC_PUBLICO = "XAXX010101000";
|
|||
var RFC_EXTRANJERO = "XEXX010101000";
|
||||
var PAIS = "México";
|
||||
var DECIMALES = 2;
|
||||
var CLAVE_ANTICIPOS = '84111506';
|
||||
|
||||
|
||||
var db = new loki('data.db');
|
||||
|
|
|
@ -233,6 +233,7 @@ var grid_details_cols = [
|
|||
{id: "id", header:"ID", hidden: true},
|
||||
{id: 'delete', header: '', width: 30, css: 'delete'},
|
||||
{id: "clave", header:{text: 'Clave', css: 'center'}, width: 100},
|
||||
{id: "clave_sat", hidden: true},
|
||||
{id: "descripcion", header:{text: 'Descripción', css: 'center'},
|
||||
fillspace: true, editor: 'text'},
|
||||
{id: "unidad", header:{text: 'Unidad', css: 'center'}, width: 100},
|
||||
|
|
|
@ -8,12 +8,11 @@
|
|||
<xsl:include href="comercioexterior11.xslt"/>
|
||||
<xsl:include href="leyendasFisc.xslt"/>
|
||||
<xsl:include href="nomina12.xslt"/>
|
||||
|
||||
<xsl:include href="implocal.xslt"/>
|
||||
<!--
|
||||
<xsl:include href="ecc11.xslt"/>
|
||||
<xsl:include href="donat11.xslt"/>
|
||||
<xsl:include href="Divisas.xslt"/>
|
||||
<xsl:include href="implocal.xslt"/>
|
||||
<xsl:include href="pfic.xslt"/>
|
||||
<xsl:include href="TuristaPasajeroExtranjero.xslt"/>
|
||||
<xsl:include href="cfdiregistrofiscal.xslt"/>
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:implocal="http://www.sat.gob.mx/implocal">
|
||||
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
|
||||
<!-- Manejador de nodos tipo implocal -->
|
||||
<xsl:template match="implocal:ImpuestosLocales">
|
||||
<!--Iniciamos el tratamiento de los atributos de ImpuestosLocales -->
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@version"/>
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@TotaldeRetenciones"/>
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@TotaldeTraslados"/>
|
||||
</xsl:call-template>
|
||||
<xsl:for-each select="implocal:RetencionesLocales">
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@ImpLocRetenido"/>
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@TasadeRetencion"/>
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@Importe"/>
|
||||
</xsl:call-template>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="implocal:TrasladosLocales">
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@ImpLocTrasladado"/>
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@TasadeTraslado"/>
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@Importe"/>
|
||||
</xsl:call-template>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
Loading…
Reference in New Issue