
## 1.业务背景
客户希望调动单,可以按照单据行来进行审批,部分分录行通过,部分分录行不通过。
## 2.解决思路
由于工作流平台不支持按照分录行进行审批,考虑将单据进行拆分,将同意的记录,重新生成一张新的单据,将不同意的记录生成一张审核不通过调动单。
另外一方面由于系统调动单校验比较多,如果重新开发单据,复制系统的校验可能会比较麻烦,所以考虑直接对调动单进行拆分。处理方式为在调动单表头增加字段标识是否汇总单(汇总单支持按行审批,非汇总单为系统真正反写人事事务的单据),分录增加是否通过的标识。
## 3.处理过程
### 3.1DEP增加字段
#### 3.1.1增加枚举,通过/驳回

#### 3.1.2表头增加字段
|名称|别名|类型|数据表字段|
|-|-|-|-|
|sgFailureID|失败单据ID|字符串|CFSgFailureID|
|sgSuccessID|成功单据ID |字符串|CFSgSuccessID|
|isSgSumBill|是否汇总单|布尔|CFIsSgSumBill|
#### 3.1.3分录增加字段
|名称|别名|类型|数据表字段|
|-|-|-|-|
|entryStatue| 分录审核状态| 业务枚举 |CFEntryStatue|
#### 3.1.4实体扩展属性,配置3.2中的全路径

