gs1 0.1.6 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2f15d386486f27cc92e1ba01d9c3d03f0633c7ac
4
- data.tar.gz: e4f0b5717132652127aafeeccdda4253d68a8201
2
+ SHA256:
3
+ metadata.gz: 16ce4a66d335b1d7fa0ac83b3fdc3064390b0a3ffe74d09734b9876cdd305449
4
+ data.tar.gz: ab4df39306570b00b5a0da26030f7c8011358f359e86c51920290e1d645685b6
5
5
  SHA512:
6
- metadata.gz: 3d3f0d9472329eafe49f3bdbf6326672c442d74b8132f07d3a21d0083d7d617fd1309af82d24ba78bd3585d61b7f6daf5ecec8fcad5f72595a29d2024afdea16
7
- data.tar.gz: 03d8e6d2faf2249b3077c38d67d90535f6a82d6d2fb1aec42c71e90cf9054497ab122a89014478840420c23f0c969ea1fa2c9316ebd933e623c5d395c5521c64
6
+ metadata.gz: 7615850e8245725560bf4af80f68d107292a83c24e9c6b0e3c6a0f7042e2c632c23664cc37f947ed46332aada6dc3ef496319c5017bd07d5a7bc05cbca87002c
7
+ data.tar.gz: 0c7196620e4531ee06a32944a9cf52a9b2fa84f1012ca27210ba9084e7ed01f8edbeca4facd1aea3e487cfa368b8b2fb2434d3fecded4cc10f7013a7b9960d61
data/.gitignore CHANGED
@@ -1,7 +1,7 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
3
  /_yardoc/
4
- /coverage/
4
+ /coverage
5
5
  /doc/
6
6
  /pkg/
7
7
  /spec/reports/
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ gs1
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.3.0
1
+ 2.7.0
data/.travis.yml CHANGED
@@ -1,8 +1,18 @@
1
1
  ---
2
+ env:
3
+ global:
4
+ secure: lQbZqhDx1dIuRA26K9vxaHWCwquTuJe4fuG9NEnJK1XnHWZge12NmFbGKrYrGEXsvzVRG6u4L6+MLudGT6nr1NOfOWHpA3FD73RcbBpuSrjrLGrnk1Z2OgBWQDbAMD8OszH3ciRQuqO780JZcTD3L6RULPJ6xHPcXI3UpCcQC78ZjuBjNGVPg6qBKmB6HeErj/THWiz4R4ouSo6/p4MsVS3ELqlukw1m6bx0wyyxI6sF33i5zC6V0dn7TUNrRDljNjO/bHfhYwRfabrTl0q4MzGC4rqS+CC8JXRMlCl7AHTKFeiRvSeI+Co8zidfGBCsocFAT4jshXC+NTddhtTnVbQ3GmSt6BGdfnprwbg8/GfsFE14L7IBlUDH1hzpuJYTsCQzR6+8UE8LA76z48Ttuv4of5TLAhDCCtKhRleVi9lbVuTT2xqlCTMwMWY3iH535L0Ou584BEYG7eRcdZS3rA96JWAlmuhmSVd8YBnXwhJC74eS5dJsb0qYSvCsUzfBUn7RbeWpCelnNRV4eX8n8Gn46DFSB414tAjCUL7rvIeSnouuI15lYaaqeORdGbhECnNoryxOsfPqp/zhpiT6dQW4LnF4WgMErzbyyZcVydFAB454XtM40kTEqLJ0S6bPfoYycR1yD/v4YjoH1nHB89om/zFVpB0VJ9BltMbAZJ8=
2
5
  sudo: false
3
6
  language: ruby
4
7
  cache: bundler
5
8
  rvm:
6
- - 2.3.0
7
- - 2.5.1
8
- before_install: gem install bundler -v 1.16.5
9
+ - 2.5.1
10
+ - 2.7.0
11
+ before_script:
12
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
13
+ - chmod +x ./cc-test-reporter
14
+ - ./cc-test-reporter before-build
15
+ script:
16
+ - bundle exec rake
17
+ after_script:
18
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ ### 1.1.0 - 2021-08-23
2
+
3
+ * enhancements
4
+ * Adds support to calculating checksum for GSIN
5
+
6
+ ### 1.0.0 - 2019-08-30
7
+
8
+ * breaking
9
+ * Returns `nil` unless no attribute for barcode segment
10
+
11
+ * enhancements
12
+ * Add errors to a barcode
13
+
14
+ * bug fixes
15
+ * Fix `nil` argument for barcode
data/gs1.gemspec CHANGED
@@ -32,9 +32,9 @@ Gem::Specification.new do |spec|
32
32
  spec.require_paths = ['lib']
