背景: 苍穹5.027 不启用携程和星瀚的标准实施方案。 二开接收OA系统的出差申请单,报销单;OA的结算单接到订单上;
本篇文章主要说明产品的代码逻辑,仅记录个人调试得到的结论,不代表真正产品的逻辑!!
一、 出差申请单下推差旅报销单,自动带出订单
以用车订单为例,自动带出出差申请单的行程的订单, 要保证订单的出差行程ID和出差申请单号和出差申请单匹配上
二、点击差旅报销单的【选择订单】按钮,是怎么去查订单的?
差旅报销单有标准插件:kd.fi.er.formplugin.trip.dailybiz.TripReimBillUpOrdersPlugin (上拉订单)
类中的具体方法: searchOrder
具体查询的类:
TripNotReimbursedOrderUtil 54行 - 过滤订单 TripNotReimbursedOrderUtil 191 查询订单: queryNotReimbursedOrdersByOrderId
①标准代码查询玩订单后,会过滤订单:根据订单的orderStatus字段过滤;
火车过滤条件 trainOrderStatus = new String[]{"1", "2", "3", "9999"}; (已出票,已改签,已退票,未知)
②、查询订单也会过滤掉那些已经被报销过的订单,即 isreimburse =0
三、 查到订单后回写差旅费用的逻辑
就是看这几个字段是怎么赋值的:(重点关注 报销金额,税率,不含税金额,抵扣税额)
代码:
在kd.fi.er.formplugin.trip.dailybiz.TripReimBillUpOrdersPlugin插件中的
closedCallBack方法中调用了
TripReimCreateOrderEntrysUtil.initOrderEntrys(dynamicObject, tripentry, travelerIdSet, orders, isShowInvoiceEntry, true, (Map)null, (DynamicObject)null, formId, (OrderExpenseDetailContext)null); initOrderEntrys方法里调用了 fillservicefee 方法: fillservicefee(targetBill, targetTripEntry, tripOrders, pullTravelOrders, true, orderExpenseDetailContext); - targetBill:上面的dynamicObject,就是差旅报销单本身 - targetTripEntry:就是差旅报销单的tripentry - tripOrders : 查到的商旅订单 - pullTravelOrders true
看不下去了,和开票设置有关。
具体看这个把:
https://vip.kingdee.com/article/509687200577859328?productLineId=2&isKnowledge=2 比看代码快多了
四、二开场景实现参考
订单合并场景: 因为服务商会把很多退票,改签的都推过来,一个差旅报销单可能出现十几个订单关联,客户想把同类型的订单都合并起来展示,金额都相加
二开方案:在保存操作直接修改订单分录
事先申明:未经过充分验证!不知道风险点!请根据实际情况和产品版本评估!
详细过程:
首先要知道差旅报销单的数据表里面有行程信息表和差旅明细表,保存了行程卡片和对应关联订单的信息,那么直接在save操作里面,操作这两个分录的合并就好了;
参考代码
super.beforeExecuteOperationTransaction(e); logger.info("差旅-合并订单"); DynamicObject[] reimburseBills = e.getDataEntities(); if(reimburseBills.length<=0) return ; DynamicObject reimburseBill = reimburseBills[0]; DynamicObjectCollection tripentry = (DynamicObjectCollection) reimburseBill.get("tripentry"); for (int i = 0; i < tripentry.size(); i++) { DynamicObject tripItem = tripentry.get(i); DynamicObjectCollection mergedOrderEntry = new DynamicObjectCollection(); DynamicObjectCollection orderEntry = (DynamicObjectCollection) tripItem.get("entryentity"); Map<String, DynamicObject> expenseItemMap = new HashMap<>(10); for (int j = 0; j < orderEntry.size(); j++) { DynamicObject orderItem = orderEntry.get(j); if (StringUtil.isEmpty((String) orderItem.get("ordernum"))) { mergedOrderEntry.add(orderItem); continue; } //费用项目:机票,火车,汽车,酒店 DynamicObject expenseitem = (DynamicObject) orderItem.get("expenseitem"); String expsenseItemBillNo = (String) expenseitem.get("longnumber"); if (!expenseItemMap.containsKey(expsenseItemBillNo)) { // 如果不存在,则将expenseitem添加到Map中 expenseItemMap.put(expsenseItemBillNo, orderItem); } else { DynamicObject finalOrder = expenseItemMap.get(expsenseItemBillNo); finalOrder = mergerCalOrder(orderItem, finalOrder); expenseItemMap.put(expsenseItemBillNo, finalOrder); } } BigDecimal tripAmount = BigDecimal.ZERO; for (String billnumber : expenseItemMap.keySet()) { DynamicObject mergerItem = expenseItemMap.get(billnumber); mergedOrderEntry.add(mergerItem); tripAmount = tripAmount.add(mergerItem.getBigDecimal("orientryamount")); } tripItem.set("entryentity", mergedOrderEntry); } }