diff --git a/source/app/controllers/util.py b/source/app/controllers/util.py
index 6077607..fec29c8 100644
--- a/source/app/controllers/util.py
+++ b/source/app/controllers/util.py
@@ -235,6 +235,10 @@ def now():
return datetime.datetime.now().replace(microsecond=0)
+def today():
+ return datetime.date.today()
+
+
def get_token():
return _get_hash(uuid.uuid4().hex)
diff --git a/source/app/models/db.py b/source/app/models/db.py
index 693e05f..89df7f6 100644
--- a/source/app/models/db.py
+++ b/source/app/models/db.py
@@ -77,6 +77,9 @@ class StorageEngine(object):
years2 = main.PreFacturas.filter_years()
return [years1, years2]
+ def _get_filteryearsticket(self, values):
+ return main.Tickets.filter_years()
+
def _get_cuentayears(self, values):
return main.CuentasBanco.get_years()
@@ -258,6 +261,11 @@ class StorageEngine(object):
opt = values.pop('opt')
if opt == 'add':
return main.Tickets.add(values)
+ if opt == 'cancel':
+ return main.Tickets.cancel(values)
+
+ def get_tickets(self, values):
+ return main.Tickets.get_by(values)
def get_invoices(self, values):
return main.Facturas.get_(values)
diff --git a/source/app/models/main.py b/source/app/models/main.py
index c0a689b..bd5d43f 100644
--- a/source/app/models/main.py
+++ b/source/app/models/main.py
@@ -3972,6 +3972,73 @@ class Tickets(BaseModel):
data = {'ok': True, 'row': row}
return data
+ @classmethod
+ def cancel(cls, values):
+ id = int(values['id'])
+ msg = 'Ticket cancelado correctamente'
+ u = {'cancelado': True, 'estatus': 'Cancelado'}
+ obj = Tickets.update(**u).where(Tickets.id==id)
+ result = bool(obj.execute())
+ row = {'estatus': 'Cancelado'}
+ return {'ok': result, 'row': row, 'msg': msg}
+
+ def _get_filters(self, values):
+ opt = values.get('opt', '')
+ if not opt:
+ return
+
+ if opt == 'today':
+ t = util.today()
+ filters = (
+ (Tickets.fecha.day == t.day) &
+ (Tickets.fecha.month == t.month) &
+ (Tickets.fecha.year == t.year)
+ )
+ return filters
+
+ if opt == 'yearmonth':
+ if values['year'] == '-1':
+ fy = (Tickets.fecha.year > 0)
+ else:
+ fy = (Tickets.fecha.year == int(values['year']))
+ if values['month'] == '-1':
+ fm = (Tickets.fecha.month > 0)
+ else:
+ fm = (Tickets.fecha.month == int(values['month']))
+ filters = (fy & fm)
+ return filters
+
+ return
+
+ @classmethod
+ def get_by(cls, values):
+ filters = cls._get_filters(cls, values)
+
+ rows = tuple(Tickets
+ .select(
+ Tickets.id,
+ Tickets.serie,
+ Tickets.folio,
+ Tickets.fecha,
+ Tickets.estatus,
+ Tickets.total)
+ .where(filters)
+ .dicts()
+ )
+ return {'ok': True, 'rows': rows}
+
+ @classmethod
+ def filter_years(cls):
+ data = [{'id': -1, 'value': 'Todos'}]
+ rows = (Tickets
+ .select(Tickets.fecha.year.alias('year'))
+ .group_by(Tickets.fecha.year)
+ .order_by(Tickets.fecha.year)
+ )
+ if not rows is None:
+ data += [{'id': int(r.year), 'value': int(r.year)} for r in rows]
+ return tuple(data)
+
class TicketsDetalle(BaseModel):
ticket = ForeignKeyField(Tickets)
diff --git a/source/static/css/app.css b/source/static/css/app.css
index 3ddaa5a..0bd1d39 100644
--- a/source/static/css/app.css
+++ b/source/static/css/app.css
@@ -54,6 +54,10 @@
color: red;
}
+.cancel {
+ color: red;
+}
+
.cmd_close_partner div button {
background-color: red !important;
diff --git a/source/static/js/controller/main.js b/source/static/js/controller/main.js
index 1d707cb..f7be4f1 100644
--- a/source/static/js/controller/main.js
+++ b/source/static/js/controller/main.js
@@ -206,7 +206,10 @@ function multi_change(prevID, nextID){
}
if(nextID == 'app_tickets'){
-
+ active = $$('multi_tickets').getActiveId()
+ if(active == 'tickets_home'){
+ configuracion_inicial_ticket()
+ }
return
}
diff --git a/source/static/js/controller/tickets.js b/source/static/js/controller/tickets.js
index c1bfc63..6adcffa 100644
--- a/source/static/js/controller/tickets.js
+++ b/source/static/js/controller/tickets.js
@@ -7,28 +7,99 @@ var tickets_controllers = {
$$('cmd_nuevo_ticket').attachEvent('onItemClick', cmd_nuevo_ticket_click)
$$('cmd_generar_ticket').attachEvent('onItemClick', cmd_generar_ticket_click)
$$('cmd_cerrar_ticket').attachEvent('onItemClick', cmd_cerrar_ticket_click)
+ $$('cmd_cancelar_ticket').attachEvent('onItemClick', cmd_cancelar_ticket_click)
$$('tsearch_product_key').attachEvent('onKeyPress', tsearch_product_key_press)
$$('grid_tdetails').attachEvent('onItemClick', grid_ticket_details_click)
$$('grid_tdetails').attachEvent('onBeforeEditStop', grid_tickets_details_before_edit_stop)
$$('gt_productos_found').attachEvent('onValueSuggest', gt_productos_found_click)
+ $$('filter_year_ticket').attachEvent('onChange', filter_year_ticket_change)
+ $$('filter_month_ticket').attachEvent('onChange', filter_month_ticket_change)
+
+ webix.extend($$('grid_tickets'), webix.ProgressBar)
}
}
+function current_dates_tickets(){
+ var fy = $$('filter_year_ticket')
+ var fm = $$('filter_month_ticket')
+ var d = new Date()
+
+ fy.blockEvent()
+ fm.blockEvent()
+
+ fm.setValue(d.getMonth() + 1)
+ webix.ajax().sync().get('/values/filteryearsticket', function(text, data){
+ var values = data.json()
+ fy.getList().parse(values)
+ fy.setValue(d.getFullYear())
+ })
+
+ fy.unblockEvent()
+ fm.unblockEvent()
+}
+
+
+function get_tickets(filters){
+ if(filters == undefined){
+ filters = {'opt': 'today'}
+ }
+
+ var grid = $$('grid_tickets')
+ grid.showProgress({type: 'icon'})
+
+ webix.ajax().get('/tickets', filters, {
+ error: function(text, data, xhr) {
+ msg_error('Error al consultar')
+ },
+ success: function(text, data, xhr) {
+ var values = data.json();
+ grid.clearAll();
+ if (values.ok){
+ grid.parse(values.rows, 'json')
+ }
+ }
+ })
+}
+
+
+function filter_year_ticket_change(nv, ov){
+ var fm = $$('filter_month_ticket')
+ filters = {'opt': 'yearmonth','year': nv, 'month': fm.getValue()}
+ get_tickets(filters)
+}
+
+
+function filter_month_ticket_change(nv, ov){
+ var fy = $$('filter_year_ticket')
+ filters = {'opt': 'yearmonth','year': fy.getValue(), 'month': nv}
+ get_tickets(filters)
+}
+
+
function configuracion_inicial_ticket(){
+ current_dates_tickets()
+ get_tickets()
+}
+
+
+function configuracion_inicial_nuevo_ticket(){
+ var grid = $$('grid_tdetails')
+
webix.ajax().sync().get('/values/taxes', function(text, data){
var values = data.json()
table_taxes.clear()
table_taxes.insert(values)
})
get_forma_pago('lst_ticket_forma_pago')
+ grid.clearAll()
table_pt.clear()
table_totals.clear()
}
function cmd_nuevo_ticket_click(){
- configuracion_inicial_ticket()
+ configuracion_inicial_nuevo_ticket()
$$('multi_tickets').setValue('tickets_new')
}
@@ -48,10 +119,10 @@ function validar_ticket(){
function guardar_ticket(values){
- var grid = $$('grid_tdetails')
- //~ showvar(values)
+ var gd = $$('grid_tdetails')
+ var grid = $$('grid_tickets')
- var rows = grid.data.getRange()
+ var rows = gd.data.getRange()
for (i = 0; i < rows.length; i++) {
delete rows[i]['delete']
delete rows[i]['clave']
@@ -77,6 +148,8 @@ function guardar_ticket(values){
if(values.ok){
msg_ok('Ticket generado correctamente')
$$('form_new_ticket').setValues({})
+ gd.clearAll()
+ grid.add(values.row)
$$('multi_tickets').setValue('tickets_home')
}else{
msg_error(values.msg)
@@ -264,3 +337,58 @@ function gt_productos_found_click(obj){
buscar_producto_key(obj.clave)
}
+
+function cancel_ticket(id){
+ var grid = $$('grid_tickets')
+ var data = new Object()
+ data['opt'] = 'cancel'
+ data['id'] = id
+
+ webix.ajax().sync().post('tickets', data, {
+ error:function(text, data, XmlHttpRequest){
+ msg = 'Ocurrio un error, consulta a soporte técnico'
+ msg_error(msg)
+ },
+ success:function(text, data, XmlHttpRequest){
+ values = data.json();
+ if(values.ok){
+ grid.updateItem(id, values.row)
+ msg_ok(values.msg)
+ }else{
+ msg_error(values.msg)
+ }
+ }
+ })
+}
+
+
+function cmd_cancelar_ticket_click(){
+ var grid = $$('grid_tickets')
+
+ if(grid.count() == 0){
+ return
+ }
+
+ var row = grid.getSelectedItem()
+ if (row == undefined){
+ msg_error('Selecciona un ticket')
+ return
+ }
+
+ msg = '¿Estás seguro de cancelar el siguiente Ticket?
'
+ msg += 'Folio: ' + row['folio']
+ msg += '
ESTA ACCIÓN NO SE PUEDE DESHACER'
+ webix.confirm({
+ title:'Cancelar Ticket',
+ ok:'Si',
+ cancel:'No',
+ type:'confirm-error',
+ text:msg,
+ callback:function(result){
+ if (result){
+ cancel_ticket(row['id'])
+ }
+ }
+ })
+
+}
\ No newline at end of file
diff --git a/source/static/js/controller/util.js b/source/static/js/controller/util.js
index fc8e90d..0beb469 100644
--- a/source/static/js/controller/util.js
+++ b/source/static/js/controller/util.js
@@ -39,7 +39,7 @@ function get_icon(tipo){
pdf: 'fa-file-pdf-o',
zip: 'fa-file-zip-o',
email: 'fa-envelope-o',
- print: 'print',
+ print: 'fa-print',
}
return ""
}
diff --git a/source/static/js/ui/invoices.js b/source/static/js/ui/invoices.js
index c183c19..7d1327a 100644
--- a/source/static/js/ui/invoices.js
+++ b/source/static/js/ui/invoices.js
@@ -216,6 +216,13 @@ var grid_invoices = {
resizeColumn: true,
headermenu: true,
columns: grid_invoices_cols,
+ scheme:{
+ $change:function(item){
+ if (item.estatus == 'Cancelada'){
+ item.$css = 'cancel'
+ }
+ }
+ },
on:{
'data->onStoreUpdated':function(){
this.data.each(function(obj, i){
diff --git a/source/static/js/ui/partners.js b/source/static/js/ui/partners.js
index 4b763fe..bc082c7 100644
--- a/source/static/js/ui/partners.js
+++ b/source/static/js/ui/partners.js
@@ -12,7 +12,7 @@ var toolbar_partners = [
var grid_partners_cols = [
{id: 'index', header:'#', css: 'right',
- footer: {content: 'rowCount', colspan: 2, css: 'right'}},
+ footer: {content: 'countRows', colspan: 2, css: 'right'}},
{id: 'id', header: 'Clave', sort: 'int', css: 'right'},
{id: 'rfc', header: ['RFC', {content: 'textFilter'}], adjust: 'data',
sort: 'string', footer: {text: 'Clientes y Proveedores', colspan: 2}},
@@ -143,7 +143,7 @@ var toolbar_contacts = [
var grid_contacts_cols = [
{id: 'index', header: '#', adjust:'data', css:'right',
- footer: {content: 'rowCount'}},
+ footer: {content: 'countRows'}},
{id: 'id', header: '', hidden: true},
{id: 'title', header: 'Título', adjust:'data', sort: 'string',
footer: 'Contactos'},
diff --git a/source/static/js/ui/tickets.js b/source/static/js/ui/tickets.js
index 7087603..a60051c 100644
--- a/source/static/js/ui/tickets.js
+++ b/source/static/js/ui/tickets.js
@@ -24,8 +24,8 @@ var grid_tickets_cols = [
footer: {content: 'countRows', colspan: 3, css: 'right'}},
{id: "id", header:"ID", hidden:true},
{id: "serie", header: ["Serie", {content: "selectFilter"}], adjust: "data",
- sort:"string"},
- {id: 'folio', header: ['Folio', {content: 'numberFilter'}], adjust: 'data',
+ sort:"string", hidden: true},
+ {id: 'folio', header: ['Folio', {content: 'numberFilter'}], adjust: 'header',
sort: 'int', css: 'right', footer: {text: 'Tickets', colspan: 3}},
{id: "fecha", header: ["Fecha y Hora"],
adjust: "data", sort: "date"},
@@ -37,7 +37,6 @@ var grid_tickets_cols = [
fillspace:true, sort:"string", hidden: true},
{id: 'pdf', header: 'PDF', adjust: 'data', template: get_icon('pdf')},
{id: 'print', header: 'I', adjust: 'data', template: get_icon('print')},
- {id: 'email', header: '', adjust: 'data', template: get_icon('email')}
]
@@ -50,6 +49,13 @@ var grid_tickets = {
resizeColumn: true,
headermenu: true,
columns: grid_tickets_cols,
+ scheme:{
+ $change:function(item){
+ if (item.estatus == 'Cancelado'){
+ item.$css = 'cancel'
+ }
+ }
+ },
on:{
'data->onStoreUpdated':function(){
this.data.each(function(obj, i){