Subversion Repositories munaweb

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
53 - 1
/*!
2
 * Barcoder
3
 * Copyright (c) 2013 mifitto GmbH <dominik@mifitto.com>
4
 * MIT Licensed
5
 */
6
 
7
(function() {
8
 
9
  'use strict';
10
 
11
  /**
12
   * Library version.
13
   */
14
 
15
  var version = '1.1.0';
16
 
17
  /**
18
   * Supported formats
19
   */
20
 
21
  var minValidLength = 6;
22
  var maxValidLength = 18;
23
  var usualValidChars = /^\d+$/;
24
 
25
  var formats = {
26
    'ean8'   : { validChars : /^\d+$/, validLength : 8 },
27
    'ean12'  : { validChars : /^\d+$/, validLength : 12 },
28
    'ean13'  : { validChars : /^\d+$/, validLength : 13 },
29
    'ean14'  : { validChars : /^\d+$/, validLength : 14 },
30
    'ean18'  : { validChars : /^\d+$/, validLength : 18 },
31
    'gtin12' : { validChars : /^\d+$/, validLength : 12 },
32
    'gtin13' : { validChars : /^\d+$/, validLength : 13 },
33
    'gtin14' : { validChars : /^\d+$/, validLength : 14 }
34
  };
35
 
36
  /**
37
   * Validates the checksum (Modulo 10)
38
   * GTIN implementation factor 3
39
   *
40
   * @param  {String} value The barcode to validate
41
   * @return {Boolean}
42
   * @api private
43
   */
44
 
45
  var validateGtin = function( value ) {
46
 
47
    var barcode = value.substring( 0, value.length - 1 );
48
    var checksum = parseInt( value.substring( value.length - 1 ), 10 );
49
    var calcSum = 0;
50
    var calcChecksum = 0;
51
 
52
    barcode.split('').map(function( number, index ) {
53
      number = parseInt( number, 10 );
54
      if ( value.length % 2 === 0 ) {
55
        index += 1;
56
      }
57
      if ( index % 2 === 0 ) {
58
        calcSum += number;
59
      }
60
      else {
61
        calcSum += number * 3;
62
      }
63
    });
64
 
65
    calcSum %= 10;
66
    calcChecksum = (calcSum === 0) ? 0 : (10 - calcSum);
67
 
68
    if ( calcChecksum !== checksum ) {
69
      return false;
70
    }
71
 
72
    return true;
73
 
74
  };
75
 
76
  /**
77
   * Barcoder class
78
   *
79
   * @param {string}  format    See formats
80
   * @param {Object}  options   Valid option `enableZeroPadding`, defaults to `true`
81
   * @api public
82
   */
83
 
84
  var Barcoder = function ( format, options ) {
85
 
86
    if ( format && !formats[format] ) throw new Error( '"format" invalid' );
87
 
88
    this.format = (format) ? formats[format] : 'autoSelect';
89
    this.options = (options) ? options : { enableZeroPadding : true };
90
 
91
    if ( !this.options.enableZeroPadding ) {
92
      this.options.enableZeroPadding = true;
93
    }
94
 
95
  };
96
 
97
  /**
98
   * Validates a barcode
99
   *
100
   * @param  {string}  barcode   EAN/GTIN barcode
101
   * @return {Boolean}
102
   * @api public
103
   */
104
 
105
  Barcoder.prototype.validate = function( barcode ) {
106
 
107
    var self = this;
108
 
109
    if ( self.format === 'autoSelect' ) {
110
 
111
      if ( barcode.length < minValidLength || barcode.length > maxValidLength ) {
112
        return false;
113
      }
114
 
115
      var isValidGtin = validateGtin( barcode );
116
      var paddedBarcode = barcode;
117
      var successfullyPadded = false;
118
 
119
      if ( !isValidGtin ) {
120
        var possiblyMissingZeros = maxValidLength - barcode.length;
121
        while( possiblyMissingZeros-- ) {
122
          paddedBarcode = '0' + paddedBarcode;
123
          if ( validateGtin( paddedBarcode ) ) {
124
            isValidGtin = true;
125
            successfullyPadded = true;
126
            break;
127
          }
128
        }
129
      }
130
 
131
      return {
132
        possibleType: (barcode.length > 8) ? 'GTIN' + barcode.length : 'EAN8 / padded GTIN',
133
        isValid: isValidGtin
134
      };
135
 
136
    }
137
 
138
    var validChars = self.format.validChars;
139
    var validLength = self.format.validLength;
140
    var enableZeroPadding = self.options.enableZeroPadding;
141
 
142
    if ( validChars.exec( barcode ) === null ) {
143
      return false;
144
    }
145
 
146
    if ( enableZeroPadding && barcode.length < validLength ) {
147
      var missingZeros = validLength - barcode.length;
148
      while( missingZeros-- ) {
149
        barcode = '0' + barcode;
150
      }
151
    }
152
    else if ( !enableZeroPadding && barcode.length != validLength ) {
153
      return false;
154
    }
155
    else if ( barcode.length > validLength ) {
156
      return false;
157
    }
158
 
159
    return validateGtin( barcode );
160
 
161
  };
162
 
163
  /**
164
   * Export
165
   */
166
 
167
  if ( 'undefined' !== typeof module && module.exports ) {
168
    module.exports = Barcoder;
169
    exports.version = version;
170
  }
171
 
172
  if ( 'undefined' === typeof ender ) {
173
    this['Barcoder'] = Barcoder;
174
  }
175
 
176
  if ( 'function' === typeof define && define.amd ) {
177
    define('Barcoder', [], function () {
178
      return Barcoder;
179
    });
180
  }
181
 
182
}).call( this );