diff --git a/source/app/controllers/cfdi_xml.py b/source/app/controllers/cfdi_xml.py
index ec369ee..7054bbe 100644
--- a/source/app/controllers/cfdi_xml.py
+++ b/source/app/controllers/cfdi_xml.py
@@ -84,6 +84,12 @@ SAT = {
'xmlns': 'http://www.sat.gob.mx/Pagos',
'schema': ' http://www.sat.gob.mx/Pagos http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos10.xsd',
},
+ 'divisas': {
+ 'version': '1.0',
+ 'prefix': 'divisas',
+ 'xmlns': 'http://www.sat.gob.mx/divisas',
+ 'schema': ' http://www.sat.gob.mx/divisas http://www.sat.gob.mx/sitio_internet/cfd/divisas/divisas.xsd',
+ },
}
@@ -101,6 +107,7 @@ class CFDI(object):
self._edu = False
self._pagos = False
self._is_nomina = False
+ self._divisas = ''
self.error = ''
def _now(self):
@@ -152,6 +159,8 @@ class CFDI(object):
self._ine = True
self._pagos = bool(datos['complementos'].get('pagos', False))
+ self._divisas = datos['comprobante'].pop('divisas', '')
+
if 'nomina' in datos:
self._is_nomina = True
return self._validate_nomina(datos)
@@ -190,6 +199,12 @@ class CFDI(object):
attributes[name] = SAT['edu']['xmlns']
schema_edu = SAT['edu']['schema']
+ schema_divisas = ''
+ if self._divisas:
+ name = 'xmlns:{}'.format(SAT['divisas']['prefix'])
+ attributes[name] = SAT['divisas']['xmlns']
+ schema_divisas = SAT['divisas']['schema']
+
schema_nomina = ''
if self._is_nomina:
name = 'xmlns:{}'.format(SAT['nomina']['prefix'])
@@ -204,7 +219,7 @@ class CFDI(object):
attributes['xsi:schemaLocation'] = self._sat_cfdi['schema'] + \
schema_locales + schema_donativo + schema_ine + schema_edu + \
- schema_nomina + schema_pagos
+ schema_divisas + schema_nomina + schema_pagos
attributes.update(datos)
if not 'Version' in attributes:
@@ -426,6 +441,13 @@ class CFDI(object):
self._complemento = ET.SubElement(
self._cfdi, '{}:Complemento'.format(self._pre))
+ if self._divisas:
+ atributos = {
+ 'version': SAT['divisas']['version'],
+ 'tipoOperacion': self._divisas,
+ }
+ ET.SubElement(self._complemento, 'divisas:Divisas', atributos)
+
if 'ine' in datos:
atributos = {'Version': SAT['ine']['version']}
atributos.update(datos['ine'])
diff --git a/source/app/models/main.py b/source/app/models/main.py
index f0e47e9..082b780 100644
--- a/source/app/models/main.py
+++ b/source/app/models/main.py
@@ -290,6 +290,7 @@ def config_timbrar():
'cfdi_anticipo': Configuracion.get_('chk_config_anticipo'),
'cfdi_ine': Configuracion.get_bool('chk_config_ine'),
'cfdi_edu': Configuracion.get_bool('chk_config_edu'),
+ 'cfdi_divisas': Configuracion.get_bool('chk_config_divisas'),
'cfdi_metodo_pago': Configuracion.get_bool('chk_config_ocultar_metodo_pago'),
'cfdi_condicion_pago': Configuracion.get_bool('chk_config_ocultar_condiciones_pago'),
'cfdi_open_pdf': Configuracion.get_bool('chk_config_open_pdf'),
@@ -421,6 +422,7 @@ class Configuracion(BaseModel):
'chk_config_ine',
'chk_config_edu',
'chk_config_pagos',
+ 'chk_config_divisas',
'chk_cfg_pays_data_bank',
)
data = (Configuracion
@@ -3630,6 +3632,7 @@ class Facturas(BaseModel):
estatus = TextField(default='Guardada')
estatus_sat = TextField(default='Vigente')
regimen_fiscal = TextField(default='')
+ divisas = TextField(default='')
notas = TextField(default='')
saldo = DecimalField(default=0.0, max_digits=20, decimal_places=6,
auto_round=True)
@@ -4506,6 +4509,12 @@ class Facturas(BaseModel):
ine = values.pop('ine', {})
tipo_comprobante = values['tipo_comprobante']
folio_custom = values.pop('folio_custom', '')
+ divisas = values.pop('divisas', '')
+ if Configuracion.get_bool('chk_config_divisas'):
+ divisas = divisas.lower()
+ if divisas == 'ninguna':
+ divisas = ''
+ values['divisas'] = divisas
emisor = Emisor.select()[0]
values['serie'] = cls._get_serie(cls, user, values['serie'])
@@ -4576,6 +4585,9 @@ class Facturas(BaseModel):
relacionados = {}
donativo = {}
complementos = FacturasComplementos.get_(invoice)
+ comprobante['divisas'] = invoice.divisas
+ if invoice.divisas:
+ complementos['divisas'] = True
if invoice.donativo:
donativo['noAutorizacion'] = emisor.autorizacion
@@ -4808,6 +4820,7 @@ class Facturas(BaseModel):
'edu': is_edu,
'complementos': complementos,
}
+
return util.make_xml(data, certificado, auth)
@classmethod
@@ -8973,6 +8986,12 @@ def _migrate_tables(rfc=''):
migrations.append(migrator.add_column(
table, 'empaques', empaques))
+ table = 'facturas'
+ columns = [c.name for c in database_proxy.get_columns(table)]
+ if not 'divisas' in columns:
+ divisas = TextField(default='')
+ migrations.append(migrator.add_column(table, 'divisas', divisas))
+
if migrations:
with database_proxy.atomic() as txn:
migrate(*migrations)
diff --git a/source/static/js/controller/admin.js b/source/static/js/controller/admin.js
index d533bdc..e577f4d 100644
--- a/source/static/js/controller/admin.js
+++ b/source/static/js/controller/admin.js
@@ -107,6 +107,7 @@ var controllers = {
$$('chk_config_ine').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_edu').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_pagos').attachEvent('onItemClick', chk_config_item_click)
+ $$('chk_config_divisas').attachEvent('onItemClick', chk_config_item_click)
$$('chk_cfg_pays_data_bank').attachEvent('onItemClick', chk_config_item_click)
$$('chk_usar_punto_de_venta').attachEvent('onItemClick', chk_config_item_click)
$$('chk_ticket_pdf_show').attachEvent('onItemClick', chk_config_item_click)
diff --git a/source/static/js/controller/invoices.js b/source/static/js/controller/invoices.js
index 0d607d1..bb7c799 100644
--- a/source/static/js/controller/invoices.js
+++ b/source/static/js/controller/invoices.js
@@ -217,6 +217,7 @@ function default_config(){
$$('grid_details').showColumn('student')
}
show('fs_students', values.cfdi_edu)
+ show('fs_divisas', values.cfdi_divisas)
show('txt_folio_custom', values.cfdi_folio_custom)
})
}
@@ -638,6 +639,7 @@ function guardar_y_timbrar(values){
data['donativo'] = donativo
data['notas'] = values.notas
data['folio_custom'] = $$('txt_folio_custom').getValue()
+ data['divisas'] = $$('opt_divisas').getValue()
var usar_ine = $$('chk_cfdi_usar_ine').getValue()
if(usar_ine){
diff --git a/source/static/js/ui/admin.js b/source/static/js/ui/admin.js
index 405e968..d419f15 100644
--- a/source/static/js/ui/admin.js
+++ b/source/static/js/ui/admin.js
@@ -756,6 +756,12 @@ var options_admin_complements = [
{view: 'text', id: 'txt_config_cfdipay_folio', name: 'txt_config_cfdipay_serie',
label: 'Folio', labelWidth: 50, labelAlign: 'right'},
{maxWidth: 15}]},
+ {maxHeight: 20},
+ {template: 'Complemento de Divisas', type: 'section'},
+ {cols: [{maxWidth: 15},
+ {view: 'checkbox', id: 'chk_config_divisas', labelWidth: 0,
+ labelRight: 'Usar complemento de divisas'},
+ {maxWidth: 15}]},
]
diff --git a/source/static/js/ui/invoices.js b/source/static/js/ui/invoices.js
index 0370bb1..9357a55 100644
--- a/source/static/js/ui/invoices.js
+++ b/source/static/js/ui/invoices.js
@@ -535,6 +535,12 @@ var body_moneda = {cols: [
]}
+var body_divisas = {cols: [
+ {view: 'radio', id: 'opt_divisas', name: 'opt_divisas',
+ options: ['Ninguna', 'Compra', 'Venta']},
+]}
+
+
var body_regimen_fiscal = {
view: 'richselect',
id: 'lst_regimen_fiscal',
@@ -593,6 +599,7 @@ var controls_generate = [
{view: 'fieldset', label: 'Comprobante', body: body_comprobante},
{view: 'fieldset', label: 'Opciones de Pago', body: body_opciones},
{view: 'fieldset', id: 'fs_moneda', label: 'Moneda', body: body_moneda},
+ {view: 'fieldset', id: 'fs_divisas', label: 'Divisas - Tipo de OperaciĆ³n', body: body_divisas},
{view: 'fieldset', id: 'fs_regimen_fiscal', label: 'Regimen Fiscal',
body: body_regimen_fiscal},
]}
diff --git a/source/xslt/cadena.xslt b/source/xslt/cadena.xslt
index 81d45ac..4c6e2d5 100644
--- a/source/xslt/cadena.xslt
+++ b/source/xslt/cadena.xslt
@@ -13,9 +13,10 @@
+
+
+
+
+
+
+
+
+
+
+
+