Merge branch 'develop'

Traslados
This commit is contained in:
Mauricio Baeza 2018-03-01 22:07:37 -06:00
commit 7308ec86ae
5 changed files with 271 additions and 69 deletions

View File

@ -88,10 +88,18 @@ class AppMain(object):
class AppValues(object):
TABLES = ('allusuarios', 'usuario', 'usuarioupdate', 'editusuario',
'addusuario')
def __init__(self, db):
self._db = db
def _valid_user(self, table, user):
if table in self.TABLES and not user.es_admin:
return False
return True
def on_get(self, req, resp, table):
values = req.params
session = req.env['beaker.session']
@ -109,6 +117,10 @@ class AppValues(object):
req.context['result'] = session['userobj'].es_superusuario \
or session['userobj'].es_admin
else:
if not self._valid_user(table, session['userobj']):
resp.status = falcon.HTTP_403
return
req.context['result'] = self._db.get_values(table, values, session)
resp.status = falcon.HTTP_200
@ -120,6 +132,10 @@ class AppValues(object):
resp.status = falcon.HTTP_204
return
if not self._valid_user(table, session['userobj']):
resp.status = falcon.HTTP_403
return
if self._db.delete(table, values['id']):
resp.status = falcon.HTTP_200
else:
@ -130,6 +146,11 @@ class AppValues(object):
if file_object is None:
session = req.env['beaker.session']
values = req.params
if not self._valid_user(table, session['userobj']):
resp.status = falcon.HTTP_403
return
if table == 'correo':
req.context['result'] = self._db.validate_email(values)
elif table == 'sendmail':

View File

