package nckd.jimin.jyyy.fi.webapi;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.kingdee.util.StringUtils;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.LocaleString;
import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
import kd.bos.db.DB;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.botp.runtime.TableDefine;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.id.ID;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.openapi.common.custom.annotation.ApiController;
import kd.bos.openapi.common.custom.annotation.ApiParam;
import kd.bos.openapi.common.custom.annotation.ApiPostMapping;
import kd.bos.openapi.common.result.CustomApiResult;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.DispatchServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import nckd.base.helper.CommonHelperUtils;
import scala.Dynamic;

import javax.validation.Valid;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * SRM系统调用，付款同步接口
 * 描述：接口实现逻辑包含对公报销单同步、预付单同步，通过参数判断传的是对公报销还是预付
 * bizAccountOutBills：对公报销单；dailyLoanBills：预付单，两个参数只有其中一个有值。
 * @author wanghaiwu_kd
 * @date 2025/05010
 */
@ApiController(
        desc = "对接SRM预付款、付款",
        value = "SRM"
)
public class SRMSynPayApiPlugin implements Serializable {
    private static final long serialVersionUID = 3112572075286232761L;
    private static final Log logger = LogFactory.getLog(SRMSynPayApiPlugin.class);
    //对公报销单
    private static final String ENTITY_PUBLICPAY = "er_publicreimbursebill";
    //预付单
    private static final String ENTITY_PREPAY = "er_prepaybill";

    @ApiPostMapping("synPayForSRM")
    public CustomApiResult<JSONObject> synPayForSRM(
            @Valid @ApiParam(value = "付款申请") JSONArray bizAccountOutBills,
            @Valid @ApiParam(value = "预付款") JSONArray dailyLoanBills) {
        if(bizAccountOutBills == null && dailyLoanBills == null){
            return returnResult("1", "失败，bizAccountOutBills、dailyLoanBills参数不能同时为空", null);
        }
        int bizAcctOutBillSize = 0;
        int dailyLoanBillSize = 0;

        if(bizAccountOutBills != null && bizAccountOutBills.size() > 0){
            bizAcctOutBillSize = bizAccountOutBills.size();
        }

        if(dailyLoanBills != null && dailyLoanBills.size() > 0){
            dailyLoanBillSize = dailyLoanBills.size();
        }

        if(bizAcctOutBillSize > 0 && dailyLoanBillSize > 0){
            return returnResult("1", "失败，bizAccountOutBills、dailyLoanBills参数不能同时存在", null);
        }

        JSONArray responseData = new JSONArray();
        if(bizAcctOutBillSize > 0){
            responseData = synBizAcctOutBill(bizAccountOutBills);
        } else if(dailyLoanBillSize > 0){
            responseData = synDailyLoanBill(dailyLoanBills);
        }

        String code = "1";
        String msg = "";

        int sucCount = 0;
        int failCount = 0;
        String billNo = "";

        if(responseData == null){
            code = "1";
            msg = "失败";
        } else if(responseData.size() > 0){
            for(int i = 0; i < responseData.size(); i++){
                JSONObject response  = responseData.getJSONObject(i);

                String srmBillNo = response.getString("SRMBillNo");
                String status = response.getString("status");
                String message = response.getString("message");

                if("0".equals(status)){
                    sucCount++;
                } else {
                    failCount++;
                }

                billNo = srmBillNo;
            }

            if(sucCount == responseData.size()){
                code = "0";
                billNo = "成功SRMBillNo ," + billNo;
            } else {
                billNo = "失败SRMBillNo ," + billNo;
            }

            msg = String.format("成功%s条，失败%s条。%s", sucCount, failCount, billNo);
        }

        return returnResult(code, msg, responseData);
    }

    /**
     * 同步付款
     * @param bizAccountOutBills
     */
    private JSONArray synBizAcctOutBill(JSONArray bizAccountOutBills){
        JSONArray responseData = new JSONArray();

        for(int i = 0; i < bizAccountOutBills.size(); i++){
            JSONObject inputData = bizAccountOutBills.getJSONObject(i);

            JSONObject saveReturn = saveBizAcctOutBillInfo(inputData);

            responseData.add(saveReturn);
        }

        return responseData;
    }

    /**
     * 同步预付
     * @param dailyLoanBills
     * @return
     */
    private JSONArray synDailyLoanBill(JSONArray dailyLoanBills){
        JSONArray responseData = new JSONArray();

        for(int i = 0; i < dailyLoanBills.size(); i++){
            JSONObject inputData = dailyLoanBills.getJSONObject(i);

            JSONObject saveReturn = saveDailyLoanBillInfo(inputData);

            responseData.add(saveReturn);
        }

        return responseData;
    }

