diff --git a/source/app/controllers/cfdi_xml.py b/source/app/controllers/cfdi_xml.py index 03c2270..d9589b2 100644 --- a/source/app/controllers/cfdi_xml.py +++ b/source/app/controllers/cfdi_xml.py @@ -45,6 +45,13 @@ SAT = { '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', }, + 'donativo': { + 'version': '1.1', + 'prefix': 'donat', + 'xmlns': 'http://www.sat.gob.mx/donat', + 'schema': ' http://www.sat.gob.mx/donat http://www.sat.gob.mx/sitio_internet/cfd/donat/donat11.xsd', + 'leyenda': 'Este comprobante ampara un donativo, el cual será destinado por la donataria a los fines propios de su objeto social. En el caso de que los bienes donados hayan sido deducidos previamente para los efectos del impuesto sobre la renta, este donativo no es deducible. La reproducción no autorizada de este comprobante constituye un delito en los términos de las disposiciones fiscales.', + }, } @@ -57,6 +64,7 @@ class CFDI(object): self._cfdi = None self._complemento = None self._impuestos_locales = False + self._donativo = False self.error = '' def _now(self): @@ -72,11 +80,14 @@ class CFDI(object): self._receptor(datos['receptor']) self._conceptos(datos['conceptos']) self._impuestos(datos['impuestos']) + self._locales(datos['impuestos']) + self._donatarias(datos['donativo']) + if 'nomina' in datos: 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): @@ -89,12 +100,13 @@ class CFDI(object): return xml def _validate(self, datos): - print (datos['impuestos']['total_locales_trasladados']) - print (datos['impuestos']['total_locales_retenciones']) if datos['impuestos']['total_locales_trasladados'] or \ datos['impuestos']['total_locales_retenciones']: self._impuestos_locales = True + if datos['donativo']: + self._donativo = True + if 'nomina' in datos: return self._validate_nomina(datos) return True @@ -121,14 +133,20 @@ class CFDI(object): attributes['xmlns:{}'.format(self._pre)] = self._sat_cfdi['xmlns'] attributes['xmlns:xsi'] = self._xsi - shema_locales = '' + schema_locales = '' if self._impuestos_locales: name = 'xmlns:{}'.format(SAT['locales']['prefix']) attributes[name] = SAT['locales']['xmlns'] - shema_locales = SAT['locales']['schema'] + schema_locales = SAT['locales']['schema'] + + schema_donativo = '' + if self._donativo: + name = 'xmlns:{}'.format(SAT['donativo']['prefix']) + attributes[name] = SAT['donativo']['xmlns'] + schema_donativo = SAT['donativo']['schema'] attributes['xsi:schemaLocation'] = self._sat_cfdi['schema'] + \ - shema_locales + schema_locales + schema_donativo attributes.update(datos) if not 'Version' in attributes: @@ -302,6 +320,23 @@ class CFDI(object): ET.SubElement(node, 'implocal:TrasladosLocales', traslado) return + def _donatarias(self, datos): + if not datos: + return + + if self._complemento is None: + self._complemento = ET.SubElement( + self._cfdi, '{}:Complemento'.format(self._pre)) + + attributes = {} + attributes['version'] = SAT['donativo']['version'] + attributes['leyenda'] = SAT['donativo']['leyenda'] + attributes.update(datos) + + node = ET.SubElement(self._complemento, 'donat:Donatarias', attributes) + + return + def _complementos(self, datos): self._complemento = ET.SubElement( self._cfdi, '{}:Complemento'.format(self._pre)) diff --git a/source/app/models/main.py b/source/app/models/main.py index 9aee95e..560d7f2 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -2122,6 +2122,7 @@ class Facturas(BaseModel): values['tipo_cambio'] = float(values['tipo_cambio']) values['lugar_expedicion'] = emisor.cp_expedicion or emisor.codigo_postal values['anticipo'] = util.get_bool(values['anticipo']) + values['donativo'] = util.get_bool(values['donativo']) with database_proxy.atomic() as txn: obj = Facturas.create(**values) @@ -2153,8 +2154,15 @@ class Facturas(BaseModel): def _make_xml(self, invoice): emisor = Emisor.select()[0] certificado = Certificado.select()[0] + comprobante = {} relacionados = {} + donativo = {} + + if invoice.donativo: + donativo['noAutorizacion'] = emisor.autorizacion + donativo['fechaAutorizacion'] = str(emisor.fecha_autorizacion) + if invoice.serie: comprobante['Serie'] = invoice.serie if invoice.condiciones_pago: @@ -2325,6 +2333,7 @@ class Facturas(BaseModel): 'receptor': receptor, 'conceptos': conceptos, 'impuestos': impuestos, + 'donativo': donativo, } return util.make_xml(data, certificado) diff --git a/source/static/js/controller/invoices.js b/source/static/js/controller/invoices.js index eb742dd..49e6402 100644 --- a/source/static/js/controller/invoices.js +++ b/source/static/js/controller/invoices.js @@ -467,6 +467,7 @@ function guardar_y_timbrar(values){ data['relacionados'] = ids data['tipo_relacion'] = tipo_relacion data['anticipo'] = anticipo + data['donativo'] = $$('chk_cfdi_donativo').getValue() if(!save_invoice(data)){ return