
企业应用后端前端移动开发【免费下载链接】hrmsOpen Source HR and Payroll Software项目地址https://gitcode.com/GitHub_Trending/hr/hrms点击查看免费下载导读Leave Block List假期封锁清单是 HRMS 开源人事系统中用于管控特殊日期请假的核心设置管理员预先将某些重要日期如财年开始首日、发薪日、项目关键交付日等标记为封锁日普通员工在这些日期提交请假后只有被授权进入 Allow List 的特殊用户如 HR Manager才能审批通过。本文以 官方 README 为主线结合 DocType 定义、服务端逻辑、前端交互 与 测试用例完整讲解其字段含义、适用范围解析、审批拦截链路与实战配置方法读完即可上手实现重要日期休假管控。Leave Block List 是什么原文档给出了一句话定义List of days on which leaves can only be approved by special users.封锁日清单在这些日期上请假只能由特殊用户审批。这句话包含了该功能的两条核心语义封锁的是审批动作而非提交动作员工依然可以在封锁日提交请假申请此时会看到警告提示但普通审批人无法将其置为 Approved特殊用户由 Allow List 显式定义只有被加入该清单授权名单的用户才有权限审批覆盖这些日期。在 HRMS 系统中这个 DocType 位于 HR 模块的 Setup 文档类型document_type: Setup见 leave_block_list.json其 DocType 描述为Block Holidays on important days.即在重要日期上封锁请假。图标为日历样式fa fa-calendar契合日期管控的定位。表单字段全景与取值说明依据 leave_block_list.json 的fields定义该 DocType 共包含以下字段字段名字段类型是否必填说明leave_block_list_nameData必填封锁清单名称唯一unique: 1并作为命名规则autoname 按字段命名companyLink → Company必填该清单所属公司跨公司场景下按公司隔离applies_to_all_departmentsCheck默认 0Applies to Company勾选后该清单全局生效不勾选则需在 Department 中逐个绑定leave_typeLink → Leave Type可选限定该清单只对指定假别生效留空表示对所有假别生效leave_block_list_datesTable → Leave Block List Date必填封锁日期明细日期 原因leave_block_list_allowedTable → Leave Block List Allow可选授权用户名单可审批封锁日请假的人add_day_wise_datesButton—Add Day-wise Dates批量按星期添加日期的按钮其中两个子表结构如下Leave Block List Date定义文件子表字段为block_dateDate必填与reasonText必填即哪一天、为什么封锁。该子表自己的 READMEleave_block_list_date/README.md描述为Date blocked on parent Leave Block List.。Leave Block List Allow定义文件仅含allow_userLink → User必填即授权用户用于判定审批权限。权限设计谁能新建与编辑权限配置位于 leave_block_list.jsonHR User具备 create / read / write / email / print / shareHR Manager在上述基础上额外具备report权限。也就是说日常操作该清单的角色是 HR 团队普通 Employee 角色没有直接读写该设置的权限其交互入口全部通过请假申请流程见下文审批拦截链路。适用范围解析全局清单 vs 部门清单get_applicable_block_listsleave_block_list.py是判定哪些封锁清单对当前员工生效的核心函数其逻辑分为两级。第一级公司级全局清单当传入或解析出company后查询满足以下条件的所有清单conditions {applies_to_all_departments: 1, company: company} if leave_type: conditions[leave_type] [IN, (leave_type, , None)]即勾选applies_to_all_departmentsApplies to Company的清单对公司内所有部门生效若指定了leave_type则只有请假类型与该leave_type匹配或清单未限定假别时才生效。第二级部门级清单当解析出员工及其所属部门后department frappe.db.get_value(Employee, employee, department) block_list frappe.db.get_value(Department, department, leave_block_list) block_list_leave_type frappe.db.get_value(Leave Block List, block_list, leave_type) if not block_list_leave_type or not leave_type or block_list_leave_type leave_type: add_block_list([block_list])这里对应了applies_to_all_departments未勾选的使用方式——原文档中该字段的说明明确写道If not checked, the list will have to be added to each Department where it has to be applied.若不勾选需要将该清单分别挂到每个适用部门上。部门的leave_block_list字段正是Leave Block List到Department的反向链接见 leave_block_list_dashboard.py 中transactions: [{items: [Department]}]的定义。注意部门级清单同样受leave_type约束只有部门清单未限定假别或假别与申请一致时才纳入生效范围。此外如果员工不属于任何部门则部门级清单自然不生效。特殊用户豁免def add_block_list(block_list): for d in block_list: if all_lists or not is_user_in_allow_list(d): block_lists.append(d)is_user_in_allow_listleave_block_list.py检查当前会话用户在指定清单的Leave Block List Allow子表中是否存在allow_user记录。存在则说明该用户是特殊用户其假单不受该清单拦截all_listsTrue时则忽略该豁免返回全部清单用于警告提示场景见下文。汇总去重函数最终通过list(set(block_lists))合并两级清单并去重返回生效清单名称列表。封锁日期的查询与批量生成按日期范围查询封锁日get_applicable_block_dates(from_date, to_date, employeeNone, companyNone, all_listsFalse, leave_typeNone)leave_block_list.py以生效清单列表为parent过滤条件查询在[from_date, to_date]区间内的所有封锁日期返回每条记录的block_date与reasonreturn frappe.db.get_all( Leave Block List Date, filters{ parent: [IN, get_applicable_block_lists(employee, company, all_lists, leave_type)], block_date: [BETWEEN, [getdate(from_date), getdate(to_date)]], }, fields[block_date, reason], )批量按星期添加封锁日add_day_wise_dates前端按钮add_day_wise_dates调用服务端白名单方法set_weekly_off_dates(start_date, end_date, days, reason)leave_block_list.py一次为整个区间内匹配指定星期的日期批量生成封锁记录。弹窗字段见 leave_block_list.js弹窗字段类型说明Start Date / End DateDate必填日期区间daysMultiCheck必填周一至周日多选支持全选select_all: true3 列布局ReasonSmall Text必填统一原因会写入每条封锁日记录底层生成逻辑get_block_dates_from_dateleave_block_list.py按天遍历区间仅添加「满足星期匹配」且「尚未存在于清单中」的日期while start_date end_date: if start_date not in existing_date_list and calendar.day_name[start_date.weekday()] in days: date_list.append(start_date) start_date timedelta(days1)calendar.day_name[start_date.weekday()]生成的英文星期名Monday…Sunday与前端 MultiCheck 的value完全对应天然规避了重复添加。提交校验禁止重复日期validate()leave_block_list.py在保存时检查子表中block_date是否重复重复则抛出Date is repeated异常从源头保证日期唯一性。请假审批拦截链路源码级验证封锁清单的最终效果体现在Leave Application的校验链路上leave_application.py。第一步提交时的警告提示show_block_day_warningleave_application.py在假单 validate 阶段被调用使用all_listsTrue查询即无视 Allow List 豁免并输出警告frappe.msgprint(_(Warning: Leave application contains following block dates) :) for d in block_dates: frappe.msgprint(formatdate(d.block_date) : d.reason)员工提交后即会看到请假申请包含以下封锁日期 原因的提示但申请仍可继续流转。第二步审批时的强制拦截validate_block_daysleave_application.py是真正的拦截点if block_dates and self.status Approved: frappe.throw(_(You are not authorized to approve leaves on Block Dates), LeaveDayBlockedError)调用get_applicable_block_dates时不带all_lists因此 Allow List 中的特殊用户会被自动豁免只有当假单状态为Approved审批通过且存在未豁免的封锁日期时才抛出LeaveDayBlockedError自定义 ValidationError定义于 leave_application.py阻止提交普通员工、普通审批人HR User 等均无法将含封锁日的假单置为已批准只有清单授权用户可以。测试用例佐证单元测试 test_leave_block_list.py 覆盖了普通用户查询返回封锁日test_get_applicable_block_dates、Allow List 用户查询返回空test_get_applicable_block_dates_for_allowed_user、all_listsTrue强制返回全部test_get_applicable_block_dates_all_lists、按假别过滤test_get_applicable_block_dates_all_lists_for_leave_type、test_get_applicable_block_dates_for_allowed_user_for_leave_type等场景集成测试 test_leave_application.pytest_block_list验证了完整链路将测试部门绑定_Test Leave Block List后普通用户审批含封锁日的假单触发LeaveDayBlockedError切换为 Allow List 中的用户test1example.com后同一假单可成功submit()。测试夹具一条完整可参考的配置样例test_records.json 提供了 4 组可直接参考的清单配置覆盖两种典型场景全局 无假别限定_Test Leave Block Listapplies_to_all_departments: 1封锁 2013-01-02授权test1example.com全局 限定 Casual Leave_Test Leave Block List Casual Leave 1与...2一组带授权用户、一组不带用于验证同假别下授权用户豁免、普通用户拦截全局 限定 Leave Without Pay_Test Leave Block List LWP用于验证假别隔离——LWP 的封锁日不会影响 Casual Leave 申请。一个典型条目如下{ doctype: Leave Block List, leave_block_list_name: _Test Leave Block List, company: _Test Company, applies_to_all_departments: 1, leave_block_list_dates: [ {block_date: 2013-01-02, reason: First work day, doctype: Leave Block List Date} ], leave_block_list_allowed: [ {allow_user: test1example.com, doctype: Leave Block List Allow} ] }实战配置步骤场景一公司级全局封锁适用于全公司统一的禁假日期如财年首日、公司年会以 HR Manager / HR User 登录进入Leave Block List列表新建填写名称唯一、选择公司勾选Applies to Company即applies_to_all_departments清单将自动作用于该公司所有部门在 Leave Block List Dates 子表中逐条添加封锁日期与原因或使用Add Day-wise Dates按星期批量添加例如封锁每月 1 日这类周期日期在 Leave Block List Allowed 子表添加可审批这些日期的特殊用户如 HR Manager 本人保存。之后普通用户在这些日期提交请假会收到警告非授权审批人置为 Approved 时会触发LeaveDayBlockedError。场景二部门级定点封锁适用于仅部分部门适用的封锁如某部门项目攻坚期新建清单时不要勾选Applies to Company保存后在对应Department文档的Leave Block List字段中挂接该清单该字段即 leave_block_list_dashboard.py 中展示的反向链接需要多个部门适用时为每个部门分别挂接同一清单。场景三按假别精细化控制新建清单时在Leave Type字段指定假别如 Casual Leave此时该清单只拦截该假别的申请未指定假别的清单对所有假别生效且同时存在时例如公司级通用清单 假别清单两者会合并生效去重后的并集见list(set(block_lists))。与员工假单处理流程的联动HRMS 中Leave Application的 validate 链leave_application.py按顺序执行validate_dates→validate_balance_leaves→validate_leave_overlap→validate_max_days→show_block_day_warning→validate_block_days→ …。这意味着封锁日检查发生在余额、重叠、最大天数等基础校验之后只有当假单整体合法且状态被置为 Approved 时封锁拦截才会触发——既不影响员工正常提交流程也杜绝了越权审批。小结Leave Block List 通过公司级全局 部门级定点 假别限定三层作用域与Allow List 授权豁免机制实现了对重要日期请假审批的精细化管控。其核心设计亮点在于封锁的是审批而非提交员工保有提交与说明的空间而系统在审批关口用LeaveDayBlockedError强制执行特殊用户才能批准封锁日的规则。配合add_day_wise_dates的按星期批量添加能力HR 团队可以在几分钟内完成整年度的禁假日规则配置。赞分享企业应用后端前端移动开发【免费下载链接】hrmsOpen Source HR and Payroll Software项目地址https://gitcode.com/GitHub_Trending/hr/hrms点击查看免费下载相关推荐Frappe HRMS v14.36.12新特性薪资计算提速50%请假审批全流程优化指南Frappe HRMS v14.36.12新特性薪资计算提速50%请假审批全流程优化指南 你还在为薪资计算耗时过长、请假审批流程繁琐而烦恼Frappe H企业应用后端前端移动开发中国节假日终极解决方案Python智能判断工作日与法定假期在Python开发中准确判断中国法定节假日和工作日是一个常见但复杂的需求。chinese calendar库作为专业的中国节假日判断工具为开发者提供了精准、后端simple-one-api负载均衡实战多模型自动切换的终极方案simple one api负载均衡实战多模型自动切换的终极方案 simple one api是一款OpenAI接口接入适配工具支持千帆大模型平台、讯飞星火上一篇Grafana Tempo 用户可配置 Overrides 完整指南通过 /api/overrides 动态管理租户限制下一篇Retrofit Gson Converter 完全指南JSON 序列化与反序列化的配置、原理与实战创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考