Soporte basico para complemento Comercio Exterior
This commit is contained in:
commit
de856f28ab
|
@ -1,3 +1,8 @@
|
|||
v 1.47.0 [28-Mar-2022]
|
||||
----------------------
|
||||
- Mejora: Soporte basico para complemento Comercio Exterior.
|
||||
|
||||
|
||||
v 1.46.5 [10-Mar-2022]
|
||||
----------------------
|
||||
- Error: Al timbrar nómina con Comercio Digital
|
||||
|
|
|
@ -102,6 +102,12 @@ SAT = {
|
|||
'prefix': 'cartaporte20',
|
||||
'xmlns': 'http://www.sat.gob.mx/CartaPorte20',
|
||||
'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',
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,6 +128,7 @@ class CFDI(object):
|
|||
self._is_nomina = False
|
||||
self._leyendas = False
|
||||
self._carta_porte = False
|
||||
self._comercio_exterior = False
|
||||
self._divisas = ''
|
||||
self.error = ''
|
||||
|
||||
|
@ -174,6 +181,7 @@ class CFDI(object):
|
|||
self._pagos = bool(datos['complementos'].get('pagos', False))
|
||||
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))
|
||||
|
||||
self._divisas = datos['comprobante'].pop('divisas', '')
|
||||
|
||||
|
@ -245,10 +253,16 @@ class CFDI(object):
|
|||
attributes[name] = SAT['cartaporte']['xmlns']
|
||||
schema_carta_porte = SAT['cartaporte']['schema']
|
||||
|
||||
schema_comercioe = ''
|
||||
if self._comercio_exterior:
|
||||
name = 'xmlns:{}'.format(SAT['comercioe']['prefix'])
|
||||
attributes[name] = SAT['comercioe']['xmlns']
|
||||
schema_carta_porte = SAT['comercioe']['schema']
|
||||
|
||||
attributes['xsi:schemaLocation'] = self._sat_cfdi['schema'] + \
|
||||
schema_locales + schema_donativo + schema_ine + schema_edu + \
|
||||
schema_divisas + schema_nomina + schema_pagos + schema_leyendas + \
|
||||
schema_carta_porte
|
||||
schema_carta_porte + schema_comercioe
|
||||
attributes.update(datos)
|
||||
|
||||
if not 'Version' in attributes:
|
||||
|
@ -556,57 +570,59 @@ class CFDI(object):
|
|||
for leyend in datos['leyendas']:
|
||||
ET.SubElement(node_leyend, '{}:Leyenda'.format(pre), leyend)
|
||||
|
||||
if 'ce' in datos:
|
||||
pre = 'cce11'
|
||||
datos = datos.pop('ce')
|
||||
if self._comercio_exterior:
|
||||
prefix = SAT['comercioe']['prefix']
|
||||
datos = datos.pop('comercioe')
|
||||
emisor = datos.pop('emisor')
|
||||
propietario = datos.pop('propietario')
|
||||
# ~ propietario = datos.pop('propietario')
|
||||
receptor = datos.pop('receptor')
|
||||
destinatario = datos.pop('destinatario')
|
||||
conceptos = datos.pop('conceptos')
|
||||
conceptos = datos.pop('mercancias')
|
||||
|
||||
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'
|
||||
attributes.update(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(
|
||||
complemento, '{}:ComercioExterior'.format(pre), attributes)
|
||||
self._complemento, f'{prefix}:ComercioExterior', attr)
|
||||
|
||||
attributes = {}
|
||||
if 'Curp' in emisor:
|
||||
attributes = {'Curp': emisor.pop('Curp')}
|
||||
node = ET.SubElement(ce, '{}:Emisor'.format(pre), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(pre), emisor)
|
||||
node = ET.SubElement(ce, '{}:Emisor'.format(prefix), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(prefix), emisor)
|
||||
|
||||
if propietario:
|
||||
ET.SubElement(ce, '{}:Propietario'.format(pre), propietario)
|
||||
# ~ 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(pre), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(pre), receptor)
|
||||
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(pre), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(pre), destinatario)
|
||||
node = ET.SubElement(ce, '{}:Destinatario'.format(prefix), attributes)
|
||||
ET.SubElement(node, '{}:Domicilio'.format(prefix), destinatario)
|
||||
|
||||
node = ET.SubElement(ce, '{}:Mercancias'.format(pre))
|
||||
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(pre), row)
|
||||
concepto = ET.SubElement(node, '{}:Mercancia'.format(prefix), row)
|
||||
if detalle:
|
||||
ET.SubElement(
|
||||
concepto, '{}:DescripcionesEspecificas'.format(pre), detalle)
|
||||
concepto, '{}:DescripcionesEspecificas'.format(prefix), detalle)
|
||||
return
|
||||
|
|
|
@ -344,6 +344,7 @@ def config_timbrar():
|
|||
'cfdi_ine': Configuracion.get_bool('chk_config_ine'),
|
||||
'cfdi_edu': Configuracion.get_bool('chk_config_edu'),
|
||||
'cfdi_carta_porte': Configuracion.get_bool('chk_config_carta_porte'),
|
||||
'cfdi_comercioe': Configuracion.get_bool('chk_config_comercio_exterior'),
|
||||
'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'),
|
||||
|
@ -482,6 +483,7 @@ class Configuracion(BaseModel):
|
|||
'chk_config_ine',
|
||||
'chk_config_edu',
|
||||
'chk_config_carta_porte',
|
||||
'chk_config_comercio_exterior',
|
||||
'chk_config_pagos',
|
||||
'chk_config_divisas',
|
||||
'chk_cfg_pays_data_bank',
|
||||
|
@ -5398,6 +5400,21 @@ class Facturas(BaseModel):
|
|||
FacturasComplementos.create(**data)
|
||||
return
|
||||
|
||||
def _save_comercioe(self, invoice, valores):
|
||||
if not valores:
|
||||
return
|
||||
|
||||
# ~ values = utils.loads(valores)
|
||||
|
||||
data = {
|
||||
'factura': invoice,
|
||||
'nombre': 'comercioe',
|
||||
# ~ 'valores': utils.dumps(values),
|
||||
'valores': valores,
|
||||
}
|
||||
FacturasComplementos.create(**data)
|
||||
return
|
||||
|
||||
def _get_serie(self, user, default_serie):
|
||||
if user.sucursal is None:
|
||||
return default_serie
|
||||
|
@ -5410,6 +5427,7 @@ class Facturas(BaseModel):
|
|||
relacionados = util.loads(values.pop('relacionados'))
|
||||
ine = values.pop('ine', {})
|
||||
cartaporte = values.pop('cartaporte', {})
|
||||
comercioe = values.pop('comercioe', {})
|
||||
tipo_comprobante = values['tipo_comprobante']
|
||||
folio_custom = values.pop('folio_custom', '')
|
||||
divisas = values.pop('divisas', '')
|
||||
|
@ -5453,6 +5471,7 @@ class Facturas(BaseModel):
|
|||
cls._guardar_relacionados(cls, obj, relacionados)
|
||||
cls._guardar_ine(cls, obj, ine)
|
||||
cls._save_cartaporte(cls, obj, cartaporte)
|
||||
cls._save_comercioe(cls, obj, comercioe)
|
||||
cls._save_leyendas_fiscales(cls, obj, leyendas_fiscales)
|
||||
obj.subtotal = totals['subtotal']
|
||||
obj.descuento = totals['descuento']
|
||||
|
@ -11480,4 +11499,3 @@ if __name__ == '__main__':
|
|||
args = _process_command_line_arguments()
|
||||
main(args)
|
||||
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ except ImportError:
|
|||
|
||||
|
||||
DEBUG = DEBUG
|
||||
VERSION = '1.46.5'
|
||||
VERSION = '1.47.0'
|
||||
EMAIL_SUPPORT = ('soporte@empresalibre.mx',)
|
||||
TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION)
|
||||
|
||||
|
|
|
@ -115,6 +115,7 @@ var controllers = {
|
|||
$$('chk_config_ine').attachEvent('onItemClick', chk_config_item_click)
|
||||
$$('chk_config_edu').attachEvent('onItemClick', chk_config_item_click)
|
||||
$$('chk_config_carta_porte').attachEvent('onItemClick', chk_config_item_click)
|
||||
$$('chk_config_comercio_exterior').attachEvent('onItemClick', chk_config_item_click)
|
||||
|
||||
$$('chk_config_leyendas_fiscales').attachEvent('onItemClick', chk_config_item_click)
|
||||
$$('cmd_admin_leyendas_fiscales').attachEvent('onItemClick', cmd_admin_leyendas_fiscales_click)
|
||||
|
|
|
@ -22,6 +22,7 @@ var tipo_relacion = ''
|
|||
var anticipo = false
|
||||
var donativo = false
|
||||
var cfg_invoice = new Object()
|
||||
var values_comercioe = null
|
||||
|
||||
|
||||
function init_config_invoices(){
|
||||
|
@ -94,6 +95,7 @@ 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)
|
||||
|
||||
webix.extend($$('grid_invoices'), webix.ProgressBar)
|
||||
|
||||
|
@ -224,12 +226,17 @@ function default_config(){
|
|||
if(!values.cfdi_carta_porte){
|
||||
$$('tv_invoice').getTabbar().hideOption('Carta Porte')
|
||||
}else{
|
||||
get_leyendas_fiscales()
|
||||
$$('tv_invoice').getTabbar().showOption('Carta Porte')
|
||||
}
|
||||
if(!values.cfdi_comercioe){
|
||||
$$('tv_invoice').getTabbar().hideOption('Comercio Exterior')
|
||||
}else{
|
||||
$$('tv_invoice').getTabbar().showOption('Comercio Exterior')
|
||||
}
|
||||
cfg_invoice['leyendasfiscales'] = values.cfdi_leyendasfiscales
|
||||
cfg_invoice['edu'] = values.cfdi_edu
|
||||
cfg_invoice['carta_porte'] = values.cfdi_carta_porte
|
||||
cfg_invoice['comercioe'] = values.cfdi_comercioe
|
||||
cfg_invoice['open_pdf'] = values.cfdi_open_pdf
|
||||
cfg_invoice['tax_locales'] = values.cfdi_tax_locales
|
||||
cfg_invoice['tax_decimals'] = values.cfdi_tax_decimals
|
||||
|
@ -769,10 +776,18 @@ function guardar_y_timbrar(values){
|
|||
data['cartaporte'] = cartaporte
|
||||
}
|
||||
|
||||
var usar_comercioe = $$('chk_cfdi_usar_comercioe').getValue()
|
||||
if(usar_comercioe){
|
||||
data['comercioe'] = values_comercioe
|
||||
}
|
||||
|
||||
if(!save_invoice(data)){
|
||||
return
|
||||
}
|
||||
|
||||
values_comercioe = null
|
||||
$$('chk_cfdi_usar_comercioe').setValue(false)
|
||||
|
||||
table_relaciones.clear()
|
||||
tipo_relacion = ''
|
||||
anticipo = false
|
||||
|
@ -816,11 +831,21 @@ function cmd_timbrar_click(id, e, node){
|
|||
}
|
||||
msg += '<BR><BR>'
|
||||
}
|
||||
|
||||
usar_ine = $$('chk_cfdi_usar_ine').getValue()
|
||||
if(usar_ine){
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
if(tipo_comprobante == 'T'){
|
||||
msg += 'El Tipo de Comprobante es Traslado, el total será puesto a 0 (Cero), asegurate de que sea el tipo de comprobante correcto<BR><BR>'
|
||||
}
|
||||
|
@ -2815,3 +2840,36 @@ function up_invoice_json_on_after_file_add(obj){
|
|||
}
|
||||
$$('win_carta_import_json').close()
|
||||
}
|
||||
|
||||
|
||||
function _set_from_json_comercioe(data){
|
||||
try{
|
||||
values_comercioe = JSON.parse(data)
|
||||
}catch(e){
|
||||
msg_error('Revisa el archivo JSON')
|
||||
webix.alert({
|
||||
title: 'Error al cargar JSON',
|
||||
text: e.message,
|
||||
type: 'alert-error'
|
||||
})
|
||||
return
|
||||
}
|
||||
msg = 'Valores cargados correctamente'
|
||||
msg_ok(msg)
|
||||
}
|
||||
|
||||
|
||||
function cmd_import_json_comercioe_click(){
|
||||
win_import_json_comercioe.init()
|
||||
$$('win_import_json_comercioe').show()
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
}
|
||||
$$('win_import_json_comercioe').close()
|
||||
}
|
||||
|
|
|
@ -887,6 +887,11 @@ var options_admin_complements = [
|
|||
{view: 'checkbox', id: 'chk_config_carta_porte', labelWidth: 0,
|
||||
labelRight: 'Usar el complemento Carta Porte'},
|
||||
{maxWidth: 15}]},
|
||||
{template: 'Complemento para Comercio Exterior', type: 'section'},
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'checkbox', id: 'chk_config_comercio_exterior', labelWidth: 0,
|
||||
labelRight: 'Usar el complemento Comercio Exterior'},
|
||||
{maxWidth: 15}]},
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -1198,6 +1198,16 @@ var controls_carta_porte = [
|
|||
]
|
||||
|
||||
|
||||
var controls_comercio_exterior = [
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'checkbox', id: 'chk_cfdi_usar_comercioe', labelWidth: 0,
|
||||
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}]}
|
||||
]
|
||||
|
||||
|
||||
var form_carta_porte = {
|
||||
type: 'space',
|
||||
responsive: true,
|
||||
|
@ -1211,6 +1221,19 @@ var form_carta_porte = {
|
|||
}
|
||||
|
||||
|
||||
var form_comercio_exterior = {
|
||||
type: 'space',
|
||||
responsive: true,
|
||||
cols: [{
|
||||
view: 'form',
|
||||
id: 'form_comercio_exterior',
|
||||
complexData: true,
|
||||
scroll: true,
|
||||
elements: controls_comercio_exterior,
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
var controls_invoices = [
|
||||
{
|
||||
view: 'tabview',
|
||||
|
@ -1222,6 +1245,7 @@ var controls_invoices = [
|
|||
{id: 'INE', rows: controls_ine},
|
||||
{id: 'Leyendas Fiscales', rows: controls_leyendas_fiscales},
|
||||
{id: 'Carta Porte', rows: [form_carta_porte]},
|
||||
{id: 'Comercio Exterior', rows: [form_comercio_exterior]},
|
||||
]
|
||||
},
|
||||
]
|
||||
|
@ -1368,3 +1392,32 @@ var win_carta_import_json = {
|
|||
$$('up_invoice_json').attachEvent('onAfterFileAdd', up_invoice_json_on_after_file_add)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var body_upload_json_comercioe = {rows: [
|
||||
{view: 'form', id: 'form_upload_comercioe', rows: [
|
||||
{cols: [{},
|
||||
{view: 'uploader', id: 'up_invoice_json', autosend: false,
|
||||
link: 'lst_upload_invoice', value: 'Seleccionar Archivo',
|
||||
accept:'application/json', upload: ''}, {}]},
|
||||
{cols: [
|
||||
{view: 'list', id: 'lst_upload_invoice', name: 'lst_upload_invoice',
|
||||
type: 'uploader', autoheight: true, borderless: true}]},
|
||||
]},
|
||||
]}
|
||||
|
||||
|
||||
var win_import_json_comercioe = {
|
||||
init: function(){
|
||||
webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_import_json_comercioe',
|
||||
width: 400,
|
||||
modal: true,
|
||||
position: 'center',
|
||||
head: 'Importar Comerio Exterior JSON',
|
||||
body: body_upload_json_comercioe,
|
||||
})
|
||||
$$('up_invoice_json').attachEvent('onAfterFileAdd', up_invoice_json_comercioe_on_after_file_add)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue