Преглед на файлове

Impresion ticket pos con delivery y mesa.

Sebas преди 5 години
ревизия
d76a9b9ee5
променени са 10 файла, в които са добавени 736 реда и са изтрити 0 реда
  1. 1 0
      __init__.py
  2. BIN
      __init__.pyc
  3. 20 0
      __openerp__.py
  4. 24 0
      static/src/js/customer.js
  5. 8 0
      static/src/js/main.js
  6. 68 0
      static/src/js/model.js
  7. 444 0
      static/src/js/screen.js
  8. 136 0
      static/src/xml/pos.xml
  9. 23 0
      static/src/xml/view.xml
  10. 12 0
      template.xml

+ 1 - 0
__init__.py

@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-

BIN
__init__.pyc


+ 20 - 0
__openerp__.py

@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+{
+    'name': 'Pos ticket with Delivery',
+    'category': 'Point Of Sale',
+    'version': '8.0.1.0.0',
+    'depends': [
+        'point_of_sale',
+    ],
+    'data': [
+        "template.xml",
+    ],
+    'qweb': [
+        'static/src/xml/pos.xml',
+        'static/src/xml/view.xml',
+    ],
+    'author': 'Eiru',
+    'website': 'https://www.eiru.com.py',
+    'license': 'AGPL-3',
+    'installable': True,
+}

+ 24 - 0
static/src/js/customer.js

@@ -0,0 +1,24 @@
+function pos_customer(instance, module){
+
+    var PosModelSuper = module.PosModel;
+    module.PosModel = module.PosModel.extend({
+        load_server_data: function(){
+            var self = this;
+            var loaded = PosModelSuper.prototype.load_server_data.call(this);
+
+            loaded = loaded.then(function(){
+                return self.fetch(
+                    'res.partner',
+                    ['ruc'],
+                );
+
+            }).then(function(partners){
+                $.each(partners, function(){
+                    $.extend(self.db.get_partner_by_id(this.id) || {}, this);
+                });
+                return $.when();
+            });
+            return loaded;
+        },
+    });
+}

+ 8 - 0
static/src/js/main.js

@@ -0,0 +1,8 @@
+openerp.pos_ticket_delivery = function(instance) {
+    var module = instance.point_of_sale;
+    pos_screens(instance, module);
+    pos_customer(instance, module);
+    pos_ticket_model(instance, module);
+
+    instance.web.client_actions.add('pos.ui', 'instance.point_of_sale.PosWidget');
+};

+ 68 - 0
static/src/js/model.js

@@ -0,0 +1,68 @@
+function pos_ticket_model(instance, module){
+    var _t = instance.web._t,
+        _lt = instance.web._lt;
+    var QWeb = instance.web.qweb;
+
+    module.ReceiptScreenWidget = module.ScreenWidget.extend({
+        template: 'ReceiptScreenWidget',
+
+        show_numpad:     false,
+        show_leftpane:   false,
+
+        show: function(){
+            this._super();
+            var self = this;
+
+            var print_button = this.add_action_button({
+                    label: _t('Print'),
+                    icon: '/point_of_sale/static/src/img/icons/png48/printer.png',
+                    click: function(){ self.print(); },
+                });
+
+            var finish_button = this.add_action_button({
+                    label: _t('Next Order'),
+                    icon: '/point_of_sale/static/src/img/icons/png48/go-next.png',
+                    click: function() { self.finishOrder(); },
+                });
+
+            this.refresh();
+
+            // if (!this.pos.get('selectedOrder')._printed) {
+            //     this.print();
+            // }
+
+            finish_button.set_disabled(true);
+            setTimeout(function(){
+                finish_button.set_disabled(false);
+            }, 2000);
+        },
+        print: function() {
+            this.pos.get('selectedOrder')._printed = true;
+            window.print();
+        },
+        finishOrder: function() {
+            this.pos.get('selectedOrder').destroy();
+        },
+        refresh: function() {
+            var order = this.pos.get('selectedOrder');
+            var orderLines = order.get('orderLines').models;
+            // console.log(orderLines);
+            var qty =  _.reduce(_.map(orderLines,function(item){
+                return item.quantity;
+            }), function(memo, num){
+                return memo + num;
+            },0);
+            // console.log(total);
+            $('.pos-receipt-container', this.$el).html(QWeb.render('PosTicket',{
+                    widget:this,
+                    order: order,
+                    orderlines: order.get('orderLines').models,
+                    paymentlines: order.get('paymentLines').models,
+                    quantity: qty,
+                }));
+        },
+        close: function(){
+            this._super();
+        }
+    });
+}

