[IMP] hw_escpos / point_of_sale: print receipt with an xml template
authorFrédéric van der Essen <fva@openerp.com>
Thu, 20 Mar 2014 16:45:30 +0000 (17:45 +0100)
committerFrédéric van der Essen <fva@openerp.com>
Thu, 20 Mar 2014 16:45:30 +0000 (17:45 +0100)
bzr revid: fva@openerp.com-20140320164530-odpeuf1igh7wkrms

addons/hw_escpos/escpos/escpos.py
addons/point_of_sale/static/src/js/devices.js
addons/point_of_sale/static/src/js/models.js
addons/point_of_sale/static/src/js/screens.js
addons/point_of_sale/static/src/xml/pos.xml

index cefa00f..7e1b18c 100644 (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)
index 5db9192..f46b156 100644 (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(){
index c8c87f1..8de82b4 100644 (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,
index 937ee3f..1d6f018 100644 (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);
index d0cd945..baea81b 100644 (file)
         </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>