Agregar, editar y eliminar productos
This commit is contained in:
parent
52169cb77c
commit
d396f5720e
|
@ -93,3 +93,27 @@ class AppPartners(object):
|
|||
resp.status = falcon.HTTP_200
|
||||
else:
|
||||
resp.status = falcon.HTTP_204
|
||||
|
||||
|
||||
class AppProducts(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
req.context['result'] = self._db.get_products(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
#~ print ('VALUES', values)
|
||||
req.context['result'] = self._db.product(values)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_delete(self, req, resp):
|
||||
values = req.params
|
||||
if self._db.delete('product', values['id']):
|
||||
resp.status = falcon.HTTP_200
|
||||
else:
|
||||
resp.status = falcon.HTTP_204
|
||||
|
|
|
@ -12,7 +12,7 @@ import uuid
|
|||
|
||||
#~ import bcrypt
|
||||
|
||||
from settings import log, template_lookup, COMPANIES
|
||||
from settings import log, template_lookup, COMPANIES, DB_SAT
|
||||
|
||||
|
||||
#~ def _get_hash(password):
|
||||
|
@ -86,6 +86,19 @@ def get_rfcs():
|
|||
return values
|
||||
|
||||
|
||||
def get_sat_key(table, key):
|
||||
con = sqlite3.connect(DB_SAT)
|
||||
cursor = con.cursor()
|
||||
sql = 'SELECT key, description FROM {} WHERE key=?'.format(table)
|
||||
cursor.execute(sql, (key,))
|
||||
data = cursor.fetchone()
|
||||
cursor.close()
|
||||
con.close()
|
||||
if data is None:
|
||||
return {'ok': False, 'text': 'No se encontró la clave'}
|
||||
return {'ok': True, 'text': data[1]}
|
||||
|
||||
|
||||
def now():
|
||||
return datetime.datetime.now()
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ from middleware import (
|
|||
)
|
||||
from models.db import StorageEngine
|
||||
from controllers.main import (
|
||||
AppLogin, AppLogout, AppAdmin, AppMain, AppValues, AppPartners
|
||||
AppLogin, AppLogout, AppAdmin, AppMain, AppValues, AppPartners, AppProducts
|
||||
)
|
||||
from settings import DEBUG
|
||||
|
||||
|
@ -30,6 +30,7 @@ api.add_route('/admin', AppAdmin(db))
|
|||
api.add_route('/main', AppMain(db))
|
||||
api.add_route('/values/{table}', AppValues(db))
|
||||
api.add_route('/partners', AppPartners(db))
|
||||
api.add_route('/products', AppProducts(db))
|
||||
|
||||
|
||||
if DEBUG:
|
||||
|
|
|
@ -20,13 +20,30 @@ class StorageEngine(object):
|
|||
def _get_formapago(self, values):
|
||||
return main.SATFormaPago.get_activos()
|
||||
|
||||
def _get_categorias(self, values):
|
||||
return main.Categorias.get_all()
|
||||
|
||||
def _get_newkey(self, values):
|
||||
return main.Productos.next_key()
|
||||
|
||||
def _get_unidades(self, values):
|
||||
return main.SATUnidades.get_activos()
|
||||
|
||||
def _get_taxes(self, values):
|
||||
return main.SATImpuestos.get_activos()
|
||||
|
||||
def _get_satkey(self, values):
|
||||
return main.get_sat_key(values['key'])
|
||||
|
||||
def delete(self, table, id):
|
||||
if table == 'partner':
|
||||
return main.Socios.remove(id)
|
||||
if table == 'product':
|
||||
return main.Productos.remove(id)
|
||||
return False
|
||||
|
||||
def get_partners(self, values):
|
||||
return main.Socios.get(values)
|
||||
return main.Socios.get_(values)
|
||||
|
||||
def partner(self, values):
|
||||
id = int(values['id'])
|
||||
|
@ -35,6 +52,16 @@ class StorageEngine(object):
|
|||
return main.Socios.actualizar(values, id)
|
||||
return main.Socios.add(values)
|
||||
|
||||
def get_products(self, values):
|
||||
return main.Productos.get_(values)
|
||||
|
||||
def product(self, values):
|
||||
id = int(values['id'])
|
||||
del values['id']
|
||||
if id:
|
||||
return main.Productos.actualizar(values, id)
|
||||
return main.Productos.add(values)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -179,6 +179,15 @@ class Categorias(BaseModel):
|
|||
(('categoria', 'padre'), True),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_all(cls):
|
||||
rows = (Categorias.select(
|
||||
Categorias.id,
|
||||
Categorias.categoria.alias('value'),
|
||||
Categorias.padre.alias('parent_id'))
|
||||
).dicts()
|
||||
return tuple(rows)
|
||||
|
||||
|
||||
class CondicionesPago(BaseModel):
|
||||
condicion = TextField(unique=True)
|
||||
|
@ -199,6 +208,17 @@ class SATUnidades(BaseModel):
|
|||
(('key', 'name'), True),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_activos(cls):
|
||||
rows = (SATUnidades
|
||||
.select(
|
||||
SATUnidades.id,
|
||||
SATUnidades.name.alias('value'))
|
||||
.where(SATUnidades.activo==True)
|
||||
.dicts()
|
||||
)
|
||||
return tuple(rows)
|
||||
|
||||
|
||||
class SATFormaPago(BaseModel):
|
||||
key = TextField(unique=True, index=True)
|
||||
|
@ -265,6 +285,11 @@ class SATImpuestos(BaseModel):
|
|||
(('key', 'factor', 'tipo', 'tasa'), True),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_activos(self):
|
||||
rows = SATImpuestos.select().where(SATImpuestos.activo==True).dicts()
|
||||
return tuple(rows)
|
||||
|
||||
|
||||
class SATUsoCfdi(BaseModel):
|
||||
key = TextField(index=True, unique=True)
|
||||
|
@ -343,7 +368,7 @@ class Socios(BaseModel):
|
|||
return fields
|
||||
|
||||
@classmethod
|
||||
def get(cls, values):
|
||||
def get_(cls, values):
|
||||
if values:
|
||||
id = int(values['id'])
|
||||
row = Socios.select().where(Socios.id==id).dicts()[0]
|
||||
|
@ -425,6 +450,129 @@ class Productos(BaseModel):
|
|||
class Meta:
|
||||
order_by = ('descripcion',)
|
||||
|
||||
@classmethod
|
||||
def next_key(cls):
|
||||
value = Productos.select(fn.Max(Productos.id)).scalar()
|
||||
if value is None:
|
||||
value = 1
|
||||
else:
|
||||
value += 1
|
||||
return {'value': value}
|
||||
|
||||
@classmethod
|
||||
def get_(cls, values):
|
||||
if values:
|
||||
id = int(values['id'])
|
||||
row = (Productos
|
||||
.select(
|
||||
Productos.id,
|
||||
Productos.es_activo.alias('es_activo_producto'),
|
||||
Productos.categoria,
|
||||
Productos.clave,
|
||||
Productos.clave_sat,
|
||||
Productos.descripcion,
|
||||
Productos.unidad,
|
||||
Productos.valor_unitario,
|
||||
)
|
||||
.where(Productos.id==id).dicts()[0]
|
||||
)
|
||||
obj = Productos.get(Productos.id==id)
|
||||
taxes = [row.id for row in obj.impuestos]
|
||||
return {'row': row, 'taxes': taxes}
|
||||
|
||||
rows = (Productos
|
||||
.select(
|
||||
Productos.id,
|
||||
Productos.clave,
|
||||
Productos.descripcion,
|
||||
SATUnidades.name.alias('unidad'),
|
||||
Productos.valor_unitario)
|
||||
.join(SATUnidades)
|
||||
.dicts()
|
||||
)
|
||||
return {'ok': True, 'rows': tuple(rows)}
|
||||
|
||||
def _clean(self, values):
|
||||
taxes = util.loads(values.pop('taxes'))
|
||||
fields = util.clean(values)
|
||||
|
||||
fields['es_activo'] = fields.pop('es_activo_producto')
|
||||
fields['descripcion'] = util.spaces(fields['descripcion'])
|
||||
fields['unidad'] = int(fields['unidad'])
|
||||
fields['valor_unitario'] = fields['valor_unitario'].replace(
|
||||
'$', '').replace(',', '')
|
||||
|
||||
fb = ('es_activo', 'inventario')
|
||||
for name in fb:
|
||||
fields[name] = bool(fields[name].replace('0', ''))
|
||||
|
||||
return fields, taxes
|
||||
|
||||
@classmethod
|
||||
def add(cls, values):
|
||||
fields, taxes = cls._clean(cls, values)
|
||||
|
||||
if Productos.select().where(Productos.clave==fields['clave']).exists():
|
||||
msg = 'Clave ya existe'
|
||||
return {'ok': False, 'msg': msg}
|
||||
|
||||
obj_taxes = SATImpuestos.select().where(SATImpuestos.id.in_(taxes))
|
||||
|
||||
with database_proxy.transaction():
|
||||
obj = Productos.create(**fields)
|
||||
obj.impuestos = obj_taxes
|
||||
row = {
|
||||
'id': obj.id,
|
||||
'clave': obj.clave,
|
||||
'descripcion': obj.descripcion,
|
||||
'unidad': obj.unidad.name,
|
||||
'valor_unitario': obj.valor_unitario,
|
||||
}
|
||||
data = {'ok': True, 'row': row, 'new': True}
|
||||
return data
|
||||
|
||||
@classmethod
|
||||
def actualizar(cls, values, id):
|
||||
fields, taxes = cls._clean(cls, values)
|
||||
obj_taxes = SATImpuestos.select().where(SATImpuestos.id.in_(taxes))
|
||||
with database_proxy.transaction():
|
||||
q = Productos.update(**fields).where(Productos.id==id)
|
||||
try:
|
||||
q.execute()
|
||||
except IntegrityError:
|
||||
msg = 'Ya existe un producto con esta clave'
|
||||
data = {'ok': False, 'row': {}, 'new': False, 'msg': msg}
|
||||
return data
|
||||
|
||||
obj = Productos.get(Productos.id==id)
|
||||
obj.impuestos = obj_taxes
|
||||
row = {
|
||||
'id': obj.id,
|
||||
'clave': obj.clave,
|
||||
'descripcion': obj.descripcion,
|
||||
'unidad': obj.unidad.name,
|
||||
'valor_unitario': obj.valor_unitario,
|
||||
}
|
||||
data = {'ok': True, 'row': row, 'new': False}
|
||||
return data
|
||||
|
||||
@classmethod
|
||||
def remove(cls, id):
|
||||
count = (FacturasDetalle
|
||||
.select(fn.COUNT(FacturasDetalle.id)).join(Productos)
|
||||
.where(Productos.id==id)
|
||||
.count()
|
||||
)
|
||||
if count:
|
||||
return False
|
||||
|
||||
with database_proxy.transaction():
|
||||
obj = Productos.get(Productos.id==id)
|
||||
obj.impuestos.clear()
|
||||
obj.tags.clear()
|
||||
q = Productos.delete().where(Productos.id==id)
|
||||
return bool(q.execute())
|
||||
|
||||
|
||||
class Facturas(BaseModel):
|
||||
cliente = ForeignKeyField(Socios)
|
||||
|
@ -553,6 +701,10 @@ def get_cp(cp):
|
|||
return data
|
||||
|
||||
|
||||
def get_sat_key(key):
|
||||
return util.get_sat_key('products', key)
|
||||
|
||||
|
||||
def _init_values():
|
||||
data = (
|
||||
{'key': 'version', 'value': VERSION},
|
||||
|
|
|
@ -18,6 +18,7 @@ PATH_TEMPLATES = os.path.abspath(os.path.join(BASE_DIR, '..', 'templates'))
|
|||
|
||||
PATH_CP = os.path.abspath(os.path.join(BASE_DIR, '..', 'db', 'cp.db'))
|
||||
COMPANIES = os.path.abspath(os.path.join(BASE_DIR, '..', 'db', 'rfc.db'))
|
||||
DB_SAT = os.path.abspath(os.path.join(BASE_DIR, '..', 'db', 'sat.db'))
|
||||
|
||||
template_lookup = TemplateLookup(directories=[PATH_TEMPLATES],
|
||||
input_encoding='utf-8',
|
||||
|
|
Binary file not shown.
|
@ -7,6 +7,13 @@
|
|||
],
|
||||
"regimen": "603"
|
||||
},
|
||||
{
|
||||
"tabla": "Categorias",
|
||||
"datos": [
|
||||
{"categoria": "Productos"},
|
||||
{"categoria": "Servicios"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tabla": "SATImpuestos",
|
||||
"datos": [
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
var PUBLICO = "Público en general";
|
||||
var RFC_PUBLICO = "XAXX010101000";
|
||||
var RFC_EXTRANJERO = "XEXX010101000";
|
||||
var PAIS = "México";
|
||||
|
||||
|
||||
var controllers = {
|
||||
|
@ -30,17 +26,18 @@ var controllers = {
|
|||
$$("cmd_delete_product").attachEvent("onItemClick", cmd_delete_product_click);
|
||||
$$("cmd_save_product").attachEvent("onItemClick", cmd_save_product_click);
|
||||
$$("cmd_cancel_product").attachEvent("onItemClick", cmd_cancel_product_click);
|
||||
$$("chk_automatica").attachEvent("onChange", chk_automatica_change)
|
||||
$$("valor_unitario").attachEvent("onChange", valor_unitario_change)
|
||||
//~ Invoices
|
||||
$$("cmd_new_invoice").attachEvent("onItemClick", cmd_new_invoice_click);
|
||||
$$("cmd_edit_invoice").attachEvent("onItemClick", cmd_edit_invoice_click);
|
||||
$$("cmd_delete_invoice").attachEvent("onItemClick", cmd_delete_invoice_click);
|
||||
$$("cmd_save_invoice").attachEvent("onItemClick", cmd_save_invoice_click);
|
||||
$$("cmd_cancel_invoice").attachEvent("onItemClick", cmd_cancel_invoice_click);
|
||||
|
||||
//~ get_partners()
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function get_partners(){
|
||||
webix.ajax().get("/partners", {}, {
|
||||
error: function(text, data, xhr) {
|
||||
|
@ -56,6 +53,24 @@ function get_partners(){
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
function get_products(){
|
||||
var grid = $$('grid_products')
|
||||
webix.ajax().get('/products', {}, {
|
||||
error: function(text, data, xhr) {
|
||||
webix.message({type: 'error', text: 'Error al consultar'})
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
grid.clearAll();
|
||||
if (values.ok){
|
||||
grid.parse(values.rows, 'json');
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function menu_user_click(id, e, node){
|
||||
if (id == 1){
|
||||
window.location = '/logout';
|
||||
|
@ -71,5 +86,26 @@ function multi_change(prevID, nextID){
|
|||
if(active == 'partners_home'){
|
||||
get_partners()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if(nextID == 'app_products'){
|
||||
active = $$('multi_products').getActiveId()
|
||||
if(active == 'products_home'){
|
||||
get_products()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function get_taxes(){
|
||||
webix.ajax().sync().get('/values/taxes', function(text, data){
|
||||
var values = data.json()
|
||||
table_taxes.clear()
|
||||
table_taxes.insert(values)
|
||||
$$("grid_product_taxes").clearAll()
|
||||
$$("grid_product_taxes").parse(values, 'json')
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,43 +1,203 @@
|
|||
|
||||
|
||||
function cmd_new_product_click(id, e, node){
|
||||
|
||||
$$('form_product').setValues({
|
||||
id: 0, es_activo_producto: true})
|
||||
add_config({'key': 'id_product', 'value': ''})
|
||||
get_new_key()
|
||||
get_taxes()
|
||||
$$('grid_products').clearSelection()
|
||||
$$('categoria').getList().load('/values/categorias')
|
||||
$$('unidad').getList().load('/values/unidades')
|
||||
$$("multi_products").setValue("product_new")
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function cmd_edit_product_click(id, e, node){
|
||||
|
||||
$$("multi_products").setValue("product_new")
|
||||
|
||||
};
|
||||
|
||||
|
||||
function cmd_delete_product_click(id, e, node){
|
||||
|
||||
webix.message({type:"success", text: "OK Delete"});
|
||||
|
||||
};
|
||||
|
||||
|
||||
function cmd_save_product_click(id, e, node){
|
||||
var form = this.getFormView();
|
||||
|
||||
if (!form.validate()) {
|
||||
webix.message({ type:"error", text:"Valores inválidos" });
|
||||
var grid = $$('grid_products')
|
||||
var row = grid.getSelectedItem()
|
||||
if(row == undefined){
|
||||
webix.message({type: 'error', text: 'Selecciona un Producto'})
|
||||
return
|
||||
}
|
||||
|
||||
$$('form_product').clear();
|
||||
$$("multi_products").setValue("products_home")
|
||||
webix.message({type:"success", text: "Producto guardado correctamente"});
|
||||
get_taxes()
|
||||
$$('categoria').getList().load('/values/categorias')
|
||||
$$('unidad').getList().load('/values/unidades')
|
||||
|
||||
webix.ajax().get('/products', {id:row['id']}, {
|
||||
error: function(text, data, xhr) {
|
||||
webix.message({type: 'error', text: 'Error al consultar'})
|
||||
},
|
||||
success: function(text, data, xhr){
|
||||
var values = data.json()
|
||||
$$('form_product').setValues(values.row)
|
||||
add_config({'key': 'id_product', 'value': values.row.id})
|
||||
for(i = 0; i < values.taxes.length; i++){
|
||||
$$('grid_product_taxes').select(values.taxes[i], true)
|
||||
}
|
||||
}
|
||||
})
|
||||
$$('multi_products').setValue('product_new')
|
||||
|
||||
};
|
||||
|
||||
|
||||
function delete_product(id){
|
||||
webix.ajax().del('/products', {id:id}, function(text, xml, xhr){
|
||||
var msg = 'Producto eliminado correctamente'
|
||||
if(xhr.status == 200){
|
||||
$$('grid_products').remove(id)
|
||||
webix.message({type:'success', text:msg})
|
||||
}else{
|
||||
msg = 'No se pudo eliminar'
|
||||
webix.message({type:'error', text:msg})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_delete_product_click(id, e, node){
|
||||
var row = $$('grid_products').getSelectedItem()
|
||||
if (row == undefined){
|
||||
webix.message({type:'error', text: 'Selecciona un Producto'})
|
||||
return
|
||||
}
|
||||
|
||||
var msg = '¿Estás seguro de eliminar el Producto?<BR><BR>'
|
||||
msg += '(' + row['clave'] + ') ' + row['descripcion']
|
||||
msg += '<BR><BR>ESTA ACCIÓN NO SE PUEDE DESHACER<BR><BR>Se recomienda '
|
||||
msg += 'solo desactivar el producto en vez de eliminar'
|
||||
webix.confirm({
|
||||
title: 'Eliminar Producto',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if (result){
|
||||
delete_product(row['id'])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function validate_sat_key_product(key, text){
|
||||
var result = false
|
||||
webix.ajax().sync().get('/values/satkey', {key:key}, function(text, data){
|
||||
result = data.json()
|
||||
})
|
||||
if(text){
|
||||
if(result.ok){
|
||||
return '<b>' + result.text + '</b>'
|
||||
}else{
|
||||
return '<b><font color="red">' + result.text + '</font></b>'
|
||||
}
|
||||
}
|
||||
return result.ok
|
||||
}
|
||||
|
||||
|
||||
function update_grid_products(values){
|
||||
var msg = 'Producto agregado correctamente'
|
||||
if(values.new){
|
||||
$$('form_product').clear()
|
||||
$$('grid_products').add(values.row)
|
||||
}else{
|
||||
msg = 'Producto actualizado correctamente'
|
||||
$$("grid_products").updateItem(values.row['id'], values.row)
|
||||
}
|
||||
$$('multi_products').setValue('products_home')
|
||||
webix.message({type: 'success', text: msg})
|
||||
}
|
||||
|
||||
|
||||
function cmd_save_product_click(id, e, node){
|
||||
var msg = ''
|
||||
var form = this.getFormView()
|
||||
|
||||
if(!form.validate()){
|
||||
webix.message({type: 'error', text: 'Valores inválidos'})
|
||||
return
|
||||
}
|
||||
|
||||
var rows = $$('grid_product_taxes').getSelectedId(true, true)
|
||||
if (rows.length == 0){
|
||||
webix.message({type: 'error', text: 'Selecciona un impuesto'})
|
||||
return
|
||||
}
|
||||
|
||||
var values = form.getValues();
|
||||
|
||||
if (!validate_sat_key_product(values.clave_sat, false)){
|
||||
webix.message({ type:'error', text:'La clave SAT no existe' })
|
||||
return
|
||||
}
|
||||
|
||||
values['taxes'] = JSON.stringify(rows)
|
||||
webix.ajax().sync().post('products', values, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
webix.message({type: 'error', text: msg})
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
var values = data.json();
|
||||
if (values.ok) {
|
||||
update_grid_products(values)
|
||||
}else{
|
||||
webix.message({type:'error', text:values.msg})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_cancel_product_click(id, e, node){
|
||||
|
||||
$$("multi_products").setValue("products_home")
|
||||
|
||||
};
|
||||
|
||||
|
||||
function chk_automatica_change(new_value, old_value){
|
||||
var value = Boolean(new_value)
|
||||
if (value){
|
||||
var value = get_config('id_product')
|
||||
if(value){
|
||||
$$("clave").setValue(value)
|
||||
$$("clave").refresh()
|
||||
}else{
|
||||
get_new_key()
|
||||
}
|
||||
$$("clave").config.readonly = true
|
||||
$$('form_product').focus('clave_sat')
|
||||
} else {
|
||||
$$("clave").setValue('')
|
||||
$$("clave").config.readonly = false
|
||||
$$('form_product').focus('clave')
|
||||
}
|
||||
$$("clave").refresh()
|
||||
}
|
||||
|
||||
|
||||
function get_new_key(){
|
||||
webix.ajax().get('/values/newkey', {
|
||||
error: function(text, data, xhr) {
|
||||
webix.message({type:'error', text: text})
|
||||
},
|
||||
success: function(text, data, xhr) {
|
||||
var values = data.json();
|
||||
$$("clave").setValue(values.value)
|
||||
$$("clave").refresh()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function valor_unitario_change(new_value, old_value){
|
||||
if(!isFinite(new_value)){
|
||||
this.config.value = old_value
|
||||
this.refresh()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,43 @@
|
|||
var PUBLICO = "Público en general";
|
||||
var RFC_PUBLICO = "XAXX010101000";
|
||||
var RFC_EXTRANJERO = "XEXX010101000";
|
||||
var PAIS = "México";
|
||||
|
||||
|
||||
var db = new loki('data.db');
|
||||
var table_config = db.addCollection('config')
|
||||
var table_taxes = db.addCollection('taxes')
|
||||
var table_pt = db.addCollection('productstaxes')
|
||||
var table_totals = db.addCollection('totals', {unique: ['tax']})
|
||||
|
||||
|
||||
function show(values){
|
||||
webix.message(JSON.stringify(values, null, 2))
|
||||
}
|
||||
|
||||
|
||||
webix.protoUI({
|
||||
$cssName: "text",
|
||||
name: "currency",
|
||||
$init:function(){
|
||||
this.attachEvent("onItemClick", function(){
|
||||
this.$setValue(this.config.raw, true)
|
||||
})
|
||||
this.attachEvent("onBlur", function(){
|
||||
this.$setValue(this.config.value)
|
||||
})
|
||||
},
|
||||
$render:function(){
|
||||
this.$setValue(this.config.value)
|
||||
},
|
||||
$setValue:function(value, raw){
|
||||
this.config.raw = value
|
||||
if(!raw){
|
||||
value = webix.i18n.priceFormat(value)
|
||||
}
|
||||
this.getInputNode().value = value
|
||||
}
|
||||
}, webix.ui.text)
|
||||
|
||||
|
||||
webix.ui.datafilter.rowCount = webix.extend({
|
||||
|
@ -68,3 +108,24 @@ function validate_email(email){
|
|||
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
return re.test(email)
|
||||
}
|
||||
|
||||
|
||||
function add_config(args){
|
||||
var key = table_config.findOne({key: args.key})
|
||||
if(key===null){
|
||||
table_config.insert(args)
|
||||
}else{
|
||||
key.value = args.value
|
||||
table_config.update(key)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function get_config(value){
|
||||
var key = table_config.findOne({key: value})
|
||||
if(key===null){
|
||||
return ''
|
||||
}else{
|
||||
return key.value
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -12,14 +12,14 @@ var toolbar_products = [
|
|||
|
||||
var grid_products_cols = [
|
||||
{ id: "id", header: "ID", width: 75},
|
||||
{ id: "key", header: ["Clave", {content: "textFilter"}], width: 100,
|
||||
{ id: "clave", header: ["Clave", {content: "textFilter"}], width: 100,
|
||||
sort:"string" },
|
||||
{ id: "description", header: ["Descripción", {content: "textFilter"}],
|
||||
{ id: "descripcion", header: ["Descripción", {content: "textFilter"}],
|
||||
fillspace:true, sort:"string" },
|
||||
{ id: "unidad", header: ["Unidad", {content: "selectFilter"}], width: 150,
|
||||
sort:"string" },
|
||||
{ id: "price", header: ["Precio", {content: "numberFilter"}], width: 150,
|
||||
sort:"int", format: webix.i18n.priceFormat, css: "cell_right" },
|
||||
{ id: "valor_unitario", header: ["Precio", {content: "numberFilter"}], width: 150,
|
||||
sort:"int", format: webix.i18n.priceFormat, css: "right" },
|
||||
]
|
||||
|
||||
|
||||
|
@ -34,51 +34,81 @@ var grid_products = {
|
|||
columns: grid_products_cols,
|
||||
}
|
||||
|
||||
var suggest_categories = {
|
||||
view: "datasuggest",
|
||||
type: "tree",
|
||||
width: 400,
|
||||
body: { data: [] },
|
||||
}
|
||||
|
||||
|
||||
var grid_product_taxes_cols = [
|
||||
{id:"id", header:"ID", hidden: true},
|
||||
{id:"name", header:'Nombre'},
|
||||
{id:"tipo", header:'Tipo'},
|
||||
{id:"tasa", header:'Tasa'},
|
||||
]
|
||||
|
||||
|
||||
var grid_product_taxes = {
|
||||
view: 'datatable',
|
||||
id: 'grid_product_taxes',
|
||||
select: 'row',
|
||||
multiselect: true,
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
autowidth: true,
|
||||
headermenu: true,
|
||||
columns: grid_product_taxes_cols,
|
||||
}
|
||||
|
||||
//~ webix.ui({
|
||||
//~ view:"combo", suggest:{body:{view:"tree", data:[]}},
|
||||
//~ on:{onChange:function(newv, oldv){
|
||||
//~ webix.message("Value changed from: "+oldv+" to: "+newv);
|
||||
//~ }}, width:300
|
||||
//~ });
|
||||
|
||||
var controls_generals = [
|
||||
{view: 'checkbox', id: 'es_activo_producto', name: 'es_activo_producto',
|
||||
label: 'Activo: ', value: true,
|
||||
bottomLabel: 'Se recomienda solo desactivar y no eliminar'},
|
||||
{cols: [
|
||||
{view: 'combo', id: 'categoria', name: 'categoria',
|
||||
label: 'Categoría', labelPosition: 'top',
|
||||
suggest: {body: {view: 'tree', data:[]}}},
|
||||
{view: 'combo', id: 'categoria', name: 'categoria', label: 'Categoría',
|
||||
labelPosition: 'top', options: suggest_categories},
|
||||
{view: 'text', id: 'clave', name: 'clave', label: 'Clave',
|
||||
labelPosition: 'top', readonly: true, required: true},
|
||||
{view: 'checkbox', label: 'Automática', labelPosition: 'top',
|
||||
value: true, maxWidth: 80},
|
||||
{view: 'text', id: 'clave_sat', name: 'clave_sat', label: 'Clave SAT',
|
||||
labelPosition: 'top', required: true},
|
||||
{view: 'checkbox', id: 'chk_automatica', label: 'Automática',
|
||||
labelPosition: 'top', value: true, maxWidth: 80},
|
||||
{view: 'search', id: 'clave_sat', name: 'clave_sat', label: 'Clave SAT',
|
||||
labelPosition: 'top', required: true, placeholder: 'Buscar clave...'},
|
||||
]},
|
||||
{view: 'text', id: 'codigo_barras', name: 'codigo_barras',
|
||||
label: 'Código de Barras', labelPosition: 'top'},
|
||||
{view: "textarea", id: "description", name: "description", height: 200,
|
||||
{cols: [
|
||||
{view: 'text', id: 'codigo_barras', name: 'codigo_barras',
|
||||
label: 'Código de Barras', labelPosition: 'top', hidden: true},
|
||||
{view: 'text', id: 'cuenta_predial', name: 'cuenta_predial',
|
||||
label: 'Cuenta Predial', labelPosition: 'top', hidden: true},
|
||||
{id: 'txt_col1'}]},
|
||||
{view: "textarea", id: "descripcion", name: "descripcion", height: 200,
|
||||
label: "Descripción", required: true, labelPosition: "top",
|
||||
invalidMessage: "La Descripción es requerida" },
|
||||
{cols: [{view: "text", id: "unidad", name: "unidad", label: "Unidad",
|
||||
width: 300, labelWidth: 130, labelAlign: "right", required: true,
|
||||
invalidMessage: "La Unidad es requerida" },{}]},
|
||||
{cols: [{view: "search", type: "text", id: "price", name: "price",
|
||||
label: "Valor Unitario", width: 300, labelWidth: 130,
|
||||
labelAlign: "right", required: true, icon: "calculator",
|
||||
invalidMessage: "Captura un valor númerico", inputAlign:"right" },{}]},
|
||||
{minHeight: 5},
|
||||
{cols: [
|
||||
{view: 'checkbox', id: 'inventario', name: 'inventario',
|
||||
label: 'Inventario', labelAlign: 'right', labelWidth: 130},
|
||||
{view: 'counter', id: 'existencia', name: 'existencia',
|
||||
label: 'Existencia', step: 5, value: 0, min: 0, disabled: true},
|
||||
{view: 'counter', id: 'minimo', name: 'minimo',
|
||||
label: 'Mínimo', step: 5, value: 0, min: 0, disabled: true},
|
||||
{view: "richselect", id: "unidad", name: "unidad", label: "Unidad",
|
||||
width: 300, labelWidth: 130, labelAlign: "right", required: true,
|
||||
invalidMessage: "La Unidad es requerida", options: []},
|
||||
{view: 'text', id: 'tags_producto', name: 'tags_producto',
|
||||
labelAlign: 'right', label: 'Etiquetas',
|
||||
placeholder: 'Separadas por comas'}
|
||||
]},
|
||||
{view: 'text', id: 'tags_producto', name: 'tags_producto', label: 'Etiquetas',
|
||||
tooltip: 'Utiles para filtrados rápidos. Separa por comas.'},
|
||||
{cols: [{view: "currency", type: "text", id: "valor_unitario",
|
||||
name: "valor_unitario", label: "Valor Unitario", width: 300,
|
||||
labelWidth: 130, labelAlign: "right", required: true,
|
||||
invalidMessage: "Captura un valor númerico", inputAlign: "right" },{}]},
|
||||
{cols: [
|
||||
{view: 'checkbox', id: 'inventario', name: 'inventario', hidden: true,
|
||||
label: 'Inventario', labelAlign: 'right', labelWidth: 130},
|
||||
{view: 'counter', id: 'existencia', name: 'existencia', hidden: true,
|
||||
label: 'Existencia', step: 5, value: 0, min: 0, disabled: true},
|
||||
{view: 'counter', id: 'minimo', name: 'minimo', hidden: true,
|
||||
label: 'Mínimo', step: 5, value: 0, min: 0, disabled: true},
|
||||
{id: 'txt_col2'}]},
|
||||
{cols:[{view:'label', label:'Impuestos', width: 300, align:'center'}, {}]},
|
||||
{cols:[grid_product_taxes, {}]}
|
||||
]
|
||||
|
||||
|
||||
|
@ -88,7 +118,7 @@ var controls_products = [
|
|||
tabbar: { options: ["Datos"]}, animate: true,
|
||||
cells: [
|
||||
{id: "Datos", rows: controls_generals},
|
||||
]
|
||||
],
|
||||
},
|
||||
{rows: [
|
||||
{ template:"", type: "section" },
|
||||
|
@ -110,9 +140,8 @@ var form_product = {
|
|||
complexData: true,
|
||||
elements: controls_products,
|
||||
rules: {
|
||||
description: function(value){ return value.trim() != ""; },
|
||||
unidad: function(value){ return value.trim() != ""; },
|
||||
price: function(value){ return value.trim() != ""; },
|
||||
descripcion: function(value){ return value.trim() != ""; },
|
||||
valor_unitario: function(value){ return value.trim() != "$"; },
|
||||
}
|
||||
}],
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<link rel="stylesheet" href="/static/css/app.css" type="text/css">
|
||||
<script src="/static/js/webix_debug.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/es-MX.js" type="text/javascript" ></script>
|
||||
<script src="/static/js/lokijs.min.js" type="text/javascript" ></script>
|
||||
<%block name="media"/>
|
||||
|
||||
</head>
|
||||
|
|
Loading…
Reference in New Issue