fiscal_year 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0917960fc403b45d283863bad77ac8e35fc8b5a3c216a13f1ca2cdb68c95410a'
4
- data.tar.gz: 68506d80a59973356f41d5bd1c55af3164542378ec8d9bea7d31be14bd90e302
3
+ metadata.gz: 9f35e4820f8a076879f9e461f172479e79899b71b71e4933fb8598b8c91b0dd7
4
+ data.tar.gz: 7616d720fff1de8d186b6809dfc2c465be1dfee8637808f3d8c490c15b253327
5
5
  SHA512:
6
- metadata.gz: 74e0c8c7ddff795d9c64754dde60b462073f45afd04892dcad3e1595970d1bc2a7ac4ebf3bc464ccc112f10bfe33393023bf008cf08b349c27839994a00c4199
7
- data.tar.gz: 50c1f1e00478c28ee72bc301ab8ab5fe42c1d142e822cc2d8747ff25f631ff62aff2e3e457e8bb852cde09676b38c0826057f8dedd503e5ad8ad2c3ad37a7e90
6
+ metadata.gz: 69d7ffc53eb33c6a65fabd20bd0b8757f40b71d11ce63a6a5754bb3af5312ad0641642a1701fc88820a7fd2764dfe29a140c045d0d524e4557d30304458c5ad5
7
+ data.tar.gz: d8c1ada946d9fd2e0ca21818e6885903fa99203a847c016759019828ca602ebf15cb03b8d94653c1801ff9a5c0ed942fa4c2afa224675563a875ad24fcf16e97
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.7.0] - 2024-07-11
2
+ - add YARD comment.
3
+ - fix `FiscalYear::YearToDate.quarter_range_by` logic.
4
+
1
5
  ## [0.6.0] - 2024-05-15
2
6
  - [BREAK] Ruby 3.0.x, 2.7.x and 2.6.x has no longer support.
3
7
  - add `FiscalYear.range_by` method
@@ -3,6 +3,7 @@
3
3
  module FiscalYear
4
4
  class Half
5
5
  class << self
6
+ # @return [Array<Integer>] the first half of the fiscal year.
6
7
  def first
7
8
  first = FiscalYear.halfs.first
8
9
  return first if first.is_a? Array
@@ -10,6 +11,7 @@ module FiscalYear
10
11
  []
11
12
  end
12
13
 
14
+ # @return [Array<Integer>] the second half of the fiscal year.
13
15
  def second
14
16
  second = FiscalYear.halfs.second
15
17
  return second if second.is_a? Array
@@ -17,14 +19,20 @@ module FiscalYear
17
19
  []
18
20
  end
19
21
 
22
+ # @param month [Integer] the month
23
+ # @return [Boolean] true if the month is in the first half of the fiscal year.
20
24
  def first?(month)
21
25
  FiscalYear.halfs.first.include?(month)
22
26
  end
23
27
 
28
+ # @param month [Integer] the month
29
+ # @return [Boolean] true if the month is in the second half of the fiscal year.
24
30
  def second?(month)
25
31
  !first?(month)
26
32
  end
27
33
 
34
+ # @param year [Integer] the calendar year
35
+ # @return [Range<Date>] the range of the first half of the fiscal year.
28
36
  def first_range_by(year)
29
37
  # care Date#parse 2 digit year auto complete.
30
38
  # 99 + 1 = 100, but expect 2000 this context.
@@ -37,6 +45,8 @@ module FiscalYear
37
45
  Date.parse("#{year}/#{first.first}/01")..Date.parse("#{end_year}/#{end_month}/01").end_of_month
38
46
  end
39
47
 
48
+ # @param year [Integer] the calendar year
49
+ # @return [Range<Date>] the range of the second half of the fiscal year.
40
50
  def second_range_by(year)
41
51
  # care Date#parse 2 digit year auto complete.
42
52
  # 99 + 1 = 100, but expect 2000 this context.
@@ -51,6 +61,8 @@ module FiscalYear
51
61
  Date.parse("#{start_year}/#{first_month}/01")..Date.parse("#{end_year}/#{end_month}/01").end_of_month
52
62
  end
53
63
 
64
+ # @param date [Date] the date
65
+ # @return [Range<Date>] the range of the half of the fiscal year by the date.
54
66
  def range_by(date)
55
67
  month = date.month
56
68
  year = date.year
