Imprimir ticket

This commit is contained in:
Mauricio Baeza 2018-01-01 02:14:30 -06:00
parent 3e323678d7
commit fad45cb502
7 changed files with 206 additions and 10 deletions

View File

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

View File

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

View File

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

View File

@ -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 = []

View File

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

View File

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

View File

@ -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')},
]