gs1 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +11 -0
- data/lib/gs1/barcode/base.rb +4 -4
- data/lib/gs1/barcode/healthcare.rb +1 -1
- data/lib/gs1/barcode/segment.rb +1 -1
- data/lib/gs1/barcode/tokenizer.rb +1 -1
- data/lib/gs1/definitions.rb +6 -1
- data/lib/gs1/expiration_date.rb +1 -1
- data/lib/gs1/extensions/date_month_based.rb +60 -0
- data/lib/gs1/extensions.rb +1 -0
- data/lib/gs1/validations/date_validation.rb +29 -0
- data/lib/gs1/version.rb +1 -1
- data/lib/gs1.rb +13 -4
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f15d386486f27cc92e1ba01d9c3d03f0633c7ac
|
4
|
+
data.tar.gz: e4f0b5717132652127aafeeccdda4253d68a8201
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d3f0d9472329eafe49f3bdbf6326672c442d74b8132f07d3a21d0083d7d617fd1309af82d24ba78bd3585d61b7f6daf5ecec8fcad5f72595a29d2024afdea16
|
7
|
+
data.tar.gz: 03d8e6d2faf2249b3077c38d67d90535f6a82d6d2fb1aec42c71e90cf9054497ab122a89014478840420c23f0c969ea1fa2c9316ebd933e623c5d395c5521c64
|
data/README.md
CHANGED
@@ -22,6 +22,17 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
Follow the examples below to start using the gem.
|
24
24
|
|
25
|
+
### Configuration
|
26
|
+
|
27
|
+
There are some configuration you can do before start using this lib.
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
GS1.configure do |config|
|
31
|
+
config.company_prefix = '123456789'
|
32
|
+
config.barcode_separator = '~' # Default is "\u001E"
|
33
|
+
end
|
34
|
+
```
|
35
|
+
|
25
36
|
### Application identifiers
|
26
37
|
|
27
38
|
To access the defined application identifier:
|
data/lib/gs1/barcode/base.rb
CHANGED
@@ -18,19 +18,19 @@ module GS1
|
|
18
18
|
end
|
19
19
|
|
20
20
|
class << self
|
21
|
-
def from_scan!(barcode, separator:
|
21
|
+
def from_scan!(barcode, separator: GS1.configuration.barcode_separator)
|
22
22
|
new(scan_to_params!(barcode, separator: separator))
|
23
23
|
end
|
24
24
|
|
25
|
-
def from_scan(barcode, separator:
|
25
|
+
def from_scan(barcode, separator: GS1.configuration.barcode_separator)
|
26
26
|
new(scan_to_params(barcode, separator: separator))
|
27
27
|
end
|
28
28
|
|
29
|
-
def scan_to_params!(barcode, separator:
|
29
|
+
def scan_to_params!(barcode, separator: GS1.configuration.barcode_separator)
|
30
30
|
Tokenizer.new(barcode, separator: separator).to_params!
|
31
31
|
end
|
32
32
|
|
33
|
-
def scan_to_params(barcode, separator:
|
33
|
+
def scan_to_params(barcode, separator: GS1.configuration.barcode_separator)
|
34
34
|
Tokenizer.new(barcode, separator: separator).to_params
|
35
35
|
end
|
36
36
|
end
|
@@ -5,7 +5,7 @@ module GS1
|
|
5
5
|
class Healthcare < Base
|
6
6
|
define_records GTIN, ExpirationDate, Batch, SerialNumber
|
7
7
|
|
8
|
-
def to_s(level: AIDCMarketingLevels::ENHANCED, separator:
|
8
|
+
def to_s(level: AIDCMarketingLevels::ENHANCED, separator: GS1.configuration.barcode_separator)
|
9
9
|
return unless valid?(level: level)
|
10
10
|
|
11
11
|
[
|
data/lib/gs1/barcode/segment.rb
CHANGED
data/lib/gs1/definitions.rb
CHANGED
@@ -15,7 +15,7 @@ module GS1
|
|
15
15
|
module ClassMethods
|
16
16
|
attr_reader :definitions
|
17
17
|
|
18
|
-
DEFINITIONS = %i[check_digit date length].freeze
|
18
|
+
DEFINITIONS = %i[check_digit date date_month_based length].freeze
|
19
19
|
|
20
20
|
def define(key, options = {})
|
21
21
|
raise UnknownDefinition, "#{key} is not a valid definition" unless DEFINITIONS.include?(key)
|
@@ -35,6 +35,11 @@ module GS1
|
|
35
35
|
{}
|
36
36
|
end
|
37
37
|
|
38
|
+
# Currently no support for options.
|
39
|
+
def normalize_date_month_based_options(_options)
|
40
|
+
{}
|
41
|
+
end
|
42
|
+
|
38
43
|
# Defaults barcode length to allowed length if not explicitly defined, only
|
39
44
|
# if there is one significant allowed.
|
40
45
|
def normalize_length_options(options)
|
data/lib/gs1/expiration_date.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module GS1
|
4
|
+
module Extensions
|
5
|
+
# Extension for a GS1 date. Ensures correct formating and validation.
|
6
|
+
#
|
7
|
+
# OBS! Month-based expiry
|
8
|
+
#
|
9
|
+
# Expiry dates for a batch of medicinal product are generally set by month, rather than day. If a batch
|
10
|
+
# expires in March 2021, for example, it expires at the very end of the month. From the 1st April 2021, the EMVS
|
11
|
+
# will report that the pack identifier has expired if it has not already been decommissioned for some other reason.
|
12
|
+
#
|
13
|
+
# Manufacturers represent expiry by month in one of two ways. They either set the expiry date to be the last day of
|
14
|
+
# the month or they set the day component of the date (DD) to '00'. Examples are shown below:
|
15
|
+
#
|
16
|
+
# Format A: 210331
|
17
|
+
# Format B: 210300
|
18
|
+
#
|
19
|
+
# These two formats effectively indicate the same expiry date. The first specifies a specific day (the last day of
|
20
|
+
# the month). The second specifies only the month of expiry.
|
21
|
+
#
|
22
|
+
# The format used in the barcodes must be exactly the same as the format used within the EMVS. If the manufacturer
|
23
|
+
# uploads batch data to the European Hub using one format, but prints the barcodes using the other, the dates will
|
24
|
+
# not match and the national system will raise 'potential falsified medicine' alerts. In this case, the packs
|
25
|
+
# cannot be supplied until the manufacturer corrects the data within the EMVS.
|
26
|
+
#
|
27
|
+
module DateMonthBased
|
28
|
+
def self.included(base)
|
29
|
+
base.define :date_month_based
|
30
|
+
base.define :length, barcode: 6
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(date)
|
34
|
+
if date.respond_to?(:strftime)
|
35
|
+
super(date.strftime('%y%m%d'))
|
36
|
+
else
|
37
|
+
super(date)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_date
|
42
|
+
to_date_format_a || to_date_format_b
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def to_date_format_a
|
48
|
+
::Date.strptime(data, '%y%m%d')
|
49
|
+
rescue TypeError, ArgumentError
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_date_format_b
|
54
|
+
::Date.strptime(data, '%y%m00').next_month.prev_day
|
55
|
+
rescue TypeError, ArgumentError
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/gs1/extensions.rb
CHANGED
@@ -9,6 +9,10 @@ module GS1
|
|
9
9
|
errors << 'Invalid date' unless valid_date?
|
10
10
|
end
|
11
11
|
|
12
|
+
def validate_date_month_based(_options = {})
|
13
|
+
errors << 'Invalid date' unless valid_month_based_date?
|
14
|
+
end
|
15
|
+
|
12
16
|
def valid_date?
|
13
17
|
return true if data.is_a?(::Date)
|
14
18
|
|
@@ -18,6 +22,31 @@ module GS1
|
|
18
22
|
rescue TypeError, ArgumentError
|
19
23
|
false
|
20
24
|
end
|
25
|
+
|
26
|
+
def valid_month_based_date?
|
27
|
+
return true if data.is_a?(::Date)
|
28
|
+
|
29
|
+
valid_format_a?(data) || valid_format_b?(data)
|
30
|
+
end
|
31
|
+
|
32
|
+
def valid_format_a?(data)
|
33
|
+
valid_date_format?(data, '%y%m%d')
|
34
|
+
end
|
35
|
+
|
36
|
+
# Read more about this date format in the GS1::Extensions::MonthBasedDate class.
|
37
|
+
def valid_format_b?(data)
|
38
|
+
valid_date_format?(data, '%y%m00')
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def valid_date_format?(data, pattern)
|
44
|
+
::Date.strptime(data, pattern)
|
45
|
+
|
46
|
+
true
|
47
|
+
rescue TypeError, ArgumentError
|
48
|
+
false
|
49
|
+
end
|
21
50
|
end
|
22
51
|
end
|
23
52
|
end
|
data/lib/gs1/version.rb
CHANGED
data/lib/gs1.rb
CHANGED
@@ -20,19 +20,28 @@ require 'gs1/barcode'
|
|
20
20
|
#
|
21
21
|
module GS1
|
22
22
|
class << self
|
23
|
-
def
|
23
|
+
def configuration
|
24
24
|
@configuration ||= Configuration.new
|
25
|
-
|
26
|
-
yield @configuration
|
27
25
|
end
|
28
26
|
|
29
|
-
|
27
|
+
def configure
|
28
|
+
if block_given?
|
29
|
+
yield configuration
|
30
|
+
else
|
31
|
+
configuration
|
32
|
+
end
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
36
|
# Configuration holds custom configuration parameters.
|
33
37
|
#
|
34
38
|
class Configuration
|
35
39
|
attr_accessor :company_prefix
|
40
|
+
attr_writer :barcode_separator
|
41
|
+
|
42
|
+
def barcode_separator
|
43
|
+
@barcode_separator || GS1::Barcode::DEFAULT_SEPARATOR
|
44
|
+
end
|
36
45
|
end
|
37
46
|
|
38
47
|
AI_CLASSES = GS1::Record.descendants.each_with_object({}) do |klass, hash|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gs1
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefan Åhman
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -143,6 +143,7 @@ files:
|
|
143
143
|
- lib/gs1/expiration_date.rb
|
144
144
|
- lib/gs1/extensions.rb
|
145
145
|
- lib/gs1/extensions/date.rb
|
146
|
+
- lib/gs1/extensions/date_month_based.rb
|
146
147
|
- lib/gs1/extensions/gtin.rb
|
147
148
|
- lib/gs1/gtin.rb
|
148
149
|
- lib/gs1/record.rb
|