@ -934,6 +934,14 @@ class Folios(BaseModel):
folio = Folios.select()[0]
return folio.serie
@classmethod
def get_id(cls, serie):
try:
obj = Folios.get(Folios.serie==serie)
return obj.id
except:
return Folios.select()[0].id
@classmethod
def get_all(cls):
rows = (Folios
@ -2987,6 +2995,7 @@ class Productos(BaseModel):
Productos.descripcion,
Productos.unidad,
Productos.valor_unitario,
Productos.codigo_barras,
Productos.cuenta_predial,
Productos.inventario,
Productos.existencia,
@ -3006,7 +3015,8 @@ class Productos(BaseModel):
Productos.clave,
Productos.descripcion,
SATUnidades.name.alias('unidad'),
Productos.valor_unitario)
Productos.valor_unitario,
Productos.existencia)
.join(SATUnidades)
.dicts()
)
@ -3057,8 +3067,8 @@ class Productos(BaseModel):
@classmethod
def actualizar(cls, values, id):
if not 'cuenta_predial' in values:
values['cuenta_predial'] = ''
values['cuenta_predial'] = values.get('cuenta_predial', '')
values['codigo_barras'] = values.get('codigo_barras', '')
fields, taxes = cls._clean(cls, values)
obj_taxes = SATImpuestos.select().where(SATImpuestos.id.in_(taxes))
with database_proxy.transaction():
@ -3521,12 +3531,36 @@ class Facturas(BaseModel):
)
return {'ok': True, 'rows': rows}
return
def _get_reinvoice(self, id):
obj = Facturas.get(Facturas.id==id)
receptor = {
'id': obj.cliente.id,
'nombre': obj.cliente.nombre,
'rfc': obj.cliente.rfc,
'notas': obj.notas,
}
invoice = {
'tipo_comprobante': obj.tipo_comprobante,
'serie': Folios.get_id(obj.serie),
'uso_cfdi': obj.uso_cfdi,
'metodo_pago': obj.metodo_pago,
'forma_pago': obj.forma_pago,
'condicion_pago': obj.condiciones_pago,
}
products = FacturasDetalle.reinvoice(id)
data = {'receptor': receptor, 'invoice': invoice, 'products': products}
return data
def _get_opt(self, values):
if values['opt'] == 'porpagar':
return self._get_por_pagar(self, util.loads(values['ids']))
if values['opt'] == 'reinvoice':
return self._get_reinvoice(self, int(values['id']))
cfdis = util.loads(values['cfdis'])
if values['year'] == '-1':
@ -3657,9 +3691,6 @@ class Facturas(BaseModel):
cantidad = float(product['cantidad'])
valor_unitario = float(product['valor_unitario'])
descuento = float(product['descuento'])
# ~ if tipo_comprobante == 'T':
# ~ valor_unitario = 0.0
# ~ descuento = 0.0
precio_final = valor_unitario - descuento
importe = round(cantidad * precio_final, DECIMALES)
@ -3711,7 +3742,10 @@ class Facturas(BaseModel):
tax.suma_impuestos = impuesto_producto
totals_tax[tax.id] = tax
if tipo_comprobante != 'T':
if tipo_comprobante == 'T':
subtotal = 0.0
descuento = 0.0
else:
for tax in totals_tax.values():
if tax.tipo == 'E':
continue
@ -3855,8 +3889,8 @@ class Facturas(BaseModel):
comprobante['Descuento'] = FORMAT.format(invoice.descuento)
if invoice.tipo_comprobante == 'T':
comprobante['SubTotal'] = '0.0'
comprobante['Total'] = '0.0'
comprobante['SubTotal'] = '0.00'
comprobante['Total'] = '0.00'
del comprobante['FormaPago']
if invoice.tipo_relacion:
@ -4642,15 +4676,18 @@ class PreFacturas(BaseModel):
product['cantidad'] = cantidad
product['valor_unitario'] = valor_unitario
product['descuento'] = descuento
product['descuento'] = round(descuento * cantidad, DECIMALES)
product['precio_final'] = precio_final
product['importe'] = round(cantidad * valor_unitario, DECIMALES)
descuento_cfdi += descuento
subtotal += importe
descuento_cfdi += product['descuento']
subtotal += product['importe']
PreFacturasDetalle.create(**product)
if invoice.tipo_comprobante == 'T':
continue
base = product['importe'] - product['descuento']
for tax in p.impuestos:
if tax_locales and tax.tipo == 'R' and tax.key == '000':
@ -4678,24 +4715,28 @@ class PreFacturas(BaseModel):
tax.suma_impuestos = impuesto_producto
totals_tax[tax.id] = tax
for tax in totals_tax.values():
if tax.tipo == 'E':
continue
if invoice.tipo_comprobante == 'T':
subtotal = 0.0
descuento = 0.0
else:
for tax in totals_tax.values():
if tax.tipo == 'E':
continue
invoice_tax = {
'factura': invoice.id,
'impuesto': tax.id,
'base': tax.base,
'importe': tax.suma_impuestos,
}
PreFacturasImpuestos.create(**invoice_tax)
invoice_tax = {
'factura': invoice.id,
'impuesto': tax.id,
'base': tax.base,
'importe': tax.suma_impuestos,
}
PreFacturasImpuestos.create(**invoice_tax)
total = subtotal - descuento_cfdi + \
(total_trasladados or 0) - (total_retenciones or 0) \
+ locales_traslados - locales_retenciones
total_mn = round(total * invoice.tipo_cambio, DECIMALES)
data = {
'subtotal': subtotal + descuento,
'subtotal': subtotal,
'descuento': descuento_cfdi,
'total': total,
'total_mn': total_mn,
@ -4809,6 +4850,34 @@ class FacturasDetalle(BaseModel):
class Meta:
order_by = ('factura',)
def _get_impuestos(self, id):
model_pt = Productos.impuestos.get_through_model()
impuestos = tuple(model_pt
.select(
model_pt.productos_id.alias('product'),
model_pt.satimpuestos_id.alias('tax'))
.where(model_pt.productos_id==id).dicts())
return impuestos
@classmethod
def reinvoice(cls, id):
data = []
products = FacturasDetalle.select().where(FacturasDetalle.factura==id)
for p in reversed(products):
row = {'delete': '-', 'id_product': p.producto.id}
row['clave'] = p.clave
row['clave_sat'] = p.clave_sat
row['descripcion'] = p.descripcion
row['unidad'] = p.producto.unidad.id
row['cantidad'] = p.cantidad
row['valor_unitario'] = p.valor_unitario
row['descuento'] = p.descuento
pf = p.valor_unitario - p.descuento
row['importe'] = round(pf * p.cantidad, DECIMALES)
impuestos = cls._get_impuestos(cls, row['id_product'])
data.append({'row': row, 'taxes': impuestos})
return data
class PreFacturasDetalle(BaseModel):
factura = ForeignKeyField(PreFacturas)
@ -4851,22 +4920,12 @@ class PreFacturasDetalle(BaseModel):
data = []
q = PreFacturas.select().where(PreFacturas.id==id)[0]
if q.cliente.forma_pago is None:
forma_pago = ''
else:
forma_pago = q.cliente.forma_pago.key
if q.cliente.uso_cfdi is None:
uso_cfdi = ''
else:
uso_cfdi = q.cliente.uso_cfdi.key
receptor = {
'id': q.cliente.id,
'nombre': q.cliente.nombre,
'rfc': q.cliente.rfc,
'forma_pago': forma_pago,
'uso_cfdi': uso_cfdi,
'forma_pago': q.forma_pago,
'uso_cfdi': q.uso_cfdi,
'notas': q.notas,
}

View File

@ -42,6 +42,7 @@ var invoices_controllers = {
$$('cmd_cfdi_relacionados').attachEvent('onItemClick', cmd_cfdi_relacionados_click)
$$('lst_metodo_pago').attachEvent('onChange', lst_metodo_pago_change)
$$('lst_moneda').attachEvent('onChange', lst_moneda_change)
$$('lst_tipo_comprobante').attachEvent('onChange', lst_tipo_comprobante_change)
$$('lst_serie').attachEvent('onChange', lst_serie_change)
$$('cmd_cfdi_notes').attachEvent('onItemClick', cmd_cfdi_notes_click)
@ -67,7 +68,7 @@ function get_condicion_pago(){
function get_series(){
webix.ajax().get('/values/series', function(text, data){
webix.ajax().sync().get('/values/series', function(text, data){
var values = data.json()
table_series.clear()
table_series.insert(values)
@ -200,7 +201,7 @@ function price_without_taxes(price, id){
}
function cmd_new_invoice_click(id, e, node){
function cmd_new_invoice_click(){
var form = $$('form_invoice')
var grid_totals = $$('grid_totals')
grid = $$('grid_details')
@ -817,6 +818,11 @@ function calcular_impuestos(){
grid_totals.clearAll()
grid_totals.add({id: 1, concepto: 'SubTotal', importe: 0})
var tc = $$('lst_tipo_comprobante').getValue()
if(tc=='T'){
return
}
grid.eachRow(function(row){
var product = grid.getItem(row)
var valor_unitario = parseFloat(product.valor_unitario)
@ -975,6 +981,10 @@ function grid_details_before_edit_start(id){
if(!columns.indexOf(id.column)){
return !this.getItem(id.row)[id.column]
}
var tc = $$('lst_tipo_comprobante').getValue()
if(tc=='T' && id.column=='descuento'){
return false
}
}
@ -1073,6 +1083,16 @@ function grid_details_before_edit_stop(state, editor){
}
var cantidad = parseFloat(row['cantidad'])
var valor_unitario = parseFloat(row['valor_unitario'])
if(descuento>=valor_unitario){
msg = 'El descuento debe ser menor al Valor Unitario'
msg_error(msg)
grid.blockEvent()
state.value = state.old
grid.editCancel()
grid.unblockEvent()
return true
}
}
var precio_final = valor_unitario - descuento
@ -1107,7 +1127,6 @@ function grid_details_header_click(id){
callback:function(result){
if (result){
grid.clearAll()
//~ calculate_taxes()
calcular_impuestos()
}
}
@ -1115,8 +1134,83 @@ function grid_details_header_click(id){
}
function set_invoice(row){
$$('lst_serie').setValue(row.serie)
$$('lst_tipo_comprobante').setValue(row.tipo_comprobante)
$$('lst_uso_cfdi').setValue(row.uso_cfdi)
$$('lst_metodo_pago').setValue(row.metodo_pago)
$$('lst_forma_pago').setValue(row.forma_pago)
$$('txt_condicion_pago').setValue(row.condicion_pago)
}
function set_products_reinvoice(values){
var rows = []
for(var product of values){
var row = product.row
rows.push(row)
var taxes = product.taxes
for(var v of taxes){
var pt = table_pt.findOne(v)
if(pt === null){
table_pt.insert(v)
}
}
}
grid.parse(rows, 'json')
}
function refacturar_invoice(id){
filters = {id: id, opt: 'reinvoice'}
webix.ajax().get('/invoices', filters, {
error: function(text, data, xhr) {
msg_error('Error al consultar')
},
success: function(text, data, xhr) {
var values = data.json();
cmd_new_invoice_click()
pause(500)
set_client(values.receptor)
set_invoice(values.invoice)
set_products_reinvoice(values.products)
calcular_impuestos()
}
})
}
function cmd_refacturar_click(){
showvar('Refacturar')
if(gi.count() == 0){
return
}
var row = gi.getSelectedItem()
if (row == undefined){
msg_error('Selecciona una factura')
return
}
if (row instanceof Array){
msg_error('Selecciona solo una factura')
return
}
var msg = '¿Estás seguro de refacturar la siguiente factura?<BR><BR>'
msg += '(' + row['serie'] + '-' + row['folio'] + ') ' + row['cliente']
webix.confirm({
title: 'Refacturar',
ok: 'Si',
cancel: 'No',
type: 'confirm-error',
text: msg,
callback:function(result){
if (result){
refacturar_invoice(row['id'])
}
}
})
}
@ -1804,13 +1898,27 @@ function lst_tipo_relacion_change(nv, ov){
}
function lst_tipo_comprobante_change(nv, ov){
if(nv=='T'){
grid.eachRow(function(row){
var p = grid.getItem(row)
p.descuento = 0.0
p.importe = (p.cantidad * p.valor_unitario).round(DECIMALES)
grid.updateItem(row, p)
})
}
if(nv=='T' || ov=='T'){
calcular_impuestos()
}
}
function lst_serie_change(nv, ov){
query = table_series.chain().find({id: nv}).data()[0]
if(query.usarcon){
$$('lst_tipo_comprobante').setValue(query.usarcon)
$$('lst_tipo_comprobante').config.readonly = true
}else{
$$('lst_tipo_comprobante').setValue('I')
$$('lst_tipo_comprobante').config.readonly = false
}
$$('lst_tipo_comprobante').refresh()

View File

@ -1,3 +1,26 @@
var cfg_products = new Object()
function products_default_config(){
webix.ajax().get('/config', {'fields': 'productos'}, {
error: function(text, data, xhr) {
msg = 'Error al consultar'
msg_error(msg)
},
success: function(text, data, xhr) {
var values = data.json()
cfg_products['inventario'] = values.chk_llevar_inventario
cfg_products['predial'] = values.chk_config_cuenta_predial
cfg_products['codigo_barras'] = values.chk_config_codigo_barras
cfg_products['con_impuestos'] = values.chk_config_precio_con_impuestos
cfg_products['default_unit'] = values.default_unidad
cfg_products['default_tax'] = values.default_tax
if(cfg_products['inventario']){
$$('grid_products').showColumn('existencia')
}
}
})
}
var products_controllers = {
@ -14,31 +37,18 @@ var products_controllers = {
$$('precio_con_impuestos').attachEvent('onTimedKeyPress', precio_con_impuestos_key_up);
$$("chk_inventario").attachEvent("onChange", chk_inventario_change)
$$('grid_products').attachEvent('onItemDblClick', cmd_edit_product_click)
products_default_config()
}
}
function configurar_productos(is_new){
webix.ajax().get('/config', {'fields': 'productos'}, {
error: function(text, data, xhr) {
msg = 'Error al consultar'
msg_error(msg)
},
success: function(text, data, xhr) {
var values = data.json()
//~ showvar(values)
show('cuenta_predial', values.chk_config_cuenta_predial)
show('codigo_barras', values.chk_config_codigo_barras)
show('precio_con_impuestos', values.chk_config_precio_con_impuestos)
show('chk_inventario', values.chk_llevar_inventario)
show('txt_existencia', values.chk_llevar_inventario)
show('txt_minimo', values.chk_llevar_inventario)
$$('unidad').setValue(values.default_unidad)
if(is_new){
$$('grid_product_taxes').select(values.default_tax)
}
}
})
function configurar_producto(){
show('cuenta_predial', cfg_products['predial'])
show('codigo_barras', cfg_products['codigo_barras'])
show('precio_con_impuestos', cfg_products['con_impuestos'])
show('chk_inventario', cfg_products['inventario'])
show('txt_existencia', cfg_products['inventario'])
show('txt_minimo', cfg_products['inventario'])
}
@ -70,21 +80,24 @@ function get_products(){
function cmd_new_product_click(id, e, node){
get_taxes()
configurar_productos(true)
$$('unidad').getList().load('/values/unidades')
configurar_producto()
$$('form_product').setValues({
id: 0, es_activo_producto: true})
add_config({'key': 'id_product', 'value': ''})
get_new_key()
get_categorias()
$$('unidad').setValue(cfg_products['default_unit'])
$$('grid_product_taxes').select(cfg_products['default_tax'])
$$('grid_products').clearSelection()
$$('unidad').getList().load('/values/unidades')
$$("multi_products").setValue("product_new")
}
function cmd_edit_product_click(){
get_taxes()
configurar_productos(false)
$$('unidad').getList().load('/values/unidades')
configurar_producto()
var grid = $$('grid_products')
var row = grid.getSelectedItem()
if(row == undefined){
@ -93,8 +106,6 @@ function cmd_edit_product_click(){
}
$$('categoria').getList().load('/values/categorias')
$$('unidad').getList().load('/values/unidades')
webix.ajax().get('/products', {id:row['id']}, {
error: function(text, data, xhr) {
msg_error()

View File

@ -23,8 +23,11 @@ var grid_products_cols = [
fillspace:true, sort: 'string', footer: 'Productos y Servicios'},
{ id: "unidad", header: ["Unidad", {content: "selectFilter"}], width: 150,
sort:"string" },
{ id: "valor_unitario", header: ["Precio", {content: "numberFilter"}], width: 150,
sort:"int", format: webix.i18n.priceFormat, css: "right" },
{ id: "valor_unitario", header: ["Precio", {content: "numberFilter"}],
width: 150, sort: 'int', format: webix.i18n.priceFormat, css: "right" },
{ id: 'existencia', header: ['Existencia', {content: 'numberFilter'}],
width: 100, sort: 'int', format: webix.i18n.numberFormat,
hidden: true, css: 'right' },
]