railsでHR領域やバックオフィス関連の新サービスを作ろうと思ったら役立つかもしれないgem8選

タイトルが対象を絞りすぎててもはや誰にも見てもらえてない疑惑もありますが。。

MoneyForwardでは、【MFクラウド】というサービス名で、会計・請求書・消し込み・決済・給与・マイナンバー・経費、といった、バックオフィス業務を最適化するサービスを運営しています。

バックオフィス業務は日本固有の法律に対応する必要があり、法律由来の一般的ではないロジックへの対応を求められる事がよくあります。

今回はそんなHR領域やバックオフィス関連のサービス開発に、もしかしたら役立つかもしれないgemをご紹介します。

# era_ja
[tomiacannondale/era_ja](https://github.com/tomiacannondale/era_ja)

和暦を扱うgemです。
給与や会計サービスなどで提出帳票などを印字する際には必須となるgemです。

使い方はREADMEを読んでもらった方が早いですが、DateやTimeに和暦変換の `to_era` methodが生えます

```rb
require 'era_ja'
Time.mktime(2012,4,29).to_era   # => "H24.4.29"
Time.mktime(2012,4,29).to_era("%O%E年%m月%d日") # => "平成24年4月29日"
Time.mktime(2012,4,29).to_era("%O%JE年%Jm月%Jd日") # => "平成二十四年四月二十九日"
```

[Rails - 和暦を手軽に扱いたい - Qiita](http://qiita.com/snoozer05/items/9b8881b09696ece05f77)
[era_jaというgemを公開しました - tomiの日記](http://tomiacannondale.hatenablog.com/entry/20120616/1339861620)

# holiday_jp
[komagata/holiday_jp](https://github.com/komagata/holiday_jp)

holiday_jpは、日本固有の祝日に関するgemです。
同等のgemに、 
[holidays/holidays](https://github.com/holidays/holidays)
があるので、お好みの方を使うとよいと思います

また、後述する
[bokmann/business_time](https://github.com/bokmann/business_time)
と組み合わせる事で、会社の就業管理系のシステムを作る際には便利になります。

勤怠システムなどを作る場合も良いのではないでしょうか。

# business_time
[bokmann/business_time](https://github.com/bokmann/business_time)

business_timeは、就業時間を扱うgemです。

こちらに関しては一度紹介の記事を書いた事があります。
[[ruby] 祝日判断や休日判断をrubyでやるなら、これでいいんじゃないかな - メモ - Qiita](http://qiita.com/ryoff/items/02b00ffc121037c25e16)

- 就業時間の設定
- 会社独自の休暇設定
- 翌営業日の取得
- 期間内の営業日数

など、一般的に思いつく就業時間に関する処理は、おおむねカバーしているかと思います。

```rb
[4] pry(#<Date>):1> Date.new(2015,1,2).workday?
=> true
[5] pry(#<Date>):1> Date.today.workday?
=> true
[6] pry(#<Date>):1> Date.today.weekday?
=> true
[7] pry(#<Date>):1> Date.today.monday?
=> true

# 特定の日付までの営業日を計算
[8] pry(#<Date>):1> Date.today.business_days_until(1.month.since)
=> 21
```

# kiji
[kufu/kiji](https://github.com/kufu/kiji)

こちらは、 [株式会社KUFU](http://kufuinc.com/) さんが作られている e-Gov APIの連携gemです。
今年のTechCrunch Tokyo2015で最優秀賞を受賞したので、ご存知の方も多いかと思います。
[【お知らせ】TechCrunch Tokyo 2015 で最優秀賞を受賞しました | KUFU Inc.](http://kufuinc.com/news/16632)

e-Govは、政府が用意している 社会保険・労働保険関連手続きの電子申請APIとなります。

>これまで様々な取組が行われてきた一方で、確定申告などで利用される国税の電子申告（e-Tax）と比べるとまだまだ普及度が低いのが実情です。
わたしたちは kiji の開発・公開によって e-Gov 外部連携 API に対応したソフトウェアが増えることを期待します。
そして、電子政府の認知度の向上、利用率の向上、及び利用の拡大に貢献し、もってユーザの利便性の向上を目指します。

社会全体の利便性向上へ貢献されるKufuさんの姿勢素敵です

```rb
client = Kiji::Client.new do |c|
  c.software_id   = ENV['EGOV_SOFTWARE_ID']
  c.api_end_point = ENV['EGOV_API_END_POINT']
  c.cert          = OpenSSL::X509::Certificate.new(File.read(cert_file))
  c.private_key   = OpenSSL::PKey::RSA.new(File.read(private_key_file))
end

# 利用者認証（Access Key の取得 & 設定）
response = client.login("REGISTERED_USER_ID")
xml = Nokogiri::XML(response.body)
client.access_key = xml.at_xpath('//AccessKey').text

# 一括申請
file_name = 'apply.zip'
encoded_data = Base64.encode64(File.new("data/#{file_name}").read)
client.apply(file_name, encoded_data)
```

# tsubaki
[kufu/tsubaki](https://github.com/kufu/tsubaki)

こちらも同じくKufuさんのgem
マイナンバーのチェックディジット gemです。

マイナンバーはチェックディジットの仕様が国から公開されています。
[総務省令第八十五号 第五条より](http://www.soumu.go.jp/main_content/000327387.pdf)

```rb
# Verifies the format and its check digit with `strict` option:
validates :digits, my_number: { strict: true, allow_blank: true }

# Without strict option, it verifies only the length of the digits:
validates :digits, my_number: true

# Or if a My Number contains any dividers, specify it:
validates :digits, my_number: { strict: true, divider: '-' } # => 4652-8126-6333 should be valid
```

個人番号、法人番号、それぞれのチェックディジットに対応しています。

# fiscali
[asanghi/fiscali](https://github.com/asanghi/fiscali)

fiscaliは、会計年度gemです。
開発者はインドの方なのかな？
インド・日本以外にも、数カ国の会計年度に対応しているみたいです

```
{ india: 4, uk: 4, us: 10, pakistan: 7, australia: 7, ireland: 1, nz: 7, japan: 4}
```

DateやTimeに、会計年度を返却するmethodは、クォーターを返却するmethodなどを追加してくれます。

```
Date.today.financial_year
=> 2009
Date.today.beginning_of_year.financial_year
=> 2008
```

# age_jp
[ryoff/age_jp](https://github.com/ryoff/age_jp)
ここからは、手前味噌なgemを２つほど

age_jpは、日本独自の年齢加算処理を扱うgemです。
日本独自の年齢加算処理というのは、 `誕生日の前日に年齢加算される` というものです。
[年齢計算ニ関スル法律 - Wikipedia](https://ja.wikipedia.org/wiki/%E5%B9%B4%E9%BD%A2%E8%A8%88%E7%AE%97%E3%83%8B%E9%96%A2%E3%82%B9%E3%83%AB%E6%B3%95%E5%BE%8B)
[明治三十五年法律第五十号（年齢計算ニ関スル法律）](http://law.e-gov.go.jp/htmldata/M35/M35HO050.html)

簡単に言うと、法律上は誕生日の前日に年齢が加算されます
>4月1日生まれの子どもの場合には誕生日前日の3月31日の満了時（午後12時）に満6歳になります

介護保険や健康保険の資格の年齢判定や、扶養親族の年少老年判定など、労務関連の法律では誕生日ではなく年齢加算日（誕生日の前日）を使用する場合が多くあります。

```rb
Timecop.freeze(Time.new(2014, 12, 31))

birthday = Date.new(2000, 1, 1)
birthday.age                                      # 14 (通常の年齢)
birthday.age_at(Date.today)                       # same as birthday.age
birthday.age_jp                                   # 15 (日本の法律準拠)
birthday.age_jp_at(Date.today)                    # same as birthday.age_jp
birthday.east_asian_age_reckoning                 # 15 (数え年)
birthday.east_asian_age_reckoning_at(Date.today)  # same as birthday.east_asian_age_reckoning
birthday.insurance_age                            # 14 (保険年齢)
birthday.insurance_age_at(Date.today)             # same as birthday.insurance_age
birthday.to_years_old(17)                         # 2017/01/01. 17歳の誕生日を返却
birthday.to_years_old_jp(17)                      # 2016/12/31. 17歳の年齢加算日(日本の法律準拠)を返却
```

age_jpはこのように、年齢加算日に関するmethodをDateに生やす事が出来ます。

# round_50sen
[ryoff/round_50sen](https://github.com/ryoff/round_50sen)

round_50sen は、50銭以下を切り捨て、50銭より多い場合は切り上げる `round_50sen` methodを、Integer/Float/BigDecimalに生やすgemです

[厚生労働省：雇用保険の一般保険料額表の廃止と被保険者負担額の算定について](http://www.mhlw.go.jp/topics/2005/04/tp0425-2.html)
雇用保険などの、一部の労務計算では、
>５０銭以下の場合は切り捨て、５０銭１厘以上の場合は切り上げとなります。

という処理を求められます。

```
[1] pry(main)> 0.50.round_50sen
=> 0
[2] pry(main)> 0.51.round_50sen
=> 1
[3] pry(main)> 0.round_50sen
=> 0
[4] pry(main)> 1.round_50sen
=> 1
[6] pry(main)> BigDecimal('0.50000000000000000000000000000000000000').round_50sen.to_f
=> 0.0
[7] pry(main)> BigDecimal('0.50000000000000000000000000000000000001').round_50sen.to_f
=> 1.0
[8] pry(main)> BigDecimal('0.5550000000000000000000000000000000000000').round_50sen(2).to_f
=> 0.55
[9] pry(main)> BigDecimal('0.5550000000000000000000000000000000000001').round_50sen(2).to_f
=> 0.56
[10] pry(main)> BigDecimal('15000.00000000000000000000000000000000000000').round_50sen(-4).to_f
=> 10000.0
[11] pry(main)> BigDecimal('15000.00000000000000000000000000000000000001').round_50sen(-4).to_f
=> 20000.0
```

# まとめ
かなり狭い領域向けの記事となってしまいました。

railsを採用するスタートアップが増えた影響もあり、狭い領域向けのgemも増えてきた印象があります。

業務で開発したロジックは、多くの場合その会社独自の仕様であったり、そのサービス固有のロジックである場合が多いですが、「このコードはここでしか使えない」と安易に諦めたりせず、一部分だけ切り出したり、抽象度を上げるなどして、「gemとして公開しよう」、という思うような風潮が今後も加速するとよいな、と思っています。