SAP HR 年休假调整:从统休制到实休制,在一个自然年度内分段式生成年休假

SAP HR 年休假调整:从统休制到实休制,在一个自然年度内分段式生成年休假

简介: 我有一个朋友,他们公司的年假只能在年底连着春节假期一次性休完,以往每当年底放假时,他都会发朋友圈公告他已经放假了,以此报复那些好像一年到头都在旅游的讨厌鬼。但是,今年他也变成我眼中的讨厌鬼了。

关键字:SAP ABAP HCM/HR PT 时间管理 PA30 考勤管理 年休假/年假


1 说来话也不长

抛开年休假天数不谈,每个公司的年休假生成规则也是千奇百怪的。

  • 年休假生成规则的变化
    • 2023 年之前,统休制
      每年年底最后一天(YYYY-12-31)一次性按照工龄生成整年的年休假,一年只能生成一次。
    • 2023 年之后,实休制
      每当按照工龄和当年工作天数比例计算的可休假天数 >= 0.5 天,就可以生成年休假,当次年休假定额 = 理论比例定额 - 已生成定额,一年可以生成多次。
  • 实休制
    年休假施行实休制,对系统而言,其实就是在一个自然年度内分段式生成年休假。一般地,为了便于管理,也会限定分段次数,最常见为按照『上下半年分段』和按照『季度分段』。

我朋友今年休假调整,就是按照『上下半年分段』施行实休制的年休假。
7 月 1 号刚到,他就订好了去日本东京的机票,而我只能苦哈哈在办公室坐等来自千里之外的投喂,苦啊。

他公司的年休假调整是我实施的。

此处记仇,
在这里插入图片描述
说远了,下面进入正文。

2 生成员工年休假定额

在完成 HCM 实施后一定会有类似功能的程序,
在这里插入图片描述

3 设计要点

关于实休制的设计(不仅限于年休假类型)挺有意思的,因此专文记录,在很多定额类计算中都可以作为参考。

  • 一个自然年度
  • 计算截止日期
  • 按天比例计算的休假天数
  • 0.5 天为最小起算单位,巧用 div 算术
  • 年度补差:当前计算截止日期的休假天数 - 已生成休假数
  • 平年闰年考虑

4 新旧代码实现

  • 统休制
        "1.6计算年休假定额
        if it_itab-rzrq+0(4) eq pn-begda+0(4)."当年入职
          call function 'ZHR_CALC_EMP_ZZTS'
            exporting
              i_pernr = pernr-pernr
              i_begda = l_begda
              i_endda = pn-endda
            importing
              e_zzts  = l_days.
          l_anzhl = ( l_days / 365 ) * 5.
          "-->0.5天起算年休假
          l_anzhl = l_anzhl div '0.5'.
          l_anzhl = l_anzhl  *  '0.5'.
          "<--0.5天起算年休假
        else.
          if it_itab-gznx ge 1 and it_itab-gznx lt 10.
            l_anzhl = 5.
          elseif it_itab-gznx ge 10 and it_itab-gznx lt 20.
            l_anzhl = 10.
          elseif it_itab-gznx ge 20.
            l_anzhl = 15.
          endif.
        endif.
        "1.7生成年休定额的有效日期
        if l_anzhl gt 0.
          it_itab-anzhl = l_anzhl.
          if it_itab-rzrq+0(4) eq pn-begda+0(4)."当年入职
            it_itab-begda = l_begda.
            it_itab-endda = pn-endda.
            it_itab-desta = g_begda.
            it_itab-deend = g_endda.
          else.
            it_itab-begda = pn-begda.
            it_itab-begda+4(4) = '0101'.
            it_itab-endda = pn-endda.
            it_itab-desta = g_begda.
            it_itab-deend = g_endda.
          endif.
        else.
          it_itab-flag = '@S_NONO@'.
          it_itab-flag_text = text-s01.
        endif.
  • 实休制
        "1.4计算员工工龄
        clear:i_years.
        call function 'ZHR_CALC_GL'
          exporting
            p_pernr = pernr-pernr
            p_begda = l_begda  "入职日期
            p_endda = pn-endda "计算截止日期
          importing
            i_years = i_years.

        it_itab-gznx = i_years.
        "1.5读取已有的年休假定额
        clear:lv_begda_ift2006,lv_endda_ift2006.
        lv_begda_ift2006 = pn-begda+0(4) && '0101'.
        lv_endda_ift2006 = pn-begda+0(4) && '1231'.

        clear lv_year_days.
        lv_year_days = lv_endda_ift2006 - lv_begda_ift2006 + 1.

        clear it_2006.refresh:it_2006[].
        call function 'HR_READ_INFOTYPE'
          exporting
