実現方法
当システムの場合は、深夜に動作するバッチ処理内で有休付与処理を行います。
人間が付与を行う運用にした場合、忘れたり遅れたりすることが考えられるため、バッチ処理で自動的に実行する方式にしました。
バッチ処理とは別に手動で有休を付与する機能もあります。
バッチの起動間隔
各社員の入社日基準で付与する場合、毎日動作する必要があります。
特定の期日に一斉付与する場合、少なくとも6か月に1度は動作する必要があります。
当システムでは、社員の入社日基準・特定の期日どちらか一方を選択できるようになっているため、毎日動作します。
有休付与タイミング
結果
当システムでは有休付与予定日の3か月前の時点で有休を付与する仕組みにしました。
有休の権利は「チケット」という名前で、有休1日分=チケット1枚に置き換えて管理します。
チケットには有効期限From~Toが設定されているため、有休付与日より前の日付を対象に申請はできません。
この仕組みにより、有休付与予定日の3か月前から事前に有休取得申請を行うことができます。
有休付与日時点で出勤率が80%に満たなかった場合は、有休チケットを消滅させます。事前に申請されていた有休は強制的に取り消しになります。
有休が発生する時刻は0:00です。
有休付与日当日の1:00に出勤した場合、システムの設定次第では前日の労働として計上される場合もありますが、0:00時点で既に出勤率が確定し、有休付与処理も完了してしまうため、出勤率としてカウントできない問題が残っています。
理屈
出勤率が80%に達するかどうかは、有休の権利が発生する直前まで分かりません。
極端な例として、有休付与日前日の 23:59:59.997 から3ミリ秒だけ勤務したことで出勤率が80%に到達する可能性があり、その直後、有休付与日の 00:00:00.000 時点では有休の権利が発生し、使える状態になっている必要があります。
有休付与日当日になってから有休の付与処理を開始すると、一時的に有休が存在しない違法な状態になってしまいます。バッチ処理が失敗した場合は違法な状態が持続することになります。
実際の運用では、有休が付与されることを見越して事前に有休申請をする可能性があります。当システムでは有休の権利をチケットのポイント数で管理する仕組みにしたため、事前申請に対応するには有休の権利(ポイント)を事前に付与するくらいしか選択肢がありませんでした。
有休発生の条件
雇い入れの日から6か月継続勤務 && 全労働日の80%以上出勤
私はこの言葉の意味を理解するのに3週間(工数にして60時間)ほど費やしました。
「雇入れの日」
当システムで言うと、ユーザーマスタ.入社日の値です。
「6か月」
C#の DateTime.AddMonths(6) を使えばOKです。
例
入社日が09/01の場合は03/01
入社日が08/31の場合は02/28(閏年の場合は02/29)
「継続勤務」
昭和63年3月14日 基準発第150号
定年退職後に再雇用された場合など、継続勤務と見なす例が書かれています。
同一人物に対してはユーザー情報を使い回し、継続勤務と見なされないほど時間が空いた場合はユーザーデータを新規登録という運用になる想定です。
「全労働日」
前回有休を付与した日(または入社日)を起算日とします。
雑な表現をすると「労働義務が課されている日」です。
法律関連の情報
平成25年7月10日 基発0710第3号 に定義が書かれています。
全労働日に含めるもの
- 労働者の責に帰すべき事由によるとはいえない不就労日(裁判所の判決により解雇が無効と確定した場合や・・・)
全労働日に含めないもの
- 所定休日
- 労働者の責に帰すべき事由によるとはいえない不就労日(下記)
- 不可抗力による休業日
- 使用者側に起因する経営、管理上の障害による休業日
- いわゆるストライキで丸一日働かなかった日
- 公民権を行使する場合(選挙の投票や裁判員に選ばれた場合など→法務省から出ている資料)
- 代休や代替休暇で丸一日働かなかった場合
他に、下記の休暇で丸一日働かなかった場合は全労働日から除いた方が望ましいそうです。
全労働日から除かなくても違法ではなさそうです。
- 子の看護休暇(育児介護休業法 第16条の2)
- 介護休暇(育児介護休業法 第16条の5)
システム内での扱い
システム内では以下のように判定します。
- カレンダーで所定休日または法定休日となっている日は全労働日に含めない
- 「労働義務を免除する」系(労働義務有無フラグがfalse)のチケットが紐付いている場合は全労働日に含めない
「労働義務有無フラグ」は、チケットタイプに応じた固定値をセットします。ただし、チケットタイプで「特別休暇」を指定した場合はユーザーが労働義務有無フラグを任意の値に設定できます。
全労働日が0の場合
昭和63年3月14日 基準発第150号 には「前年に全労働日が0だった場合、有休は発生しない」とありますが
平成25年7月10日 基発0710第3号 では「削る」となっています。結局良く分かりません。
システム的にはカレンダーの全ての日付を所定休日に設定することも可能なため、全労日が0になる事は有り得ます。
当システムでは、全労働日が0のパターンを十分考えていませんでした。
全労働日が0だとしても有休が発生します。
有休付与日になった後、改めて出勤率計算を行いますが、全労働日が0の場合は0除算を回避するため処理を行わず、剥奪処理は動作しません。結果として有休が付与された状態になります。
「80%以上」
言葉通りの意味で、特に問題はありません。
「出勤」
法律関連の情報
労働日(労働義務のある日)に出勤した(労働義務を果たした)かどうかを判定します。
実働時間が0を超えている場合は出勤扱いになります。
極端な話、1日1秒ずつ労働しただけでも出勤扱いになり、出勤率が80%以上であれば有休が付与されることになります。
出勤したものと見なす
- 有休を使って休んだ(昭和63年3月14日 基準発第150号)
- 業務上負傷し、又は疾病にかかり療養のために休業した期間(労働基準法 第39条 ⑩)
- 育児休業(育児介護休業法 第2条 1、労働基準法 第39条 ⑩)
- 介護休業(育児介護休業法 第2条 2、労働基準法 第39条 ⑩)
- 産前産後休業期間(労働基準法 第65条、労働基準法 第39条 ⑩、昭和23年7月31日基収2675号)
- 労働者の責に帰すべき事由によるとはいえない不就労日のうち、全労働日に含まれる日(平成25年7月10日 基発0710第3号)
出勤していないものと見なす(出勤扱いにしなくても違法とは言えない)
- 生理休暇
- 子の看護休暇(育児介護休業法 第16条の2)
- 介護休暇(育児介護休業法 第16条の5)
「出勤していないものと見なす」のは絶対ではなく、出勤したものと見なしても問題ないはずです(労働者が有利になるため)。
生理休暇は出勤したものと見なしても良い旨が書かれています。(昭和23年7月31日 基収2675号)
システム内での扱い
実動時間が0を超えている場合は出勤扱いとします。
出勤したものと見なす系(出勤扱いフラグがtrue)のチケットが1つでも発見できた場合、出勤したものと見なします。
出勤率計算
出勤率 = 出勤日数 / 全労働日
この計算のためには「全労働日にあたるか」「出勤したものとみなすか」を判定する必要があります。
当システムでは、月報作成時に上記の判定を行い、判定結果を月報データの一部としてDBに保持します。
出勤率計算の際は、判定結果を単純にカウントするだけで済むようになっています。
平成6年1月4日 基発第1号
有休を一斉に付与する場合、出勤率計算はどうするか。
有休付与日の前日までは出勤の有無を判定する。付与日以降は全期間出勤したものと見なす。
有休付与数
有休付与日数はDBに固定で保持しており、ユーザーは操作できません。
法改正が発生した場合はDBのデータを直接操作して対応する想定です。
この仕組みにより、誤った設定をして違法な状態になる事を防いでいます。
法律で定められている以上の休暇を付与する場合は、当システム独自の「季節休暇」というタイプの休暇を使います。有休とは別の休暇とすることで、有休特有の法的な制限を回避できるようにしています。
平成6年1月4日 基発第1号
付与日数は勤続年数によって決まります。
前年に出勤率が80%に到達せず、有休の付与が行われなかったとしても、勤続年数はカウントアップした状態で有休付与数を計算します。
有休付与実績の管理
有休を付与済みかどうかDBで管理します。
これはバッチ処理が失敗した場合を想定した仕組みです。同じ日に有休付与処理を再実行した場合でも2重計上を防ぐことができます。