@@ -60,6 +72,8 @@ module FiscalYear
60
72
  first?(month) ? first_range_by(year) : second_range_by(year)
61
73
  end
62
74
 
75
+ # @param half [Array<Integer>] the half of the fiscal year
76
+ # @return [Boolean] true if the any month of half are crossed calendar year.
63
77
  def cross_year_in_half?(half)
64
78
  FiscalYear.cross_year? && half.any? { |month| month == 12 }
65
79
  end
@@ -3,28 +3,49 @@
3
3
  module FiscalYear
4
4
  class Quarter
5
5
  class << self
6
+ # @!method first
7
+ # @return [Array<Integer>] the first quarter of the fiscal year.
8
+
9
+ # @!method second
10
+ # @return [Array<Integer>] the second quarter of the fiscal year.
11
+
12
+ # @!method third
13
+ # @return [Array<Integer>] the third quarter of the fiscal year.
14
+
15
+ # @!method fourth
16
+ # @return [Array<Integer>] the fourth quarter of the fiscal year.
6
17
  %i[first second third fourth].each do |method_name|
7
18
  define_method(method_name) do
8
19
  FiscalYear.quarters.public_send(method_name)
9
20
  end
10
21
  end
11
22
 
23
+ # @param month [Integer] the month
24
+ # @return [Boolean] true if the month is in the first quarter of the fiscal year.
12
25
  def first?(month)
13
26
  FiscalYear.quarters.first.include?(month)
14
27
  end
15
28
 
29
+ # @param month [Integer] the month
30
+ # @return [Boolean] true if the month is in the second quarter of the fiscal year.
16
31
  def second?(month)
17
32
  FiscalYear.quarters.second.include?(month)
18
33
  end
19
34
 
35
+ # @param month [Integer] the month
36
+ # @return [Boolean] true if the month is in the third quarter of the fiscal year.
20
37
  def third?(month)
21
38
  FiscalYear.quarters.third.include?(month)
22
39
  end
23
40
 
41
+ # @param month [Integer] the month
42
+ # @return [Boolean] true if the month is in the fourth quarter of the fiscal year.
24
43
  def fourth?(month)
25
44
  FiscalYear.quarters.fourth.include?(month)
26
45
  end
27
46
 
47
+ # @param month [Integer] the month
48
+ # @return [Array<Integer>] the quarter month by the month.
28
49
  def months(month)
29
50
  months = FiscalYear.quarters.find { |a| a.include?(month) }
30
51
  raise ::StandardError if months.nil?
@@ -32,6 +53,8 @@ module FiscalYear
32
53
  months
33
54
  end
34
55
 
56
+ # @param date [Date] the date
57
+ # @return [Range<Date>] the range of the quarter by the date.
35
58
  def range_by(date)
36
59
  year = date.year
37
60
  this_quarter = months(date.month)
@@ -40,12 +63,16 @@ module FiscalYear
40
63
  Date.parse("#{year}/#{this_quarter.first}/01")..Date.parse("#{last_year}/#{this_quarter.last}/01").end_of_month
41
64
  end
42
65
 
66
+ # @param month [Integer] the month
67
+ # @return [Integer] the quarter number by the month.
43
68
  def quarter_num(month)
44
69
  rindex = FiscalYear.quarters.rindex(months(month))
45
70
 
46
71
  rindex.nil? ? 0 : (rindex + 1)
47
72
  end
48
73
 
74
+ # @param quarter [Array<Integer>] the quarter
75
+ # @return [Boolean] true if the quarter is crossed calendar year.
49
76
  def cross_year_in_quarter?(quarter)
50
77
  FiscalYear.cross_year? && quarter.any? { |month| month == 12 }
51
78
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FiscalYear
4
- VERSION = "0.6.0"
4
+ VERSION = "0.7.0"
5
5
  end
@@ -3,6 +3,14 @@
3
3
  module FiscalYear
4
4
  class YearToDate
5
5
  class << self
6
+ # @param date [Date] the date
7
+ # @return [Range<Date>] the range of the year to date.
8
+ # @example
9
+ # FiscalYear::YearToDate.range_by(Date.parse("2021-08-01"))
10
+ # => Thu, 01 Apr 2021..Tue, 31 Aug 2021
11
+ #
12
+ # FiscalYear::YearToDate.range_by(Date.parse("2021-01-01"))
13
+ # => Wed, 01 Apr 2020..Sun, 31 Jan 2021
6
14
  def range_by(date)
