Imprimir ticket
This commit is contained in:
parent
3e323678d7
commit
fad45cb502
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
#~ import falcon
|
||||
import os
|
||||
import re
|
||||
import smtplib
|
||||
import ssl
|
||||
|
@ -13,8 +13,8 @@ from email.mime.text import MIMEText
|
|||
from email import encoders
|
||||
from email.utils import formatdate
|
||||
|
||||
import os
|
||||
import requests
|
||||
from escpos import printer
|
||||
|
||||
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate, Image
|
||||
from reportlab.lib import colors
|
||||
|
@ -949,3 +949,92 @@ class SeaFileAPI(object):
|
|||
resp = requests.get(url, headers=self._headers)
|
||||
return resp.json()
|
||||
|
||||
|
||||
class PrintTicket(object):
|
||||
LINE = '------------------------------------------------\n'
|
||||
TITLES = 'CANT. U ARTICULO P.U. TOTAL\n'
|
||||
LEYENDA = 'GRACIAS POR SU COMPRA\n\nGuarde este ticket para cualquier ' \
|
||||
'aclaración.\nComprobante simplificado de operación con\npúblico en ' \
|
||||
'general de acuerdo al Art. 37\nFracc II inc. v del Reglamento del\n' \
|
||||
'Código Fiscal de la Federación.\n\n'
|
||||
|
||||
def __init__(self, info):
|
||||
self.p = self._init_printer(info)
|
||||
|
||||
def _init_printer(self, info):
|
||||
try:
|
||||
if info['ip']:
|
||||
p = printer.Network(info['ip'])
|
||||
else:
|
||||
p = printer.Usb(*info['usb'])
|
||||
p.codepage = 'cp850'
|
||||
return p
|
||||
except Exception as e:
|
||||
print (e)
|
||||
return
|
||||
|
||||
def _set(self, *data):
|
||||
self.p.set(*data)
|
||||
return
|
||||
|
||||
def _t(self, text):
|
||||
self.p.text(text)
|
||||
return
|
||||
|
||||
def _l(self):
|
||||
self._t(self.LINE)
|
||||
return
|
||||
|
||||
def printer(self, data):
|
||||
if self.p is None:
|
||||
return False
|
||||
|
||||
self._emisor(data['emisor'])
|
||||
self._receptor(data['receptor'])
|
||||
self._ticket(data['ticket'])
|
||||
self._products(data['products'])
|
||||
self._footer(data['ticket'])
|
||||
self.p.cut()
|
||||
return True
|
||||
|
||||
def _emisor(self, data):
|
||||
self._set('center', 'B', 'B', 2, 2)
|
||||
self._t(data['name'])
|
||||
self._set('center', 'B', 'B', 2)
|
||||
self._t(data['rfc'])
|
||||
self._set('center', 'A')
|
||||
self._t(data['address'])
|
||||
return
|
||||
|
||||
def _receptor(self, data):
|
||||
self._set('center', 'B', 'B', 2)
|
||||
self._t(data['name'])
|
||||
return
|
||||
|
||||
def _ticket(self, data):
|
||||
self._set('left', 'B', 'B', 2)
|
||||
self._t(data['title'])
|
||||
self._set('left', 'A')
|
||||
self._t(data['date'])
|
||||
return
|
||||
|
||||
def _products(self, data):
|
||||
self._l()
|
||||
self._t(self.TITLES)
|
||||
self._l()
|
||||
for p in data:
|
||||
self._t(p)
|
||||
self._l()
|
||||
self._t('Total artículos: {}\n'.format(len(data)))
|
||||
self._l()
|
||||
return
|
||||
|
||||
def _footer(self, data):
|
||||
self._set('right', 'B', 'B', 2)
|
||||
self._t(data['total'])
|
||||
self._set('center', 'A')
|
||||
self._t(data['letters'])
|
||||
self._t(self.LEYENDA)
|
||||
self._set('center', 'A', 'B')
|
||||
self._t('empresalibre.net')
|
||||
return
|
|
@ -36,7 +36,7 @@ import pyqrcode
|
|||
from dateutil import parser
|
||||
|
||||
from .helper import CaseInsensitiveDict, NumLet, SendMail, TemplateInvoice, \
|
||||
SeaFileAPI
|
||||
SeaFileAPI, PrintTicket
|
||||
from settings import DEBUG, MV, log, template_lookup, COMPANIES, DB_SAT, \
|
||||
PATH_XSLT, PATH_XSLTPROC, PATH_OPENSSL, PATH_TEMPLATES, PATH_MEDIA, PRE, \
|
||||
PATH_XMLSEC, TEMPLATE_CANCEL, DEFAULT_SAT_PRODUCTO, DECIMALES, DIR_FACTURAS
|
||||
|
@ -1705,12 +1705,12 @@ class ImportFacturaLibreGambas(object):
|
|||
('cfdifacturas', 'Facturas'),
|
||||
('categorias', 'Categorias'),
|
||||
('productos', 'Productos'),
|
||||
# ~ ('tickets', 'Tickets'),
|
||||
('tickets', 'Tickets'),
|
||||
)
|
||||
for source, target in tables:
|
||||
data[target] = self._get_table(source)
|
||||
|
||||
# ~ data['Socios'] += self._clientes
|
||||
data['Socios'] += self._clientes
|
||||
|
||||
return data
|
||||
|
||||
|
@ -2505,3 +2505,8 @@ class ImportFacturaLibre(object):
|
|||
|
||||
data.append(new)
|
||||
return data
|
||||
|
||||
|
||||
def print_ticket(data, info):
|
||||
p = PrintTicket(info)
|
||||
return p.printer(data)
|
||||
|
|
|
@ -268,6 +268,8 @@ class StorageEngine(object):
|
|||
return main.Tickets.cancel(values)
|
||||
if opt == 'invoice':
|
||||
return main.Tickets.invoice(values)
|
||||
if opt == 'print':
|
||||
return main.Tickets.printer(values)
|
||||
|
||||
def get_tickets(self, values):
|
||||
return main.Tickets.get_by(values)
|
||||
|
|
|
@ -17,7 +17,7 @@ if __name__ == '__main__':
|
|||
from controllers import util
|
||||
from settings import log, VERSION, PATH_CP, COMPANIES, PRE, CURRENT_CFDI, \
|
||||
INIT_VALUES, DEFAULT_PASSWORD, DECIMALES, IMPUESTOS, DEFAULT_SAT_PRODUCTO, \
|
||||
CANCEL_SIGNATURE
|
||||
CANCEL_SIGNATURE, PUBLIC
|
||||
|
||||
|
||||
FORMAT = '{0:.2f}'
|
||||
|
@ -4328,6 +4328,63 @@ class Tickets(BaseModel):
|
|||
doc = util.to_pdf(data, data['emisor']['rfc'])
|
||||
return doc, name
|
||||
|
||||
def _format_ticket(self, id):
|
||||
emisor = util.get_dict(Emisor.select().dicts()[0])
|
||||
ticket = Tickets.select().where(Tickets.id==id).dicts()[0]
|
||||
products = TicketsDetalle.get_by_print(id)
|
||||
|
||||
emisor['name'] = '{}\n'.format(emisor['nombre'])
|
||||
emisor['rfc'] = 'RFC: {}\n'.format(emisor['rfc'])
|
||||
interior = ''
|
||||
if emisor['no_interior']:
|
||||
interior = ', {}'.format(emisor['no_interior'])
|
||||
colonia = ''
|
||||
if emisor['colonia']:
|
||||
colonia = ', Col. {}'.format(emisor['colonia'])
|
||||
municipio = ''
|
||||
if emisor['municipio']:
|
||||
municipio = ', {}'.format(emisor['municipio'])
|
||||
estado = ''
|
||||
if emisor['estado']:
|
||||
estado = ', {}'.format(emisor['estado'])
|
||||
cp = ''
|
||||
if emisor['codigo_postal']:
|
||||
cp = ', C.P. {}'.format(emisor['codigo_postal'])
|
||||
pais = ''
|
||||
if emisor['pais']:
|
||||
pais = ', {}'.format(emisor['pais'])
|
||||
direccion = '{} {}{}{}{}{}{}{}\n\n'.format(emisor['calle'],
|
||||
emisor['no_exterior'], interior, colonia, municipio, estado, cp,
|
||||
pais)
|
||||
emisor['address'] = direccion
|
||||
|
||||
ticket['title'] = 'Ticket: {}{}\n\n'.format(ticket['serie'],
|
||||
ticket['folio'])
|
||||
ticket['date'] = 'Fecha y hora: {}\n'.format(ticket['fecha'])
|
||||
ticket['letters'] = '{}\n\n'.format(
|
||||
util.to_letters(ticket['total'], 'peso'))
|
||||
ticket['total'] = 'TOTAL: $ {:>12,.2f}\n\n'.format(ticket['total'])
|
||||
|
||||
data = {
|
||||
'emisor': emisor,
|
||||
'receptor': {'name': '{}\n\n'.format(PUBLIC)},
|
||||
'ticket': ticket,
|
||||
'products': products,
|
||||
}
|
||||
return data
|
||||
|
||||
@classmethod
|
||||
def printer(cls, values):
|
||||
id = int(values['id'])
|
||||
info = {'ip': '', 'usb': (int('1ba0', 16), int('2204', 16))}
|
||||
data = cls._format_ticket(cls, id)
|
||||
result = util.print_ticket(data, info)
|
||||
msg = 'Ticket impreso correctamente'
|
||||
if not result:
|
||||
msg = 'Asegurate de que la impresora este conectada y funcionando.'
|
||||
result = {'ok': result, 'msg': msg}
|
||||
return result
|
||||
|
||||
|
||||
class TicketsDetalle(BaseModel):
|
||||
ticket = ForeignKeyField(Tickets)
|
||||
|
@ -4356,6 +4413,21 @@ class TicketsDetalle(BaseModel):
|
|||
|
||||
return precio_final
|
||||
|
||||
@classmethod
|
||||
def get_by_print(cls, id):
|
||||
products = TicketsDetalle.select().where(TicketsDetalle.ticket==id)
|
||||
lines = []
|
||||
for p in products:
|
||||
price_with_tax = cls._with_tax(cls, p)
|
||||
importe = round(price_with_tax * float(p.cantidad), DECIMALES)
|
||||
l = '{:>6,.2f} {:<4} {:<14} {:>9,.2f} {:>10,.2f}\n'.format(
|
||||
p.cantidad, p.producto.unidad.name, p.descripcion,
|
||||
price_with_tax, importe
|
||||
)
|
||||
lines.append(l)
|
||||
|
||||
return lines
|
||||
|
||||
@classmethod
|
||||
def get_by_ticket(cls, id):
|
||||
data = []
|
||||
|
|
|
@ -117,4 +117,5 @@ IMPUESTOS = {
|
|||
DEFAULT_SAT_PRODUCTO = '01010101'
|
||||
DIR_FACTURAS = 'facturas'
|
||||
USAR_TOKEN = False
|
||||
CANCEL_SIGNATURE = False
|
||||
CANCEL_SIGNATURE = False
|
||||
PUBLIC = 'Público en general'
|
|
@ -651,11 +651,38 @@ function ticket_notes_key_up(){
|
|||
}
|
||||
|
||||
|
||||
function print_ticket(id){
|
||||
var data = new Object()
|
||||
data['opt'] = 'print'
|
||||
data['id'] = id
|
||||
|
||||
webix.ajax().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){
|
||||
msg_ok(values.msg)
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function grid_tickets_click(id, e, node){
|
||||
//~ var row = this.getItem(id)
|
||||
if(id.column == 'pdf'){
|
||||
//~ window.open('/doc/tpdf/' + id, '_blank')
|
||||
get_ticket_pdf(id)
|
||||
get_ticket_pdf(id.row)
|
||||
return
|
||||
}
|
||||
|
||||
if(id.column == 'print'){
|
||||
print_ticket(id.row)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
|
@ -38,7 +38,7 @@ var grid_tickets_cols = [
|
|||
{id: "cliente", header: ["Razón Social", {content: "selectFilter"}],
|
||||
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: 'print', header: '', adjust: 'data', template: get_icon('print')},
|
||||
]
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue