[IMP] point_of_sale: ESC/POS receipt printing
bzr revid: fva@openerp.com-20131220163057-9nu1u7hti0m8wo3h
This commit is contained in:
parent
2fec901cb5
commit
293001c826
|
@ -0,0 +1,25 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import controllers
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
|
||||
{
|
||||
'name': 'ESC/POS Hardware Driver',
|
||||
'version': '1.0',
|
||||
'category': 'Hardware Drivers',
|
||||
'sequence': 6,
|
||||
'summary': 'Hardware Driver for ESC/POS Printers and Cashdrawers',
|
||||
'description': """
|
||||
ESC/POS Hardware Driver
|
||||
=======================
|
||||
|
||||
This module allows openerp to print with ESC/POS compatible printers and
|
||||
to open ESC/POS controlled cashdrawers in the point of sale and other modules
|
||||
that would need such functionality.
|
||||
|
||||
""",
|
||||
'author': 'OpenERP SA',
|
||||
'depends': [],
|
||||
'test': [
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -0,0 +1,3 @@
|
|||
import main
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
|
@ -0,0 +1,143 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
import simplejson
|
||||
import os
|
||||
import openerp
|
||||
import time
|
||||
import random
|
||||
import openerp.addons.hw_proxy.controllers.main as hw_proxy
|
||||
import subprocess
|
||||
import usb.core
|
||||
import escpos
|
||||
import escpos.printer
|
||||
|
||||
from openerp import http
|
||||
from openerp.http import request
|
||||
from openerp.addons.web.controllers.main import manifest_list, module_boot, html_template
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class EscposDriver(hw_proxy.Proxy):
|
||||
|
||||
supported_printers = [
|
||||
{ 'vendor' : 0x04b8, 'product' : 0x0e03, 'name' : 'Epson TM-T20' }
|
||||
]
|
||||
|
||||
@http.route('/hw_proxy/open_cashbox', type='json', auth='admin')
|
||||
def open_cashbox(self):
|
||||
print 'ESC/POS: OPEN CASHBOX'
|
||||
|
||||
@http.route('/hw_proxy/print_receipt', type='json', auth='admin')
|
||||
def print_receipt(self, receipt):
|
||||
print 'ESC/POS: PRINT RECEIPT ' + str(receipt)
|
||||
|
||||
printers = self.connected_usb_devices(self.supported_printers)
|
||||
|
||||
def check(string):
|
||||
return string != True and bool(string) and string.strip()
|
||||
|
||||
def price(amount):
|
||||
return "{0:.2f}".format(amount)
|
||||
|
||||
def printline(left, right='', width=40, ratio=0.5, indent=0):
|
||||
lwidth = int(width * ratio)
|
||||
rwidth = width - lwidth
|
||||
lwidth = lwidth - indent
|
||||
|
||||
left = left[:lwidth]
|
||||
if len(left) != lwidth:
|
||||
left = left + ' ' * (lwidth - len(left))
|
||||
|
||||
right = right[-rwidth:]
|
||||
if len(right) != rwidth:
|
||||
right = ' ' * (rwidth - len(right)) + right
|
||||
|
||||
return ' ' * indent + left + right + '\n'
|
||||
|
||||
|
||||
if len(printers) > 0:
|
||||
printer = printers[0]
|
||||
|
||||
eprint = escpos.printer.Usb(printer['vendor'], printer['product'])
|
||||
#eprint.image(os.path.join(os.path.dirname(__file__),'logo_grayscale.png'))
|
||||
|
||||
# Receipt Header
|
||||
eprint.set(align='center',type='b',height=2,width=2)
|
||||
eprint.text(receipt['shop']['name'] + '\n')
|
||||
|
||||
eprint.set(align='center',type='b')
|
||||
if check(receipt['company']['name']):
|
||||
eprint.text(receipt['company']['name'] + '\n')
|
||||
if check(receipt['company']['contact_address']):
|
||||
eprint.text(receipt['company']['contact address'] + '\n')
|
||||
if check(receipt['company']['phone']):
|
||||
eprint.text('Tel:' + receipt['company']['phone'] + '\n')
|
||||
if check(receipt['company']['vat']):
|
||||
eprint.text('VAT:' + receipt['company']['vat'] + '\n')
|
||||
if check(receipt['company']['email']):
|
||||
eprint.text(receipt['company']['email'] + '\n')
|
||||
if check(receipt['company']['website']):
|
||||
eprint.text(receipt['company']['website'] + '\n')
|
||||
|
||||
if check(receipt['cashier']):
|
||||
eprint.text('-'*32+'\n')
|
||||
eprint.text('Served by '+receipt['cashier']+'\n')
|
||||
|
||||
# Orderlines
|
||||
eprint.text('\n\n')
|
||||
eprint.set(align='center')
|
||||
for line in receipt['orderlines']:
|
||||
pricestr = price(line['price_display'])
|
||||
if line['discount'] == 0 and line['unit_name'] == 'Unit(s)' and line['quantity'] == 1:
|
||||
eprint.text(printline(line['product_name'],pricestr,ratio=0.6))
|
||||
else:
|
||||
eprint.text(printline(line['product_name'],ratio=0.6))
|
||||
if line['discount'] != 0:
|
||||
eprint.text(printline('Discount: '+str(line['discount'])+'%', ratio=0.6, indent=2))
|
||||
if line['unit_name'] == 'Unit(s)':
|
||||
eprint.text( printline( str(line['quantity']) + ' x ' + price(line['price']), pricestr, ratio=0.6, indent=2))
|
||||
else:
|
||||
eprint.text( printline( str(line['quantity']) + line['unit_name'] + ' x ' + price(line['price']), pricestr, ratio=0.6, indent=2))
|
||||
|
||||
# Subtotal if the taxes are not included
|
||||
taxincluded = True
|
||||
if price(receipt['subtotal']) != price(receipt['total_with_tax']):
|
||||
eprint.text(printline('','-------'));
|
||||
eprint.text(printline('Subtotal',price(receipt['subtotal']),width=40, ratio=0.6))
|
||||
eprint.text(printline('Taxes',price(receipt['total_tax']),width=40, ratio=0.6))
|
||||
taxincluded = False
|
||||
|
||||
|
||||
# Total
|
||||
eprint.text(printline('','-------'));
|
||||
eprint.set(align='center',height=2)
|
||||
eprint.text(printline(' TOTAL',price(receipt['total_with_tax']),width=40, ratio=0.6))
|
||||
eprint.text('\n\n');
|
||||
|
||||
# Paymentlines
|
||||
eprint.set(align='center')
|
||||
for line in receipt['paymentlines']:
|
||||
eprint.text(printline(line['journal'], price(line['amount']), ratio=0.6))
|
||||
|
||||
eprint.text('\n');
|
||||
eprint.set(align='center',height=2)
|
||||
eprint.text(printline(' CHANGE',price(receipt['change']),width=40, ratio=0.6))
|
||||
eprint.set(align='center')
|
||||
eprint.text('\n');
|
||||
|
||||
# Extra Payment info
|
||||
if receipt['total_discount'] != 0:
|
||||
eprint.text(printline('Discounts',price(receipt['total_discount']),width=40, ratio=0.6))
|
||||
if taxincluded:
|
||||
eprint.text(printline('Taxes',price(receipt['total_tax']),width=40, ratio=0.6))
|
||||
|
||||
# Footer
|
||||
eprint.text(receipt['name']+'\n')
|
||||
eprint.text( str(receipt['date']['date']).zfill(2)
|
||||
+'/'+ str(receipt['date']['month']+1).zfill(2)
|
||||
+'/'+ str(receipt['date']['year']).zfill(4)
|
||||
+' '+ str(receipt['date']['hour']).zfill(2)
|
||||
+':'+ str(receipt['date']['minute']).zfill(2) )
|
||||
eprint.cut()
|
||||
return
|
||||
|
|
@ -5,6 +5,10 @@ import os
|
|||
import openerp
|
||||
import time
|
||||
import random
|
||||
import subprocess
|
||||
import usb.core
|
||||
import escpos
|
||||
import escpos.printer
|
||||
|
||||
from openerp import http
|
||||
from openerp.http import request
|
||||
|
@ -12,12 +16,19 @@ from openerp.addons.web.controllers.main import manifest_list, module_boot, html
|
|||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class ProxyController(http.Controller):
|
||||
class Proxy(http.Controller):
|
||||
def __init__(self):
|
||||
self.scale = 'closed'
|
||||
self.scale_weight = 0.0
|
||||
pass
|
||||
|
||||
def connected_usb_devices(self,devices):
|
||||
connected = []
|
||||
for device in devices:
|
||||
if usb.core.find(idVendor=device['vendor'], idProduct=device['product']) != None:
|
||||
connected.append(device)
|
||||
return connected
|
||||
|
||||
@http.route('/hw_proxy/test_connection', type='json', auth='admin')
|
||||
def test_connection(self):
|
||||
_logger.info('Received Connection Test from the Point of Sale');
|
||||
|
|
|
@ -331,6 +331,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
|||
* }
|
||||
*/
|
||||
print_receipt: function(receipt){
|
||||
console.log('PRINT RECEIPT:', receipt);
|
||||
return this.message('print_receipt',{receipt: receipt});
|
||||
},
|
||||
|
||||
|
|
|
@ -845,7 +845,8 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
|||
date: date.getDate(), // day of the month
|
||||
day: date.getDay(), // day of the week
|
||||
hour: date.getHours(),
|
||||
minute: date.getMinutes()
|
||||
minute: date.getMinutes() ,
|
||||
isostring: date.toISOString(),
|
||||
},
|
||||
company:{
|
||||
email: company.email,
|
||||
|
|
Loading…
Reference in New Issue