diff --git a/CHANGELOG.md b/CHANGELOG.md index 16e58b1..07a7f66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +v 1.6.0 [18-feb-2018] +--------------------- + - Facturacion a extranjeros + +* IMPORTANTE: Es necesario realizar una migración, despues de actualizar la rama principal. + +``` +git pull origin master + +cd source/app/models + +python main.py -m +``` + v 1.5.0 [30-ene-2018] --------------------- - Timbrado de Nómina diff --git a/source/app/models/main.py b/source/app/models/main.py index edae9fa..cb19171 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -528,6 +528,29 @@ class Sucursales(BaseModel): order_by = ('nombre',) +class Roles(BaseModel): + nombre = TextField(default='') + + class Meta: + order_by = ('nombre',) + + +class Permisos(BaseModel): + rol = ForeignKeyField(Roles) + modulo = TextField(default='') + ver = BooleanField(default=False) + agregar = BooleanField(default=False) + editar = BooleanField(default=False) + eliminar = BooleanField(default=False) + especiales = TextField(default='') + + class Meta: + order_by = ('rol', 'modulo') + indexes = ( + (('rol', 'modulo'), True), + ) + + class Usuarios(BaseModel): usuario = TextField(unique=True) nombre = TextField(default='') @@ -540,6 +563,7 @@ class Usuarios(BaseModel): fecha_ingreso = DateTimeField(default=util.now) ultimo_ingreso = DateTimeField(null=True) sucursal = ForeignKeyField(Sucursales, null=True) + rol = ForeignKeyField(Roles, null=True) def __str__(self): t = '{} {} ({})' @@ -897,6 +921,7 @@ class Folios(BaseModel): inicio = IntegerField(default=1) default = BooleanField(default=False) usarcon = TextField(default='') + plantilla = TextField(default='') class Meta: order_by = ('-default', 'serie', 'inicio') @@ -2305,6 +2330,7 @@ class Addendas(BaseModel): class Socios(BaseModel): tipo_persona = IntegerField(default=1) rfc = TextField(index=True) + id_fiscal = TextField(default='') nombre = TextField(index=True) slug = TextField(default='') nombre_comercial = TextField(index=True, default='') @@ -2338,6 +2364,7 @@ class Socios(BaseModel): addenda = ForeignKeyField(Addendas, null=True) uso_cfdi = ForeignKeyField(SATUsoCfdi, null=True) tags = ManyToManyField(Tags, related_name='socios_tags') + plantilla = TextField(default='') def __str__(self): t = '{} ({})' @@ -2363,6 +2390,17 @@ class Socios(BaseModel): 'es_proveedor', 'es_ong') for name in fb: fields[name] = bool(fields[name].replace('0', '')) + + ft = ('nombre_comercial', 'calle', 'no_exterior', 'no_interior', + 'colonia', 'municipio', 'estado', 'pais', 'codigo_postal', 'notas', + 'telefonos', 'cuenta_cliente', 'cuenta_proveedor', 'web', + 'correo_facturas', 'plantilla', 'id_fiscal') + for name in ft: + fields[name] = values.get(name, '') + + if fields['pais'] != 'México': + fields['pais'] = fields['pais'].upper() + return fields @classmethod @@ -3831,6 +3869,11 @@ class Facturas(BaseModel): 'Nombre': invoice.cliente.nombre, 'UsoCFDI': invoice.uso_cfdi, } + if invoice.cliente.tipo_persona == 4: + if invoice.cliente.pais: + receptor['ResidenciaFiscal'] = invoice.cliente.pais + if invoice.cliente.id_fiscal: + receptor['NumRegIdTrib'] = invoice.cliente.id_fiscal conceptos = [] rows = FacturasDetalle.select().where(FacturasDetalle.factura==invoice) @@ -4782,6 +4825,7 @@ class PreFacturasDetalle(BaseModel): nivel = TextField(default='') autorizacion = TextField(default='') cuenta_predial = TextField(default='') + unidad = TextField(default='') class Meta: order_by = ('factura',) @@ -7057,7 +7101,7 @@ def _init_values(rfc): def _crear_tablas(rfc): tablas = [Addendas, Categorias, Certificado, CondicionesPago, Configuracion, - Folios, Registro, CamposPersonalizados, + Folios, Registro, CamposPersonalizados, Permisos, Emisor, Facturas, FacturasDetalle, FacturasImpuestos, FacturasPagos, FacturasRelacionadas, FacturasComplementos, FacturasPersonalizados, SeriesProductos, Almacenes, Productos, RangosPrecios, Sucursales, @@ -7071,7 +7115,7 @@ def _crear_tablas(rfc): SATTipoPercepcion, SATTipoRegimen, Socios, Contactos, ContactoCorreos, ContactoDirecciones, Empleados, ContactoTelefonos, Departamentos, Puestos, - Tags, Usuarios, CuentasBanco, TipoCambio, MovimientosBanco, + Tags, Roles, Usuarios, CuentasBanco, TipoCambio, MovimientosBanco, TipoCorreo, TipoDireccion, TipoPariente, TipoResponsable, TipoTelefono, TipoTitulo, TipoMovimientoAlumno, TipoMovimientoAlmacen, CfdiPagos, NivelesEducativos, Alumnos, AlumnosParientes, Grupos, @@ -7133,7 +7177,7 @@ def _migrate_tables(): CfdiNominaHorasExtra, CfdiNominaIncapacidad, CfdiNominaJubilacion, CfdiNominaOtroPago, CfdiNominaOtros, CfdiNominaPercepciones, CfdiNominaRelacionados, CfdiNominaSeparacion, CfdiNominaSubcontratos, - CfdiNominaTotales, SATNivelesEducativos + CfdiNominaTotales, SATNivelesEducativos, Roles, Permisos ] log.info('Creando tablas nuevas...') database_proxy.create_tables(tablas, True) @@ -7148,6 +7192,10 @@ def _migrate_tables(): sucursal = ForeignKeyField(Sucursales, null=True, to_field=Sucursales.id) migrations.append( migrator.add_column('usuarios', 'sucursal_id', sucursal)) + if not 'rol_id' in columns: + rol = ForeignKeyField(Roles, null=True, to_field=Roles.id) + migrations.append( + migrator.add_column('usuarios', 'rol_id', rol)) columns = [c.name for c in database_proxy.get_columns('emisor')] if not 'registro_patronal' in columns: @@ -7160,6 +7208,29 @@ def _migrate_tables(): migrations.append( migrator.add_column('emisor', 'curp', curp)) + columns = [c.name for c in database_proxy.get_columns('socios')] + if not 'id_fiscal' in columns: + id_fiscal = TextField(default='') + migrations.append( + migrator.add_column( + 'socios', 'id_fiscal', id_fiscal)) + if not 'plantilla' in columns: + plantilla = TextField(default='') + migrations.append( + migrator.add_column('socios', 'plantilla', plantilla)) + + columns = [c.name for c in database_proxy.get_columns('folios')] + if not 'plantilla' in columns: + plantilla = TextField(default='') + migrations.append( + migrator.add_column('folios', 'plantilla', plantilla)) + + columns = [c.name for c in database_proxy.get_columns('prefacturasdetalle')] + if not 'unidad' in columns: + unidad = TextField(default='') + migrations.append( + migrator.add_column('prefacturasdetalle', 'unidad', unidad)) + if migrations: with database_proxy.atomic() as txn: migrate(*migrations) diff --git a/source/db/valores_iniciales.json b/source/db/valores_iniciales.json index 5f21429..2067cd5 100644 --- a/source/db/valores_iniciales.json +++ b/source/db/valores_iniciales.json @@ -102,7 +102,7 @@ {"key": "610", "name": "Residentes en el Extranjero sin Establecimiento Permanente en México", "fisica": true, "moral": true, "activo": false}, {"key": "611", "name": "Ingresos por Dividendos (socios y accionistas)", "fisica": true, "activo": false}, {"key": "612", "name": "Personas Físicas con Actividades Empresariales y Profesionales", "fisica": true, "activo": true, "default": true}, - {"key": "614", "name": "Ingresos por intereses", "fisica": true, "activo": false}, + {"key": "614", "name": "Ingresos por intereses", "fisica": true, "activo": true}, {"key": "616", "name": "Sin obligaciones fiscales", "fisica": true, "activo": false}, {"key": "620", "name": "Sociedades Cooperativas de Producción que optan por diferir sus ingresos", "moral": true, "activo": false}, {"key": "621", "name": "Incorporación Fiscal", "fisica": true, "activo": true}, diff --git a/source/static/js/controller/partners.js b/source/static/js/controller/partners.js index 155ab7f..6a09c38 100644 --- a/source/static/js/controller/partners.js +++ b/source/static/js/controller/partners.js @@ -169,6 +169,14 @@ function cmd_save_partner_click(id, e, node){ return } + if(values.tipo_persona == 4){ + if(values.pais && values.pais.length != 3){ + msg = 'Longitud de país inválida' + msg_error(msg) + return + } + } + webix.ajax().post('/partners', values, { error:function(text, data, XmlHttpRequest){ msg = 'Ocurrio un error, consulta a soporte técnico'; @@ -268,20 +276,21 @@ function opt_tipo_change(new_value, old_value){ $$("nombre").define("value", "") $$("pais").define("readonly", true) $$("pais").define("value", PAIS) - + $$('id_fiscal').define('value', '') + show('id_fiscal', new_value == 4) if (new_value == 1 || new_value == 2){ - $$("rfc").define("value", ""); - $$("rfc").define("readonly", false); + $$("rfc").define("value", "") + $$("rfc").define("readonly", false) } else if (new_value == 3) { - $$("rfc").define("value", RFC_PUBLICO); - $$("nombre").define("value", PUBLICO); - $$("rfc").define("readonly", true); + $$("rfc").define("value", RFC_PUBLICO) + $$("nombre").define("value", PUBLICO) + $$("rfc").define("readonly", true) } else if (new_value == 4) { - $$("rfc").define("value", RFC_EXTRANJERO); - $$("rfc").define("readonly", true); - $$("pais").define("readonly", false); - $$("pais").define("value", ""); + $$("rfc").define("value", RFC_EXTRANJERO) + $$("rfc").define("readonly", true) + $$("pais").define("readonly", false) + $$("pais").define("value", "") } $$("nombre").refresh(); diff --git a/source/static/js/ui/partners.js b/source/static/js/ui/partners.js index a2572fe..efba303 100644 --- a/source/static/js/ui/partners.js +++ b/source/static/js/ui/partners.js @@ -69,7 +69,10 @@ var controls_fiscales = [ invalidMessage: 'El Tipo de Persona es requerido'}, {template: 'Dirección Fiscal', type: 'section'}, {cols: [{view: 'text', id: 'rfc', name: 'rfc', label: 'RFC: ', width: 300, - required: true, invalidMessage: 'RFC inválido', attributes: {maxlength: 13}},{}]}, + required: true, invalidMessage: 'RFC inválido', attributes: {maxlength: 13}}, + {view: 'text', id: 'id_fiscal', name: 'id_fiscal', label: 'ID Fiscal: ', + width: 400, required: false, attributes: {maxlength: 40}, hidden: true}, + {}]}, {view: 'text', id: 'nombre', name: 'nombre', label: 'Razón Social: ', required: true, invalidMessage: 'La Razón Social es requerida'}, {view: 'text', id: 'calle', name: 'calle', label: 'Calle: '}, @@ -82,8 +85,8 @@ var controls_fiscales = [ {view: 'text', id: 'colonia', name: 'colonia', label: 'Colonia: '}, {view: 'text', id: 'municipio', name: 'municipio', label: 'Municipio: '}, {view: 'text', id: 'estado', name: 'estado', label: 'Estado: '}, - {view: 'text', id: 'pais', name: 'pais', label: 'País: ', - value: 'México', readonly: true}, + {view: 'text', id: 'pais', name: 'pais', label: 'País: ', value: 'México', + readonly: true, placeholder: 'Usa solo tres letras de acuerdo al catalogo del SAT'}, {template: 'Condiciones Comerciales', type: 'section'}, {cols: [ {view: 'richselect', id: 'forma_pago', name: 'forma_pago', diff --git a/source/templates/plantilla_factura.ods b/source/templates/plantilla_factura.ods index c2c7afe..8061850 100644 Binary files a/source/templates/plantilla_factura.ods and b/source/templates/plantilla_factura.ods differ