gs1 0.1.5 → 0.1.6
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 +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
|