interests 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a9be6b2c88262c28c80dcc15a26d0d5cd851db5e
4
+ data.tar.gz: 4164f4c6678d69dec248c44f0a0e6bd97448a4a7
5
+ SHA512:
6
+ metadata.gz: d215cb2d3b8f87afff1a384d218cca84f26a5fa719b7fb8de306436b801e807250d212cf086b96abb8af221e567937bc4fd355e2704fc148c8c086f0e19ff41b
7
+ data.tar.gz: a0d653ffb6f2d77d82b6e54b80231d2f101a2e283852d5c08832ffcc9c56056e8fc1e217122af1a5621ff973b9dddf5237e08ab007c602f3b4fa4dafd0b1389e
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 Alek Niemczyk
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ ## Interests
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/interests.svg)](http://badge.fury.io/rb/interests)
4
+ [![Build Status](https://travis-ci.org/logicorg/interests.svg?branch=master)](https://travis-ci.org/logicorg/interests)
5
+ [![Code Climate](https://codeclimate.com/github/logicorg/interests/badges/gpa.svg)](https://codeclimate.com/github/logicorg/interests)
6
+
7
+ Factory shift methods collection by [RubyLogic, PL](http://rubylogic.eu)
8
+
9
+ ## Installation
10
+
11
+ Add it to your Gemfile with:
12
+
13
+ ```ruby
14
+ gem 'interests'
15
+ ```
16
+
17
+ Run the bundle command to install it.
18
+
19
+ Run generator if needed with:
20
+
21
+ ```console
22
+ rails generate interests:config
23
+ ```
24
+
25
+ ### Basic usage
26
+
27
+ Interests gem allows to calculate total interests between two dates
28
+
29
+ ```ruby
30
+ Interests::Calculator.total_interests(1000, Date.new(2014, 1, 1), Date.new(2014, 12, 31))
31
+ ````
32
+
33
+ Moreover the gem provides access to the following extensions.
34
+
35
+ ### Date class exts
36
+
37
+ ```ruby
38
+ Date.new(2014, 1, 1).total_interests_till(1000, Date.new(2014, 12, 31))
39
+ # returns total interests from the 1st of January 2014 till 31st of December of 2014
40
+
41
+ Date.new(2014, 12, 31).total_interests_from(1000, Date.new(2014, 1, 1))
42
+ # returns total interests from the 1st of January 2014 till 31st of December of 2014
43
+ ```
44
+
45
+ ### Fixnum and Float class exts
46
+
47
+ ```ruby
48
+ 1000.total_interests(Date.new(2014, 1, 1), Date.new(2014, 12, 31))
49
+ # returns total interests from the 1st of January 2014 till 31st of December of 2014
50
+
51
+ 12.99.total_interests(Date.new(2014, 1, 1), Date.new(2014, 12, 31))
52
+ # returns total interests from the 1st of January 2014 till 31st of December of 2014
53
+ ```
54
+
55
+ ## License
56
+ Copyright © 2012 - 2015 Ruby Logic, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Interests'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ task(:default).clear
18
+ task :default => :spec
19
+
20
+ Bundler::GemHelper.install_tasks
21
+
@@ -0,0 +1,20 @@
1
+ module Interests
2
+ module Generators
3
+ class ConfigGenerator < Rails::Generators::Base # :nodoc:
4
+
5
+ def self.gem_root
6
+ File.expand_path("../../../..", __FILE__)
7
+ end
8
+
9
+ def self.source_root
10
+ # Use the templates from the 2.3.x generator
11
+ File.join(gem_root, 'rails_generators', 'templates')
12
+ end
13
+
14
+ def generate
15
+ template 'interests.rb', File.join('config', 'initializers', 'interests.rb')
16
+ template 'interests.yml', File.join('config', 'interests.yml')
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,62 @@
1
+ require 'ostruct'
2
+
3
+ module Interests
4
+
5
+ BEGINNING_OF_COMPUTER_ERA = Date.new(1970, 1, 1)
6
+
7
+ class Calculator
8
+ class << self
9
+ def config_rates(scope = :default)
10
+ Interests::Config.send(scope).map{ |cfg| OpenStruct.new(date: Date.parse(cfg[:date]), rate: cfg[:rate]) }
11
+ end
12
+
13
+ def rates(till = Date.today)
14
+ @rates = []
15
+ return @rates if config_rates.none? || !starts_in_computers_era?
16
+
17
+ prev_rate = nil
18
+ config_rates.sort!{ |x, y| x.date <=> y.date }
19
+ ([blank_rate] + config_rates + [blank_rate(till + 1.day, config_rates.last.rate)]).each_with_index do |rate, i|
20
+ if i > 0
21
+ from_date = prev_rate.date
22
+ to_date = rate.date - 1.day
23
+ days = (to_date - from_date).to_i
24
+ day_rate = prev_rate.rate.to_f / 365
25
+ @rates << OpenStruct.new(from_date: from_date, to_date: to_date, days: days, rate: prev_rate.rate, day_rate: day_rate)
26
+ end
27
+ prev_rate = rate
28
+ end
29
+
30
+ @rates
31
+ end
32
+
33
+ def interests(amount = 0.0, from_date = BEGINNING_OF_COMPUTER_ERA, to_date = Date.today)
34
+ rates(to_date).select{ |rate| rate.to_date >= from_date && rate.from_date <= to_date }.map do |rate|
35
+ date_beg = [from_date + 1.day, rate.from_date].max
36
+ date_end = [to_date, rate.to_date].min
37
+ OpenStruct.new(
38
+ date_beg: date_beg,
39
+ date_end: date_end,
40
+ days: (date_beg..date_end).count,
41
+ day_rate: rate.day_rate,
42
+ interests: amount * (date_beg..date_end).count * rate.day_rate
43
+ )
44
+ end
45
+ end
46
+
47
+ def total_interests(amount = 0.0, from_date = BEGINNING_OF_COMPUTER_ERA, to_date = Date.today)
48
+ interests(amount, from_date, to_date).map(&:interests).inject(0, :+)
49
+ end
50
+
51
+ private
52
+
53
+ def starts_in_computers_era?
54
+ config_rates.map(&:date).min > BEGINNING_OF_COMPUTER_ERA
55
+ end
56
+
57
+ def blank_rate(date = BEGINNING_OF_COMPUTER_ERA, rate = 0.0)
58
+ OpenStruct.new(date: date, rate: rate)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,73 @@
1
+ module Interests
2
+ class Config
3
+ DEFAULT_CONFIG = {
4
+ default: [
5
+ { date: '1997-01-01', rate: 0.35 },
6
+ { date: '1998-04-15', rate: 0.33 },
7
+ { date: '1999-02-01', rate: 0.24 },
8
+ { date: '1999-05-15', rate: 0.21 },
9
+ { date: '2000-11-01', rate: 0.30 },
10
+ { date: '2001-12-15', rate: 0.20 },
11
+ { date: '2002-07-25', rate: 0.16 },
12
+ { date: '2003-02-01', rate: 0.13 },
13
+ { date: '2003-09-25', rate: 0.1225 },
14
+ { date: '2005-01-10', rate: 0.135 },
15
+ { date: '2005-10-15', rate: 0.115 },
16
+ { date: '2008-12-15', rate: 0.13 },
17
+ { date: '2014-12-23', rate: 0.08 }
18
+ ]
19
+ }
20
+
21
+ class << self
22
+ private
23
+
24
+ def config
25
+ Thread.main[:interests_config] ||= default_config
26
+ end
27
+
28
+ def config=(config)
29
+ Thread.main[:interests_config] = config
30
+ end
31
+
32
+ def threadsafe_cattr_accessor(name)
33
+ define_singleton_method name do
34
+ config[name]
35
+ end
36
+ define_singleton_method "#{name}=" do |value|
37
+ config[name] = value
38
+ end
39
+ end
40
+ end
41
+
42
+ threadsafe_cattr_accessor :default
43
+
44
+ class << self
45
+ def load(file)
46
+ reset
47
+ data = YAML::load(file.respond_to?(:read) ? file : File.open(file))
48
+ config = (data['interests'] || {})
49
+
50
+ config_vars = %w(default)
51
+ config_vars.each do |var|
52
+ send("#{var}=", config[var]) if config[var] && respond_to?("#{var}=")
53
+ end
54
+ end
55
+
56
+ def default_config
57
+ deep_dup(DEFAULT_CONFIG)
58
+ end
59
+
60
+ private
61
+
62
+ def reset
63
+ self.config = default_config
64
+ end
65
+
66
+ def deep_dup(object)
67
+ Marshal.load(Marshal.dump(object))
68
+ end
69
+ end
70
+
71
+ reset
72
+ end
73
+ end
@@ -0,0 +1,10 @@
1
+ class Date
2
+
3
+ def total_interests_till(amount, to_date)
4
+ Interests::Calculator.total_interests(amount, self, to_date)
5
+ end
6
+
7
+ def total_interests_from(amount, from_date)
8
+ Interests::Calculator.total_interests(amount, from_date, self)
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ class Fixnum
2
+
3
+ def total_interests(from_date, to_date)
4
+ Interests::Calculator.total_interests(self, from_date, to_date)
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ class Float
2
+
3
+ def total_interests(from_date, to_date)
4
+ Interests::Calculator.total_interests(self, from_date, to_date)
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module Interests
2
+ VERSION = "0.1.0"
3
+ end
data/lib/interests.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'thread'
2
+ require 'active_support'
3
+ require 'active_support/time'
4
+ require 'yaml'
5
+
6
+ require 'interests/config'
7
+ require 'interests/calculator'
8
+ require 'interests/core_ext/date'
9
+ require 'interests/core_ext/float'
10
+ require 'interests/core_ext/fixnum'
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :interests do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,9 @@
1
+ class InterestsConfigGenerator < Rails::Generator::Base
2
+
3
+ def manifest
4
+ record do |m|
5
+ m.template('interests.rb', "config/initializers/interests.rb")
6
+ m.template('interests.yml', "config/interests.yml")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1 @@
1
+ Interests::Config.load("#{Rails.root}/config/interests.yml")
@@ -0,0 +1,41 @@
1
+ interests:
2
+ base:
3
+ -
4
+ date: '1997-01-01'
5
+ rate: 0.35
6
+ -
7
+ date: '1998-04-15'
8
+ rate: 0.33
9
+ -
10
+ date: '1999-02-01'
11
+ rate: 0.24
12
+ -
13
+ date: '1999-05-15'
14
+ rate: 0.21
15
+ -
16
+ date: '2000-11-01'
17
+ rate: 0.30
18
+ -
19
+ date: '2001-12-15'
20
+ rate: 0.20
21
+ -
22
+ date: '2002-07-25'
23
+ rate: 0.16
24
+ -
25
+ date: '2003-02-01'
26
+ rate: 0.13
27
+ -
28
+ date: '2003-09-25'
29
+ rate: 0.1225
30
+ -
31
+ date: '2005-01-10'
32
+ rate: 0.135
33
+ -
34
+ date: '2005-10-15'
35
+ rate: 0.115
36
+ -
37
+ date: '2008-12-15'
38
+ rate: 0.13
39
+ -
40
+ date: '2014-12-23'
41
+ rate: 0.08
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: interests
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alek Niemczyk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
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-rails
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
+ description: Interests calculator
56
+ email:
57
+ - alek@rubylogic.pl
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - lib/generators/interests/config_generator.rb
63
+ - lib/interests.rb
64
+ - lib/interests/calculator.rb
65
+ - lib/interests/core_ext/fixnum.rb
66
+ - lib/interests/core_ext/date.rb
67
+ - lib/interests/core_ext/float.rb
68
+ - lib/interests/config.rb
69
+ - lib/interests/version.rb
70
+ - lib/tasks/interests_tasks.rake
71
+ - rails_generators/templates/interests.rb
72
+ - rails_generators/templates/interests.yml
73
+ - rails_generators/interests_config_generator.rb
74
+ - MIT-LICENSE
75
+ - Rakefile
76
+ - README.md
77
+ homepage: https://github.com/logicorg/interests
78
+ licenses:
79
+ - MIT
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.1.11
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Interests calculator
101
+ test_files: []