rsr_group 0.1.6 → 1.0.0.pre
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/.gitignore +2 -0
- data/config.rb.example +5 -0
- data/lib/rsr_group.rb +28 -0
- data/lib/rsr_group/base.rb +23 -8
- data/lib/rsr_group/order.rb +84 -0
- data/lib/rsr_group/order_detail.rb +29 -0
- data/lib/rsr_group/order_ffl.rb +24 -0
- data/lib/rsr_group/order_recipient.rb +55 -0
- data/lib/rsr_group/version.rb +1 -1
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c9bf20350d6ad63a809ab9b1ec14ed29dec0acb
|
4
|
+
data.tar.gz: 0cdadb5c40579b6abe6d28fa55e68dd486f9e27d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d608e462128d6ab5e7dcef36f317c5b028e21ce9d47329c5b5b4eacff091a363028fa66b2b1afc505fb7faa7fabc83689848c6de0120d0061aaaa242d92e5d87
|
7
|
+
data.tar.gz: 1ecd0f05f172f4a071df7e5c74c16e4367ad2cc9e269f67011cdf3bbb853e7f5d7a2f369d68b87370665d470f4c7f5b1f9d0b2f3f2db07a686e024e620c0807c
|
data/.gitignore
CHANGED
data/config.rb.example
ADDED
data/lib/rsr_group.rb
CHANGED
@@ -7,9 +7,37 @@ require 'net/ftp'
|
|
7
7
|
require 'rsr_group/base'
|
8
8
|
require 'rsr_group/department'
|
9
9
|
require 'rsr_group/inventory'
|
10
|
+
require 'rsr_group/order'
|
11
|
+
require 'rsr_group/order_detail'
|
12
|
+
require 'rsr_group/order_ffl'
|
13
|
+
require 'rsr_group/order_recipient'
|
10
14
|
require 'rsr_group/user'
|
11
15
|
|
12
16
|
module RsrGroup
|
13
17
|
class NotAuthenticated < StandardError; end
|
14
18
|
class UnknownDepartment < StandardError; end
|
19
|
+
|
20
|
+
class << self
|
21
|
+
attr_accessor :config
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.config
|
25
|
+
@config ||= Configuration.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.configure
|
29
|
+
yield(config)
|
30
|
+
end
|
31
|
+
|
32
|
+
class Configuration
|
33
|
+
attr_accessor :ftp_host
|
34
|
+
attr_accessor :submission_dir
|
35
|
+
attr_accessor :vendor_email
|
36
|
+
|
37
|
+
def initialize
|
38
|
+
@ftp_host ||= "ftp.rsrgroup.com"
|
39
|
+
@submission_dir ||= File.join("eo", "incoming")
|
40
|
+
@vendor_email ||= nil
|
41
|
+
end
|
42
|
+
end
|
15
43
|
end
|
data/lib/rsr_group/base.rb
CHANGED
@@ -1,13 +1,22 @@
|
|
1
1
|
module RsrGroup
|
2
2
|
class Base
|
3
3
|
|
4
|
-
|
4
|
+
SHIPPING_CARRIERS = %w(UPS USPS)
|
5
|
+
|
6
|
+
SHIPPING_METHODS = {
|
7
|
+
"Grnd" => "Ground",
|
8
|
+
"1Day" => "Next Day Air",
|
9
|
+
"2Day" => "2nd Day Air",
|
10
|
+
"3Day" => "3 Day Select",
|
11
|
+
"NDam" => "Next Day Early AM",
|
12
|
+
"NDAS" => "Next Day Air Saver",
|
13
|
+
"PRIO" => "Priority"
|
14
|
+
}
|
5
15
|
|
6
16
|
protected
|
7
17
|
|
8
|
-
|
9
|
-
|
10
|
-
self.class.requires!(*args)
|
18
|
+
def self.ftp_host
|
19
|
+
RsrGroup.config.ftp_host
|
11
20
|
end
|
12
21
|
|
13
22
|
def self.requires!(hash, *params)
|
@@ -23,16 +32,22 @@ module RsrGroup
|
|
23
32
|
end
|
24
33
|
end
|
25
34
|
|
35
|
+
def ftp_host
|
36
|
+
self.class.ftp_host
|
37
|
+
end
|
38
|
+
|
39
|
+
# Wrapper to `self.requires!` that can be used as an instance method.
|
40
|
+
def requires!(*args)
|
41
|
+
self.class.requires!(*args)
|
42
|
+
end
|
43
|
+
|
26
44
|
def connect(options = {})
|
27
45
|
requires!(options, :username, :password)
|
28
46
|
|
29
|
-
Net::FTP.open(
|
47
|
+
Net::FTP.open(ftp_host, options[:username], options[:password]) do |ftp|
|
30
48
|
ftp.passive = true
|
31
49
|
yield ftp
|
32
50
|
end
|
33
|
-
# TODO: Disable this rescue for now, so we can figure out what's happening when used in an actual app.
|
34
|
-
# rescue Net::FTPPermError
|
35
|
-
# raise RsrGroup::NotAuthenticated
|
36
51
|
end
|
37
52
|
|
38
53
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module RsrGroup
|
2
|
+
class Order < Base
|
3
|
+
|
4
|
+
attr_reader :credentials
|
5
|
+
attr_reader :identifier
|
6
|
+
attr_reader :timestamp
|
7
|
+
attr_reader :sequence_number
|
8
|
+
attr_accessor :recipients
|
9
|
+
|
10
|
+
LINE_TYPES = {
|
11
|
+
"00" => "file_header",
|
12
|
+
"10" => "order_header",
|
13
|
+
"11" => "ffl_dealer",
|
14
|
+
"20" => "order_detail",
|
15
|
+
"90" => "order_trailer",
|
16
|
+
"99" => "file_trailer"
|
17
|
+
}
|
18
|
+
|
19
|
+
def initialize(options = {})
|
20
|
+
requires!(options, :sequence_number, :username, :password, :identifier)
|
21
|
+
|
22
|
+
@credentials = options.select { |k, v| [:username, :password].include?(k) }
|
23
|
+
@identifier = options[:identifier]
|
24
|
+
@sequence_number = "%04d" % options[:sequence_number] # Leading zeros are required
|
25
|
+
@timestamp = Time.now.strftime("%Y%m%e")
|
26
|
+
@recipients = options[:recipients] || []
|
27
|
+
end
|
28
|
+
|
29
|
+
def header
|
30
|
+
["FILEHEADER", LINE_TYPES.key("file_header"), customer_number, @timestamp, @sequence_number].join(";")
|
31
|
+
end
|
32
|
+
|
33
|
+
def footer
|
34
|
+
["FILETRAILER", LINE_TYPES.key("file_trailer"), ("%05d" % recipients.length)].join(";")
|
35
|
+
end
|
36
|
+
|
37
|
+
def filename
|
38
|
+
name = ["EORD", customer_number, timestamp, sequence_number].join("-")
|
39
|
+
[name, ".txt"].join
|
40
|
+
end
|
41
|
+
|
42
|
+
def recipients
|
43
|
+
@recipients ||= []
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_txt
|
47
|
+
txt = header + "\n"
|
48
|
+
recipients.each do |recipient|
|
49
|
+
txt += (recipient.to_single_line + "\n")
|
50
|
+
if recipient.ffl
|
51
|
+
txt += (recipient.ffl.to_single_line + "\n")
|
52
|
+
end
|
53
|
+
recipient.items.each do |item|
|
54
|
+
txt += (item.to_single_line + "\n")
|
55
|
+
end
|
56
|
+
txt += recipient.trailer + "\n"
|
57
|
+
end
|
58
|
+
txt += footer
|
59
|
+
end
|
60
|
+
|
61
|
+
def submit!
|
62
|
+
connect(@credentials) do |ftp|
|
63
|
+
ftp.chdir(RsrGroup.config.submission_dir)
|
64
|
+
io = StringIO.new(to_txt)
|
65
|
+
begin
|
66
|
+
ftp.storlines("STOR " + filename, io)
|
67
|
+
ensure
|
68
|
+
io.close
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def customer_number
|
76
|
+
credentials[:username]
|
77
|
+
end
|
78
|
+
|
79
|
+
def items
|
80
|
+
recipients.map(&:items).flatten.compact
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module RsrGroup
|
2
|
+
class OrderDetail < Base
|
3
|
+
|
4
|
+
attr_reader :order_identifier
|
5
|
+
attr_reader :quantity
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
requires!(options, :order_identifier, :rsr_stock_number, :quantity, :shipping_carrier, :shipping_method)
|
9
|
+
|
10
|
+
@order_identifier = options[:order_identifier]
|
11
|
+
@rsr_stock_number = options[:rsr_stock_number]
|
12
|
+
@quantity = (options[:quantity].is_a?(Integer) ? ("%05d" % options[:quantity]) : options[:quantity])
|
13
|
+
@shipping_carrier = options[:shipping_carrier]
|
14
|
+
@shipping_method = options[:shipping_method]
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_single_line
|
18
|
+
[
|
19
|
+
order_identifier,
|
20
|
+
Order::LINE_TYPES.key("order_detail"),
|
21
|
+
@rsr_stock_number,
|
22
|
+
@quantity,
|
23
|
+
@shipping_carrier,
|
24
|
+
@shipping_method
|
25
|
+
].join(";")
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RsrGroup
|
2
|
+
class OrderFFL < Base
|
3
|
+
|
4
|
+
attr_reader :order_identifier
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
requires!(options, :order_identifier, :licence_number, :name, :zip)
|
8
|
+
|
9
|
+
@options = options
|
10
|
+
@order_identifier = options[:order_identifier]
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_single_line
|
14
|
+
[
|
15
|
+
order_identifier,
|
16
|
+
Order::LINE_TYPES.key("ffl_dealer"),
|
17
|
+
@options[:licence_number],
|
18
|
+
@options[:name],
|
19
|
+
@options[:zip],
|
20
|
+
].join(";")
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module RsrGroup
|
2
|
+
class OrderRecipient < Base
|
3
|
+
|
4
|
+
attr_reader :order_identifier
|
5
|
+
attr_accessor :ffl
|
6
|
+
attr_accessor :items
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
requires!(options, :order_identifier, :shipping_name, :address_one, :city, :state, :zip)
|
10
|
+
|
11
|
+
@ffl = options[:ffl]
|
12
|
+
@items = options[:items] || []
|
13
|
+
@options = options
|
14
|
+
@order_identifier = options[:order_identifier]
|
15
|
+
end
|
16
|
+
|
17
|
+
def items
|
18
|
+
@items ||= []
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_single_line
|
22
|
+
[
|
23
|
+
order_identifier,
|
24
|
+
Order::LINE_TYPES.key("order_header"),
|
25
|
+
@options[:shipping_name],
|
26
|
+
@options[:attn],
|
27
|
+
@options[:address_one],
|
28
|
+
@options[:address_two],
|
29
|
+
@options[:city],
|
30
|
+
@options[:state],
|
31
|
+
@options[:zip],
|
32
|
+
@options[:phone],
|
33
|
+
(@options[:email].nil? ? "N" : "Y"),
|
34
|
+
@options[:email],
|
35
|
+
RsrGroup.config.vendor_email,
|
36
|
+
nil
|
37
|
+
].join(";")
|
38
|
+
end
|
39
|
+
|
40
|
+
def trailer
|
41
|
+
[
|
42
|
+
order_identifier,
|
43
|
+
Order::LINE_TYPES.key("order_trailer"),
|
44
|
+
("%07d" % quantity_sum)
|
45
|
+
].join(";")
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def quantity_sum
|
51
|
+
items.map(&:quantity).map(&:to_i).inject(:+)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
data/lib/rsr_group/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rsr_group
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dale Campbell
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -84,10 +84,15 @@ files:
|
|
84
84
|
- Rakefile
|
85
85
|
- bin/console
|
86
86
|
- bin/setup
|
87
|
+
- config.rb.example
|
87
88
|
- lib/rsr_group.rb
|
88
89
|
- lib/rsr_group/base.rb
|
89
90
|
- lib/rsr_group/department.rb
|
90
91
|
- lib/rsr_group/inventory.rb
|
92
|
+
- lib/rsr_group/order.rb
|
93
|
+
- lib/rsr_group/order_detail.rb
|
94
|
+
- lib/rsr_group/order_ffl.rb
|
95
|
+
- lib/rsr_group/order_recipient.rb
|
91
96
|
- lib/rsr_group/user.rb
|
92
97
|
- lib/rsr_group/version.rb
|
93
98
|
- rsr_group.gemspec
|
@@ -106,9 +111,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
106
111
|
version: '2.0'
|
107
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
113
|
requirements:
|
109
|
-
- - "
|
114
|
+
- - ">"
|
110
115
|
- !ruby/object:Gem::Version
|
111
|
-
version:
|
116
|
+
version: 1.3.1
|
112
117
|
requirements: []
|
113
118
|
rubyforge_project:
|
114
119
|
rubygems_version: 2.6.7
|