*           TCLAS           = 'A'
            pernr           = pernr-pernr
            infty           = '2006'
            begda           = lv_begda_ift2006
            endda           = lv_endda_ift2006
          tables
            infty_tab       = it_2006
          exceptions
            infty_not_found = 1
            others          = 2.
        if sy-subrc eq 0.
          delete it_2006 where ktart ne '91'.
          clear lv_anzhl_history.
          loop at it_2006.
            lv_anzhl_history = lv_anzhl_history + it_2006-anzhl.
          endloop.
        endif.

        clear:lv_begda_p2006,lv_endda_p2006,lv_desta_p2006,lv_deend_p2006.
*        sort it_2006 by endda descending."定额终止日期 降序
*        read table it_2006 index 1.
*        if sy-subrc <> 0."[自然年内]:没有年休假记录
        if it_itab-rzrq+0(4) eq pn-begda+0(4)."当年入职
          lv_begda_p2006 = l_begda."定额开始日期 = 入职日期
        else.
          lv_begda_p2006 = pn-begda+0(4) && '0101'.
        endif.
*        else.            "[自然年内]:有年休假记录
*          lv_begda_p2006 = it_2006-endda + 1.
*        endif.
        lv_endda_p2006 = pn-endda."  = 输入的计算截止日期
        lv_desta_p2006 = lv_endda_p2006 + 1."开始决定日期(有效开始日期)
        call function 'RP_CALC_DATE_IN_INTERVAL'
          exporting
            date      = lv_desta_p2006
            days      = 0
            months    = 0
            signum    = '+'
            years     = 1
          importing
            calc_date = lv_deend_p2006.
        lv_deend_p2006 = lv_deend_p2006 - 1."终止决定日期(有效结束日期)

        lv_de_days = lv_endda_p2006 - lv_begda_p2006 + 1.

        "1.6计算年休假定额
        clear l_anzhl.
        if it_itab-rzrq+0(4) eq pn-begda+0(4)."当年入职
          l_anzhl = 5.
        else.
          if it_itab-gznx lt 10.
            l_anzhl = 5.
          elseif it_itab-gznx ge 10 and it_itab-gznx lt 20.
            l_anzhl = 10.
          elseif it_itab-gznx ge 20.
            l_anzhl = 15.
          endif.
        endif.

        "按天算
        l_anzhl = ( lv_de_days / lv_year_days ) * l_anzhl.
        "-->0.5天起算年休假
        l_anzhl = l_anzhl div '0.5'.
        l_anzhl = l_anzhl  *  '0.5'.
        "<--0.5天起算年休假
        l_anzhl = l_anzhl - lv_anzhl_history."[自然年内]:剩余年休假 = 年休假 - 已生成年休假

        if lv_endda_p2006 >= lv_begda_p2006.
          "1.7生成年休定额的有效日期
          if l_anzhl gt 0.
            it_itab-anzhl = l_anzhl.
            it_itab-begda = lv_begda_p2006."定额开始日期
            it_itab-endda = lv_endda_p2006."定额终止日期
            it_itab-desta = lv_desta_p2006."开始决定日期(有效开始日期)
            it_itab-deend = lv_deend_p2006."终止决定日期(有效结束日期)
          else.
            it_itab-flag = '@S_NONO@'.
            it_itab-flag_text = text-s01.
          endif.
        else.
          it_itab-flag = '@S_NONO@'.
          it_itab-flag_text = text-s09.
        endif.
      when others.
        "DO NOTHING
    endcase.

其他

我的微信群、QQ群和其他发布平台。

长期提供开发和运维服务。

猜你喜欢

转载自blog.csdn.net/libin961797440/article/details/131544791