Add support for Comercio Exterior 2.0
This commit is contained in:
commit
f0c4423fc8
|
@ -1,3 +1,9 @@
|
|||
v 2.2.0 [24-Ene-2024]
|
||||
- Mejora: Soporte para complemento Comercio Exterior 2.0
|
||||
- **IMPORTANTE**: Aunque no lo uses, esto afecta al JS de facturación, por
|
||||
lo que tienes que forzar el refresco (CTRL+F5) si tienes algún problema.
|
||||
|
||||
|
||||
v 2.1.0 [26-Dic-2023]
|
||||
- Mejora: Se agrega filtro por día en facturas.
|
||||
|
||||
|
|
|
@ -117,10 +117,10 @@ SAT = {
|
|||
'schema': ' http://www.sat.gob.mx/CartaPorte20 http://www.sat.gob.mx/sitio_internet/cfd/CartaPorte/CartaPorte20.xsd',
|
||||
},
|
||||
'comercioe': {
|
||||
'version': '1.1',
|
||||
'prefix': 'cce11',
|
||||
'xmlns': 'http://www.sat.gob.mx/ComercioExterior11',
|
||||
'schema': ' http://www.sat.gob.mx/ComercioExterior11 http://www.sat.gob.mx/sitio_internet/cfd/ComercioExterior11/ComercioExterior11.xsd',
|
||||
'version': '2.0',
|
||||
'prefix': 'cce20',
|
||||
'xmlns': 'http://www.sat.gob.mx/ComercioExterior20',
|
||||
'schema': ' http://www.sat.gob.mx/ComercioExterior20 http://www.sat.gob.mx/sitio_internet/cfd/ComercioExterior20/ComercioExterior20.xsd',
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,6 +144,7 @@ class CFDI(object):
|
|||
self._comercio_exterior = False
|
||||
self._divisas = ''
|
||||
self._tipo_de_comprobante = ''
|
||||
self._exportacion = DEFAULT['exportacion']
|
||||
self.error = ''
|
||||
|
||||
def _now(self):
|
||||
|
@ -168,7 +169,9 @@ class CFDI(object):
|
|||
if 'nomina' in datos:
|
||||
self._nomina(datos['nomina'])
|
||||
|
||||
return self._to_pretty_xml(ET.tostring(self._cfdi, encoding='utf-8'))
|
||||
xml = self._to_pretty_xml(ET.tostring(self._cfdi, encoding='utf-8'))
|
||||
|
||||
return xml
|
||||
|
||||
def add_sello(self, sello, cert_txt):
|
||||
self._cfdi.attrib['Sello'] = sello
|
||||
|
@ -198,6 +201,8 @@ class CFDI(object):
|
|||
self._leyendas = bool(datos['complementos'].get('leyendas', False))
|
||||
self._carta_porte = bool(datos['complementos'].get('cartaporte', False))
|
||||
self._comercio_exterior = bool(datos['complementos'].get('comercioe', False))
|
||||
if self._comercio_exterior:
|
||||
self._exportacion = datos['complementos']['comercioe'].pop('Exportacion')
|
||||
|
||||
self._divisas = datos['comprobante'].pop('divisas', '')
|
||||
|
||||
|
@ -288,7 +293,7 @@ class CFDI(object):
|
|||
|
||||
# ~ cfdi4
|
||||
if not 'Exportacion' in attributes:
|
||||
attributes['Exportacion'] = DEFAULT['exportacion']
|
||||
attributes['Exportacion'] = self._exportacion
|
||||
|
||||
self._tipo_de_comprobante = attributes['TipoDeComprobante']
|
||||
|
||||
|
@ -515,6 +520,47 @@ class CFDI(object):
|
|||
|
||||
return
|
||||
|
||||
def _complemento_comercio_exterior(self, datos):
|
||||
prefix = SAT['comercioe']['prefix']
|
||||
|
||||
emisor = datos.pop('emisor')
|
||||
propietarios = datos.pop('propietarios', {})
|
||||
receptor = datos.pop('receptor')
|
||||
destinatario = datos.pop('destinatario', {})
|
||||
mercancias = datos.pop('mercancias')
|
||||
|
||||
attr = {'Version': SAT['comercioe']['version']}
|
||||
attr.update(datos)
|
||||
ce = ET.SubElement(
|
||||
self._complemento, f'{prefix}:ComercioExterior', attr)
|
||||
|
||||
attributes = {}
|
||||
if 'Curp' in emisor:
|
||||
attributes = {'Curp': emisor.pop('Curp')}
|
||||
node = ET.SubElement(ce, '{}:Emisor'.format(prefix), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(prefix), emisor)
|
||||
|
||||
attributes = {}
|
||||
if 'NumRegIdTrib' in receptor:
|
||||
attributes = {'NumRegIdTrib': receptor.pop('NumRegIdTrib')}
|
||||
node = ET.SubElement(ce, '{}:Receptor'.format(prefix), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(prefix), receptor)
|
||||
|
||||
node = ET.SubElement(ce, '{}:Mercancias'.format(prefix))
|
||||
fields = ('Marca', 'Modelo', 'SubModelo', 'NumeroSerie')
|
||||
for row in mercancias:
|
||||
detalle = {}
|
||||
for f in fields:
|
||||
if f in row and row[f]:
|
||||
detalle[f] = row[f]
|
||||
row.pop(f)
|
||||
concepto = ET.SubElement(node, '{}:Mercancia'.format(prefix), row)
|
||||
if detalle:
|
||||
ET.SubElement(
|
||||
concepto, '{}:DescripcionesEspecificas'.format(prefix), detalle)
|
||||
|
||||
return
|
||||
|
||||
def _complementos(self, datos):
|
||||
if not datos:
|
||||
return
|
||||
|
@ -639,58 +685,7 @@ class CFDI(object):
|
|||
ET.SubElement(node_leyend, '{}:Leyenda'.format(pre), leyend)
|
||||
|
||||
if self._comercio_exterior:
|
||||
prefix = SAT['comercioe']['prefix']
|
||||
datos = datos.pop('comercioe')
|
||||
emisor = datos.pop('emisor')
|
||||
# ~ propietario = datos.pop('propietario')
|
||||
receptor = datos.pop('receptor')
|
||||
destinatario = datos.pop('destinatario')
|
||||
conceptos = datos.pop('mercancias')
|
||||
self._complemento_comercio_exterior(datos)
|
||||
|
||||
# ~ attributes = {}
|
||||
# ~ attributes['xmlns:{}'.format(pre)] = \
|
||||
# ~ 'http://www.sat.gob.mx/ComercioExterior11'
|
||||
# ~ attributes['xsi:schemaLocation'] = \
|
||||
# ~ 'http://www.sat.gob.mx/ComercioExterior11 ' \
|
||||
# ~ 'http://www.sat.gob.mx/sitio_internet/cfd/ComercioExterior11/ComercioExterior11.xsd'
|
||||
|
||||
attr = {'Version': SAT['comercioe']['version']}
|
||||
attr.update(datos)
|
||||
ce = ET.SubElement(
|
||||
self._complemento, f'{prefix}:ComercioExterior', attr)
|
||||
|
||||
attributes = {}
|
||||
if 'Curp' in emisor:
|
||||
attributes = {'Curp': emisor.pop('Curp')}
|
||||
node = ET.SubElement(ce, '{}:Emisor'.format(prefix), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(prefix), emisor)
|
||||
|
||||
# ~ if propietario:
|
||||
# ~ ET.SubElement(ce, '{}:Propietario'.format(prefix), propietario)
|
||||
|
||||
attributes = {}
|
||||
if 'NumRegIdTrib' in receptor:
|
||||
attributes = {'NumRegIdTrib': receptor.pop('NumRegIdTrib')}
|
||||
node = ET.SubElement(ce, '{}:Receptor'.format(prefix), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(prefix), receptor)
|
||||
|
||||
attributes = {}
|
||||
if 'NumRegIdTrib' in destinatario:
|
||||
attributes = {'NumRegIdTrib': destinatario.pop('NumRegIdTrib')}
|
||||
if 'Nombre' in destinatario:
|
||||
attributes.update({'Nombre': destinatario.pop('Nombre')})
|
||||
node = ET.SubElement(ce, '{}:Destinatario'.format(prefix), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(prefix), destinatario)
|
||||
|
||||
node = ET.SubElement(ce, '{}:Mercancias'.format(prefix))
|
||||
fields = ('Marca', 'Modelo', 'SubModelo', 'NumeroSerie')
|
||||
for row in conceptos:
|
||||
detalle = {}
|
||||
for f in fields:
|
||||
if f in row:
|
||||
detalle[f] = row.pop(f)
|
||||
concepto = ET.SubElement(node, '{}:Mercancia'.format(prefix), row)
|
||||
if detalle:
|
||||
ET.SubElement(
|
||||
concepto, '{}:DescripcionesEspecificas'.format(prefix), detalle)
|
||||
return
|
||||
|
|
|
@ -1022,6 +1022,51 @@ class LIBO(object):
|
|||
|
||||
return
|
||||
|
||||
def _comercio_exterior(self, data):
|
||||
if not data:
|
||||
return
|
||||
|
||||
emisor = data.pop('emisor')
|
||||
receptor = data.pop('receptor')
|
||||
mercancias = data.pop('mercancias')
|
||||
|
||||
for k, v in data.items():
|
||||
self._set_cell(f'{{cce.{k}}}', v)
|
||||
for k, v in emisor.items():
|
||||
self._set_cell(f'{{cce.emisor.{k}}}', v)
|
||||
for k, v in receptor.items():
|
||||
self._set_cell(f'{{cce.receptor.{k}}}', v)
|
||||
|
||||
first = True
|
||||
count = len(mercancias) - 1
|
||||
for i, mercancia in enumerate(mercancias):
|
||||
no_identificacion = mercancia['NoIdentificacion']
|
||||
fraccion = mercancia['FraccionArancelaria']
|
||||
unidad = mercancia['UnidadAduana']
|
||||
cantidad = mercancia['CantidadAduana']
|
||||
valor_unitario = mercancia['ValorUnitarioAduana']
|
||||
valor_dolares = mercancia['ValorDolares']
|
||||
if first:
|
||||
first = False
|
||||
cell_1 = self._set_cell('{cce.mercancia.noidentificacion}', no_identificacion)
|
||||
cell_2 = self._set_cell('{cce.mercancia.fraccionarancelaria}', fraccion)
|
||||
cell_3 = self._set_cell('{cce.mercancia.unidadaduana}', unidad)
|
||||
cell_4 = self._set_cell('{cce.mercancia.cantidadaduana}', cantidad)
|
||||
cell_5 = self._set_cell('{cce.mercancia.valorunitarioaduana}', valor_unitario)
|
||||
cell_6 = self._set_cell('{cce.mercancia.valordolares}', valor_dolares)
|
||||
if count > 0:
|
||||
row = cell_1.CellAddress.Row + 1
|
||||
self._sheet.getRows().insertByIndex(row, count)
|
||||
self._copy_paste_rows(cell_1, count)
|
||||
else:
|
||||
cell_1 = self._set_cell(v=no_identificacion, cell=cell_1)
|
||||
cell_2 = self._set_cell(v=fraccion, cell=cell_2)
|
||||
cell_3 = self._set_cell(v=unidad, cell=cell_3)
|
||||
cell_4 = self._set_cell(v=cantidad, cell=cell_4)
|
||||
cell_5 = self._set_cell(v=valor_unitario, cell=cell_5)
|
||||
cell_6 = self._set_cell(v=valor_dolares, cell=cell_6)
|
||||
return
|
||||
|
||||
def _nomina(self, data):
|
||||
if not data:
|
||||
return
|
||||
|
@ -1258,6 +1303,7 @@ class LIBO(object):
|
|||
self._divisas(data.get('divisas', {}))
|
||||
self._leyendas(data.get('leyendas', ''))
|
||||
self._carta_porte(data.get('carta_porte', {}))
|
||||
self._comercio_exterior(data.get('comercio_exterior', {}))
|
||||
|
||||
self._timbre(data['timbre'])
|
||||
|
||||
|
@ -1571,6 +1617,59 @@ class LIBO(object):
|
|||
rows = tuple(data[1:])
|
||||
return rows, ''
|
||||
|
||||
def _data_to_dict(self, rows):
|
||||
data = {k: v for k, v in rows if v}
|
||||
return data
|
||||
|
||||
def _current_region_to_tuple(self, cursor):
|
||||
data = []
|
||||
cursor.collapseToCurrentRegion()
|
||||
rows = cursor.getDataArray()[1:]
|
||||
|
||||
if len(rows) == 1:
|
||||
return data
|
||||
|
||||
keys = rows[0]
|
||||
data = [dict(zip(keys, values)) for values in rows[1:]]
|
||||
return data
|
||||
|
||||
def _get_data_ce(self, doc):
|
||||
msg = ''
|
||||
data = {}
|
||||
try:
|
||||
sheet = doc.Sheets[0]
|
||||
rango = sheet['A2:B10']
|
||||
data = self._data_to_dict(rango.DataArray)
|
||||
rango = sheet['A13:B23']
|
||||
data['emisor'] = self._data_to_dict(rango.DataArray)
|
||||
rango = sheet['A26:B36']
|
||||
data['receptor'] = self._data_to_dict(rango.DataArray)
|
||||
rango = sheet['A39:B50']
|
||||
data['destinatario'] = self._data_to_dict(rango.DataArray)
|
||||
cursor = sheet.createCursorByRange(sheet['E12'])
|
||||
data['propietarios'] = self._current_region_to_tuple(cursor)
|
||||
cursor = sheet.createCursorByRange(sheet['A53'])
|
||||
data['mercancias'] = self._current_region_to_tuple(cursor)
|
||||
except Exception as e:
|
||||
msg = str(e)
|
||||
|
||||
return data, msg
|
||||
|
||||
def get_ce(self, path):
|
||||
options = {'AsTemplate': True, 'Hidden': True}
|
||||
doc = self._doc_open(path, options)
|
||||
if doc is None:
|
||||
return (), 'No se pudo abrir la plantilla'
|
||||
|
||||
data, msg = self._get_data_ce(doc)
|
||||
doc.close(True)
|
||||
|
||||
if len(data) == 1:
|
||||
msg = 'Sin datos para importar'
|
||||
return (), msg
|
||||
|
||||
return data, ''
|
||||
|
||||
|
||||
def to_pdf(data, emisor_rfc, ods=False, pdf_from='1'):
|
||||
rfc = data['emisor']['rfc']
|
||||
|
@ -1602,8 +1701,13 @@ def to_pdf(data, emisor_rfc, ods=False, pdf_from='1'):
|
|||
default = f'plantilla_donatarias_{version}_{version_donatarias}.ods'
|
||||
version = f'{version}_cd_{version_donatarias}'
|
||||
|
||||
if 'comercio_exterior' in data:
|
||||
version_cce = data['comercio_exterior']['version']
|
||||
default = f'plantilla_cce_{version}_{version_cce}.ods'
|
||||
version = f'{version}_cce_{version_cce}'
|
||||
|
||||
template_name = f'{rfc.lower()}_{version}.ods'
|
||||
# ~ print('T', template_name, default)
|
||||
# ~ print('\nT', template_name, default)
|
||||
|
||||
if APP_LIBO:
|
||||
app = LIBO()
|
||||
|
@ -2317,6 +2421,7 @@ def upload_file(rfc, opt, file_obj):
|
|||
'_4.0_cp_2.0.ods',
|
||||
'_4.0_ccp_2.0.ods',
|
||||
'_4.0_cd_1.1.ods',
|
||||
'_4.0_cce_2.0.ods',
|
||||
'_4.0.json',
|
||||
)
|
||||
if opt in versions:
|
||||
|
@ -2438,6 +2543,15 @@ def upload_file(rfc, opt, file_obj):
|
|||
|
||||
name = '{}_nomina.ods'.format(rfc.lower())
|
||||
path = _join(PATH_MEDIA, 'tmp', name)
|
||||
elif opt == 'ceods':
|
||||
tmp = file_obj.filename.split('.')
|
||||
ext = tmp[-1].lower()
|
||||
if ext != 'ods':
|
||||
msg = 'Extensión de archivo incorrecta, selecciona un archivo ODS'
|
||||
return {'status': 'server', 'name': msg, 'ok': False}
|
||||
|
||||
name = '{}_ce.ods'.format(rfc.lower())
|
||||
path = _join(PATH_MEDIA, 'tmp', name)
|
||||
|
||||
if save_file(path, file_obj.file.read()):
|
||||
return {'status': 'server', 'name': file_obj.filename, 'ok': True}
|
||||
|
@ -2915,6 +3029,20 @@ def import_invoice(rfc):
|
|||
return (), 'No se encontro LibreOffice'
|
||||
|
||||
|
||||
def import_ceods(rfc):
|
||||
name = '{}_ce.ods'.format(rfc.lower())
|
||||
path = _join(PATH_MEDIA, 'tmp', name)
|
||||
if not is_file(path):
|
||||
return (), 'No se encontró la plantilla'
|
||||
|
||||
if APP_LIBO:
|
||||
app = LIBO()
|
||||
if app.is_running:
|
||||
return app.get_ce(path)
|
||||
|
||||
return (), 'No se encontro LibreOffice'
|
||||
|
||||
|
||||
def calc_to_date(value):
|
||||
return datetime.date.fromordinal(int(value) + 693594)
|
||||
|
||||
|
|
|
@ -265,6 +265,7 @@ class CfdiToDict(object):
|
|||
'leyendasFisc': 'http://www.sat.gob.mx/leyendasFiscales',
|
||||
'cartaporte20': 'http://www.sat.gob.mx/CartaPorte20',
|
||||
'nomina12': 'http://www.sat.gob.mx/nomina12',
|
||||
'cce20': 'http://www.sat.gob.mx/ComercioExterior20',
|
||||
}
|
||||
tipo_figura = {
|
||||
'01': '[01] Operador',
|
||||
|
@ -513,6 +514,29 @@ class CfdiToDict(object):
|
|||
|
||||
self._values['carta_porte'] = values
|
||||
|
||||
self._complemento_comercio_exterior(complemento)
|
||||
|
||||
return
|
||||
|
||||
def _complemento_comercio_exterior(self, complemento):
|
||||
path = '//cce20:ComercioExterior'
|
||||
comercio_exterior = complemento.xpath(path, namespaces=self.NS)
|
||||
|
||||
if comercio_exterior:
|
||||
values = CaseInsensitiveDict(comercio_exterior[0].attrib)
|
||||
|
||||
for node in comercio_exterior[0]:
|
||||
if 'Emisor' in node.tag:
|
||||
values['emisor'] = CaseInsensitiveDict(node.attrib)
|
||||
values['emisor'].update(CaseInsensitiveDict(node[0].attrib))
|
||||
elif 'Receptor' in node.tag:
|
||||
values['receptor'] = CaseInsensitiveDict(node.attrib)
|
||||
values['receptor'].update(CaseInsensitiveDict(node[0].attrib))
|
||||
elif 'Mercancias' in node.tag:
|
||||
mercancias = [
|
||||
CaseInsensitiveDict(m.attrib) for m in node]
|
||||
values['mercancias'] = mercancias
|
||||
self._values['comercio_exterior'] = values
|
||||
return
|
||||
|
||||
|
||||
|
@ -861,9 +885,6 @@ def get_cert(args):
|
|||
|
||||
def make_xml(data, certificado):
|
||||
cert = SATCertificate(certificado.cer, certificado.key_enc.encode())
|
||||
# ~ if DEBUG:
|
||||
# ~ data['emisor']['Rfc'] = certificado.rfc
|
||||
# ~ data['emisor']['RegimenFiscal'] = '603'
|
||||
|
||||
cfdi = CFDI()
|
||||
xml = ET.parse(BytesIO(cfdi.get_xml(data).encode()))
|
||||
|
@ -1087,6 +1108,7 @@ def _save_template(rfc, name, file_obj):
|
|||
|
||||
rfc = rfc.lower()
|
||||
path = _join(PATHS['USER'], f'{rfc}{name}')
|
||||
|
||||
if save_file(path, file_obj.file.read()):
|
||||
result['ok'] = True
|
||||
|
||||
|
|
|
@ -70,6 +70,9 @@ class StorageEngine(object):
|
|||
def _get_importinvoice(self, values):
|
||||
return main.import_invoice()
|
||||
|
||||
def _get_importceods(self, values):
|
||||
return main.import_ceods()
|
||||
|
||||
def _get_main(self, values, session):
|
||||
return main.config_main(session['userobj'])
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ def upload_file(rfc, opt, file_obj):
|
|||
|
||||
result = util.upload_file(rfc, opt, file_obj)
|
||||
if result['ok']:
|
||||
names = ('bdfl', 'employees', 'nomina', 'products', 'invoiceods')
|
||||
names = ('bdfl', 'employees', 'nomina', 'products', 'invoiceods', 'ceods')
|
||||
if not opt in names:
|
||||
Configuracion.add({opt: file_obj.filename})
|
||||
return result
|
||||
|
@ -268,6 +268,18 @@ def import_invoice():
|
|||
return {'ok': True, 'rows': tuple(products)}
|
||||
|
||||
|
||||
def import_ceods():
|
||||
log.info('Importando plantilla...')
|
||||
emisor = Emisor.select()[0]
|
||||
data, msg = util.import_ceods(emisor.rfc)
|
||||
|
||||
if not data:
|
||||
return {'ok': False, 'msg': msg}
|
||||
|
||||
log.info('Plantilla importada...')
|
||||
return {'ok': True, 'data': data}
|
||||
|
||||
|
||||
def get_doc(type_doc, id, rfc):
|
||||
types = {
|
||||
'xml': 'application/xml',
|
||||
|
@ -5611,12 +5623,9 @@ class Facturas(BaseModel):
|
|||
if not valores:
|
||||
return
|
||||
|
||||
# ~ values = utils.loads(valores)
|
||||
|
||||
data = {
|
||||
'factura': invoice,
|
||||
'nombre': 'comercioe',
|
||||
# ~ 'valores': utils.dumps(values),
|
||||
'valores': valores,
|
||||
}
|
||||
FacturasComplementos.create(**data)
|
||||
|
|
|
@ -39,7 +39,7 @@ except ImportError:
|
|||
|
||||
|
||||
DEBUG = DEBUG
|
||||
VERSION = '2.1.0'
|
||||
VERSION = '2.2.0'
|
||||
|
||||
EMAIL_SUPPORT = ('soporte@empresalibre.mx',)
|
||||
TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION)
|
||||
|
|
|
@ -22,7 +22,7 @@ var tipo_relacion = ''
|
|||
var anticipo = false
|
||||
var donativo = false
|
||||
var cfg_invoice = new Object()
|
||||
var values_comercioe = null
|
||||
//~ var values_comercioe = null
|
||||
var values_global = ''
|
||||
|
||||
|
||||
|
@ -102,7 +102,15 @@ var invoices_controllers = {
|
|||
$$('cmd_carta_add_product').attachEvent('onItemClick', cmd_carta_add_product_click)
|
||||
$$('cmd_carta_copy_from_invoice').attachEvent('onItemClick', cmd_carta_copy_from_invoice_click)
|
||||
$$('cmd_carta_import_json').attachEvent('onItemClick', cmd_carta_import_json_click)
|
||||
|
||||
$$('cmd_import_json_comercioe').attachEvent('onItemClick', cmd_import_json_comercioe_click)
|
||||
$$('cmd_ce_import_ods').attachEvent('onItemClick', cmd_ce_import_ods_click)
|
||||
$$('cmd_ce_tipo_cambio').attachEvent('onItemClick', cmd_ce_tipo_cambio_click)
|
||||
$$('cmd_ce_add_propietario').attachEvent('onItemClick', cmd_ce_add_propietario_click)
|
||||
$$('cmd_ce_add_mercancia').attachEvent('onItemClick', cmd_ce_add_mercancia_click)
|
||||
$$('grid_ce_propietarios').attachEvent('onItemClick', grid_ce_propietarios_click)
|
||||
$$('grid_ce_mercancias').attachEvent('onItemClick', grid_ce_mercancias_click)
|
||||
|
||||
$$('cmd_show_global_information').attachEvent('onItemClick', cmd_show_global_information_click)
|
||||
|
||||
webix.extend($$('grid_invoices'), webix.ProgressBar)
|
||||
|
@ -239,6 +247,7 @@ function default_config(){
|
|||
$$('tv_invoice').getTabbar().hideOption('Comercio Exterior')
|
||||
}else{
|
||||
$$('tv_invoice').getTabbar().showOption('Comercio Exterior')
|
||||
_set_default_comercio_exterior()
|
||||
}
|
||||
cfg_invoice['leyendasfiscales'] = values.cfdi_leyendasfiscales
|
||||
cfg_invoice['edu'] = values.cfdi_edu
|
||||
|
@ -574,6 +583,12 @@ function validate_invoice(values){
|
|||
}
|
||||
}
|
||||
|
||||
//~ validate comercio exterior
|
||||
var usar_comercioe = $$('chk_cfdi_usar_comercioe').getValue()
|
||||
if(usar_comercioe){
|
||||
var values = _get_values_comercio_exterior()
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -848,14 +863,14 @@ function guardar_y_timbrar(values){
|
|||
|
||||
var usar_comercioe = $$('chk_cfdi_usar_comercioe').getValue()
|
||||
if(usar_comercioe){
|
||||
data['comercioe'] = values_comercioe
|
||||
data['comercioe'] = _get_values_comercio_exterior()
|
||||
}
|
||||
|
||||
if(!save_invoice(data)){
|
||||
return
|
||||
}
|
||||
|
||||
values_comercioe = null
|
||||
//~ values_comercioe = null
|
||||
values_global = ''
|
||||
$$('chk_cfdi_usar_comercioe').setValue(false)
|
||||
|
||||
|
@ -907,16 +922,11 @@ function cmd_timbrar_click(id, e, node){
|
|||
|
||||
usar_ine = $$('chk_cfdi_usar_ine').getValue()
|
||||
if(usar_ine){
|
||||
msg += 'Estas usando el complemento INE<BR><BR>'
|
||||
msg += 'Estas usando el complemento: INE<BR><BR>'
|
||||
}
|
||||
|
||||
if($$('chk_cfdi_usar_comercioe').getValue()){
|
||||
msg += 'Estas usando el complemento Comercio Exterior<BR><BR>'
|
||||
if(values_comercioe === null){
|
||||
msg = 'El complemento de Comercio Exterior esta vacío'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
msg += 'Estas usando el complemento:<BR>Comercio Exterior<BR><BR>'
|
||||
}
|
||||
|
||||
if(tipo_comprobante == 'T'){
|
||||
|
@ -2952,9 +2962,54 @@ function up_invoice_json_on_after_file_add(obj){
|
|||
}
|
||||
|
||||
|
||||
function _set_from_json_comercioe(data){
|
||||
function _set_default_comercio_exterior(){
|
||||
const controls = {
|
||||
lst_ce_exportacion: '02',
|
||||
lst_ce_motivo_traslado: '',
|
||||
lst_ce_clave_pedimento: 'A1',
|
||||
lst_ce_certificado_origen: '0',
|
||||
txt_ce_numero_certificado: '',
|
||||
txt_ce_numero_exportador: '',
|
||||
lst_ce_incoterm: 'CFR',
|
||||
txt_ce_observaciones: '',
|
||||
txt_ce_tipo_cambio_usd: '',
|
||||
txt_ce_total_usd: '',
|
||||
};
|
||||
|
||||
Object.keys(controls).forEach(key => {
|
||||
$$(key).setValue(controls[key])
|
||||
});
|
||||
|
||||
var grid = $$('grid_ce_emisor')
|
||||
grid.clearAll()
|
||||
grid.add({id: 0})
|
||||
|
||||
var grid = $$('grid_ce_receptor')
|
||||
grid.clearAll()
|
||||
grid.add({id: 0})
|
||||
|
||||
var grid = $$('grid_ce_destinatario')
|
||||
grid.clearAll()
|
||||
grid.add({id: 0})
|
||||
|
||||
var grid = $$('grid_ce_propietarios')
|
||||
grid.clearAll()
|
||||
|
||||
var grid = $$('grid_ce_mercancias')
|
||||
grid.clearAll()
|
||||
}
|
||||
|
||||
|
||||
function _set_from_json_comercioe(data, json){
|
||||
|
||||
_set_default_comercio_exterior()
|
||||
|
||||
try{
|
||||
values_comercioe = JSON.parse(data)
|
||||
if(json){
|
||||
values = JSON.parse(data)
|
||||
}else{
|
||||
values = data
|
||||
}
|
||||
}catch(e){
|
||||
msg_error('Revisa el archivo JSON')
|
||||
webix.alert({
|
||||
|
@ -2964,6 +3019,66 @@ function _set_from_json_comercioe(data){
|
|||
})
|
||||
return
|
||||
}
|
||||
|
||||
const controls = {
|
||||
Exportacion: 'lst_ce_exportacion',
|
||||
MotivoTraslado: 'lst_ce_motivo_traslado',
|
||||
ClaveDePedimento: 'lst_ce_clave_pedimento',
|
||||
CertificadoOrigen: 'lst_ce_certificado_origen',
|
||||
NumCertificadoOrigen: 'txt_ce_numero_certificado',
|
||||
NumeroExportadorConfiable: 'txt_ce_numero_exportador',
|
||||
Incoterm: 'lst_ce_incoterm',
|
||||
Observaciones: 'txt_ce_observaciones',
|
||||
TipoCambioUSD: 'txt_ce_tipo_cambio_usd',
|
||||
TotalUSD: 'txt_ce_total_usd',
|
||||
};
|
||||
|
||||
Object.keys(controls).forEach(key => {
|
||||
if(key in values){
|
||||
$$(controls[key]).setValue(values[key])
|
||||
}
|
||||
});
|
||||
|
||||
var grid = $$('grid_ce_emisor')
|
||||
grid.clearAll()
|
||||
if ('emisor' in values) {
|
||||
grid.add(values['emisor'])
|
||||
} else {
|
||||
grid.add({id: 0})
|
||||
}
|
||||
|
||||
var grid = $$('grid_ce_receptor')
|
||||
grid.clearAll()
|
||||
if ('receptor' in values) {
|
||||
grid.add(values['receptor'])
|
||||
} else {
|
||||
grid.add({id: 0})
|
||||
}
|
||||
|
||||
var grid = $$('grid_ce_destinatario')
|
||||
grid.clearAll()
|
||||
if ('destinatario' in values) {
|
||||
grid.add(values['destinatario'])
|
||||
} else {
|
||||
grid.add({id: 0})
|
||||
}
|
||||
|
||||
var grid = $$('grid_ce_propietarios')
|
||||
grid.clearAll()
|
||||
if ('propietarios' in values) {
|
||||
values['propietarios'].forEach(function(row, index){
|
||||
row['delete'] = '-'
|
||||
grid.add(row)
|
||||
})
|
||||
}
|
||||
|
||||
var grid = $$('grid_ce_mercancias')
|
||||
grid.clearAll()
|
||||
values['mercancias'].forEach(function(row, index){
|
||||
row['delete'] = '-'
|
||||
grid.add(row)
|
||||
})
|
||||
|
||||
msg = 'Valores cargados correctamente'
|
||||
msg_ok(msg)
|
||||
}
|
||||
|
@ -2979,7 +3094,7 @@ function up_invoice_json_comercioe_on_after_file_add(obj){
|
|||
let reader = new FileReader()
|
||||
reader.readAsText(obj.file)
|
||||
reader.onload = function(){
|
||||
_set_from_json_comercioe(reader.result)
|
||||
_set_from_json_comercioe(reader.result, true)
|
||||
}
|
||||
$$('win_import_json_comercioe').close()
|
||||
}
|
||||
|
@ -3000,3 +3115,175 @@ function cmd_save_global_information_click(){
|
|||
function cmd_win_global_close_click(){
|
||||
$$('win_global_information').close()
|
||||
}
|
||||
|
||||
|
||||
function cmd_ce_tipo_cambio_click(){
|
||||
window.open('https://www.banxico.org.mx/tipcamb/tipCamMIAction.do?idioma=sp', '_blank')
|
||||
}
|
||||
|
||||
|
||||
function cmd_ce_add_propietario_click(){
|
||||
var g = $$('grid_ce_propietarios')
|
||||
g.add({delete: '-'})
|
||||
}
|
||||
|
||||
|
||||
function grid_ce_propietarios_click(id, e, node){
|
||||
if(id.column != 'delete'){
|
||||
return
|
||||
}
|
||||
this.remove(id.row)
|
||||
}
|
||||
|
||||
|
||||
function cmd_ce_add_mercancia_click(){
|
||||
var g = $$('grid_ce_mercancias')
|
||||
g.add({delete: '-'})
|
||||
}
|
||||
|
||||
|
||||
function grid_ce_mercancias_click(id, e, node){
|
||||
if(id.column != 'delete'){
|
||||
return
|
||||
}
|
||||
this.remove(id.row)
|
||||
}
|
||||
|
||||
|
||||
|
||||
function _get_values_comercio_exterior(){
|
||||
var form = $$('form_comercio_exterior')
|
||||
|
||||
if(!form.validate()) {
|
||||
msg_error('Valores inválidos en Comercio Exterior')
|
||||
return
|
||||
}
|
||||
|
||||
const controls = {
|
||||
Exportacion: 'lst_ce_exportacion',
|
||||
MotivoTraslado: 'lst_ce_motivo_traslado',
|
||||
ClaveDePedimento: 'lst_ce_clave_pedimento',
|
||||
CertificadoOrigen: 'lst_ce_certificado_origen',
|
||||
NumCertificadoOrigen: 'txt_ce_numero_certificado',
|
||||
NumeroExportadorConfiable: 'txt_ce_numero_exportador',
|
||||
Incoterm: 'lst_ce_incoterm',
|
||||
Observaciones: 'txt_ce_observaciones',
|
||||
TipoCambioUSD: 'txt_ce_tipo_cambio_usd',
|
||||
TotalUSD: 'txt_ce_total_usd',
|
||||
};
|
||||
|
||||
var values = new Object()
|
||||
|
||||
Object.keys(controls).forEach(key => {
|
||||
var value = $$(controls[key]).getValue().trim()
|
||||
if(value){
|
||||
values[key] = value
|
||||
}
|
||||
});
|
||||
|
||||
var propietarios = $$('grid_ce_propietarios').data.getRange()
|
||||
propietarios.forEach(function(row, index){
|
||||
delete row['id']
|
||||
delete row['delete']
|
||||
})
|
||||
|
||||
var mercancias = $$('grid_ce_mercancias').data.getRange()
|
||||
mercancias.forEach(function(row, index){
|
||||
delete row['id']
|
||||
delete row['delete']
|
||||
})
|
||||
|
||||
var emisor = $$('grid_ce_emisor').data.getRange()[0]
|
||||
delete emisor['id']
|
||||
|
||||
var receptor = $$('grid_ce_receptor').data.getRange()[0]
|
||||
delete receptor['id']
|
||||
|
||||
var destinatario = $$('grid_ce_destinatario').data.getRange()[0]
|
||||
delete destinatario['id']
|
||||
|
||||
values['emisor'] = emisor
|
||||
values['propietarios'] = propietarios
|
||||
values['receptor'] = receptor
|
||||
values['destinatario'] = destinatario
|
||||
values['mercancias'] = mercancias
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
|
||||
function cmd_ce_import_ods_click(){
|
||||
win_ce_import_ods.init()
|
||||
$$('win_ce_import_ods').show()
|
||||
}
|
||||
|
||||
|
||||
function cmd_ce_upload_ods_click(){
|
||||
var form = $$('form_ce_import_ods')
|
||||
|
||||
var values = form.getValues()
|
||||
|
||||
if(!$$('lst_ce_up_template').count()){
|
||||
$$('win_ce_import_ods').close()
|
||||
return
|
||||
}
|
||||
|
||||
if($$('lst_ce_up_template').count() > 1){
|
||||
msg = 'Selecciona solo un archivo'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
var template = $$('ce_up_template').files.getItem($$('ce_up_template').files.getFirstId())
|
||||
|
||||
if(template.type.toLowerCase() != 'ods'){
|
||||
msg = 'Archivo inválido.\n\nSe requiere un archivo ODS'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de importar este archivo?'
|
||||
webix.confirm({
|
||||
title: 'Importar datos de plantilla',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
$$('ce_up_template').send()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function ce_up_template_complete(response){
|
||||
if(response.status != 'server'){
|
||||
msg = 'Ocurrio un error al subir el archivo'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
msg = 'Archivo subido correctamente.\n\nComenzando importación.'
|
||||
msg_ok(msg)
|
||||
$$('win_ce_import_ods').close()
|
||||
|
||||
webix.ajax().get('/values/importceods', {
|
||||
error: function(text, data, xhr) {
|
||||
msg_error('Error al consultar')
|
||||
},
|
||||
success: function(text, data, xhr){
|
||||
var values = data.json()
|
||||
if (values.ok){
|
||||
_set_from_json_comercioe(values.data, false)
|
||||
//~ msg_ok('Plantilla importada correctamente...')
|
||||
}else{
|
||||
webix.alert({
|
||||
title: 'Error al importar',
|
||||
text: values.msg,
|
||||
type: 'alert-error',
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
|
@ -605,6 +605,7 @@ var opt_templates_cfdi = [
|
|||
{id: '_4.0_cp_2.0.ods', value: 'CFDI v4.0 - Pagos v2.0'},
|
||||
{id: '_4.0_ccp_2.0.ods', value: 'CFDI v4.0 - Carta Porte v2.0'},
|
||||
{id: '_4.0_cd_1.1.ods', value: 'CFDI v4.0 - Donativos v1.1'},
|
||||
{id: '_4.0_cce_2.0.ods', value: 'CFDI v4.0 - Comercio Exterior v2.0'},
|
||||
{id: '_4.0.json', value: 'CFDI v4.0 - JSON'},
|
||||
{id: '_3.3.ods', value: 'CFDI v3.3'},
|
||||
{id: '_3.3_cn_1.2.ods', value: 'CFDI v3.3 - Nómina v1.2'},
|
||||
|
|
|
@ -1210,13 +1210,268 @@ var controls_carta_porte = [
|
|||
]
|
||||
|
||||
|
||||
var opt_ce_exportacion = [
|
||||
{id: '02', value: '[02] Definitiva con clave A1'},
|
||||
{id: '03', value: '[03] Temporal'},
|
||||
{id: '04', value: '[04] Definitiva con clave distinta a A1'},
|
||||
]
|
||||
|
||||
|
||||
var opt_ce_motivo_traslado = [
|
||||
{id: '', value: ''},
|
||||
{id: '01', value: '[01] Envío de mercancias facturadas con anterioridad'},
|
||||
{id: '02', value: '[02] Reubicación de mercancías propias'},
|
||||
{id: '03', value: '[03] Envío de mercancías objeto de contrato de consignación'},
|
||||
{id: '04', value: '[04] Envío de mercancías para posterior enajenación'},
|
||||
{id: '05', value: '[05] Envío de mercancías propiedad de terceros'},
|
||||
{id: '99', value: '[99] Otros'},
|
||||
]
|
||||
|
||||
|
||||
var opt_ce_clave_pedimento = [
|
||||
{id: 'A1', value: '[A1] Definitiva'},
|
||||
]
|
||||
|
||||
|
||||
var opt_ce_certificado_origen = [
|
||||
{id: '0', value: '[0] No funge'},
|
||||
{id: '1', value: '[1] Funge'},
|
||||
]
|
||||
|
||||
|
||||
var opt_ce_incoterm = [
|
||||
{id: 'CFR', value: '[CFR] Coste y flete (puerto de destino convenido)'},
|
||||
{id: 'CIF', value: '[CIF] Coste, seguro y flete (puerto de destino convenido)'},
|
||||
{id: 'CPT', value: '[CPT] Trasnporte pagado hasta el lugar de destino convenido'},
|
||||
{id: 'CIP', value: '[CIP] Trasnporte y seguro pagado hasta el lugar de destino convenido'},
|
||||
{id: 'DAP', value: '[DAP] Entregada en lugar'},
|
||||
{id: 'DDP', value: '[DDP] Entregada derechos pagados en lugar de destino convenido'},
|
||||
{id: 'DPU', value: '[DPU] Entregada y descargada en lugar acordado'},
|
||||
{id: 'EXW', value: '[EXW] En fábrica (lugar convenido)'},
|
||||
{id: 'FCA', value: '[FCA] Franco transportista (lugar designado)'},
|
||||
{id: 'FAS', value: '[FAS] Franco al costado del buque (puerto de carga convenido)'},
|
||||
{id: 'FOB', value: '[FOB] Franco a bordo (puerto de carga convenido)'},
|
||||
]
|
||||
|
||||
|
||||
var body_ce_datos_generales = {rows:[
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'richselect', id: 'lst_ce_exportacion', label: 'Exportación: ',
|
||||
value: '02', labelWidth: 130, minWidth: 400, options: opt_ce_exportacion},
|
||||
{view: 'richselect', id: 'lst_ce_motivo_traslado', label: 'Motivo Traslado: ',
|
||||
labelWidth: 130, minWidth: 500, options: opt_ce_motivo_traslado},
|
||||
{},
|
||||
{maxWidth: 15}]},
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'richselect', id: 'lst_ce_clave_pedimento', label: 'Clave de Pedimento: ',
|
||||
value: 'A1', labelWidth: 130, minWidth: 400, maxWidth: 400, options: opt_ce_clave_pedimento},
|
||||
{view: 'richselect', id: 'lst_ce_certificado_origen', label: 'Certificado Origen: ',
|
||||
value: '0', labelWidth: 130, maxWidth: 300, options: opt_ce_certificado_origen},
|
||||
{view: 'text', id: 'txt_ce_numero_certificado', label: 'Nº Certificado:', labelWidth: 100},
|
||||
{maxWidth: 15}]},
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'text', id: 'txt_ce_numero_exportador', label: 'Nº Exportador: ',
|
||||
labelWidth: 130, minWidth: 400, maxWidth: 500},
|
||||
{view: 'richselect', id: 'lst_ce_incoterm', label: 'Incoterm: ', value: 'CFR',
|
||||
labelWidth: 130, minWidth: 500, maxWidth: 500, options: opt_ce_incoterm},
|
||||
{view: 'text', id: 'txt_ce_observaciones', label: 'Observaciones:', labelWidth: 100},
|
||||
{maxWidth: 15}]},
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'text', id: 'txt_ce_total_usd', label: 'Total USD: ',
|
||||
labelWidth: 130, minWidth: 400, inputAlign: 'right'},
|
||||
{view: 'text', id: 'txt_ce_tipo_cambio_usd', label: 'Tipo Cambio USD:', labelWidth: 130,
|
||||
inputAlign: 'right'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_ce_tipo_cambio', label: 'TC Banxico',
|
||||
type: 'iconButton', autowidth: true, icon: ''},
|
||||
{maxWidth: 15}]},
|
||||
]}
|
||||
|
||||
|
||||
var grid_cols_ce_emisor = [
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'Curp', header: 'Curp', editor: 'text', fillspace: 1},
|
||||
{id: 'Calle', header: 'Calle *', editor: 'text', fillspace: 1},
|
||||
{id: 'NumeroExterior', header: 'Numero Exterior', editor: 'text', fillspace: 1},
|
||||
{id: 'NumeroInterior', header: 'Número Interior', editor: 'text', fillspace: 1},
|
||||
{id: 'Colonia', header: 'Colonia', editor: 'text', fillspace: 1},
|
||||
{id: 'Municipio', header: 'Municipio', editor: 'text', fillspace: 1},
|
||||
{id: 'Estado', header: 'Estado *', editor: 'text', fillspace: 1},
|
||||
{id: 'Pais', header: 'País *', editor: 'text', fillspace: 1},
|
||||
{id: 'CodigoPostal', header: 'C.P. *', editor: 'text', fillspace: 1},
|
||||
]
|
||||
|
||||
|
||||
var grid_ce_emisor = {
|
||||
view: 'datatable',
|
||||
id: 'grid_ce_emisor',
|
||||
multiselect: false,
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
headermenu: true,
|
||||
editable: true,
|
||||
columns: grid_cols_ce_emisor,
|
||||
data: [{id: 0}],
|
||||
}
|
||||
|
||||
var body_ce_emisor = {rows:[
|
||||
grid_ce_emisor
|
||||
]}
|
||||
|
||||
|
||||
var grid_cols_ce_propietarios = [
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'delete', header: '', width: 30, css: 'delete'},
|
||||
{id: 'NumRegIdTrib', header: 'Registro Fiscal', editor: 'text', fillspace: 1},
|
||||
{id: 'ResidenciaFiscal', header: 'Residencia Fiscal', editor: 'text', fillspace: 1},
|
||||
]
|
||||
|
||||
|
||||
var grid_ce_propietarios = {
|
||||
view: 'datatable',
|
||||
id: 'grid_ce_propietarios',
|
||||
multiselect: false,
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
headermenu: true,
|
||||
editable: true,
|
||||
footer: false,
|
||||
columns: grid_cols_ce_propietarios,
|
||||
}
|
||||
|
||||
|
||||
var body_ce_propietarios = {rows:[
|
||||
{cols: [
|
||||
{view: 'button', id: 'cmd_ce_add_propietario', label: 'Agregar Propietario',
|
||||
icon: 'plus', type: 'iconButton', autowidth: true, align: 'center'},
|
||||
{},
|
||||
]},
|
||||
{maxHeight: 10},
|
||||
grid_ce_propietarios
|
||||
]}
|
||||
|
||||
|
||||
var grid_cols_ce_receptor = [
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'NumRegIdTrib', header: 'Registro Fiscal', editor: 'text', fillspace: 1},
|
||||
{id: 'Calle', header: 'Calle *', editor: 'text', fillspace: 1},
|
||||
{id: 'NumeroExterior', header: 'Numero Exterior', editor: 'text', fillspace: 1},
|
||||
{id: 'NumeroInterior', header: 'Número Interior', editor: 'text', fillspace: 1},
|
||||
{id: 'Colonia', header: 'Colonia', editor: 'text', fillspace: 1},
|
||||
{id: 'Municipio', header: 'Municipio', editor: 'text', fillspace: 1},
|
||||
{id: 'Estado', header: 'Estado *', editor: 'text', fillspace: 1},
|
||||
{id: 'Pais', header: 'País *', editor: 'text', fillspace: 1},
|
||||
{id: 'CodigoPostal', header: 'C.P. *', editor: 'text', fillspace: 1},
|
||||
]
|
||||
|
||||
|
||||
var grid_ce_receptor = {
|
||||
view: 'datatable',
|
||||
id: 'grid_ce_receptor',
|
||||
multiselect: false,
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
headermenu: true,
|
||||
editable: true,
|
||||
columns: grid_cols_ce_receptor,
|
||||
data: [{id: 0}],
|
||||
}
|
||||
|
||||
|
||||
var body_ce_receptor = {rows:[
|
||||
grid_ce_receptor
|
||||
]}
|
||||
|
||||
|
||||
var grid_cols_ce_destinatario = [
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'NumRegIdTrib', header: 'Registro Fiscal', editor: 'text', fillspace: 1},
|
||||
{id: 'Nombre', header: 'Nombre', editor: 'text', fillspace: 1},
|
||||
{id: 'Calle', header: 'Calle *', editor: 'text', fillspace: 1},
|
||||
{id: 'NumeroExterior', header: 'No Exterior', editor: 'text', fillspace: 1},
|
||||
{id: 'NumeroInterior', header: 'No Interior', editor: 'text', fillspace: 1},
|
||||
{id: 'Colonia', header: 'Colonia', editor: 'text', fillspace: 1},
|
||||
{id: 'Municipio', header: 'Municipio', editor: 'text', fillspace: 1},
|
||||
{id: 'Estado', header: 'Estado *', editor: 'text', fillspace: 1},
|
||||
{id: 'Pais', header: 'País *', editor: 'text', fillspace: 1},
|
||||
{id: 'CodigoPostal', header: 'C.P. *', editor: 'text', fillspace: 1},
|
||||
]
|
||||
|
||||
|
||||
var grid_ce_destinatario = {
|
||||
view: 'datatable',
|
||||
id: 'grid_ce_destinatario',
|
||||
multiselect: false,
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
headermenu: true,
|
||||
editable: true,
|
||||
columns: grid_cols_ce_destinatario,
|
||||
data: [{id: 0}],
|
||||
}
|
||||
|
||||
|
||||
var body_ce_destinatario = {rows:[
|
||||
grid_ce_destinatario
|
||||
]}
|
||||
|
||||
|
||||
var grid_cols_ce_mercancias = [
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'delete', header: '', width: 30, css: 'delete'},
|
||||
{id: 'NoIdentificacion', header: 'Clave', editor: 'text', fillspace: 1},
|
||||
{id: 'FraccionArancelaria', header: 'Fraccion Arancelaria', editor: 'text', fillspace: 1},
|
||||
{id: 'CantidadAduana', header: 'Cantidad Aduana', editor: 'text', fillspace: 1},
|
||||
{id: 'UnidadAduana', header: 'Unidad Aduana', editor: 'text', fillspace: 1},
|
||||
{id: 'ValorUnitarioAduana', header: 'PU Aduana', editor: 'text', fillspace: 1},
|
||||
{id: 'ValorDolares', header: 'Valor USD', editor: 'text', fillspace: 1},
|
||||
{id: 'Marca', header: 'Marca', editor: 'text', hidden: true, fillspace: 1},
|
||||
{id: 'Modelo', header: 'Modelo', editor: 'text', hidden: true, fillspace: 1},
|
||||
{id: 'SubModelo', header: 'SubModelo', editor: 'text', hidden: true, fillspace: 1},
|
||||
{id: 'NumeroSerie', header: 'Serie', editor: 'text', hidden: true, fillspace: 1},
|
||||
]
|
||||
|
||||
|
||||
var grid_ce_mercancias = {
|
||||
view: 'datatable',
|
||||
id: 'grid_ce_mercancias',
|
||||
multiselect: false,
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
headermenu: true,
|
||||
editable: true,
|
||||
footer: true,
|
||||
columns: grid_cols_ce_mercancias,
|
||||
}
|
||||
|
||||
|
||||
var body_ce_mercancias = {rows:[
|
||||
{cols: [
|
||||
{view: 'button', id: 'cmd_ce_add_mercancia', label: 'Agregar Mercancía',
|
||||
icon: 'plus', type: 'iconButton', autowidth: true, align: 'center'},
|
||||
{},
|
||||
]},
|
||||
{maxHeight: 10},
|
||||
grid_ce_mercancias
|
||||
]}
|
||||
|
||||
|
||||
var controls_comercio_exterior = [
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'checkbox', id: 'chk_cfdi_usar_comercioe', labelWidth: 0,
|
||||
labelRight: 'Usar el complemento Comercio Exterior'}, {},
|
||||
labelRight: 'Usar el complemento Comercio Exterior'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_import_json_comercioe', label: 'Importar JSON',
|
||||
icon: 'upload', type: 'iconButton', autowidth: true, align: 'center'},
|
||||
{maxWidth: 15}]}
|
||||
{view: 'button', id: 'cmd_ce_import_ods', label: 'Importar ODS',
|
||||
icon: 'upload', type: 'iconButton', autowidth: true, align: 'center'},
|
||||
{maxWidth: 15}]},
|
||||
{view: 'fieldset', label: 'Datos generales', body: body_ce_datos_generales},
|
||||
{view: 'fieldset', label: 'Emisor', body: body_ce_emisor},
|
||||
{view: 'fieldset', label: 'Propietario', body: body_ce_propietarios},
|
||||
{view: 'fieldset', label: 'Receptor', body: body_ce_receptor},
|
||||
{view: 'fieldset', label: 'Destinatario', body: body_ce_destinatario},
|
||||
{view: 'fieldset', label: 'Mercancías', body: body_ce_mercancias},
|
||||
]
|
||||
|
||||
|
||||
|
@ -1324,7 +1579,13 @@ var win_import_invoice = {
|
|||
width: 400,
|
||||
modal: true,
|
||||
position: 'center',
|
||||
head: 'Importar Factura de Plantilla',
|
||||
head: {view: 'toolbar',
|
||||
elements: [
|
||||
{view: 'label', label: 'Importar Factura en Lote'},
|
||||
{view: 'icon', icon: 'times-circle',
|
||||
click: '$$("win_import_invoice").close()'},
|
||||
]
|
||||
},
|
||||
body: body_upload_invoice,
|
||||
})
|
||||
$$('cmd_upload_invoice').attachEvent('onItemClick', cmd_upload_invoice_click)
|
||||
|
@ -1473,3 +1734,41 @@ var win_global_information = {
|
|||
$$('cmd_win_global_close').attachEvent('onItemClick', cmd_win_global_close_click)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var body_win_ce_import_ods = {rows: [
|
||||
{view: 'form', id: 'form_ce_import_ods', rows: [
|
||||
{cols: [{},
|
||||
{view: 'uploader', id: 'ce_up_template', autosend: false,
|
||||
link: 'lst_ce_up_template', value: 'Seleccionar Archivo',
|
||||
upload: '/files/ceods'}, {}]},
|
||||
{cols: [
|
||||
{view: 'list', id: 'lst_ce_up_template',
|
||||
type: 'uploader', autoheight: true, borderless: true}]},
|
||||
{cols: [{}, {view: 'button', id: 'cmd_ce_upload_ods',
|
||||
label: 'Importar Plantilla'}, {}]},
|
||||
]},
|
||||
]}
|
||||
|
||||
|
||||
var win_ce_import_ods = {
|
||||
init: function(){
|
||||
webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_ce_import_ods',
|
||||
width: 400,
|
||||
modal: true,
|
||||
position: 'center',
|
||||
head: {view: 'toolbar',
|
||||
elements: [
|
||||
{view: 'label', label: 'Importar desde archivo ODS'},
|
||||
{view: 'icon', icon: 'times-circle',
|
||||
click: '$$("win_ce_import_ods").close()'},
|
||||
]
|
||||
},
|
||||
body: body_win_ce_import_ods,
|
||||
})
|
||||
$$('cmd_ce_upload_ods').attachEvent('onItemClick', cmd_ce_upload_ods_click)
|
||||
$$('ce_up_template').attachEvent('onUploadComplete', ce_up_template_complete)
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -11,7 +11,7 @@
|
|||
<xsl:include href="iedu.xslt"/>
|
||||
<xsl:include href="leyendasFisc.xslt"/>
|
||||
<xsl:include href="cartaporte20.xslt"/>
|
||||
<xsl:include href="comercioexterior11.xslt"/>
|
||||
<xsl:include href="comercioexterior20.xslt"/>
|
||||
<xsl:include href="donat11.xslt"/>
|
||||
<xsl:include href="pagos20.xslt"/>
|
||||
<xsl:include href="implocal.xslt"/>
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
<?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:cce20="http://www.sat.gob.mx/ComercioExterior20">
|
||||
|
||||
<xsl:template match="cce20:ComercioExterior">
|
||||
<!--Manejador de nodos tipo ComercioExterior-->
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@Version" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@MotivoTraslado" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@ClaveDePedimento" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@CertificadoOrigen" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@NumCertificadoOrigen" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@NumeroExportadorConfiable" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@Incoterm" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@Observaciones" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@TipoCambioUSD" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@TotalUSD" />
|
||||
</xsl:call-template>
|
||||
|
||||
<!-- Iniciamos el manejo de los elementos hijo en la secuencia -->
|
||||
<xsl:apply-templates select="./cce20:Emisor" />
|
||||
<xsl:apply-templates select="./cce20:Receptor" />
|
||||
<xsl:for-each select="./cce20:Destinatario">
|
||||
<xsl:apply-templates select="."/>
|
||||
</xsl:for-each>
|
||||
<xsl:apply-templates select="./cce20:Mercancias" />
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="cce20:Emisor">
|
||||
<!-- Iniciamos el tratamiento de los atributos de cce20:Emisor-->
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@Curp" />
|
||||
</xsl:call-template>
|
||||
|
||||
<xsl:apply-templates select="./cce20:Domicilio" />
|
||||
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="cce20:Propietario">
|
||||
<!-- Iniciamos el tratamiento de los atributos de cce20:Propietario-->
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@NumRegIdTrib" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@ResidenciaFiscal" />
|
||||
</xsl:call-template>
|
||||
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="cce20:Receptor">
|
||||
<!-- Tratamiento de los atributos de cce20:Receptor-->
|
||||
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@NumRegIdTrib" />
|
||||
</xsl:call-template>
|
||||
<xsl:apply-templates select="./cce20:Domicilio" />
|
||||
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="cce20:Destinatario">
|
||||
<!-- Tratamiento de los atributos de cce20:Destinatario-->
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@NumRegIdTrib" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@Nombre" />
|
||||
</xsl:call-template>
|
||||
<!-- Manejo de los nodos dependientes -->
|
||||
<xsl:for-each select="./cce20:Domicilio">
|
||||
<xsl:apply-templates select="."/>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="cce20:Mercancias">
|
||||
<!-- Iniciamos el manejo de los nodos dependientes -->
|
||||
<xsl:for-each select="./cce20:Mercancia">
|
||||
<xsl:apply-templates select="."/>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="cce20:Domicilio">
|
||||
<!-- Iniciamos el tratamiento de los atributos de cce20:Domicilio-->
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@Calle" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@NumeroExterior" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@NumeroInterior" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@Colonia" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@Localidad" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@Referencia" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@Municipio" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@Estado" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@Pais" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@CodigoPostal" />
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="cce20:Mercancia">
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@NoIdentificacion" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@FraccionArancelaria" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@CantidadAduana" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@UnidadAduana" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@ValorUnitarioAduana" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@ValorDolares" />
|
||||
</xsl:call-template>
|
||||
<xsl:for-each select="./cce20:DescripcionesEspecificas">
|
||||
<xsl:apply-templates select="."/>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="cce20:DescripcionesEspecificas">
|
||||
<xsl:call-template name="Requerido">
|
||||
<xsl:with-param name="valor" select="./@Marca" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@Modelo" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@SubModelo" />
|
||||
</xsl:call-template>
|
||||
<xsl:call-template name="Opcional">
|
||||
<xsl:with-param name="valor" select="./@NumeroSerie" />
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
Loading…
Reference in New Issue