瀏覽代碼

Usar funciones de pos por teclado.

Sebas 6 年之前
當前提交
ab448b4e6f

+ 12 - 0
__init__.py

@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+#################################################################################
+# Author      : Acespritech Solutions Pvt. Ltd. (<www.acespritech.com>)
+# Copyright(c): 2012-Present Acespritech Solutions Pvt. Ltd.
+# All Rights Reserved.
+#
+# This program is copyright property of the author mentioned above.
+# You can`t redistribute it and/or modify it.
+#
+#################################################################################
+import account
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

二進制
__init__.pyc


+ 31 - 0
__openerp__.py

@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+#################################################################################
+# Author      : Acespritech Solutions Pvt. Ltd. (<www.acespritech.com>)
+# Copyright(c): 2012-Present Acespritech Solutions Pvt. Ltd.
+# All Rights Reserved.
+#
+# This program is copyright property of the author mentioned above.
+# You can`t redistribute it and/or modify it.
+#
+#################################################################################
+{
+    'name': 'POS Keyboard Shortcuts',
+    'version': '1.0',
+    'category': 'Point of Sale',
+    'summary': 'POS Keyboard Shortcuts',
+    'description': """
+This module is used to handle point of sale features with keyboard shortcuts.
+""",
+    'author': "Acespritech Solutions Pvt. Ltd.",
+    'website': "www.acespritech.com",
+    'price': 25.00,
+    'currency': 'EUR',
+    'depends': ['web', 'point_of_sale', 'base'],
+    'images': ['static/description/main_screenshot.png'],
+    'data': ['views/pos_keyboard.xml',
+             'account/account_view.xml',
+             'views/res_company.xml'],
+    'installable': True,
+    'auto_install': False,
+}
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

+ 12 - 0
account/__init__.py

@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+#################################################################################
+# Author      : Acespritech Solutions Pvt. Ltd. (<www.acespritech.com>)
+# Copyright(c): 2012-Present Acespritech Solutions Pvt. Ltd.
+# All Rights Reserved.
+#
+# This program is copyright property of the author mentioned above.
+# You can`t redistribute it and/or modify it.
+#
+#################################################################################
+import account, res_company
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

二進制
account/__init__.pyc


+ 18 - 0
account/account.py

@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+#################################################################################
+# Author      : Acespritech Solutions Pvt. Ltd. (<www.acespritech.com>)
+# Copyright(c): 2012-Present Acespritech Solutions Pvt. Ltd.
+# All Rights Reserved.
+#
+# This program is copyright property of the author mentioned above.
+# You can`t redistribute it and/or modify it.
+#
+#################################################################################
+
+from openerp import models, fields, api, _
+
+
+class account_journal(models.Model):
+    _inherit = 'account.journal'
+
+    shortcut_key = fields.Char('Shortcut Key')

二進制
account/account.pyc


+ 17 - 0
account/account_view.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+        <record id="acespritech_view_account_journal_form" model="ir.ui.view">
+            <field name="name">acespritech.account.journal.form</field>
+            <field name="model">account.journal</field>
+            <field name="inherit_id" ref="account.view_account_journal_form"/>
+            <field name="arch" type="xml">
+                <field name="centralisation" position="before">
+                    <field name="shortcut_key"/>
+                </field>
+            </field>
+        </record>
+
+    </data>
+</openerp>

+ 24 - 0
account/res_company.py

@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+#################################################################################
+# Author      : Acespritech Solutions Pvt. Ltd. (<www.acespritech.com>)
+# Copyright(c): 2012-Present Acespritech Solutions Pvt. Ltd.
+# All Rights Reserved.
+#
+# This program is copyright property of the author mentioned above.
+# You can`t redistribute it and/or modify it.
+#
+#################################################################################
+
+from openerp import models, fields, api, _
+
+
+class res_company(models.Model):
+    _inherit = "res.company"
+
+    pos_price = fields.Char(string="Price", size=1)
+    pos_quantity = fields.Char(string="Quantity", size=1)
+    pos_discount = fields.Char(string=" Discount", size=1)
+    pos_search = fields.Char(string="Search", size=1)
+    pos_next = fields.Char(string="Next order", size=1)
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

二進制
account/res_company.pyc


二進制
static/description/ace_logo.png


二進制
static/description/icon.png


+ 52 - 0
static/description/index.html

