Răsfoiți Sursa

1.新增调度任务,创建财务底稿确认单;创建补助底稿、补助信息、商旅费用信息、用车信息;
2.新增确认单操作,创建商旅对账单
3.新增通用插件,查看行数据关联的底稿、全部结算单、用车结算等
4.增加列表插件,动态查询出差人岗位及关联职级信息
5.新增商旅对账单数据过滤,部门秘书查看部门秘书的数据,出差人查看出差人的数据

lisheng 3 săptămâni în urmă
părinte
comite
35b41cbc22

+ 64 - 38
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/common/constant/travelcheck/BusTravelCheckBillConstant.java

@@ -2,6 +2,9 @@ package nckd.jimin.jyyy.fi.common.constant.travelcheck;
 
 import nckd.jimin.jyyy.fi.common.constant.BillConstant;
 
+import java.util.Arrays;
+import java.util.List;
+
 /**
  * 商旅对账单常量类
  */
@@ -18,45 +21,11 @@ public interface BusTravelCheckBillConstant extends BillConstant {
 
     String NCKD_DEPSECRETARY = "nckd_depsecretary"; // 部门秘书
 
-    String NCKD_FINANDRAFT_CONFIRM = "nckd_finandraft_confirm"; // 底稿确认单
-
-
-    interface NCKD_BZ_ENTRY{
-
-        String ENTITYID = "nckd_bz_entry";
-        String NCKD_BZ_COMPANY = "nckd_bz_company"; // 法人主体
-        String NCKD_BZ_TRAVELER = "nckd_bz_traveler"; // 出差人
-        String NCKD_BZ_TRAVELERNO = "nckd_bz_travlererno"; // 工号
-        String NCKD_BZ_SUMDAYS = "nckd_bz_sumdays"; // 出差天数合计
-        String NCKD_BZ_AMOUNT = "nckd_bz_amount"; // 补助金额
-        String NCKD_BZ_PAYERBANK = "nckd_bz_payerbank"; // 银行账号
-        String NCKD_BZ_ACCOUNT = "nckd_bz_account"; // 开户行
-        String NCKD_BZ_CHECKAMT = "nckd_bz_checkamt"; // 核定金额
-        String NCKD_BZ_DESCRIBE = "nckd_bz_describe"; // 部门反馈
-        String NCKD_BZ_DEPFULLNAME = "nckd_bz_depfullname"; // 部门名称
-        String NCKD_BZ_POST = "nckd_bz_post"; // 岗位
-        String NCKD_BZ_EXPBURNDEND = "nckd_bz_expburndend"; // 费用承担部门
-        String NCKD_BZ_EXPCOLL = "nckd_bz_expcoll"; // 费用归集说明
-        String NCKD_BZ_SUPDAYS = "nckd_bz_supdays"; // 补助未涵盖天数
-        String NCKD_BZ_TRAVELDAYS = "nckd_bz_traveldays"; // 出差天数
-        String NCKD_BZ_ADJAMOUNT = "nckd_bz_adjamount"; // 补助调整金额
-        String NCKD_BZ_FINOPINION = "nckd_bz_finopinion"; // 财务建议说明
-
-        String NCKD_BZ_FINANDRAFT = "nckd_bz_finandraft"; // 财务对账底稿
-    }
+    String NCKD_NCKD_SOURCEBILLID = "nckd_sourcebillid"; // 底稿确认单
 
-    /**
-     * 商旅费用
-     */
-    interface NCKD_SL_ENTRY {
-        String NCKD_SL_TRAVELER = "nckd_sl_traveler"; // 出差人
-        String NCKD_SL_TRAVELERNO = "nckd_sl_travlererno"; // 工号
-        String NCKD_SL_PLANPAYAMT = "nckd_sl_planpayamt"; // 机票金额
-        String NCKD_SL_TRAINPAYAMT = "nckd_sl_trainpayamt"; // 火车金额
-        String NCKD_SL_HOTELPAYAMT = "nckd_sl_hotelpayamt"; // 酒店金额
-        String NCKD_SL_ORDERAMT = "nckd_sl_orderamt"; // 合计金额
-        String NCKD_SL_SERVER = "nckd_sl_server"; // 服务商
-    }
+    List<String> BZ_EDITFIELD = Arrays.asList(NCKD_BZ_ENTRY.NCKD_BZ_SUPDAYS,NCKD_BZ_ENTRY.NCKD_BZ_SUMDAYS,NCKD_BZ_ENTRY.NCKD_BZ_ADJAMOUNT,NCKD_BZ_ENTRY.NCKD_BZ_CHECKAMT,NCKD_BZ_ENTRY.NCKD_BZ_DESCRIBE);
+    List<String> SL_EDITFIELD = Arrays.asList(NCKD_SL_ENTRY.NCKD_SL_DESCRIBE);
+    List<String> YC_EDITFIELD = Arrays.asList(NCKD_YC_ENTRY.NCKD_YC_DESCRIBE);
 
     interface NCKD_BZ_SUPDATA{
 
@@ -137,4 +106,61 @@ public interface BusTravelCheckBillConstant extends BillConstant {
         String NCKD_REMARK = "nckd_remark";
     }
 
+
+    interface NCKD_BZ_ENTRY{
+
+        String ENTITYID = "nckd_bz_entry";
+        String NCKD_BZ_INFO = "nckd_bz_info"; //补助信息
+        String NCKD_BZ_TRAVELER = "nckd_bz_traveler"; // 出差人
+        String NCKD_BZ_SUMDAYS = "nckd_bz_sumdays"; // 出差天数合计
+        String NCKD_BZ_CHECKAMT = "nckd_bz_checkamt"; // 核定金额
+        String NCKD_BZ_DESCRIBE = "nckd_bz_describe"; // 部门反馈
+        String NCKD_BZ_SUPDAYS = "nckd_bz_supdays"; // 补助未涵盖天数
+        String NCKD_BZ_ADJAMOUNT = "nckd_bz_adjamount"; // 补助调整金额
+        String NCKD_BZ_FINANDRAFT = "nckd_bz_finandraft"; // 财务对账底稿
+    }
+
+
+    /**
+     * 商旅费用
+     */
+    interface NCKD_SL_ENTRY {
+
+        String ENTITYID = "nckd_sl_entry";
+        String NCKD_SL_INFO = "nckd_sl_info"; //商旅费用信息
+        String NCKD_SL_DESCRIBE = "nckd_sl_describe"; // 部门反馈
+
+    }
+
+    /**
+     * 用车费用
+     */
+    interface NCKD_YC_ENTRY {
+        String ENTITYID = "nckd_yc";
+        String NCKD_YC_INFO = "nckd_yc_info"; //用车信息
+        String NCKD_YC_DESCRIBE = "nckd_yc_describe"; // 部门反馈
+    }
+
+    /**
+     * 超标明细
+     */
+    interface NCKD_CB_ENTRY {
+        String ENTITYID = "nckd_cb";
+    }
+
+    /**
+     * 退改明细
+     */
+    interface NCKD_TG_ENTRY {
+        String ENTITYID = "nckd_tg";
+
+    }
+
+    /**
+     * 住宿明细
+     */
+    interface NCKD_ZS_ENTRY {
+        String ENTITYID = "nckd_zs";
+    }
+
 }

+ 155 - 20
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/common/constant/travelcheck/FinanceBillConfirmConstant.java

@@ -4,36 +4,171 @@ import nckd.jimin.jyyy.fi.common.constant.BillConstant;
 
 public interface FinanceBillConfirmConstant extends BillConstant {
     String ENTITYID = "nckd_finandraft_confirm";
+    String ENTITYID_NCKD_BZ_FINANCONFIRM = "nckd_bz_financonfirm";
+
+    String ENTITYID_NCKD_SL_FINANCONFIRM = "nckd_sl_financonfirm";
+
+    String ENTITYID_NCKD_YC_FINANCONFIRM = "nckd_yc_financonfirm";
 
     /**
      * 对账期间
      */
     String NCKD_CHECKMONTH = "nckd_checkmonth";
+    /**
+     * 商旅确认补助ID
+     */
+    String NCKD_BZ_CONFRMID = "nckd_bz_confrmid";
+    /**
+     * 商旅确认商旅费用D
+     */
+    String NCKD_SL_CONFRMID = "nckd_sl_confrmid";
+    /**
+     * 商旅确认用车D
+     */
+    String NCKD_YC_CONFRMID = "nckd_yc_confrmid";
 
-    interface DETAILENTITY{
-        String ENTITYID = "detailentity";
-        /**
-         * 部门秘书
-         */
-        String NCKD_DEPSECRETARY = "nckd_depsecretary";
+    /**
+     * 下推商旅对账
+     */
+    String OP_PUSHCHECKBILL = "pushcheckbill";
 
-        /**
-         * 负责部门
-         */
-        String NCKD_CHARGE_DEPT = "nckd_charge_dept";
+    String FID = "fid";
 
-        /**
-         * 确认状态
-         */
-        String NCKD_CONFIRMSTATUS = "nckd_confirmstatus";
+    interface NCKD_BZ_ENTRY{
 
+        String ENTITYID = "nckd_bz_entry";
+        String NCKD_BZ_DEPSECRETARY = "nckd_bz_depsecretary"; //部门秘书
+        String NCKD_BZ_COMPANY = "nckd_bz_company"; // 法人主体
+        String NCKD_BZ_TRAVELER = "nckd_bz_traveler"; // 出差人
+        String NCKD_BZ_TRAVELERNO = "nckd_bz_travlererno"; // 工号
+        String NCKD_BZ_SUMDAYS = "nckd_bz_sumdays"; // 出差天数合计
+        String NCKD_BZ_AMOUNT = "nckd_bz_amount"; // 补助金额
+        String NCKD_BZ_PAYERBANK = "nckd_bz_payerbank"; // 银行账号
+        String NCKD_BZ_ACCOUNT = "nckd_bz_account"; // 开户行
+        String NCKD_BZ_CHECKAMT = "nckd_bz_checkamt"; // 核定金额
+        String NCKD_BZ_DESCRIBE = "nckd_bz_describe"; // 部门反馈
+        String NCKD_BZ_DEPFULLNAME = "nckd_bz_depfullname"; // 部门名称
+        String NCKD_BZ_POST = "nckd_bz_post"; // 岗位
+        String NCKD_BZ_EXPBURNDEND = "nckd_bz_expburndend"; // 费用承担部门
+        String NCKD_BZ_EXPCOLL = "nckd_bz_expcoll"; // 费用归集说明
+        String NCKD_BZ_SUPDAYS = "nckd_bz_supdays"; // 补助未涵盖天数
+        String NCKD_BZ_TRAVELDAYS = "nckd_bz_traveldays"; // 出差天数
+        String NCKD_BZ_ADJAMOUNT = "nckd_bz_adjamount"; // 补助调整金额
+        String NCKD_BZ_FINOPINION = "nckd_bz_finopinion"; // 财务建议说明
+
+        String NCKD_BZ_FINANDRAFT = "nckd_bz_finandraft"; // 财务对账底稿
     }
 
-    interface DRAFTENTRY{
-        String ENTITYID = "draftentry";
-        /**
-         * 财务对账底稿F7
-         */
-        String NCKD_TRAVELFINANDRAFT = "nckd_travelfinandraft";
+
+    /**
+     * 商旅费用
+     */
+    interface NCKD_SL_ENTRY {
+
+        String ENTITYID = "nckd_sl_entry";
+        String NCKD_SL_DEPSECRETARY = "nckd_sl_depsecretary"; //部门秘书
+        String NCKD_SL_TRAVELER = "nckd_sl_traveler"; // 出差人
+        String NCKD_SL_TRAVELERNO = "nckd_sl_travlererno"; // 工号
+        String NCKD_SL_PLANPAYAMT = "nckd_sl_planpayamt"; // 机票金额
+        String NCKD_SL_TRAINPAYAMT = "nckd_sl_trainpayamt"; // 火车金额
+        String NCKD_SL_HOTELPAYAMT = "nckd_sl_hotelpayamt"; // 酒店金额
+        String NCKD_SL_ORDERAMT = "nckd_sl_orderamt"; // 合计金额
+        String NCKD_SL_SERVER = "nckd_sl_server"; // 服务商
+        String NCKD_SL_COMPANY = "nckd_sl_company"; // 法人单位
+        String NCKD_SL_DEPFULLNAME = "nckd_sl_depfullname"; // 部门
+        String NCKD_SL_POST = "nckd_sl_post"; // 岗位
+        String NCKD_SL_EXPBURNDEND = "nckd_sl_expburndend"; // 费用承担部门
+        String NCKD_SL_EXPCOLL = "nckd_sl_expcoll"; // 费用归集说明
+        String NCKD_SL_FINOPINION = "nckd_sl_finopinion"; // 财务建议说明
+    }
+
+    /**
+     * 用车费用
+     */
+    interface NCKD_YC_ENTRY {
+        String ENTITYID = "nckd_yc";
+        String NCKD_YC_DEPSECRETARY = "nckd_yc_depsecretary"; //部门秘书
+        String NCKD_YC_COMPANY = "nckd_yc_company"; // 法人单位
+        String NCKD_YC_TRAVELER = "nckd_yc_traveler"; // 出差人
+        String NCKD_YC_TRAVELERNO = "nckd_yc_travlererno"; // 工号
+        String NCKD_YC_DEPFULLNAME = "nckd_yc_depfullname"; // 部门
+        String NCKD_YC_POST = "nckd_yc_post"; // 岗位
+        String NCKD_YC_TYPE = "nckd_yc_type"; // 用车类型
+        String NCKD_YC_AMOUNT = "nckd_yc_amount"; // 用车金额
+        String NCKD_YC_DESCRIBE = "nckd_yc_describe"; // 部门反馈
+        String NCKD_YC_FINOPINION = "nckd_yc_finopinion"; // 财务建议说明
+        String NCKD_YC_EXPBURNDEND = "nckd_yc_expburndend"; // 费用承担部门
+        String NCKD_YC_EXPCOLL = "nckd_yc_expcoll"; // 费用归集说明
+        String NCKD_YC_RELATEDTALS = "nckd_yc_relatedtals"; // 联查明细
+    }
+
+    /**
+     * 超标明细
+     */
+    interface NCKD_CB_ENTRY {
+        String ENTITYID = "nckd_cb";
+        String NCKD_CB_DEPSECRETARY = "nckd_cb_depsecretary"; //部门秘书
+        String NCKD_CB_COMPANY = "nckd_cb_company"; // 法人单位
+        String NCKD_CB_TRAVELER = "nckd_cb_traveler"; // 出差人
+        String NCKD_CB_TRAVELERNO = "nckd_cb_travlererno"; // 工号
+        String NCKD_CB_DEPFULLNAME = "nckd_cb_depfullname"; // 部门
+        String NCKD_CB_POST = "nckd_cb_post"; // 岗位
+        String NCKD_CB_TRIPREQBILLNO = "nckd_cb_tripreqbillno"; // 出差申请单号
+        String NCKD_CB_ORDERNUM = "nckd_cb_ordernum"; // 订单编号
+        String NCKD_CB_PARAMT = "nckd_cb_paramt"; // 订单金额
+        String NCKD_CB_TYPE = "nckd_cb_type"; // 超标类型
+        String NCKD_CB_STANDARD = "nckd_cb_standard"; // 标准
+        String NCKD_CB_EXCSTAMT = "nckd_cb_excstamt"; // 超标金额
+        String NCKD_CB_FIOPINION = "nckd_cb_fiopinion"; // 财务建议说明
+        String NCKD_CB_DESCRIBE = "nckd_cb_describe"; // 部门反馈
+        String NCKD_CB_OPINION = "nckd_cb_opinion"; // 最终结果
+    }
+
+    /**
+     * 退改明细
+     */
+    interface NCKD_TG_ENTRY {
+        String ENTITYID = "nckd_tg";
+        String NCKD_TG_DEPSECRETARY = "nckd_tg_depsecretary"; //部门秘书
+        String NCKD_TG_ORDERTYPE = "nckd_tg_ordertype"; // 订单类型
+        String NCKD_TG_TYPE = "nckd_tg_type"; // 退改类型
+        String NCKD_TG_TRAVELER = "nckd_tg_traveler"; // 出差人
+        String NCKD_TG_DEPFULLNAME = "nckd_tg_depfullname"; // 部门
+        String NCKD_TG_POST = "nckd_tg_post"; // 岗位
+        String NCKD_TG_TRIPREQBILLNO = "nckd_tg_tripreqbillno"; // 出差申请单号
+        String NCKD_TG_ORDERNUM = "nckd_tg_ordernum"; // 订单编号
+        String NCKD_TG_HAPPENDDATE = "nckd_tg_happenddate"; // 账单生成时间
+        String NCKD_TG_DEPARTIME = "nckd_tg_departime"; // 出发时间
+        String NCKD_TG_TRIPCTY = "nckd_tg_tripcty"; // 出发地点
+        String NCKD_TG_UPGRADEAMT = "nckd_tg_upgradeamt"; // 升舱费
+        String NCKD_TG_MODIFYAMT = "nckd_tg_modifyamt"; // 退改金额
+        String NCKD_TG_SUMAMT = "nckd_tg_sumamt"; // 总额
+        String NCKD_TG_REASON = "nckd_tg_reason"; // 退改原因
+        String NCKD_TG_DESCRIBE = "nckd_tg_describe"; // 部门反馈
+        String NCKD_TG_OPINION = "nckd_tg_opinion"; // 财务建议说明
+    }
+
+    /**
+     * 住宿明细
+     */
+    interface NCKD_ZS_ENTRY {
+        String ENTITYID = "nckd_zs";
+        String NCKD_ZS_DEPSECRETARY = "nckd_zs_depsecretary"; //部门秘书
+        String NCKD_ZS_SOURCEBOOKEDID = "nckd_zs_sourcebookedid"; // 预订单
+        String NCKD_ZS_SOURCEBOOKEDNO = "nckd_zs_sourcebookedno"; // 预订单号
+        String NCKD_ZS_GENDER = "nckd_zs_gender"; // 性别
+        String NCKD_ZS_DEPFULLNAME = "nckd_zs_depfullname"; // 部门
+        String NCKD_ZS_POST = "nckd_zs_post"; // 岗位
+        String NCKD_ZS_CHECKINDATE = "nckd_zs_checkindate"; // 入住日期
+        String NCKD_ZS_CHECKOUTDATE = "nckd_zs_checkoutdate"; // 离店日期
+        String NCKD_ZS_CITYNAME = "nckd_zs_cityname"; // 酒店城市
+        String NCKD_ZS_HOTELNAME = "nckd_zs_hotelname"; // 酒店名称
+        String NCKD_ZS_ROOMTYPE = "nckd_zs_roomtype"; // 房型
+        String NCKD_ZS_LIVEDAYS = "nckd_zs_livedays"; // 入住天数
+        String NCKD_ZS_TOTALAMOUNT = "nckd_zs_totalamount"; // 总价
+        String NCKD_ZS_PERSONALFEE = "nckd_zs_personalfee"; // 超标承担金额
+        String NCKD_ZS_COHABIT = "nckd_zs_cohabit"; // 同住人员
+        String NCKD_ZS_DESCRIBE = "nckd_zs_describe"; // 部门反馈
+        String NCKD_ZS_FINOPINION = "nckd_zs_finopinion"; // 财务建议说明
     }
 }

+ 22 - 0
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/common/util/CommonUtils.java

@@ -23,6 +23,8 @@ public class CommonUtils {
 
     private static final SimpleDateFormat PERIOD_FORMAT = new SimpleDateFormat("yyyy-MM");
 
+
+
     public static String parsePeriod(Date date){
         return PERIOD_FORMAT.format(date);
     }
@@ -38,6 +40,26 @@ public class CommonUtils {
         }
         return datas;
     }
+    public static String join(String... fileds){
+        return String.join(".", fileds);
+    }
+    /**
+     * 获取指定日期的开始时间(当天00:00:00)
+     * @param date 指定日期
+     * @return 当天的开始时间
+     */
+    public static Date getStartOfDay(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+
+        // 将时分秒毫秒设置为0,确保是当天的开始
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+
+        return calendar.getTime();
+    }
 
     public static JSONArray transDataSetJson(DataSet dt , String... selectFiled){
         JSONArray jsonArray = new JSONArray();

+ 117 - 31
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/form/travelcheck/BusTravelCheckBillEdit.java

@@ -1,31 +1,141 @@
 package nckd.jimin.jyyy.fi.plugin.form.travelcheck;
 
+import com.grapecity.documents.excel.Q;
 import kd.bos.bill.AbstractBillPlugIn;
+import kd.bos.context.RequestContext;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.MainEntityType;
 import kd.bos.entity.datamodel.events.PropertyChangedArgs;
 import kd.bos.form.ShowType;
 import kd.bos.form.control.EntryGrid;
+import kd.bos.form.events.BeforeDoOperationEventArgs;
 import kd.bos.form.events.HyperLinkClickEvent;
 import kd.bos.form.events.HyperLinkClickListener;
+import kd.bos.form.operate.FormOperate;
 import kd.bos.list.ListShowParameter;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import nckd.jimin.jyyy.fi.common.constant.BillConstant;
 import nckd.jimin.jyyy.fi.common.constant.travelcheck.BusTravelCheckBillConstant;
+import nckd.jimin.jyyy.fi.common.constant.travelcheck.FinanceBillConfirmConstant;
 import nckd.jimin.jyyy.fi.common.constant.travelcheck.TripReqBillConstant;
 import nckd.jimin.jyyy.fi.common.constant.travelcheck.TravelFinanDraftConstant;
 
 import java.util.EventObject;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
-public class BusTravelCheckBillEdit extends AbstractBillPlugIn implements BusTravelCheckBillConstant, HyperLinkClickListener {
+public class BusTravelCheckBillEdit extends AbstractBillPlugIn implements BusTravelCheckBillConstant {
 
     @Override
-    public void registerListener(EventObject e) {
-        super.registerListener(e);
-        EntryGrid bzEntryGrid = this.getControl(NCKD_BZ_ENTRY.ENTITYID);
-        bzEntryGrid.addHyperClickListener(this);
+    public void beforeBindData(EventObject e) {
+        super.beforeBindData(e);
+        loadDataFromConfirmBill();
+
+        // 重新计算分录补助
+        int entryRowCount = getModel().getEntryRowCount(NCKD_BZ_SUPDATA.ENTITYID);
+        IntStream.range(0, entryRowCount).forEach(this::updateBzEntryFromUnCoveredData);
+    }
+
+    @Override
+    public void beforeDoOperation(BeforeDoOperationEventArgs args) {
+        super.beforeDoOperation(args);
+        FormOperate operate = (FormOperate)args.getSource();
+        String operateKey = operate.getOperateKey();
+        if("save".equals(operateKey) || "submit".equals(operateKey)){
+            writeBackConfirmBill();
+        }
+
+    }
+
+    protected void writeBackConfirmBill(){
+        writeBackConfirmBillEntryData(NCKD_BZ_ENTRY.ENTITYID,NCKD_BZ_ENTRY.NCKD_BZ_INFO,FinanceBillConfirmConstant.ENTITYID_NCKD_BZ_FINANCONFIRM,BZ_EDITFIELD);
+        writeBackConfirmBillEntryData(NCKD_SL_ENTRY.ENTITYID,NCKD_SL_ENTRY.NCKD_SL_INFO,FinanceBillConfirmConstant.ENTITYID_NCKD_SL_FINANCONFIRM,SL_EDITFIELD);
+        writeBackConfirmBillEntryData(NCKD_YC_ENTRY.ENTITYID,NCKD_YC_ENTRY.NCKD_YC_INFO,FinanceBillConfirmConstant.ENTITYID_NCKD_YC_FINANCONFIRM,YC_EDITFIELD);
+    }
+
+    protected void writeBackConfirmBillEntryData(String entryName , String keyField , String sourceEntity, List<String> filedList){
+        DynamicObjectCollection entryEntity = this.getModel().getEntryEntity(entryName);
+        Map<Object, DynamicObject> keyFiledMap = entryEntity.stream().collect(Collectors.toMap(r -> r.getDynamicObject(keyField).getPkValue(), r -> r, (r1, r2) -> r2));
+        List<Object> entryIdList = entryEntity.stream().map(r -> r.getDynamicObject(keyField).getPkValue()).collect(Collectors.toList());
+        MainEntityType sourceEntityType = EntityMetadataCache.getDataEntityType(sourceEntity);
+        // 来源分录字段
+        DynamicObject[] entryDataArray = BusinessDataServiceHelper.load(entryIdList.toArray(), sourceEntityType);
+        // 当前分录字段
+        for(DynamicObject entryData : entryDataArray){
+            Object entryId = entryData.getPkValue();
+            if(keyFiledMap.containsKey(entryId)){
+                DynamicObject entryInfo = keyFiledMap.get(entryId);
+                for(String field : filedList){
+                    entryData.set(field, entryInfo.get(field));
+                }
+            }
+        }
+        SaveServiceHelper.save(entryDataArray);
+    }
+
+    /**
+     * 从财务确认单上带出数据
+     */
+    protected void loadDataFromConfirmBill(){
+        long currUserId = RequestContext.get().getCurrUserId();
+        DynamicObject dataEntity = getModel().getDataEntity();
+        DynamicObject depSecretary = dataEntity.getDynamicObject(BusTravelCheckBillConstant.NCKD_DEPSECRETARY);
+        long sourceBillId = dataEntity.getLong(BusTravelCheckBillConstant.NCKD_NCKD_SOURCEBILLID);
+        DynamicObject confirmBillInfo = BusinessDataServiceHelper.loadSingle(sourceBillId, FinanceBillConfirmConstant.ENTITYID);
+        // 如果是部门秘书,通过部门秘书过滤,如果不是部门秘书,通过出差人过滤
+        if(depSecretary == null || sourceBillId == 0L){
+            return;
+        }
+        QFilter filter = new QFilter(FinanceBillConfirmConstant.FID, QCP.equals, confirmBillInfo.getPkValue());
+        if(depSecretary.getPkValue().equals(currUserId)){
+            loadEntryData(NCKD_BZ_ENTRY.ENTITYID,NCKD_BZ_ENTRY.NCKD_BZ_INFO,FinanceBillConfirmConstant.ENTITYID_NCKD_BZ_FINANCONFIRM,
+                    new QFilter(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_DEPSECRETARY, QCP.equals, currUserId).and(filter),BZ_EDITFIELD);
+            loadEntryData(NCKD_SL_ENTRY.ENTITYID,NCKD_SL_ENTRY.NCKD_SL_INFO,FinanceBillConfirmConstant.ENTITYID_NCKD_SL_FINANCONFIRM,
+                    new QFilter(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_DEPSECRETARY, QCP.equals, currUserId).and( filter),SL_EDITFIELD);
+            loadEntryData(NCKD_YC_ENTRY.ENTITYID,NCKD_YC_ENTRY.NCKD_YC_INFO,FinanceBillConfirmConstant.ENTITYID_NCKD_YC_FINANCONFIRM,
+                    new QFilter(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_DEPSECRETARY, QCP.equals, currUserId).and( filter),YC_EDITFIELD);
+        }else{
+            loadEntryData(NCKD_BZ_ENTRY.ENTITYID,NCKD_BZ_ENTRY.NCKD_BZ_INFO,FinanceBillConfirmConstant.ENTITYID_NCKD_BZ_FINANCONFIRM,
+                    new QFilter(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_TRAVELER, QCP.equals, currUserId).and( filter),BZ_EDITFIELD);
+            loadEntryData(NCKD_SL_ENTRY.ENTITYID,NCKD_SL_ENTRY.NCKD_SL_INFO,FinanceBillConfirmConstant.ENTITYID_NCKD_SL_FINANCONFIRM,
+                    new QFilter(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_TRAVELER, QCP.equals, currUserId).and( filter),SL_EDITFIELD);
+            loadEntryData(NCKD_YC_ENTRY.ENTITYID,NCKD_YC_ENTRY.NCKD_YC_INFO,FinanceBillConfirmConstant.ENTITYID_NCKD_YC_FINANCONFIRM,
+                    new QFilter(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_TRAVELER, QCP.equals, currUserId).and( filter),YC_EDITFIELD);
+        }
+    }
+
+    protected void loadEntryData(String entryName , String keyField , String sourceEntity, QFilter filters , List<String> filedList){
+        // 查询ID
+        DynamicObjectCollection queryEntryData = QueryServiceHelper.query(sourceEntity, BillConstant.ID, filters.toArray());
+        if(queryEntryData == null || queryEntryData.size() == 0){
+            return ;
+        }
+        List<Long> entryIdList = queryEntryData.stream().map(r -> r.getLong(BillConstant.ID)).collect(Collectors.toList());
+        MainEntityType sourceEntityType = EntityMetadataCache.getDataEntityType(sourceEntity);
+        // 来源分录字段
+        DynamicObject[] entryDataArray = BusinessDataServiceHelper.load(entryIdList.toArray(), sourceEntityType);
+        // 当前分录字段
+        getModel().deleteEntryData(entryName);
+        getModel().batchCreateNewEntryRow(entryName, entryDataArray.length);
+        for(int i = 0; i < entryDataArray.length; i++){
+            DynamicObject entryData = entryDataArray[i];
+            getModel().setValue(keyField, entryData,i);
+            for(String field : filedList){
+                getModel().setValue(field, entryData.get( field),i);
+            }
+        }
     }
 
+
     @Override
     public void propertyChanged(PropertyChangedArgs e) {
         super.propertyChanged(e);
@@ -34,37 +144,13 @@ public class BusTravelCheckBillEdit extends AbstractBillPlugIn implements BusTra
         Object oldValue = e.getChangeSet()[0].getOldValue();
         Object newValue = e.getChangeSet()[0].getNewValue();
         // 出差申请单号
-        if(NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL.equals(name)){
+        if(BusTravelCheckBillConstant.NCKD_BZ_SUPDATA.NCKD_TRIPREQBILL.equals(name)){
             tripReqBillChanged(oldValue, newValue, rowIndex);
         }
-        if(NCKD_BZ_SUPDATA.NCKD_SUPDAYS.equals( name) || NCKD_BZ_SUPDATA.NCKD_SUAPMT.equals(name)){
+        if(BusTravelCheckBillConstant.NCKD_BZ_SUPDATA.NCKD_SUPDAYS.equals( name) || BusTravelCheckBillConstant.NCKD_BZ_SUPDATA.NCKD_SUAPMT.equals(name)){
             updateBzEntryFromUnCoveredData(rowIndex);
         }
     }
-
-    @Override
-    public void hyperLinkClick(HyperLinkClickEvent event) {
-        String fieldName = event.getFieldName();
-        int rowIndex = event.getRowIndex();
-        if(NCKD_BZ_ENTRY.NCKD_BZ_TRAVELER.equals(fieldName)){
-            DynamicObjectCollection finanDraftCol = (DynamicObjectCollection)this.getModel().getValue(NCKD_BZ_ENTRY.NCKD_BZ_FINANDRAFT, rowIndex);
-            List<Long> draftIdList = finanDraftCol.stream().map(r -> r.getDynamicObject(KEY_FBASEDATAID).getLong(ID)).collect(Collectors.toList());
-
-            ListShowParameter showParameter = new ListShowParameter();
-            showParameter.setBillFormId(TravelFinanDraftConstant.ENTITYID);
-            showParameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);
-            showParameter.setShowFilter(false);
-            showParameter.setShowQuickFilter(false);
-            for(Object draftId : draftIdList){
-                showParameter.addLinkQueryPkId(draftId);
-            }
-            showParameter.getCustomParams().put("showdetail", "true");
-            this.getView().showForm(showParameter);
-
-        }
-    }
-
-
     protected void tripReqBillChanged(Object oldValue , Object newValue, int rowIndex){
         if(oldValue != null){
             DynamicObject tripReqBill = (DynamicObject) oldValue;

+ 105 - 0
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/form/travelcheck/BusTravelCommonEdit.java

@@ -0,0 +1,105 @@
+package nckd.jimin.jyyy.fi.plugin.form.travelcheck;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.form.ShowType;
+import kd.bos.form.control.EntryGrid;
+import kd.bos.form.events.HyperLinkClickEvent;
+import kd.bos.form.events.HyperLinkClickListener;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.list.ListFilterParameter;
+import kd.bos.list.ListShowParameter;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import nckd.jimin.jyyy.fi.common.constant.travelcheck.BusTravelCheckBillConstant;
+import nckd.jimin.jyyy.fi.common.constant.travelcheck.FinanceBillConfirmConstant;
+import nckd.jimin.jyyy.fi.common.constant.travelcheck.TravelFinanDraftConstant;
+import nckd.jimin.jyyy.fi.common.constant.travelcheck.TripReqBillConstant;
+import nckd.jimin.jyyy.fi.common.util.CommonUtils;
+
+import java.util.EventObject;
+import java.util.List;
+
+public class BusTravelCommonEdit extends AbstractFormPlugin implements FinanceBillConfirmConstant, HyperLinkClickListener {
+
+
+    @Override
+    public void registerListener(EventObject e) {
+        super.registerListener(e);
+        EntryGrid bzEntryGrid = this.getControl(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.ENTITYID);
+        bzEntryGrid.addHyperClickListener(this);
+
+        EntryGrid slEntryGrid = this.getControl(BusTravelCheckBillConstant.NCKD_SL_ENTRY.ENTITYID);
+        slEntryGrid.addHyperClickListener(this);
+
+        EntryGrid ycEntryGrid = this.getControl(BusTravelCheckBillConstant.NCKD_YC_ENTRY.ENTITYID);
+        ycEntryGrid.addHyperClickListener(this);
+    }
+
+
+
+    @Override
+    public void hyperLinkClick(HyperLinkClickEvent event) {
+        String fieldName = event.getFieldName();
+        int rowIndex = event.getRowIndex();
+        DynamicObject dataEntity = getModel().getDataEntity();
+        String name = dataEntity.getDynamicObjectType().getName();
+        Long confirmBilId = ENTITYID.equals(name) ? dataEntity.getLong(ID) : dataEntity.getLong(BusTravelCheckBillConstant.NCKD_NCKD_SOURCEBILLID);
+        // 补助 打开 商旅补助列表
+        if (NCKD_BZ_ENTRY.NCKD_BZ_TRAVELER.equals(fieldName)) {
+            DynamicObject entryInfo = getModel().getEntryRowEntity(NCKD_BZ_ENTRY.ENTITYID, rowIndex);
+
+            DynamicObject traveler = ENTITYID.equals(name) ? entryInfo.getDynamicObject(NCKD_BZ_ENTRY.NCKD_BZ_TRAVELER)
+                    : entryInfo.getDynamicObject(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.NCKD_BZ_INFO).getDynamicObject(NCKD_BZ_ENTRY.NCKD_BZ_TRAVELER);
+
+            ListShowParameter showParameter = new ListShowParameter();
+            showParameter.setBillFormId(TravelFinanDraftConstant.ENTITYID);
+            showParameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);
+            showParameter.setShowFilter(false);
+            showParameter.setCustomParam("showdetail",true);
+            // 查询出差人下的单据
+            ListFilterParameter listFilterParameter = showParameter.getListFilterParameter();
+            List<QFilter> qFilters = listFilterParameter.getQFilters();
+            qFilters.add(new QFilter(NCKD_BZ_CONFRMID, QCP.equals, confirmBilId));
+            qFilters.add(new QFilter(CommonUtils.join(TravelFinanDraftConstant.NCKD_TRIPREQBILL, TripReqBillConstant.APPLIER), QCP.equals, traveler.getLong(ID)));
+            this.getView().showForm(showParameter);
+        }
+
+        // 商旅费用 打开 全部结算单列表界面
+        if (NCKD_SL_ENTRY.NCKD_SL_TRAVELER.equals(fieldName)) {
+            DynamicObject entryInfo = getModel().getEntryRowEntity(NCKD_SL_ENTRY.ENTITYID, rowIndex);
+
+            DynamicObject traveler = ENTITYID.equals(name) ? entryInfo.getDynamicObject(NCKD_SL_ENTRY.NCKD_SL_TRAVELER)
+                    : entryInfo.getDynamicObject(BusTravelCheckBillConstant.NCKD_SL_ENTRY.NCKD_SL_INFO).getDynamicObject(NCKD_SL_ENTRY.NCKD_SL_TRAVELER);
+
+            ListShowParameter showParameter = new ListShowParameter();
+            showParameter.setBillFormId("er_allcheckingbill");
+            showParameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);
+            showParameter.setShowFilter(false);
+            // 查询出差人下的单据
+            ListFilterParameter listFilterParameter = showParameter.getListFilterParameter();
+            List<QFilter> qFilters = listFilterParameter.getQFilters();
+            qFilters.add(new QFilter(NCKD_SL_CONFRMID, QCP.equals, confirmBilId));
+            qFilters.add(new QFilter("sourcebookedid", QCP.equals, traveler.getLong(ID)));
+            this.getView().showForm(showParameter);
+        }
+
+        // 用车 打开 用车结算单列表界面
+        if (NCKD_YC_ENTRY.NCKD_YC_TRAVELER.equals(fieldName)) {
+            DynamicObject entryInfo = getModel().getEntryRowEntity(NCKD_YC_ENTRY.ENTITYID, rowIndex);
+
+            DynamicObject traveler = ENTITYID.equals(name) ? entryInfo.getDynamicObject(NCKD_YC_ENTRY.NCKD_YC_TRAVELER)
+                    : entryInfo.getDynamicObject(BusTravelCheckBillConstant.NCKD_YC_ENTRY.NCKD_YC_INFO).getDynamicObject(NCKD_YC_ENTRY.NCKD_YC_TRAVELER);
+
+            ListShowParameter showParameter = new ListShowParameter();
+            showParameter.setBillFormId("er_vehiclecheckingbill");
+            showParameter.getOpenStyle().setShowType(ShowType.MainNewTabPage);
+            showParameter.setShowFilter(false);
+            // 查询出差人下的单据
+            ListFilterParameter listFilterParameter = showParameter.getListFilterParameter();
+            List<QFilter> qFilters = listFilterParameter.getQFilters();
+            qFilters.add(new QFilter(NCKD_YC_CONFRMID, QCP.equals, confirmBilId));
+            qFilters.add(new QFilter("sourcebookedid", QCP.equals, traveler.getLong(ID)));
+            this.getView().showForm(showParameter);
+        }
+    }
+}

+ 0 - 264
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/form/travelcheck/FinanDraftConfirmEdit.java

@@ -26,269 +26,5 @@ import java.util.stream.Collectors;
  */
 public class FinanDraftConfirmEdit extends AbstractBillPlugIn {
 
-    /**
-     * 下推商旅对账
-     */
-    private static final String OPERATE_PUSHCHECKBILL = "pushcheckbill";
 
-    @Override
-    public void afterCreateNewData(EventObject e) {
-        super.afterCreateNewData(e);
-        FormShowParameter parameter = this.getView().getFormShowParameter();
-        OperationStatus status = parameter.getStatus();
-        if(OperationStatus.ADDNEW.equals(status)){
-            // 新建界面赋值
-            initDataCreateNew();
-        }
-    }
-
-    @Override
-    public void afterDoOperation(AfterDoOperationEventArgs args) {
-        super.afterDoOperation(args);
-
-        String operateKey = args.getOperateKey();
-        if(args.getOperationResult() == null || !args.getOperationResult().isSuccess()){
-            return;
-        }
-        if(OPERATE_PUSHCHECKBILL.equals(operateKey)){
-            createBusTravelCheckBill();
-        }
-
-    }
-
-    protected void createBusTravelCheckBill() {
-        DynamicObject billInfo = getModel().getDataEntity(true);
-        DynamicObjectCollection detailEntryCol = billInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.DETAILENTITY.ENTITYID);
-        List<String> operateDescList = new ArrayList<>();
-        detailEntryCol.stream().forEach(detailEntry -> operateDescList.add(createBusTravelCheckBillByDetail(billInfo,detailEntry)));
-        getView().showMessage(String.join("\n", operateDescList));
-    }
-
-    protected String createBusTravelCheckBillByDetail(DynamicObject confirmBillInfo, DynamicObject detailEntry) {
-        Long financeBillConfirmId = confirmBillInfo.getLong(FinanceBillConfirmConstant.ID);
-        Long depSecretrayId = detailEntry.getDynamicObject(FinanceBillConfirmConstant.DETAILENTITY.NCKD_DEPSECRETARY).getLong(FinanceBillConfirmConstant.ID);
-        String depSecretrayName = detailEntry.getDynamicObject(FinanceBillConfirmConstant.DETAILENTITY.NCKD_DEPSECRETARY).getString(FinanceBillConfirmConstant.KEY_NAME);
-
-        DynamicObject queryCheckBillInfo = QueryServiceHelper.queryOne(BusTravelCheckBillConstant.ENTITYID, BusTravelCheckBillConstant.KEY_BILLNO, new QFilter[]{
-                new QFilter(BusTravelCheckBillConstant.NCKD_FINANDRAFT_CONFIRM, QCP.equals, financeBillConfirmId),
-                new QFilter(BusTravelCheckBillConstant.NCKD_DEPSECRETARY, QCP.equals, depSecretrayId)
-        });
-
-        if(queryCheckBillInfo != null){
-            return String.format("部门秘书【%s】已存在商旅对账单【%s】", depSecretrayName, queryCheckBillInfo.getString(BusTravelCheckBillConstant.KEY_BILLNO));
-        }
-
-        DynamicObject busTavelCheckBillInfo = BusinessDataServiceHelper.newDynamicObject(BusTravelCheckBillConstant.ENTITYID);
-        String number = CodeRuleServiceHelper.getNumber(BusTravelCheckBillConstant.ENTITYID, busTavelCheckBillInfo, null);
-        busTavelCheckBillInfo.set(BusTravelCheckBillConstant.KEY_BILLNO, number);
-        busTavelCheckBillInfo.set(BusTravelCheckBillConstant.NCKD_CHECKMONTH, confirmBillInfo.getString(FinanceBillConfirmConstant.NCKD_CHECKMONTH));
-        busTavelCheckBillInfo.set(BusTravelCheckBillConstant.NCKD_DEPSECRETARY, detailEntry.get(FinanceBillConfirmConstant.DETAILENTITY.NCKD_DEPSECRETARY));
-        busTavelCheckBillInfo.set(BusTravelCheckBillConstant.NCKD_FINANDRAFT_CONFIRM, financeBillConfirmId);
-
-        DynamicObjectCollection draftEntryCol = detailEntry.getDynamicObjectCollection(FinanceBillConfirmConstant.DRAFTENTRY.ENTITYID);
-        DynamicObjectCollection bzEntryCol = busTavelCheckBillInfo.getDynamicObjectCollection(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.ENTITYID);
-
-        // 创建差旅补助汇总分录
-        createCheckBzEntry(bzEntryCol,draftEntryCol);
-
-        SaveServiceHelper.save(new DynamicObject[]{ busTavelCheckBillInfo });
-        return String.format("部门秘书【%s】成功创建商旅对账单【%s】", depSecretrayName, busTavelCheckBillInfo.getString(BusTravelCheckBillConstant.KEY_BILLNO));
-    }
-
-    protected void createCheckBzEntry(DynamicObjectCollection bzEntryCol,DynamicObjectCollection draftEntryCol){
-        List<Object> draftBillIdList = draftEntryCol.stream().map(r -> r.getDynamicObject(FinanceBillConfirmConstant.DRAFTENTRY.NCKD_TRAVELFINANDRAFT).getPkValue()).collect(Collectors.toList());
-
-        DynamicObject[] draftBillArray = BusinessDataServiceHelper.load(draftBillIdList.toArray(), EntityMetadataCache.getDataEntityType(TravelFinanDraftConstant.ENTITYID_F7));
-
-        // 按照出差人分组
-        Map<Long, List<DynamicObject>> applyGroupMap = Arrays.stream(draftBillArray)
-                .collect(Collectors.groupingBy(r -> r.getDynamicObject(TravelFinanDraftConstant.NCKD_TRIPREQBILL).getDynamicObject(TripReqBillConstant.APPLIER).getLong(TripReqBillConstant.ID)));
-
-        for(Map.Entry<Long, List<DynamicObject>> applierRow : applyGroupMap.entrySet()){
-            DynamicObject bzEntry = bzEntryCol.addNew();
-            Long applierId = applierRow.getKey();
-            List<DynamicObject> applierDraftList = applierRow.getValue();
-            int sumDays = 0 ;
-            BigDecimal sumAmount = BigDecimal.ZERO;
-            for(DynamicObject draftEntry : applierDraftList){
-                sumDays += draftEntry.getInt(TravelFinanDraftConstant.NCKD_SUMDAYS);
-                sumAmount = sumAmount.add(draftEntry.getBigDecimal(TravelFinanDraftConstant.NCKD_AMOUNT));
-            }
-            DynamicObject applierInfo = BusinessDataServiceHelper.loadSingleFromCache(applierId, "bos_user");
-            bzEntry.set(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.NCKD_BZ_TRAVELER, applierInfo);
-            bzEntry.set(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.NCKD_BZ_TRAVELDAYS, sumDays);
-            bzEntry.set(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.NCKD_BZ_AMOUNT, sumAmount);
-            // 设置出差人信息,工号、部门、岗位。 银行账户、开户行
-            createApplierInfo(bzEntry);
-
-            // 设置关联底稿
-            DynamicObjectCollection multiDraftCol = bzEntry.getDynamicObjectCollection(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.NCKD_BZ_FINANDRAFT);
-            applierDraftList.stream().forEach(draftEntry -> multiDraftCol.addNew().set(BusTravelCheckBillConstant.KEY_FBASEDATAID, draftEntry));
-        }
-    }
-
-    protected void createApplierInfo(DynamicObject bzEntry){
-        DynamicObject traveler = bzEntry.getDynamicObject(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.NCKD_BZ_TRAVELER);
-        if(traveler != null){
-            // 获取员工信息
-            DynamicObject userInfo = QueryServiceHelper.queryOne("bos_user", "number,entryentity.orgstructure.fullname,entryentity.post.name",
-                    new QFilter(BusTravelCheckBillConstant.ID, QCP.equals, traveler.getLong(BusTravelCheckBillConstant.ID)).toArray());
-            //bzEntry.set(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.NCKD_BZ_TRAVELERNO, userInfo.getString("number"));
-            bzEntry.set(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.NCKD_BZ_DEPFULLNAME, userInfo.getString("entryentity.orgstructure.fullname"));
-            bzEntry.set(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.NCKD_BZ_POST, userInfo.getString("entryentity.post.name"));
-
-            // 获取收款账户信息
-//            DynamicObject payeerInfo = QueryServiceHelper.queryOne("er_payeer", "bankaccount,bankaccount.bank",new QFilter[]{
-//                    new QFilter("payer", QCP.equals, traveler.getLong(BusTravelCheckBillConstant.ID)),
-//                    new QFilter("isdefault", QCP.equals, Boolean.TRUE)
-//            });
-//            if(payeerInfo != null){
-//                bzEntry.set(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.NCKD_BZ_ACCOUNT, payeerInfo.get("payeraccount"));
-//                bzEntry.set(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.NCKD_BZ_PAYERBANK, payeerInfo.get("payerbank"));
-//            }
-            // 收款信息通过薪酬发放设置hsas_paysetting中获取
-            DynamicObject hrPaySetting = QueryServiceHelper.queryOne("hsas_paysetting", "entryentity.perbankcard.bankcardnum,entryentity.perbankcard.bankdeposit", new QFilter[]{
-                    new QFilter("salaryfile.person.number", QCP.equals, traveler.getString("number")),
-                    new QFilter("iscurrentversion", QCP.equals, "1"),
-                    new QFilter("datastatus", QCP.equals, "1"),
-                    new QFilter("entryentity.perbankcard.accountrelation.number", QCP.equals, "1010_S")
-            });
-            if(hrPaySetting != null){
-                bzEntry.set(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.NCKD_BZ_ACCOUNT, hrPaySetting.getString("entryentity.perbankcard.bankcardnum"));
-                bzEntry.set(BusTravelCheckBillConstant.NCKD_BZ_ENTRY.NCKD_BZ_PAYERBANK, hrPaySetting.get("entryentity.perbankcard.bankdeposit"));
-            }
-        }
-    }
-
-    protected void initDataCreateNew(){
-        // 单头字段赋值
-        String period = CommonUtils.parsePeriod(new Date());
-        getModel().setValue(FinanceBillConfirmConstant.NCKD_CHECKMONTH, period);
-        // 详情分录赋值
-        initDetailEntryData();
-    }
-
-    protected void initDetailEntryData(){
-        Map<Long, List<Long>> depSecretaryOrgMap = getDepSecretaryOrgMap();
-
-        DynamicObjectCollection detailEntryCol = this.getModel().getDataEntity(true).getDynamicObjectCollection(FinanceBillConfirmConstant.DETAILENTITY.ENTITYID);
-        detailEntryCol.clear();
-
-        // 创建对账明细
-        depSecretaryOrgMap.forEach((secreataryId, deptIds) -> createDetailEntry(detailEntryCol,secreataryId, deptIds));
-
-        //getView().updateView(FinanceBillConfirmConstant.DETAILENTITY.ENTITYID);
-
-    }
-
-    protected void createDetailEntry(DynamicObjectCollection detailEntryCol,Long secreataryId, List<Long> deptIds) {
-
-        Set<Long> draftIds = QueryServiceHelper.query(TravelFinanDraftConstant.ENTITYID, TravelFinanDraftConstant.ID, new QFilter[]{
-                new QFilter(TravelFinanDraftConstant.NCKD_DEPT, QFilter.in, deptIds),
-                new QFilter(TravelFinanDraftConstant.NCKD_CONFIRMSTATUS, QFilter.equals, TravelFinanDraftConstant.ConfirmStatus.TOCONFIRM),
-        }).stream().map(r -> r.getLong(TravelFinanDraftConstant.ID)).collect(Collectors.toSet());
-        if(CollectionUtils.isEmpty(draftIds)){
-            // 没有待确认商旅财务对账底稿数据,不创建
-            return;
-        }
-
-        DynamicObject detailEntry = detailEntryCol.addNew();
-        DynamicObject secreatary = BusinessDataServiceHelper.loadSingleFromCache(secreataryId, "bos_user");
-        detailEntry.set(FinanceBillConfirmConstant.DETAILENTITY.NCKD_DEPSECRETARY, secreatary);
-        DynamicObjectCollection multiDeptCol = detailEntry.getDynamicObjectCollection(FinanceBillConfirmConstant.DETAILENTITY.NCKD_CHARGE_DEPT);
-
-        Map<Object, DynamicObject> deptMap = BusinessDataServiceHelper.loadFromCache(deptIds.toArray(), "bos_org");
-        deptIds.stream().forEach(deptId -> multiDeptCol.addNew().set(FinanceBillConfirmConstant.KEY_FBASEDATAID, deptMap.get(deptId)));
-
-        DynamicObjectCollection draftEntryCol = detailEntry.getDynamicObjectCollection(FinanceBillConfirmConstant.DRAFTENTRY.ENTITYID);
-        DynamicObject[] draftArray = BusinessDataServiceHelper.load(draftIds.toArray(), EntityMetadataCache.getDataEntityType(TravelFinanDraftConstant.ENTITYID_F7));
-
-        List<DynamicObject> draftList = Arrays.asList(draftArray);
-        // 移除秘书管辖部门中,配置了特殊人员的出差人数据
-        removeSecretarySetting(draftList,deptIds);
-        // 添加秘书管辖部门中,配置了特殊人员的出差人数据
-        addSecretarySetting(draftList,deptIds);
-        draftList.forEach(draftInfo -> draftEntryCol.addNew().set(FinanceBillConfirmConstant.DRAFTENTRY.NCKD_TRAVELFINANDRAFT, draftInfo));
-    }
-
-    protected void removeSecretarySetting(List<DynamicObject> draftList,List<Long> deptIds) {
-        // 查询特殊秘书特殊人员配置
-        List<DynamicObject> secretarySpeSettingCol = getSecretarySpeSettingCol();
-        // 移除配置了部门特殊人员配置的底稿
-        Map<Object, DynamicObject> applierBelongOrgMap = secretarySpeSettingCol.stream()
-                .filter(r -> deptIds.contains(r.getDynamicObject(SecretarySpeSettingConstant.NCKD_ORG_BELONG).getPkValue()))
-                .collect(Collectors.toMap(r -> r.getDynamicObject(SecretarySpeSettingConstant.NCKD_USER).getPkValue(),
-                        r -> r, (v1, v2) -> v1));
-
-
-        Iterator<DynamicObject> iterator = draftList.iterator();
-        while (iterator.hasNext()){
-            DynamicObject draftInfo = iterator.next();
-            Object applierId = draftInfo.getDynamicObject(TravelFinanDraftConstant.NCKD_TRIPREQBILL).getDynamicObject(TripReqBillConstant.APPLIER).getPkValue();
-            if(applierBelongOrgMap.containsKey(applierId)){
-                DynamicObject speSetting = applierBelongOrgMap.get(applierId);
-                if(speSetting != null && draftInfo.getDynamicObject(TravelFinanDraftConstant.NCKD_DEPT).getPkValue()
-                        .equals(speSetting.getDynamicObject(SecretarySpeSettingConstant.NCKD_ORG_BELONG).getPkValue())){
-                    // 移除
-                    iterator.remove();
-                }
-            }
-        }
-    }
-
-    protected void addSecretarySetting(List<DynamicObject> draftList,List<Long> deptIds) {
-        List<DynamicObject> secretarySpeSettingCol = getSecretarySpeSettingCol();
-
-        Map<Object, DynamicObject> applierCheckOrgMap = secretarySpeSettingCol.stream()
-                .filter(r -> deptIds.contains(r.getDynamicObject(SecretarySpeSettingConstant.NCKD_ORG_CHECK).getPkValue()))
-                .collect(Collectors.toMap(r -> r.getDynamicObject(SecretarySpeSettingConstant.NCKD_USER).getPkValue(),
-                        r -> r, (v1, v2) -> v1));
-        Set<Long> otherDeptApplierData = new HashSet<>();
-        applierCheckOrgMap.forEach( (applierId, secretarySpeSetting) -> otherDeptApplierData.addAll(
-                getDeptApplierData(applierId, secretarySpeSetting.getDynamicObject(SecretarySpeSettingConstant.NCKD_ORG_CHECK).getPkValue())
-        ));
-        DynamicObject[] draftArray = BusinessDataServiceHelper.load(otherDeptApplierData.toArray(), EntityMetadataCache.getDataEntityType(TravelFinanDraftConstant.ENTITYID_F7));
-        draftList.addAll(Arrays.asList(draftArray));
-
-    }
-
-    protected Set<Long> getDeptApplierData(Object applierId , Object deptId){
-        return QueryServiceHelper.query(TravelFinanDraftConstant.ENTITYID, TravelFinanDraftConstant.ID, new QFilter[]{
-                new QFilter(TravelFinanDraftConstant.NCKD_DEPT, QFilter.equals, deptId),
-                new QFilter(String.join(",", TravelFinanDraftConstant.NCKD_TRIPREQBILL,TripReqBillConstant.APPLIER), QFilter.equals, applierId),
-                new QFilter(TravelFinanDraftConstant.NCKD_CONFIRMSTATUS, QFilter.equals, TravelFinanDraftConstant.ConfirmStatus.TOCONFIRM),
-        }).stream().map(r -> r.getLong(TravelFinanDraftConstant.ID)).collect(Collectors.toSet());
-    }
-
-
-    protected Map<Long, List<Long>> getDepSecretaryOrgMap() {
-        DynamicObject[] depSecretaryArray = BusinessDataServiceHelper.load(DepSecretaryConstant.ENTITYID,
-                String.join(",", DepSecretaryConstant.NCKD_SECRETARY, DepSecretaryConstant.ENTITYID_ENTRY, DepSecretaryConstant.NCKD_ORG), new QFilter[]{
-                        new QFilter(DepSecretaryConstant.KEY_STATUS, QFilter.equals, "C"),
-                        new QFilter(DepSecretaryConstant.KEY_ENABLE, QFilter.equals, Boolean.TRUE)
-                });
-
-        // 部门秘书和及关联的组织映射
-        return Arrays.stream(depSecretaryArray).collect(Collectors.toMap(
-                r -> r.getDynamicObject(DepSecretaryConstant.NCKD_SECRETARY).getLong(DepSecretaryConstant.ID),
-                r -> r.getDynamicObjectCollection(DepSecretaryConstant.ENTITYID_ENTRY).stream()
-
-
-                        .map(entry -> entry.getDynamicObject(DepSecretaryConstant.NCKD_ORG).getLong(DepSecretaryConstant.ID))
-                        .collect(Collectors.toList()),
-                (a, b) -> a));
-
-    }
-
-    protected List<DynamicObject> getSecretarySpeSettingCol() {
-        List<Long> idList = QueryServiceHelper.query(SecretarySpeSettingConstant.ENTITYID, SecretarySpeSettingConstant.ID, new QFilter[]{
-                QFilter.isNotNull(SecretarySpeSettingConstant.NCKD_ORG_CHECK),
-                QFilter.isNotNull(SecretarySpeSettingConstant.NCKD_ORG_BELONG),
-                new QFilter(SecretarySpeSettingConstant.KEY_STATUS, QFilter.equals, "C"),
-                new QFilter(SecretarySpeSettingConstant.KEY_ENABLE, QFilter.equals, Boolean.TRUE)
-        }).stream().map(r -> r.getLong(SecretarySpeSettingConstant.ID)).collect(Collectors.toList());
-        return Arrays.stream(BusinessDataServiceHelper.load(idList.toArray(), EntityMetadataCache.getDataEntityType(SecretarySpeSettingConstant.ENTITYID)))
-                .filter(r -> r.getDynamicObject(SecretarySpeSettingConstant.NCKD_ORG_CHECK).getPkValue().equals(r.getDynamicObject(SecretarySpeSettingConstant.NCKD_ORG_BELONG).getPkValue()))
-                .collect(Collectors.toList());
-    }
 }

+ 6 - 6
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/form/travelcheck/PersonPositionListProvider.java

@@ -19,13 +19,13 @@ public class PersonPositionListProvider extends ListDataProvider {
     public DynamicObjectCollection getData(int start, int limit) {
         DynamicObjectCollection data = super.getData(start, limit);
 
-        List<String> applierNameList = data.stream()
-                .map(dyx -> dyx.getString("nckd_tripreqbill.applier.name"))
+        List<String> applierNumberList = data.stream()
+                .map(dyx -> dyx.getString("nckd_tripreqbill.applier.number"))
                 .collect(Collectors.toList());
 
         DynamicObjectCollection queryUserCol = QueryServiceHelper.query("bos_user", "number,entryentity.orgstructure.fullname", new QFilter[]{
-                new QFilter("number", QCP.in, applierNameList),
-                new QFilter("ispartjob", QCP.equals, Boolean.FALSE),
+                new QFilter("number", QCP.in, applierNumberList),
+                new QFilter("entryentity.ispartjob", QCP.equals, Boolean.FALSE),
         });
         // 查询人员及主岗部门映射
         Map<String, String> userDeptMap = queryUserCol.stream()
@@ -38,7 +38,7 @@ public class PersonPositionListProvider extends ListDataProvider {
                 new QFilter("iscurrentversion", QCP.equals, "1"),
                 new QFilter("datastatus", QCP.equals, "1"),
                 new QFilter("isprimary", QCP.equals, "1"),
-                new QFilter("person.number", QCP.in, applierNameList)
+                new QFilter("person.number", QCP.in, applierNumberList)
         }).stream().collect(Collectors.toMap(r -> r.getString("person.number"), r -> r.getString("position.name"), (k1, k2) -> k1));
 
         // 查询当前生效的人员职级信息
@@ -46,7 +46,7 @@ public class PersonPositionListProvider extends ListDataProvider {
                 new QFilter("businessstatus", QCP.equals, "1"),
                 new QFilter("datastatus", QCP.equals, "1"),
                 new QFilter("iscurrentversion", QCP.equals, "1"),
-                new QFilter("person.number", QCP.in, applierNameList)
+                new QFilter("person.number", QCP.in, applierNumberList)
         }).stream().collect(Collectors.toMap(r -> r.getString("person.number"), r -> r.getString("joblevel.name"), (k1, k2) -> k1));
 
         for(DynamicObject listRow : data){

+ 1 - 1
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/form/travelcheck/TravelFinanDraftList.java

@@ -42,7 +42,7 @@ public class TravelFinanDraftList extends AbstractListPlugin {
     @Override
     public void beforeCreateListDataProvider(BeforeCreateListDataProviderArgs args) {
         super.beforeCreateListDataProvider(args);
-        //args.setListDataProvider(new PersonPositionListProvider());
+        args.setListDataProvider(new PersonPositionListProvider());
     }
 
     @Override

+ 49 - 30
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/plugin/operate/travelcheck/FinanDraftConfirmOp.java

@@ -1,58 +1,77 @@
 package nckd.jimin.jyyy.fi.plugin.operate.travelcheck;
 
 import kd.bos.dataentity.entity.DynamicObject;
-import kd.bos.dataentity.entity.DynamicObjectCollection;
-import kd.bos.entity.EntityMetadataCache;
 import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
 import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.orm.ORM;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.operation.SaveServiceHelper;
+import nckd.jimin.jyyy.fi.common.constant.travelcheck.BusTravelCheckBillConstant;
 import nckd.jimin.jyyy.fi.common.constant.travelcheck.FinanceBillConfirmConstant;
-import nckd.jimin.jyyy.fi.common.constant.travelcheck.TravelFinanDraftConstant;
 
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.List;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 public class FinanDraftConfirmOp extends AbstractOperationServicePlugIn {
 
+    private static final Log logger = LogFactory.getLog(FinanDraftConfirmOp.class);
+
     @Override
     public void beginOperationTransaction(BeginOperationTransactionArgs e) {
         super.beginOperationTransaction(e);
         String operationKey = e.getOperationKey();
-
-        DynamicObject[] dataEntities = e.getDataEntities();
-        List<Object> idList = Arrays.stream(dataEntities).map(dataEntity -> dataEntity.getPkValue()).collect(Collectors.toList());
-        DynamicObject[] billArray = BusinessDataServiceHelper.load(idList.toArray(), EntityMetadataCache.getDataEntityType(TravelFinanDraftConstant.ENTITYID));
-        // 保存或者提交后反写商旅底稿已对账
-        if("save".equals(operationKey) || "submit".equals(operationKey)){
-            Arrays.stream(billArray).forEach(confirmBill -> writeBackDraft(confirmBill,"20"));
-        }
-        // 删除后更新成待对账
-        if("delete".equals(operationKey)){
-            Arrays.stream(billArray).forEach(confirmBill -> writeBackDraft(confirmBill,"10"));
+        if(FinanceBillConfirmConstant.OP_PUSHCHECKBILL.equals(operationKey)){
+            DynamicObject[] dataEntities = e.getDataEntities();
+            Arrays.stream(dataEntities).forEach(r -> createBusTravelCheckBill(r));
         }
     }
 
-    protected void writeBackDraft(DynamicObject confirmBill,String status){
+    protected void createBusTravelCheckBill(DynamicObject confirmBillInfo){
+        // 根据部门秘书创建商旅对账单
+        confirmBillInfo = BusinessDataServiceHelper.loadSingle(confirmBillInfo.getPkValue(),confirmBillInfo.getDynamicObjectType().getName());
 
-        List<Object> draftIdList = new ArrayList<>();
-        DynamicObjectCollection detailEntryCol = confirmBill.getDynamicObjectCollection(FinanceBillConfirmConstant.DETAILENTITY.ENTITYID);
-        for(DynamicObject detailEntry : detailEntryCol){
-            DynamicObjectCollection draftEntryCol = detailEntry.getDynamicObjectCollection(FinanceBillConfirmConstant.DRAFTENTRY.ENTITYID);
-            for(DynamicObject draftEntry : draftEntryCol){
-                draftIdList.add(draftEntry.getDynamicObject(FinanceBillConfirmConstant.DRAFTENTRY.NCKD_TRAVELFINANDRAFT).getPkValue());
-            }
-        }
 
-        DynamicObject[] draftBillArray = BusinessDataServiceHelper.load(TravelFinanDraftConstant.ENTITYID_F7, TravelFinanDraftConstant.NCKD_CONFIRMSTATUS,
-                new QFilter(TravelFinanDraftConstant.ID, QCP.in, draftIdList).toArray());
-        for(DynamicObject draftBill : draftBillArray){
-            draftBill.set(TravelFinanDraftConstant.NCKD_CONFIRMSTATUS, status);
+        // 补助部门秘书
+        Set<Long> bzDepSecretaryIds = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.ENTITYID).stream()
+                .filter(r -> r.getDynamicObject(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_DEPSECRETARY) != null)
+                .map(r -> r.getDynamicObject(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_DEPSECRETARY).getLong(FinanceBillConfirmConstant.ID))
+                .collect(Collectors.toSet());
+        Set<Long> slDepSecretaryIds = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_SL_ENTRY.ENTITYID).stream()
+                .filter(r -> r.getDynamicObject(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_DEPSECRETARY) != null)
+                .map(r -> r.getDynamicObject(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_DEPSECRETARY).getLong(FinanceBillConfirmConstant.ID))
+                .collect(Collectors.toSet());
+        Set<Long> ycDepSecretaryIds = confirmBillInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_YC_ENTRY.ENTITYID).stream()
+                .filter(r -> r.getDynamicObject(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_DEPSECRETARY) != null)
+                .map(r -> r.getDynamicObject(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_DEPSECRETARY).getLong(FinanceBillConfirmConstant.ID))
+                .collect(Collectors.toSet());
+        bzDepSecretaryIds.addAll(slDepSecretaryIds);
+        bzDepSecretaryIds.addAll(ycDepSecretaryIds);
+
+        String checkMonth = confirmBillInfo.getString(FinanceBillConfirmConstant.NCKD_CHECKMONTH);
+        long confirmBillId = confirmBillInfo.getLong(FinanceBillConfirmConstant.ID);
+        bzDepSecretaryIds.forEach(r -> createCheckBill(r, checkMonth,confirmBillId));
+    }
+
+    protected void createCheckBill(Long secretaryId, String checkMonth , Long confrimBillId){
+        // 查询是否存在
+        QFilter qFilter = new QFilter(BusTravelCheckBillConstant.NCKD_NCKD_SOURCEBILLID, QCP.equals,confrimBillId);
+        qFilter.and(BusTravelCheckBillConstant.NCKD_DEPSECRETARY, QCP.equals, secretaryId);
+        if(ORM.create().exists(BusTravelCheckBillConstant.ENTITYID, qFilter.toArray())){
+            logger.info("部门秘书【{}}】已存在商旅对账单【{}}】", secretaryId, checkMonth);
+            return;
         }
-        SaveServiceHelper.save(draftBillArray);
+
+        // 创建
+        DynamicObject busCheckBill = BusinessDataServiceHelper.newDynamicObject(BusTravelCheckBillConstant.ENTITYID);
+        busCheckBill.set(BusTravelCheckBillConstant.NCKD_DEPSECRETARY, secretaryId);
+        busCheckBill.set(BusTravelCheckBillConstant.NCKD_CHECKMONTH, checkMonth);
+        busCheckBill.set(BusTravelCheckBillConstant.NCKD_NCKD_SOURCEBILLID, confrimBillId);
+        busCheckBill.set(BusTravelCheckBillConstant.KEY_BILLSTATUS,"A");
+        SaveServiceHelper.save(new DynamicObject[]{ busCheckBill});
     }
 }

+ 499 - 0
code/jyyy/nckd-jimin-jyyy-fi/src/main/java/nckd/jimin/jyyy/fi/task/TravelFinanConfirmCreateTask.java

@@ -0,0 +1,499 @@
+package nckd.jimin.jyyy.fi.task;
+
+import kd.bos.algo.DataSet;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.db.tx.TX;
+import kd.bos.db.tx.TXHandle;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.exception.KDBizException;
+import kd.bos.exception.KDException;
+import kd.bos.id.ID;
+import kd.bos.logging.Log;
+import kd.bos.logging.LogFactory;
+import kd.bos.orm.ORM;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.schedule.executor.AbstractTask;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.bos.servicehelper.org.OrgUnitServiceHelper;
+import kd.bos.servicehelper.org.OrgViewType;
+import kd.bos.util.CollectionUtils;
+import nckd.jimin.jyyy.fi.common.constant.BillTypeConstants;
+import nckd.jimin.jyyy.fi.common.constant.travelcheck.*;
+import nckd.jimin.jyyy.fi.common.util.CommonUtils;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 创建商旅对账确认单
+ */
+public class TravelFinanConfirmCreateTask extends AbstractTask {
+
+    private static final Log logger = LogFactory.getLog(TravelFinanConfirmCreateTask.class);
+    @Override
+    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
+        logger.info("TravelFinanConfirmCreateTask begin");
+        // 创建当月的财务底稿确认单
+        String period = CommonUtils.parsePeriod(new Date());
+        if(ORM.create().exists(FinanceBillConfirmConstant.ENTITYID,
+                new QFilter(FinanceBillConfirmConstant.NCKD_CHECKMONTH, QCP.equals, period).toArray())){
+            logger.info(String.format("期间[%s]已经存在商旅对账确认单,请勿重复创建!", period));
+            return;
+        }
+
+        try(TXHandle tx = TX.requiresNew(this.getClass().getName())){
+            try {
+
+                DynamicObject financeConfirmInfo = BusinessDataServiceHelper.newDynamicObject(FinanceBillConfirmConstant.ENTITYID);
+                // 创建ID,用ID来清除已创建的数据
+                long financeConfirmId = ID.genLongId();
+                financeConfirmInfo.set(FinanceBillConfirmConstant.ID, financeConfirmId);
+                financeConfirmInfo.set(FinanceBillConfirmConstant.NCKD_CHECKMONTH, period);
+                financeConfirmInfo.set(FinanceBillConfirmConstant.KEY_BILLSTATUS, "A");
+                // 创建差旅补助
+                createBzEntry(financeConfirmInfo);
+                // 创建商旅费用
+                createSlEntry(financeConfirmInfo);
+                // 创建用车汇总
+                createYcEntry(financeConfirmInfo);
+                // 创建超标明细
+
+                // 创建退改明细
+
+                // 创建同性别未同住
+                SaveServiceHelper.save(new DynamicObject[]{financeConfirmInfo});
+
+            }catch (Exception e){
+                tx.markRollback();
+                logger.error(String.format("创建期间[%s]下的商旅对账确认单失败。", period),e);
+            }
+        }
+        logger.info("TravelFinanConfirmCreateTask end");
+    }
+    protected void createYcEntry(DynamicObject financeConfirmInfo) {
+
+        DynamicObjectCollection ycEntryCol = financeConfirmInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_YC_ENTRY.ENTITYID);
+        ycEntryCol.clear();
+        long confirmBillId = financeConfirmInfo.getLong("id");
+
+        // 查询用车结算单
+        DynamicObjectCollection vehicleCheckCol = QueryServiceHelper.query("er_vehiclecheckingbill", "id,oabillnum,server,sourcebookedid.id applierId,totalamount", new QFilter[]{
+                new QFilter("happenddate", QCP.less_equals, new Date()),
+                new QFilter(FinanceBillConfirmConstant.NCKD_YC_CONFRMID, QFilter.equals, 0)
+                        .or(QFilter.isNull(FinanceBillConfirmConstant.NCKD_YC_CONFRMID)),
+        });
+        if(CollectionUtils.isEmpty(vehicleCheckCol)){
+            return;
+        }
+
+        Map<Long, List<DynamicObject>> applierGroupList = vehicleCheckCol.stream().collect(Collectors.groupingBy(r -> r.getLong("applierId")));
+        for (Map.Entry<Long, List<DynamicObject>> applierRow : applierGroupList.entrySet()) {
+            Long applierId = applierRow.getKey();
+            List<DynamicObject> dataList = applierRow.getValue();
+            DynamicObject ycEntry = ycEntryCol.addNew();
+            DynamicObject applierInfo = BusinessDataServiceHelper.loadSingleFromCache(applierId, "bos_user");
+            ycEntry.set(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_TRAVELER, applierInfo);
+            createApplierInfo(ycEntry,applierInfo);
+            BigDecimal totalAmount = dataList.stream()
+                    .map(r -> r.getBigDecimal("totalamount")).reduce(BigDecimal.ZERO, BigDecimal::add);
+            ycEntry.set(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_AMOUNT, totalAmount);
+        }
+
+        List<Long> vehicleBillIdList = vehicleCheckCol.stream().map(r -> r.getLong("id")).collect(Collectors.toList());
+        DynamicObject[] vehicleCheckBillArray = BusinessDataServiceHelper.load("er_vehiclecheckingbill", FinanceBillConfirmConstant.NCKD_SL_CONFRMID, new QFilter("id", QCP.in, vehicleBillIdList).toArray());
+        for(DynamicObject vehicleCheckBill : vehicleCheckBillArray){
+            vehicleCheckBill.set(FinanceBillConfirmConstant.NCKD_YC_CONFRMID, confirmBillId);
+        }
+        SaveServiceHelper.save(vehicleCheckBillArray);
+    }
+
+    protected void createSlEntry(DynamicObject financeConfirmInfo) {
+        // 该方法从各个明细中查询,注释掉,改成从全部订单上查询
+        //DynamicObjectCollection slOrderDataCol = getSlOrderDataCol();
+        DynamicObjectCollection slOrderDataCol = QueryServiceHelper.query("er_allcheckingbill", "id,oabillnum,server,sourcebookedid.id applierId,totalamount,operationtype", new QFilter[]{
+                new QFilter("happenddate", QCP.less_equals, new Date()),
+//                new QFilter(FinanceBillConfirmConstant.NCKD_SL_CONFRMID, QFilter.equals, 0)
+//                        .or(QFilter.isNull(FinanceBillConfirmConstant.NCKD_SL_CONFRMID)),
+                new QFilter("operationtype", QFilter.in, Arrays.asList("1","2","4","5","6")),
+        });
+        long confirmBillId = financeConfirmInfo.getLong("id");
+        DynamicObjectCollection slEntryCol = financeConfirmInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_SL_ENTRY.ENTITYID);
+        slEntryCol.clear();
+        // 按照出差人分组汇总
+        Map<Long, List<DynamicObject>> applierGroupMap = slOrderDataCol.stream().collect(Collectors.groupingBy(r -> r.getLong("applierId")));
+        for (Map.Entry<Long, List<DynamicObject>> applierRow : applierGroupMap.entrySet()) {
+            Long applierId = applierRow.getKey();
+            List<DynamicObject> dataList = applierRow.getValue();
+            DynamicObject slEntry = slEntryCol.addNew();
+            DynamicObject applierInfo = BusinessDataServiceHelper.loadSingleFromCache(applierId, "bos_user");
+            slEntry.set(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_TRAVELER, applierInfo);
+            createApplierInfo(slEntry,applierInfo);
+            // 服务商已经和实施沟通,取第一个就行,按理只会出现同城
+            slEntry.set(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_SERVER,dataList.get(0).getString("server"));
+            // 对火车订单金额合计
+            BigDecimal trainTotalAmount = dataList.stream()
+                    .filter(r -> "6".equals(r.getString("operationtype")))
+                    .map(r -> r.getBigDecimal("totalamount")).reduce(BigDecimal.ZERO, BigDecimal::add);
+            slEntry.set(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_TRAINPAYAMT, trainTotalAmount);
+            // 对机票订单金额合计
+            BigDecimal planeTotalAmount = dataList.stream()
+                    .filter(r -> "2".equals(r.getString("operationtype")) || "4".equals(r.getString("operationtype")))
+                    .map(r -> r.getBigDecimal("totalamount")).reduce(BigDecimal.ZERO, BigDecimal::add);
+            slEntry.set(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_PLANPAYAMT, planeTotalAmount);
+            // 对酒店订单金额合计
+            BigDecimal hotelTotalAmount = dataList.stream()
+                    .filter(r ->"1".equals(r.getString("operationtype")) || "5".equals(r.getString("operationtype")))
+                    .map(r -> r.getBigDecimal("totalamount")).reduce(BigDecimal.ZERO, BigDecimal::add);
+            slEntry.set(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_HOTELPAYAMT, hotelTotalAmount);
+            slEntry.set(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_ORDERAMT, trainTotalAmount.add(planeTotalAmount).add(hotelTotalAmount));
+
+        }
+        List<Long> allBillIdList = slOrderDataCol.stream().map(r -> r.getLong("id")).collect(Collectors.toList());
+        DynamicObject[] allCheckBillArray = BusinessDataServiceHelper.load("er_allcheckingbill", FinanceBillConfirmConstant.NCKD_SL_CONFRMID, new QFilter("id", QCP.in, allBillIdList).toArray());
+        for(DynamicObject allCheckBill : allCheckBillArray){
+            allCheckBill.set(FinanceBillConfirmConstant.NCKD_SL_CONFRMID, confirmBillId);
+        }
+        SaveServiceHelper.save(allCheckBillArray);
+    }
+    protected DynamicObjectCollection getSlOrderDataCol(){
+
+        // 查询火车订单
+        DataSet trainCheckDataSet = QueryServiceHelper.queryDataSet(this.getClass().getName(), "er_traincheckingbill", "'er_traincheckingbill' type,id,oabillnum,server,sourcebookedid.id applierId,totalamount", new QFilter[]{
+                new QFilter("happenddate", QCP.less_equals, new Date()),
+                new QFilter(FinanceBillConfirmConstant.NCKD_SL_CONFRMID, QFilter.equals, 0),
+        }, "");
+
+        // 查询机票订单
+        DataSet planeCheckDataSet = QueryServiceHelper.queryDataSet(this.getClass().getName(), "er_planecheckingbill", "'er_planecheckingbill' type,id,oabillnum,server,sourcebookedid.id applierId,totalamount", new QFilter[]{
+                new QFilter("happenddate", QCP.less_equals, new Date()),
+                new QFilter(FinanceBillConfirmConstant.NCKD_SL_CONFRMID, QFilter.equals, 0),
+        }, "");
+
+        // 查询酒店订单
+        DataSet hotelCheckDataSet = QueryServiceHelper.queryDataSet(this.getClass().getName(), "er_hotelcheckingbill", "'er_hotelcheckingbill' type,id,oabillnum,server,sourcebookedid.id applierId,totalamount", new QFilter[]{
+                new QFilter("happenddate", QCP.less_equals, new Date()),
+                new QFilter(FinanceBillConfirmConstant.NCKD_SL_CONFRMID, QFilter.equals, 0),
+        }, "");
+        DataSet sumDataSet = CommonUtils.joinDataSetList(Arrays.asList(trainCheckDataSet, planeCheckDataSet, hotelCheckDataSet));
+        return ORM.create().toPlainDynamicObjectCollection(sumDataSet);
+    }
+
+
+
+    protected void createBzEntry(DynamicObject financeConfirmInfo){
+        long confirmBillId = financeConfirmInfo.getLong(FinanceBillConfirmConstant.ID);
+        BigDecimal bzAmount = getBzAmount();
+        // 获取本月月初
+        LocalDateTime firstDayStart = LocalDate.now().withDayOfMonth(1).atStartOfDay();
+        // 转换为Date对象
+        Date firstDay = Date.from(firstDayStart.atZone(ZoneId.systemDefault()).toInstant());
+
+        // 查询出差申请单
+        DynamicObjectCollection tripReqBillCol = QueryServiceHelper.query(TripReqBillConstant.ENTITYID, String.join(",",TripReqBillConstant.ID,TripReqBillConstant.BILLNO), new QFilter[]{
+                // 状态为审核通过、已付款、关闭
+                new QFilter(TripReqBillConstant.KEY_BILLSTATUS, QFilter.in, Arrays.asList("E", "G", "I")),
+//                new QFilter(FinanceBillConfirmConstant.NCKD_BZ_CONFRMID, QFilter.equals, 0)
+//                        .or(QFilter.isNull(FinanceBillConfirmConstant.NCKD_BZ_CONFRMID)),
+                new QFilter(TripReqBillConstant.RENDDATE, QFilter.less_than, firstDay),
+        },"createtime desc" );
+        if(tripReqBillCol == null || tripReqBillCol.size() == 0){
+            return ;
+        }
+        List<Object> tripReqBillIdList = tripReqBillCol.stream().map(r -> r.get(TripReqBillConstant.ID)).collect(Collectors.toList());
+        // 创建财务对账底稿
+        //createTravelFinanDraft(financeConfirmInfo,tripReqBillIdList,bzAmount);
+        DynamicObjectCollection bzEntryCol = financeConfirmInfo.getDynamicObjectCollection(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.ENTITYID);
+        // 查询关联的商旅补助底稿数据
+        List<Long> draftBillIdList = QueryServiceHelper.query(TravelFinanDraftConstant.ENTITYID, TravelFinanDraftConstant.ID,
+                        new QFilter(FinanceBillConfirmConstant.NCKD_BZ_CONFRMID, QCP.equals, confirmBillId)
+                                .and(new QFilter(TravelFinanDraftConstant.NCKD_SUMDAYS,QCP.large_than,0)).toArray())
+                .stream().map(r -> r.getLong(TravelFinanDraftConstant.ID)).collect(Collectors.toList());
+        // 创建商旅对账确认补助
+        createCheckBzEntry(bzEntryCol,draftBillIdList);
+    }
+
+    protected BigDecimal getBzAmount(){
+        DynamicObject tripExpenseItem = QueryServiceHelper.queryOne("er_tripexpenseitem", "nckd_travelbzstd", new QFilter("longnumber", QCP.equals, "004").toArray());
+        if(tripExpenseItem == null){
+            throw new KDBizException("没有配置补助的差旅标准。");
+        }
+        BigDecimal bzAmount = tripExpenseItem.getBigDecimal("nckd_travelbzstd");
+        if(bzAmount == null || bzAmount.compareTo(BigDecimal.ZERO) <= 0){
+            throw new KDBizException("差旅补助金额不能为0。");
+        }
+        return bzAmount;
+    }
+
+
+    protected void createCheckBzEntry(DynamicObjectCollection bzEntryCol,List<Long> draftBillIdList){
+        DynamicObject[] draftBillArray = BusinessDataServiceHelper.load(draftBillIdList.toArray(), EntityMetadataCache.getDataEntityType(TravelFinanDraftConstant.ENTITYID_F7));
+
+        // 按照出差人分组
+        Map<Long, List<DynamicObject>> applyGroupMap = Arrays.stream(draftBillArray)
+                .collect(Collectors.groupingBy(r -> r.getDynamicObject(TravelFinanDraftConstant.NCKD_TRIPREQBILL).getDynamicObject(TripReqBillConstant.APPLIER).getLong(TripReqBillConstant.ID)));
+
+        for(Map.Entry<Long, List<DynamicObject>> applierRow : applyGroupMap.entrySet()){
+            DynamicObject bzEntry = bzEntryCol.addNew();
+            Long applierId = applierRow.getKey();
+            List<DynamicObject> applierDraftList = applierRow.getValue();
+            int sumDays = 0 ;
+            BigDecimal sumAmount = BigDecimal.ZERO;
+            for(DynamicObject draftEntry : applierDraftList){
+                sumDays += draftEntry.getInt(TravelFinanDraftConstant.NCKD_SUMDAYS);
+                sumAmount = sumAmount.add(draftEntry.getBigDecimal(TravelFinanDraftConstant.NCKD_AMOUNT));
+            }
+            DynamicObject applierInfo = BusinessDataServiceHelper.loadSingleFromCache(applierId, "bos_user");
+            bzEntry.set(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_TRAVELER, applierInfo);
+            bzEntry.set(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_TRAVELDAYS, sumDays);
+            bzEntry.set(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_AMOUNT, sumAmount);
+            bzEntry.set(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_CHECKAMT, sumAmount);
+            // 设置出差人信息,工号、部门、岗位。 银行账户、开户行
+            createApplierInfo(bzEntry,applierInfo);
+        }
+    }
+
+    protected void createApplierInfo(DynamicObject entry , DynamicObject traveler){
+        if(traveler != null) {
+            String entryEntityName = entry.getDynamicObjectType().getName();
+            // 获取员工信息
+            DynamicObject userInfo = QueryServiceHelper.queryOne("bos_user", "number,entryentity.dpt,entryentity.orgstructure.fullname,entryentity.post.name",
+                    new QFilter(FinanceBillConfirmConstant.ID, QCP.equals, traveler.getLong(FinanceBillConfirmConstant.ID)).toArray());
+            long deptId = userInfo.getLong("entryentity.dpt");
+            Map<String, Object> companyInfoMap = OrgUnitServiceHelper.getCompanyfromOrg(deptId);
+            Object companyId = companyInfoMap.get("id");
+            DynamicObject company = BusinessDataServiceHelper.loadSingleFromCache(companyId, "bos_org");
+            DynamicObject travelDeptSecretary = getTravelDeptSecretary(traveler.getLong(FinanceBillConfirmConstant.ID), deptId);
+            if (FinanceBillConfirmConstant.NCKD_BZ_ENTRY.ENTITYID.equals(entryEntityName)) {
+                entry.set(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_DEPFULLNAME, userInfo.getString("entryentity.orgstructure.fullname"));
+                entry.set(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_POST, userInfo.getString("entryentity.post.name"));
+                entry.set(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_COMPANY, company);
+                entry.set(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_DEPSECRETARY, travelDeptSecretary);
+                // 收款信息通过薪酬发放设置hsas_paysetting中获取
+                DynamicObject hrPaySetting = QueryServiceHelper.queryOne("hsas_paysetting", "entryentity.perbankcard.bankcardnum,entryentity.perbankcard.bankdeposit", new QFilter[]{
+                        new QFilter("salaryfile.person.number", QCP.equals, traveler.getString("number")),
+                        new QFilter("iscurrentversion", QCP.equals, "1"),
+                        new QFilter("datastatus", QCP.equals, "1"),
+                        new QFilter("entryentity.perbankcard.accountrelation.number", QCP.equals, "1010_S")
+                });
+                if (hrPaySetting != null) {
+                    entry.set(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_ACCOUNT, hrPaySetting.getString("entryentity.perbankcard.bankcardnum"));
+                    entry.set(FinanceBillConfirmConstant.NCKD_BZ_ENTRY.NCKD_BZ_PAYERBANK, hrPaySetting.get("entryentity.perbankcard.bankdeposit"));
+                }
+            }
+            if (FinanceBillConfirmConstant.NCKD_SL_ENTRY.ENTITYID.equals(entryEntityName)) {
+                entry.set(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_DEPFULLNAME, userInfo.getString("entryentity.orgstructure.fullname"));
+                entry.set(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_POST, userInfo.getString("entryentity.post.name"));
+                entry.set(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_COMPANY, company);
+                entry.set(FinanceBillConfirmConstant.NCKD_SL_ENTRY.NCKD_SL_DEPSECRETARY, travelDeptSecretary);
+            }
+
+            if(FinanceBillConfirmConstant.NCKD_YC_ENTRY.ENTITYID.equals(entryEntityName)){
+                entry.set(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_DEPFULLNAME, userInfo.getString("entryentity.orgstructure.fullname"));
+                entry.set(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_POST, userInfo.getString("entryentity.post.name"));
+                entry.set(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_COMPANY, company);
+                entry.set(FinanceBillConfirmConstant.NCKD_YC_ENTRY.NCKD_YC_DEPSECRETARY, travelDeptSecretary);
+            }
+        }
+    }
+
+    /**
+     * 创建财务对账底稿单据
+     * @param financeConfirmInfo 来源商旅对账确认单ID
+     * @param tripReqBillIdList 出差申请单ID
+     * @param bzAmount 补助金额
+     */
+    protected void createTravelFinanDraft(DynamicObject financeConfirmInfo, List<Object> tripReqBillIdList ,BigDecimal bzAmount) {
+        long confirmBillId = financeConfirmInfo.getLong(FinanceBillConfirmConstant.ID);
+        // 创建商旅财务对账底稿
+        DynamicObject[] tripReqBillArray = BusinessDataServiceHelper.load(tripReqBillIdList.toArray(), EntityMetadataCache.getDataEntityType(TripReqBillConstant.ENTITYID_F7));
+        List<String> tripReqBillNumberList = Arrays.stream(tripReqBillArray).map(r -> r.getString(TripReqBillConstant.BILLNO)).collect(Collectors.toList());
+        // 获取关联的火车订单
+        Map<String, List<DynamicObject>> trainBillMap = QueryServiceHelper.query("er_trainbill", "oabillnum,ordernum,departtime,arrivetime,departcity,arrivecity,totalamount",
+                        new QFilter("oabillnum", QCP.in, tripReqBillNumberList).toArray())
+                .stream()
+                .collect(Collectors.groupingBy(r -> r.getString("oabillnum")));
+
+        // 获取机票订单
+        Map<String, List<DynamicObject>> planBillMap = QueryServiceHelper.query("er_planebill", "oabillnum,ordernum,takeofftime,landingtime,fromcityname,tocityname,totalamount",
+                        new QFilter("oabillnum", QCP.in, tripReqBillNumberList).toArray())
+                .stream()
+                .collect(Collectors.groupingBy(r -> r.getString("oabillnum")));
+
+        // 获取关联的差旅报销发票分录 -》 发票与费用明细分录 联查 行程信息分录 通过源单行程分录ID 联查出差申请
+        Map<String, List<DynamicObject>> tripReimInvoiceData = getTripReimInvoiceData(tripReqBillNumberList);
+
+        for(DynamicObject tripReqBill : tripReqBillArray){
+            String billno = tripReqBill.getString(TripReqBillConstant.BILLNO);
+            DynamicObject travelFinanDraftInfo = BusinessDataServiceHelper.newDynamicObject(TravelFinanDraftConstant.ENTITYID);
+            travelFinanDraftInfo.set(FinanceBillConfirmConstant.NCKD_BZ_CONFRMID, confirmBillId);
+            travelFinanDraftInfo.set(TravelFinanDraftConstant.NCKD_TRIPREQBILL, tripReqBill);
+            travelFinanDraftInfo.set(TravelFinanDraftConstant.ORG, tripReqBill.get(TripReqBillConstant.COMPANY));
+            travelFinanDraftInfo.set(TravelFinanDraftConstant.NCKD_DEPT, tripReqBill.get(TripReqBillConstant.ORG));
+            travelFinanDraftInfo.set(TravelFinanDraftConstant.NCKD_CONFIRMSTATUS, "10");
+            travelFinanDraftInfo.set(TravelFinanDraftConstant.KEY_BILLNO,tripReqBill.getString(TripReqBillConstant.BILLNO));
+
+            DynamicObjectCollection draftEntryCol = travelFinanDraftInfo.getDynamicObjectCollection(TravelFinanDraftConstant.NCKD_DETAILENTITY.ENTITYID);
+            if(trainBillMap.containsKey(billno) && trainBillMap.get(billno) != null){
+                List<DynamicObject> trainBillList = trainBillMap.get(billno);
+                trainBillList.stream().forEach(trainBill -> getDraftData(draftEntryCol.addNew(),"6",trainBill.getString("ordernum"),
+                        trainBill.getDate("departtime"),trainBill.getDate("arrivetime"),
+                        trainBill.getString("departcity"),trainBill.getString("arrivecity"), trainBill.getBigDecimal("totalamount")));
+            }
+            if(planBillMap.containsKey(billno) && planBillMap.get(billno) != null){
+                List<DynamicObject> planBillList = planBillMap.get(billno);
+                planBillList.stream().forEach(planBill -> getDraftData(draftEntryCol.addNew(),"2",planBill.getString("ordernum"),
+                        planBill.getDate("takeofftime"),planBill.getDate("landingtime"),
+                        planBill.getString("fromcityname"),planBill.getString("tocityname"),planBill.getBigDecimal("totalamount")));
+            }
+            if(tripReimInvoiceData.containsKey(billno) && tripReimInvoiceData.get(billno) != null){
+                List<DynamicObject> tripReimInvoiceList = tripReimInvoiceData.get(billno);
+                tripReimInvoiceList.stream().forEach(tripReimInvoice -> getDraftData(draftEntryCol.addNew(),"7",
+                        String.join("-",tripReimInvoice.getString("tripBillno"),tripReimInvoice.getString("invoiceentry.invoiceno")),
+                        tripReimInvoice.getDate("invoiceentry.carrierdate"),null,
+                        tripReimInvoice.getString("invoiceentry.istartcity"),tripReimInvoice.getString("invoiceentry.idestcity"),tripReimInvoice.getBigDecimal("invoiceentry.totalamount")));
+            };
+
+            // 获取draftEntryCol中开始时间的额最早时间  和结束时间的最晚时间
+            Date earliestTime = draftEntryCol.stream()
+                    .filter(d -> d.getDate(TravelFinanDraftConstant.NCKD_DETAILENTITY.NCKD_STARTDATE) != null)
+                    .map(d -> d.getDate(TravelFinanDraftConstant.NCKD_DETAILENTITY.NCKD_STARTDATE))
+                    .min(Comparator.comparing(Date::getTime)).orElse(null);
+
+            Date latestTime = draftEntryCol.stream()
+                    .filter(d -> d.getDate(TravelFinanDraftConstant.NCKD_DETAILENTITY.NCKD_FINISHDATE) != null)
+                    .map(d -> d.getDate(TravelFinanDraftConstant.NCKD_DETAILENTITY.NCKD_FINISHDATE))
+                    .max(Comparator.comparing(Date::getTime)).orElse(null);
+            //获取latestTime与earliestTime 的日期相差天数,加上1
+            if(earliestTime != null && latestTime != null){
+                int days = getDays(earliestTime, latestTime, tripReqBill.getDynamicObject(TripReqBillConstant.COMPANY));
+                travelFinanDraftInfo.set(TravelFinanDraftConstant.NCKD_SUMDAYS, days);
+                // 查询补助金额
+                travelFinanDraftInfo.set(TravelFinanDraftConstant.NCKD_AMOUNT, bzAmount.multiply(BigDecimal.valueOf(days)));
+            }
+            tripReqBill.set(FinanceBillConfirmConstant.NCKD_BZ_CONFRMID, confirmBillId);
+            // 分录为空的时候不创建底稿,但是更新
+            SaveServiceHelper.save(new DynamicObject[]{ travelFinanDraftInfo });
+            SaveServiceHelper.save(new DynamicObject[]{ tripReqBill });
+        }
+    }
+
+    protected int getDays(Date startTime, Date endTime,DynamicObject org){
+        // 获取组织下的工作日历
+        DynamicObject workCalendar = getWorkCalandar(org.getLong("id"));
+        List<Date> notWorkDayList = new ArrayList<>();
+        if(workCalendar != null){
+            notWorkDayList = QueryServiceHelper.query("bd_workcalendar", "dateentry.workdate", new QFilter[]{
+                    new QFilter("dateentry.datetype", QCP.equals, "3"),
+                    new QFilter("dateentry.workdate", QCP.large_equals, startTime),
+                    new QFilter("dateentry.workdate", QCP.less_equals, endTime),
+                    new QFilter("id", QCP.equals, workCalendar.getPkValue())
+            }).stream().map(r -> r.getDate("dateentry.workdate")).collect(Collectors.toList());
+        }
+        startTime = CommonUtils.getStartOfDay(startTime);
+        endTime = CommonUtils.getStartOfDay(endTime);
+        // 计算开始日期和结束日期之间总天数,时间转成日期,然后相减
+        long diffInMillis = endTime.getTime() - startTime.getTime();
+        int totalDays = (int) (diffInMillis / (24 * 60 * 60 * 1000)) + 1;
+
+        // 计算工作日天数(总天数减去非工作日天数)
+        int workDays = totalDays - notWorkDayList.size();
+
+        return workDays;
+    }
+
+    protected DynamicObject getWorkCalandar(Long orgId){
+        DynamicObject workCalendar = QueryServiceHelper.queryOne("bd_workcalendar", "id", new QFilter("org", QCP.equals, orgId).toArray());
+        if(workCalendar == null){
+            Map<Long, Long> parentOrgMap = OrgUnitServiceHelper.getDirectSuperiorOrg(OrgViewType.Admin, Collections.singletonList(orgId));
+            if(!parentOrgMap.containsKey(orgId)){
+                return null;
+            }else{
+                return getWorkCalandar(parentOrgMap.get(orgId));
+            }
+        }
+        return workCalendar;
+    }
+
+
+    protected DynamicObject getDraftData( DynamicObject draftEntry , String source, String orderNum, Date startTime,
+                                          Date endTime , String from , String to , BigDecimal amount){
+        draftEntry.set(TravelFinanDraftConstant.NCKD_DETAILENTITY.NCKD_SOURCE, source);
+        draftEntry.set(TravelFinanDraftConstant.NCKD_DETAILENTITY.NCKD_ORDER_NUMBER, orderNum);
+        draftEntry.set(TravelFinanDraftConstant.NCKD_DETAILENTITY.NCKD_STARTDATE, startTime);
+        draftEntry.set(TravelFinanDraftConstant.NCKD_DETAILENTITY.NCKD_FINISHDATE, endTime);
+        draftEntry.set(TravelFinanDraftConstant.NCKD_DETAILENTITY.NCKD_FROM, from);
+        draftEntry.set(TravelFinanDraftConstant.NCKD_DETAILENTITY.NCKD_TO, to);
+        draftEntry.set(TravelFinanDraftConstant.NCKD_DETAILENTITY.NCKD_ORDER_AMOUNT, amount);
+        return draftEntry;
+    }
+
+
+
+    protected Map<String, List<DynamicObject>> getTripReimInvoiceData(List<String> tripReqBillNumberList){
+
+        // 查询关联的行程分录ID
+        DataSet queryTripReqEntryDataSet = QueryServiceHelper.queryDataSet(this.getClass().getName(), TripReqBillConstant.ENTITYID,
+                "billno,tripentry.id", new QFilter("billno", QCP.in, tripReqBillNumberList).toArray(), "");
+        Set tripEntryIdSet = CommonUtils.getFiledFromDataSet(queryTripReqEntryDataSet, "tripentry.id");
+        // 通过行程分录ID 联查差旅报销行程
+        // 差旅报销单行程分录ID -> 出差申请分录ID映射
+        DataSet tripReimEntryDataSet = QueryServiceHelper.queryDataSet(this.getClass().getName(), BillTypeConstants.ER_TRIPREIMBURSEBILL, "tripentry.tripentrysourceid,tripentry.entryentity.id",
+                new QFilter("tripentry.tripentrysourceid", QCP.in, tripEntryIdSet).toArray(), "");
+        Set tripReimEntryIdSet = CommonUtils.getFiledFromDataSet(tripReimEntryDataSet, "tripentry.entryentity.id");
+
+        // 获取行程信息分录下的发票信息
+        DataSet queryReimInvoiceEntryDataSet = QueryServiceHelper.queryDataSet(this.getClass().getName(), BillTypeConstants.ER_TRIPREIMBURSEBILL, "invoiceitementry.itementryid,invoiceitementry.invoiceheadentryid",
+                new QFilter("invoiceitementry.itementryid", QCP.in, tripReimEntryIdSet).toArray(), "");
+        Set invoiceEntryIdSet = CommonUtils.getFiledFromDataSet(queryReimInvoiceEntryDataSet, "invoiceitementry.invoiceheadentryid");
+
+
+        // 查询发票相关信息
+        DataSet queryInvoiceEntryDataSet = QueryServiceHelper.queryDataSet(this.getClass().getName(), BillTypeConstants.ER_TRIPREIMBURSEBILL, "billno,invoiceentry.id,invoiceentry.invoiceno,invoiceentry.carrierdate,invoiceentry.istartcity,invoiceentry.idestcity,invoiceentry.totalamount",
+                new QFilter("invoiceentry.id", QCP.in, invoiceEntryIdSet).toArray(), "");
+
+        // 建议出差申请和发票明细的关联关系
+        DataSet queryReimInvoiceDataSet = queryTripReqEntryDataSet.leftJoin(tripReimEntryDataSet)
+                .on("tripentry.id", "tripentry.tripentrysourceid").select("billno", "tripentry.entryentity.id").finish()
+                .leftJoin(queryReimInvoiceEntryDataSet)
+                .on("tripentry.entryentity.id", "invoiceitementry.itementryid").select("billno", "invoiceitementry.invoiceheadentryid").finish()
+                .leftJoin(queryInvoiceEntryDataSet)
+                .on("invoiceitementry.invoiceheadentryid", "invoiceentry.id").select(new String[]{ "billno" }, new String[]{ "billno tripBillno","invoiceentry.invoiceno", "invoiceentry.carrierdate", "invoiceentry.istartcity","invoiceentry.idestcity", "invoiceentry.totalamount" }).finish();
+        DynamicObjectCollection reimInvoiceCol = ORM.create().toPlainDynamicObjectCollection(queryReimInvoiceDataSet);
+        return reimInvoiceCol.stream().filter(r -> !Objects.isNull(r.getString("invoiceentry.invoiceno"))).collect(Collectors.groupingBy(r -> r.getString("billno")));
+
+    }
+
+    /**
+     * 获取出差人部门秘书
+     * @param applierId
+     * @param deptId
+     * @return
+     */
+    protected DynamicObject getTravelDeptSecretary(Long applierId , Long deptId){
+        // 优先从秘书特殊人员配置中取,如果没有特殊配置,则从部门秘书中取
+        DynamicObject speSettingInfo = QueryServiceHelper.queryOne(SecretarySpeSettingConstant.ENTITYID,
+                SecretarySpeSettingConstant.NCKD_ORG_CHECK, new QFilter(SecretarySpeSettingConstant.NCKD_USER, QCP.equals, applierId).toArray());
+        Long checkOrg = 0L;
+        if(speSettingInfo != null){
+            checkOrg = speSettingInfo.getLong(SecretarySpeSettingConstant.NCKD_ORG_CHECK);
+        }else{
+            checkOrg = deptId;
+        }
+        // 查询部门秘书配置
+        DynamicObject depSecretaryInfo = QueryServiceHelper.queryOne(DepSecretaryConstant.ENTITYID, DepSecretaryConstant.NCKD_SECRETARY,
+                new QFilter(CommonUtils.join(DepSecretaryConstant.ENTITYID_ENTRY, DepSecretaryConstant.NCKD_ORG), QCP.equals, checkOrg).toArray());
+        if(depSecretaryInfo != null){
+            return BusinessDataServiceHelper.loadSingleFromCache(depSecretaryInfo.getLong(DepSecretaryConstant.NCKD_SECRETARY),"bos_user");
+        }
+        return null;
+    }
+}