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 +7 -0
- data/lib/floor_calculator.rb +22 -0
- data/lib/floor_calculator/pricer.rb +50 -0
- data/lib/floor_calculator/solver.rb +41 -0
- metadata +101 -0
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: []
|