### 3.2controllerbean扩展
主要涉及到的扩展有,提交生效、审核通过、审核不通过、反审核、删除操作。
#### 3.2.1反审核-列表界面
```java
//反审核
@Override
public void untiCheckBizBill(Context ctx, String billId)
throws BOSException, EASBizException {
System.out.println("untiCheckBizBill");
//反审核扩展,如果是汇总单,则直接反审核,并且反审核对应成功的单据, 如果不是汇总单则调用原先的逻辑
IFluctuationBizBill ifbb = FluctuationBizBillFactory.getLocalInstance(ctx);
FluctuationBizBillInfo info = ifbb.getFluctuationBizBillInfo(new ObjectUuidPK(billId));
if(info.get("isSgSumBill") instanceof Boolean && (Boolean)info.get("isSgSumBill") == true ){
//
SelectorItemCollection billSelector = new SelectorItemCollection();
billSelector.add(new SelectorItemInfo("billState"));
String realId = info.get("sgSuccessID") == null ? null : info.get("sgSuccessID").toString() ;
if(realId != null && ifbb.exists(new ObjectUuidPK(realId))) //单据要先存在
super.untiCheckBizBill(ctx, realId);
String fID = info.get("sgFailureID") == null ? null : info.get("sgFailureID").toString() ;
if(fID != null && ifbb.exists(new ObjectUuidPK(fID)) ){ //单据要先存在
FluctuationBizBillInfo info2 = ifbb.getFluctuationBizBillInfo(new ObjectUuidPK(fID));
info2.setBillState(HRBillStateEnum.SAVED);
ifbb.updatePartial(info2, billSelector);
}
info.setBillState(HRBillStateEnum.SAVED);
ifbb.updatePartial(info, billSelector);
}else{
super.untiCheckBizBill(ctx, billId);
}
}
```
#### 3.2.2审核通过-工作流
```java
//设置审核通过
@Override
public void setAudited(Context ctx, BOSUuid billID) throws BOSException,
EASBizException {
IFluctuationBizBill ifbb = FluctuationBizBillFactory.getLocalInstance(ctx);
FluctuationBizBillInfo info = ifbb.getFluctuationBizBillInfo(new ObjectUuidPK(billID));
if(info.get("isSgSumBill") instanceof Boolean && (Boolean)info.get("isSgSumBill") == true ){
//汇总单处理方式
//走扩展逻辑,否则走原先逻辑
//处理事务状态运行创建新的单据,原先单据表现为审核通过 将人事事务记录中的信息设置为未审核,否则会影响填单。
String billId = billID.toString();
String oql = "select billState,entryBizDate where billID='" + billId + "'";
IHRAffairBiz iRAffairBiz = HRAffairBizFactory.getLocalInstance(ctx);
HRAffairBizCollection affairBizColl = iRAffairBiz.getHRAffairBizCollection(oql.toString());
SelectorItemCollection selector = new SelectorItemCollection();
selector.add(new SelectorItemInfo("billState"));
for(int i = 0 ; i < affairBizColl.size() ; i++){
HRAffairBizInfo bizInfo = affairBizColl.get(i);
bizInfo.setBillState(HRBillStateEnum.AUDITEND);
iRAffairBiz.updatePartial(bizInfo, selector);
}
//生成单据体
//将数据设置为未生效之后,新增一个单据。
FluctuationBizBillInfo info_s = (FluctuationBizBillInfo) info.clone();
info_s.setId(BOSUuid.create("C0DAD00D"));
info_s.put("isSgSumBill", false);
info_s.setNumber("AAA"); //系统会调用编码规则
FluctuationBizBillEntryCollection entrys_s = info_s.getEntrys();
FluctuationBizBillInfo info_f = (FluctuationBizBillInfo) info.clone();
info_f.setId(BOSUuid.create("C0DAD00D"));
info_f.put("isSgSumBill", false);
FluctuationBizBillEntryCollection entrys_f = info_f.getEntrys();
List removeSuc = new ArrayList<FluctuationBizBillEntryInfo >();
List removeFaul = new ArrayList<FluctuationBizBillEntryInfo >();
for(int i = 0 ; i < entrys_s.size() ; i++){
entrys_s.get(i).setId(BOSUuid.create("C1964865"));
System.out.println("ASAA");
if("0".equals(entrys_s.get(i).get("entryStatue")) || entrys_s.get(i).get("entryStatue") == "0" ){
//清除当前行
removeSuc.add(entrys_s.get(i));
}
}
for(int i = 0 ; i < entrys_f.size() ; i++){
entrys_f.get(i).setId(BOSUuid.create("C1964865"));
if("1".equals(entrys_f.get(i).get("entryStatue")) || entrys_f.get(i).get("entryStatue") == "1" ){
//清除当前行
removeFaul.add(entrys_f.get(i));
}
}
//删除不需要的分录
for(int i = 0 ; i < removeSuc.size() ; i++){
entrys_s.remove((FluctuationBizBillEntryInfo) removeSuc.get(i));
}
//删除不需要的分录
for(int i = 0 ; i < removeFaul.size() ; i++){
entrys_f.remove((FluctuationBizBillEntryInfo) removeFaul.get(i));
}
//先处理失败的,再处理成功,否则无法保存
if(entrys_f.size() > 0){ //失败的单据,直接设置审核不通过
info_f.setBillState(HRBillStateEnum.AUDITEND);
IObjectPK fid = super.save(ctx, info_f);
info.put("sgFailureID", fid);
}
if(entrys_s.size() > 0){ //成功的单据直接审核生效
IObjectPK sid = super.save(ctx, info_s);
setAudited(ctx, BOSUuid.read(sid.toString()));
info.put("sgSuccessID", sid);
}
//更新单据状态
info.setBillState(HRBillStateEnum.AUDITED);
//审核人,审核日期
info.setAuditor(ContextUtil.getCurrentUserInfo(ctx));
info.setBizDate(new Date());
SelectorItemCollection billSelector = new SelectorItemCollection();
billSelector.add(new SelectorItemInfo("billState"));
billSelector.add(new SelectorItemInfo("sgSuccessID"));
billSelector.add(new SelectorItemInfo("sgFailureID"));
billSelector.add(new SelectorItemInfo("bizDate"));
billSelector.add(new SelectorItemInfo("auditor"));
FluctuationBizBillFactory.getLocalInstance(ctx).updatePartial(info, billSelector);
}else{ //其余的处理方式
super.setAudited(ctx, billID);
}
}
```
#### 3.2.3提交生效
```language
@Override
protected IObjectPK _submitEffect(Context ctx, CoreBaseInfo model)
throws BOSException, EASBizException {
//不直接生效,重新复制一个单子来生效
IObjectPK objectPK = super.save(ctx, model);
FluctuationBizBillInfo info = (FluctuationBizBillInfo) model;
if( info.get("isSgSumBill") == null || !(info.get("isSgSumBill") instanceof Boolean)) { //DEP如果失效,将无意义
System.out.println(info.get("isSgSumBill"));
throw new EASBizException(new NumericExceptionSubItem("001","未获取到关键字段isSgSumBill,请检查视图配置!"));
}
if(info.get("isSgSumBill") instanceof Boolean && (Boolean)info.get("isSgSumBill") == true ){
//走扩展逻辑,否则走原先逻辑
//处理事务状态运行创建新的单据,原先单据表现为审核通过 将人事事务记录中的信息设置为未审核,否则会影响填单。
System.out.println("AAA");
String billId = objectPK.toString();
String oql = "select billState,entryBizDate where billID='" + billId + "'";
IHRAffairBiz iRAffairBiz = HRAffairBizFactory.getLocalInstance(ctx);
HRAffairBizCollection affairBizColl = iRAffairBiz.getHRAffairBizCollection(oql.toString());
SelectorItemCollection selector = new SelectorItemCollection();
selector.add(new SelectorItemInfo("billState"));
if (affairBizColl.size() > 0) {
}
for(int i = 0 ; i < affairBizColl.size() ; i++){
HRAffairBizInfo bizInfo = affairBizColl.get(i);
bizInfo.setBillState(HRBillStateEnum.AUDITEND);
iRAffairBiz.updatePartial(bizInfo, selector);
}
//生成单据体
//将数据设置为未生效之后,新增一个单据。
FluctuationBizBillInfo info_s = (FluctuationBizBillInfo) info.clone();
info_s.setId(BOSUuid.create("C0DAD00D"));
info_s.put("isSgSumBill", false);
info_s.setNumber("AAA"); //系统会调用编码规则
FluctuationBizBillEntryCol