+ 444 - 0
static/src/js/screen.js

@@ -0,0 +1,444 @@
+function pos_screens(instance, module){ //module is instance.point_of_sale
+    var QWeb = instance.web.qweb,
+    _t = instance.web._t;
+
+    var round_pr = instance.web.round_precision
+
+    module.ClientListScreenWidget = module.ScreenWidget.extend({
+        template: 'ClientListScreenWidget',
+
+        init: function(parent, options){
+            this._super(parent, options);
+        },
+
+        show_leftpane: false,
+
+        auto_back: true,
+
+        show: function(){
+            var self = this;
+            this._super();
+
+            this.renderElement();
+            this.details_visible = false;
+            this.old_client = this.pos.get('selectedOrder').get('client');
+            this.new_client = this.old_client;
+
+            this.$('.back').click(function(){
+                self.pos_widget.screen_selector.back();
+            });
+
+            this.$('.next').click(function(){
+                self.save_changes();
+                self.pos_widget.screen_selector.back();
+            });
+
+            this.$('.new-customer').click(function(){
+                self.display_client_details('edit',{
+                    'country_id': self.pos.company.country_id,
+                });
+            });
+
+            var partners = this.pos.db.get_partners_sorted(1000);
+            this.render_list(partners);
+
+            this.reload_partners();
+
+            if( this.old_client ){
+                this.display_client_details('show',this.old_client,0);
+            }
+
+            this.$('.client-list-contents').delegate('.client-line','click',function(event){
+                self.line_select(event,$(this),parseInt($(this).data('id')));
+            });
+
+            var search_timeout = null;
+
+            if(this.pos.config.iface_vkeyboard && this.pos_widget.onscreen_keyboard){
+                this.pos_widget.onscreen_keyboard.connect(this.$('.searchbox input'));
+            }
+
+            this.$('.searchbox input').on('keyup',function(event){
+                clearTimeout(search_timeout);
+
+                var query = this.value;
+
+                search_timeout = setTimeout(function(){
+                    self.perform_search(query,event.which === 13);
+                },70);
+            });
+
+            this.$('.searchbox .search-clear').click(function(){
+                self.clear_search();
+            });
+        },
+        barcode_client_action: function(code){
+            if (this.editing_client) {
+                this.$('.detail.barcode').val(code.code);
+            } else if (this.pos.db.get_partner_by_ean13(code.code)) {
+                this.display_client_details('show',this.pos.db.get_partner_by_ean13(code.code));
+            }
+        },
+        perform_search: function(query, associate_result){
+            var customers;
+            if(query){
+                customers = this.pos.db.search_partner(query);
+                this.display_client_details('hide');
+                if ( associate_result && customers.length === 1){
+                    this.new_client = customers[0];
+                    this.save_changes();
+                    this.pos_widget.screen_selector.back();
+                }
+                this.render_list(customers);
+            }else{
+                customers = this.pos.db.get_partners_sorted();
+                this.render_list(customers);
+            }
+        },
+        clear_search: function(){
+            var customers = this.pos.db.get_partners_sorted(1000);
+            this.render_list(customers);
+            this.$('.searchbox input')[0].value = '';
+            this.$('.searchbox input').focus();
+        },
+        render_list: function(partners){
+            var contents = this.$el[0].querySelector('.client-list-contents');
+            contents.innerHTML = "";
+            for(var i = 0, len = Math.min(partners.length,1000); i < len; i++){
+                var partner    = partners[i];
+                var clientline_html = QWeb.render('ClientLine',{widget: this, partner:partners[i]});
+                var clientline = document.createElement('tbody');
+                clientline.innerHTML = clientline_html;
+                clientline = clientline.childNodes[1];
+
+                if( partners === this.new_client ){
+                    clientline.classList.add('highlight');
+                }else{
+                    clientline.classList.remove('highlight');
+                }
+
+                contents.appendChild(clientline);
+            }
+        },
+        save_changes: function(){
+            if( this.has_client_changed() ){
+                this.pos.get('selectedOrder').set_client(this.new_client);
+            }
+        },
+        has_client_changed: function(){
+            if( this.old_client && this.new_client ){
+                return this.old_client.id !== this.new_client.id;
+            }else{
+                return !!this.old_client !== !!this.new_client;
+            }
+        },
+        toggle_save_button: function(){
+            var $button = this.$('.button.next');
+            if (this.editing_client) {
+                $button.addClass('oe_hidden');
+                return;
+            } else if( this.new_client ){
+                if( !this.old_client){
+                    $button.text(_t('Set Customer'));
+                }else{
+                    $button.text(_t('Change Customer'));
+                }
+            }else{
+                $button.text(_t('Deselect Customer'));
+            }
+            $button.toggleClass('oe_hidden',!this.has_client_changed());
+        },
+        line_select: function(event,$line,id){
+            var partner = this.pos.db.get_partner_by_id(id);
+            this.$('.client-list .lowlight').removeClass('lowlight');
+            if ( $line.hasClass('highlight') ){
+                $line.removeClass('highlight');
+                $line.addClass('lowlight');
+                this.display_client_details('hide',partner);
+                this.new_client = null;
+                this.toggle_save_button();
+            }else{
+                this.$('.client-list .highlight').removeClass('highlight');
+                $line.addClass('highlight');
+                var y = event.pageY - $line.parent().offset().top
+                this.display_client_details('show',partner,y);
+                this.new_client = partner;
+                this.toggle_save_button();
+            }
+        },
+        partner_icon_url: function(id){
+            return '/web/binary/image?model=res.partner&id='+id+'&field=image_small';
+        },
+
+        // ui handle for the 'edit selected customer' action
+        edit_client_details: function(partner) {
+            this.display_client_details('edit',partner);
+        },
+
+        // ui handle for the 'cancel customer edit changes' action
+        undo_client_details: function(partner) {
+            if (!partner.id) {
+                this.display_client_details('hide');
+            } else {
+                this.display_client_details('show',partner);
+            }
+        },
+
+        // what happens when we save the changes on the client edit form -> we fetch the fields, sanitize them,
+        // send them to the backend for update, and call saved_client_details() when the server tells us the
+        // save was successfull.
+        save_client_details: function(partner) {
+            var self = this;
+
+            var fields = {}
+            this.$('.client-details-contents .detail').each(function(idx,el){
+                fields[el.name] = el.value;
+            });
+
+            if (!fields.name) {
+                this.pos_widget.screen_selector.show_popup('error',{
+                    message: _t('A Customer Name Is Required'),
+                });
+                return;
+            }
+
+            if (this.uploaded_picture) {
+                fields.image = this.uploaded_picture;
+            }
+
+            fields.id           = partner.id || false;
+            fields.country_id   = fields.country_id || false;
+            fields.ean13        = fields.ean13 ? this.pos.barcode_reader.sanitize_ean(fields.ean13) : false;
+
+            new instance.web.Model('res.partner').call('create_from_ui',[fields]).then(function(partner_id){
+                self.saved_client_details(partner_id, fields);
+            },function(err,event){
+                event.preventDefault();
+                self.pos_widget.screen_selector.show_popup('error',{
+                    'message':_t('Error: Could not Save Changes'),
+                    'comment':_t('Your Internet connection is probably down.'),
+                });
+            });
+        },
+
+        // what happens when we've just pushed modifications for a partner of id partner_id
+        saved_client_details: function(partner_id, fields){
+            var self = this;
+            this.reload_partners().then(function(){
+                var partner = self.pos.db.get_partner_by_id(partner_id);
+                partner['ruc'] = fields.ruc;
+                if (partner) {
+                    self.new_client = partner;
+                    self.toggle_save_button();
+                    self.display_client_details('show',partner);
+                } else {
+                    // should never happen, because create_from_ui must return the id of the partner it
+                    // has created, and reload_partner() must have loaded the newly created partner.
+                    self.display_client_details('hide');
+                }
+            });
+        },
+
+        // resizes an image, keeping the aspect ratio intact,
+        // the resize is useful to avoid sending 12Mpixels jpegs
+        // over a wireless connection.
+        resize_image_to_dataurl: function(img, maxwidth, maxheight, callback){
+            img.onload = function(){
+                var png = new Image();
+                var canvas = document.createElement('canvas');
+                var ctx    = canvas.getContext('2d');
+                var ratio  = 1;
+
+                if (img.width > maxwidth) {
+                    ratio = maxwidth / img.width;
+                }
+                if (img.height * ratio > maxheight) {
+                    ratio = maxheight / img.height;
+                }
+                var width  = Math.floor(img.width * ratio);
+                var height = Math.floor(img.height * ratio);
+
+                canvas.width  = width;
+                canvas.height = height;
+                ctx.drawImage(img,0,0,width,height);
+
+                var dataurl = canvas.toDataURL();
+                callback(dataurl);
+            }
+        },
+
+        // Loads and resizes a File that contains an image.
+        // callback gets a dataurl in case of success.
+        load_image_file: function(file, callback){
+            var self = this;
+            if (!file.type.match(/image.*/)) {
+                this.pos_widget.screen_selector.show_popup('error',{
+                    message:_t('Unsupported File Format'),
+                    comment:_t('Only web-compatible Image formats such as .png or .jpeg are supported'),
+                });
+                return;
+            }
+
+            var reader = new FileReader();
+            reader.onload = function(event){
+                var dataurl = event.target.result;
+                var img     = new Image();
+                img.src = dataurl;
+                self.resize_image_to_dataurl(img,800,600,callback);
+            }
+            reader.onerror = function(){
+                self.pos_widget.screen_selector.show_popup('error',{
+                    message:_t('Could Not Read Image'),
+                    comment:_t('The provided file could not be read due to an unknown error'),
+                });
+            };
+            reader.readAsDataURL(file);
+        },
+
+        // This fetches partner changes on the server, and in case of changes,
+        // rerenders the affected views
+        reload_partners: function(){
+            var self = this;
+            return this.pos.load_new_partners().then(function(){
+                self.render_list(self.pos.db.get_partners_sorted(1000));
+
+                // update the currently assigned client if it has been changed in db.
+                var curr_client = self.pos.get_order().get_client();
+                if (curr_client) {
+                    self.pos.get_order().set_client(self.pos.db.get_partner_by_id(curr_client.id));
+                }
+            });
+        },
+
+        // Shows,hides or edit the customer details box :
+        // visibility: 'show', 'hide' or 'edit'
+        // partner:    the partner object to show or edit
+        // clickpos:   the height of the click on the list (in pixel), used
+        //             to maintain consistent scroll.
+        display_client_details: function(visibility,partner,clickpos){
+            var self = this;
+            var contents = this.$('.client-details-contents');
+            var parent   = this.$('.client-list').parent();
+            var scroll   = parent.scrollTop();
+            var height   = contents.height();
+
+            contents.off('click','.button.edit');
+            contents.off('click','.button.save');
+            contents.off('click','.button.undo');
+            contents.on('click','.button.edit',function(){ self.edit_client_details(partner); });
+            contents.on('click','.button.save',function(){ self.save_client_details(partner); });
+            contents.on('click','.button.undo',function(){ self.undo_client_details(partner); });
+            this.editing_client = false;
+            this.uploaded_picture = null;
+
+            if(visibility === 'show'){
+                contents.empty();
+                contents.append($(QWeb.render('ClientDetails',{widget:this,partner:partner})));
+
+                var new_height   = contents.height();
+
+                if(!this.details_visible){
+                    if(clickpos < scroll + new_height + 20 ){
+                        parent.scrollTop( clickpos - 20 );
+                    }else{
+                        parent.scrollTop(parent.scrollTop() + new_height);
+                    }
+                }else{
+                    parent.scrollTop(parent.scrollTop() - height + new_height);
+                }
+
+                this.details_visible = true;
+                this.toggle_save_button();
+            } else if (visibility === 'edit') {
+                this.editing_client = true;
+                contents.empty();
+                contents.append($(QWeb.render('ClientDetailsEdit',{widget:this,partner:partner})));
+                this.toggle_save_button();
+
+                contents.find('.image-uploader').on('change',function(event){
+                    self.load_image_file(event.target.files[0],function(res){
+                        if (res) {
+                            contents.find('.client-picture img, .client-picture .fa').remove();
+                            contents.find('.client-picture').append("<img src='"+res+"'>");
+                            contents.find('.detail.picture').remove();
+                            self.uploaded_picture = res;
+                        }
+                    });
+                });
+            } else if (visibility === 'hide') {
+                contents.empty();
+                if( height > scroll ){
+                    contents.css({height:height+'px'});
+                    contents.animate({height:0},400,function(){
+                        contents.css({height:''});
+                    });
+                }else{
+                    parent.scrollTop( parent.scrollTop() - height);
+                }
+                this.details_visible = false;
+                this.toggle_save_button();
+            }
+        },
+        close: function(){
+            this._super();
+        },
+    });
+
+    module.ReceiptScreenWidget = module.ScreenWidget.extend({
+        template: 'ReceiptScreenWidget',
+
+        show_numpad:     false,
+        show_leftpane:   false,
+
+        show: function(){
+            this._super();
+            var self = this;
+
+            var print_button = this.add_action_button({
+                    label: _t('Print'),
+                    icon: '/point_of_sale/static/src/img/icons/png48/printer.png',
+                    click: function(){ self.print(); },
+                });
+
+            var finish_button = this.add_action_button({
+                    label: _t('Next Order'),
+                    icon: '/point_of_sale/static/src/img/icons/png48/go-next.png',
+                    click: function() { self.finishOrder(); },
+                });
+
+            this.refresh();
+
+            finish_button.set_disabled(true);
+            setTimeout(function(){
+                finish_button.set_disabled(false);
+            }, 2000);
+        },
+        print: function() {
+            this.pos.get('selectedOrder')._printed = true;
+            window.print();
+        },
+        finishOrder: function() {
+            this.pos.get('selectedOrder').destroy();
+        },
+        refresh: function() {
+            var order = this.pos.get('selectedOrder');
+
+            var pos_driver = _.find(this.pos.users, function (item) {
+                return item.id === order.attributes.pos_driver
+            });
+
+            $('.pos-receipt-container', this.$el).html(QWeb.render('PosTicket',{
+                widget:this,
+                order: order,
+                pos_driver_name: (pos_driver && pos_driver.name) || '' ,
+                table_name: (order.attributes.table && order.attributes.table.name) || '' ,
+                orderlines: order.get('orderLines').models,
+                paymentlines: order.get('paymentLines').models
+            }));
+        },
+        close: function(){
+            this._super();
+        }
+    });
+
+}