@@ -0,0 +1,52 @@
+<section class="oe_container">
+    <div>
+        <div class="text-center">
+            <a target="new" href="http://www.acespritech.com">
+                <img src="ace_logo.png">
+            </a>
+        </div>
+    </div>
+</section>
+<br/>
+<section class="oe_container oe_dark">
+    <div class="oe_row">
+        <div class="oe_span12">
+            <h2 class="oe_slogan">Odoo 8 Point of Sale Extension</h2>
+            <h3 class="oe_slogan">User can use shortcuts in POS Interface.</h3>
+            <br/>
+            <div><font style="color:red;font-weight:bold;"><b>Note: </b>This module is tested and working in Odoo community edition but not tested in Enterprise version. And we are supporting Ubuntu OS and not Windows OS.</font></div>
+            <h4 class="oe_slogan">How to use</h4>
+            <div class="oe_screenshot" style="text-align: left;">
+	            <ul>
+	                <li style="color:#30054D;font-weight:bold;"><a style="color: blue; font-weight: 600;" href="https://www.youtube.com/watch?v=meNK9aENoO8" target="new">Let's see the video</a>
+	                </li>
+	                <li style="color:#30054D;font-weight:bold;">There are multiple shortcuts which user can use as mentioned below.</li>
+	            </ul>
+                <img style="max-width: 100%;" src="main_screenshot.png"><br /><br />
+                <img style="max-width: 100%;" src="pos_config.png"/><br /><br />
+            </div>
+        </div>
+    </div>
+</section>
+<section class="oe_container">
+   <div class="oe_row" style="background-color: #008000;"> 
+       <div style="margin-bottom:10px;" class="oe_slogan text-center">
+           <div class="oe_span12">
+               <h3 class="text-center" style="color:#FFFFFF; font-size:20px"><b>NOTE:</b> We give 60 days support for our customers. Before trying in your live db, please ask us to provide you for test link. If any other custom modules are installed and because of that some errors occurs then we charge extra.</h3>
+           </div>
+       </div>
+   </div>
+   <div class="oe_row" style="background-color: #004CFF;"> 
+       <div style="margin-bottom:10px;" class="oe_slogan text-center">
+           <div class="oe_span12">
+           <h3 class="text-center" style="color:#FFFFFF; font-size:20px">Contact us for support, query, customization</h3>
+       </div>
+           <span>
+               <a target="new" href="http://www.acespritech.com" style="color: yellow !important;font-weight:bold;">Website</a> | 
+               <a target="new" href="http://www.acespritechblog.com" style="color: yellow !important;font-weight:bold;">Blog</a> | 
+               <a href="mailto:info@acespritech.com" style="color: yellow !important;font-weight:bold;">Email us</a>
+               | <a style="color: yellow !important;font-weight:bold;">Skype: acespritech</a>
+           </span>
+       </div>
+   </div>
+</section>

二進制
static/description/main_screenshot.png


二進制
static/description/pos_config.png


二進制
static/src/img/search.png


二進制
static/src/img/search_reset.gif


+ 263 - 0
static/src/js/pos.js

