[IMP] hw_escpos / point_of_sale: print receipt with an xml template

bzr revid: fva@openerp.com-20140320164530-odpeuf1igh7wkrms
This commit is contained in:
Frédéric van der Essen 2014-03-20 17:45:30 +01:00
parent 5596413901
commit a4afb910e9
5 changed files with 160 additions and 59 deletions

View File

@ -177,7 +177,6 @@ class XmlSerializer:
def start_inline(self,stylestack=None):
""" starts an inline entity with an optional style definition """
print 'start_inline'
self.stack.append('inline')
if self.dirty:
self.escpos._raw(' ')
@ -186,9 +185,7 @@ class XmlSerializer:
def start_block(self,stylestack=None):
""" starts a block entity with an optional style definition """
print 'start_block'
if self.dirty:
print 'cleanup before block'
self.escpos._raw('\n')
self.dirty = False
self.stack.append('block')
@ -197,9 +194,7 @@ class XmlSerializer:
def end_entity(self):
""" ends the entity definition. (but does not cancel the active style!) """
print 'end_entity'
if self.stack[-1] == 'block' and self.dirty:
print 'cleanup after block'
self.escpos._raw('\n')
self.dirty = False
if len(self.stack) > 1:
@ -218,7 +213,6 @@ class XmlSerializer:
text = text.strip()
text = re.sub('\s+',' ',text)
if text:
print 'printing text:'+text
self.dirty = True
self.escpos.text(text)
@ -254,7 +248,6 @@ class XmlLineSerializer:
self.left = True
def _txt(self,txt):
print '_txt: ',txt
if self.left:
if self.clwidth < self.lwidth:
txt = txt[:max(0, self.lwidth - self.clwidth)]
@ -267,7 +260,6 @@ class XmlLineSerializer:
self.crwidth += len(txt)
def start_inline(self,stylestack=None):
print 'LINE:start_entity'
if (self.left and self.clwidth) or (not self.left and self.crwidth):
self._txt(' ')
@ -286,7 +278,6 @@ class XmlLineSerializer:
text = text.strip()
text = re.sub('\s+',' ',text)
if text:
print 'LINE:printing text:'+text
self._txt(text)
def linebreak(self):
@ -300,11 +291,6 @@ class XmlLineSerializer:
self.left = False
def get_line(self):
print 'LBUFFER: '+self.lbuffer
print self.clwidth
print 'RBUFFER: '+self.rbuffer
print self.crwidth
return ' ' * self.indent * self.tabwidth + self.lbuffer + ' ' * (self.width - self.clwidth - self.crwidth) + self.rbuffer
@ -551,15 +537,11 @@ class Escpos:
formatstr = "{:"+str(width)+"."+str(decimals)+"f}"
print formatstr
print value
ret = formatstr.format(value)
print ret
ret = ret.replace(',','COMMA')
ret = ret.replace('.','DOT')
ret = ret.replace('COMMA',thousands_separator)
ret = ret.replace('DOT',decimals_separator)
print 'RET '+ret
if symbol:
if position == 'after':
@ -674,8 +656,9 @@ class Escpos:
serializer.linebreak()
elif elem.tag == 'img':
if src in elem.attrib and 'data:' in elem.attrib['src']:
self.print_base64_image(elem.attrib['src'])
pass
#if 'src' in elem.attrib and 'data:' in elem.attrib['src']:
# self.print_base64_image(elem.attrib['src'])
elif elem.tag == 'barcode' and 'encoding' in elem.attrib:
serializer.start_block(stylestack)

View File

@ -511,43 +511,8 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
return this.message('open_cashbox');
},
/* ask the printer to print a receipt
* receipt is a JSON object with the following specs:
* receipt{
* - orderlines : list of orderlines :
* {
* quantity: (number) the number of items, or the weight,
* unit_name: (string) the name of the item's unit (kg, dozen, ...)
* price: (number) the price of one unit of the item before discount
* discount: (number) the discount on the product in % [0,100]
* product_name: (string) the name of the product
* price_with_tax: (number) the price paid for this orderline, tax included
* price_without_tax: (number) the price paid for this orderline, without taxes
* tax: (number) the price paid in taxes on this orderline
* product_description: (string) generic description of the product
* product_description_sale: (string) sales related information of the product
* }
* - paymentlines : list of paymentlines :
* {
* amount: (number) the amount paid
* journal: (string) the name of the journal on wich the payment has been made
* }
* - total_with_tax: (number) the total of the receipt tax included
* - total_without_tax: (number) the total of the receipt without taxes
* - total_tax: (number) the total amount of taxes paid
* - total_paid: (number) the total sum paid by the client
* - change: (number) the amount of change given back to the client
* - name: (string) a unique name for this order
* - client: (string) name of the client. or null if no client is logged
* - cashier: (string) the name of the cashier
* - date: { the date at wich the payment has been done
* year: (number) the year [2012, ...]
* month: (number) the month [0,11]
* date: (number) the day of the month [1,31]
* day: (number) the day of the week [0,6]
* hour: (number) the hour [0,23]
* minute: (number) the minute [0,59]
* }
/*
* ask the printer to print a receipt
*/
print_receipt: function(receipt){
var self = this;
@ -558,7 +523,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
function send_printing_job(){
if (self.receipt_queue.length > 0){
var r = self.receipt_queue.shift();
self.message('print_receipt',{ receipt: r },{ timeout: 5000 })
self.message('print_xml_receipt',{ receipt: r },{ timeout: 5000 })
.then(function(){
send_printing_job();
},function(){

View File

@ -987,6 +987,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
hour: date.getHours(),
minute: date.getMinutes() ,
isostring: date.toISOString(),
localestring: date.toLocaleString(),
},
company:{
email: company.email,

View File

@ -1172,7 +1172,10 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
}else{
this.pos.push_order(currentOrder)
if(this.pos.config.iface_print_via_proxy){
this.pos.proxy.print_receipt(currentOrder.export_for_printing());
var receipt = currentOrder.export_for_printing();
this.pos.proxy.print_receipt(QWeb.render('XmlReceipt',{
receipt: receipt
}));
this.pos.get('selectedOrder').destroy(); //finish order and go back to scan screen
}else{
this.pos_widget.screen_selector.set_current_screen(this.next_screen);

View File

@ -319,6 +319,155 @@
</div>
</t>
<t t-name="XmlReceipt">
<receipt align='center' width='40' value-thousands-separator='' >
<t t-if='receipt.company.logo'>
<img t-att-src='receipt.company.logo' />
<br/>
</t>
<t t-if='!receipt.company.logo'>
<h1><t t-esc='receipt.company.name' /></h1>
<br/>
</t>
<div font='b'>
<t t-if='receipt.shop.name'>
<div><t t-esc='receipt.shop.name' /></div>
</t>
<t t-if='receipt.company.contact_address'>
<div><t t-esc='receipt.company.contact_address' /></div>
</t>
<t t-if='receipt.company.phone'>
<div>Tel:<t t-esc='receipt.company.phone' /></div>
</t>
<t t-if='receipt.company.vat'>
<div>VAT:<t t-esc='receipt.company.vat' /></div>
</t>
<t t-if='receipt.company.email'>
<div><t t-esc='receipt.company.email' /></div>
</t>
<t t-if='receipt.company.website'>
<div><t t-esc='receipt.company.website' /></div>
</t>
<t t-if='receipt.header'>
<div><t t-esc='receipt.header' /></div>
</t>
<t t-if='receipt.cashier'>
<div>--------------------------------</div>
<div>Served by <t t-esc='receipt.cashier' /></div>
</t>
</div>
<br /><br />
<!-- Orderlines -->
<div line-ratio='0.6'>
<t t-foreach='receipt.orderlines' t-as='line'>
<t t-set='simple' t-value='line.discount === 0 and line.unit_name === "Unit(s)" and line.quantity === 1' />
<t t-if='simple'>
<line>
<left><t t-esc='line.product_name' /></left>
<right><value><t t-esc='line.price_display' /></value></right>
</line>
</t>
<t t-if='!simple'>
<line><left><t t-esc='line.product_name' /></left></line>
<t t-if='line.discount !== 0'>
<line indent='1'><left>Discount: <t t-esc='line.discount' />%</left></line>
</t>
<line indent='1'>
<left>
<value value-decimals='3' autoint='on'>
<t t-esc='line.quantity' />
</value>
<t t-if='line.unit_name !== "Unit(s)"'>
<t t-esc='line.unit_name' />
</t>
x
<value value-decimals='2'>
<t t-esc='line.price' />
</value>
</left>
<right>
<value><t t-esc='line.price_display' /></value>
</right>
</line>
</t>
</t>
</div>
<!-- Subtotal -->
<t t-set='taxincluded' t-value='Math.abs(receipt.subtotal - receipt.total_with_tax) &lt;= 0.000001' />
<t t-if='!taxincluded'>
<line><right>--------</right></line>
<line><left>Subtotal</left><right> <value>receipt.subtotal</value></right></line>
<t t-foreach='receipt.tax_details' t-as='tax'>
<line>
<left><t t-esc='tax.name' /></left>
<right><value><t t-esc='tax.amount' /></value></right>
</line>
</t>
</t>
<!-- Total -->
<line><right>-------</right></line>
<line size='double-height'>
<left><pre> TOTAL</pre></left>
<right><value><t t-esc='receipt.total_with_tax' /></value></right>
</line>
<br/><br/>
<!-- Payment Lines -->
<t t-foreach='receipt.paymentlines' t-as='line'>
<line>
<left><t t-esc='line.journal' /></left>
<right><value><t t-esc='line.amount'/></value></right>
</line>
</t>
<br/>
<line size='double-height'>
<left><pre> CHANGE</pre></left>
<right><value><t t-esc='receipt.change' /></value></right>
</line>
<br/>
<!-- Extra Payment Info -->
<t t-if='receipt.total_discount'>
<line>
<left>Discounts</left>
<right><value><t t-esc='receipt.total_discount'/></value></right>
</line>
</t>
<t t-if='taxincluded'>
<t t-foreach='receipt.tax_details' t-as='tax'>
<line>
<left><t t-esc='tax.name' /></left>
<right><value><t t-esc='tax.amount' /></value></right>
</line>
</t>
</t>
<!-- Footer -->
<t t-if='receipt.footer'>
<br/>
<pre><t t-esc='receipt.footer' /></pre>
<br/>
<br/>
</t>
<br/>
<div font='b'>
<div><t t-esc='receipt.name' /></div>
<div><t t-esc='receipt.date.localestring' /></div>
</div>
</receipt>
</t>
<t t-name="WelcomeScreenWidget">
<div class="welcome-screen screen">
<header class='rightpane-header'><h2>Welcome</h2></header>