33
33
  spec.required_ruby_version = '>= 2.3.0'
34
34
 
35
- spec.add_development_dependency 'bundler', '~> 1.16'
35
+ spec.add_development_dependency 'bundler'
36
36
  spec.add_development_dependency 'byebug', '~> 10.0'
37
- spec.add_development_dependency 'rake', '~> 10.0'
37
+ spec.add_development_dependency 'rake', '>= 10.0'
38
38
  spec.add_development_dependency 'rb-readline', '~> 0.1'
39
39
  spec.add_development_dependency 'rspec', '~> 3.0'
40
40
  spec.add_development_dependency 'rubocop', '~> 0.49.0'
@@ -6,15 +6,18 @@ module GS1
6
6
  include Definitions
7
7
 
8
8
  def initialize(options = {})
9
- self.class.records.each do |record|
10
- data = options.fetch(record.underscore_name, nil)
11
-
12
- instance_variable_set("@#{record.underscore_name}", record.new(data))
9
+ options.each do |(attribute_name, data)|
10
+ validate_attribute_data(attribute_name)
11
+ validate_attribute_record(attribute_name) do |record|
12
+ instance_variable_set("@#{attribute_name}", record.new(data))
13
+ end
13
14
  end
15
+
16
+ @params_order = options.to_h.keys
14
17
  end
15
18
 
16
19
  def errors
17
- @errors ||= []
20
+ @errors ||= Errors.new
18
21
  end
19
22
 
20
23
  class << self
@@ -5,6 +5,7 @@ module GS1
5
5
  module Definitions
6
6
  def self.included(base)
7
7
  base.extend ClassMethods
8
+ base.send :include, InstanceMethods
8
9
  end
9
10
 
10
11
  # Adding defintion class methods.
@@ -21,6 +22,27 @@ module GS1
21
22
  end
22
23
  end
23
24
  end
25
+
26
+ # Adding defintion instance methods.
27
+ #
28
+ module InstanceMethods
29
+ def validate_attribute_data(attribute_name)
30
+ return unless instance_variable_get("@#{attribute_name}")
31
+
32
+ errors[attribute_name] << Error.new(:already_defined, persistent: true)
33
+ end
34
+
35
+ def validate_attribute_record(attribute_name)
36
+ self.class.records.find { |r| r.underscore_name == attribute_name }.tap do |record|
37
+ if record
38
+ yield record
39
+ next
40
+ end
41
+
42
+ errors[attribute_name] << Error.new(:unknown_attribute, persistent: true)
43
+ end
44
+ end
45
+ end
24
46
  end
25
47
  end
26
48
  end
@@ -0,0 +1,30 @@
1
+ module GS1
2
+ module Barcode
3
+ # Error wrapper class for a barcode.
4
+ #
5
+ class Error
6
+ attr_reader :message
7
+
8
+ def initialize(message, persistent: false)
9
+ @message = message
10
+ @persistent = persistent
11
+ end
12
+
13
+ def persistent?
14
+ @persistent
15
+ end
16
+
17
+ def human_message
18
+ message.to_s.tr('_', ' ').capitalize
19
+ end
20
+
21
+ def hash
22
+ message.hash
23
+ end
24
+
25
+ def eql?(other)
26
+ @message == other.message
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,41 @@
1
+ module GS1
2
+ module Barcode
3
+ # Error collection handler wrapper class for a barcode.
4
+ #
5
+ class Errors
6
+ attr_reader :errors
7
+
8
+ def initialize
9
+ @errors = {}
10
+ end
11
+
12
+ def [](attribute_name)
13
+ errors[attribute_name] ||= []
14
+ end
15
+
16
+ def clear
17
+ errors.each_value do |errs|
18
+ errs.select!(&:persistent?)
19
+ end
20
+ end
21
+
22
+ def empty?
23
+ errors.values.flatten.empty?
24
+ end
25
+
26
+ def messages
27
+ errors.each_with_object({}) do |(attribute_name, errors), hash|
28
+ hash[attribute_name] = errors.uniq.map(&:human_message)
29
+ end
30
+ end
31
+
32
+ def full_messages
33
+ errors.flat_map do |(attribute_name, errors)|
34
+ errors.uniq.map do |error|
35
+ "#{error.human_message} #{attribute_name.to_s.tr('_', ' ')}"
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -8,13 +8,14 @@ module GS1
8
8
  def to_s(level: AIDCMarketingLevels::ENHANCED, separator: GS1.configuration.barcode_separator)
