gs1 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,26 @@
1
+ module GS1
2
+ module Barcode
3
+ # Module for handling definitions.
4
+ #
5
+ module Definitions
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ # Adding defintion class methods.
11
+ #
12
+ module ClassMethods
13
+ attr_reader :records
14
+
15
+ def define_records(*records)
16
+ @records ||= []
17
+ @records = records
18
+
19
+ records.each do |record|
20
+ attr_reader record.underscore_name
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,53 @@
1
+ module GS1
2
+ module Barcode
3
+ # Barcode for boxes in healthcare business.
4
+ #
5
+ class Healthcare < Base
6
+ define_records GTIN, ExpirationDate, Batch, SerialNumber
7
+
8
+ def to_s(level: AIDCMarketingLevels::ENHANCED)
9
+ return unless valid?(level: level)
10
+
11
+ [gtin.to_ai,
12
+ expiration_date&.to_ai,
13
+ batch&.to_ai,
14
+ serial_number&.to_ai].compact.join
15
+ end
16
+
17
+ def valid?(level: AIDCMarketingLevels::ENHANCED)
18
+ return false unless AIDCMarketingLevels::ALL.include?(level)
19
+
20
+ validate(level)
21
+
22
+ errors.empty?
23
+ end
24
+
25
+ private
26
+
27
+ def validate(level)
28
+ errors.clear
29
+
30
+ validate_minimum
31
+ return if level == AIDCMarketingLevels::MINIMUM
32
+
33
+ validate_enhanced
34
+ return if level == AIDCMarketingLevels::ENHANCED
35
+
36
+ validate_highest
37
+ end
38
+
39
+ def validate_minimum
40
+ errors << 'Invalid gtin' unless gtin.valid?
41
+ end
42
+
43
+ def validate_enhanced
44
+ errors << 'Invalid batch' unless batch&.valid?
45
+ errors << 'Invalid expiration date' unless expiration_date&.valid?
46
+ end
47
+
48
+ def validate_highest
49
+ errors << 'Invalid serial number' unless serial_number&.valid?
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,4 @@
1
+ require 'gs1/barcode/definitions'
2
+
3
+ require 'gs1/barcode/base'
4
+ require 'gs1/barcode/healthcare'
data/lib/gs1/batch.rb ADDED
@@ -0,0 +1,33 @@
1
+ module GS1
2
+ # Batch or lot number: AI (10)
3
+ #
4
+ # The GS1 Application Identifier (10) indicates that the GS1 Application Identifier data field contains a
5
+ # batch or lot number. The batch or lot number associates an item with information the manufacturer
6
+ # considers relevant for traceability of the trade item to which the element string is applied. The data may
7
+ # refer to the trade item itself or to items contained. The number may be, for example, a production lot
8
+ # number, a shift number, a machine number, a time, or an internal production code. The data is
9
+ # alphanumeric and may include all characters contained in figure 7.11-1.
10
+ #
11
+ # Note: The batch or lot number is not part of the unique identification of a trade item.
12
+ #
13
+ # Figure 3.4.1-1. Format of the element string
14
+ # |----|------------------------------------------------------|
15
+ # | AI | Batch or lot number |
16
+ # |----|------------------------------------------------------|
17
+ # | 10 | X1 -------------> variable length -------------> X20 |
18
+ # |----|------------------------------------------------------|
19
+ #
20
+ # The data transmitted by the barcode reader means that the element string denoting a batch or lot
21
+ # number has been captured. As this element string is an attribute of a particular item, it must be
22
+ # processed together with the GTIN of the trade item to which it relates. When indicating this element
23
+ # string in the non-HRI text section of a barcode label, the following data title SHOULD be used (see
24
+ # also section 3.2): BATCH/LOT
25
+ #
26
+ # Source: https://www.gs1.org/sites/default/files/docs/barcodes/GS1_General_Specifications.pdf
27
+ #
28
+ class Batch < Record
29
+ AI = AI::BATCH_LOT
30
+
31
+ define :length, allowed: 1..20
32
+ end
33
+ end
@@ -0,0 +1,49 @@
1
+ module GS1
2
+ # GS1 check digit calculation
3
+ #
4
+ # Implementation of: http://www.gs1.org/how-calculate-check-digit-manually
5
+ # Notice! This class does not validate the format of the given sequence,
6
+ # only the length.
7
+ #
8
+ class CheckDigitCalculator
9
+ MULTIPLIER_ARRAY = [3, 1] * 9
10
+ VALID_LENGTHS = [7, 11, 12, 13, 17].freeze
11
+
12
+ def initialize(sequence)
13
+ @sequence = sequence
14
+ @reverse_sequence = sequence.chars.reverse
15
+
16
+ raise ArgumentError, 'Invalid length' unless VALID_LENGTHS.include?(sequence.size)
17
+ end
18
+
19
+ def self.from_sequence(sequence)
20
+ new(sequence).check_digit
21
+ end
22
+
23
+ def self.with_sequence(sequence)
24
+ new(sequence).calculate_sequence_with_digit
25
+ end
26
+
27
+ def check_digit
28
+ sub_from_nearest_higher_ten.to_s
29
+ end
30
+
31
+ def calculate_sequence_with_digit
32
+ sequence + check_digit
33
+ end
34
+
35
+ private
36
+
37
+ attr_reader :sequence, :reverse_sequence
38
+
39
+ def multiplied_sequence
40
+ @multiplied_sequence ||= reverse_sequence.each_with_index.map do |digit, idx|
41
+ digit.to_i * MULTIPLIER_ARRAY[idx]
42
+ end
43
+ end
44
+
45
+ def sub_from_nearest_higher_ten
46
+ (10 - (multiplied_sequence.inject(:+) % 10)) % 10
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,47 @@
1
+ module GS1
2
+ # Identification of trade items contained in a logistic unit: AI (02)
3
+ #
4
+ # The GS1 Application Identifier (02) indicates that the GS1 Application Identifier data field includes
5
+ # the GTIN of the contained trade items. The GTIN is used to identify trade items (see section 4).
6
+ #
7
+ # The GTIN for trade items may be a GTIN-8, GTIN-12, GTIN-13 or a GTIN-14. See section 2 for the
8
+ # rules for GTIN formats and mandatory or optional attributes in the various trade item applications.
9
+ #
10
+ # The GTIN of the trade items contained is the GTIN of the highest level of trade item contained in the
11
+ # logistic unit.
12
+ #
13
+ # Note: This element string SHALL be used only on a logistic unit if:
14
+ #
15
+ # - the logistic unit is not itself a trade item; and
16
+ # - all trade items that are contained at the highest level have the same GTIN
17
+ #
18
+ # The check digit is explained in section 7.9. Its verification, which must be carried out in the
19
+ # application software, ensures that the number is correctly composed.
20
+ #
21
+ # Figure 3.3.3-1. Format of the element string
22
+ # |----|-------------------------------------------------------------|
23
+ # | | Global Trade Item Number (GTIN) |
24
+ # | |-----------------------------------------------------|-------|
25
+ # | AI | GS1-8 Prefix or GS1 Company Prefix Item reference | Check |
26
+ # | | -----------------------------> <-----------------| digit |
27
+ # |----|-----------------------------------------------------|-------|
28
+ # GTIN-8 | 02 | 0 0 0 0 0 0 N1 N2 N3 N4 N5 N6 N7 | N8 |
29
+ # GTIN-12 | 02 | 0 0 N1 N2 N3 N4 N5 N6 N7 N8 N9 N10 N11 | N12 |
30
+ # GTIN-13 | 02 | 0 N1 N2 N3 N4 N5 N6 N7 N8 N9 N10 N11 N12 | N13 |
31
+ # GTIN-14 | 02 | N1 N2 N3 N4 N5 N6 N7 N8 N9 N10 N11 N12 N13 | N14 |
32
+ # |----|-----------------------------------------------------|-------|
33
+ #
34
+ # The data transmitted from the barcode reader means that the element string denoting the GTIN of
35
+ # trade items contained in a logistic unit has been captured. This element string must be processed
36
+ # together with the count of trade items, AI (37), which must appear on the same unit (see section
37
+ # 3.6.5). When indicating this element string in the non-HRI text section of a barcode label, the
38
+ # following data title SHOULD be used (see also section 3.2): CONTENT
39
+ #
40
+ # Source: https://www.gs1.org/sites/default/files/docs/barcodes/GS1_General_Specifications.pdf
41
+ #
42
+ class Content < Record
43
+ include Extensions::GTIN
44
+
45
+ AI = AI::CONTENT
46
+ end
47
+ end
@@ -0,0 +1,79 @@
1
+ module GS1
2
+ # Module for handling definitions.
3
+ #
4
+ module Definitions
5
+ class UnknownDefinition < StandardError; end
6
+
7
+ def self.included(base)
8
+ base.extend ClassMethods
9
+ end
10
+
11
+ # Adding defintion class methods.
12
+ #
13
+ module ClassMethods
14
+ attr_reader :definitions
15
+
16
+ DEFINITIONS = %i[check_digit date length].freeze
17
+
18
+ def define(key, options = {})
19
+ raise UnknownDefinition, "#{key} is not a valid definition" unless DEFINITIONS.include?(key)
20
+
21
+ @definitions ||= {}
22
+
23
+ definitions[key] = send("normalize_#{key}_options", options)
24
+ end
25
+
26
+ # Currently no support for options.
27
+ def normalize_check_digit_options(_options)
28
+ {}
29
+ end
30
+
31
+ # Currently no support for options.
32
+ def normalize_date_options(_options)
33
+ {}
34
+ end
35
+
36
+ # Defaults barcode length to allowed length if not explicitly defined, only
37
+ # if there is one significant allowed.
38
+ def normalize_length_options(options)
39
+ options[:allowed] = normalize_multiple_option(options[:allowed])
40
+ options[:barcode] = normalize_singlural_option(options[:barcode])
41
+ options[:max_barcode] = normalize_singlural_option(options[:barcode] || options[:allowed])
42
+
43
+ options
44
+ end
45
+
46
+ def normalize_multiple_option(option_value)
47
+ case option_value
48
+ when nil then nil
49
+ when Range then option_value.to_a
50
+ when Array then option_value
51
+ else [option_value]
52
+ end
53
+ end
54
+
55
+ def normalize_singlural_option(option_value)
56
+ case option_value
57
+ when Array then option_value.last
58
+ else option_value
59
+ end
60
+ end
61
+
62
+ def barcode_length
63
+ lengths[:barcode]
64
+ end
65
+
66
+ def barcode_max_length
67
+ lengths[:max_barcode]
68
+ end
69
+
70
+ def allowed_lengths
71
+ lengths[:allowed]
72
+ end
73
+
74
+ def lengths
75
+ definitions[:length]
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,55 @@
1
+ module GS1
2
+ # Expiration date: AI (17)
3
+ #
4
+ # The GS1 Application Identifier (17) indicates that the GS1 Application Identifier data fields contain
5
+ # an expiration date. The expiration date is the date that determines the limit of consumption or use
6
+ # of a product/coupon. Its meaning is determined based on the trade item context (e.g., for food, the
7
+ # date will indicate the possibility of a direct health risk resulting from use of the product after the
8
+ # date, for pharmaceutical products, it will indicate the possibility of an indirect health risk resulting
9
+ # from the ineffectiveness of the product after the date). It is often referred to as "use by date" or
10
+ # "maximum durability date."
11
+ #
12
+ # Note: A retailer may use this to determine a date that after which, they will no longer
13
+ # merchandise the product. Currently, there are implementations of best before date which are
14
+ # interpreted in their processes as date to Sell By.
15
+ #
16
+ # The structure is:
17
+ #
18
+ # - Year: the tens and units of the year (e.g., 2003 = 03), which is mandatory.
19
+ # - Month: the number of the month (e.g., January = 01), which is mandatory.
20
+ # - Day: the number of the day of the relevant month (e.g., second day = 02); if it is not necessary
21
+ # to specify the day, the field must be filled with two zeros.
22
+ #
23
+ # Note: When it is not necessary to specify the day (the Day field is filled with two zeros), the
24
+ # resultant data string SHALL be interpreted as the last day of the noted month including any
25
+ # adjustment for leap years (e.g., "130200" is "2013 February 28", "160200" is "2016 February
26
+ # 29", etc.).
27
+ #
28
+ # Note: This element string can only specify dates ranging from 49 years in the past to 50
29
+ # years in the future. Determination of the correct century is explained in section 7.12.
30
+ #
31
+ # Figure 3.4.5-1. Format of the element string
32
+ # |----|-----------------------------------|
33
+ # | | Best before date |
34
+ # | |-----------|-----------|-----------|
35
+ # | AI | Year | Month | Day |
36
+ # | | | | |
37
+ # |----|-----------|-----------|-----------|
38
+ # | 15 | N1 N2 | N3 N4 | N5 N6 |
39
+ # |----|-----------|-----------|-----------|
40
+ #
41
+ # The data transmitted from the barcode reader means that the element string denoting a best before
42
+ # date has been captured. As this element string is an attribute of a trade item, it must be processed
43
+ # together with the GTIN of the trade item to which it relates.
44
+ #
45
+ # When indicating this element string in the non-HRI text section of a barcode label, the following data
46
+ # title SHOULD be used (see also section 3.2): BEST BEFORE or BEST BY
47
+ #
48
+ # Source: https://www.gs1.org/sites/default/files/docs/barcodes/GS1_General_Specifications.pdf
49
+ #
50
+ class ExpirationDate < Record
51
+ include Extensions::Date
52
+
53
+ AI = AI::USE_BY
54
+ end
55
+ end
@@ -0,0 +1,26 @@
1
+ require 'date'
2
+
3
+ module GS1
4
+ module Extensions
5
+ # Extension for a GS1 date. Ensures correct formating and validation.
6
+ #
7
+ module Date
8
+ def self.included(base)
9
+ base.define :date
10
+ base.define :length, barcode: 6
11
+ end
12
+
13
+ def to_s
14
+ return data.strftime('%y%m%d') if data.is_a?(::Date)
15
+
16
+ data
17
+ end
18
+
19
+ def to_date
20
+ return data if data.is_a?(::Date)
21
+
22
+ ::Date.parse(data)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ module GS1
2
+ module Extensions
3
+ # Extension for a GS1 GTIN. Ensures correct formating and validation.
4
+ #
5
+ module GTIN
6
+ def self.included(base)
7
+ base.define :check_digit
8
+ base.define :length, allowed: [8, 12, 13, 14].freeze, barcode: 14
9
+
10
+ base.allowed_lengths.each do |length|
11
+ define_method "to_gtin_#{length}" do
12
+ data.to_s.rjust(length, '0')
13
+ end
14
+ end
15
+ end
16
+
17
+ # Default to GTIN-14 since it is the most common format.
18
+ def to_s
19
+ to_gtin_14
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,2 @@
1
+ require 'gs1/extensions/date'
2
+ require 'gs1/extensions/gtin'
data/lib/gs1/gtin.rb ADDED
@@ -0,0 +1,39 @@
1
+ module GS1
2
+ # Identification of a trade item (GTIN): AI (01)
3
+ #
4
+ # The GS1 Application Identifier (01) indicates that the GS1 Application Identifier data field contains a
5
+ # GTIN. The GTIN is used to identify trade items (see section 4).
6
+ #
7
+ # The GTIN for trade items may be a GTIN-8, GTIN-12, GTIN-13 or a GTIN-14. See section 2.1 for the
8
+ # rules for GTIN formats and mandatory or optional attributes in the various trade item applications.
9
+ #
10
+ # The check digit is explained in section 7.9. Its verification, which must be carried out in the
11
+ # application software, ensures that the number is correctly composed.
12
+ #
13
+ # Figure 3.3.2-1. Format of the element string
14
+ # |----|-------------------------------------------------------------|
15
+ # | | Global Trade Item Number (GTIN) |
16
+ # | |-----------------------------------------------------|-------|
17
+ # | AI | GS1-8 Prefix or GS1 Company Prefix Item reference | Check |
18
+ # | | -----------------------------> <-----------------| digit |
19
+ # |----|-----------------------------------------------------|-------|
20
+ # GTIN-8 | 02 | 0 0 0 0 0 0 N1 N2 N3 N4 N5 N6 N7 | N8 |
21
+ # GTIN-12 | 02 | 0 0 N1 N2 N3 N4 N5 N6 N7 N8 N9 N10 N11 | N12 |
22
+ # GTIN-13 | 02 | 0 N1 N2 N3 N4 N5 N6 N7 N8 N9 N10 N11 N12 | N13 |
23
+ # GTIN-14 | 02 | N1 N2 N3 N4 N5 N6 N7 N8 N9 N10 N11 N12 N13 | N14 |
24
+ # |----|-----------------------------------------------------|-------|
25
+ #
26
+ # The data transmitted from the barcode reader means that the element string denoting the GTIN of a
27
+ # fixed measure trade item has been captured.
28
+ #
29
+ # When indicating this element string in the non-HRI text section of a barcode label, the following data
30
+ # title SHOULD be used (see also section 3.2): GTIN
31
+ #
32
+ # Source: https://www.gs1.org/sites/default/files/docs/barcodes/GS1_General_Specifications.pdf
33
+ #
34
+ class GTIN < Record
35
+ include Extensions::GTIN
36
+
37
+ AI = AI::GTIN
38
+ end
39
+ end
data/lib/gs1/record.rb ADDED
@@ -0,0 +1,55 @@
1
+ module GS1
2
+ # Base class for a GS1 record.
3
+ #
4
+ class Record
5
+ include Definitions
6
+ include Validations
7
+
8
+ attr_reader :data
9
+
10
+ def initialize(data)
11
+ super
12
+ @data = data
13
+ end
14
+
15
+ singleton_class.send(:attr_reader, :descendants)
16
+ @descendants = []
17
+
18
+ class << self
19
+ def inherited(subclass)
20
+ descendants << subclass
21
+ end
22
+
23
+ def ai
24
+ self::AI
25
+ end
26
+
27
+ def underscore_name
28
+ name.split('::')
29
+ .last
30
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
31
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
32
+ .tr('-', '_')
33
+ .downcase
34
+ .to_sym
35
+ end
36
+ end
37
+
38
+ def ai
39
+ self.class.ai
40
+ end
41
+
42
+ def to_s
43
+ data&.to_s
44
+ end
45
+
46
+ def to_ai
47
+ "#{ai}#{data}"
48
+ end
49
+
50
+ def ==(other)
51
+ self.class == other.class &&
52
+ to_s == other.to_s
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,31 @@
1
+ module GS1
2
+ # Serial number: AI (21)
3
+ #
4
+ # The GS1 Application Identifier (21) indicates that the GS1 Application Identifier data field contains a
5
+ # serial number. A serial number is assigned to an entity for its lifetime. When combined with a GTIN,
6
+ # a serial number uniquely identifies an individual item. The serial number field is alphanumeric and
7
+ # may include all characters contained in figure 7.11-1. The manufacturer determines the serial
8
+ # number.
9
+ #
10
+ # Figure 3.5.2-1. Format of the element string
11
+ # |----|------------------------------------------------------|
12
+ # | AI | Serial number |
13
+ # |----|------------------------------------------------------|
14
+ # | 21 | X1 -------------> variable length -------------> X20 |
15
+ # |----|------------------------------------------------------|
16
+ #
17
+ # The data transmitted from the barcode reader means that the element string denoting a serial
18
+ # number has been captured. As this element string is an attribute of a trade item, it must be
19
+ # processed together with the GTIN of the trade item to which it relates.
20
+ #
21
+ # When indicating this element string in the non-HRI text section of a barcode label, the following data
22
+ # title SHOULD be used (see also section 3.2): SERIAL
23
+ #
24
+ # Source: https://www.gs1.org/sites/default/files/docs/barcodes/GS1_General_Specifications.pdf
25
+ #
26
+ class SerialNumber < Record
27
+ AI = AI::SERIAL
28
+
29
+ define :length, allowed: 1..20
30
+ end
31
+ end
data/lib/gs1/sscc.rb ADDED
@@ -0,0 +1,43 @@
1
+ module GS1
2
+ #
3
+ # Identification of a logistic unit (SSCC): AI (00)
4
+ #
5
+ # The GS1 Application Identifier (00) indicates that the GS1 Application Identifier data field contains an
6
+ # SSCC (Serial Shipping Container Code). The SSCC is used to identify logistic units (see section 2.2).
7
+ #
8
+ # The extension digit is used to increase the capacity of the serial reference within the SSCC. It is
9
+ # assigned by the company that constructs the SSCC. The extension digit ranges from 0-9.
10
+ #
11
+ # The GS1 Company Prefix is allocated by GS1 Member Organisations to the company that allocates
12
+ # the SSCC - here the physical builder or the brand owner of the logistic unit (see section 1.4.4). It
13
+ # makes the SSCC unique worldwide but does not identify the origin of the unit.
14
+ #
15
+ # The structure and content of the serial reference is at the discretion of owner of the GS1 Company
16
+ # Prefix to uniquely identify each logistic unit.
17
+ #
18
+ # The check digit is explained in section 7.9. Its verification, which must be carried out in the
19
+ # application software, ensures that the number is correctly composed.
20
+ #
21
+ # Figure 3.3.1-1. Format of the element string
22
+ # |----|-----------------------------------------------------------------------------|
23
+ # | | SSCC (Serial Shipping Container Code) |
24
+ # | |-----------|---------------------------------------------------------|-------|
25
+ # | AI | Extension | GS1 Company Prefix Serial reference | Check |
26
+ # | | digit | --------------> <-----------------------| digit |
27
+ # |----|-----------|---------------------------------------------------------|-------|
28
+ # | 00 | N1 | N2 N3 N4 N5 N6 N7 N8 N9 N10 N11 N12 N13 N14 N15 N16 N17 | N18 |
29
+ # |----|-----------|---------------------------------------------------------|-------|
30
+ #
31
+ # The data transmitted from the barcode reader means that the element string denoting the SSCC of
32
+ # a logistic unit has been captured. When indicating this element string in the non-HRI text section of
33
+ # a barcode label, the following data title SHOULD be used (see also section 3.2): SSCC
34
+ #
35
+ # Source: https://www.gs1.org/sites/default/files/docs/barcodes/GS1_General_Specifications.pdf
36
+ #
37
+ class SSCC < Record
38
+ AI = AI::SSCC
39
+
40
+ define :check_digit
41
+ define :length, allowed: 18
42
+ end
43
+ end
@@ -0,0 +1,17 @@
1
+ module GS1
2
+ module Validations
3
+ # Ensures correct check digit validation.
4
+ #
5
+ module CheckDigitValidation
6
+ def validate_check_digit
7
+ errors << 'Check digit mismatch' unless valid_check_digit?
8
+ end
9
+
10
+ def valid_check_digit?
11
+ GS1::CheckDigitCalculator.with_sequence(data[0..-2]) == data
12
+ rescue ArgumentError
13
+ false
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ require 'date'
2
+
3
+ module GS1
4
+ module Validations
5
+ # Ensures correct date validation.
6
+ #
7
+ module DateValidation
8
+ def validate_date(_options = {})
9
+ errors << 'Invalid date' unless valid_date?
10
+ end
11
+
12
+ def valid_date?
13
+ return true if data.is_a?(::Date)
14
+
15
+ ::Date.parse(data)
16
+
17
+ true
18
+ rescue TypeError, ArgumentError
19
+ false
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ module GS1
2
+ module Validations
3
+ # Ensures correct length validation.
4
+ #
5
+ module LengthValidation
6
+ def validate_length
7
+ errors << 'Invalid length' unless valid_length?
8
+ end
9
+
10
+ def valid_length?
11
+ return false unless data
12
+
13
+ valid_barcode_length? || valid_allowed_length?
14
+ end
15
+
16
+ def valid_allowed_length?
17
+ self.class.allowed_lengths.include?(data.size)
18
+ end
19
+
20
+ def valid_barcode_length?
21
+ self.class.barcode_length == data.size if self.class.barcode_length
22
+ end
23
+ end
24
+ end
25
+ end