    /**
     * 保存对公报销单对象
     * @param inputData
     * @return
     */
    private JSONObject saveBizAcctOutBillInfo (JSONObject inputData){
        JSONObject returnMap = new JSONObject();
        String code = "1";
        String returnMessage = "";

        String billType = inputData.getString("billType");//单据类型
        String srmBillNo = inputData.getString("SRMBillNo");//srm单据号
        String srmUrl = inputData.getString("srmUrl");//
        String project = inputData.getString("project");//项目编号
        String u8Org = inputData.getString("u8Org");//发票抬头
        String invoicedAmount = inputData.getString("invoicedAmount");//本次开票金额
        String contract = inputData.getString("contractNumber");//合同编号
        String cause = inputData.getString("cause");//事由
        String orgUnit = inputData.getString("orgUnit");//申请部门
        String position = inputData.getString("position");//职位
        String biller = inputData.getString("biller");//制单人工号
        String applier = inputData.getString("applier");//经办人工号
        String isRelapj = "0";

        if(StringUtils.isEmpty(srmBillNo)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "SRM单号 不能为空";
        }

        if(StringUtils.isEmpty(srmUrl)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "srmUrl 不能为空";
        }

        if(StringUtils.isEmpty(cause)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "事由 不能为空";
        }

        if(StringUtils.isEmpty(orgUnit)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "申请部门 不能为空";
        }

        if(StringUtils.isEmpty(position)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "申请人职位 不能为空";
        }

        if(StringUtils.isEmpty(biller)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "制单人 不能为空";
        }

        if(StringUtils.isEmpty(applier)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "经办人 不能为空";
        }

        if(StringUtils.isEmpty(u8Org)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "u8组织 不能为空";
        }

        if("XM".equals(billType)){
            if(StringUtils.isEmpty(project)){
                returnMessage = ("".equals(returnMessage) ? "" : ",") + "项目类付款 项目编码 不能为空";
            }

            isRelapj = "1";
        }

        if(!StringUtils.isEmpty(returnMessage)){
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        //根据srm单据编号，校验在星瀚中是否已存在单据
        String xhBillNO = queryBillInfoBySRMBillNo(ENTITY_PUBLICPAY, srmBillNo);
        if(!StringUtils.isEmpty(xhBillNO)){
            returnMessage = "此SRM单号在星瀚系统已存在，对公报销单编号：" + xhBillNO;
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

//        DynamicObject projectInfo = CommonHelperUtils.queryDynamicObject("bd_project", "number", project);
//        if(projectInfo == null){
//            returnMessage = "项目(" + project + ")在星瀚系统中未匹配到数据！";
//            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
//        }

        DynamicObject creatorInfo = CommonHelperUtils.queryBaseDynamicObject("bos_user", "number", biller);
        if(creatorInfo == null){
            returnMessage = "制单人(" + biller + ")在星瀚系统中未匹配到数据！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        DynamicObject applierInfo = CommonHelperUtils.queryBaseDynamicObject("bos_user", "number", applier);
        if(applierInfo == null){
            returnMessage = "经办人(" + applier + ")在星瀚系统中未匹配到数据！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        DynamicObject dept = CommonHelperUtils.queryBaseDynamicObject("bos_org", "number", orgUnit);
        if(dept == null){
            returnMessage = "行政组织(" + orgUnit + ")在星瀚系统中未匹配到数据！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        DynamicObject positionInfo = CommonHelperUtils.queryBaseDynamicObject("hbpm_positionhr", "number", position);
        if(positionInfo == null){
            returnMessage = "岗位(" + position + ")在星瀚系统中未匹配到数据！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }
        LocaleString positionName = new LocaleString(positionInfo.getString("name"));

        //申请人公司行政组织
        DynamicObject adminCompany = CommonHelperUtils.getAdminCompany(dept);

        QFilter qFilter = new QFilter("toorg", QCP.equals, dept.getPkValue());
//        DynamicObject relation = BusinessDataServiceHelper.loadSingle("bos_org_orgrelation_dept", qFilter.toArray());
//        if(relation == null){
//            returnMessage = "行政组织(" + dept.getString("number") + ", " + dept.getString("name") + ")在星瀚系统未维护委托业务单元！";
//            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
//        }
        //费用承担公司 改成取u8组织
//        DynamicObject costCompany = relation.getDynamicObject("fromorg");

        DynamicObject costCompany = CommonHelperUtils.queryBaseDynamicObject("bos_org", "name", u8Org);
        if(costCompany == null){
            returnMessage = "u8组织(" + u8Org + ")在星瀚系统中未匹配到数据！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        //汇率表Id
        Long exchangeTableId = CommonHelperUtils.getExchageTableId(costCompany.getLong("id"));

        if(exchangeTableId == null){
            returnMessage = "核算组织(" + costCompany.getString("name") + ")在星瀚系统匹配到汇率表！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        String detailtype = "biztype_other";
        boolean isframeworkcontract = false;

        //合同台账
        DynamicObject contractInfo = null;
        if(!StringUtils.isEmpty(contract)) {
            qFilter = new QFilter("contractcode", QCP.equals, contract);
            contractInfo = BusinessDataServiceHelper.loadSingle("er_contractbill", qFilter.toArray());

            if(contractInfo == null){
                returnMessage = "合同(" + contract + ")在星瀚中未匹配到合同台账";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }
            if(contractInfo.getBigDecimal("contractamount").compareTo(BigDecimal.ZERO) == 0){
                isframeworkcontract = true;
            }

            detailtype = "biztype_contract";
        }


        //单据类型
        //处理单据类型
        QFilter f = new QFilter("number", "=", "nckd_er_publicsrmapply");
        DynamicObject layoutInfo = BusinessDataServiceHelper.loadSingle("bos_formmeta", "id, number,name, basedatafield", f.toArray());

        if(layoutInfo == null){
            returnMessage = "未匹配到PC布局(nckd_er_publicsrmapply)！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        DynamicObject billTypeInfo = CommonHelperUtils.queryBaseDynamicObject("bos_billtype", "layoutsolution", layoutInfo.getString("id"));
        if(billTypeInfo == null){
            returnMessage = "未匹配到PC布局(nckd_er_publicsrmapply)对应的单据类型！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        DynamicObject bizAcctOutBill = BusinessDataServiceHelper.newDynamicObject(ENTITY_PUBLICPAY);
        Date bizDate = new Date();
        try {
            bizDate = CommonHelperUtils.getCurDateForm(new Date(), true);//申请日期
        } catch (ParseException e) {
//            throw new RuntimeException(e);
            returnMessage = e.getMessage();
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        bizAcctOutBill.set("bizdate", bizDate);//申请日期
        bizAcctOutBill.set("billstatus", "A");//单据状态
        bizAcctOutBill.set("reimbursetype", "expense");//报账类型
        bizAcctOutBill.set("nckd_srmbillno", srmBillNo);//srm单据号
        bizAcctOutBill.set("nckd_srmurl", srmUrl);//srm单点url
        bizAcctOutBill.set("contractsconn", contract);//合同号
        bizAcctOutBill.set("description", cause);//事由
        bizAcctOutBill.set("applier", applierInfo);//申请人
        bizAcctOutBill.set("applierpositionstr", positionName);//职位
        bizAcctOutBill.set("org", dept);//申请人部门
        bizAcctOutBill.set("company", adminCompany);//申请人公司
        bizAcctOutBill.set("costdept", dept);//费用承担部门
        bizAcctOutBill.set("costcompany", costCompany);//费用承担公司
        bizAcctOutBill.set("paycompany", costCompany);//支付公司
        bizAcctOutBill.set("creator", creatorInfo);//制单人
        bizAcctOutBill.set("tel", applierInfo.get("phone"));//电话号码
        bizAcctOutBill.set("formid", "er_publicreimbursebill");//表单id
        bizAcctOutBill.set("iscrepayablebill", "0");//生成应付单
        bizAcctOutBill.set("billpayertype", "bd_supplier");//往来类型
        bizAcctOutBill.set("detailtype", detailtype);//关联业务
        bizAcctOutBill.set("nckd_detailtype", detailtype);//是否关联合同
        bizAcctOutBill.set("assettype", "newasset");//资产类型
        bizAcctOutBill.set("abovequota", "0");//超额
        bizAcctOutBill.set("ispush", "false");//合同下推生成
        bizAcctOutBill.set("nckd_srmstatus", "1");//srm状态，1：SRM已推送；2：已退回SRM；3：已反写SRM；4：反写SRM失败
        bizAcctOutBill.set("nckd_duigong", "01");//是否对公业务
        setDefaultMultViewType(bizAcctOutBill);//多选页面类型
        bizAcctOutBill.set("isbeforeshare", "0");//费用分摊
        bizAcctOutBill.set("sharerule", "orgrule");//
        bizAcctOutBill.set("sharemethod", "rate");//
        bizAcctOutBill.set("nckd_pageid", "nckd_er_publicsrmapply");//默认页面布局
        bizAcctOutBill.set("nckd_isrelapj", isRelapj);//是否关联项目
        bizAcctOutBill.set("frameworkcontract", isframeworkcontract);//是否框架合同

        //单据类型
        if(bizAcctOutBill.getDynamicObjectType().getProperties().containsKey("nckd_billtypefield")) {
            bizAcctOutBill.set("nckd_billtypefield", billTypeInfo);
        }

        //费用明细
        DynamicObjectCollection expenseEntry  = bizAcctOutBill.getDynamicObjectCollection("expenseentryentity");
        DynamicObjectType type = expenseEntry.getDynamicObjectType();
        JSONArray bizAccountOutBillEntry = inputData.getJSONArray("bizAccountOutBillEntry");

        Long itemEntryId = DB.genLongId("er_publicreimbursebill.expenseentryentity");

        BigDecimal totalReimburseAmount = BigDecimal.ZERO;//报销金额合计
        BigDecimal totalCurrReimburseAmount = BigDecimal.ZERO;//报销金额合计本位币

        if(bizAccountOutBillEntry.size() > 0) {
            DynamicObject currency = null;
            BigDecimal exchangeRate = BigDecimal.ONE;
            DynamicObject projectInfo = null;
            BigDecimal taxRate = BigDecimal.ZERO;
            BigDecimal totalTaxAmount = BigDecimal.ZERO;
            BigDecimal totalAmountOriWithoutTax = BigDecimal.ZERO;
            BigDecimal totalCurrAmountOriWithoutTax = BigDecimal.ZERO;

            for (int i = 0; i < bizAccountOutBillEntry.size(); i++) {
                JSONObject jsonData = bizAccountOutBillEntry.getJSONObject(i);

                String xsproject = jsonData.getString("xsproject");//核算项目，项目编号
                String currencyType = jsonData.getString("currencyType");//币别
                BigDecimal taxAmount = CommonHelperUtils.getBigDecimal(jsonData.getString("tax"));//税额
                BigDecimal amountOriWithoutTax = CommonHelperUtils.getBigDecimal(jsonData.getString("amountOriWithoutTax"));//原币不含税金额
                taxRate = CommonHelperUtils.getBigDecimal(jsonData.getString("taxRate"));//税率
                BigDecimal amountOri = CommonHelperUtils.getBigDecimal(jsonData.getString("amountOri"));//原币金额

                currency = CommonHelperUtils.queryBaseDynamicObject("bd_currency", "number", currencyType);
                if (currency == null) {
                    returnMessage = "币别(" + orgUnit + ")在星瀚系统中未匹配到数据！";
                    return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
                }

                if ("XM".equals(billType)) {
                    if (StringUtils.isEmpty(xsproject)) {
                        returnMessage = "项目类付款，请检查以下费用明细参数 项目编码 是否为空！";
                        return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
                    }

                    //替换连接符
                    xsproject = xsproject.replace("-", ".");

                    QFilter projectFilter = new QFilter("status", QCP.equals, "C");
                    projectFilter.and(new QFilter("enable", QCP.equals, "1"));
                    projectFilter.and(new QFilter("number", QCP.equals, xsproject));
                    projectFilter.and(new QFilter("createorg.id", QCP.equals, costCompany.getLong("id")));

                    projectInfo = BusinessDataServiceHelper.loadSingle("bd_project", projectFilter.toArray());
                    if (projectInfo == null) {
                        returnMessage = "组织(" + costCompany.getString("name") + ")下的项目(" + xsproject + ")在星瀚系统中未匹配到数据！";
                        return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
                    }

                    bizAcctOutBill.set("nckd_project", projectInfo);//项目，表头项目字段也取费用明细中的项目，一张付款单只会对应一个项目
                }

                if (currency.getLong("id") != 1L) {
                    exchangeRate = CommonHelperUtils.getExchangeRate(exchangeTableId, currency.getLong("id"), 1L, bizDate);
                }

                totalTaxAmount = totalTaxAmount.add(taxAmount);
                totalAmountOriWithoutTax = totalAmountOriWithoutTax.add(amountOriWithoutTax);

                totalReimburseAmount = totalReimburseAmount.add(amountOri);
                //报销金额本位币
                totalCurrReimburseAmount = totalCurrReimburseAmount.add(amountOri.multiply(exchangeRate).setScale(4, BigDecimal.ROUND_HALF_UP));
                totalCurrAmountOriWithoutTax = totalCurrAmountOriWithoutTax.add(amountOriWithoutTax.multiply(exchangeRate).setScale(4, BigDecimal.ROUND_HALF_UP));
            }

            DynamicObject entry = new DynamicObject(type);

            entry.set("id", itemEntryId);
            entry.set("seq", 1);
            entry.set("happendate", bizDate);
            entry.set("std_project", projectInfo);//分录项目

            entry.set("entrycostdept", dept);//费用承担部门
            entry.set("entrycostcompany", costCompany);//费用承担公司
            entry.set("entrycurrency", currency);//币别
            entry.set("taxRate", taxRate);//税率
            entry.set("expenseamount", totalReimburseAmount);//报销金额
            entry.set("expeapproveamount", totalReimburseAmount);//核定金额
            entry.set("taxamount", totalTaxAmount);//税额
            entry.set("approvetax", totalTaxAmount);//核定税额
            entry.set("orientryamount", totalAmountOriWithoutTax);//不含税金额
            entry.set("price", totalAmountOriWithoutTax);//核定不含税金额

            entry.set("exchangerate", exchangeRate);//汇率
            entry.set("expquotetype", "0");//换算方式
            entry.set("currexpenseamount", totalCurrReimburseAmount.setScale(2, BigDecimal.ROUND_HALF_UP));//报销金额本位币
            entry.set("expeapprovecurramount", totalCurrReimburseAmount.setScale(2, BigDecimal.ROUND_HALF_UP));//核定金额本位币
            entry.set("curprice", totalCurrAmountOriWithoutTax.setScale(2, BigDecimal.ROUND_HALF_UP));//核定不含税金额本位币
            entry.set("itemfrom", "0");//来源类型
            entry.set("invoicetypeitem", "0");//发票类型
            entry.set("iscrepayableentry", "1");//生成应付单
//            entry.set("expentrystatus", "");//单据状态
            entry.set("settlestatus", "unsettle");//结算状态
            entry.set("pubreimburser", applierInfo);//报销人

            if (contractInfo != null) {
                entry.set("entrycontractno", contract);
                entry.set("entrycontractname", contractInfo.getString("contractname"));
            }

            expenseEntry.add(entry);

            bizAcctOutBill.set("expenseentryentity", expenseEntry);
        }

        //报销金额本位币
        bizAcctOutBill.set("nckd_expenseamt", totalCurrReimburseAmount.setScale(2, BigDecimal.ROUND_HALF_UP));

        //收款明细
        //支付方式：默认为 银企直连
        qFilter = new QFilter("number", QCP.equals, "BANK");

        DynamicObject settleType = BusinessDataServiceHelper.loadSingle("bd_settlementtype", qFilter.toArray());
        DynamicObject supplier = null;

        DynamicObjectCollection accountEntry  = bizAcctOutBill.getDynamicObjectCollection("accountentry");
        type = accountEntry.getDynamicObjectType();
        JSONArray bizAccountOutBillAccountEntry = inputData.getJSONArray("bizAccountOutBillAccountEntry");

        for(int i = 0; i < bizAccountOutBillAccountEntry.size(); i++){
            JSONObject jsonData = bizAccountOutBillAccountEntry.getJSONObject(i);

            String payerType = jsonData.getString("payerType");//收款人类型
            String payerName = jsonData.getString("payerName");//原币社会信用码
            String currencyType = jsonData.getString("currencyType");//币别
            BigDecimal amountOri = CommonHelperUtils.getBigDecimal(jsonData.getString("amountOri"));//原币金额

            if(StringUtils.isEmpty(payerType)){
                returnMessage = "检查以下收款信息参数 收款人类型 是否为空！";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }
            if(!"20".equals(payerType)){
                returnMessage = "收款人类型只支持供应商！";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }

            supplier = CommonHelperUtils.queryBaseDynamicObject("bd_supplier", "societycreditcode", payerName);
            if(supplier == null){
                returnMessage = "供应商(" + payerName + ")在星瀚系统中未匹配到数据！";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }

            //供应商银行账号信息
            DynamicObjectCollection entryBanks = supplier.getDynamicObjectCollection("entry_bank");

            DynamicObject currency = CommonHelperUtils.queryBaseDynamicObject("bd_currency", "number", currencyType);
            if(currency == null){
                returnMessage = "币别(" + orgUnit + ")在星瀚系统中未匹配到数据！";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }

            BigDecimal exchangeRate = BigDecimal.ONE;
            if(currency.getLong("id") != 1L){
                exchangeRate = CommonHelperUtils.getExchangeRate(exchangeTableId, currency.getLong("id"), 1L, bizDate);
            }
            BigDecimal amountOriLocal = amountOri.multiply(exchangeRate).setScale(4, BigDecimal.ROUND_HALF_UP);

            DynamicObject entry = new DynamicObject(type);

            entry.set("paymode", settleType);//支付方式
            entry.set("payerType", "bd_supplier");//收款人类型
            entry.set("supplier", supplier);//收款人
            entry.set("payername", supplier.getString("name"));//收款人名称

            if(entryBanks.size() > 0){
                for(DynamicObject entryBank : entryBanks){
                    if(entryBank.getBoolean("isdefault_bank")){
                        entry.set("payeraccount", entryBank.getString("bankaccount"));//银行账号
                        entry.set("payeraccountname", entryBank.getString("accountname"));//账户名称
                        entry.set("payerbank", entryBank.getDynamicObject("bank"));//开户银行

                        break;
                    }
                }
            }

            entry.set("accountcurrency", currency);//币别
            entry.set("accexchangerate", exchangeRate);//汇率
            entry.set("orireceiveamount", amountOri);//收款金额
            entry.set("receiveamount", amountOriLocal);//收款金额本位币
            entry.set("oriaccnotpayamount", amountOri);//未付金额
            entry.set("accnotpayamount", amountOriLocal);//未付金额本位币

            accountEntry.add(entry);

            bizAcctOutBill.set("billpayerid", supplier);//表头往来单位
        }
        bizAcctOutBill.set("accountentry", accountEntry);

        BigDecimal totalLoanCheckAmount = BigDecimal.ZERO;//冲销金额合计
        //冲预付/借款
        DynamicObjectCollection writeoffmoney  = bizAcctOutBill.getDynamicObjectCollection("writeoffmoney");
        type = writeoffmoney.getDynamicObjectType();
        JSONArray bizAccountOutBillLoanCheckEntry = inputData.getJSONArray("bizAccountOutBillLoanCheckEntry");

        for(int i = 0; i < bizAccountOutBillLoanCheckEntry.size(); i++){
            JSONObject jsonData = bizAccountOutBillLoanCheckEntry.getJSONObject(i);

            String sourceBillNumber = jsonData.getString("sourceBillNumber");//SRM预付单编号
            String currencyType = jsonData.getString("currencyType");//币别
            String srmseq = jsonData.getString("srmseq");//预付单行号

            BigDecimal checkAmountOri = CommonHelperUtils.getBigDecimal(jsonData.getString("checkAmountOri"));//冲账金额

            if(StringUtils.isEmpty(sourceBillNumber) || StringUtils.isEmpty(currencyType)){
                returnMessage = "请检查冲预付参数 预付单号、币别 是否为空！";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }

            DynamicObject currency = CommonHelperUtils.queryBaseDynamicObject("bd_currency", "number", currencyType);
            if(currency == null){
                returnMessage = "币别(" + orgUnit + ")在星瀚系统中未匹配到数据！";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }

            BigDecimal exchangeRate = BigDecimal.ONE;
            if(currency.getLong("id") != 1L){
                exchangeRate = CommonHelperUtils.getExchangeRate(exchangeTableId, currency.getLong("id"), 1L, bizDate);
            }

            DynamicObject prepayBillInfo = CommonHelperUtils.queryBillDynamicObject("er_prepaybill", "nckd_srmbillno", sourceBillNumber, "G");
            if(prepayBillInfo == null){
                returnMessage = "预付单(" + sourceBillNumber + ")在星瀚系统中未匹配到已付款状态的数据！";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }

            DynamicObjectCollection prepayEntrys = prepayBillInfo.getDynamicObjectCollection("expenseentryentity");
            DynamicObject prepayEntry = prepayEntrys.get(0);

            for(DynamicObject preEntry : prepayEntrys){
                if(preEntry.getString("seq").equals(srmseq)){
                    prepayEntry = preEntry;
                    break;
                }
            }

            DynamicObjectCollection prepayAccounts = prepayBillInfo.getDynamicObjectCollection("accountentry");
            DynamicObject prepayAccount = prepayAccounts.get(0);

            DynamicObject entry = new DynamicObject(type);

            entry.set("loanbillnov1", prepayBillInfo.getString("billno"));//单据编号
            entry.set("sourceentrycostdept", prepayBillInfo.getDynamicObject("costdept"));//费用承担部门
            entry.set("sourceentrycostcompany", prepayBillInfo.getDynamicObject("costcompany"));//费用承担公司
            entry.set("std_srcentrycostcenter", prepayBillInfo.getDynamicObject("std_costcenter"));//成本中心
            entry.set("sourceexpenseitem", prepayEntry.getDynamicObject("expenseitem"));//费用项目
            entry.set("srcentrywltype", "bd_supplier");//往来类型
            entry.set("srcentrywlunit", prepayAccount.getDynamicObject("supplier"));// 往来单位
            entry.set("writeoffquotetype", "0");//换算方式
            entry.set("loanperson", prepayBillInfo.getDynamicObject("applier").getString("name"));//借款人
            entry.set("loanapplydatev1", prepayBillInfo.getDate("bizdate"));//申请日期
            entry.set("loandescriptionv1", prepayBillInfo.getString("description"));//事由
            entry.set("loancurrency", currency);//币种
            entry.set("loanexchangerate", exchangeRate);//汇率
            entry.set("loanamount", prepayEntry.getBigDecimal("orgiexpebalanceamount"));//借款余额
            entry.set("currloanamount", prepayEntry.getBigDecimal("expebalanceamount"));//借款余额(本位币)
            entry.set("accloanamount", checkAmountOri);//冲销金额
            entry.set("curraccloanamount", checkAmountOri.multiply(exchangeRate));//冲销金额(本位币)
            entry.set("sourcebillid", prepayBillInfo.getString("id"));//源单id
            entry.set("sourceentryid", prepayEntry.getString("id"));//源单分录id
            entry.set("srcbilltype", "er_prepaybill");//源单类型
            entry.set("seq", srmseq);

            //记录对公报销与预付单的关联关系
            String targetEntityNumber = "er_publicreimbursebill";//对公报销
            String targetEntryKey = "writeoffmoney";//对公报销-冲预付、冲借款
            String srcEntityNumber = "er_prepaybill";//预付单
            String srcEntryKey = "expenseentryentity";//预付信息
            // 获取目标单单据体的实体表格定义：主实体 + 单据体 -> 对应一个唯一的实体表格定义
            TableDefine targetTableDefine = EntityMetadataCache.loadTableDefine(targetEntityNumber, targetEntryKey);
            // 获取源单单据体的表格定义：记录关联关系时，需要用到此对象中的tableId值，用一个长整数值唯一标识源单及单据体
            TableDefine srcTableDefine = EntityMetadataCache.loadTableDefine(srcEntityNumber, srcEntryKey);

            DynamicObjectCollection linkRows = entry.getDynamicObjectCollection("writeoffmoney_lk");
            if (linkRows.isEmpty()) {
                String lkEntryKey ="writeoffmoney_lk";
                Long srcTableId = srcTableDefine.getTableId();

                // 找到了匹配的行，创建一条_lk子实体上数据，记录源单内码
                DynamicObject linkRow = new DynamicObject(linkRows.getDynamicObjectType());
                linkRows.add(linkRow);
                // 在lk行中，记录源单分录表格编码、源单内码、源单分录内码

                linkRow.set("id", ID.genLongId());
                linkRow.set("seq", 1);
                linkRow.set(lkEntryKey + "_stableid", srcTableId);        // 源单分录表格编码：以此标识源单类型及单据体
                linkRow.set(lkEntryKey + "_sbillid", prepayBillInfo.getString("id"));        // 源单内码
                linkRow.set(lkEntryKey + "_sid", prepayEntry.getString("id"));            // 源单分录行内码
            }

            writeoffmoney.add(entry);

            totalLoanCheckAmount = totalLoanCheckAmount.add(checkAmountOri);
        }
        bizAcctOutBill.set("writeoffmoney", writeoffmoney);

        bizAcctOutBill.set("reimburseamount", totalReimburseAmount);//报销金额
        bizAcctOutBill.set("approveamount", totalReimburseAmount);//核定金额
        bizAcctOutBill.set("payamount", totalReimburseAmount.subtract(totalLoanCheckAmount));//付现金额
        bizAcctOutBill.set("notpayamount", totalReimburseAmount);//未付金额

        //发票信息
        DynamicObjectCollection invoiceEntry  = bizAcctOutBill.getDynamicObjectCollection("invoiceentry");
        type = invoiceEntry.getDynamicObjectType();
        JSONArray fpentry = inputData.getJSONArray("fpentry");

        //发票数量
        int fpCount = fpentry.size();
        //发票合计可用金额
        BigDecimal totalInvAmount = BigDecimal.ZERO;

        String invoiceCode = "";
        String invoiceName = "";

        for(int i = 0; i < fpentry.size(); i++){
            JSONObject jsonData = fpentry.getJSONObject(i);

            String fpNumber = jsonData.getString("fpNumber");//发票号
            String fpCode = jsonData.getString("fpCode");//发票代码
            String serialNo = jsonData.getString("serialNo");//发票流水号
            String taxAmount = jsonData.getString("taxAmount");//税额

            if(StringUtils.isEmpty(serialNo)){
//                returnMessage = "发票分录的第" + (i + 1) + "行的发票流水号不能为空";
//                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);

                continue;
            }

            Long invoiceEntryId = DB.genLongId("er_publicreimbursebill.invoiceentry");

            DynamicObject entry = new DynamicObject(type);
            entry.set("id", invoiceEntryId);
            entry.set("seq", (i + 1));
            entry.set("invoiceno", fpNumber);//发票号
            entry.set("invoicecode", fpCode);//发票代码
            entry.set("serialno", serialNo);//发票流水号

            List<String> serialNoList = new ArrayList<String>();
            serialNoList.add(serialNo);

            Map<String, Object> invoiceMap = DispatchServiceHelper.invokeBizService("imc", "rim", "FpzsService", "query", serialNoList);

            if(invoiceMap != null && invoiceMap.get("data") != null){
                JSONArray invoiceArray =  (JSONArray)invoiceMap.get("data");
                for(int j = 0; j < invoiceArray.size(); j++) {
                    //发票表头
                    JSONObject invoiceObj = invoiceArray.getJSONObject(j);

                    invoiceCode += (invoiceCode.length() > 0 ? "，" : "") + invoiceObj.getString("invoiceNo");

                    fpNumber = invoiceObj.getString("invoiceNo");
                    Date invoiceDate = CommonHelperUtils.getDateStringFormat(invoiceObj.getString("invoiceDate"), "yyyy-MM-dd");
                    Date billCreateTime = CommonHelperUtils.getDateStringFormat(invoiceObj.getString("billCreateTime"), "yyyy-MM-dd HH:mm:ss");
                    String salerName = invoiceObj.getString("salerName");//销方名称
                    String salerTaxNo = invoiceObj.getString("salerTaxNo");//销方税号
                    String buyerName = invoiceObj.getString("buyerName");//购方名称
                    String buyerTaxNo = invoiceObj.getString("buyerTaxNo");//购方税号
                    DynamicObject invoiceTypeInfo = CommonHelperUtils.queryBaseDynamicObject("er_invoicetype", "number", invoiceObj.getString("invoiceType"));
                    BigDecimal taxAmountTotal = CommonHelperUtils.getBigDecimal(invoiceObj.getBigDecimal("totalTaxAmount"));//税额
                    BigDecimal totalamount = CommonHelperUtils.getBigDecimal(invoiceObj.getBigDecimal("totalAmount"));//价税合计
                    BigDecimal invoiceAmount = CommonHelperUtils.getBigDecimal(invoiceObj.getBigDecimal("invoiceAmount"));//不含税金额

                    DynamicObject salerInfo = CommonHelperUtils.queryBaseDynamicObject("bd_supplier", "societycreditcode", salerTaxNo);
                    if(salerInfo == null){
                        salerInfo = supplier;

//                        returnMessage = "供应商(" + salerTaxNo + ")在星瀚系统中未匹配到数据！";
//                        return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
                    }

                    DynamicObject buyer = BusinessDataServiceHelper.loadSingle("bdm_enterprise_baseinfo", (new QFilter("number", QCP.equals, buyerTaxNo)).toArray());


                    if(buyer == null){
                        returnMessage = "购方税号(" + buyerTaxNo + ")在星瀚系统中未匹配到企业信息！";
                        return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
                    }

                    entry.set("invoicetype", invoiceObj.getString("invoiceType"));//发票类型
                    entry.set("invoiceno", invoiceObj.getString("invoiceNo"));//发票号
                    entry.set("invoicecode", invoiceObj.getString("invoiceNo"));//发票代码
                    entry.set("serialno", invoiceObj.getString("serialNo"));//发票流水号
                    entry.set("invoicedate", invoiceDate);//开票日期
                    entry.set("invexchangerate", "1");//汇率
                    entry.set("invexpquotetype", "0");//换算方式
                    entry.set("totalamount", totalamount);//价税合计
                    entry.set("currtotalamount", totalamount);//价税合计本位币
//                    entry.set("taxdetails", "");//多税率信息
                    entry.set("taxamount_invoice", taxAmountTotal);//税额
                    entry.set("invoicenotaxamount", invoiceAmount);//不含税金额
                    entry.set("validatemessage", invoiceObj.getString("validateMessage"));//发票校验结果
                    entry.set("ie_validatest", invoiceObj.getString("checkStatus"));//查验状态
                    entry.set("invoiceischange", "1");//已修改
                    entry.set("sequencenum", "2");//连号
                    entry.set("billcreatetime", billCreateTime);//采集时间
                    entry.set("buyerorgname", buyerName);//收票公司
                    entry.set("buyertaxno", buyerTaxNo);//收票方税号
                    entry.set("makeoutcompname", salerName);//开票公司
                    entry.set("salertaxno_h", salerTaxNo);//开票方税号
                    entry.set("count", 1);//发票张数
                    entry.set("invoicefrom", "1");//发票来源
                    entry.set("ismapexpense", "1");//关联费用明细
                    entry.set("offset_invoice", invoiceObj.getString("deductionFlag"));//可抵扣
                    entry.set("offsetamount", CommonHelperUtils.getBigDecimal(invoiceObj.getString("effectiveTaxAmount")));//可抵扣税额
                    entry.set("buyerorg", buyer.getDynamicObject("org"));//购方组织
                    entry.set("sellerorg", salerInfo);//销方供应商
                    entry.set("issupplement", "0");//后补发票
                    entry.set("passverifybuyername", "1");//发票抬头一致
                    entry.set("passverifybuyertaxno", "1");//发票税号一致
                    entry.set("personalinvoice", "0");//个人发票
                    entry.set("isred", invoiceObj.getString("type"));//红字发票
                    entry.set("invoicecurrency", 1L);//发票币种
                    entry.set("invoicebuyeraddressphone", invoiceObj.getString("buyerAddressPhone"));
                    entry.set("oribalanceamount", CommonHelperUtils.getBigDecimal(invoiceObj.getBigDecimal("totalAmount")));//账单余额
                    entry.set("poolreimburseamount", CommonHelperUtils.getBigDecimal(invoiceObj.getBigDecimal("totalAmount")));//本次报销金额
                    entry.set("transportnote", "0");//运输票据

                    entry.set("ismutilreimburse", true);//多次报销
                    QFilter qFilterSerialNo = new QFilter("serialno", QCP.equals, serialNo);
                    DynamicObject billingPool = BusinessDataServiceHelper.loadSingle("er_billingpool", qFilterSerialNo.toArray());
                    if(billingPool != null){
                        entry.set("ispool", true);//账单id
                        entry.set("billingpoolid", billingPool.getLong("id"));//账单id
                        entry.set("oribalanceamount", billingPool.getBigDecimal("oribalanceamount"));//可用余额
                        entry.set("poolreimburseamount", billingPool.getBigDecimal("oribalanceamount"));//可用余额

                        bizAcctOutBill.set("automapinvoice", false);
                    }

                    totalInvAmount = totalInvAmount.add(entry.getBigDecimal("poolreimburseamount"));

                    if(fpCount == 1){
                        if(totalReimburseAmount.compareTo(entry.getBigDecimal("poolreimburseamount")) < 0) {
                            entry.set("poolreimburseamount", totalReimburseAmount);//本次报销金额
                        }
                    }

                    String invoiceGoodsName = "";

                    List<String> invoiceGoodsCode = new ArrayList<>();
                    BigDecimal taxRate = BigDecimal.ZERO;
                    BigDecimal taxRate100 = BigDecimal.ZERO;
                    JSONArray itemArray = invoiceObj.getJSONArray("items");

                    if(itemArray != null && itemArray.size() > 0) {
                        DynamicObjectCollection invoiceitementry  = bizAcctOutBill.getDynamicObjectCollection("invoiceitementry");
                        DynamicObjectType itemType = invoiceitementry.getDynamicObjectType();

                        for (int k = 0; k < itemArray.size(); k++) {
                            //发票明细
                            JSONObject itemObj = itemArray.getJSONObject(k);

                            String goodsCode = itemObj.getString("goodsCode");//商品编码

                            DynamicObject goodsCodeInfo = CommonHelperUtils.queryBaseDynamicObject("er_taxclasscode", "mergecode", goodsCode);

                            String goodsName = itemObj.getString("goodsName");//商品名称
                            String specModel = itemObj.getString("specModel");//规格型号
                            String unit = itemObj.getString("unit");//单位
                            BigDecimal unitPrice = CommonHelperUtils.getBigDecimal(itemObj.getString("unitPrice"));//单价
                            BigDecimal num = CommonHelperUtils.getBigDecimal(itemObj.getString("num"));//数量
                            BigDecimal taxAmountItem = CommonHelperUtils.getBigDecimal(itemObj.getString("taxAmount"));//税额
                            taxRate = CommonHelperUtils.getBigDecimal(itemObj.getString("taxRate"));
                            taxRate100 = taxRate.multiply(new BigDecimal("100"));//税率
                            BigDecimal detailAmount = CommonHelperUtils.getBigDecimal(itemObj.getString("detailAmount"));//明细金额

                            invoiceGoodsName += (invoiceGoodsName.length() > 0 ? "，" : "") + goodsName;
                            invoiceName += (invoiceName.length() > 0 ? "，" : "") + goodsName;

                            if(goodsCodeInfo != null && !invoiceGoodsCode.contains(goodsCodeInfo.getString("name"))){
                                invoiceGoodsCode.add(goodsCodeInfo.getString("name"));
                            }

                            DynamicObject itemEntry = new DynamicObject(itemType);

                            itemEntry.set("seq", (k+1));//序号
                            itemEntry.set("itementryid", itemEntryId);//费用项目分录id
                            itemEntry.set("invoiceheadentryid", invoiceEntryId);//费用项目分录id
                            itemEntry.set("invoicetype_item", invoiceTypeInfo);//发票类型
                            itemEntry.set("invoiceno_item", fpNumber);//发票号码
                            itemEntry.set("invoicedate_item", invoiceDate);//开票日期
                            itemEntry.set("invoicecurrency_item", 1L);//发票币种
                            itemEntry.set("unit", unit);//单位
                            itemEntry.set("num", num);//数量
                            itemEntry.set("unitprice", unitPrice.setScale(2, BigDecimal.ROUND_HALF_UP));//不含税单价
                            itemEntry.set("excludeamount", detailAmount);//不含税金额
                            itemEntry.set("invoiceitemtaxrate", taxRate);//税率
                            itemEntry.set("invoiceitemtaxamout", taxAmountItem);//税额
                            itemEntry.set("totalamount_item", totalamount);//价税合计
//                            itemEntry.set("invoicetaxrate_item", "");//单头税率
                            itemEntry.set("invoicetaxamount_item", taxAmountTotal);//单头税额
                            itemEntry.set("specmodel", specModel);//规格型号
                            itemEntry.set("goodscode", goodsCode);//税收分类编码
                            itemEntry.set("goodsname", goodsName);//商品名称
                            itemEntry.set("invoicefrom1", "1");//发票来源
                            itemEntry.set("invoiceitemoffset", invoiceObj.getString("deductionFlag"));//可抵扣
                            itemEntry.set("invoicecloudoffset", "1");//发票抵扣
                            itemEntry.set("salertaxno", salerTaxNo);//开票方税号
                            itemEntry.set("invoiceitemisunbind", "0");//解绑
                            itemEntry.set("invoiceitemserialno", serialNo);//发票序列号

                            //发票信息分录的部分字段取发票明细的第一条记录
                            if(k == 0){
                                entry.set("unit_h", unit);//单位
                                entry.set("alltaxrate", taxRate100);//税率
                                entry.set("num_h", num);//数量
                                entry.set("unitprice_h", unitPrice.setScale(2, BigDecimal.ROUND_HALF_UP));//单价

//                                DynamicObjectCollection expenseEntrys = bizAcctOutBill.getDynamicObjectCollection("expenseentryentity");
//                                expenseEntrys.get(0).set("invoiceno_entry", invoiceObj.getString("invoiceNo"));
//                                expenseEntrys.get(0).set("expensegoodsname", goodsName);
                            }

                            invoiceitementry.add(itemEntry);
                        }

                        bizAcctOutBill.set("invoiceitementry", invoiceitementry);

                        if(invoiceGoodsName.length() > 200){
                            invoiceGoodsName = invoiceGoodsName.substring(0, 200) + "...";
                        }
                        String invoiceGoodsCodeString = String.join("，", invoiceGoodsCode);
                        if(invoiceGoodsCodeString.length() > 200){
                            invoiceGoodsCodeString = invoiceGoodsCodeString.substring(0, 200) + "...";
                        }

                        entry.set("invoicegoodsname", invoiceGoodsName);//商品名称
                        entry.set("invoicealltaxcode", invoiceGoodsCodeString);//税收分类编码
                    }
                }
            }
            invoiceEntry.add(entry);
        }

        if(fpCount > 1 && totalInvAmount.compareTo(totalReimburseAmount) != 0){
            for(DynamicObject checkEntry : invoiceEntry){
                checkEntry.set("poolreimburseamount", BigDecimal.ZERO);
            }
        }

        bizAcctOutBill.set("invoiceentry", invoiceEntry);

        if(invoiceName.length() > 200){
            invoiceName = invoiceName.substring(0, 200) + "...";
        }

        if(invoiceCode.length() > 200){
            invoiceCode = invoiceCode.substring(0, 200) + "...";
        }

        DynamicObjectCollection expenseEntrys = bizAcctOutBill.getDynamicObjectCollection("expenseentryentity");
        if(expenseEntrys.size() > 0) {
            expenseEntrys.get(0).set("invoiceno_entry", invoiceCode);
            expenseEntrys.get(0).set("expensegoodsname", invoiceName);
        }

        //合同信息
        if(contractInfo != null){
            DynamicObjectCollection contractEntry  = bizAcctOutBill.getDynamicObjectCollection("contractentry");
            type = contractEntry.getDynamicObjectType();

            DynamicObject currency = contractInfo.getDynamicObject("contractcurrency");
            currency = CommonHelperUtils.queryBaseDynamicObject("bd_currency", "number", currency.getString("number"));

            if(currency == null){
                returnMessage = "币别(" + orgUnit + ")在星瀚系统中未匹配到数据！";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }

            BigDecimal exchangeRate = BigDecimal.ONE;
            if(currency.getLong("id") != 1L){
                exchangeRate = CommonHelperUtils.getExchangeRate(exchangeTableId, currency.getLong("id"), 1L, bizDate);
            }

            BigDecimal contractAmount = contractInfo.getBigDecimal("contractamount");//合同总额（初始）
            BigDecimal oriapplyAmount = contractInfo.getBigDecimal("oriapplyamount");//合同总额（变更后）

            DynamicObjectCollection contractPartyEntry = contractInfo.getDynamicObjectCollection("contractpartyentry"); //
            if(contractPartyEntry.size() > 0){
                for(DynamicObject partyEntry : contractPartyEntry){
                    DynamicObject entry = new DynamicObject(type);

                    DynamicObject contractparty = partyEntry.getDynamicObject("contractparty");
                    if(contractparty.getLong("id") != supplier.getLong("id")){
                        continue;
                    }

                    entry.set("seq", 1);
                    entry.set("contractcode", contract);//合同号
                    entry.set("contractname", contractInfo.getString("contractname"));//合同名称
                    entry.set("signdate", contractInfo.getDate("signdate"));//签订日期
                    entry.set("contractdescription", contractInfo.getString("description"));//合同说明
                    entry.set("contractapplier", contractInfo.getDynamicObject("applier"));//经办人
                    entry.set("contractcostorg", contractInfo.getDynamicObject("costcompany"));//核算组织
                    entry.set("contractparta", contractInfo.getDynamicObject("parta"));//甲方old
                    entry.set("contractpartbtype", "bd_supplier");//乙方类型
                    entry.set("contractpartb", contractparty);//乙方
                    entry.set("contractpartatypenew", "bos_org");//甲方类型
                    entry.set("contractpartanew", costCompany);//甲方
                    entry.set("nckd_contractamt", contractAmount);//合同总额（初始）
                    entry.set("nckd_oriapplyamt", oriapplyAmount);//合同总额（变更后）

                    DynamicObjectCollection payplanEntrys = contractInfo.getDynamicObjectCollection("expenseentryentity");
                    if(payplanEntrys.size() > 0){
                        DynamicObject planEntry = payplanEntrys.get(0);

                        entry.set("contractexppaytypeid", planEntry.getDynamicObject("paymenttypeid"));//付款类型
                        entry.set("contractexphappendate", planEntry.getDate("happendate"));//预计付款日期
                        entry.set("contractexpproject", planEntry.getDynamicObject("std_project"));//项目
                        entry.set("contractexpenseitem", planEntry.getDynamicObject("expenseitem"));//费用项目
                        entry.set("contractexpcurrency", planEntry.getDynamicObject("entrycurrency"));//币种
                        entry.set("contractexpchangerate", planEntry.getBigDecimal("exchangerate"));//汇率
                        entry.set("contractexpquotetype", "0");//换算方式
                        entry.set("entryprepayedamount", planEntry.getBigDecimal("pushedamount"));//已预付金额
                        entry.set("entrycurrprepayedamount", planEntry.getBigDecimal("pushedcurramount"));//已预付金额本位币
                        entry.set("contractreimamount", planEntry.getBigDecimal("oriexppayedamount"));//已付金额
                        entry.set("contractcurrreimamhttount", planEntry.getBigDecimal("exppayedamount"));//已付金额本位币
                        entry.set("contractcanamount", planEntry.getBigDecimal("orgiexpebalanceamount"));//可报销金额
                        entry.set("contractcurrcanamount", planEntry.getBigDecimal("expebalanceamount"));//可报销金额本位币
//                        entry.set("contractwriteoff", planEntry.getBigDecimal("canloanamount"));//冲销金额
//                        entry.set("contractcurrwriteoff", planEntry.getBigDecimal("canloancurramount"));//冲销金额本位币
                        entry.set("oricontractnotpayamount", planEntry.getBigDecimal("oriexpnotpayamount"));//未付金额
                        entry.set("contractnotpayamount", planEntry.getBigDecimal("expnotpayamount"));//未付金额本位币

                        entry.set("contractsid", contractInfo.getLong("id"));//源单id
                        entry.set("contractsrcentryid", planEntry.getLong("id"));//关联合同分录id


                        //记录对公报销与合同台账的
                        String targetEntityNumber = "er_publicreimbursebill";//对公报销
                        String targetEntryKey = "contractentry";//对公报销-冲预付、冲借款
                        String srcEntityNumber = "er_contractbill";//合同台账
                        String srcEntryKey = "expenseentryentity";//合同付款计划
                        // 获取目标单单据体的实体表格定义：主实体 + 单据体 -> 对应一个唯一的实体表格定义
                        TableDefine targetTableDefine = EntityMetadataCache.loadTableDefine(targetEntityNumber, targetEntryKey);
                        // 获取源单单据体的表格定义：记录关联关系时，需要用到此对象中的tableId值，用一个长整数值唯一标识源单及单据体
                        TableDefine srcTableDefine = EntityMetadataCache.loadTableDefine(srcEntityNumber, srcEntryKey);

                        DynamicObjectCollection linkRows = entry.getDynamicObjectCollection("contractentry_lk");
                        if (linkRows.isEmpty()) {
                            String lkEntryKey ="contractentry_lk";
                            Long srcTableId = srcTableDefine.getTableId();

                            // 找到了匹配的行，创建一条_lk子实体上数据，记录源单内码
                            DynamicObject linkRow = new DynamicObject(linkRows.getDynamicObjectType());
                            linkRows.add(linkRow);
                            // 在lk行中，记录源单分录表格编码、源单内码、源单分录内码

                            linkRow.set("id", ID.genLongId());
                            linkRow.set("seq", 1);
                            linkRow.set(lkEntryKey + "_stableid", srcTableId);        // 源单分录表格编码：以此标识源单类型及单据体
                            linkRow.set(lkEntryKey + "_sbillid", contractInfo.getString("id"));        // 源单内码
                            linkRow.set(lkEntryKey + "_sid", planEntry.getString("id"));            // 源单分录行内码
                        }

                    }


                    contractEntry.add(entry);


                    break;
                }
            }

            bizAcctOutBill.set("contractentry", contractEntry);
        }

        try {
            //新增保存供应商对象
            OperationResult resultSave = SaveServiceHelper.saveOperate(ENTITY_PUBLICPAY, new DynamicObject[]{bizAcctOutBill}, OperateOption.create());

            StringBuilder err = new StringBuilder();
            if (resultSave.getSuccessPkIds().size() <= 0) {
                if(kd.bos.util.StringUtils.isNotEmpty(resultSave.getMessage())){
                    err.append(resultSave.getMessage() + ";");
                }

                for (int i = 0; i < resultSave.getAllErrorOrValidateInfo().size(); i++) {
                    String message = resultSave.getAllErrorOrValidateInfo().get(i).getMessage();
                    err.append("/").append(message);
                }

                returnMessage = "失败" + err.toString();
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }

            DynamicObject billInfo = BusinessDataServiceHelper.loadSingle(resultSave.getSuccessPkIds().get(0), ENTITY_PUBLICPAY);

            return buildReturnData("0", srmBillNo, "成功", resultSave.getSuccessPkIds().get(0).toString(), billInfo.getString("billno"), ENTITY_PUBLICPAY);

        } catch(Exception e){
            returnMessage = "失败" + e.getMessage();
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }
    }

    /**
     * 保存预付单
     * @param inputData
     * @return
     */
    private JSONObject saveDailyLoanBillInfo (JSONObject inputData){
        JSONObject returnMap = new JSONObject();
        String code = "1";
        String returnMessage = "";

        String billType = inputData.getString("billTypeEx");//单据类型
        String srmBillNo = inputData.getString("SRMBillNo");//srm单据号
        String srmUrl = inputData.getString("srmUrl");//
        String u8Org = inputData.getString("u8Org");//发票抬头
        String contract = inputData.getString("contract");//合同编号
        String cause = inputData.getString("cause");//事由
        String applier = inputData.getString("applier");//经办人工号
        String orgUnit = inputData.getString("orgUnit");//申请部门
        String position = inputData.getString("position");//职位
        String biller = inputData.getString("biller");//制单人工号

        if(StringUtils.isEmpty(srmBillNo)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "SRM单号 不能为空";
        }

        if(StringUtils.isEmpty(srmUrl)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "srmUrl 不能为空";
        }

        if(StringUtils.isEmpty(cause)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "事由 不能为空";
        }

        if(StringUtils.isEmpty(orgUnit)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "申请部门 不能为空";
        }

        if(StringUtils.isEmpty(position)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "申请人职位 不能为空";
        }

        if(StringUtils.isEmpty(biller)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "制单人 不能为空";
        }

        if( StringUtils.isEmpty(applier)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "经办人 不能为空";
        }

        if(StringUtils.isEmpty(u8Org)){
            returnMessage = ("".equals(returnMessage) ? "" : ",") + "u8组织 不能为空";
        }

        if(!StringUtils.isEmpty(returnMessage)){
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        //根据srm单据编号，校验在星瀚中是否已存在单据
        String xhBillNO = queryBillInfoBySRMBillNo(ENTITY_PREPAY, srmBillNo);
        if(!StringUtils.isEmpty(xhBillNO)){
            returnMessage = "此SRM单号在星瀚系统已存在，预付单编号：" + xhBillNO;
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        DynamicObject creatorInfo = CommonHelperUtils.queryBaseDynamicObject("bos_user", "number", biller);
        if(creatorInfo == null){
            returnMessage = "制单人(" + biller + ")在星瀚系统中未匹配到数据！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        DynamicObject applierInfo = CommonHelperUtils.queryBaseDynamicObject("bos_user", "number", applier);
        if(applierInfo == null){
            returnMessage = "经办人(" + applier + ")在星瀚系统中未匹配到数据！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        DynamicObject dept = CommonHelperUtils.queryBaseDynamicObject("bos_org", "number", orgUnit);
        if(dept == null){
            returnMessage = "行政组织(" + orgUnit + ")在星瀚系统中未匹配到数据！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        DynamicObject positionInfo = CommonHelperUtils.queryBaseDynamicObject("hbpm_positionhr", "number", position);
        if(positionInfo == null){
            returnMessage = "岗位(" + position + ")在星瀚系统中未匹配到数据！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }
        LocaleString positionName = new LocaleString(positionInfo.getString("name"));

        //申请人公司行政组织
        DynamicObject adminCompany = CommonHelperUtils.getAdminCompany(dept);

        QFilter qFilter = new QFilter("toorg", QCP.equals, dept.getPkValue());
//        DynamicObject relation = BusinessDataServiceHelper.loadSingle("bos_org_orgrelation_dept", qFilter.toArray());
//        if(relation == null){
//            returnMessage = "行政组织(" + dept.getString("number") + ", " + dept.getString("name") + ")在星瀚系统未维护委托业务单元！";
//            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
//        }
        //费用承担公司
//        DynamicObject costCompany = relation.getDynamicObject("fromorg");

        DynamicObject costCompany = CommonHelperUtils.queryBaseDynamicObject("bos_org", "name", u8Org);
        if(costCompany == null){
            returnMessage = "u8组织(" + u8Org + ")在星瀚系统中未匹配到数据！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        //汇率表Id
        Long exchangeTableId = CommonHelperUtils.getExchageTableId(costCompany.getLong("id"));

        if(exchangeTableId == null){
            returnMessage = "核算组织(" + costCompany.getString("name") + ")在星瀚系统匹配到汇率表！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        String detailtype = "biztype_other";
        //合同台账
        DynamicObject contractInfo = null;
        if(!StringUtils.isEmpty(contract)) {
            qFilter = new QFilter("contractcode", QCP.equals, contract);
            contractInfo = BusinessDataServiceHelper.loadSingle("er_contractbill", qFilter.toArray());

            if(contractInfo == null){
                returnMessage = "合同(" + contract + ")在星瀚中未匹配到合同台账";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }

            detailtype = "biztype_contract";
        }

        //单据类型
        //处理单据类型
        QFilter f = new QFilter("number", "=", "nckd_er_srmperpaybill");
        DynamicObject layoutInfo = BusinessDataServiceHelper.loadSingle("bos_formmeta", "id, number,name, basedatafield", f.toArray());

        if(layoutInfo == null){
            returnMessage = "未匹配到PC布局(nckd_er_srmperpaybill)！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        DynamicObject billTypeInfo = CommonHelperUtils.queryBaseDynamicObject("bos_billtype", "layoutsolution", layoutInfo.getString("id"));
        if(billTypeInfo == null){
            returnMessage = "未匹配到PC布局(nckd_er_srmperpaybill)对应的单据类型！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        DynamicObject dailyLoanBill = BusinessDataServiceHelper.newDynamicObject(ENTITY_PREPAY);
        Date bizDate = new Date();
        try {
            bizDate = CommonHelperUtils.getCurDateForm(new Date(), true);//申请日期
        } catch (ParseException e) {
//            throw new RuntimeException(e);
            returnMessage = e.getMessage();
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }
//        Date repaymentDate = CommonHelperUtils.getDateStringFormat("2099-12-31", "yyyy-MM-dd");

        dailyLoanBill.set("bizdate", bizDate);//申请日期
        dailyLoanBill.set("billstatus", "A");//单据状态
        dailyLoanBill.set("stdbilltype", billTypeInfo);//单据类型
        dailyLoanBill.set("nckd_srmbillno", srmBillNo);//srm单据号
        dailyLoanBill.set("nckd_srmurl", srmUrl);//srm单点url
        dailyLoanBill.set("contractsconn", contract);//合同号
        dailyLoanBill.set("description", cause);//事由
        dailyLoanBill.set("applier", applierInfo);//申请人
        dailyLoanBill.set("applierpositionstr", positionName);//职位
        dailyLoanBill.set("org", dept);//申请人部门
        dailyLoanBill.set("company", adminCompany);//申请人公司
        dailyLoanBill.set("costdept", dept);//费用承担部门
        dailyLoanBill.set("costcompany", costCompany);//费用承担公司
        dailyLoanBill.set("paycompany", costCompany);//支付公司
        dailyLoanBill.set("creator", creatorInfo);//制单人
        dailyLoanBill.set("tel", applierInfo.get("phone"));//电话号码
        dailyLoanBill.set("formid", ENTITY_PREPAY);//表单id
        dailyLoanBill.set("billpayertype", "bd_supplier");//往来类型
        dailyLoanBill.set("detailtype", detailtype);//关联业务
        dailyLoanBill.set("nckd_detailtype", detailtype);//是否关联合同
        dailyLoanBill.set("ispush", "false");//合同下推生成
        dailyLoanBill.set("nckd_srmstatus", "1");//srm状态，1：SRM已推送；2：已退回SRM；3：已反写SRM；4：反写SRM失败
//        dailyLoanBill.set("repaymentdate", repaymentDate);//预计冲销日期
        dailyLoanBill.set("nckd_duigong", "01");//是否对公业务
        dailyLoanBill.set("nckd_pageid", "nckd_er_srmperpaybill");//默认页面布局
        dailyLoanBill.set("nckd_isrelapj", "0");//是否关联项目

        setDefaultMultViewType(dailyLoanBill);//多选页面类型

        BigDecimal totalReimburseAmount = BigDecimal.ZERO;//报销金额合计

        //预付信息
        DynamicObjectCollection expenseEntry  = dailyLoanBill.getDynamicObjectCollection("expenseentryentity");
        DynamicObjectType type = expenseEntry.getDynamicObjectType();
        JSONArray dailyLoanBillEntry = inputData.getJSONArray("dailyLoanBillEntry");

        for(int i = 0; i < dailyLoanBillEntry.size(); i++){
            JSONObject jsonData = dailyLoanBillEntry.getJSONObject(i);

            String srmseq = jsonData.getString("srmseq");//预付单行号
            String currencyType = jsonData.getString("currencyType");//币别
            BigDecimal amountOri = CommonHelperUtils.getBigDecimal(jsonData.getString("amountOri"));//原币金额

            DynamicObject currency = CommonHelperUtils.queryBaseDynamicObject("bd_currency", "number", currencyType);
            if(currency == null){
                returnMessage = "币别(" + orgUnit + ")在星瀚系统中未匹配到数据！";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }

            BigDecimal exchangeRate = BigDecimal.ONE;
            if(currency.getLong("id") != 1L){
                exchangeRate = CommonHelperUtils.getExchangeRate(exchangeTableId, currency.getLong("id"), 1L, bizDate);
            }
            BigDecimal amountOriLocal = amountOri.multiply(exchangeRate).setScale(2, BigDecimal.ROUND_HALF_UP);//本位币金额

            DynamicObject entry = new DynamicObject(type);

            entry.set("seq", srmseq);
            entry.set("happendate", bizDate);
            entry.set("entrycostdept", dept);//费用承担部门
            entry.set("entrycostcompany", costCompany);//费用承担公司
            entry.set("entrycurrency", currency);//币别
            entry.set("exchangerate", exchangeRate);//预付汇率
            entry.set("expenseamount", amountOri);//申请金额
            entry.set("expeapproveamount", amountOri);//核定金额
            entry.set("orgiexpebalanceamount", amountOri);//未核销金额
            entry.set("currexpenseamount", amountOriLocal);//申请金额本位币
            entry.set("expeapprovecurramount", amountOriLocal);//核定金额本位币
            entry.set("expebalanceamount", amountOriLocal);//未核销金额本位币
            entry.set("expquotetype", "0");//换算方式

            if(contractInfo != null) {
                entry.set("entrycontractno", contract);
                entry.set("entrycontractname", contractInfo.getString("contractname"));
            }

            expenseEntry.add(entry);

            totalReimburseAmount = totalReimburseAmount.add(amountOri);
        }
        dailyLoanBill.set("expenseentryentity", expenseEntry);

        //收款明细
        //支付方式：默认为 银企直连
        qFilter = new QFilter("number", QCP.equals, "BANK");

        DynamicObject settleType = BusinessDataServiceHelper.loadSingle("bd_settlementtype", qFilter.toArray());
        DynamicObject supplier = null;

        DynamicObjectCollection accountEntry  = dailyLoanBill.getDynamicObjectCollection("accountentry");
        type = accountEntry.getDynamicObjectType();
        JSONArray dailyLoanBillAccountEntry = inputData.getJSONArray("dailyLoanBillAccountEntry");

        for(int i = 0; i < dailyLoanBillAccountEntry.size(); i++){
            JSONObject jsonData = dailyLoanBillAccountEntry.getJSONObject(i);

            String payerType = jsonData.getString("payerType");//收款人类型
            String payerName = jsonData.getString("payerName");//原币社会信用码
            String currencyType = jsonData.getString("currencyType");//币别
            BigDecimal amountOri = CommonHelperUtils.getBigDecimal(jsonData.getString("amountOri"));//原币金额

            if(StringUtils.isEmpty(payerType)){
                returnMessage = "检查以下收款信息参数 收款人类型 是否为空！";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }
            if(!"20".equals(payerType)){
                returnMessage = "收款人类型只支持供应商！";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }

            supplier = CommonHelperUtils.queryBaseDynamicObject("bd_supplier", "societycreditcode", payerName);
            if(supplier == null){
                returnMessage = "供应商(" + payerName + ")在星瀚系统中未匹配到数据！";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }
            //供应商银行账号信息
            DynamicObjectCollection entryBanks = supplier.getDynamicObjectCollection("entry_bank");

            DynamicObject currency = CommonHelperUtils.queryBaseDynamicObject("bd_currency", "number", currencyType);
            if(currency == null){
                returnMessage = "币别(" + orgUnit + ")在星瀚系统中未匹配到数据！";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }

            BigDecimal exchangeRate = BigDecimal.ONE;
            if(currency.getLong("id") != 1L){
                exchangeRate = CommonHelperUtils.getExchangeRate(exchangeTableId, currency.getLong("id"), 1L, bizDate);
            }
            BigDecimal amountOriLocal = amountOri.multiply(exchangeRate).setScale(4, BigDecimal.ROUND_HALF_UP);

            DynamicObject entry = new DynamicObject(type);

            entry.set("paymode", settleType);//支付方式
            entry.set("payertype", "bd_supplier");//收款人类型
            entry.set("supplier", supplier);//收款人
            entry.set("payername", supplier.getString("name"));//收款人名称

            if(entryBanks.size() > 0){
                for(DynamicObject entryBank : entryBanks){
                    if(entryBank.getBoolean("isdefault_bank")){
                        entry.set("payeraccount", entryBank.getString("bankaccount"));//银行账号
                        entry.set("payeraccountname", entryBank.getString("accountname"));//账户名称
                        entry.set("payerbank", entryBank.getDynamicObject("bank"));//开户银行

                        break;
                    }
                }
            }

            entry.set("accountcurrency", currency);//币别
            entry.set("accexchangerate", exchangeRate);//汇率
            entry.set("orireceiveamount", amountOri);//收款金额
            entry.set("receiveamount", amountOriLocal);//收款金额本位币
            entry.set("oriaccnotpayamount", amountOri);//未付金额
            entry.set("accnotpayamount", amountOriLocal);//未付金额本位币

            accountEntry.add(entry);

            dailyLoanBill.set("billpayerid", supplier);//表头往来单位
        }
        dailyLoanBill.set("accountentry", accountEntry);

        if(supplier == null){
            returnMessage = "无收款供应商信息！";
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }

        //合同信息
        if(contractInfo != null){
            DynamicObjectCollection contractEntry  = dailyLoanBill.getDynamicObjectCollection("contractentry");
            type = contractEntry.getDynamicObjectType();

            DynamicObject currency = contractInfo.getDynamicObject("contractcurrency");
            currency = CommonHelperUtils.queryBaseDynamicObject("bd_currency", "number", currency.getString("number"));

            if(currency == null){
                returnMessage = "币别(" + orgUnit + ")在星瀚系统中未匹配到数据！";
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }

            BigDecimal exchangeRate = BigDecimal.ONE;
            if(currency.getLong("id") != 1L){
                exchangeRate = CommonHelperUtils.getExchangeRate(exchangeTableId, currency.getLong("id"), 1L, bizDate);
            }

            BigDecimal contractAmount = contractInfo.getBigDecimal("contractamount");//合同总额（初始）
            BigDecimal oriapplyAmount = contractInfo.getBigDecimal("oriapplyamount");//合同总额（变更后）

            DynamicObjectCollection contractPartyEntry = contractInfo.getDynamicObjectCollection("contractpartyentry"); //
            if(contractPartyEntry.size() > 0){
                for(DynamicObject partyEntry : contractPartyEntry){
                    DynamicObject entry = new DynamicObject(type);

                    DynamicObject contractparty = partyEntry.getDynamicObject("contractparty");
                    if(contractparty.getLong("id") != supplier.getLong("id")){
                        continue;
                    }

                    entry.set("seq", 1);
                    entry.set("contractcode", contract);//合同号
                    entry.set("contractname", contractInfo.getString("contractname"));//合同名称
                    entry.set("signdate", contractInfo.getDate("signdate"));//签订日期
                    entry.set("contractdescription", contractInfo.getString("description"));//合同说明
                    entry.set("contractapplier", contractInfo.getDynamicObject("applier"));//经办人
                    entry.set("contractcostorg", contractInfo.getDynamicObject("costcompany"));//核算组织
                    entry.set("contractparta", contractInfo.getDynamicObject("parta"));//甲方old
                    entry.set("contractpartbtype", "bd_supplier");//乙方类型
                    entry.set("contractpartb", contractparty);//乙方
                    entry.set("contractpartatypenew", "bos_org");//甲方类型
                    entry.set("contractpartanew", costCompany);//甲方
                    entry.set("nckd_contractamt", contractAmount);//合同总额（初始）
                    entry.set("nckd_oriapplyamt", oriapplyAmount);//合同总额（变更后）

                    DynamicObjectCollection payplanEntrys = contractInfo.getDynamicObjectCollection("expenseentryentity");
                    if(payplanEntrys.size() > 0){
                        DynamicObject planEntry = payplanEntrys.get(0);

                        entry.set("contractexppaytypeid", planEntry.getDynamicObject("paymenttypeid"));//付款类型
                        entry.set("contractexphappendate", planEntry.getDate("happendate"));//预计付款日期
                        entry.set("contractexpproject", planEntry.getDynamicObject("std_project"));//项目
                        entry.set("contractexpenseitem", planEntry.getDynamicObject("expenseitem"));//费用项目
                        entry.set("contractexpcurrency", planEntry.getDynamicObject("entrycurrency"));//币种
                        entry.set("contractexpchangerate", planEntry.getBigDecimal("exchangerate"));//汇率
                        entry.set("contractexpquotetype", "0");//换算方式

                        entry.set("entryprepayedamount", planEntry.getBigDecimal("pushedamount"));//已预付金额
                        entry.set("entrycurrprepayedamount", planEntry.getBigDecimal("pushedcurramount"));//已预付金额本位币
                        entry.set("contractreimamount", planEntry.getBigDecimal("oriexppayedamount"));//已付金额
                        entry.set("contractcurrreimamhttount", planEntry.getBigDecimal("exppayedamount"));//已付金额本位币
                        entry.set("contractcanloanamount", planEntry.getBigDecimal("oriexppayedamount"));//可预付金额
                        entry.set("concurrcanloanamount", planEntry.getBigDecimal("canloancurramount"));//可预付金额本位币
                        entry.set("contractcanamount", planEntry.getBigDecimal("orgiexpebalanceamount"));//可报销金额
                        entry.set("contractcurrcanamount", planEntry.getBigDecimal("expebalanceamount"));//可报销金额本位币
//                        entry.set("contractwriteoff", planEntry.getBigDecimal("canloanamount"));//冲销金额
//                        entry.set("contractcurrwriteoff", planEntry.getBigDecimal("canloancurramount"));//冲销金额本位币
                        entry.set("contractnotpayamount", planEntry.getBigDecimal("oriexpnotpayamount"));//未付金额

                        entry.set("contractsid", contractInfo.getLong("id"));//源单id
                        entry.set("contractsrcentryid", planEntry.getLong("id"));//关联合同分录id


                        //记录预付单与合同台账的
                        String targetEntityNumber = "er_prepaybill";//预付单
                        String targetEntryKey = "contractentry";//对公报销-合同分录
                        String srcEntityNumber = "er_contractbill";//合同台账
                        String srcEntryKey = "expenseentryentity";//合同台账-付款计划
                        // 获取目标单单据体的实体表格定义：主实体 + 单据体 -> 对应一个唯一的实体表格定义
                        TableDefine targetTableDefine = EntityMetadataCache.loadTableDefine(targetEntityNumber, targetEntryKey);
                        // 获取源单单据体的表格定义：记录关联关系时，需要用到此对象中的tableId值，用一个长整数值唯一标识源单及单据体
                        TableDefine srcTableDefine = EntityMetadataCache.loadTableDefine(srcEntityNumber, srcEntryKey);

                        DynamicObjectCollection linkRows = entry.getDynamicObjectCollection("contractentry_lk");
                        if (linkRows.isEmpty()) {
                            String lkEntryKey ="contractentry_lk";
                            Long srcTableId = srcTableDefine.getTableId();

                            // 找到了匹配的行，创建一条_lk子实体上数据，记录源单内码
                            DynamicObject linkRow = new DynamicObject(linkRows.getDynamicObjectType());
                            linkRows.add(linkRow);
                            // 在lk行中，记录源单分录表格编码、源单内码、源单分录内码

                            linkRow.set("id", ID.genLongId());
                            linkRow.set("seq", 1);
                            linkRow.set(lkEntryKey + "_stableid", srcTableId);        // 源单分录表格编码：以此标识源单类型及单据体
                            linkRow.set(lkEntryKey + "_sbillid", contractInfo.getString("id"));        // 源单内码
                            linkRow.set(lkEntryKey + "_sid", planEntry.getString("id"));            // 源单分录行内码
                        }
                    }


                    contractEntry.add(entry);

                    break;
                }
            }

            dailyLoanBill.set("contractentry", contractEntry);
        }


        dailyLoanBill.set("loanamount", totalReimburseAmount);//报销金额
        dailyLoanBill.set("approveamount", totalReimburseAmount);//核定金额
        dailyLoanBill.set("notpayamount", totalReimburseAmount);//未付金额


        try {


            //新增保存供应商对象
            OperationResult resultSave = SaveServiceHelper.saveOperate(ENTITY_PREPAY, new DynamicObject[]{dailyLoanBill}, OperateOption.create());

            StringBuilder err = new StringBuilder();
            if (resultSave.getSuccessPkIds().size() <= 0) {
                for (int i = 0; i < resultSave.getAllErrorOrValidateInfo().size(); i++) {
                    String message = resultSave.getAllErrorOrValidateInfo().get(i).getMessage();
                    err.append("/").append(message);
                }

                returnMessage = "失败, " + (resultSave.getMessage() == null ? "异常错误" : resultSave.getMessage()) + err.toString();
                return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
            }

            DynamicObject billInfo = BusinessDataServiceHelper.loadSingle(resultSave.getSuccessPkIds().get(0), ENTITY_PREPAY);

            return buildReturnData("0", srmBillNo, "成功", resultSave.getSuccessPkIds().get(0).toString(), billInfo.getString("billno"), ENTITY_PREPAY);

        } catch(Exception e){
            returnMessage = "失败, exception：" + e.getMessage();
            return buildReturnData(code, srmBillNo, returnMessage, null, null, null);
        }
    }

    /**
     * 构造返回data参数
     * @param status
     * @param message
     * @param fid
     * @param number
     * @param entityName
     * @return
     */
    public JSONObject buildReturnData(String status, String srmBillNO, String message, String fid, String number, String entityName){
        JSONObject data = new JSONObject();

        data.put("status", status);
        data.put("SRMBillNo", srmBillNO);
        data.put("message", message);
        if("0".equals(status)) {
            String url = "/ierp?app=cexp&formId=bos_list&billFormId=" + entityName + "&pkId=" + fid;

            data.put("fid", fid);
            data.put("number", number);
            data.put("url", url);
        }

        return data;
    }

    /**
     * 自定义返回data对象
     * @param code  编码
     * @param message  错误信息
     * @return   CustomApiResult  返回
     */
    public CustomApiResult<JSONObject> returnResult(String code, String message, JSONArray responseData){
        JSONObject resultData = new JSONObject();

        resultData.put("msg", message);
        resultData.put("code", code);
        resultData.put("successFlag", ("0".equals(code) ? true : false));

        resultData.put("data", responseData);

        return CustomApiResult.success(resultData);
    }

    /**
     * 根据srm单据号检测星瀚系统是否已存在
     * @param entityName
     * @param srmBillNo
     * @return
     */
    private String queryBillInfoBySRMBillNo(String entityName, String srmBillNo){
        String billNO = "";

        QFilter qFilter = new QFilter("nckd_srmbillno", QCP.equals, srmBillNo);
        qFilter.and(new QFilter("billstatus", QCP.not_equals2, "H"));

        DynamicObject info = BusinessDataServiceHelper.loadSingle(entityName, qFilter.toArray());

        if(info != null){
            billNO = info.getString("billno");
        }
        return billNO;
    }


    /**
     * 默认多选页面类型
     * @return
     */
    private void setDefaultMultViewType(DynamicObject objectInfo){
        String[] typeStrings = new String[]{"1007", "1008"};

        QFilter qFilter = new QFilter("number", QCP.in, typeStrings);
        DynamicObject[] viewTypeCols = BusinessDataServiceHelper.load("nckd_payviewtype", "id, number, name", qFilter.toArray());
        if(viewTypeCols != null && viewTypeCols.length > 0){
            DynamicObjectCollection veiwTypeMulColl = objectInfo.getDynamicObjectCollection("nckd_payviewtypemul");

            for (DynamicObject viewType : viewTypeCols) {
                DynamicObject newViewTypeMul = new DynamicObject(veiwTypeMulColl.getDynamicObjectType());
                newViewTypeMul.set("fbasedataId", viewType);

                veiwTypeMulColl.add(newViewTypeMul);
            }

            objectInfo.set("nckd_payviewtypemul", veiwTypeMulColl);
        }
    }
}