7
15
  year = date.year
8
16
  month = date.month
@@ -14,45 +22,60 @@ module FiscalYear
14
22
  end
15
23
  end
16
24
 
17
- # TODO: fit to Abc size
18
- def year_month_pairs(date) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
25
+ # @param date [Date] the date
26
+ # @return [Array<Array<Integer>, Array<Integer>>] the passed year and month pairs.
27
+ # @example
28
+ # FiscalYear::YearToDate.year_month_pairs(Date.parse("2021-08-01"))
29
+ # => [[2021, 4], [2021, 5], [2021, 6], [2021, 7], [2021, 8]]
30
+ #
31
+ # FiscalYear::YearToDate.year_month_pairs(Date.parse("2021-01-01"))
32
+ # => [
33
+ # [2020, 4], [2020, 5], [2020, 6], [2020, 7], [2020, 8], [2020, 9],
34
+ # [2020, 10], [2020, 11], [2020, 12], [2021, 1]
35
+ # ]
36
+ def year_month_pairs(date)
19
37
  month = date.month
20
38
  month_index = FiscalYear.months.index(month)
21
39
  months = FiscalYear.months[(0..month_index)]
22
40
  raise StandardError if months.nil?
23
41
 
24
42
  [date.year].product(months).map do |e|
25
- if FiscalYear.cross_year_month?(month)
26
- (FiscalYear.cross_year_month?(e.second) ? e : [e.first - 1, e.second])
27
- else
28
- e
29
- end
43
+ [FiscalYear.decrease_year_by_month(e.first, e.second), e.second]
30
44
  end
31
45
  end
32
46
 
33
- # TODO: fit to Abc size
34
- def half_range_by(date) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
47
+ # @param date [Date] the date
48
+ # @return [Range<Date>] the range of the half year to date.
49
+ # @example
50
+ # FiscalYear::YearToDate.half_range_by(Date.parse("2021-08-01"))
51
+ # => Thu, 01 Apr 2021..Tue, 31 Aug 2021
52
+ #
53
+ # FiscalYear::YearToDate.half_range_by(Date.parse("2021-01-01"))
54
+ # => Thu, 01 Oct 2020..Sun, 31 Jan 2021
55
+ def half_range_by(date)
35
56
  year = date.year
36
57
  month = date.month
37
58
 
38
- if Half.first?(month)
39
- return (Date.parse("#{FiscalYear.cross_year_month?(month) ? year - 1 : year}/#{Half.first.first}/01")..
40
- date.end_of_month.to_date
41
- )
42
- end
59
+ beginning_year =
60
+ if Half.first?(month)
61
+ FiscalYear.cross_year_month?(month) ? year - 1 : year
62
+ else
63
+ Half.cross_year_in_half?(Half.second) ? FiscalYear.decrease_year_by_month(year, month) : year
64
+ end
65
+
66
+ half_method = Half.first?(month) ? :first : :second
43
67
 
44
- Date.parse(
45
- "#{
46
- if FiscalYear::Half.cross_year_in_half?(Half.second) &&
47
- FiscalYear.cross_year_month?(month)
48
- year - 1
49
- else
50
- year
51
- end
52
- }/#{Half.second.first}"
53
- )..date.end_of_month.to_date
68
+ Date.parse("#{beginning_year}/#{Half.public_send(half_method).first}/01")..date.end_of_month.to_date
54
69
  end
55
70
 
71
+ # @param date [Date] the date
72
+ # @return [Range<Date>] the range of the quarter to date.
73
+ # @example
74
+ # FiscalYear::YearToDate.quarter_range_by(Date.parse("2021-08-01"))
75
+ # => Thu, 01 Jul 2021..Tue, 31 Aug 2021
76
+ #
77
+ # FiscalYear::YearToDate.quarter_range_by(Date.parse("2021-01-01"))
78
+ # => Wed, 01 Jan 2020..Sun, 31 Jan 2021
56
79
  def quarter_range_by(date)
57
80
  year = date.year
58
81
  month = date.month
@@ -63,10 +86,10 @@ module FiscalYear
63
86
 
64
87
  quarter = Quarter.public_send(quarter_method)
65
88
 
66
- (
67
- Date.parse("#{FiscalYear.cross_year_month?(month) ? year - 1 : year}/#{quarter.first}/01")..
68
- date.end_of_month.to_date
69
- )
89
+ beginning_year =
90
+ Quarter.cross_year_in_quarter?(quarter) ? FiscalYear.decrease_year_by_month(year, month) : year
91
+
92
+ Date.parse("#{beginning_year}/#{quarter.first}/01")..date.end_of_month.to_date
70
93
  end
71
94
  end
72
95
  end
data/lib/fiscal_year.rb CHANGED
@@ -14,24 +14,40 @@ module FiscalYear
14
14
  # @type ivar @config: FiscalYear::Config
15
15
  @config ||= FiscalYear::Config.new
16
16
  class << self
17
+ # @return [FiscalYear::Config]
17
18
  attr_reader :config
18
19
 
20
+ # configure start month of fiscal year.
21
+ #
22
+ # @yieldparam config [FiscalYear::Config]
23
+ # @example
24
+ # FiscalYear.configure do |config|
25
+ # config.start_month = 6
26
+ # end
19
27
  def configure
20
28
  yield(@config) if block_given?
21
29
  end
22
30
 
31
+ # If the fiscal year start from 4, the month 1, 2, 3 are crossed year.
32
+ #
33
+ # @param month [Integer] the month to check, 1-12.
34
+ # @return [Boolean] true if the month is crossed year on calendar year.
35
+ # Determines if the month passed is beyond the year, By relative to the beginning month of the fiscal year.
23
36
  def cross_year_month?(month)
24
37
  cross_year_months.include?(month)
25
38
  end
26
39
 
40
+ # @return [Boolean] true if the fiscal year is crossed year.
27
41
  def cross_year?
28
42
  months.rindex(1) != 0
29
43
  end
30
44
 
45
+ # @return [Array<Integer>] the months of the fiscal year.
31
46
  def months
32
47
  (1..12).to_a.tap { |arr| arr.concat(arr.shift(@config.start_month - 1)) }
33
48
  end
34
49
 
50
+ # @return [Array<Integer>] the months of the crossed year.
35
51
  def cross_year_months
36
52
  return [] if @config.start_month == 1
37
53
 
@@ -43,16 +59,25 @@ module FiscalYear
43
59
  m
44
60
  end
45
61
 
62
+ # @return [Array(Array<Integer>, Array<Integer>)] the first half and the second half of the fiscal year.
46
63
  def halfs
47
64
  # @type self: singleton(FiscalYear)
48
65
  months.in_groups(2)
49
66
  end
50
67
 
68
+ # @return [Array(Array<Integer>, Array<Integer>, Array<Integer>, Array<Integer>)] the quarters of the fiscal year.
51
69
  def quarters
52
70
  # @type self: singleton(FiscalYear)
53
71
  months.in_groups(4)
54
72
  end
55
73
 
74
+ # increate the calendar year by month, if the month is crossed year.
75
+ #
76
+ # for example, in case of the fiscal year start from 4, you want to obtain calendar year of the month 1, 2, 3.
77
+ #
78
+ # @param year [Integer] the calendar year
79
+ # @param month [Integer] the month
80
+ # @return [Integer] year
56
81
  def increase_year_by_month(year, month)
57
82
  if FiscalYear.cross_year_month?(month)
58
83
  year + 1
@@ -61,6 +86,13 @@ module FiscalYear
61
86
  end
62
87
  end
63
88
 
89
+ # decrease the calendar year by month, if the month is crossed year.
90
+ #
91
+ # for example, in case of the fiscal year start from 4, you want to obtain fiscal year from the month 1, 2, 3.
92
+ #
93
+ # @param year [Integer] the calendar year
94
+ # @param month [Integer] the month
95
+ # @return [Integer] year
64
96
  def decrease_year_by_month(year, month)
65
97
  if FiscalYear.cross_year_month?(month)
66
98
  year - 1
@@ -69,6 +101,8 @@ module FiscalYear
69
101
  end
70
102
  end
71
103
 
104
+ # @param date [Date] the date
105
+ # @return [Range<Date>] the range of the fiscal year between beginning and end by the date.
72
106
  def range_by(date)
73
107
  year = date.year
74
108
  month = date.month
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fiscal_year
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tsubasa Kawajiri
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-15 00:00:00.000000000 Z
11
+ date: 2024-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport