rsr_group 0.1.6 → 1.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- 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
|