+ 136 - 0
static/src/xml/pos.xml

@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates>
+    <t t-extend="PosTicket">
+        <t t-jquery="div.pos-sale-ticket" t-operation="replace">
+            <div class="pos-sale-ticket" style='font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 15px;'>
+                <!-- <div id="company_logo">
+                    <img t-att-src="logo" style="width:100%;"/>
+                </div> -->
+                <br/><br/>
+                <div class="pos-center-align"><t t-esc="new Date().toString(Date.CultureInfo.formatPatterns.shortDate + ' ' +
+                    Date.CultureInfo.formatPatterns.longTime)"/>
+                    <br/>
+                    <t t-esc="order.get('name')"/></div>
+
+                <br/>
+                <br />
+                <t t-if="widget.pos.config.receipt_header">
+                    <div style='text-align:center;font-size: 30px;'>
+                        <t t-esc="widget.pos.config.receipt_header" />
+                    </div>
+                    <br />
+                </t>
+                <t t-esc="widget.pos.company.name || ''"/><br />
+                <t t-esc="widget.pos.company.street || ''"/><br />
+                <t t-esc="widget.pos.company.phone || ''"/><br />
+                <br/>
+                User: <t t-esc="widget.pos.cashier ? widget.pos.cashier.name : widget.pos.user.name"/>
+                <t t-if="order.attributes.client">
+                    <p>========================</p>
+                    <!-- RUC: <t t-esc="order.attributes.client.ruc ? order.attributes.client.ruc : ''"/><br /> -->
+                    Cliente: <t t-esc="order.attributes.client.name ? order.attributes.client.name : ''"/><br />
+                    Teléfono: <t t-esc="order.attributes.client.phone ? order.attributes.client.phone : ''"/><br />
+                    Dirección: <t t-esc="order.attributes.client.address ? order.attributes.client.address : ''"/><br />
+                    Delivery: <t t-esc="pos_driver_name"/><br />
+                    Mesa N°: <t t-esc="table_name"/>
+                </t>
+                <p>========================</p>
+                <table class="table table-condensed" style="font-size: 12px;">
+                    <thead>
+                        <tr>
+                            <th class="text-right">Cant.</th>
+                            <th>Producto</th>
+                            <th class="text-right">Precio</th>
+                            <th class="text-right">Sub-total</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        <colgroup>
+                            <col width='15%'/>
+                            <col width='35%'/>
+                            <col width='25%'/>
+                            <col width='25%'/>
+                        </colgroup>
+                        <t t-foreach="orderlines" t-as="orderline">
+                            <tr>
+                                <td>
+                                    <t t-esc="orderline.quantity"/>
+                                </td>
+                                <td>
+                                    <t t-esc="orderline.get_product().display_name"/>
+                                </td>
+                                <td>
+                                    <t t-esc="widget.format_currency(orderline.price)"/>
+                                </td>
+                                <td class="pos-right-align">
+                                    <t t-esc="widget.format_currency(orderline.get_display_price())"/>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td>********</td>
+                                <td>******************</td>
+                                <td>*************</td>
+                                <td>*************</td>
+                            </tr>
+                        </t>
+                    </tbody>
+                </table>
+                <p>========================</p>
+                <strong>Total de items: <t t-esc="quantity"/></strong>
+                <p>========================</p>
+                <table>
+                    <tr>
+                        <td>Subtotal:</td>
+                        <td class="pos-right-align">
+                            <t t-esc="widget.format_currency(order.getTotalTaxExcluded())"/>
+                        </td>
+                    </tr>
+                    <t t-foreach="order.getTaxDetails()" t-as="taxdetail">
+                        <tr>
+                            <td><t t-esc="taxdetail.name" /></td>
+                            <td class="pos-right-align">
+                                <t t-esc="widget.format_currency(taxdetail.amount)"/>
+                            </td>
+                        </tr>
+                    </t>
+                    <tr>
+                        <td>Descuento:</td>
+                        <td class="pos-right-align">
+                            <t t-esc="widget.format_currency(order.getDiscountTotal())"/>
+                        </td>
+                    </tr>
+                    <tr class="emph">
+                        <td>Total:</td>
+                        <td class="pos-right-align" style='font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 20px;'>
+                            <t t-esc="widget.format_currency(order.getTotalTaxIncluded())"/>
+                        </td>
+                    </tr>
+                </table>
+                <p>========================</p>
+                <table>
+                    <tr t-foreach="paymentlines" t-as="line">
+                        <td>
+                            <t t-esc="line.name"/>
+                        </td>
+                        <td class="pos-right-align">
+                            <t t-esc="widget.format_currency(line.get_amount())"/>
+                        </td>
+                    </tr>
+                </table>
+                <br />
+                <table>
+                    <tr><td>Change:</td><td class="pos-right-align">
+                        <t t-esc="widget.format_currency(order.getChange())"/>
+                        </td></tr>
+                </table>
+                <br/>
+                <t t-if="widget.pos.config.receipt_footer">
+                    <br />
+                    <div style='text-align:center'>
+                        <t t-esc="widget.pos.config.receipt_footer" />
+                    </div>
+                </t>
+            </div>
+        </t>
+    </t>
+</templates>

