floor_calculator 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b0f48d804000fa4334d9a9cb29a2d06ff73c0f07
4
+ data.tar.gz: 847a2a4c42515b3a15bd267caf6ef523b9583372
5
+ SHA512:
6
+ metadata.gz: a1e1ea32ba2e54418c31eb9f14d4dae7352e36cd7acfa2f85335966824f337219ae7336fb6f4669f95f5f3fba46a7b4564fb00809f377a9e0fe83e09b0b8c276
7
+ data.tar.gz: 81a4ad5cbbfb21b0f51faf452dd274b4498aadec11eaaaf4a2911c2e33e58cac3cc60eab8ab9f675a42099a251e92d533d50984e27a8bc0fa29c7da93b5273a6
@@ -0,0 +1,22 @@
1
+ require 'floor_calculator/solver'
2
+ require 'floor_calculator/pricer'
3
+ require 'dentaku'
4
+ require 'money'
5
+
6
+ module FloorCalculator
7
+ def self.initialize_methods
8
+ %i(usd gbp jpy mxn cad eur).each do |country_code|
9
+ Dentaku::Calculator.add_function country_code, :numeric, ->(value) do
10
+ if value.is_a?(Money)
11
+ value.exchange_to(country_code.to_s)
12
+ else
13
+ Money.new(value, country_code.to_s)
14
+ end
15
+ end
16
+ end
17
+
18
+ Dentaku::Calculator.add_function(:ceil, :numeric, ->(value) { value.ceil } )
19
+ Dentaku::Calculator.add_function(:fractional, :numeric, ->(value) { value.fractional.to_f } )
20
+ Dentaku.enable_caching!
21
+ end
22
+ end
@@ -0,0 +1,50 @@
1
+ require 'floor_calculator'
2
+
3
+ module FloorCalculator
4
+ class Pricer
5
+ attr_reader :partial_results, :markups, :source_catalog, :destination, :offer, :weight
6
+
7
+ def initialize(offer, weight, markups)
8
+ @partial_results = {}
9
+ @markups = markups
10
+ @weight = weight
11
+ @offer = offer
12
+ @source_catalog = offer[:source_catalog]
13
+ @destination = offer.catalog
14
+ end
15
+
16
+ def calculate_floor
17
+ new_price = cost_to_fill(prepare_options(offer, offer.price))
18
+ new_price = cost_to_ship(prepare_options(offer, new_price))
19
+ new_price = cost_of_spoilage(prepare_options(offer, new_price))
20
+ new_price = minimum_profit(prepare_options(offer, new_price))
21
+ round_to_20s(cost_to_list(prepare_options(offer, new_price)).fractional)
22
+ end
23
+
24
+ %w(cost_to_list cost_to_fill cost_of_spoilage
25
+ cost_to_ship minimum_profit).each do |method|
26
+ define_method method do |options|
27
+ calculated_value =
28
+ Solver.calculate(markups, method, options)
29
+ @partial_results[method] = calculated_value
30
+ result = options[:price] + calculated_value
31
+ result
32
+ end
33
+ end
34
+
35
+ def round_to_20s(price)
36
+ (price % 20) > 0 ? ((price.to_i / 20) + 1) * 20 : price
37
+ end
38
+
39
+ def prepare_options(offer, price)
40
+ {
41
+ source: offer[:source_catalog],
42
+ destination: offer.catalog,
43
+ price: price,
44
+ condition: offer.condition,
45
+ weight: weight,
46
+ fast: offer[:fast]
47
+ }
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,41 @@
1
+ require 'dentaku'
2
+ require 'yaml'
3
+
4
+ module FloorCalculator
5
+ class Solver
6
+ attr_reader :formula, :price, :weight, :markups, :fast, :condition
7
+
8
+ def self.calculate(markups, markup_name, options)
9
+ new(markups, markup_name, options).calculate
10
+ end
11
+
12
+ def initialize(markups, markup_name, options)
13
+ @markups = markups
14
+ markup = markups.fetch(markup_name.to_s, {})
15
+ source_formula = source_markup(markup, options[:source])
16
+ @formula = destination_markup(source_formula, options[:destination])
17
+ raise "Formula not found for: #{options[:source]}, #{options[:destination]}" if @formula.nil?
18
+ @price = options[:price]
19
+ @weight = options[:weight]
20
+ @fast = options[:fast]
21
+ @condition = options[:condition]
22
+ end
23
+
24
+ def calculate
25
+ Dentaku.evaluate(formula, price: price, weight: weight, fast: fast, condition: condition)
26
+ end
27
+
28
+ private
29
+
30
+ def source_markup(markup, source)
31
+ result = markup.fetch(source.to_s, {})
32
+ return markup.fetch('default', {}) if result == {}
33
+ return markup.fetch(result, {}) if !result.is_a?(Hash) && result.start_with?('shared')
34
+ result
35
+ end
36
+
37
+ def destination_markup(source, destination)
38
+ source.fetch(destination) { source.fetch('default', nil) }
39
+ end
40
+ end
41
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: floor_calculator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Marek Mikołajczyk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dentaku
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.11
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.11
27
+ - !ruby/object:Gem::Dependency
28
+ name: money
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-its
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Calculate offer floor using dentaku
70
+ email:
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/floor_calculator.rb
76
+ - lib/floor_calculator/pricer.rb
77
+ - lib/floor_calculator/solver.rb
78
+ homepage:
79
+ licenses: []
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.5.2
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Floor Calculator
101
+ test_files: []