activesupport-fiscal_dates 1.0.3
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/.gitignore +17 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +124 -0
- data/Rakefile +1 -0
- data/activesupport-fiscal_dates.gemspec +27 -0
- data/circle.yml +3 -0
- data/lib/active_support/fiscal_dates/date.rb +86 -0
- data/lib/active_support/fiscal_dates/version.rb +5 -0
- data/lib/activesupport-fiscal_dates.rb +4 -0
- data/spec/lib/active_support/fiscal_dates/date_spec.rb +205 -0
- data/spec/spec_helper.rb +1 -0
- data/year.rb +285 -0
- metadata +136 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: eabba22bd3da26b1255e5b036c01b549fa93eb97
|
4
|
+
data.tar.gz: d0cca4cff92a2715eaba5c78190ccf4e5a8883fc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c6b566649829d5be47bba83e6c1ea5f698ab66a25643e10d865f91b0ddab4e4a1898e6e2f6c78a76268af89aadaa3b0896d5993ea43e063adfc15a212bb32f62
|
7
|
+
data.tar.gz: de95233c91b1d1332a5ef25387173918d93e267e8ed48a76106b4335b0dbd3e6304fb7408404e52e6c460f098d618141bc98eb259976e965aca9488674da5b7e
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour --fail-fast --format documentation
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2016 Kinesis Pty Ltd
|
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,124 @@
|
|
1
|
+
[](https://circleci.com/gh/kinesisptyltd/activesupport-fiscal_dates)
|
2
|
+
|
3
|
+
# Activesupport::FiscalDates
|
4
|
+
|
5
|
+
Activesupport::FiscalDates adds some useful methods for fiscal year calculations to the `Date` class. Currently it only supports the Australian fiscal year period (July to June).
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'activesupport-fiscal_dates'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install activesupport-fiscal_dates
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
### Getting Fiscal Years and Ranges
|
24
|
+
|
25
|
+
Use `.current_fiscal_year` to get the current fiscal year as an integer. Returns `2015` for FY 2014-15.
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
# Today is September 10th, 2014
|
29
|
+
|
30
|
+
Date.current_fiscal_year
|
31
|
+
# => 2015
|
32
|
+
```
|
33
|
+
|
34
|
+
Or get the fiscal year range with `.current_fiscal_year_range`.
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
# Today is September 10th, 2014
|
38
|
+
|
39
|
+
Date.current_fiscal_year_range
|
40
|
+
# => Tue, 01 Jul 2014..Tue, 30 Jun 2015
|
41
|
+
```
|
42
|
+
|
43
|
+
Use `.fiscal_year_ranges_between` and `.calendar_year_ranges_between` to get an array of fiscal or calendar year ranges.
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
start_date = Date.new(2012)
|
47
|
+
end_date = Date.new(2014)
|
48
|
+
|
49
|
+
Date.fiscal_year_ranges_between(start_date, end_date)
|
50
|
+
|
51
|
+
# => [
|
52
|
+
# [0] Fri, 01 Jul 2011..Sat, 30 Jun 2012,
|
53
|
+
# [1] Sun, 01 Jul 2012..Sun, 30 Jun 2013,
|
54
|
+
# [2] Mon, 01 Jul 2013..Mon, 30 Jun 2014
|
55
|
+
# ]
|
56
|
+
|
57
|
+
Date.calendar_year_ranges_between(start_date, end_date)
|
58
|
+
|
59
|
+
# => [
|
60
|
+
# [0] Sun, 01 Jan 2012..Mon, 31 Dec 2012,
|
61
|
+
# [1] Tue, 01 Jan 2013..Tue, 31 Dec 2013,
|
62
|
+
# [2] Wed, 01 Jan 2014..Wed, 31 Dec 2014
|
63
|
+
# ]
|
64
|
+
```
|
65
|
+
|
66
|
+
Use `.fiscal_years_since` to create an array of arrays of the format `[label, value]` that's useful for `<select>` options. It includes the current fiscal year. The output style is set in `.fiscal_year_label`.
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
Date.fiscal_years_since(2012)
|
70
|
+
|
71
|
+
# => [
|
72
|
+
# [0] [
|
73
|
+
# [0] "2011-12",
|
74
|
+
# [1] "2012"
|
75
|
+
# ],
|
76
|
+
# [1] [
|
77
|
+
# [0] "2012-13",
|
78
|
+
# [1] "2013"
|
79
|
+
# ],
|
80
|
+
# [2] [
|
81
|
+
# [0] "2013-14",
|
82
|
+
# [1] "2014"
|
83
|
+
# ]
|
84
|
+
# [3] [
|
85
|
+
# [0] "2014-15",
|
86
|
+
# [1] "2015"
|
87
|
+
# ]
|
88
|
+
# ]
|
89
|
+
```
|
90
|
+
|
91
|
+
### Instance methods
|
92
|
+
|
93
|
+
Use `#fiscal_year` to get the specified date's fiscal year as an integer.
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
Date.new(2014, 7).fiscal_year
|
97
|
+
# => 2015
|
98
|
+
```
|
99
|
+
|
100
|
+
Use `#fiscal_year_first_day`, `#fiscal_year_last_day`, `#calendar_year_first_day` and `#calendar_year_last_day` to get those specific days.
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
Date.new(2014, 1).fiscal_year_first_day
|
104
|
+
# => Mon, 01 Jul 2013
|
105
|
+
|
106
|
+
Date.new(2014, 1).fiscal_year_last_day
|
107
|
+
# => Mon, 30 Jun 2014
|
108
|
+
|
109
|
+
Date.new(2014, 1).calendar_year_first_day
|
110
|
+
# => Wed, 01 Jan 2014
|
111
|
+
|
112
|
+
Date.new(2014, 1).calendar_year_last_day
|
113
|
+
# => Wed, 31 Dec 2014
|
114
|
+
```
|
115
|
+
|
116
|
+
And use `#fiscal_year_range` and `#calendar_year_range` to get the individual year as a range.
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
Date.new(2014, 1).fiscal_year_range
|
120
|
+
# => Mon, 01 Jul 2013..Mon, 30 Jun 2014
|
121
|
+
|
122
|
+
Date.new(2014, 1).calendar_year_range
|
123
|
+
# => Wed, 01 Jan 2014..Wed, 31 Dec 2014
|
124
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'active_support/fiscal_dates/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "activesupport-fiscal_dates"
|
8
|
+
spec.version = ActiveSupport::FiscalDates::VERSION
|
9
|
+
spec.authors = ["Kinesis Pty Ltd"]
|
10
|
+
spec.email = ["devs@kinesis.org"]
|
11
|
+
spec.summary = %q{Adds fiscal date support}
|
12
|
+
spec.description = %q{Adds fiscal date support to Date objects}
|
13
|
+
spec.homepage = "https://github.com/kinesisptyltd/activesupport-fiscal_dates"
|
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_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake", "~> 11"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.5"
|
24
|
+
spec.add_development_dependency "pry-byebug", "~> 3.4"
|
25
|
+
|
26
|
+
spec.add_dependency "activesupport", "~> 4.1", ">= 4.1.0"
|
27
|
+
end
|
data/circle.yml
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
class Date
|
2
|
+
def self.current_fiscal_year
|
3
|
+
# Returns "2015" for FY 2014-15
|
4
|
+
today = Date.today
|
5
|
+
today.month < 7 ? today.year : today.year + 1
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.current_fiscal_year_range
|
9
|
+
today = Date.today
|
10
|
+
if today.month < 7
|
11
|
+
Date.new(today.year - 1, 7)..Date.new(today.year, 6, 30)
|
12
|
+
else
|
13
|
+
Date.new(today.year, 7)..Date.new(today.year + 1, 6, 30)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.fiscal_year_ranges_between(start_date, end_date)
|
18
|
+
(start_date.fiscal_year_first_day.year..end_date.fiscal_year_first_day.year).map do |year|
|
19
|
+
Date.new(year, 7).fiscal_year_range
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.calendar_year_ranges_between(start_date, end_date)
|
24
|
+
(start_date.year..end_date.year).map { |year| Date.new(year).calendar_year_range }
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.fiscal_years_since(start_year)
|
28
|
+
# Includes the current fiscal year
|
29
|
+
# Output gets set in .fiscal_year_label
|
30
|
+
# Suitable for year select dropdowns in Corporate.
|
31
|
+
|
32
|
+
result = []
|
33
|
+
today = Date.today
|
34
|
+
current_year = today.year.to_i
|
35
|
+
month = today.month.to_i
|
36
|
+
end_year = month >= 7 ? current_year + 1 : current_year
|
37
|
+
|
38
|
+
(start_year..end_year).each do |year|
|
39
|
+
result << [fiscal_year_label(year), year.to_s]
|
40
|
+
end
|
41
|
+
|
42
|
+
result
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.fiscal_year_label(year)
|
46
|
+
# Output example: [["2012-13", "2013"], ["2013-14", "2014"]]
|
47
|
+
|
48
|
+
"#{year - 1}-#{year.to_s[-2, 2]}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def fiscal_year
|
52
|
+
self.month < 7 ? self.year : self.year + 1
|
53
|
+
end
|
54
|
+
|
55
|
+
def fiscal_year_first_day
|
56
|
+
if self.month < 7
|
57
|
+
Date.new(self.year - 1, 7)
|
58
|
+
else
|
59
|
+
Date.new(self.year, 7)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def fiscal_year_last_day
|
64
|
+
if self.month < 7
|
65
|
+
Date.new(self.year, 6).end_of_month
|
66
|
+
else
|
67
|
+
Date.new(self.year + 1, 6).end_of_month
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def fiscal_year_range
|
72
|
+
fiscal_year_first_day..fiscal_year_last_day
|
73
|
+
end
|
74
|
+
|
75
|
+
def calendar_year_first_day
|
76
|
+
Date.new(self.year)
|
77
|
+
end
|
78
|
+
|
79
|
+
def calendar_year_last_day
|
80
|
+
Date.new(self.year).end_of_year
|
81
|
+
end
|
82
|
+
|
83
|
+
def calendar_year_range
|
84
|
+
calendar_year_first_day..calendar_year_last_day
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "pry"
|
3
|
+
require "pry-byebug"
|
4
|
+
|
5
|
+
describe Date do
|
6
|
+
describe ".current_fiscal_year" do
|
7
|
+
context "before july" do
|
8
|
+
before { allow(Date).to receive(:today) { Date.new(2013, 1) } }
|
9
|
+
|
10
|
+
it "returns the correct fiscal year" do
|
11
|
+
expect(Date.current_fiscal_year).to eq 2013
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "after july" do
|
16
|
+
before { allow(Date).to receive(:today) { Date.new(2013, 8) } }
|
17
|
+
|
18
|
+
it "returns the correct fiscal year" do
|
19
|
+
expect(Date.current_fiscal_year).to eq 2014
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe ".current_fiscal_year_range" do
|
25
|
+
context "before july" do
|
26
|
+
before { allow(Date).to receive(:today) { Date.new(2013, 1) } }
|
27
|
+
|
28
|
+
it "returns the correct fiscal year range" do
|
29
|
+
expect(Date.current_fiscal_year_range).to eq Date.new(2012, 7)..Date.new(2013, 6, 30)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "after july" do
|
34
|
+
before { allow(Date).to receive(:today) { Date.new(2013, 8) } }
|
35
|
+
|
36
|
+
it "returns the correct fiscal year" do
|
37
|
+
expect(Date.current_fiscal_year_range).to eq Date.new(2013, 7)..Date.new(2014, 6, 30)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe ".fiscal_year_ranges_between" do
|
43
|
+
let(:start_date) { Date.new(2012, 1) }
|
44
|
+
let(:end_date) { Date.new(2014, 8) }
|
45
|
+
|
46
|
+
it "returns an array" do
|
47
|
+
expect(Date.fiscal_year_ranges_between(start_date, end_date)).to be_an Array
|
48
|
+
end
|
49
|
+
|
50
|
+
it "returns the correct number of elements" do
|
51
|
+
expect(Date.fiscal_year_ranges_between(start_date, end_date).length).to eq 4
|
52
|
+
end
|
53
|
+
|
54
|
+
it "contains ranges" do
|
55
|
+
expect(Date.fiscal_year_ranges_between(start_date, end_date).first).to be_a Range
|
56
|
+
end
|
57
|
+
|
58
|
+
it "contains ranges with the correct dates" do
|
59
|
+
expect(Date.fiscal_year_ranges_between(start_date, end_date).first).to eq Date.new(2011, 7)..Date.new(2012, 6 ,30)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe ".calendar_year_ranges_between" do
|
64
|
+
let(:start_date) { Date.new(2012, 1) }
|
65
|
+
let(:end_date) { Date.new(2014, 8) }
|
66
|
+
|
67
|
+
it "returns an array" do
|
68
|
+
expect(Date.calendar_year_ranges_between(start_date, end_date)).to be_an Array
|
69
|
+
end
|
70
|
+
|
71
|
+
it "returns the correct number of elements" do
|
72
|
+
expect(Date.calendar_year_ranges_between(start_date, end_date).length).to eq 3
|
73
|
+
end
|
74
|
+
|
75
|
+
it "contains ranges" do
|
76
|
+
expect(Date.calendar_year_ranges_between(start_date, end_date).first).to be_a Range
|
77
|
+
end
|
78
|
+
|
79
|
+
it "contains ranges with the correct dates" do
|
80
|
+
expect(Date.calendar_year_ranges_between(start_date, end_date).first).to eq Date.new(2012, 1)..Date.new(2012, 12, 31)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe ".fiscal_years_since" do
|
85
|
+
let(:start_year) { 2012 }
|
86
|
+
|
87
|
+
before { allow(Date).to receive(:today) { Date.new(2014, 1) } }
|
88
|
+
|
89
|
+
it "returns an array" do
|
90
|
+
expect(Date.fiscal_years_since(start_year)).to be_an Array
|
91
|
+
end
|
92
|
+
|
93
|
+
it "contains the right number of years" do
|
94
|
+
expect(Date.fiscal_years_since(start_year).length).to eq 3
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe ".fiscal_year_label" do
|
99
|
+
context "year is 2008" do
|
100
|
+
it "correctly formats the years" do
|
101
|
+
expect(Date.fiscal_year_label(2008)).to eq "2007-08"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "year is 2011" do
|
106
|
+
it "correctly formats the years" do
|
107
|
+
expect(Date.fiscal_year_label(2011)).to eq "2010-11"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#fiscal_year" do
|
113
|
+
context "before july" do
|
114
|
+
let(:date) { Date.new(2013, 01) }
|
115
|
+
|
116
|
+
it "returns the correct fiscal year" do
|
117
|
+
expect(date.fiscal_year).to eq date.year
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "after july" do
|
122
|
+
let(:date) { Date.new(2013, 8) }
|
123
|
+
|
124
|
+
it "returns the correct fiscal year" do
|
125
|
+
expect(date.fiscal_year).to eq date.year + 1
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "#fiscal_year_first_day" do
|
131
|
+
context "before july" do
|
132
|
+
let(:date) { Date.new(2013, 01) }
|
133
|
+
|
134
|
+
it "returns the correct date" do
|
135
|
+
expect(date.fiscal_year_first_day).to eq Date.new(2012, 7)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "after july" do
|
140
|
+
let(:date) { Date.new(2013, 8) }
|
141
|
+
|
142
|
+
it "returns the correct date" do
|
143
|
+
expect(date.fiscal_year_first_day).to eq Date.new(2013, 7)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "#fiscal_year_last_day" do
|
149
|
+
context "before july" do
|
150
|
+
let(:date) { Date.new(2013, 01) }
|
151
|
+
|
152
|
+
it "returns the correct date" do
|
153
|
+
expect(date.fiscal_year_last_day).to eq Date.new(2013, 6, 30)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context "after july" do
|
158
|
+
let(:date) { Date.new(2013, 8) }
|
159
|
+
|
160
|
+
it "returns the correct date" do
|
161
|
+
expect(date.fiscal_year_last_day).to eq Date.new(2014, 6, 30)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "#fiscal_year_range" do
|
167
|
+
let(:date) { Date.new(2013, 01) }
|
168
|
+
|
169
|
+
it "returns a range" do
|
170
|
+
expect(date.fiscal_year_range).to be_a Range
|
171
|
+
end
|
172
|
+
|
173
|
+
it "returns the correct dates" do
|
174
|
+
expect(date.fiscal_year_range).to eq Date.new(2012, 7)..Date.new(2013, 6, 30)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "#calendar_year_first_day" do
|
179
|
+
let(:date) { Date.new(2013, 8) }
|
180
|
+
|
181
|
+
it "returns the correct date" do
|
182
|
+
expect(date.calendar_year_first_day).to eq Date.new(2013, 1, 1)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "#calendar_year_last_day" do
|
187
|
+
let(:date) { Date.new(2013, 8) }
|
188
|
+
|
189
|
+
it "returns the correct date" do
|
190
|
+
expect(date.calendar_year_last_day).to eq Date.new(2013, 12, 31)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "#calendar_year_range" do
|
195
|
+
let(:date) { Date.new(2013, 8) }
|
196
|
+
|
197
|
+
it "returns a range" do
|
198
|
+
expect(date.calendar_year_range).to be_a Range
|
199
|
+
end
|
200
|
+
|
201
|
+
it "returns the correct dates" do
|
202
|
+
expect(date.calendar_year_range).to eq Date.new(2013, 1)..Date.new(2013, 12, 31)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "activesupport-fiscal_dates"
|
data/year.rb
ADDED
@@ -0,0 +1,285 @@
|
|
1
|
+
class Year
|
2
|
+
NUMBER_OF_WEEKDAYS = 250
|
3
|
+
NUMBER_OF_SATURDAYS = 52
|
4
|
+
NUMBER_OF_SUNDAYS = 51
|
5
|
+
NUMBER_OF_PUBLIC_HOLIDAYS = 12
|
6
|
+
|
7
|
+
# TODO loookup public holidays by region and year.
|
8
|
+
|
9
|
+
START_YEAR = 2003
|
10
|
+
|
11
|
+
# Returns an array of [month, year] which represents a financial reporting
|
12
|
+
# year. month and year are numerical
|
13
|
+
def self.financial_months(starting_year)
|
14
|
+
result = []
|
15
|
+
7.upto(12) {|n| result << [n, starting_year]}
|
16
|
+
1.upto(6) {|n| result << [n, starting_year + 1]}
|
17
|
+
result
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns true if today's date is past the end of the given financial year.
|
21
|
+
def self.incomplete_financial_year(year)
|
22
|
+
Date.today < financial_year_end_date(year)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.financial_months_menu_options(starting_year)
|
26
|
+
result = ActiveSupport::OrderedHash.new
|
27
|
+
7.upto(12) {|n| result["#{Date::MONTHNAMES[n]} #{starting_year}"] = "#{n},#{starting_year}"}
|
28
|
+
1.upto(6) {|n| result["#{Date::MONTHNAMES[n]} #{starting_year + 1}"] = "#{n},#{starting_year + 1}"}
|
29
|
+
result
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.financial_months_menu_values(starting_year)
|
33
|
+
result = []
|
34
|
+
7.upto(12) {|n| result << "#{n},#{starting_year}"}
|
35
|
+
1.upto(6) {|n| result << "#{n},#{starting_year + 1}"}
|
36
|
+
result
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.financial_months_menu_labels(starting_year)
|
40
|
+
result = []
|
41
|
+
7.upto(12) {|n| result << "#{n} #{starting_year}"}
|
42
|
+
1.upto(6) {|n| result << "#{n} #{starting_year + 1}"}
|
43
|
+
result
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns an array of [month, year] counting back from the given month, year,
|
47
|
+
# by the given num_prior
|
48
|
+
def self.months_prior(year, month, num_prior)
|
49
|
+
count = num_prior.to_i
|
50
|
+
y = year.to_i
|
51
|
+
m = month.to_i
|
52
|
+
result = []
|
53
|
+
while count > 0
|
54
|
+
result << [m, y]
|
55
|
+
if m == 1
|
56
|
+
y -= 1
|
57
|
+
m = 12
|
58
|
+
else
|
59
|
+
m -= 1
|
60
|
+
end
|
61
|
+
count -= 1
|
62
|
+
end
|
63
|
+
return result
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns an array of [month, year] counting forward from the given month,
|
67
|
+
# year, by the given num_prior
|
68
|
+
def self.months_ahead(year, month, num_ahead)
|
69
|
+
count = num_ahead.to_i
|
70
|
+
y = year.to_i
|
71
|
+
m = month.to_i
|
72
|
+
result = []
|
73
|
+
while count > 0
|
74
|
+
result << [m, y]
|
75
|
+
if m == 12
|
76
|
+
y += 1
|
77
|
+
m = 1
|
78
|
+
else
|
79
|
+
m += 1
|
80
|
+
end
|
81
|
+
count -= 1
|
82
|
+
end
|
83
|
+
return result
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.natural_year_months(year)
|
87
|
+
result = Array.new
|
88
|
+
for month in 1..12
|
89
|
+
result << [month, year]
|
90
|
+
end
|
91
|
+
result
|
92
|
+
end
|
93
|
+
|
94
|
+
# Returns an array of [year, month] starting from start_date and counting to
|
95
|
+
# end_date
|
96
|
+
def self.months_between(start_date, end_date)
|
97
|
+
if start_date && end_date
|
98
|
+
cur_year = start_date.year
|
99
|
+
cur_month = start_date.month
|
100
|
+
result = [[cur_month, cur_year]]
|
101
|
+
while cur_year < end_date.year || cur_month < end_date.month
|
102
|
+
if cur_month >= 12
|
103
|
+
cur_month = 0
|
104
|
+
cur_year += 1
|
105
|
+
end
|
106
|
+
cur_month += 1
|
107
|
+
result << [cur_month, cur_year]
|
108
|
+
end
|
109
|
+
result
|
110
|
+
else
|
111
|
+
[]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Returns an array of ranges for start_date =>
|
116
|
+
# month_start_date..month_end_date
|
117
|
+
def self.financial_year_month_ranges(starting_year)
|
118
|
+
result = Array.new
|
119
|
+
financial_months(starting_year).each {|m|
|
120
|
+
result << month_range(m[1], m[0])
|
121
|
+
}
|
122
|
+
result
|
123
|
+
end
|
124
|
+
|
125
|
+
#Return the first_day_of_month for each month of the financial year of starting_year
|
126
|
+
def self.financial_year_start_months(starting_year)
|
127
|
+
result = Array.new
|
128
|
+
financial_months(starting_year).each {|m|
|
129
|
+
result << Date.new(m[1],m[0], 01)
|
130
|
+
}
|
131
|
+
result
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.last_day_of_month(year, month)
|
135
|
+
last_date_of_month(year.to_i, month.to_i).day
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.last_date_of_month(year, month)
|
139
|
+
d = Date.new(year.to_i, month.to_i, -1)
|
140
|
+
d
|
141
|
+
end
|
142
|
+
|
143
|
+
# Returns a range from the first day to the last day of the month.
|
144
|
+
def self.month_range(year, month)
|
145
|
+
last_day = last_date_of_month(year, month)
|
146
|
+
Range.new(Date.new(year.to_i, month.to_i, 1), last_day)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Returns a range from the first day to the last day of the previous month
|
150
|
+
def self.previous_month_range(year,month)
|
151
|
+
y = month == 1 ? year - 1 : year
|
152
|
+
m = month == 1 ? 12 : month - 1
|
153
|
+
month_range(y,m)
|
154
|
+
end
|
155
|
+
|
156
|
+
# Returns a range from the first day to the last day of the next month
|
157
|
+
def self.next_month_range(year,month)
|
158
|
+
y = month == 12 ? year + 1 : year
|
159
|
+
m = month == 12 ? 1 : month + 1
|
160
|
+
month_range(y,m)
|
161
|
+
end
|
162
|
+
|
163
|
+
# Returns a hash with :first_day_of_month => (<first day of month>..<end of
|
164
|
+
# month>)
|
165
|
+
def self.month_range_condition(year, month)
|
166
|
+
{:first_day_of_month => month_range(year, month)}
|
167
|
+
end
|
168
|
+
|
169
|
+
# returns an array with a start and end date for the given australian
|
170
|
+
# financial year.
|
171
|
+
def self.financial_year_dates(year)
|
172
|
+
[financial_year_start_date(year), financial_year_end_date(year)]
|
173
|
+
end
|
174
|
+
|
175
|
+
def self.financial_year_range(starting_year)
|
176
|
+
fyr = financial_year_dates(starting_year)
|
177
|
+
Range.new(fyr[0], fyr[1])
|
178
|
+
end
|
179
|
+
|
180
|
+
def self.financial_years_range(starting_year, finishing_year)
|
181
|
+
Range.new(financial_year_start_date(starting_year), financial_year_end_date(finishing_year))
|
182
|
+
end
|
183
|
+
|
184
|
+
def self.financial_year_start_date(year)
|
185
|
+
if year.is_a? Date
|
186
|
+
year = if year.month >= 7
|
187
|
+
year.year
|
188
|
+
else
|
189
|
+
year.year - 1
|
190
|
+
end
|
191
|
+
end
|
192
|
+
Date.new(year.to_i, 7, 1)
|
193
|
+
end
|
194
|
+
|
195
|
+
def self.financial_year_end_date(year)
|
196
|
+
if year.is_a? Date
|
197
|
+
year = if year.month >= 7
|
198
|
+
year.year
|
199
|
+
else
|
200
|
+
year.year - 1
|
201
|
+
end
|
202
|
+
end
|
203
|
+
Date.new(year.to_i + 1, 6, 30)
|
204
|
+
end
|
205
|
+
|
206
|
+
def self.natural_year_dates(year)
|
207
|
+
[Date.new(year.to_i, 1, 1), Date.new(year.to_i, 12, 31)]
|
208
|
+
end
|
209
|
+
|
210
|
+
def self.natural_year_range(year)
|
211
|
+
nyr = natural_year_dates(year)
|
212
|
+
Range.new(nyr[0], nyr[1])
|
213
|
+
end
|
214
|
+
|
215
|
+
def self.year_range(year, financial = true)
|
216
|
+
return Year.financial_year_range(year) if financial
|
217
|
+
Year.natural_year_range(year)
|
218
|
+
end
|
219
|
+
|
220
|
+
def self.year_conditions(year, financial = true)
|
221
|
+
return Year.financial_year_conditions(year) if financial
|
222
|
+
Year.natural_year_conditions(year)
|
223
|
+
end
|
224
|
+
|
225
|
+
def self.natural_year_conditions(year)
|
226
|
+
{:start_date => natural_year_range(year)}
|
227
|
+
end
|
228
|
+
|
229
|
+
def self.financial_year_conditions(starting_year)
|
230
|
+
{:start_date => financial_year_range(starting_year)}
|
231
|
+
end
|
232
|
+
|
233
|
+
def self.useable_natural_years(start_year = START_YEAR)
|
234
|
+
result = Array.new
|
235
|
+
(start_year..DateTime.now.year).each {|y| result << y}
|
236
|
+
result
|
237
|
+
end
|
238
|
+
|
239
|
+
def self.useable_financial_years(start_year = START_YEAR)
|
240
|
+
result = Array.new
|
241
|
+
now = DateTime.now
|
242
|
+
y = now.year.to_i
|
243
|
+
m = now.month.to_i
|
244
|
+
c = y - 1
|
245
|
+
c = y if m >= 7
|
246
|
+
(start_year..c).each {|y| result << [financial_year_label(y), y.to_s]}
|
247
|
+
result
|
248
|
+
end
|
249
|
+
|
250
|
+
def self.financial_year_label(starting_year)
|
251
|
+
next_year = (starting_year.to_i + 1).to_s[-1,1]
|
252
|
+
next_year = (starting_year.to_i + 1).to_s[-2,2] if (starting_year.to_i + 1).to_s[-2,2].to_i > 9
|
253
|
+
"#{starting_year}-#{next_year}"
|
254
|
+
end
|
255
|
+
|
256
|
+
def self.in_financial_year?(date, starting_year)
|
257
|
+
financial_year_range(starting_year).include?(date)
|
258
|
+
end
|
259
|
+
|
260
|
+
def self.financial_year_of(date)
|
261
|
+
year = date.year
|
262
|
+
month = date.month
|
263
|
+
return year - 1 if month < 7
|
264
|
+
year
|
265
|
+
end
|
266
|
+
|
267
|
+
def self.natural_years_range(starting_year, finishing_year)
|
268
|
+
Range.new(Date.new(starting_year, 01, 01), last_date_of_month(finishing_year,12))
|
269
|
+
end
|
270
|
+
|
271
|
+
def self.financial_year_first_label(date)
|
272
|
+
year = date.year
|
273
|
+
if date.month > 6
|
274
|
+
year
|
275
|
+
else
|
276
|
+
year - 1
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def self.current_financial_year
|
281
|
+
current_year = Date.today.year
|
282
|
+
month = Date.today.month
|
283
|
+
month >= 7 ? current_year : current_year - 1
|
284
|
+
end
|
285
|
+
end
|
metadata
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: activesupport-fiscal_dates
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kinesis Pty Ltd
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '11'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '11'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.5'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry-byebug
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.4'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.4'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: activesupport
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4.1'
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 4.1.0
|
79
|
+
type: :runtime
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - "~>"
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '4.1'
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 4.1.0
|
89
|
+
description: Adds fiscal date support to Date objects
|
90
|
+
email:
|
91
|
+
- devs@kinesis.org
|
92
|
+
executables: []
|
93
|
+
extensions: []
|
94
|
+
extra_rdoc_files: []
|
95
|
+
files:
|
96
|
+
- ".gitignore"
|
97
|
+
- ".rspec"
|
98
|
+
- Gemfile
|
99
|
+
- LICENSE.txt
|
100
|
+
- README.md
|
101
|
+
- Rakefile
|
102
|
+
- activesupport-fiscal_dates.gemspec
|
103
|
+
- circle.yml
|
104
|
+
- lib/active_support/fiscal_dates/date.rb
|
105
|
+
- lib/active_support/fiscal_dates/version.rb
|
106
|
+
- lib/activesupport-fiscal_dates.rb
|
107
|
+
- spec/lib/active_support/fiscal_dates/date_spec.rb
|
108
|
+
- spec/spec_helper.rb
|
109
|
+
- year.rb
|
110
|
+
homepage: https://github.com/kinesisptyltd/activesupport-fiscal_dates
|
111
|
+
licenses:
|
112
|
+
- MIT
|
113
|
+
metadata: {}
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubyforge_project:
|
130
|
+
rubygems_version: 2.4.5.1
|
131
|
+
signing_key:
|
132
|
+
specification_version: 4
|
133
|
+
summary: Adds fiscal date support
|
134
|
+
test_files:
|
135
|
+
- spec/lib/active_support/fiscal_dates/date_spec.rb
|
136
|
+
- spec/spec_helper.rb
|