fiscal 0.2.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: 8f0e6e35a3fae45297b2c8ae7ce481dbda11936a
4
+ data.tar.gz: 31d045ef305bbddea3aeb81d2f79b83bc9b602c3
5
+ SHA512:
6
+ metadata.gz: b3215f7db218abaeba0357ca55197ec9244124ce4083a2ab8bfe9be9ae510330ee2cc9b62af7c8e388ed14cf4cd42be369f99711874d370b19e4f5ede1618497
7
+ data.tar.gz: bc08dd7da0fb990e72ffeab195505e2f06f6f187ff78b39314260fa8e7d7443fcd66a8e0f35e19c4f5d53c60858264b1ea2d710a011ee6ff8decff14b808793f
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .bundle/*
2
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fiscal.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ fiscal (0.2.0)
5
+ activesupport
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (4.0.2)
11
+ i18n (~> 0.6, >= 0.6.4)
12
+ minitest (~> 4.2)
13
+ multi_json (~> 1.3)
14
+ thread_safe (~> 0.1)
15
+ tzinfo (~> 0.3.37)
16
+ atomic (1.1.14)
17
+ diff-lcs (1.2.5)
18
+ i18n (0.6.9)
19
+ minitest (4.7.5)
20
+ multi_json (1.8.4)
21
+ rake (10.1.1)
22
+ rspec (2.14.1)
23
+ rspec-core (~> 2.14.0)
24
+ rspec-expectations (~> 2.14.0)
25
+ rspec-mocks (~> 2.14.0)
26
+ rspec-core (2.14.7)
27
+ rspec-expectations (2.14.5)
28
+ diff-lcs (>= 1.1.3, < 2.0)
29
+ rspec-mocks (2.14.5)
30
+ thread_safe (0.1.3)
31
+ atomic
32
+ tzinfo (0.3.38)
33
+
34
+ PLATFORMS
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ bundler (~> 1.5)
39
+ fiscal!
40
+ rake
41
+ rspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Geordee Naliyath
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # Fiscal
2
+
3
+ Get the fiscal period attributes for various countries.
4
+
5
+ The gem extends the Date and Time classes to add a fiscal object,
6
+ which in turn provides additional objects and methods to find fiscal
7
+ year, half year, quarter and month, along with start and end dates.
8
+
9
+ Additionally, a prev and next methods are available to step through
10
+ fiscal periods.
11
+
12
+ The gem also supports fiscal calendars of different countries. Please
13
+ see examples for more details.
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ gem 'fiscal'
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install fiscal
28
+
29
+ ## Usage
30
+
31
+ The methods for fiscal periods are available both in Date and Time classes
32
+ as well as in the instances.
33
+
34
+ A typical usage would be:
35
+
36
+ Date.today.fiscal.year.start
37
+ Date.today.fiscal.quarter.prev.end
38
+
39
+ Date.today.fiscal(country: :us).quarter.next.start
40
+ Date.today.fiscal(country: :in).month.number
41
+
42
+ Alternatively a fiscal object can be created for further use.
43
+
44
+ fiscal = Date.fiscal(date: '2014-01-01', country: :in)
45
+ fiscal.year.start
46
+
47
+ fiscal_month = Date.fiscal(date: '2014-01-01', country: :in).month
48
+ fiscal_month.start
49
+ fiscal_month.prev.end
50
+
51
+ ## Contributing
52
+
53
+ 1. Fork it ( http://github.com/samyukti/fiscal/fork )
54
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
55
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
56
+ 4. Push to the branch (`git push origin my-new-feature`)
57
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/fiscal.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'fiscal/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "fiscal"
8
+ spec.version = Fiscal::VERSION
9
+ spec.authors = ["Geordee Naliyath"]
10
+ spec.email = ["geordee@gmail.com"]
11
+ spec.summary = %q{Get the fiscal period attributes for various countries}
12
+ spec.description = %q{The "fiscal" gem helps to retrieve the fiscal year, half year, quarter and month along with start and end dates for many countries.}
13
+ spec.homepage = "https://github.com/samyukti/fiscal"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "activesupport"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.5"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "rspec"
26
+ end
data/lib/fiscal.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'date'
2
+ require 'active_support/core_ext'
3
+ require 'fiscal/version'
4
+ require 'fiscal/config'
5
+ require 'fiscal/period'
6
+ require 'fiscal/methods'
7
+ require 'fiscal/base'
8
+
9
+ Date.send :include, Fiscal
10
+ Time.send :include, Fiscal
@@ -0,0 +1,19 @@
1
+ module Fiscal
2
+
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def fiscal(options = {})
9
+ Fiscal.new(options)
10
+ end
11
+ end
12
+
13
+ def fiscal(options = {})
14
+ # default date from the date instance
15
+ options[:date] = options[:date] || Date.new(self.year, self.month, self.day)
16
+ Fiscal.new(options)
17
+ end
18
+
19
+ end
@@ -0,0 +1,243 @@
1
+ module Fiscal
2
+
3
+ module FiscalConfig
4
+ def config
5
+ # The World Factbook 2013-14. Washington, DC: Central Intelligence Agency, 2013 .
6
+ # https://www.cia.gov/library/publications/the-world-factbook/fields/2080.html
7
+
8
+ # NOTE: ki, so are defaulted to 1, 1
9
+
10
+ # country, month, day
11
+ {nil: { mm: 1, dd: 1 },
12
+ ad: { mm: 1, dd: 1 },
13
+ ae: { mm: 1, dd: 1 },
14
+ af: { mm: 12, dd: 21 },
15
+ ag: { mm: 4, dd: 1 },
16
+ ai: { mm: 4, dd: 1 },
17
+ al: { mm: 1, dd: 1 },
18
+ am: { mm: 1, dd: 1 },
19
+ ao: { mm: 1, dd: 1 },
20
+ ar: { mm: 1, dd: 1 },
21
+ as: { mm: 10, dd: 1 },
22
+ at: { mm: 1, dd: 1 },
23
+ au: { mm: 7, dd: 1 },
24
+ aw: { mm: 1, dd: 1 },
25
+ az: { mm: 1, dd: 1 },
26
+ ba: { mm: 1, dd: 1 },
27
+ bb: { mm: 4, dd: 1 },
28
+ bd: { mm: 7, dd: 1 },
29
+ be: { mm: 1, dd: 1 },
30
+ bf: { mm: 1, dd: 1 },
31
+ bg: { mm: 1, dd: 1 },
32
+ bh: { mm: 1, dd: 1 },
33
+ bi: { mm: 1, dd: 1 },
34
+ bj: { mm: 1, dd: 1 },
35
+ bm: { mm: 4, dd: 1 },
36
+ bn: { mm: 4, dd: 1 },
37
+ bo: { mm: 1, dd: 1 },
38
+ br: { mm: 1, dd: 1 },
39
+ bs: { mm: 7, dd: 1 },
40
+ bt: { mm: 7, dd: 1 },
41
+ bw: { mm: 4, dd: 1 },
42
+ by: { mm: 1, dd: 1 },
43
+ bz: { mm: 4, dd: 1 },
44
+ ca: { mm: 4, dd: 1 },
45
+ cc: { mm: 7, dd: 1 },
46
+ cd: { mm: 1, dd: 1 },
47
+ cf: { mm: 1, dd: 1 },
48
+ cg: { mm: 1, dd: 1 },
49
+ ch: { mm: 1, dd: 1 },
50
+ ci: { mm: 1, dd: 1 },
51
+ ck: { mm: 4, dd: 1 },
52
+ cl: { mm: 1, dd: 1 },
53
+ cm: { mm: 7, dd: 1 },
54
+ cn: { mm: 1, dd: 1 },
55
+ co: { mm: 1, dd: 1 },
56
+ cr: { mm: 1, dd: 1 },
57
+ cu: { mm: 1, dd: 1 },
58
+ cv: { mm: 1, dd: 1 },
59
+ cx: { mm: 7, dd: 1 },
60
+ cy: { mm: 1, dd: 1 },
61
+ cz: { mm: 1, dd: 1 },
62
+ de: { mm: 1, dd: 1 },
63
+ dj: { mm: 1, dd: 1 },
64
+ dk: { mm: 1, dd: 1 },
65
+ dm: { mm: 7, dd: 1 },
66
+ do: { mm: 1, dd: 1 },
67
+ dz: { mm: 1, dd: 1 },
68
+ ec: { mm: 1, dd: 1 },
69
+ ee: { mm: 1, dd: 1 },
70
+ eg: { mm: 7, dd: 1 },
71
+ eh: { mm: 1, dd: 1 },
72
+ er: { mm: 1, dd: 1 },
73
+ es: { mm: 1, dd: 1 },
74
+ et: { mm: 7, dd: 8 },
75
+ fi: { mm: 1, dd: 1 },
76
+ fj: { mm: 1, dd: 1 },
77
+ fk: { mm: 4, dd: 1 },
78
+ fm: { mm: 10, dd: 1 },
79
+ fo: { mm: 1, dd: 1 },
80
+ fr: { mm: 1, dd: 1 },
81
+ ga: { mm: 1, dd: 1 },
82
+ gb: { mm: 4, dd: 6 },
83
+ gd: { mm: 1, dd: 1 },
84
+ ge: { mm: 1, dd: 1 },
85
+ gg: { mm: 1, dd: 1 },
86
+ gh: { mm: 1, dd: 1 },
87
+ gi: { mm: 7, dd: 1 },
88
+ gl: { mm: 1, dd: 1 },
89
+ gm: { mm: 1, dd: 1 },
90
+ gn: { mm: 1, dd: 1 },
91
+ gq: { mm: 1, dd: 1 },
92
+ gr: { mm: 1, dd: 1 },
93
+ gt: { mm: 1, dd: 1 },
94
+ gu: { mm: 10, dd: 1 },
95
+ gw: { mm: 1, dd: 1 },
96
+ gy: { mm: 1, dd: 1 },
97
+ hk: { mm: 4, dd: 1 },
98
+ hn: { mm: 1, dd: 1 },
99
+ hr: { mm: 1, dd: 1 },
100
+ ht: { mm: 10, dd: 1 },
101
+ hu: { mm: 1, dd: 1 },
102
+ id: { mm: 1, dd: 1 },
103
+ ie: { mm: 1, dd: 1 },
104
+ il: { mm: 1, dd: 1 },
105
+ im: { mm: 4, dd: 1 },
106
+ in: { mm: 4, dd: 1 },
107
+ iq: { mm: 1, dd: 1 },
108
+ ir: { mm: 3, dd: 21 },
109
+ is: { mm: 1, dd: 1 },
110
+ it: { mm: 1, dd: 1 },
111
+ je: { mm: 4, dd: 1 },
112
+ jm: { mm: 4, dd: 1 },
113
+ jo: { mm: 1, dd: 1 },
114
+ jp: { mm: 4, dd: 1 },
115
+ ke: { mm: 7, dd: 1 },
116
+ kg: { mm: 1, dd: 1 },
117
+ kh: { mm: 1, dd: 1 },
118
+ ki: { mm: 1, dd: 1 },
119
+ km: { mm: 1, dd: 1 },
120
+ kn: { mm: 1, dd: 1 },
121
+ kp: { mm: 1, dd: 1 },
122
+ kr: { mm: 1, dd: 1 },
123
+ kw: { mm: 4, dd: 1 },
124
+ ky: { mm: 4, dd: 1 },
125
+ kz: { mm: 1, dd: 1 },
126
+ la: { mm: 10, dd: 1 },
127
+ lb: { mm: 1, dd: 1 },
128
+ lc: { mm: 4, dd: 1 },
129
+ li: { mm: 1, dd: 1 },
130
+ lk: { mm: 1, dd: 1 },
131
+ lr: { mm: 1, dd: 1 },
132
+ ls: { mm: 4, dd: 1 },
133
+ lt: { mm: 1, dd: 1 },
134
+ lu: { mm: 1, dd: 1 },
135
+ lv: { mm: 1, dd: 1 },
136
+ ly: { mm: 1, dd: 1 },
137
+ ma: { mm: 1, dd: 1 },
138
+ mc: { mm: 1, dd: 1 },
139
+ md: { mm: 1, dd: 1 },
140
+ me: { mm: 1, dd: 1 },
141
+ mg: { mm: 1, dd: 1 },
142
+ mh: { mm: 10, dd: 1 },
143
+ mk: { mm: 1, dd: 1 },
144
+ ml: { mm: 1, dd: 1 },
145
+ mm: { mm: 4, dd: 1 },
146
+ mn: { mm: 1, dd: 1 },
147
+ mo: { mm: 1, dd: 1 },
148
+ mp: { mm: 10, dd: 1 },
149
+ mr: { mm: 1, dd: 1 },
150
+ ms: { mm: 4, dd: 1 },
151
+ mt: { mm: 1, dd: 1 },
152
+ mu: { mm: 7, dd: 1 },
153
+ mv: { mm: 1, dd: 1 },
154
+ mw: { mm: 7, dd: 1 },
155
+ mx: { mm: 1, dd: 1 },
156
+ my: { mm: 1, dd: 1 },
157
+ mz: { mm: 1, dd: 1 },
158
+ na: { mm: 4, dd: 1 },
159
+ nc: { mm: 1, dd: 1 },
160
+ ne: { mm: 1, dd: 1 },
161
+ nf: { mm: 7, dd: 1 },
162
+ ng: { mm: 1, dd: 1 },
163
+ ni: { mm: 1, dd: 1 },
164
+ nl: { mm: 1, dd: 1 },
165
+ no: { mm: 1, dd: 1 },
166
+ np: { mm: 7, dd: 16 },
167
+ nr: { mm: 7, dd: 1 },
168
+ nu: { mm: 4, dd: 1 },
169
+ nz: { mm: 4, dd: 1 },
170
+ om: { mm: 1, dd: 1 },
171
+ pa: { mm: 1, dd: 1 },
172
+ pe: { mm: 1, dd: 1 },
173
+ pf: { mm: 1, dd: 1 },
174
+ pg: { mm: 1, dd: 1 },
175
+ ph: { mm: 1, dd: 1 },
176
+ pk: { mm: 7, dd: 1 },
177
+ pl: { mm: 1, dd: 1 },
178
+ pm: { mm: 1, dd: 1 },
179
+ pn: { mm: 4, dd: 1 },
180
+ pr: { mm: 7, dd: 1 },
181
+ pt: { mm: 1, dd: 1 },
182
+ pw: { mm: 10, dd: 1 },
183
+ py: { mm: 1, dd: 1 },
184
+ qa: { mm: 4, dd: 1 },
185
+ ro: { mm: 1, dd: 1 },
186
+ ru: { mm: 1, dd: 1 },
187
+ rw: { mm: 1, dd: 1 },
188
+ sa: { mm: 1, dd: 1 },
189
+ sb: { mm: 1, dd: 1 },
190
+ sc: { mm: 1, dd: 1 },
191
+ sd: { mm: 1, dd: 1 },
192
+ se: { mm: 1, dd: 1 },
193
+ sg: { mm: 4, dd: 1 },
194
+ sh: { mm: 4, dd: 1 },
195
+ si: { mm: 1, dd: 1 },
196
+ sk: { mm: 1, dd: 1 },
197
+ sl: { mm: 1, dd: 1 },
198
+ sm: { mm: 1, dd: 1 },
199
+ sn: { mm: 1, dd: 1 },
200
+ so: { mm: 1, dd: 1 },
201
+ sr: { mm: 1, dd: 1 },
202
+ st: { mm: 1, dd: 1 },
203
+ sv: { mm: 1, dd: 1 },
204
+ sy: { mm: 1, dd: 1 },
205
+ sz: { mm: 4, dd: 1 },
206
+ tc: { mm: 1, dd: 1 },
207
+ td: { mm: 1, dd: 1 },
208
+ tg: { mm: 1, dd: 1 },
209
+ th: { mm: 10, dd: 1 },
210
+ tj: { mm: 1, dd: 1 },
211
+ tk: { mm: 4, dd: 1 },
212
+ tl: { mm: 1, dd: 1 },
213
+ tm: { mm: 1, dd: 1 },
214
+ tn: { mm: 1, dd: 1 },
215
+ to: { mm: 7, dd: 1 },
216
+ tr: { mm: 1, dd: 1 },
217
+ tt: { mm: 10, dd: 1 },
218
+ tv: { mm: 1, dd: 1 },
219
+ tw: { mm: 1, dd: 1 },
220
+ tz: { mm: 7, dd: 1 },
221
+ ua: { mm: 1, dd: 1 },
222
+ ug: { mm: 7, dd: 1 },
223
+ us: { mm: 10, dd: 1 },
224
+ uy: { mm: 1, dd: 1 },
225
+ uz: { mm: 1, dd: 1 },
226
+ va: { mm: 1, dd: 1 },
227
+ vc: { mm: 1, dd: 1 },
228
+ ve: { mm: 1, dd: 1 },
229
+ vg: { mm: 4, dd: 1 },
230
+ vi: { mm: 10, dd: 1 },
231
+ vn: { mm: 1, dd: 1 },
232
+ vu: { mm: 1, dd: 1 },
233
+ wf: { mm: 1, dd: 1 },
234
+ ws: { mm: 6, dd: 1 },
235
+ ye: { mm: 1, dd: 1 },
236
+ za: { mm: 4, dd: 1 },
237
+ zm: { mm: 1, dd: 1 },
238
+ zw: { mm: 1, dd: 1 }
239
+ }
240
+ end
241
+ end
242
+
243
+ end
@@ -0,0 +1,26 @@
1
+ module Fiscal
2
+
3
+ class Fiscal
4
+ def initialize(options = {})
5
+ @date = options[:date]
6
+ @country = options[:country]
7
+ end
8
+
9
+ def year(index = nil)
10
+ FiscalPeriod.new(date: @date, country: @country, type: :year, index: index)
11
+ end
12
+
13
+ def half_year(index = nil)
14
+ FiscalPeriod.new(date: @date, country: @country, type: :half_year, index: index)
15
+ end
16
+
17
+ def quarter(index = nil)
18
+ FiscalPeriod.new(date: @date, country: @country, type: :quarter, index: index)
19
+ end
20
+
21
+ def month(index = nil)
22
+ FiscalPeriod.new(date: @date, country: @country, type: :month, index: index)
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,135 @@
1
+ module Fiscal
2
+
3
+ class FiscalPeriod
4
+ include FiscalConfig
5
+
6
+ class FiscalError < StandardError; end
7
+
8
+ def initialize(options = {})
9
+
10
+ @type = (options[:type])
11
+ @date = (options[:date] || Date.today).to_date
12
+ @country = (options[:country] || :nil).to_sym
13
+
14
+ if options[:index]
15
+ # user input
16
+ @index = options[:index].to_i
17
+ elsif @type == :year
18
+ # only 1 year in a fiscal year
19
+ @index = 1
20
+ else
21
+ # if the user does not enter, compute the index
22
+ @index = number
23
+ end
24
+
25
+ validate
26
+ end
27
+
28
+ def validate
29
+ # date validation is handled by active support
30
+ # country
31
+ raise(FiscalError, "`#{@country}` is not a recognized country") unless self.config()[@country]
32
+ # index
33
+ valid_indexes = (1..(12 / months_in(type)))
34
+ raise(FiscalError, "`#{@index}` is not a valid index for `#{@type}`") unless valid_indexes.include?(@index)
35
+ end
36
+
37
+ def type
38
+ # return type, in case user decides to pass around the return object
39
+ @type
40
+ end
41
+
42
+ def start
43
+ # start date
44
+ start_date
45
+ end
46
+
47
+ def end
48
+ # find start date for next year, and minus one
49
+ start_date(next: true) - 1
50
+ end
51
+
52
+ def number
53
+ if @type == :year
54
+ # if year, return the year number
55
+ self.end.year
56
+ elsif @index
57
+ # if user input index, return it and save some computation
58
+ @index
59
+ else
60
+ # find the number of intervals from start of the year
61
+ start = start_date(type: :year)
62
+ ((months_between(start, @date).to_f) / months_in(@type)).ceil
63
+ end
64
+ end
65
+
66
+ def next
67
+ if @index == (12 / months_in(@type))
68
+ date = @date.change(year: @date.year + 1)
69
+ index = 1
70
+ else
71
+ date = @date
72
+ index = @index + 1
73
+ end
74
+ self.class.new(date: date, country: @country, type: @type, index: index)
75
+ end
76
+
77
+ def prev
78
+ if @index == 1
79
+ date = @date.change(year: @date.year - 1)
80
+ index = (12 / months_in(@type))
81
+ else
82
+ date = @date
83
+ index = @index - 1
84
+ end
85
+ self.class.new(date: date, country: @country, type: @type, index: index)
86
+ end
87
+
88
+ def to_i
89
+ number
90
+ end
91
+
92
+ def to_s
93
+ number.to_s
94
+ end
95
+
96
+ private
97
+ def start_month
98
+ self.config()[@country][:mm]
99
+ end
100
+
101
+ def start_day
102
+ self.config()[@country][:dd]
103
+ end
104
+
105
+ def months_between(from, to)
106
+ (to.month - from.month) + 12 * (to.year - from.year) + 1
107
+ end
108
+
109
+ def months_in(type)
110
+ {year: 12, half_year: 6, quarter: 3, month: 1}[type]
111
+ end
112
+
113
+ def start_date(options = {})
114
+ # get type from options, or default to instance variable
115
+ type = options[:type] || @type
116
+
117
+ # override index, especially if ye
118
+ index = (type == :year ? 1 : @index)
119
+
120
+ # modifier, 0 for current, 1 for next
121
+ i = options[:next] ? 0 : 1
122
+
123
+ # find the start year, if the fiscal year spans across multiple years
124
+ year = (@date.to_date - (start_month - 1).months).year
125
+
126
+ # months to offset, for half-year, quarter and month
127
+ add = (index - i) * (months_in(type))
128
+
129
+ # construct the start date
130
+ Date.new(year, start_month, start_day) + add.months
131
+ end
132
+
133
+ end
134
+
135
+ end
@@ -0,0 +1,3 @@
1
+ module Fiscal
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fiscal do
4
+
5
+ it "returns current calendar year start date as fiscal year start, by default" do
6
+ Date.fiscal.year.start.should eql(Date.today.beginning_of_year)
7
+ end
8
+
9
+ it "returns current calendar year end date as fiscal end start, by default" do
10
+ Date.fiscal.year.end.should eql(Date.today.end_of_year)
11
+ end
12
+
13
+ it "returns '2013-04-01' as fiscal year start date of India for the date '2013-10-10'" do
14
+ Date.fiscal(date: '2013-10-10', country: :in).year.start.should eql('2013-04-01'.to_date)
15
+ end
16
+
17
+ it "returns '2013-04-01' as fiscal year start date of India for the date '2014-01-10'" do
18
+ Date.fiscal(date: '2014-01-10', country: :in).year.start.should eql('2013-04-01'.to_date)
19
+ end
20
+
21
+ it "returns '2013-04-06' as fiscal year start date of Great Britain for the date '2014-01-10'" do
22
+ Date.fiscal(date: '2014-01-10', country: :gb).year.start.should eql('2013-04-06'.to_date)
23
+ end
24
+
25
+ it "returns '2014-10-01' as fiscal quarter start date of US for the date '2014-11-11'" do
26
+ Date.fiscal(date: '2014-11-11', country: :us).quarter.start.should eql('2014-10-01'.to_date)
27
+ end
28
+
29
+ it "returns '2014-10-01' as first fiscal quarter start date of US for the date '2015-08-25'" do
30
+ Date.fiscal(date: '2015-08-25', country: :us).quarter(1).start.should eql('2014-10-01'.to_date)
31
+ end
32
+
33
+ it "returns '2015-06-30' as first fiscal quarter end date of India for the date '2015-08-25'" do
34
+ Date.fiscal(date: '2015-08-25', country: :in).quarter(1).end.should eql('2015-06-30'.to_date)
35
+ end
36
+
37
+ it "returns '2015-04-30' as first fiscal month end date of India for the date '2015-08-25'" do
38
+ Date.fiscal(date: '2015-08-25', country: :in).month(1).end.should eql('2015-04-30'.to_date)
39
+ end
40
+
41
+ it "returns '2013-05-06' as second fiscal month start date of Great Britain for the date '2014-01-10'" do
42
+ Date.fiscal(date: '2014-01-10', country: :gb).month(2).start.should eql('2013-05-06'.to_date)
43
+ end
44
+
45
+ it "returns current calendar year start date as fiscal year start, for today" do
46
+ Date.today.fiscal.year.start.should eql(Date.today.beginning_of_year)
47
+ end
48
+
49
+ it "returns current calendar year start date as fourth quarter start of India, for today" do
50
+ Date.today.fiscal(country: :in).quarter(4).start.should eql(Date.today.beginning_of_year)
51
+ end
52
+
53
+ end
@@ -0,0 +1,8 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'fiscal'
5
+
6
+ RSpec.configure do |config|
7
+
8
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fiscal
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Geordee Naliyath
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
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: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
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
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: The "fiscal" gem helps to retrieve the fiscal year, half year, quarter
70
+ and month along with start and end dates for many countries.
71
+ email:
72
+ - geordee@gmail.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - fiscal.gemspec
84
+ - lib/fiscal.rb
85
+ - lib/fiscal/base.rb
86
+ - lib/fiscal/config.rb
87
+ - lib/fiscal/methods.rb
88
+ - lib/fiscal/period.rb
89
+ - lib/fiscal/version.rb
90
+ - spec/fiscal_spec.rb
91
+ - spec/spec_helper.rb
92
+ homepage: https://github.com/samyukti/fiscal
93
+ licenses:
94
+ - MIT
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.0.6
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: Get the fiscal period attributes for various countries
116
+ test_files:
117
+ - spec/fiscal_spec.rb
118
+ - spec/spec_helper.rb