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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 914036ba6b5750a904124c069afd486e1ff4d38ff0a29328d93f012f8d3f0068
4
- data.tar.gz: 5c57655ba02a193e651319d14cb4f0da7e3898dfff958c900218a3a400aea3f8
3
+ metadata.gz: b286e3483e84a4b0fd324fadb43e51d780a38127d34bb0bc75ff7cfb9f33d67d
4
+ data.tar.gz: 8abfaf696c4b51cea85a4683abfc29e941ab57d6a63467498bc59d269b553010
5
5
  SHA512:
6
- metadata.gz: dbe533e923bc65689cd552207e4a1dcbd8e7217001d7bacddfbe5b619ca84639ef5b257d66aead601d1c04ae83b6084c14c91d0f5a15e40161c81c914c52e3aa
7
- data.tar.gz: a67c8daafc227e823331cc91f2cb32c76226b63f8c5481b6101c98c56abc184fa5fe43764460c65baafa35fcf08fb880d60ef9b689a4dd4cbbe931bc8a326c22
6
+ metadata.gz: 5b2c54f5e13281b8ef373ff67ccda709c279ed583420845f1fa4f9477a5153fad8df0524a19181a5974315b3dd06db1a63c1a91c3996503abc974c09f7e2460a
7
+ data.tar.gz: 271fba58c6784f8b014aa9de3f5e7f58a78f0962aacc420326209cb7d31f70e6fb24da3b23d27502b841d3a8cf0c73c7e77775a4b03a571bb2771b738f73361e
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ .DS_Store
1
2
  /.bundle/
2
3
  /.yardoc
3
4
  /Gemfile.lock
@@ -47,17 +47,9 @@ module Davidsons
47
47
 
48
48
  def get_file(filename)
49
49
  connect(@options) do |ftp|
50
- begin
51
- tempfile = Tempfile.new
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
 
@@ -1,13 +1,31 @@
1
1
  module Davidsons
2
2
  class Catalog < Base
3
3
 
4
- CATALOG_FILENAME = "davidsons_inventory.csv".freeze
5
- CHUNK_SIZE = 100
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(CATALOG_FILENAME)
20
-
21
- # TODO: account for Sale Price and MSP (minimum price)
37
+ tempfile = get_file(WHOLE_CATALOG_FILENAME)
22
38
 
23
- SmarterCSV.process(tempfile.open, {
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] = item[:quantity].to_i
46
- item[:features] = map_features(item)
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
 
@@ -1,89 +1,124 @@
1
1
  module Davidsons
2
2
  class Inventory < Base
3
3
 
4
- INVENTORY_FILENAME = "davidsons_quantity.csv"
5
- CHUNK_SIZE = 100
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).quantity(&block)
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 quantity(&block)
29
- tempfile = get_file(INVENTORY_FILENAME)
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
- item[:quantity] = item[:quantity_nc].to_i + item[:quantity_az].to_i
41
- item[:locations] = map_location_quantities(item)
71
+ SmarterCSV.process(tempfile, DEFAULT_WHOLE_CATALOG_SMART_OPTS) do |chunk|
72
+ chunk.each do |item|
73
+ item[:upc].tr!('#', '')
42
74
 
43
- item.except!(:quantity_nc, :quantity_az)
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 get_quantity_file
51
- inventory_tempfile = get_file(INVENTORY_FILENAME)
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
- item.except!(:quantity_nc, :quantity_az)
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
- tempfile.puts("#{item[:item_number]},#{item[:quantity]}")
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
- protected
96
+ private
80
97
 
81
98
  def map_location_quantities(item)
82
99
  {
83
- nc: item[:quantity_nc],
84
- az: item[:quantity_az]
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
@@ -1,3 +1,3 @@
1
1
  module Davidsons
2
- VERSION = '1.0.4'.freeze
2
+ VERSION = '3.0.0.pre2'.freeze
3
3
  end
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: 1.0.4
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-08-30 00:00:00.000000000 Z
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: '0'
141
+ version: 1.3.1
142
142
  requirements: []
143
143
  rubyforge_project:
144
144
  rubygems_version: 2.7.7