davidsons 1.0.4 → 3.0.0.pre2
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 +1 -0
- data/lib/davidsons/base.rb +3 -11
- data/lib/davidsons/catalog.rb +50 -25
- data/lib/davidsons/inventory.rb +85 -50
- data/lib/davidsons/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b286e3483e84a4b0fd324fadb43e51d780a38127d34bb0bc75ff7cfb9f33d67d
|
4
|
+
data.tar.gz: 8abfaf696c4b51cea85a4683abfc29e941ab57d6a63467498bc59d269b553010
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b2c54f5e13281b8ef373ff67ccda709c279ed583420845f1fa4f9477a5153fad8df0524a19181a5974315b3dd06db1a63c1a91c3996503abc974c09f7e2460a
|
7
|
+
data.tar.gz: 271fba58c6784f8b014aa9de3f5e7f58a78f0962aacc420326209cb7d31f70e6fb24da3b23d27502b841d3a8cf0c73c7e77775a4b03a571bb2771b738f73361e
|
data/.gitignore
CHANGED
data/lib/davidsons/base.rb
CHANGED
@@ -47,17 +47,9 @@ module Davidsons
|
|
47
47
|
|
48
48
|
def get_file(filename)
|
49
49
|
connect(@options) do |ftp|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
ftp.getbinaryfile(filename, tempfile.path)
|
54
|
-
|
55
|
-
tempfile.close
|
56
|
-
|
57
|
-
tempfile
|
58
|
-
ensure
|
59
|
-
ftp.close
|
60
|
-
end
|
50
|
+
tempfile = Tempfile.new
|
51
|
+
ftp.getbinaryfile(filename, tempfile.path)
|
52
|
+
tempfile
|
61
53
|
end
|
62
54
|
end
|
63
55
|
|
data/lib/davidsons/catalog.rb
CHANGED
@@ -1,13 +1,31 @@
|
|
1
1
|
module Davidsons
|
2
2
|
class Catalog < Base
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
WHOLE_CATALOG_FILENAME = 'davidsons_inventory.csv'.freeze
|
5
|
+
DEFAULT_SMART_OPTS = {
|
6
|
+
chunk_size: 500,
|
7
|
+
convert_values_to_numeric: false,
|
8
|
+
force_utf8: true,
|
9
|
+
key_mapping: {
|
10
|
+
"item_#": :item_identifier,
|
11
|
+
item_description: :name,
|
12
|
+
upc_code: :upc,
|
13
|
+
manufacturer: :brand,
|
14
|
+
retail_price: :msrp,
|
15
|
+
gun_type: :category,
|
16
|
+
}
|
17
|
+
}
|
6
18
|
|
19
|
+
# @param [Hash] options
|
20
|
+
# @option options [Symbol] :username *required*
|
21
|
+
# @option options [Symbol] :password *required*
|
22
|
+
# @option options [Symbol] :pricing_tier *optional*
|
23
|
+
# * Denotes which price to use
|
24
|
+
# * Can be :regular or :minimum
|
7
25
|
def initialize(options = {})
|
8
26
|
requires!(options, :username, :password)
|
9
|
-
|
10
27
|
@options = options
|
28
|
+
@options[:pricing_tier] ||= :regular
|
11
29
|
end
|
12
30
|
|
13
31
|
def self.all(options = {}, &block)
|
@@ -16,42 +34,48 @@ module Davidsons
|
|
16
34
|
end
|
17
35
|
|
18
36
|
def all(&block)
|
19
|
-
tempfile = get_file(
|
20
|
-
|
21
|
-
# TODO: account for Sale Price and MSP (minimum price)
|
37
|
+
tempfile = get_file(WHOLE_CATALOG_FILENAME)
|
22
38
|
|
23
|
-
SmarterCSV.process(tempfile
|
24
|
-
chunk_size: CHUNK_SIZE,
|
25
|
-
convert_values_to_numeric: false,
|
26
|
-
force_utf8: true,
|
27
|
-
key_mapping: {
|
28
|
-
"item_#": :item_identifier,
|
29
|
-
item_description: :name,
|
30
|
-
upc_code: :upc,
|
31
|
-
manufacturer: :brand,
|
32
|
-
retail_price: :msrp,
|
33
|
-
dealer_price: :price,
|
34
|
-
gun_type: :category,
|
35
|
-
}
|
36
|
-
}) do |chunk|
|
39
|
+
SmarterCSV.process(tempfile, DEFAULT_SMART_OPTS) do |chunk|
|
37
40
|
chunk.each do |item|
|
38
|
-
item.except!(:retail_price, :capacity, :sale_price, :sale_ends)
|
39
|
-
|
40
41
|
item[:msrp].tr!('$', '')
|
41
|
-
item[:price].tr!('$', '')
|
42
42
|
item[:upc].tr!('#', '')
|
43
43
|
|
44
|
+
item[:price] = lowest_price(item)
|
44
45
|
item[:mfg_number] = item[:item_identifier]
|
45
|
-
item[:quantity]
|
46
|
-
item[:features]
|
46
|
+
item[:quantity] = item[:quantity].to_i
|
47
|
+
item[:features] = map_features(item)
|
48
|
+
|
49
|
+
item.delete(:sale_ends)
|
50
|
+
item.delete(:sale_price)
|
47
51
|
|
48
52
|
yield(item)
|
49
53
|
end
|
50
54
|
end
|
55
|
+
|
56
|
+
tempfile.unlink
|
51
57
|
end
|
52
58
|
|
53
59
|
protected
|
54
60
|
|
61
|
+
def lowest_price(item)
|
62
|
+
case @options[:pricing_tier]
|
63
|
+
when :minimum
|
64
|
+
relevant_price = item.delete(:msp).tr('$', '')
|
65
|
+
item.delete(:dealer_price)
|
66
|
+
else
|
67
|
+
relevant_price = item.delete(:dealer_price).tr('$', '')
|
68
|
+
item.delete(:msp)
|
69
|
+
end
|
70
|
+
|
71
|
+
if item[:sale_price]
|
72
|
+
sale_price = item.delete(:sale_price).tr('$', '')
|
73
|
+
return sale_price if sale_price.to_f < relevant_price.to_f
|
74
|
+
end
|
75
|
+
|
76
|
+
relevant_price
|
77
|
+
end
|
78
|
+
|
55
79
|
def map_features(item)
|
56
80
|
{
|
57
81
|
finish: item.delete(:finish),
|
@@ -60,6 +84,7 @@ module Davidsons
|
|
60
84
|
model_series: item.delete(:model_series),
|
61
85
|
sights: item.delete(:sights),
|
62
86
|
stock: item.delete(:stock),
|
87
|
+
capacity: item.delete(:capacity),
|
63
88
|
}
|
64
89
|
end
|
65
90
|
|
data/lib/davidsons/inventory.rb
CHANGED
@@ -1,89 +1,124 @@
|
|
1
1
|
module Davidsons
|
2
2
|
class Inventory < Base
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
WHOLE_CATALOG_FILENAME = 'davidsons_inventory.csv'.freeze
|
5
|
+
DEFAULT_WHOLE_CATALOG_SMART_OPTS = {
|
6
|
+
chunk_size: 500,
|
7
|
+
convert_values_to_numeric: false,
|
8
|
+
force_utf8: true,
|
9
|
+
remove_unmapped_keys: true,
|
10
|
+
key_mapping: {
|
11
|
+
"item_#": :item_identifier,
|
12
|
+
upc_code: :upc,
|
13
|
+
msp: :msp,
|
14
|
+
dealer_price: :dealer_price,
|
15
|
+
sale_price: :sale_price,
|
16
|
+
quantity: :quantity,
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
QUANTITY_FILENAME = 'davidsons_quantity.csv'.freeze
|
21
|
+
DEFAULT_QUANTITY_SMART_OPTS = {
|
22
|
+
chunk_size: 2000,
|
23
|
+
convert_values_to_numeric: false,
|
24
|
+
force_utf8: true,
|
25
|
+
key_mapping: {
|
26
|
+
item_number: :item_identifier,
|
27
|
+
upc_code: :upc
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
# @param [Hash] options
|
32
|
+
# @option options [Symbol] :username *required*
|
33
|
+
# @option options [Symbol] :password *required*
|
34
|
+
# @option options [Symbol] :pricing_tier *optional*
|
35
|
+
# * Denotes which price to use
|
36
|
+
# * Can be :regular or :minimum
|
7
37
|
def initialize(options = {})
|
8
38
|
requires!(options, :username, :password)
|
9
|
-
|
10
39
|
@options = options
|
40
|
+
@options[:pricing_tier] ||= :regular
|
11
41
|
end
|
12
42
|
|
43
|
+
# Iterates over all items in the 'davidsons_inventory.csv' file yielding the item_identifier, quantity, and price.
|
44
|
+
# We have to use this file since the 'davidsons_quantity.csv' file does not included prices.
|
45
|
+
# The price can vary based on the +pricing_tier+
|
46
|
+
#
|
47
|
+
# @param [Hash] options
|
48
|
+
# @option options [Symbol] :username *required*
|
49
|
+
# @option options [Symbol] :password *required*
|
50
|
+
# @option options [Symbol] :pricing_tier *optional*
|
51
|
+
# * Denotes which price to use
|
52
|
+
# * Can be :regular or :minimum
|
13
53
|
def self.all(options = {}, &block)
|
14
54
|
requires!(options, :username, :password)
|
15
|
-
new(options).
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.get_quantity_file(options = {})
|
19
|
-
requires!(options, :username, :password)
|
20
|
-
new(options).get_quantity_file
|
55
|
+
new(options).all(&block)
|
21
56
|
end
|
22
57
|
|
58
|
+
# Iterates over all items in the 'davidsons_quantity.csv' file yielding the item_identifier, upc, quantity and locations.
|
59
|
+
#
|
60
|
+
# @param [Hash] options
|
61
|
+
# @option options [Symbol] :username *required*
|
62
|
+
# @option options [Symbol] :password *required*
|
23
63
|
def self.quantity(options = {}, &block)
|
24
64
|
requires!(options, :username, :password)
|
25
65
|
new(options).quantity(&block)
|
26
66
|
end
|
27
67
|
|
28
|
-
def
|
29
|
-
tempfile = get_file(
|
30
|
-
|
31
|
-
SmarterCSV.process(tempfile.open, {
|
32
|
-
chunk_size: CHUNK_SIZE,
|
33
|
-
convert_values_to_numeric: false,
|
34
|
-
force_utf8: true,
|
35
|
-
key_mapping: { item_number: :item_identifier }
|
36
|
-
}) do |chunk|
|
37
|
-
chunk.each do |item|
|
38
|
-
item.except!(:upc_code)
|
68
|
+
def all
|
69
|
+
tempfile = get_file(WHOLE_CATALOG_FILENAME)
|
39
70
|
|
40
|
-
|
41
|
-
|
71
|
+
SmarterCSV.process(tempfile, DEFAULT_WHOLE_CATALOG_SMART_OPTS) do |chunk|
|
72
|
+
chunk.each do |item|
|
73
|
+
item[:upc].tr!('#', '')
|
42
74
|
|
43
|
-
item
|
75
|
+
item[:price] = lowest_price(item)
|
76
|
+
item[:quantity] = item[:quantity].to_i
|
44
77
|
|
45
78
|
yield(item)
|
46
79
|
end
|
47
80
|
end
|
48
81
|
end
|
49
82
|
|
50
|
-
def
|
51
|
-
|
52
|
-
tempfile = Tempfile.new
|
53
|
-
|
54
|
-
SmarterCSV.process(inventory_tempfile.open, {
|
55
|
-
chunk_size: CHUNK_SIZE,
|
56
|
-
convert_values_to_numeric: false,
|
57
|
-
force_utf8: true,
|
58
|
-
key_mapping: {
|
59
|
-
item_number: :item_identifier
|
60
|
-
}
|
61
|
-
}) do |chunk|
|
62
|
-
chunk.each do |item|
|
63
|
-
item.except!(:upc_code)
|
64
|
-
|
65
|
-
item[:quantity] = item[:quantity_nc].to_i + item[:quantity_az].to_i
|
83
|
+
def quantity(&block)
|
84
|
+
tempfile = get_file(QUANTITY_FILENAME)
|
66
85
|
|
67
|
-
|
86
|
+
SmarterCSV.process(tempfile, DEFAULT_QUANTITY_SMART_OPTS) do |chunk|
|
87
|
+
chunk.each do |item|
|
88
|
+
item[:quantity] = item[:quantity_nc].to_i + item[:quantity_az].to_i
|
89
|
+
item[:locations] = map_location_quantities(item)
|
68
90
|
|
69
|
-
|
91
|
+
yield(item)
|
70
92
|
end
|
71
93
|
end
|
72
|
-
|
73
|
-
inventory_tempfile.unlink
|
74
|
-
tempfile.close
|
75
|
-
|
76
|
-
tempfile.path
|
77
94
|
end
|
78
95
|
|
79
|
-
|
96
|
+
private
|
80
97
|
|
81
98
|
def map_location_quantities(item)
|
82
99
|
{
|
83
|
-
nc: item
|
84
|
-
az: item
|
100
|
+
nc: item.delete(:quantity_nc),
|
101
|
+
az: item.delete(:quantity_az),
|
85
102
|
}
|
86
103
|
end
|
87
104
|
|
105
|
+
def lowest_price(item)
|
106
|
+
case @options[:pricing_tier]
|
107
|
+
when :minimum
|
108
|
+
relevant_price = item.delete(:msp).tr('$', '')
|
109
|
+
item.delete(:dealer_price)
|
110
|
+
else
|
111
|
+
relevant_price = item.delete(:dealer_price).tr('$', '')
|
112
|
+
item.delete(:msp)
|
113
|
+
end
|
114
|
+
|
115
|
+
if item[:sale_price]
|
116
|
+
sale_price = item.delete(:sale_price).tr('$', '')
|
117
|
+
return sale_price if sale_price.to_f < relevant_price.to_f
|
118
|
+
end
|
119
|
+
|
120
|
+
relevant_price
|
121
|
+
end
|
122
|
+
|
88
123
|
end
|
89
124
|
end
|
data/lib/davidsons/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: davidsons
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0.pre2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Knight
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: savon
|
@@ -136,9 +136,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
136
136
|
version: '0'
|
137
137
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
138
|
requirements:
|
139
|
-
- - "
|
139
|
+
- - ">"
|
140
140
|
- !ruby/object:Gem::Version
|
141
|
-
version:
|
141
|
+
version: 1.3.1
|
142
142
|
requirements: []
|
143
143
|
rubyforge_project:
|
144
144
|
rubygems_version: 2.7.7
|