[WIP] pos_barcodes: initial commit of the barcode nomenclature addon for the point...
authorFrederic van der Essen <fva@openerp.com / fvdessen+o@gmail.com>
Tue, 30 Sep 2014 22:37:04 +0000 (00:37 +0200)
committerFrédéric van der Essen <fvdessen@gmail.com>
Tue, 25 Nov 2014 18:16:26 +0000 (19:16 +0100)
addons/point_of_sale/static/src/js/devices.js
addons/pos_barcodes/__init__.py [new file with mode: 0644]
addons/pos_barcodes/__openerp__.py [new file with mode: 0644]
addons/pos_barcodes/barcodes.py [new file with mode: 0644]
addons/pos_barcodes/barcodes_view.xml [new file with mode: 0644]
addons/pos_barcodes/static/src/js/barcodes.js [new file with mode: 0644]
addons/pos_barcodes/views/templates.xml [new file with mode: 0644]

index 5e813b9..09595c0 100644 (file)
@@ -635,7 +635,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
                     if( p === 'N'){
                         value *= 10;
                         value += v;
-                    }else if( p === 'D'){
+                    }else if( p === 'D'){   // FIXME precision ....
                         decimals += 1;
                         value += v * Math.pow(10,-decimals);
                     }
diff --git a/addons/pos_barcodes/__init__.py b/addons/pos_barcodes/__init__.py
new file mode 100644 (file)
index 0000000..e69cfb8
--- /dev/null
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#    
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.     
+#
+##############################################################################
+
+import barcodes
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/pos_barcodes/__openerp__.py b/addons/pos_barcodes/__openerp__.py
new file mode 100644 (file)
index 0000000..afd208f
--- /dev/null
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+
+{
+    'name': 'Advanced Barcodes',
+    'version': '1.0',
+    'category': 'Point of Sale',
+    'sequence': 6,
+    'summary': 'Advanced Barcode Setup for the Point of Sale',
+    'description': """
+
+=======================
+
+This module unlocks several advanced barcode features for the point of sale:
+
+- Barcode aliases allows you to identify the same product with different barcodes
+- Barcode patterns to identify customers, employees, weighted, discounted, and custom priced products
+- Unlimited barcode patterns and definitions. 
+
+""",
+    'author': 'OpenERP SA',
+    'depends': ['point_of_sale'],
+    'website': 'https://www.odoo.com/page/point-of-sale',
+    'data': [
+        'barcodes_view.xml',
+        'views/templates.xml',
+    ],
+    'installable': True,
+    'auto_install': False,
+}
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pos_barcodes/barcodes.py b/addons/pos_barcodes/barcodes.py
new file mode 100644 (file)
index 0000000..492f573
--- /dev/null
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+import logging
+
+import openerp
+from openerp import tools
+from openerp.osv import fields, osv
+from openerp.tools.translate import _
+
+_logger = logging.getLogger(__name__)
+
+class barcode_nomenclature(osv.osv):
+    _name = 'barcode.nomenclature'
+    _columns = {
+        'name':             fields.char('Nomenclature Name', size=32, required=True, help='An internal identification of the barcode nomenclature'),
+        #'convert_to_ean13': fields.boolean('Convert to EAN-13',help='Numerical Barcodes shorter than EAN-13 will be automatically converted to EAN-13'),
+        'pos_config_ids':   fields.one2many('pos.config','barcode_nomenclature_id','Point of Sale', help='The Point of Sales using this barcode nomenclature'),
+        'rule_ids':        fields.one2many('barcode.rule','barcode_nomenclature_id','Rules', help='The list of barcode rules'),
+    }
+
+class barcode_rule(osv.osv):
+    _name = 'barcode.rule'
+    _columns = {
+        'name':     fields.char('Rule Name', size=32, required=True, help='An internal identification for this barcode nomenclature rule'),
+        'barcode_nomenclature_id':     fields.many2one('barcode.nomenclature','Barcode Nomenclature'),
+        'priority': fields.float('Priority', help='Rules with a higher priority match first'),
+        #'encoding': fields.selection([('any','Any'),('ean13','EAN-13'),('ean8','EAN-8'),('codabar','Codabar'),('upca','UPC-A'),('upce','UPC-E')],'Encoding',help='This rule will apply only if the barcode is encoded with the specified encoding'),
+        'type':     fields.selection([('unit','Unit Product'),('weight','Weighted Product'),('price','Priced Product'),('discount','Discounted Product'),('client','Client'),('cashier','Cashier')],'Type', required=True),
+        'pattern':  fields.char('Barcode Pattern', size=32, help="The barcode matching pattern"),
+        #'alias':    fields.char('Alias',size=32,help='The matched pattern will alias to this barcode'),      
+    }
+
+    _defaults = {
+        'type': 'unit',
+        'pattern': '*',
+        #'encoding': 'any',
+    }
+
+class pos_config(osv.osv):
+    _inherit = 'pos.config'
+    _columns = {
+        'barcode_nomenclature_id':  fields.many2one('barcode.nomenclature','Barcode Nomenclature', help='A barcode nomenclature'),
+    }
+            
+
diff --git a/addons/pos_barcodes/barcodes_view.xml b/addons/pos_barcodes/barcodes_view.xml
new file mode 100644 (file)
index 0000000..30e6b23
--- /dev/null
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<openerp>
+    <data>
+
+        <!--     BARCODE NOMENCLATURES     -->
+
+        <record model="ir.ui.view" id="view_barcode_nomenclature_form">
+            <field name="name">Barcode Nomenclatures</field>
+            <field name="model">barcode.nomenclature</field>
+            <field name="arch" type="xml">
+                <form string="Barcode Nomenclature">
+                    <sheet>
+                        <group col="4">
+                            <field name="name" />
+                        </group>
+                        <field name="rule_ids">
+                            <tree string='Tables'>
+                                <field name="name" />
+                                <field name="type" />
+                                <field name="pattern" />
+                                <field name="priority" />
+                            </tree>
+                        </field>
+                    </sheet>
+                </form>
+            </field>
+        </record>
+
+        <record model="ir.ui.view" id="view_barcode_nomenclature_tree">
+            <field name="name">Barcode Nomenclatures</field>
+            <field name="model">barcode.nomenclature</field>
+            <field name="arch" type="xml">
+                <tree string="Barcode Nomenclatures">
+                    <field name="name" />
+                </tree>
+            </field>
+        </record>
+
+        <record model="ir.actions.act_window" id="action_barcode_nomenclature_form">
+            <field name="name">Barcode Nomenclatures</field>
+            <field name="type">ir.actions.act_window</field>
+            <field name="res_model">barcode.nomenclature</field>
+            <field name="view_type">form</field>
+            <field name="view_mode">tree,form</field>
+            <field name="help" type="html">
+              <p class="oe_view_nocontent_create">
+                Click to add a Barcode Nomenclature .
+              </p><p>
+                A barcode nomenclature defines how the point of sale identify and interprets barcodes
+              </p>
+            </field>
+        </record>
+
+        <record model="ir.ui.view" id="view_barcode_rule_form">
+            <field name="name">Barcode Rule</field>
+            <field name="model">barcode.rule</field>
+            <field name="arch" type="xml">
+                <form string="Barcode Rule">
+                    <group col="4">
+                        <field name="name" />
+                        <field name="type" />
+                        <field name="priority" />
+                    </group>
+                    <group col="2">
+                        <field name="pattern" />
+                    </group>
+                </form>
+            </field>
+        </record>
+
+        <menuitem
+            parent="point_of_sale.menu_point_config_product"
+            action="action_barcode_nomenclature_form"
+            id="menu_barcode_nomenclature_all"
+            sequence="30"
+            groups="point_of_sale.group_pos_manager"/>
+
+
+    </data>
+</openerp>
diff --git a/addons/pos_barcodes/static/src/js/barcodes.js b/addons/pos_barcodes/static/src/js/barcodes.js
new file mode 100644 (file)
index 0000000..460a12c
--- /dev/null
@@ -0,0 +1,123 @@
+openerp.pos_barcodes = function(instance){
+    var module = instance.point_of_sale;
+    var _t     = instance.web._t;
+
+    // At POS Startup, load the barcode nomenclature and add it to the pos model
+    module.PosModel.prototype.models.push({
+        model: 'barcode.nomenclature',
+        fields: ['name','rule_ids'],
+        domain: function(self){ return [] },
+        loaded: function(self,nomenclatures){
+            if (self.config.barcode_nomenclature_id) {
+                for (var i = 0; i < nomenclatures.length; i++) {
+                    if (nomenclatures[i].id === self.config.barcode_nomenclature_id[0]) {
+                        self.nomenclature = nomenclatures[i];
+                    }
+                }
+            }
+            self.nomenclature = self.nomenclature || null;
+        },
+    });
+
+    module.PosModel.prototype.models.push({
+        model: 'barcode.rule',
+        fields: ['name','priority','type','pattern'],
+        domain: function(self){ return [['barcode_nomenclature_id','=',self.nomenclature ? self.nomenclature.id : 0]]; },
+        loaded: function(self,rules){
+            rules = rules.sort(function(a,b){ return b.priority - a.priority; });
+            self.nomenclature.rules = rules;
+            for (var i = 0; i < rules.length; i++) {
+                var pattern = rules[i].pattern;
+                pattern = pattern.replace(/[x\*]/gi,'x');
+                
+                while (pattern.length < 12) {
+                    pattern += 'x';
+                }
+             
+                rules[i].pattern = pattern;
+            }
+        },
+    });
+
+    module.BarcodeReader.include({
+        parse_ean: function(ean) {
+            var self = this;
+            var parse_result = {
+                encoding: 'ean13',
+                type: 'error',
+                code: ean,
+                base_code: ean,
+                value: 0,
+            };
+
+            if (!this.pos.nomenclature) {
+                return this._super(ean);
+            }
+
+            if (!this.check_ean(ean)) {
+                return parse_result;
+            }
+
+            function is_number(char) {
+                n = char.charCodeAt(0);
+                return n >= 48 && n <= 57;
+            }
+
+            function match_pattern(ean,pattern) {
+                for (var i = 0; i < pattern.length; i++) {
+                    var p = pattern[i];
+                    var e = ean[i];
+                    if( is_number(p) && p !== e ){
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+            function get_value(ean,pattern){
+                var value = 0;
+                var decimals = 0;
+                for(var i = 0; i < pattern.length; i++){
+                    var p = pattern[i];
+                    var v = parseInt(ean[i]);
+                    if( p === 'N'){
+                        value *= 10;
+                        value += v;
+                    }else if( p === 'D'){   // FIXME precision ...
+                        decimals += 1;
+                        value += v * Math.pow(10,-decimals);
+                    }
+                }
+                return value;
+            }
+
+            function get_basecode(ean,pattern){
+                var base = '';
+                for(var i = 0; i < pattern.length; i++){
+                    var p = pattern[i];
+                    var v = ean[i];
+                    if( p === 'x'  || is_number(p)){
+                        base += v;
+                    }else{
+                        base += '0';
+                    }
+                }
+                return self.sanitize_ean(base);
+            }
+
+            var rules = this.pos.nomenclature.rules;
+
+            for (var i = 0; i < rules.length; i++) {
+                if (match_pattern(ean,rules[i].pattern)) {
+                    parse_result.type      = rules[i].type;
+                    parse_result.value     = get_value(ean,patterns[i].pattern);
+                    parse_result.base_code = get_basecode(ean,patterns[i].pattern);
+                    return parse_result;
+                }
+            }
+
+            return parse_result;
+        },
+    });
+
+};
diff --git a/addons/pos_barcodes/views/templates.xml b/addons/pos_barcodes/views/templates.xml
new file mode 100644 (file)
index 0000000..9f2b357
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- vim:fdn=3:
+-->
+<openerp>
+    <data>
+
+        <template id="assets_frontend" inherit_id="web.assets_common">
+          <xpath expr="." position="inside">
+              <script type="text/javascript" src="/pos_barcodes/static/src/js/barcodes.js"></script>
+          </xpath>
+        </template>
+
+    </data>
+</openerp>