[FIX] barcodes, stock, point_of_sale: parse_barcode function uses regex, pattern and barcodes may now contain special characters \ { and ., special character * replaced by .
This commit is contained in:
committed by
Frédéric van der Essen
parent
f250013329
commit
b671824048
+33
-61
@@ -88,69 +88,37 @@ class barcode_nomenclature(osv.osv):
|
||||
'base_code': barcode,
|
||||
'value': 0}
|
||||
|
||||
def match_pattern(barcode,pattern):
|
||||
if(len(barcode) < len(pattern.replace('{','').replace('}',''))):
|
||||
return False # match of this pattern is impossible
|
||||
numerical_content = False
|
||||
j=0
|
||||
for i in range(len(pattern)):
|
||||
p = pattern[i]
|
||||
if p == '{' or p == '}':
|
||||
numerical_content = not numerical_content
|
||||
continue
|
||||
def match_pattern(barcode, pattern):
|
||||
match = {
|
||||
"value": 0,
|
||||
"base_code": barcode,
|
||||
"match": False,
|
||||
}
|
||||
|
||||
if not numerical_content and p != '*' and p != barcode[j]:
|
||||
return False
|
||||
j+=1
|
||||
return True
|
||||
barcode = barcode.replace("\\", "\\\\").replace("{", '\{').replace("}", "\}").replace(".", "\.")
|
||||
numerical_content = re.search("[{][N]*[D]*[}]", pattern)
|
||||
|
||||
def get_value(barcode,pattern):
|
||||
value = 0
|
||||
decimals = 0
|
||||
numerical_content = False
|
||||
j = 0
|
||||
for i in range(len(pattern)):
|
||||
p = pattern[i]
|
||||
if not numerical_content and p != "{":
|
||||
j+=1
|
||||
continue
|
||||
elif p == "{":
|
||||
numerical_content = True
|
||||
continue
|
||||
elif p == "}":
|
||||
break;
|
||||
if numerical_content:
|
||||
num_start = numerical_content.start()
|
||||
num_end = numerical_content.end()
|
||||
value_string = barcode[num_start:num_end-2]
|
||||
|
||||
v = int(barcode[j])
|
||||
if p == 'N':
|
||||
value *= 10
|
||||
value += v
|
||||
elif p == 'D': #FIXME precision ....
|
||||
decimals += 1
|
||||
value += v * pow(10,-decimals)
|
||||
j+=1
|
||||
return value
|
||||
whole_part_match = re.search("[{][N]*[D}]", numerical_content.group())
|
||||
decimal_part_match = re.search("[{N][D]*[}]", numerical_content.group())
|
||||
whole_part = value_string[:whole_part_match.end()-2]
|
||||
decimal_part = "0." + value_string[decimal_part_match.start():decimal_part_match.end()-1]
|
||||
if whole_part == '':
|
||||
whole_part = '0'
|
||||
match['value'] = int(whole_part) + float(decimal_part)
|
||||
|
||||
def get_basecode(barcode,pattern,encoding):
|
||||
base = ''
|
||||
numerical_content = False
|
||||
j = 0
|
||||
for i in range(len(pattern)):
|
||||
p = pattern[i]
|
||||
if p == '{' or p == '}':
|
||||
numerical_content = not numerical_content
|
||||
continue
|
||||
match['base_code'] = barcode[:num_start] + (num_end-num_start-2)*"0" + barcode[num_end-2:]
|
||||
match['base_code'] = match['base_code'].replace("\\\\", "\\").replace("\{", "{").replace("\}","}").replace("\.",".")
|
||||
pattern = pattern[:num_start] + (num_end-num_start-2)*"0" + pattern[num_end:]
|
||||
|
||||
if numerical_content:
|
||||
base += '0'
|
||||
else:
|
||||
base += barcode[j]
|
||||
j+=1
|
||||
match['match'] = re.match(pattern, match['base_code'][:len(pattern)])
|
||||
|
||||
return match
|
||||
|
||||
for i in range(j, len(barcode)): # Read the rest of the barcode
|
||||
base += barcode[i]
|
||||
if encoding == "ean13":
|
||||
base = self.sanitize_ean(base)
|
||||
return base
|
||||
|
||||
rules = []
|
||||
for rule in self.rule_ids:
|
||||
@@ -166,16 +134,21 @@ class barcode_nomenclature(osv.osv):
|
||||
cur_barcode = barcode
|
||||
if prepend_zero and rule['encoding'] == "ean13":
|
||||
cur_barcode = '0'+cur_barcode
|
||||
if match_pattern(cur_barcode, rule['pattern']):
|
||||
|
||||
match = match_pattern(cur_barcode, rule['pattern'])
|
||||
if match['match']:
|
||||
if rule['type'] == 'alias':
|
||||
barcode = rule['alias']
|
||||
parsed_result['code'] = barcode
|
||||
else:
|
||||
parsed_result['encoding'] = rule['encoding']
|
||||
parsed_result['type'] = rule['type']
|
||||
parsed_result['value'] = get_value(cur_barcode, rule['pattern'])
|
||||
parsed_result['value'] = match['value']
|
||||
parsed_result['code'] = cur_barcode
|
||||
parsed_result['base_code'] = get_basecode(cur_barcode, rule['pattern'], parsed_result['encoding'])
|
||||
if rule['encoding'] == "ean13":
|
||||
parsed_result['base_code'] = self.sanitize_ean(match['base_code'])
|
||||
else:
|
||||
parsed_result['base_code'] = match['base_code']
|
||||
return parsed_result
|
||||
|
||||
return parsed_result
|
||||
@@ -193,7 +166,6 @@ class barcode_rule(models.Model):
|
||||
'barcode_nomenclature_id': fields.many2one('barcode.nomenclature','Barcode Nomenclature'),
|
||||
'sequence': fields.integer('Sequence', help='Used to order rules such that rules with a smaller sequence match first'),
|
||||
'encoding': fields.selection([('any','Any'),('ean13','EAN-13')],'Encoding',required=True,help='This rule will apply only if the barcode is encoded with the specified encoding'),
|
||||
#'type': fields.selection([('alias','Alias'),('product','Unit Product')],'Type', required=True),
|
||||
'type': fields.selection('_get_type_selection','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',required=True),
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<field name="sequence">90</field>
|
||||
<field name="type">product</field>
|
||||
<field name="encoding">ean13</field>
|
||||
<field name="pattern">*</field>
|
||||
<field name="pattern">.</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -162,81 +162,41 @@ openerp.barcodes = function(instance) {
|
||||
return parsed_result;
|
||||
}
|
||||
|
||||
function match_pattern(barcode,pattern){
|
||||
if(barcode.length < pattern.replace(/[{}]/g, '').length){
|
||||
return false; // Match of this pattern is impossible
|
||||
}
|
||||
var numerical_content = false; // Used to detect when we are between { }
|
||||
for(var i = 0, j = 0; i < pattern.length; i++, j++){
|
||||
var p = pattern[i];
|
||||
if(p === "{" || p === "}"){
|
||||
numerical_content = !numerical_content;
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!numerical_content && p !== '*' && p !== barcode[j]){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function get_value(barcode,pattern){
|
||||
var value = 0;
|
||||
var decimals = 0;
|
||||
var numerical_content = false;
|
||||
for(var i = 0, j = 0; i < pattern.length; i++, j++){
|
||||
var p = pattern[i];
|
||||
if(!numerical_content && p !== "{"){
|
||||
continue;
|
||||
}
|
||||
else if(p === "{"){
|
||||
numerical_content = true;
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
else if(p === "}"){
|
||||
break;
|
||||
}
|
||||
function match_pattern(barcode, pattern){
|
||||
var match = {
|
||||
value: 0,
|
||||
base_code: barcode,
|
||||
match: false,
|
||||
};
|
||||
barcode = barcode.replace("\\", "\\\\").replace("{", '\{').replace("}", "\}").replace(".", "\.");
|
||||
|
||||
var v = parseInt(barcode[j]);
|
||||
if(p === 'N'){
|
||||
value *= 10;
|
||||
value += v;
|
||||
}else if(p === 'D'){ // FIXME precision ....
|
||||
decimals += 1;
|
||||
value += v * Math.pow(10,-decimals);
|
||||
var numerical_content = pattern.match(/[{][N]*[D]*[}]/);
|
||||
var base_pattern = pattern;
|
||||
if(numerical_content){
|
||||
var num_start = numerical_content.index;
|
||||
var num_length = numerical_content[0].length;
|
||||
var value_string = barcode.substr(num_start, num_length-2);
|
||||
var whole_part_match = numerical_content[0].match("[{][N]*[D}]");
|
||||
var decimal_part_match = numerical_content[0].match("[{N][D]*[}]");
|
||||
var whole_part = value_string.substr(0, whole_part_match.index+whole_part_match[0].length-2);
|
||||
var decimal_part = "0." + value_string.substr(decimal_part_match.index, decimal_part_match[0].length-1);
|
||||
if (whole_part === ''){
|
||||
whole_part = '0';
|
||||
}
|
||||
match['value'] = parseInt(whole_part) + parseFloat(decimal_part);
|
||||
match['base_code'] = barcode.substr(0,num_start);
|
||||
var base_pattern = pattern.substr(0,num_start);
|
||||
for(var i=0;i<(num_length-2);i++) {
|
||||
match['base_code'] += "0";
|
||||
base_pattern += "0";
|
||||
}
|
||||
match['base_code'] += barcode.substr(num_start+num_length-2,barcode.length-1);
|
||||
base_pattern += pattern.substr(num_start+num_length,pattern.length-1);
|
||||
match['base_code'] = match['base_code'].replace("\\\\", "\\").replace("\{", "{").replace("\}","}").replace("\.",".");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function get_basecode(barcode,pattern,encoding){
|
||||
var base = '';
|
||||
var numerical_content = false;
|
||||
for(var i = 0, j = 0; i < pattern.length; i++, j++){
|
||||
var p = pattern[i];
|
||||
if(p === "{" || p === "}"){
|
||||
numerical_content = !numerical_content;
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(numerical_content){
|
||||
base += '0';
|
||||
}
|
||||
else{
|
||||
base += barcode[j];
|
||||
}
|
||||
}
|
||||
for(i=j; i<barcode.length; i++){ // Read the rest of the barcode
|
||||
base += barcode[i];
|
||||
}
|
||||
if(encoding === "ean13"){
|
||||
base = self.sanitize_ean(base);
|
||||
}
|
||||
return base;
|
||||
match['match'] = match['base_code'].substr(0,base_pattern.length).match(base_pattern);
|
||||
return match;
|
||||
}
|
||||
|
||||
// If the nomenclature does not use strict EAN, prepend the barcode with a 0 if it seems
|
||||
@@ -251,7 +211,8 @@ openerp.barcodes = function(instance) {
|
||||
if (prepend_zero && rules[i].encoding == 'ean13'){
|
||||
cur_barcode = '0'+cur_barcode;
|
||||
}
|
||||
if (match_pattern(cur_barcode,rules[i].pattern)) {
|
||||
var match = match_pattern(cur_barcode,rules[i].pattern);
|
||||
if (match.match) {
|
||||
if(rules[i].type === 'alias') {
|
||||
barcode = rules[i].alias;
|
||||
parsed_result.code = barcode;
|
||||
@@ -260,9 +221,14 @@ openerp.barcodes = function(instance) {
|
||||
else {
|
||||
parsed_result.encoding = rules[i].encoding;
|
||||
parsed_result.type = rules[i].type;
|
||||
parsed_result.value = get_value(cur_barcode,rules[i].pattern);
|
||||
parsed_result.value = match.value
|
||||
parsed_result.code = cur_barcode;
|
||||
parsed_result.base_code = get_basecode(cur_barcode,rules[i].pattern,parsed_result.encoding);
|
||||
if (rules[i].encoding === "ean13"){
|
||||
parsed_result.base_code = this.sanitize_ean(match.base_code);
|
||||
}
|
||||
else{
|
||||
parsed_result.base_code = match.base_code;
|
||||
}
|
||||
return parsed_result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<field name="sequence">36</field>
|
||||
<field name="type">weight</field>
|
||||
<field name="encoding">ean13</field>
|
||||
<field name="pattern">21*****{NNDDD}*</field>
|
||||
<field name="pattern">21.....{NNDDD}.</field>
|
||||
</record>
|
||||
|
||||
<record id="barcode_rule_discount" model="barcode.rule">
|
||||
@@ -34,7 +34,7 @@
|
||||
<field name="sequence">20</field>
|
||||
<field name="type">discount</field>
|
||||
<field name="encoding">any</field>
|
||||
<field name="pattern">22{NN}*</field>
|
||||
<field name="pattern">22{NN}.</field>
|
||||
</record>
|
||||
|
||||
<record id="barcode_rule_price_two_dec" model="barcode.rule">
|
||||
@@ -43,7 +43,7 @@
|
||||
<field name="sequence">14</field>
|
||||
<field name="type">price</field>
|
||||
<field name="encoding">ean13</field>
|
||||
<field name="pattern">23*****{NNNDD}*</field>
|
||||
<field name="pattern">23.....{NNNDD}.</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -515,7 +515,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
|
||||
this.action_callback['product'](parsed_result);
|
||||
}
|
||||
}
|
||||
else if (parsed_result.type in {'cashier':'', 'client':''}){
|
||||
else if (parsed_result.type in {'cashier':'', 'client':'', 'discount':''}){
|
||||
if(this.action_callback[parsed_result.type]){
|
||||
this.action_callback[parsed_result.type](parsed_result);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<field name="sequence">36</field>
|
||||
<field name="type">weight</field>
|
||||
<field name="encoding">ean13</field>
|
||||
<field name="pattern">21*****{NNDDD}*</field>
|
||||
<field name="pattern">21.....{NNDDD}.</field>
|
||||
</record>
|
||||
|
||||
<record id="barcode_rule_package" model="barcode.rule">
|
||||
@@ -16,7 +16,7 @@
|
||||
<field name="sequence">70</field>
|
||||
<field name="type">package</field>
|
||||
<field name="encoding">any</field>
|
||||
<field name="pattern">PACK*</field>
|
||||
<field name="pattern">PACK.</field>
|
||||
</record>
|
||||
|
||||
<record id="barcode_rule_lot" model="barcode.rule">
|
||||
@@ -25,7 +25,7 @@
|
||||
<field name="sequence">80</field>
|
||||
<field name="type">lot</field>
|
||||
<field name="encoding">any</field>
|
||||
<field name="pattern">10*</field>
|
||||
<field name="pattern">10.</field>
|
||||
</record>
|
||||
|
||||
<record id="barcode_rule_location" model="barcode.rule">
|
||||
@@ -34,7 +34,7 @@
|
||||
<field name="sequence">60</field>
|
||||
<field name="type">location</field>
|
||||
<field name="encoding">any</field>
|
||||
<field name="pattern">414*</field>
|
||||
<field name="pattern">414.</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
Reference in New Issue
Block a user