9
9
  return unless valid?(level: level)
10
10
 
11
- [
12
- gtin.to_ai,
13
- expiration_date&.to_ai,
14
- batch&.to_ai,
15
- separator,
16
- serial_number&.to_ai
17
- ].compact.join
11
+ @params_order.each_with_object('') do |param, out|
12
+ record = send(param)
13
+
14
+ next unless record.to_ai
15
+
16
+ out << record.to_ai
17
+ out << separator if record.class.separator? && param != @params_order.last
18
+ end
18
19
  end
19
20
 
20
21
  def valid?(level: AIDCMarketingLevels::ENHANCED)
@@ -40,16 +41,26 @@ module GS1
40
41
  end
41
42
 
42
43
  def validate_minimum
43
- errors << 'Invalid gtin' unless gtin.valid?
44
+ validate_attribute(:gtin)
44
45
  end
45
46
 
46
47
  def validate_enhanced
47
- errors << 'Invalid batch' unless batch&.valid?
48
- errors << 'Invalid expiration date' unless expiration_date&.valid?
48
+ validate_attribute(:batch)
49
+ validate_attribute(:expiration_date)
49
50
  end
50
51
 
51
52
  def validate_highest
52
- errors << 'Invalid serial number' unless serial_number&.valid?
53
+ validate_attribute(:serial_number)
54
+ end
55
+
56
+ def validate_attribute(attribute_name)
57
+ attribute = public_send(attribute_name)
58
+
59
+ if attribute.nil?
60
+ errors[attribute_name] << Error.new(:blank)
61
+ elsif !attribute.valid?
62
+ errors[attribute_name] << Error.new(:invalid)
63
+ end
53
64
  end
54
65
  end
55
66
  end
@@ -6,14 +6,14 @@ module GS1
6
6
  attr_reader :data, :separator
7
7
 
8
8
  def initialize(data, separator: GS1.configuration.barcode_separator)
9
- @data = data.chars
9
+ @data = data.to_s.chars
10
10
  @separator = separator
11
11
  end
12
12
 
13
13
  def to_params
14
- return {} unless record
14
+ return [] unless record
15
15
 
16
- { record.underscore_name => record_data }
16
+ [record.underscore_name, record_data]
17
17
  end
18
18
 
19
19
  # Fetch the two first characters (interpreted as AI) from the remaining
@@ -99,7 +99,7 @@ module GS1
99
99
  def shift_separator_length
100
100
  separator_index = data.find_index(separator)
101
101
 
102
- return unless separator_index && separator_index < record.barcode_max_length
102
+ return unless separator_index && separator_index <= record.barcode_max_length
103
103
 
104
104
  shift_fixed_length(separator_index).tap do
105
105
  data.shift # Shift separator character
@@ -9,7 +9,7 @@ module GS1
9
9
  def initialize(data, separator: GS1.configuration.barcode_separator)
10
10
  @data = data
11
11
  @separator = separator
12
- @params = {}
12
+ @params = []
13
13
  end
14
14
 
15
15
  def to_params
@@ -26,7 +26,8 @@ module GS1
26
26
  segment_from_input(input, bang) do |segment|
27
27
  next if segment.to_params.empty?
28
28
 
29
- params.merge!(segment.to_params)
29
+ params << segment.to_params
30
+
30
31
  next if segment.rest.empty?
31
32
 
32
33
  segment_to_params(segment.rest, bang)
data/lib/gs1/barcode.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require 'gs1/barcode/definitions'
2
+ require 'gs1/barcode/error'
3
+ require 'gs1/barcode/errors'
2
4
 
3
5
  require 'gs1/barcode/base'
4
6
  require 'gs1/barcode/healthcare'