@@ -0,0 +1,263 @@
+openerp.aces_pos_keyboard = function (instance) {
+    var _t = instance.web._t;
+    var QWeb = instance.web.qweb;
+    
+    var round_di = instance.web.round_decimals;
+    var round_pr = instance.web.round_precision;
+
+    var models = instance.point_of_sale.PosModel.prototype.models;
+	for (var i = 0; i < models.length; i++) {
+		var model = models[i];
+		if (model.model === 'res.company') {
+			model.fields.push('pos_price');
+			model.fields.push('pos_quantity');
+			model.fields.push('pos_discount');
+			model.fields.push('pos_search');
+			model.fields.push('pos_next');
+		}
+	} 
+    instance.point_of_sale.ReceiptScreenWidget = instance.point_of_sale.ReceiptScreenWidget.extend({
+        show: function(){
+            this._super();
+            var self = this;
+            var next = self.pos.company.pos_next;
+            this.handler_new_order = function(e){
+                if(String.fromCharCode(e.which) === next){ // for ASCII of 'n' character
+                    self.finishOrder();
+                }
+            };
+            $('body').on('keypress', this.handler_new_order);
+        },
+    });
+
+    var _super_order = instance.point_of_sale.Order.prototype;
+    instance.point_of_sale.Order = instance.point_of_sale.Order.extend({
+        addProduct: function(product, options){
+            var self = this;
+            _super_order.addProduct.call(this, product, options);
+            this.numpad_state = this.pos.pos_widget.numpad.state;
+            this.numpad_state.set('mode', 'quantity');
+            this.pos.pos_widget.numpad.changedMode();
+        }
+    });
+
+    instance.point_of_sale.ProductListWidget = instance.point_of_sale.ProductListWidget.extend({
+        defaults: {
+            buffer: "0",
+            mode: "quantity"
+        },
+        init: function(parent, options) {
+            var self = this;
+            this._super(parent,options);
+            var order_widget = this.pos;
+            this.state = new instance.point_of_sale.NumpadState();
+            var timeStamp = 0;
+            var ok = true;
+
+            this.handler_find_operation = function(e){
+                var token = String.fromCharCode(e.which);
+                var cashregisters = self.pos.cashregisters;
+                var paymentLines_keys = [];
+                var qty = self.pos.company.pos_quantity || '';
+                var search = self.pos.company.pos_search || '';
+                var discount = self.pos.company.pos_discount || '';
+		        var price = self.pos.company.pos_price || '';
+
+		        if (!(token == discount || token == price || (e.which >= 48 && e.which <= 57) 
+		    			|| e.which == 190 || token == qty || token == search || e.which == 8)) {
+                    var flag = true;
+		    		_.each(cashregisters, function(paymentline){
+				        if (paymentline.journal.shortcut_key && paymentline.journal.shortcut_key == String.fromCharCode(e.which)) {
+				        	flag = false;
+				        }
+					});
+		    		if (flag) {
+		    			return
+		    		}
+				}
+                var order = self.pos.get('selectedOrder');
+                oldBuffer = self.get('buffer');
+                if (oldBuffer === '0' || oldBuffer == undefined) {
+                    self.set({
+                        buffer: String.fromCharCode(e.which)
+                    });
+                } else if (oldBuffer === '-0') {
+                    self.set({
+                        buffer: "-" + String.fromCharCode(e.which)
+                    });
+                } else {
+                    self.set({
+                        buffer: (self.get('buffer')) + String.fromCharCode(e.which)
+                    });
+                }
+
+                var cashregisters = self.pos.cashregisters;
+                var paymentLines = order.get('paymentLines');
+                var paymentLines_keys = [];
+                _.each(cashregisters, function(paymentline){
+                    if (paymentline.journal.shortcut_key) {
+                        paymentLines_keys.push(paymentline.journal.shortcut_key);
+                    }
+                    if (paymentline.journal.shortcut_key && paymentline.journal.shortcut_key == String.fromCharCode(e.which)) {
+                        var newPaymentline = new instance.point_of_sale.Paymentline({},{cashregister:paymentline, pos:self.pos});
+                        if(paymentline.journal.type !== 'cash'){
+                            newPaymentline.set_amount( Math.max(order.getDueLeft(),0) );
+                        }
+                        
+                        paymentLines.add(newPaymentline);
+                        order.selectPaymentline(newPaymentline);
+                        self.pos_widget.screen_selector.set_current_screen('payment');
+                    }
+                });
+
+                if (e.which == 8 && order.getSelectedLine()) {
+                    if(self.get('buffer') === ""){
+                        if(self.get('mode') === 'quantity'){
+                            order.getSelectedLine().set_quantity('remove');
+                        }else if( self.get('mode') === 'discount'){
+                            order.getSelectedLine().set_discount(self.get('buffer'));
+                        }else if( self.get('mode') === 'price'){
+                            order.getSelectedLine().set_unit_price(self.get('buffer'));
+                        }
+                    } else {
+                        var newBuffer = "";
+                        self.set({ buffer: newBuffer });
+                        if(self.get('mode') === 'quantity'){
+                            if(self.get('buffer') === "") {
+                                order.getSelectedLine().set_quantity('remove');
+                            } else {
+                                order.getSelectedLine().set_quantity(self.get('buffer'));
+                            }
+                        }else if( self.get('mode') === 'discount'){
+                            order.getSelectedLine().set_discount(self.get('buffer'));
+                        }else if( self.get('mode') === 'price'){
+                            order.getSelectedLine().set_unit_price(self.get('buffer'));
+                        }
+                    }
+                }
+
+                if (token == search) {
+                    $( "div.searchbox" ).find( "input" ).focus();
+                    return
+                } else if (token == discount) {
+                    order_widget.pos_widget.numpad.state.set('mode', 'discount');
+                    self.set({
+                        buffer: "0",
+                        mode: 'discount'
+                    });
+                    order_widget.pos_widget.numpad.changedMode();
+                } else if (token == qty) {
+                    order_widget.pos_widget.numpad.state.set('mode', 'quantity');
+                    self.set({
+                        buffer: "0",
+                        mode: 'quantity'
+                    });
+                    order_widget.pos_widget.numpad.changedMode();
+                } else if (token == price) {
+                    order_widget.pos_widget.numpad.state.set('mode', 'price');
+                    self.set({
+                        buffer: "0",
+                        mode: 'price'
+                    });
+                    order_widget.pos_widget.numpad.changedMode();
+                } else if (order.getSelectedLine() && e.which != 113 && e.which != 100 && e.which != 112 &&
+                                   $.inArray(String.fromCharCode(e.which), paymentLines_keys) == -1) {
+                    var mode = order_widget.pos_widget.numpad.state.get('mode');
+                    if( mode === 'quantity'){
+                        if (order.getSelectedLine().get_quantity() == 1 || order.getSelectedLine().get_quantity() == 0 ) {
+                            if (self.get('buffer').length >= 1) {
+                                if ((self.get('buffer').length == 2 || self.get('buffer').length == 3) && self.get('buffer').slice(0,1) == '1') {
+                                    order.getSelectedLine().set_quantity(self.get('buffer'));
+                                } else {
+                                    var qty = self.get('buffer').split('');
+                                    self.set({
+                                        buffer: qty[qty.length-1],
+                                        mode: 'quantity'
+                                    });
+                                    order.getSelectedLine().set_quantity(qty[qty.length-1]);
+                                }
+                            }
+                        } else {
+                            order.getSelectedLine().set_quantity(self.get('buffer'));
+                        }
+                    }else if( mode === 'discount'){
+                        order.getSelectedLine().set_discount(self.get('buffer'));
+                    }else if( mode === 'price'){
+                        order.getSelectedLine().set_unit_price(self.get('buffer'));
+                    }
+                } else {
+                    return;
+                }
+            };
+
+            $('body').on('keypress', function(e){
+            	var order = self.pos.get('selectedOrder');
+            	var focus = $(":focus");
+            	if(focus.length > 0){
+            		if(focus[0].type){
+            			return
+            		}
+            	}
+            	if (timeStamp + 50 > new Date().getTime()) {
+                    ok = false;
+                } else {
+                    ok = true;
+                }
+                timeStamp = new Date().getTime();
+                setTimeout(function(){
+                    if (ok) {self.handler_find_operation(e);}
+                }, 50);
+            });
+
+            var rx = /INPUT|SELECT|TEXTAREA/i;
+            $('body').on("keydown keypress", function(e){
+                var order = self.pos.get('selectedOrder');
+                if( e.which == 8 && order.getSelectedLine() ){ // 8 == backspace
+                    if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
+                        e.preventDefault();
+                        if (self.get('mode') == 'quantity') {
+                            self.set({
+                                buffer: self.get('buffer').slice(0,-1),
+                                mode: 'quantity'
+                            });
+                            qty = self.get('buffer')
+                            if (qty == '' && order.getSelectedLine().get_quantity() == 0) {
+                                qty = 'remove';
+                            }
+                            order.getSelectedLine().set_quantity(qty);
+                        }
+                        if (self.get('mode') == 'discount') {
+                            self.set({
+                                buffer: self.get('buffer').slice(0,-1),
+                                mode: 'discount'
+                            });
+                            order.getSelectedLine().set_discount(self.get('buffer'));
+                        }
+                        if (self.get('mode') == 'price') {
+                            self.set({
+                                buffer: self.get('buffer').slice(0,-1),
+                                mode: 'price'
+                            });
+                            order.getSelectedLine().set_unit_price(self.get('buffer'));
+                        }
+                    }
+                } else if (e.which == 8) {
+                    if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
+                        e.preventDefault();
+                    } 
+                }
+            });
+        },
+    });
+
+    var _super_ProductCategoriesWidget = instance.point_of_sale.ProductCategoriesWidget.prototype;
+    instance.point_of_sale.ProductCategoriesWidget = instance.point_of_sale.ProductCategoriesWidget.extend({
+        // empties the content of the search box
+        clear_search: function(){
+            _super_ProductCategoriesWidget.clear_search.call(this);
+            var input = this.el.querySelector('.searchbox input');
+                input.value = '';
+                input.blur();
+        },
+    });
+}

+ 12 - 0
views/pos_keyboard.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+        <template id="assets_backend" name="aces_pos_keyboard assets" inherit_id="web.assets_backend">
+            <xpath expr="." position="inside">
+                <script type="text/javascript" src="/aces_pos_keyboard/static/src/js/pos.js"></script>
+            </xpath>
+        </template>
+
+    </data>
+</openerp>

+ 25 - 0
views/res_company.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<openerp>
+    <data>
+
+        <record id="view_company_form_ace" model="ir.ui.view">
+            <field name="name">res.company.form</field>
+            <field name="model">res.company</field>
+            <field name="inherit_id" ref="base.view_company_form"/>
+            <field name="arch" type="xml">
+                <page position="after">
+                    <page name="point_of_sale" string="POS Keyboard">
+                        <group col="4" colspan="4">
+                            <field name="pos_price"/>
+	                        <field name="pos_quantity"/>
+	                        <field name="pos_discount"/>
+	                        <field name="pos_search"/>
+	                        <field name="pos_next"/>
+                        </group>
+                    </page>
+                </page>
+            </field>
+        </record>
+
+    </data>
+</openerp>