Fix - Issue #188

This commit is contained in:
Mauricio Baeza 2018-02-16 13:52:30 -06:00
parent 9f6e9e36fe
commit c45d95d762
5 changed files with 130 additions and 50 deletions

View File

@ -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:

View File

@ -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':

View File

@ -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

View File

@ -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',

View File

@ -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)
} }
} }