【開発ログ⑩】Railsで法定付与日と勤続年数を計算したよ

# 前提について
はじめまして、 プログラミングスクールに通ういりふねと申します。この記事は、スクールの課題である個人アプリの開発の記録を書くことで、自身のアウトプットに利用しています。もし、読んでいただけた方がいましたら、フィードバックをしていただけたら嬉しいです。

開発するのは「有給休暇管理ツール」です。仕様は[過去記事](https://qiita.com/iczo32/items/97ad7d4baa985b3b99ca)をどうぞ。

アプリはデプロイまで行いますが、サービスとして提供するものではありません。あくまでも自学習の一環ですので、ご理解下さい。では本題へどうぞ。

# 今回の実施内容
前回までで、社員登録の実装が完了しました。社員登録時に「入社日（カラム名は、hire_date）」を入力してもらいます。そこで、この入社日を使用して、法定付与日と勤続年数を計算させます。具体的には以下の手順で進めます。今回は書くこと少なめ。

- 法定付与日の計算方法を確認
- 法定付与日の実装
- 勤続年数の計算方法を確認
- 勤続年数の実装

# 法定付与日の「とは？」と「計算方法」
大見出しを使用するほどではないのですが、法定付与日について確認しておきます。法定付与日は、毎年有給休暇が付与される日のことです。これは、入社日から６ヵ月後となります。詳細は厚生労働省のページ等で確認できますが、あまりここでは関係ないので省きます。

2019年04月01日に入社した人は、毎年10月01日が法定付与日。
2019年01月30日に入社した人は、毎年07月30日が法定付与日。
つまり、入社日に６ヵ月を足し算すれば法定付与日は求められるわけです。

もちろん、会社が作成する就業規則によって法定付与日は、変更されている場合があります。一律、4月1日と定めているところもあるようです。今回は、基本的にこの考え方で進めます。

# 法定付与日の実装
日付計算に際しては、[こちらの記事](https://www.javadrive.jp/ruby/date_class/index4.html)を参考にさせていただきました。今回は、ルーティングとコントローラーの編集は行わないので、モデルとビューを掲載します。
モデルには、入社日（hire_date）に「 >> 6 」を記述して、月数に6を足す計算メソッドcalculate_grant_dateを定義しました。

```ruby:models/employee.rb
class Employee < ApplicationRecord
〜中略〜
  def calculate_grant_date
    grant_day = hire_date >> 6
    grant_day.strftime("%m/%d")
  end
end

```

モデルファイルに定義したcalculate_grant_dateをeach文の変数employeeに対して実行しています。これでOKでした。

```haml:branches/_main.html.haml
.main
  =render 'branches/mainheader'
〜中略〜
        - @employees.each do |employee|
          %tr　
〜中略〜
            %th{id: "short"}
              = employee.calculate_grant_date
〜以下省略〜
```

# 勤続年数の計算方法
今回、勤続年数は「何年何ヵ月」という表示をさせたいと考えています。大まかな考え方としては、現在の日付(rubyでは、Date.todayで表示)から、入社日（hire_date）を引き算すれば求められます。

仮に今日の日付が「2020年05月」で、入社日が「2019年3月」とするならば、「1年2ヵ月」と表示させることができればよいということになります。年と月をバラバラにとりだして、それぞれ引き算すれば良さそうです。具体的には以下のとおりです。

●勤務年数の計算●
　今日の年「2020」　-　入社の年「2019」　=　1年
　今日の月「05」　-　入社の月「03」　=　2ヵ月
　計算結果を合体させて「１年2ヵ月」となります。これならイケそう！！

計算がヘンテコになるパターンもありました。今日の日付が「2020年05月」で、入社日が「2015年08月」であれば、「4年9ヵ月」にならなければいけませんが、先程の計算を適用するとこうなります。

●ヘンテコになる勤務年数の計算●
　今日の年「2020」　-　入社の年「2015」　=　5年
　今日の月「05」　-　入社の月「08」　=　-3ヵ月
　計算結果を合体させて「5年-3ヵ月」となります。っておい！！！！

つまり、月の計算結果がマイナスになるときは、下のように年の計算結果に「-1」を月の計算結果に「+12」を足せば正しい勤続年数が算出されるというわけです。

●勤務年数の計算●
　今日の年「2020」　-　入社の年「2015」　-1　=　4年
　今日の月「05」　-　入社の月「08」　+12　=　9ヵ月
　計算結果を合体させて「4年9ヵ月」となります。できました!!

ちなみに月の計算結果が、０のときはどうでしょうか？今日の日付が「2020年05月」で、入社日が「2015年05月」とであれば、「5年0ヵ月」になります。

●勤務年数の計算●
　今日の年「2020」　-　入社の年「2015」　=　5年
　今日の月「05」　-　入社の月「05」　=　0ヵ月
　計算結果を合体させて「5年0ヵ月」となります。こっちは問題なさそう。

# 勤続年数の実装
前置きが長くなりましたが、実装します。今回もモデルとビューのみの編集になります。
同じくモデルに勤続年数を計算させる「calculate_year_of_service」メソッドを定義します。
先程の計算結果から、月の計算結果が「０以上」か「0未満」かで条件分岐をさせています。「0以上」ならそのまま年と月の引き算を行い、それ以外（月の計算結果がマイナスになった場合）は、計算結果の最後に年に「-1」を月に「+12」を付け加えればOK！！

```ruby:model/employee.rb
class Employee < ApplicationRecord
〜中略〜
  def calculate_year_of_service
    if Date.today.month - hire_date.month >= 0
      year = Date.today.year - hire_date.year
      month = Date.today.month - hire_date.month
    else
      year = Date.today.year - hire_date.year - 1
      month = Date.today.month - hire_date.month + 12
    end
    "#{year}年#{month}ヵ月"
  end
end
```

★2020/5/17編集
　上の 「employee.rb」の４行目を書き直しました。もともと比較演算子を「>」とだけ記入していたので、ちょうど１年勤務している方の場合、「０年１２ヵ月」と出たためです。よって比較演算子を「>=」に直しました。



```haml:branches/_main.html.haml
.main
  =render 'branches/mainheader'
〜中略〜
        - @employees.each do |employee|
〜中略〜
            %th{id: "short"}
              = employee.calculate_year_of_service
〜以下省略〜
```

# ビューの確認
無事に実装できました。ビュー確認時点は、2020年05月です。
<img width="664" alt="スクリーンショット 2020-05-13 23.55.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614723/f5d62df4-2d29-fe52-1bec-1015659e49b8.png">

# 今日の積み上げ
計算系のメソッドを作るときは、紙に手書きで計算を書いてから論理を組み立てることが大切だと感じました。この記事も計算式と説明している内容が合っているかドキドキしながら書きました〜。
あと、数字を際立たせるために文中に「カギカッコ」を使いすぎ。。。