问题背景
工作量优化思路与方法
优化用户体验
总结
未来的展望
企业法务部门一直以来承担着合同处理的重要职责。随着企业规模的扩大,合同数量和复杂度不断增加,例如劳动合同、租赁合同、签约协议等。这些合同的内容一般都比较复杂,不同的合同需要经常修改。再加上各级审批人的审批流程冗长,修改成本和审批成本的叠加导致法务部门处理合同效率低下。
为此,企业法务部门根据合同的特点将其分为模板合同和非模板合同。模板合同是指内容比较固定,只需针对部分内容进行填写或修改的合同。企业法务部门希望将模板合同的能力扩展到OA系统上,借助OA系统完成合同填写、修改、归档审批等工作,从而提高工作效率。
为了解决法务部门的工作量问题,让我们来看看法务部门的工作流程。法务部门的工作流程如图1所示:
从图中可以看出,法务部门原来的工作流程主要包括合同的转化、填写、归档审核等环节。
合同的转化步骤:
法务同事将合同的设计文件定版转化为PDF文件。
填写步骤:
在转化后的PDF文件中,法务同事填写本次合同要用到的信息,例如联系人电话、联系人地址等。
归档审核步骤:
法务同事将填写完成的合同逐级提交给上级和不同的负责人审阅。最后,将经过审核的合同归档保存。这样的工作流程,法务同事需要花费时间去填写合同的内容。而且,在定稿之后,还需要发送给各级领导进行审阅。但是,由于合同的内容复杂,加之让领导来回审阅的过程也比较繁琐,导致工作效率低下。
针对上面的情况,我们可以将法务模板合同的工作流程抽象为OA系统中的线上流程。首先,我们可以将合同的转化步骤抽象为OA系统中的上传步骤。预先处理好PDF文件,并将要填写的内容处理为XLS文件,然后上传到系统中。
然后,我们可以将合同的各级负责人审阅的步骤抽象为Activiti引擎中的一个流程。OA系统会代替法务同事完成PDF文件的转化和填写内容的校验和填写。流程步骤作为审批步骤,不需要法务同事再去挨个找不同的负责人审阅。
这样,如图2所示,我们就将合同的转化、填写、归档审核等环节抽象为了OA系统中的上传、填写、审批流程线上化等环节,从而提高了工作效率。
等等,这可不行!
如果这样做,真的能提高效率吗?随着公司持续发展,模板合同的数量会越来越多。像上图所示,每一个模板合同都对应着一个Activiti流程。每新增一个模板合同,就需要设计一个Activiti流程。熟悉Activiti引擎的同学都知道,设计一个Activiti流程需要构造Bpmn图、编写流程代码、部署流程等,这会给开发人员带来很大的工作量。在大量模板添加的情况下,开发人员就会成为瓶颈,无法快速提高效率,最终导致工作效率并没有提升。
那么,我们应该如何优化呢?别急,一切皆可抽象。通过梳理已有的几十个模板合同的逻辑,我发现,这些模板合同虽然内容各不相同,但总体上可以分为5个大类。并且,这五个大类的审批流程中,有些审批节点是相同的,例如,每个合同都需要财务部门的同事审阅。因此,我们可以重用这些审批节点。
图3展示了优化前后的对比图:
因此,我们可以将N次的工作量简化为一次,只需将5个大类的审批流程抽象出来。这样,每新增一个模板合同,只需要根据合同的分类,即可执行对应的流程,从而减少了工作量。
此外,上述流程中的文件内容校验,可以在Apollo配置中心配置对应的校验规则,以进一步减少工作量。我们可以利用Excel的数据校验、数据选择框等功能来限制填写内容。同时,利用Apollo配置中心将每个合同的填写内容规则抽象出来,设置为一个个的Apollo配置。然后,在上传合同时,根据合同的分类获取对应的Apollo配置,实现一个通用的校验器。最后,根据配置来校验填写的内容是否符合规则。
图5展示了配置中心和校验器的交互过程:
通用的校验器的实现示例代码如下所示:
public static OpResult<Map<String, String>> checkExcelIsValidOrNot(InputStream inputStream, String templateName) throws Exception {
Sheet sheetByStream = getSheetByStream(inputStream, "sheet1");
StringBuilder errMsg = new StringBuilder();
String templateData = config.getProperty(templateName, "");
JsonNode jsonNode = JsonUtil.string2JsonNode(templateData);
JsonNode content = jsonNode.get("content");
HashMap<String, String> PDFNeedMap = Maps.newHashMap();
int row = 1;
int max = 200;
while (row < max) {
try {
String keyInChn = ExcelUtil.readCell(sheetByStream, row, 1, null, "");
String valueInChn = ExcelUtil.readCell(sheetByStream, row, 3, null, "");
keyInChn = keyInChn.trim();
valueInChn = valueInChn.trim();
int lengthLimitForKey = content.get(keyInChn).asInt();
if (StringUtils.isNotBlank(valueInChn) && valueInChn.length() <= lengthLimitForKey) {
PDFNeedMap.put(keyInChn, valueInChn);
} else {
errMsg.append("字段:").append(keyInChn).append(" 填写的参数不合法.");
}
} catch (Exception e) {
log.info("读取Excel结束,error: " + e);
break;
}
row += 1;
}
String err = errMsg.toString();
// 如果excel是合法的,那么err字符串就会是空的。
if (StringUtils.isNotBlank(err)) {
return OpResult.createFailResult(-1, err);
}
return OpResult.createSucResult(PDFNeedMap);
}
现在,让我们再梳理一下优化后的工作流程。通过优化,我们将原先N个合同N次的工作量优化为N个合同1次的工作量。同时,我们还优化了原先工作流程中的规则检查逻辑,借助配置中心和通用的校验器,避免在代码中进行大量的硬编码,从而提高了代码的整洁度。
当改造过后,OA法务模板合同系统,借助直观的界面和交互方式和简洁清晰的逻辑,无论是针对使用方还是开发者方,都大大降低了心智成本,提高了用户感受。
下面,我们来看看优化后的用户真实场景的体验是怎样的?
一:用户可以选择不同的模板,选择之后可以下载对应的可编辑的模板合同PDF,并且可以根据Excel查看合同的填写规则。
二:用户下载好PDF文件后,可以在PDF文件里编辑,根据上下文和实际情况,填写好对应的内容
三:填写好内容后上传,这时系统会校验参数是否符合规则,有问题报错提醒用户,没问题就生成不可编辑的定版PDF文件
四:提交开启流程,由各级审核人审核
通过对法务模板合同工作量优化思路和方法的介绍,我们可以看到,通过抽象、通用化等手段,可以有效提高工作效率和用户体验。具体来说,优化后的效果如下:
工作效率提升:
原先,需要逐个合同去处理,每新增一个合同,都需要设计一个Activiti流程,合同越多工作量越多。优化后,将合同分类,抽象出通用的审批流程,每新增一个合同,只需要根据分类,配置合同为对应的分类下,设置合同的Apollo配置,即可让用户借助OA完成合同的相关工作,提高了工作效率。
我们虽然现在已经将合同的审批流程抽象出来了,新增模板合同后,简单配置即可使用。但是OA整体的开发过程中,对于新的审批流仍然需要开发Activiti流程,设置新的审批矩阵。工作量还比较高,计划将这部分整体抽象出来,将流程和审批矩阵做成可配置形式,将流程开发工作量的N变成趋近于1,彻底释放开发工作量,提高交付效率。在读的各位如果有相关的建议和思路欢迎在评论区讨论。
关于作者
刘希宁,转转工程效率组开发工程师,负责OA系统等平台的开发和维护,欢迎各位交流沟通。