data/lib/gs1/batch.rb CHANGED
@@ -29,5 +29,6 @@ module GS1
29
29
  AI = AI::BATCH_LOT
30
30
 
31
31
  define :length, allowed: 1..20
32
+ define :separator
32
33
  end
33
34
  end
@@ -7,7 +7,7 @@ module GS1
7
7
  #
8
8
  class CheckDigitCalculator
9
9
  MULTIPLIER_ARRAY = [3, 1] * 9
10
- VALID_LENGTHS = [7, 11, 12, 13, 17].freeze
10
+ VALID_LENGTHS = [7, 11, 12, 13, 16, 17].freeze
11
11
 
12
12
  def initialize(sequence)
13
13
  @sequence = sequence
@@ -15,7 +15,7 @@ module GS1
15
15
  module ClassMethods
16
16
  attr_reader :definitions
17
17
 
18
- DEFINITIONS = %i[check_digit date date_month_based length].freeze
18
+ DEFINITIONS = %i[check_digit date date_month_based length separator].freeze
19
19
 
20
20
  def define(key, options = {})
21
21
  raise UnknownDefinition, "#{key} is not a valid definition" unless DEFINITIONS.include?(key)
@@ -40,6 +40,11 @@ module GS1
40
40
  {}
41
41
  end
42
42
 
43
+ # Boolean value
44
+ def normalize_separator_options(_options)
45
+ true
46
+ end
47
+
43
48
  # Defaults barcode length to allowed length if not explicitly defined, only
44
49
  # if there is one significant allowed.
45
50
  def normalize_length_options(options)
@@ -67,6 +72,10 @@ module GS1
67
72
  option_value
68
73
  end
69
74
 
75
+ def separator?
76
+ definitions[:separator]
77
+ end
78
+
70
79
  def barcode_length
71
80
  lengths[:barcode]
72
81
  end
@@ -27,5 +27,6 @@ module GS1
27
27
  AI = AI::SERIAL
28
28
 
29
29
  define :length, allowed: 1..20
30
+ define :separator
30
31
  end
31
32
  end
@@ -39,6 +39,8 @@ module GS1
39
39
 
40
40
  def validate
41
41
  self.class.definitions.each_key do |definition|
42
+ next if definition == :separator
43
+
42
44
  public_send("validate_#{definition}")
43
45
  end
44
46
  end
data/lib/gs1/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module GS1
2
- VERSION = '0.1.6'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gs1
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Åhman
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-12-02 00:00:00.000000000 Z
11
+ date: 2021-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.16'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.16'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: byebug
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -42,14 +42,14 @@ dependencies:
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '10.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '10.0'
55
55
  - !ruby/object:Gem::Dependency
@@ -118,8 +118,10 @@ files:
118
118
  - ".gitignore"
119
119
  - ".rspec"
120
120
  - ".rubocop.yml"
121
+ - ".ruby-gemset"
121
122
  - ".ruby-version"
122
123
  - ".travis.yml"
124
+ - CHANGELOG.md
123
125
  - CODE_OF_CONDUCT.md
124
126
  - Gemfile
125
127
  - LICENSE.txt
@@ -133,6 +135,8 @@ files:
133
135
  - lib/gs1/barcode.rb
134
136
  - lib/gs1/barcode/base.rb
135
137
  - lib/gs1/barcode/definitions.rb
138
+ - lib/gs1/barcode/error.rb
139
+ - lib/gs1/barcode/errors.rb
136
140
  - lib/gs1/barcode/healthcare.rb
137
141
  - lib/gs1/barcode/segment.rb
138
142
  - lib/gs1/barcode/tokenizer.rb
@@ -159,7 +163,7 @@ licenses:
159
163
  - MIT
160
164
  metadata:
161
165
  allowed_push_host: https://rubygems.org
162
- post_install_message:
166
+ post_install_message:
163
167
  rdoc_options: []
164
168
  require_paths:
165
169
  - lib
@@ -174,9 +178,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
174
178
  - !ruby/object:Gem::Version
175
179
  version: '0'
176
180
  requirements: []
177
- rubyforge_project:
178
- rubygems_version: 2.5.1
179
- signing_key:
181
+ rubygems_version: 3.1.2
182
+ signing_key:
180
183
  specification_version: 4
181
184
  summary: A ruby gem for implementing GS1 standards
182
185
  test_files: []