presik_pos/app/reporting.py

1029 lines
37 KiB
Python
Executable File

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import os
import logging
from datetime import datetime
from decimal import Decimal
from .printing.protocols import FileSSH
try:
from escpos import printer
except ImportError as error:
logging.warning(f"Error importing ! {error}")
pyudev = None
try:
import pyudev
except ImportError as error:
logging.warning(f"Error importing ! {error}")
try:
import cups
except ImportError as error:
logging.warning(f"Error importing ! {error}")
__all__ = ['Receipt']
_ROW_CHARACTERS = 48
_DIGITS = 9
_PRINT_TAX_ID = False
_DIGITS_CODE_RECEIPT = 4
# Type Font Escpos
_FONT_A = 'a' # Normal Font
_FONT_B = 'b' # Condensed Font
if os.name == 'posix':
homex = 'HOME'
dirconfig = '.tryton/temp'
elif os.name == 'nt':
homex = 'USERPROFILE'
dirconfig = 'AppData/Local/tryton/temp'
HOME_DIR = os.getenv(homex)
directory = os.path.join(HOME_DIR, dirconfig)
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
image_test_file = os.path.join(ROOT_DIR, 'image_test.jpeg')
if not os.path.exists(directory):
os.makedirs(directory)
TEMP_INVOICE_FILE = os.path.join(directory, 'invoice.txt')
SSH_PORT = 23
def money(value):
if type(value) != int:
value = int(value)
return '{:,}'.format(value)
dev_printers = {}
if os.name == 'posix' and pyudev:
context = pyudev.Context()
for device in context.list_devices():
if device.subsystem == 'usbmisc':
# print(device.subsystem, device.sys_path.split('2-1/')[1][0:5], device.device_node)
# dev_printers[str(device.sys_path.split('2-1/')[1][0:5])] = device.device_node
pass
class Receipt(object):
__name__ = 'frontend_pos.ticket'
def __init__(self, context, row_characters=None, logo=None, environment='retail'):
self.logger = logging.getLogger('reporting')
self._company = context.get('company')
self._sale_device = context.get('sale_device')
self._shop = context.get('shop')
self._street = context.get('street')
self._city = context.get('city')
self._phone = context.get('phone')
self._id_number = context.get('id_number')
self._regime_tax = context.get('regime_tax')
self._gta_info = context.get('gta_info')
self._authorizations = context.get('authorizations')
self._user = context.get('user')
self._footer = context.get('footer')
self._header = context.get('header')
self._printing_taxes = context.get('printing_taxes')
self._print_invoice_payment = context.get('print_invoice_payment')
self._delta_locale = context.get('delta_locale')
self._environment = environment
self._row_characters = _ROW_CHARACTERS
if context.get('row_characters'):
self._row_characters = int(context.get('row_characters'))
taxes_col = int(self._row_characters / 3)
self.taxes_col_width1 = taxes_col + 4
self.taxes_col_width2 = taxes_col - 3
self.taxes_col_width3 = taxes_col - 1
delivery_col = int(self._row_characters / 3)
self.delivery_col_width1 = delivery_col
self.delivery_col_width2 = delivery_col - 1
self.delivery_col_width3 = delivery_col - 1
payments_col = int(self._row_characters / 3)
self.payments_col_width1 = payments_col + 3
self.payments_col_width2 = payments_col - 2
self.payments_col_width3 = payments_col
order_col_width = int(self._row_characters / 3)
self.order_col_1 = order_col_width - 10
self.order_col_2 = order_col_width + 15
self.order_col_3 = order_col_width - 5
if self._row_characters <= 33:
self.order_col_1 = order_col_width - 6
self._show_position = context.get('show_position')
self._show_discount = context.get('show_discount')
self._print_lines_product = context.get('print_lines_product')
self._img_logo = logo if logo else None
# if logo:
# self._img_logo = StringIO(logo)
def printer_found(self):
return self._printer
def test_printer(self):
if self._interface == 'usb':
if os.name == 'posix':
self._printer = printer.File(
self._device, profile=self._profile)
elif os.name == 'nt':
self._printer = printer.Win32Raw(self._device)
self._printer.open()
elif self._interface == 'network':
self._printer = printer.Network(self._device, timeout=15)
elif self._interface == 'ssh':
self._printer = FileSSH(*self._device.split('@'))
self._printer.open()
if not self._printer:
return
self.print_enter()
try:
self._printer.image(image_test_file, center=True)
except:
pass
self.print_enter()
self.print_header()
self.print_enter()
self.print_enter()
self.print_enter()
self._printer.cut()
self._printer.cashdraw(2)
# self._printer.beep()
def config_printer(self, printer):
if dev_printers.get(printer['device']):
device = dev_printers[printer['device']]
else:
device = printer['device']
self._interface = printer['interface']
self._device = device
self._profile = printer['profile']
def set_printer(self):
try:
if self._interface == 'usb':
if os.name == 'posix':
self._printer = printer.File(
self._device, profile=self._profile)
elif os.name == 'nt':
self._printer = printer.Win32Raw(self._device)
self._printer.open()
elif self._interface == 'network':
self._printer = printer.Network(self._device, timeout=15)
elif self._interface == 'ssh':
self._printer = FileSSH(*self._device.split('@'))
self._printer.open()
elif self._interface == 'cups':
self.conn = cups.Connection()
self._file = open(TEMP_INVOICE_FILE, 'w')
self._printer = CupsPrinter(self._file, self._row_characters)
if not self._printer:
self.logger.info("Warning: Can not found Printer!")
return
self.logger.info("Info: Printer is OK!")
except:
self.logger.info("Warning: Printer error or device not found!")
def print_sale(self, sale, type_doc=None, open_box=False):
try:
if self._interface == 'usb':
if os.name == 'posix':
self._printer = printer.File(
self._device, profile=self._profile)
elif os.name == 'nt':
self._printer = printer.Win32Raw(self._device)
self._printer.open()
elif self._interface == 'network':
self._printer = printer.Network(self._device, timeout=15)
elif self._interface == 'ssh':
self._printer = FileSSH(*self._device.split('@'))
self._printer.open()
elif self._interface == 'cups':
self.conn = cups.Connection()
self._file = open(TEMP_INVOICE_FILE, 'w')
self._printer = CupsPrinter(self._file, self._row_characters)
if not self._printer:
self.logger.info("Warning: Can not found Printer!")
return
self.logger.info("Info: Printer is OK!")
if type_doc == 'invoice' or self._environment == 'retail':
self._print_sale(sale, type_doc, open_box)
else:
self._print_sale_verification(sale)
except:
self.logger.info("Warning: Printer error or device not found!")
def _print_sale(self, sale, type_doc=None, open_box=False):
self.print_header()
self.print_body(sale, type_doc)
if sale.get('cufe'):
self._printer.text('CUFE: ' + sale['cufe'])
try:
if sale.get('qr_code'):
self.print_qrcode(sale['qr_code'])
except:
pass
self.print_footer(open_box)
# self.print_extra_info(sale)
if self._interface == 'cups':
self._file.close()
self.conn.printFile(self._printer_name, TEMP_INVOICE_FILE,
'POS Invoice', {})
else:
self._printer.close()
def _print_sale_verification(self, sale):
self.print_header_sale_verification(sale)
self.print_sale_lines(sale)
self.print_totals(sale)
self.print_enter()
self.print_enter()
self.print_enter()
self._printer.cut()
self.print_enter()
self.print_enter()
self._printer.close()
def print_line(self, *args):
text = ''
for arg in args:
text += arg + ' '
self._printer.text(text.rstrip())
def word_space(self, word, space, aling):
space = space - len(word)
if aling == 'right':
text = ' ' * space + word
elif aling == 'left':
text = word + ' ' * space
return text
def print_delivery_report(self, data):
self.set_printer()
self._printer.set(align='center')
self._printer.text('REPORTE DE ENTREGA DE DOMICILIARIOS')
self.print_enter()
self.print_enter()
self.print_horinzontal_line()
self._printer.set(align='left')
name = data['name']
sale_date = data['sale_date']
self._printer.text(f'DOMICILIARIO: {name}')
self.print_enter()
self._printer.text(f'FECHA: {sale_date}')
self.print_enter()
self.print_horinzontal_line()
self.print_enter()
for sale in data['sales']:
sale_total = self.word_space(money(sale['total']), 9, 'right')
sale_number = self.word_space(sale['number'], 9, 'left')
address = sale['consumer_address']
character_address = self._row_characters - 20
if len(address) > character_address:
address = address[:character_address]
address = self.word_space(address, character_address, 'left')
self.print_line(sale_number, address, sale_total)
self.print_enter()
self.print_enter()
total = money(data['total'])
self._printer.text(f'TOTAL: {total}')
self.print_enter()
self._printer.cut()
self.print_enter()
self.print_enter()
self._printer.close()
def print_count_money(self, data):
self.set_printer()
self._printer.set(align='center')
self.print_enter()
self._printer.text('REPORTE DE DINERO EN CAJA')
self.print_enter()
self.print_enter()
self.print_horinzontal_line()
self._printer.set(align='left')
type_ = data['type']
self._printer.text(f'TIPO: {type_}')
self.print_enter()
now = datetime.now()
print_date = now.strftime("%Y-%m-%d %H:%M %p")
self._printer.text(f'FECHA / HORA: {print_date}')
self.print_enter()
self.print_horinzontal_line()
self.print_enter()
self.print_col('Moneda', self.taxes_col_width1)
self.print_col('Cant.', self.taxes_col_width2)
self.print_col('Subtotal', self.taxes_col_width3)
self.print_enter()
for line in data['lines']:
self.print_col(str(line[0]), self.taxes_col_width1)
self.print_col(str(line[1]), self.taxes_col_width2)
self.print_col(str(line[2]), self.taxes_col_width3)
self.print_enter()
self.print_enter()
self._printer.set(custom_size=True, width=2, height=2, align='center')
_total = data['total']
self._printer.text(f'TOTAL: {_total}')
self.print_enter()
self._printer.cut()
self.print_enter()
self.print_enter()
self._printer.close()
def print_header_sale_verification(self, sale):
title = 'VERIFICACION DE CUENTA'
msg = """ESTIMADO CLIENTE UNA VEZ REALICE EL \n PAGO DE LA CUENTA POR \n FAVOR EXIJA SU RESPECTIVA FACTURA"""
self.print_enter()
self.print_enter()
self._printer.set(custom_size=True, width=2, height=2, align='center')
self._printer.text(title)
self.print_enter()
self.print_horinzontal_line('big')
self.print_enter()
self.print_enter()
self._printer.set(align='center')
self._printer.text(msg)
self.print_enter()
self._printer.set(align='left')
self.print_enter()
self.print_enter()
create_date = sale.get('create_date')
if create_date:
self._printer.text(f'FECHA: {create_date}')
self.print_enter()
salesman = sale.get('salesman')
if salesman:
self._printer.text(f'VENDEDOR: {salesman}')
self.print_enter()
comment = sale.get('comment')
if comment:
self._printer.text(f'NOTAS: {comment}')
self.print_enter()
table_assigned = sale.get('table_assigned')
if table_assigned:
self._printer.text(f'MESA: {table_assigned}')
self.print_enter()
position = sale.get('position')
if position:
self._printer.text(f'POSICION: {position}')
self.print_enter()
self.print_enter()
def print_logo(self):
try:
self._printer.set(align='center')
self._printer.image(self._img_logo, center=True)
self.print_enter()
except:
pass
def print_qrcode(self, qrcode):
self._printer.qr(qrcode, center=True, size=5)
self.print_enter()
def print_header(self):
if self._img_logo:
self.print_logo()
self._printer.set(align='center')
if self._header != '' and self._header is not None:
self._printer.text(self._header)
self.print_enter()
self._printer.text(self._company)
self.print_enter()
self._printer.text(self._shop)
self.print_enter()
if self._id_number:
self._printer.text('NIT:' + self._id_number)
if self._regime_tax:
self._printer.text(' ' + self._regime_tax)
self.print_enter()
if self._street:
self._printer.text(self._street)
self.print_enter()
if self._city:
self._printer.text(self._city)
if self._phone:
if self._city:
self._printer.text(' ')
self._printer.text('Telefono:' + self._phone)
if self._city or self._phone:
self.print_enter()
self.print_enter()
self.print_enter()
def print_horinzontal_line(self, size=None):
if size == 'big':
row_characters = '-' * int(self._row_characters / 2)
else:
row_characters = '-' * self._row_characters
self._printer.text(row_characters)
self.print_enter()
def print_horinzontal_double_line(self):
self._printer.text('=' * self._row_characters)
def print_enter(self):
self._printer.text('\n')
def print_split(self, left, right):
len_left = self._row_characters - len(right) - 1
left = left[:len_left]
if type(left) == bytes:
left = left.decode("utf-8")
if type(right) == bytes:
right = right.decode("utf-8")
left += (len_left - len(left) + 1) * ' '
self._printer.text(left)
self._printer.text(right + '\n')
def print_sale_lines(self, sale):
self.print_enter()
self.print_horinzontal_line()
self.print_split(' Articulo ', 'Subtotal ')
self.print_horinzontal_line()
len_row = self._row_characters - \
(_DIGITS_CODE_RECEIPT + 1) - (_DIGITS + 1)
for line in sale['lines']:
if line['taxes'] and _PRINT_TAX_ID:
tax_id = ' ' + str(line['taxes'][0].id)
else:
tax_id = ''
line_total = money(line['amount_w_tax']) + tax_id
discount = line.get('discount')
if self._show_discount and discount and Decimal(discount) > 0:
amount_w_tax = Decimal(line['amount_w_tax'])
discount = Decimal(discount)
initial = 'DCTO - ' + str(round(discount*100, 0)) + '%'
if discount == 1:
line_total = 0
else:
line_total = amount_w_tax/(1-discount)
discount = '-' + money(line_total - amount_w_tax)
line_total = money(line_total)
code = line['code'] or ' '
if line['quantity'] != 1:
length_name = self._row_characters - 11
first_line = code + ' ' + line['name'][:length_name]
if type(first_line) == bytes:
first_line = first_line.decode('utf-8')
self._printer.text(first_line + '\n')
unit_price_w_tax = str(round(line['unit_price_w_tax'], 2))
second_line = ' %s x %s' % (
line['quantity'], unit_price_w_tax)
second_line = second_line.encode('utf-8')
self.print_split(second_line, line_total)
if self._show_discount and discount:
self.print_split(initial, str(discount))
else:
if self._environment == 'retail':
line_pt = code + ' ' + line['name'][:len_row]
else:
line_pt = line['name'][:len_row]
self.print_split(line_pt, line_total)
if line['discount'] and Decimal(line['discount']) and self._show_discount:
self.print_split(initial, discount)
def print_totals(self, sale):
untaxed_amount = sale['untaxed_amount']
total_amount = sale['total_amount']
self.print_split('', '----------------')
self.print_split('Subtotal Base:', money(untaxed_amount))
self.print_split('Impuesto:', money(sale['tax_amount']))
self.print_split('', '----------------')
self.print_split('Total:', money(total_amount))
self.print_enter()
net_amount = sale['total_amount']
delivery_amount = sale.get('delivery_amount', 0)
if delivery_amount and delivery_amount > 0:
net_amount = net_amount + delivery_amount
tip_amount = sale.get('tip_amount', 0)
if tip_amount and tip_amount > 0:
net_amount = net_amount + tip_amount
if tip_amount:
self.print_split('Propina:', money(tip_amount))
if delivery_amount:
self.print_split('Domicilio:', money(delivery_amount))
if tip_amount or delivery_amount:
self.print_split('Valor Neto:', money(net_amount))
# if self._show_discount:
# self.print_split('Descuento:', money(sale['discount']))
self.print_enter()
if sale['cash_received']:
self.print_split('Recibido:', money(sale['cash_received']))
else:
pass
change = sale['change']
if sale['cash_received'] < net_amount:
msg_residual = 'Pendiente:'
else:
msg_residual = 'Cambio:'
self.print_split(msg_residual, money(change))
self.print_enter()
order = sale.get('order')
if order:
self._printer.text(f'CODIGO: {order}')
self.print_enter()
def _print_info_consumer(self, sale):
consumer = sale.get('consumer', None)
if consumer:
payment_method = sale.get('payment_method', None)
consumer_name = consumer.get('consumer_name', None)
consumer_address = consumer.get('consumer_address', '')
consumer_phone = consumer.get('consumer_phone', '')
self.print_horinzontal_line()
self.print_enter()
self._printer.set(align='center')
self._printer.text('========== INFO CONSUMIDOR ==========')
self.print_enter()
self._printer.set(align='left')
self._printer.text('NOMBRE: %s' % consumer_name)
self.print_enter()
self._printer.text('DIRECCION: %s' % consumer_address)
self.print_enter()
self._printer.text('TELEFONO: %s' % consumer_phone)
self.print_enter()
if payment_method and payment_method == 'terminal':
payment_method = '- PAGA CON DATAFONO'
elif payment_method and payment_method == 'all_paid':
payment_method = '- TODO PAGO'
elif payment_method and payment_method == 'partial_paid':
payment_method = '- PAGO PARCIAL'
else:
payment_method = '- PAGA EN EFECTIVO'
self._printer.text(f'MEDIO DE PAGO: {payment_method}')
self.print_enter()
self.print_enter()
delivery_amount = money(sale.get('delivery_amount', 0))
self._printer.text(f'Domicilio: {delivery_amount}')
self.print_enter()
self.print_enter()
def print_body(self, sale, type_doc='invoice'):
self._printer.set(font=_FONT_B)
kind_string = sale.get('kind_string', None)
if type_doc != 'invoice' and kind_string and self._environment != 'retail':
self._printer.set(custom_size=True, width=2,
height=2, align='center')
kind = f'- - - {kind_string} - - -'
self._printer.text(kind)
self.print_enter()
self.print_enter()
self._printer.set(custom_size=False)
self._printer.set(align='left')
if type_doc == 'invoice':
if sale['number']:
if sale['total_amount'] >= 0:
self._printer.text(
'FACTURA DE VENTA No. ' + sale['number'])
else:
self._printer.text('NOTA CREDITO No. ' + sale['number'])
elif type_doc in ['order', 'delivery']:
self._printer.text('PEDIDO: ' + sale['order'])
self.print_enter()
self._printer.text('Fecha:%s' % sale['date'])
if sale.get('invoice_time'):
self._printer.text(' Hora:%s' % sale['invoice_time'])
self.print_enter()
if sale.get('turn') and sale['turn'] != 0:
self._printer.text('Turno: %s - ' % str(sale['turn']))
self.print_enter()
self.print_horinzontal_line()
party_name = 'Cliente: %s ' % sale['party']
party_id_number = 'Id: %s' % sale.get('party_id_number', '')
if len(party_name + party_id_number) > self._row_characters:
self._printer.text(party_name)
self.print_enter()
self._printer.text(party_id_number)
else:
self._printer.text(party_name + party_id_number)
if sale.get('party_address'):
self.print_enter()
self._printer.text('Direccion: %s' % sale['party_address'])
if sale.get('party_phone'):
self.print_enter()
self._printer.text('Telefono: %s' % sale['party_phone'])
if sale.get('payment_term'):
self.print_enter()
self._printer.text('Forma de Pago: %s' % sale['payment_term'])
self.print_enter()
self._print_info_consumer(sale)
self.print_sale_lines(sale)
self.print_totals(sale)
self.print_horinzontal_line()
self.print_enter()
self._printer.set(align='left')
self._printer.text('DETALLE DE IMPUESTOS')
self.print_enter()
if self._printing_taxes:
self.print_col('Tipo', self.taxes_col_width1)
self.print_col('Base', self.taxes_col_width2)
self.print_col('Imp.', self.taxes_col_width3)
self.print_enter()
taxes = sale['taxes']
for tax in taxes:
self.print_col(str(taxes[tax]['name'])
+ ' ', self.taxes_col_width1)
self.print_col(
str(int(taxes[tax]['base'])), self.taxes_col_width2)
self.print_col(
str(int(taxes[tax]['tax'])), self.taxes_col_width3)
self.print_enter()
self.print_enter()
self.print_horinzontal_line()
if sale.get('payments'):
self.print_enter()
self.print_col('MEDIO PAGO', self.payments_col_width1)
self.print_col('# APROB', self.payments_col_width2)
self.print_col('VALOR', self.payments_col_width3)
self.print_enter()
payments = sale['payments']
for p in payments:
self.print_col(str(p['name']) + ' ', self.payments_col_width1)
self.print_col(str(p['voucher']) + ' ',
self.payments_col_width2)
self.print_col(str(int(p['amount'])), self.payments_col_width3)
self.print_enter()
self.print_horinzontal_line()
no_products = 'No ITEMS: %s' % str(sale['num_products'])
self._printer.text(no_products)
self.print_enter()
comment = sale.get('comment')
if comment:
self.print_horinzontal_line()
self.print_enter()
self._printer.text(f'NOTAS: {comment}')
self.print_enter()
self.print_horinzontal_line()
# if type_doc == 'invoice':
# self._printer.text('No PEDIDO: ' + sale['order'])
# self.print_enter()
register = 'CAJA No. %s' % self._sale_device
self._printer.text(register)
self.print_enter()
self._printer.text('CAJERO: %s' % self._user)
self.print_enter()
if sale.get('salesman'):
self._printer.text('VENDEDOR: %s' % sale['salesman'])
self.print_enter()
if sale.get('channel'):
self._printer.text('CANAL DE VENTA: %s' % sale['channel'])
self.print_enter()
if sale.get('delivery_party'):
self._printer.text('DOMICILIARIO: %s' % sale['delivery_party'])
self.print_enter()
print(self._show_position, sale['position'], '*************')
if self._show_position:
self._printer.text('POSICION: %s' % str(sale['position']))
self.print_enter()
self.print_horinzontal_line()
auth_kind = sale.get('auth_kind', None)
if auth_kind and sale['state'] not in ['draft']:
auth_data = self._authorizations[auth_kind]
self._printer.text(self.get_authorization(auth_data))
self.print_enter()
elif self._gta_info and sale['state'] not in ['draft']:
self._printer.text(self._gta_info)
self.print_enter()
self._printer.text('Fecha de creacion: %s' % sale["create_date"])
self.print_enter()
self.print_enter()
def print_extra_info(self, sale):
if sale.get('pos_notes'):
self.print_enter()
self.print_header()
self.print_horinzontal_line()
self.print_enter()
party_name = 'Cliente: %s ' % sale['party']
self._printer.text(party_name)
self.print_enter()
if self._show_position:
self._printer.text('Posicion: %s' % str(sale['position']))
self.print_enter()
if sale['state'] in ['draft']:
self._printer.text('Cotizacion: ', sale['order'])
else:
self._printer.text('Factura No. ' + sale['number'])
self.print_enter()
self._printer.text(str(sale.get('pos_notes')))
self.print_enter()
self.print_horinzontal_line()
self.print_enter()
self._printer.cut()
def print_col(self, x, l):
self._printer.text(x[:l] + (l - len(x)) * ' ')
def print_footer(self, open_box=False):
if self._footer:
self._printer.text(self._footer)
self.print_enter()
self._printer.text('SOFTWARE TRYTON - www.presik.com')
self.print_enter()
self._printer.cut()
if open_box:
self._printer.cashdraw(2)
self.print_enter()
def print_orders(self, orders, reversion=None, kind='command'):
res = []
self.order_kind = kind
for order in orders.values():
try:
if dev_printers.get(order['host']):
host = dev_printers[order['host']]
else:
host = order['host']
if order['interface'] == 'usb':
if os.name == 'posix':
self._printer = printer.File(host)
elif os.name == 'nt':
self._printer = printer.Win32Raw(host)
self._printer.open()
elif order['interface'] == 'network':
self._printer = printer.Network(host, timeout=15)
elif order['interface'] == 'ssh':
self._printer = FileSSH(*host.split('@'))
if self._printer:
self._printer.open()
elif order['interface'] == 'cups':
pass
if not self._printer:
self.logger.info(
"Warning: Interface not found for printer!")
res.append(None)
continue
self.logger.info("Info: Printer is OK!")
res.append(self._print_order(order, reversion))
self._printer.close()
except:
self.logger.info("Warning: Can not found Printer!")
res.append(None)
return all(res)
def _print_order(self, order, reversion):
self.print_body_order(order, reversion)
self._print_info_consumer(order)
self._printer.cut()
self._row_characters = order['row_characters']
return True
def print_body_order(self, order, reversion):
# Exists 2 types of order:
# command => For restaurants kitchens
# dispatch => For external dispatch
self._printer.set(font=_FONT_B)
self._printer.set(align='center')
turn = order.get('turn')
if turn:
self._printer.text('TURNO: %s' % str(turn))
self.print_enter()
self.print_enter()
if self._environment != 'retail':
kind = order.get('kind', 'delivery')
if kind == 'take_away':
_kind = 'PARA LLEVAR'
elif kind == 'to_table':
_kind = 'PARA MESA'
else:
_kind = 'DOMICILIO'
self._printer.set(custom_size=True, width=2, height=2, align='center')
title = f'+ + + {_kind} + + +'
self._printer.text(title)
self.print_enter()
self._printer.set(custom_size=True, width=2, height=2, align='center')
self.print_enter()
self._printer.text(order['sale_number'])
self.print_enter()
self._printer.set(custom_size=False)
self._printer.set(align='left')
self.print_enter()
date_ = datetime.now().strftime("%Y-%m-%d %H:%M %p")
self._printer.text('FECHA: ' + date_)
self.print_enter()
table_assigned = order.get('table_assigned', None)
if table_assigned:
self.print_enter()
self._printer.set(custom_size=True, width=2,
height=2, align='center')
self._printer.text('MESA: %s' % table_assigned)
self.print_enter()
self._printer.set(align='left')
delivery_charge = order.get('delivery_charge', None)
if self.order_kind == 'dispatch' and delivery_charge:
self._printer.text('FACTURA: ' + order['number'])
self.print_enter()
_charge_to = 'Cliente'
if delivery_charge == 'company':
_charge_to = 'Empresa'
self._printer.text('CARGO DEL DOMICILIO: ' + _charge_to)
self.print_enter()
if self.order_kind == 'dispatch':
self._printer.text('FORMA DE PAGO: ' + order.get('payment_term', ''))
self.print_enter()
position = order.get('position')
if position:
self._printer.text('POSICION: %s' % str(position))
self.print_enter()
self._printer.text('VENDEDOR: %s' % order['salesman'])
self.print_enter()
self._printer.text('SUCURSAL: %s' % order['shop'])
self.print_enter()
self._printer.text('CLIENTE: %s' % order['party'])
self.print_enter()
if self.order_kind == 'dispatch':
self._printer.text('VALOR: ' + str(order['total_amount']))
self.print_enter()
if order.get('pos_notes'):
self._printer.text(order['pos_notes'])
self.print_enter()
self._printer.text('CAJA No: %s' % self._sale_device or '')
self.print_enter()
self.print_enter()
self._printer.set(align='center')
if self.order_kind == 'command':
self._printer.set(custom_size=True, width=2,
height=2, align='center')
if reversion:
self._printer.text('>> R E V E R S I O N <<')
self.print_enter()
col_width_name = self.order_col_2 + self.order_col_3
self._printer.set(align='left')
self._printer.set(custom_size=True, width=1, height=2)
if not self._print_lines_product:
self.print_horinzontal_double_line()
self.print_enter()
for line in order['lines']:
if self.order_kind == 'command':
self._printer.set(custom_size=True, width=1, height=2)
qty = ' ' + str(int(Decimal(line['quantity'])))
self.print_col(qty, self.order_col_1)
self.print_col(line['name'], col_width_name)
if line['note']:
self.print_enter()
for msg_note in line['note'].split('\n'):
self._printer.text(f' NOTA -> {msg_note}')
self.print_enter()
self.print_enter()
self.print_enter()
self.print_horinzontal_double_line()
self.print_enter()
self._printer.set(custom_size=True, width=2, height=2, align='left')
self._printer.text('NOTA:')
self.print_enter()
if order['comment']:
self._printer.text(str(order['comment']))
self.print_enter()
self.print_enter()
self.print_enter()
# if self._environment != 'retail':
# self._printer.set(custom_size=True, width=2, height=2, align='center')
# title = f'+ + + {_kind} + + +'
# self._printer.text(title)
# self.print_enter()
# self.print_enter()
@classmethod
def get_authorization(cls, auth):
res = ''
kind = auth['kind']
start_date_auth = auth['start_date_auth']
from_auth = auth['from_auth']
to_auth = auth['to_auth']
number = auth['number']
if auth:
res = f"Autorizacion de facturacion {kind} No {number} del {start_date_auth}, habilita desde {from_auth} a {to_auth}"
return res
class CupsPrinter(object):
"Cups Printer"
__name__ = 'sale_pos_frontend.cups_printer'
def __init__(self, _file, row_characters):
self._file = _file
self.align = 'left'
self._row_characters = row_characters
def text(self, text):
self._text(text)
def set(self, align='left', font=_FONT_A):
if align:
self.align = align
if font:
self.font = font
def cut(self):
pass
def cashdraw(number):
pass
def _text(self, text):
start_spaces = ''
if self.align == 'center':
start_spaces = int((self._row_characters - len(text)) / 2) * ' '
elif self.align == 'right':
start_spaces = int(self._row_characters - len(text)) * ' '
else:
pass
text = start_spaces + text
self._file.write(text)
if __name__ == '__main__':
# Test for Escpos interface printer Linux
# Network example
# device = 'network', '192.168.0.33'
# Unix-like Usb example
device = ('usb', ' /dev/usb/lp1')
# Windows Usb example for printer name SATPOS
# device = 'usb', 'SATPOS'
# SSH example
# device = 'ssh', 'psk@123@192.168.20.25@22@/dev/usb/lp1'
example_dev = {
'interface': device[0],
'device': device[1],
'profile': 'TM-P80',
}
ctx_printing = {}
ctx_printing['company'] = 'OSCORP INC'
ctx_printing['sale_device'] = 'CAJA-10'
ctx_printing['shop'] = 'Shop Wall Boulevard'
ctx_printing['street'] = 'Cll 21 # 172-81. Central Park'
ctx_printing['user'] = 'Charles Chapplin'
ctx_printing['city'] = 'Dallas'
ctx_printing['zip'] = '0876'
ctx_printing['phone'] = '591 5513 455'
ctx_printing['id_number'] = '123456789-0'
ctx_printing['tax_regime'] = 'none'
receipt = Receipt(ctx_printing)
receipt.config_printer(example_dev)
receipt.test_printer()