Fix - Issue #188
This commit is contained in:
parent
9f6e9e36fe
commit
c45d95d762
|
@ -265,7 +265,7 @@ class CFDI(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
def _impuestos(self, datos):
|
def _impuestos(self, datos):
|
||||||
if self._is_nomina:
|
if self._is_nomina or not datos:
|
||||||
return
|
return
|
||||||
|
|
||||||
if not datos:
|
if not datos:
|
||||||
|
|
|
@ -1420,7 +1420,8 @@ def _comprobante(doc, options):
|
||||||
data['tipodecomprobante'] = tipos.get(data['tipodecomprobante'])
|
data['tipodecomprobante'] = tipos.get(data['tipodecomprobante'])
|
||||||
data['lugarexpedicion'] = \
|
data['lugarexpedicion'] = \
|
||||||
'C.P. de Expedición: {}'.format(data['lugarexpedicion'])
|
'C.P. de Expedición: {}'.format(data['lugarexpedicion'])
|
||||||
data['metododepago'] = options['metododepago']
|
if 'metododepago' in options:
|
||||||
|
data['metododepago'] = options['metododepago']
|
||||||
data['formadepago'] = options['formadepago']
|
data['formadepago'] = options['formadepago']
|
||||||
|
|
||||||
if 'condicionesdepago' in data:
|
if 'condicionesdepago' in data:
|
||||||
|
@ -2199,7 +2200,7 @@ def local_copy(files):
|
||||||
args = 'df -P {} | tail -1 | cut -d" " -f 1'.format(path_bk)
|
args = 'df -P {} | tail -1 | cut -d" " -f 1'.format(path_bk)
|
||||||
try:
|
try:
|
||||||
result = _call(args)
|
result = _call(args)
|
||||||
log.info(result)
|
# ~ log.info(result)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
# ~ if result != 'empresalibre\n':
|
# ~ if result != 'empresalibre\n':
|
||||||
|
|
|
@ -3235,8 +3235,9 @@ class Facturas(BaseModel):
|
||||||
'PUE': 'Pago en una sola exhibición',
|
'PUE': 'Pago en una sola exhibición',
|
||||||
'PPD': 'Pago en parcialidades o diferido',
|
'PPD': 'Pago en parcialidades o diferido',
|
||||||
}
|
}
|
||||||
values['metododepago'] = 'Método de Pago: ({}) {}'.format(
|
if invoice.metodo_pago:
|
||||||
invoice.metodo_pago, mp[invoice.metodo_pago])
|
values['metododepago'] = 'Método de Pago: ({}) {}'.format(
|
||||||
|
invoice.metodo_pago, mp[invoice.metodo_pago])
|
||||||
|
|
||||||
obj = SATFormaPago.get(SATFormaPago.key==invoice.forma_pago)
|
obj = SATFormaPago.get(SATFormaPago.key==invoice.forma_pago)
|
||||||
values['formadepago'] = str(obj)
|
values['formadepago'] = str(obj)
|
||||||
|
@ -3591,7 +3592,7 @@ class Facturas(BaseModel):
|
||||||
|
|
||||||
return inicio
|
return inicio
|
||||||
|
|
||||||
def _calculate_totals(self, invoice, products):
|
def _calculate_totals(self, invoice, products, tipo_comprobante):
|
||||||
tax_locales = Configuracion.get_bool('chk_config_tax_locales')
|
tax_locales = Configuracion.get_bool('chk_config_tax_locales')
|
||||||
tax_decimals = Configuracion.get_bool('chk_config_tax_decimals')
|
tax_decimals = Configuracion.get_bool('chk_config_tax_decimals')
|
||||||
subtotal = 0
|
subtotal = 0
|
||||||
|
@ -3618,6 +3619,9 @@ class Facturas(BaseModel):
|
||||||
cantidad = float(product['cantidad'])
|
cantidad = float(product['cantidad'])
|
||||||
valor_unitario = float(product['valor_unitario'])
|
valor_unitario = float(product['valor_unitario'])
|
||||||
descuento = float(product['descuento'])
|
descuento = float(product['descuento'])
|
||||||
|
if tipo_comprobante == 'T':
|
||||||
|
valor_unitario = 0.0
|
||||||
|
descuento = 0.0
|
||||||
precio_final = valor_unitario - descuento
|
precio_final = valor_unitario - descuento
|
||||||
importe = round(cantidad * precio_final, DECIMALES)
|
importe = round(cantidad * precio_final, DECIMALES)
|
||||||
|
|
||||||
|
@ -3639,6 +3643,9 @@ class Facturas(BaseModel):
|
||||||
|
|
||||||
FacturasDetalle.create(**product)
|
FacturasDetalle.create(**product)
|
||||||
|
|
||||||
|
if tipo_comprobante == 'T':
|
||||||
|
continue
|
||||||
|
|
||||||
base = product['importe'] - product['descuento']
|
base = product['importe'] - product['descuento']
|
||||||
for tax in p.impuestos:
|
for tax in p.impuestos:
|
||||||
if tax_locales and tax.tipo == 'R' and tax.key == '000':
|
if tax_locales and tax.tipo == 'R' and tax.key == '000':
|
||||||
|
@ -3666,17 +3673,18 @@ class Facturas(BaseModel):
|
||||||
tax.suma_impuestos = impuesto_producto
|
tax.suma_impuestos = impuesto_producto
|
||||||
totals_tax[tax.id] = tax
|
totals_tax[tax.id] = tax
|
||||||
|
|
||||||
for tax in totals_tax.values():
|
if tipo_comprobante != 'T':
|
||||||
if tax.tipo == 'E':
|
for tax in totals_tax.values():
|
||||||
continue
|
if tax.tipo == 'E':
|
||||||
|
continue
|
||||||
|
|
||||||
invoice_tax = {
|
invoice_tax = {
|
||||||
'factura': invoice.id,
|
'factura': invoice.id,
|
||||||
'impuesto': tax.id,
|
'impuesto': tax.id,
|
||||||
'base': tax.base,
|
'base': tax.base,
|
||||||
'importe': tax.suma_impuestos,
|
'importe': tax.suma_impuestos,
|
||||||
}
|
}
|
||||||
FacturasImpuestos.create(**invoice_tax)
|
FacturasImpuestos.create(**invoice_tax)
|
||||||
|
|
||||||
total = subtotal - descuento_cfdi + \
|
total = subtotal - descuento_cfdi + \
|
||||||
(total_trasladados or 0) - (total_retenciones or 0) \
|
(total_trasladados or 0) - (total_retenciones or 0) \
|
||||||
|
@ -3725,6 +3733,7 @@ class Facturas(BaseModel):
|
||||||
productos = util.loads(values.pop('productos'))
|
productos = util.loads(values.pop('productos'))
|
||||||
relacionados = util.loads(values.pop('relacionados'))
|
relacionados = util.loads(values.pop('relacionados'))
|
||||||
ine = values.pop('ine', {})
|
ine = values.pop('ine', {})
|
||||||
|
tipo_comprobante = values['tipo_comprobante']
|
||||||
|
|
||||||
emisor = Emisor.select()[0]
|
emisor = Emisor.select()[0]
|
||||||
values['serie'] = cls._get_serie(cls, user, values['serie'])
|
values['serie'] = cls._get_serie(cls, user, values['serie'])
|
||||||
|
@ -3733,10 +3742,12 @@ class Facturas(BaseModel):
|
||||||
values['lugar_expedicion'] = emisor.cp_expedicion or emisor.codigo_postal
|
values['lugar_expedicion'] = emisor.cp_expedicion or emisor.codigo_postal
|
||||||
values['anticipo'] = util.get_bool(values['anticipo'])
|
values['anticipo'] = util.get_bool(values['anticipo'])
|
||||||
values['donativo'] = util.get_bool(values['donativo'])
|
values['donativo'] = util.get_bool(values['donativo'])
|
||||||
|
if tipo_comprobante == 'T':
|
||||||
|
values['metodo_pago'] = ''
|
||||||
|
|
||||||
with database_proxy.atomic() as txn:
|
with database_proxy.atomic() as txn:
|
||||||
obj = Facturas.create(**values)
|
obj = Facturas.create(**values)
|
||||||
totals = cls._calculate_totals(cls, obj, productos)
|
totals = cls._calculate_totals(cls, obj, productos, tipo_comprobante)
|
||||||
cls._guardar_relacionados(cls, obj, relacionados)
|
cls._guardar_relacionados(cls, obj, relacionados)
|
||||||
cls._guardar_ine(cls, obj, ine)
|
cls._guardar_ine(cls, obj, ine)
|
||||||
obj.subtotal = totals['subtotal']
|
obj.subtotal = totals['subtotal']
|
||||||
|
@ -3798,7 +3809,8 @@ class Facturas(BaseModel):
|
||||||
comprobante['TipoCambio'] = FORMAT.format(invoice.tipo_cambio)
|
comprobante['TipoCambio'] = FORMAT.format(invoice.tipo_cambio)
|
||||||
comprobante['Total'] = FORMAT.format(invoice.total)
|
comprobante['Total'] = FORMAT.format(invoice.total)
|
||||||
comprobante['TipoDeComprobante'] = invoice.tipo_comprobante
|
comprobante['TipoDeComprobante'] = invoice.tipo_comprobante
|
||||||
comprobante['MetodoPago'] = invoice.metodo_pago
|
if invoice.metodo_pago:
|
||||||
|
comprobante['MetodoPago'] = invoice.metodo_pago
|
||||||
comprobante['LugarExpedicion'] = invoice.lugar_expedicion
|
comprobante['LugarExpedicion'] = invoice.lugar_expedicion
|
||||||
if invoice.descuento:
|
if invoice.descuento:
|
||||||
comprobante['Descuento'] = FORMAT.format(invoice.descuento)
|
comprobante['Descuento'] = FORMAT.format(invoice.descuento)
|
||||||
|
@ -3857,38 +3869,45 @@ class Facturas(BaseModel):
|
||||||
traslados = []
|
traslados = []
|
||||||
retenciones = []
|
retenciones = []
|
||||||
|
|
||||||
for impuesto in row.producto.impuestos:
|
if invoice.tipo_comprobante != 'T':
|
||||||
if impuesto.tipo == 'E':
|
for impuesto in row.producto.impuestos:
|
||||||
continue
|
base = float(row.importe - row.descuento)
|
||||||
|
if impuesto.tipo == 'E':
|
||||||
|
tax = {
|
||||||
|
'Base': FORMAT.format(base),
|
||||||
|
'Impuesto': '002',
|
||||||
|
'TipoFactor': 'Exento',
|
||||||
|
}
|
||||||
|
traslados.append(tax)
|
||||||
|
continue
|
||||||
|
|
||||||
if impuesto.key == '000':
|
if impuesto.key == '000':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
base = float(row.importe - row.descuento)
|
tasa = float(impuesto.tasa)
|
||||||
tasa = float(impuesto.tasa)
|
|
||||||
|
|
||||||
if tax_decimals:
|
if tax_decimals:
|
||||||
import_tax = round(tasa * base, DECIMALES_TAX)
|
import_tax = round(tasa * base, DECIMALES_TAX)
|
||||||
tmp += import_tax
|
tmp += import_tax
|
||||||
xml_importe = FORMAT_TAX.format(import_tax)
|
xml_importe = FORMAT_TAX.format(import_tax)
|
||||||
else:
|
else:
|
||||||
import_tax = round(tasa * base, DECIMALES)
|
import_tax = round(tasa * base, DECIMALES)
|
||||||
xml_importe = FORMAT.format(import_tax)
|
xml_importe = FORMAT.format(import_tax)
|
||||||
|
|
||||||
tipo_factor = 'Tasa'
|
tipo_factor = 'Tasa'
|
||||||
if impuesto.factor != 'T':
|
if impuesto.factor != 'T':
|
||||||
tipo_factor = 'Cuota'
|
tipo_factor = 'Cuota'
|
||||||
tax = {
|
tax = {
|
||||||
"Base": FORMAT.format(base),
|
"Base": FORMAT.format(base),
|
||||||
"Impuesto": impuesto.key,
|
"Impuesto": impuesto.key,
|
||||||
"TipoFactor": tipo_factor,
|
"TipoFactor": tipo_factor,
|
||||||
"TasaOCuota": str(impuesto.tasa),
|
"TasaOCuota": str(impuesto.tasa),
|
||||||
"Importe": xml_importe,
|
"Importe": xml_importe,
|
||||||
}
|
}
|
||||||
if impuesto.tipo == 'T':
|
if impuesto.tipo == 'T':
|
||||||
traslados.append(tax)
|
traslados.append(tax)
|
||||||
else:
|
else:
|
||||||
retenciones.append(tax)
|
retenciones.append(tax)
|
||||||
|
|
||||||
if traslados:
|
if traslados:
|
||||||
taxes['traslados'] = traslados
|
taxes['traslados'] = traslados
|
||||||
|
@ -3974,6 +3993,9 @@ class Facturas(BaseModel):
|
||||||
impuestos['locales_trasladados'] = locales_trasladados
|
impuestos['locales_trasladados'] = locales_trasladados
|
||||||
impuestos['locales_retenciones'] = locales_retenciones
|
impuestos['locales_retenciones'] = locales_retenciones
|
||||||
|
|
||||||
|
if invoice.tipo_comprobante == 'T':
|
||||||
|
impuestos = {}
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'comprobante': comprobante,
|
'comprobante': comprobante,
|
||||||
'relacionados': relacionados,
|
'relacionados': relacionados,
|
||||||
|
@ -7856,6 +7878,45 @@ def _import_from_folder(path):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _exportar_documentos():
|
||||||
|
rfc = input('Introduce el RFC: ').strip().upper()
|
||||||
|
if not rfc:
|
||||||
|
msg = 'El RFC es requerido'
|
||||||
|
log.error(msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
args = util.get_con(rfc)
|
||||||
|
if not args:
|
||||||
|
return
|
||||||
|
|
||||||
|
conectar(args)
|
||||||
|
log.info('Exportar documentos...')
|
||||||
|
|
||||||
|
n = util.now()
|
||||||
|
year = input('Introduce el año [{}]: '.format(n.year)).strip()
|
||||||
|
if not year:
|
||||||
|
year = str(n.year)
|
||||||
|
month = input('Introduce el mes [{}]: '.format(n.month)).strip()
|
||||||
|
if not month:
|
||||||
|
month = str(n.month)
|
||||||
|
|
||||||
|
filters = {
|
||||||
|
'year': year,
|
||||||
|
'month': month,
|
||||||
|
}
|
||||||
|
result = Facturas.get_(filters)
|
||||||
|
if result['ok']:
|
||||||
|
t = len(result['rows'])
|
||||||
|
for i, row in enumerate(result['rows']):
|
||||||
|
msg = 'Extrayendo factura {} de {}: {}-{}'.format(
|
||||||
|
i+1, t, row['serie'], row['folio'])
|
||||||
|
log.info(msg)
|
||||||
|
Facturas.get_xml(row['id'])
|
||||||
|
Facturas.get_pdf(row['id'], rfc, True)
|
||||||
|
log.info('Documentos exportados...')
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
def _test():
|
def _test():
|
||||||
rfc = input('Introduce el RFC: ').strip().upper()
|
rfc = input('Introduce el RFC: ').strip().upper()
|
||||||
if not rfc:
|
if not rfc:
|
||||||
|
@ -7907,11 +7968,12 @@ help_lr = 'Listar RFCs'
|
||||||
@click.option('-r', '--rfc')
|
@click.option('-r', '--rfc')
|
||||||
@click.option('-d', '--detalle', is_flag=True, default=False)
|
@click.option('-d', '--detalle', is_flag=True, default=False)
|
||||||
@click.option('-id', '--importar-directorio')
|
@click.option('-id', '--importar-directorio')
|
||||||
|
@click.option('-ed', '--exportar_documentos', is_flag=True, default=False)
|
||||||
def main(iniciar_bd, migrar_bd, nuevo_superusuario, cambiar_contraseña,
|
def main(iniciar_bd, migrar_bd, nuevo_superusuario, cambiar_contraseña,
|
||||||
agregar_rfc, borrar_rfc, listar_rfc, importar_valores, archivo, conexion,
|
agregar_rfc, borrar_rfc, listar_rfc, importar_valores, archivo, conexion,
|
||||||
factura_libre, factura_libre_gambas, test, generar_archivo_productos,
|
factura_libre, factura_libre_gambas, test, generar_archivo_productos,
|
||||||
importar_productos, backup_dbs, no_bd, alta, rfc, detalle,
|
importar_productos, backup_dbs, no_bd, alta, rfc, detalle,
|
||||||
importar_directorio):
|
importar_directorio, exportar_documentos):
|
||||||
|
|
||||||
opt = locals()
|
opt = locals()
|
||||||
|
|
||||||
|
@ -8019,9 +8081,14 @@ def main(iniciar_bd, migrar_bd, nuevo_superusuario, cambiar_contraseña,
|
||||||
|
|
||||||
if opt['importar_directorio']:
|
if opt['importar_directorio']:
|
||||||
_import_from_folder(opt['importar_directorio'])
|
_import_from_folder(opt['importar_directorio'])
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
if opt['backup_dbs']:
|
if opt['backup_dbs']:
|
||||||
util.backup_dbs()
|
util.backup_dbs()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if opt['exportar_documentos']:
|
||||||
|
_exportar_documentos()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -406,6 +406,11 @@ function validate_invoice(values){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tipo_comprobante = $$('lst_tipo_comprobante').getValue()
|
||||||
|
if(tipo_comprobante == 'T'){
|
||||||
|
msg_ok('El CFDI es de tipo Traslado')
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,7 +570,6 @@ function guardar_y_timbrar(values){
|
||||||
delete rows[i]['delete']
|
delete rows[i]['delete']
|
||||||
delete rows[i]['clave']
|
delete rows[i]['clave']
|
||||||
delete rows[i]['clave_sat']
|
delete rows[i]['clave_sat']
|
||||||
//~ delete rows[i]['unidad']
|
|
||||||
delete rows[i]['importe']
|
delete rows[i]['importe']
|
||||||
delete rows[i]['student']
|
delete rows[i]['student']
|
||||||
rows[i]['valor_unitario'] = parseFloat(rows[i]['valor_unitario'])
|
rows[i]['valor_unitario'] = parseFloat(rows[i]['valor_unitario'])
|
||||||
|
@ -630,7 +634,9 @@ function cmd_timbrar_click(id, e, node){
|
||||||
if(!validate_invoice(values)){
|
if(!validate_invoice(values)){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//~ showvar(values)
|
|
||||||
|
var tipo_comprobante = $$('lst_tipo_comprobante').getValue()
|
||||||
|
|
||||||
query = table_relaciones.chain().data()
|
query = table_relaciones.chain().data()
|
||||||
msg = '¿Todos los datos son correctos?<BR><BR>'
|
msg = '¿Todos los datos son correctos?<BR><BR>'
|
||||||
if(query.length > 0){
|
if(query.length > 0){
|
||||||
|
@ -650,7 +656,12 @@ function cmd_timbrar_click(id, e, node){
|
||||||
if(usar_ine){
|
if(usar_ine){
|
||||||
msg += 'Estas usando el complemento INE<BR><BR>'
|
msg += 'Estas usando el complemento INE<BR><BR>'
|
||||||
}
|
}
|
||||||
msg += '¿Estás seguro de timbrar esta factura?'
|
|
||||||
|
if(tipo_comprobante == 'T'){
|
||||||
|
msg += 'El Tipo de Comprobante es Traslado, todos los importes serán puesto a 0 (Cero), asegurate de que sea el tipo de comprobante correcto<BR><BR>'
|
||||||
|
}
|
||||||
|
|
||||||
|
msg += '¿Estás seguro de timbrar esta factura?<BR><BR>'
|
||||||
|
|
||||||
webix.confirm({
|
webix.confirm({
|
||||||
title: 'Timbrar Factura',
|
title: 'Timbrar Factura',
|
||||||
|
|
|
@ -337,6 +337,7 @@ function partner_reset_saldo(id){
|
||||||
if(values.ok){
|
if(values.ok){
|
||||||
msg = 'Saldo actualizado correctamente'
|
msg = 'Saldo actualizado correctamente'
|
||||||
$$('grid_partners').updateItem(id, {saldo_cliente: 0.0})
|
$$('grid_partners').updateItem(id, {saldo_cliente: 0.0})
|
||||||
|
$$('cmd_partner_zero').disable()
|
||||||
msg_ok(msg)
|
msg_ok(msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue