fiscal_year 0.6.0 → 0.7.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 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