[IMP] hw_escpos / point_of_sale: print receipt with an xml template
bzr revid: fva@openerp.com-20140320164530-odpeuf1igh7wkrms
This commit is contained in:
parent
5596413901
commit
a4afb910e9
|
@ -177,7 +177,6 @@ class XmlSerializer:
|
||||||
|
|
||||||
def start_inline(self,stylestack=None):
|
def start_inline(self,stylestack=None):
|
||||||
""" starts an inline entity with an optional style definition """
|
""" starts an inline entity with an optional style definition """
|
||||||
print 'start_inline'
|
|
||||||
self.stack.append('inline')
|
self.stack.append('inline')
|
||||||
if self.dirty:
|
if self.dirty:
|
||||||
self.escpos._raw(' ')
|
self.escpos._raw(' ')
|
||||||
|
@ -186,9 +185,7 @@ class XmlSerializer:
|
||||||
|
|
||||||
def start_block(self,stylestack=None):
|
def start_block(self,stylestack=None):
|
||||||
""" starts a block entity with an optional style definition """
|
""" starts a block entity with an optional style definition """
|
||||||
print 'start_block'
|
|
||||||
if self.dirty:
|
if self.dirty:
|
||||||
print 'cleanup before block'
|
|
||||||
self.escpos._raw('\n')
|
self.escpos._raw('\n')
|
||||||
self.dirty = False
|
self.dirty = False
|
||||||
self.stack.append('block')
|
self.stack.append('block')
|
||||||
|
@ -197,9 +194,7 @@ class XmlSerializer:
|
||||||
|
|
||||||
def end_entity(self):
|
def end_entity(self):
|
||||||
""" ends the entity definition. (but does not cancel the active style!) """
|
""" ends the entity definition. (but does not cancel the active style!) """
|
||||||
print 'end_entity'
|
|
||||||
if self.stack[-1] == 'block' and self.dirty:
|
if self.stack[-1] == 'block' and self.dirty:
|
||||||
print 'cleanup after block'
|
|
||||||
self.escpos._raw('\n')
|
self.escpos._raw('\n')
|
||||||
self.dirty = False
|
self.dirty = False
|
||||||
if len(self.stack) > 1:
|
if len(self.stack) > 1:
|
||||||
|
@ -218,7 +213,6 @@ class XmlSerializer:
|
||||||
text = text.strip()
|
text = text.strip()
|
||||||
text = re.sub('\s+',' ',text)
|
text = re.sub('\s+',' ',text)
|
||||||
if text:
|
if text:
|
||||||
print 'printing text:'+text
|
|
||||||
self.dirty = True
|
self.dirty = True
|
||||||
self.escpos.text(text)
|
self.escpos.text(text)
|
||||||
|
|
||||||
|
@ -254,7 +248,6 @@ class XmlLineSerializer:
|
||||||
self.left = True
|
self.left = True
|
||||||
|
|
||||||
def _txt(self,txt):
|
def _txt(self,txt):
|
||||||
print '_txt: ',txt
|
|
||||||
if self.left:
|
if self.left:
|
||||||
if self.clwidth < self.lwidth:
|
if self.clwidth < self.lwidth:
|
||||||
txt = txt[:max(0, self.lwidth - self.clwidth)]
|
txt = txt[:max(0, self.lwidth - self.clwidth)]
|
||||||
|
@ -267,7 +260,6 @@ class XmlLineSerializer:
|
||||||
self.crwidth += len(txt)
|
self.crwidth += len(txt)
|
||||||
|
|
||||||
def start_inline(self,stylestack=None):
|
def start_inline(self,stylestack=None):
|
||||||
print 'LINE:start_entity'
|
|
||||||
if (self.left and self.clwidth) or (not self.left and self.crwidth):
|
if (self.left and self.clwidth) or (not self.left and self.crwidth):
|
||||||
self._txt(' ')
|
self._txt(' ')
|
||||||
|
|
||||||
|
@ -286,7 +278,6 @@ class XmlLineSerializer:
|
||||||
text = text.strip()
|
text = text.strip()
|
||||||
text = re.sub('\s+',' ',text)
|
text = re.sub('\s+',' ',text)
|
||||||
if text:
|
if text:
|
||||||
print 'LINE:printing text:'+text
|
|
||||||
self._txt(text)
|
self._txt(text)
|
||||||
|
|
||||||
def linebreak(self):
|
def linebreak(self):
|
||||||
|
@ -300,11 +291,6 @@ class XmlLineSerializer:
|
||||||
self.left = False
|
self.left = False
|
||||||
|
|
||||||
def get_line(self):
|
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
|
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}"
|
formatstr = "{:"+str(width)+"."+str(decimals)+"f}"
|
||||||
|
|
||||||
|
|
||||||
print formatstr
|
|
||||||
print value
|
|
||||||
ret = formatstr.format(value)
|
ret = formatstr.format(value)
|
||||||
print ret
|
|
||||||
ret = ret.replace(',','COMMA')
|
ret = ret.replace(',','COMMA')
|
||||||
ret = ret.replace('.','DOT')
|
ret = ret.replace('.','DOT')
|
||||||
ret = ret.replace('COMMA',thousands_separator)
|
ret = ret.replace('COMMA',thousands_separator)
|
||||||
ret = ret.replace('DOT',decimals_separator)
|
ret = ret.replace('DOT',decimals_separator)
|
||||||
print 'RET '+ret
|
|
||||||
|
|
||||||
if symbol:
|
if symbol:
|
||||||
if position == 'after':
|
if position == 'after':
|
||||||
|
@ -674,8 +656,9 @@ class Escpos:
|
||||||
serializer.linebreak()
|
serializer.linebreak()
|
||||||
|
|
||||||
elif elem.tag == 'img':
|
elif elem.tag == 'img':
|
||||||
if src in elem.attrib and 'data:' in elem.attrib['src']:
|
pass
|
||||||
self.print_base64_image(elem.attrib['src'])
|
#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:
|
elif elem.tag == 'barcode' and 'encoding' in elem.attrib:
|
||||||
serializer.start_block(stylestack)
|
serializer.start_block(stylestack)
|
||||||
|
|
|
@ -511,43 +511,8 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
||||||
return this.message('open_cashbox');
|
return this.message('open_cashbox');
|
||||||
},
|
},
|
||||||
|
|
||||||
/* ask the printer to print a receipt
|
/*
|
||||||
* receipt is a JSON object with the following specs:
|
* ask the printer to print a receipt
|
||||||
* 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]
|
|
||||||
* }
|
|
||||||
*/
|
*/
|
||||||
print_receipt: function(receipt){
|
print_receipt: function(receipt){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -558,7 +523,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
||||||
function send_printing_job(){
|
function send_printing_job(){
|
||||||
if (self.receipt_queue.length > 0){
|
if (self.receipt_queue.length > 0){
|
||||||
var r = self.receipt_queue.shift();
|
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(){
|
.then(function(){
|
||||||
send_printing_job();
|
send_printing_job();
|
||||||
},function(){
|
},function(){
|
||||||
|
|
|
@ -987,6 +987,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
|
||||||
hour: date.getHours(),
|
hour: date.getHours(),
|
||||||
minute: date.getMinutes() ,
|
minute: date.getMinutes() ,
|
||||||
isostring: date.toISOString(),
|
isostring: date.toISOString(),
|
||||||
|
localestring: date.toLocaleString(),
|
||||||
},
|
},
|
||||||
company:{
|
company:{
|
||||||
email: company.email,
|
email: company.email,
|
||||||
|
|
|
@ -1172,7 +1172,10 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
||||||
}else{
|
}else{
|
||||||
this.pos.push_order(currentOrder)
|
this.pos.push_order(currentOrder)
|
||||||
if(this.pos.config.iface_print_via_proxy){
|
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
|
this.pos.get('selectedOrder').destroy(); //finish order and go back to scan screen
|
||||||
}else{
|
}else{
|
||||||
this.pos_widget.screen_selector.set_current_screen(this.next_screen);
|
this.pos_widget.screen_selector.set_current_screen(this.next_screen);
|
||||||
|
|
|
@ -319,6 +319,155 @@
|
||||||
</div>
|
</div>
|
||||||
</t>
|
</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) <= 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">
|
<t t-name="WelcomeScreenWidget">
|
||||||
<div class="welcome-screen screen">
|
<div class="welcome-screen screen">
|
||||||
<header class='rightpane-header'><h2>Welcome</h2></header>
|
<header class='rightpane-header'><h2>Welcome</h2></header>
|
||||||
|
|
Loading…
Reference in New Issue