+ 23 - 0
static/src/xml/view.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates id="template" xml:space="preserve">
+
+    <!-- Mostrar Formulario -->
+    <t t-extend="ClientDetails">
+        <t t-jquery="div.client-details-left>div:first-child" t-operation="before">
+            <div class='client-detail'>
+                <span class='label'>RUC-DNI</span>
+                <span class='detail client-ruc'><t t-esc='partner.ruc' /></span>
+            </div>
+        </t>
+    </t>
+
+    <!-- Editar Formulario -->
+    <t t-extend="ClientDetailsEdit">
+        <t t-jquery="div.client-details-left>div:first-child" t-operation="before">
+            <div class='client-detail'>
+                <span class='label'>RUC</span>
+                <input class='detail client-ruc' name='ruc' t-att-value='partner.ruc' placeholder='RUC-DNI'></input>
+            </div>
+        </t>
+    </t>
+</templates>

+ 12 - 0
template.xml

@@ -0,0 +1,12 @@
+<openerp>
+    <data>
+        <template id="pos_ticket_delivery_assets_backend" name="pos_ticket_delivery_assets_backend" inherit_id="web.assets_backend">
+            <xpath expr="." position="inside">
+                <script src="/pos_ticket_delivery/static/src/js/main.js" type="text/javascript"></script>
+                <script src="/pos_ticket_delivery/static/src/js/customer.js" type="text/javascript"></script>
+                <script src="/pos_ticket_delivery/static/src/js/screen.js" type="text/javascript"></script>
+                <script src="/pos_ticket_delivery/static/src/js/model.js" type="text/javascript"></script>
+            </xpath>
+        </template>
+    </data>
+</openerp>