package nc.bs.sscivm.ivsale.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.bs.sscivm.ivsale.ivaconst.IVAWebConst;
import nc.bs.sscivm.ivsale.relation.bp.IVApplicationRelationVODeleteBP;
import nc.bs.sscivm.ivsale.relation.bp.IVApplicationRelationVOInsertBP;
import nc.bs.sscivm.ivsale.splitmerge.util.TransSpiltMergePksUtil;
import nc.bs.sscivm.logger.SSCIVMLogger;
import nc.dto.imag.boot.RequestInfo;
import nc.dto.imag.boot.ResponseInfo;
import nc.dto.imag.invoice.*;
import nc.dto.imag.invoice.tax.InvalidCommonRequest;
import nc.dto.imag.invoice.tax.InvalidCommonResponse;
import nc.dto.imag.invoice.tax.TaxCommonResponse;
import nc.dto.imag.invoice.tax.apply.InvoiceApplyCommonRequest;
import nc.dto.imag.invoice.tax.apply.InvoiceApplyCommonResponse;
import nc.dto.imag.invoice.tax.apply.InvoiceApplyStatusCallBackRequest;
import nc.dto.imag.invoice.tax.apply.InvoiceApplyStatusCommonRequest;
import nc.dto.imag.invoice.tax.invoicebill.InvoiceBillStatusCommonRequest;
import nc.dto.imag.invoice.tax.invoicebill.InvoiceBillStatusCommonResponse.InvoiceBillInfo;
import nc.dto.imag.invoice.tax.red.InvoiceRedApplyCommonRequest;
import nc.itf.sscivm.service.IVMInvoiceQueryService;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.generator.SequenceGenerator;
import nc.jdbc.framework.processor.BeanListProcessor;
import nc.vo.bd.defdoc.DefdocVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.VOStatus;
import nc.vo.pub.billtype.BilltypeVO;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.pub.lang.UFDouble;
import nc.vo.sscivm.invoice.*;
import nc.vo.sscivm.ivmpub.*;
import nc.vo.sscivm.ivsale.*;
import nc.vo.trade.pub.IBillStatus;
import nccloud.commons.lang.StringUtils;
import nccloud.itf.sscivm.ivsale.service.ApplicationLogService;
import nccloud.itf.sscivm.ivsale.splitmerge.service.InvoiceSplitMergeService;
import nccloud.putitf.riart.billtype.IBilltypeService;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

public class InvoiceTransferUtil {

    /**
     * 根据开票申请单转换开票请求
     *
     * @param vos
     * @return
     */
    public static RequestInfo<InvoiceApplyCommonRequest> getRequestInfo4BlueInvoiceApply(IVApplicationAggVO[] vos,
                                                                                         int isSpit) {

        RequestInfo<InvoiceApplyCommonRequest> requet = new RequestInfo<InvoiceApplyCommonRequest>();
        // 对于收票由于税务云入台账的接口不同需要再额外制定纳税人识别号、组织等信息，对于开票指定下面这些字段只是为了记录日志更清晰
        requet.setUserCode(InvocationInfoProxy.getInstance().getUserCode());
        requet.setUserid(InvocationInfoProxy.getInstance().getUserId());
        requet.setBilltype(IVAWebConst.IVA_DJLXBM);
        requet.setBillid(vos[0].getParentVO().getPk_ivapplication());
        InvoiceApplyCommonRequest applyRequest = new InvoiceApplyCommonRequest();
        if (IVAWebConst.IVA_KP_SSCIVA01_1.equals(String.valueOf(isSpit))) {
            applyRequest.setAutoAudit(UFBoolean.TRUE.booleanValue());// 是自动审核
        } else if (IVAWebConst.IVA_KP_SSCIVA01_2.equals(String.valueOf(isSpit))) {
            applyRequest.setAutoAudit(UFBoolean.FALSE.booleanValue());// 否自动审核
        }

        List<PInvoice> invoices = new ArrayList<PInvoice>();
        for (IVApplicationAggVO vo : vos) {

            applyRequest.addEmail(vo.getParentVO().getPk_ivapplication(), null, null, new String[]{vo.getParentVO().getEmail()});
            applyRequest.addSMS(vo.getParentVO().getPk_ivapplication(), null, null, new String[]{vo.getParentVO().getSms()});

            requet.setPk_org(vo.getParentVO().getPk_org());
            PInvoice invoice = getPInvoiceByApplyHead(vo.getParentVO());
            BigDecimal bodyMoneyTotal = new BigDecimal(0.00);

            List<PInvoiceDetail> details = new ArrayList<PInvoiceDetail>();
            for (IVApplicationBodyVO detailvo : vo.getBodyVOs()) {
                if (detailvo.getCaninvoice_xmjshj().compareTo(UFDouble.ZERO_DBL) == 0) {
                    continue;
                }
                PInvoiceDetail detail = getPInvoiceByApplyHead(vo.getParentVO(), detailvo);
                details.add(detail);
                bodyMoneyTotal = bodyMoneyTotal.add(detail.getXmjshj());
            }
            invoice.setJshj(bodyMoneyTotal);
            invoice.setItems(details.toArray(new PInvoiceDetail[0]));


            // 数电票特殊票种
            IVTspzsBodyVO[] tspzVOs = vo.getIvTspzsBodyVO();
            if (tspzVOs != null && tspzVOs.length > 0) {
                invoice = getPInvoiceByApplyTspz(tspzVOs, invoice);
            }
            invoices.add(invoice);
        }

        applyRequest.setInvoices(invoices.toArray(new PInvoice[0]));
        requet.setData(applyRequest);

        return requet;
    }

    /**
     * 开票信息查询请求参数转换
     *
     * @param logvo
     * @return
     * @throws BusinessException
     */
    public static RequestInfo<InvoiceApplyStatusCommonRequest> getRequestInfo4Refresh(IVApplogVO logvo,
                                                                                      IVApplicationAggVO applyVO) throws BusinessException {

        RequestInfo<InvoiceApplyStatusCommonRequest> request = new RequestInfo<InvoiceApplyStatusCommonRequest>();

        request.setUserCode(InvocationInfoProxy.getInstance().getUserCode());
        request.setUserid(InvocationInfoProxy.getInstance().getUserId());
        request.setBilltype(IVAWebConst.IVA_DJLXBM);
        request.setPk_org(applyVO.getParentVO().getPk_org());
        request.setBillid(applyVO.getParentVO().getPk_ivapplication());
        InvoiceApplyStatusCommonRequest statusR = new InvoiceApplyStatusCommonRequest();
        if (logvo.getKpzt() == KpztEnum.ZFING.intValue() || logvo.getKpzt() == KpztEnum.ZFERR.intValue()) {
            // 查询原蓝字发票(红冲)的日志信息
            String condition = " ( " + IVMInvoiceHeadVO.FPDM + " = '" + logvo.getFpdm() + "' and " + IVMInvoiceHeadVO.FPHM
                    + " = '" + logvo.getFphm() + "' ) " + " and (" + IVApplogVO.KPZT + " =" + KpztEnum.ZFING
                    + " or " + IVApplogVO.KPZT + " =" + KpztEnum.ZFERR
                    + " )" + " and " + IVApplogVO.ISSYNC + " ='Y' ";
            if (logvo.getFpdm() == null) {
                condition = " ( " + IVMInvoiceHeadVO.FPHM
                        + " = '" + logvo.getFphm() + "' ) " + " and (" + IVApplogVO.KPZT + " =" + KpztEnum.ZFING
                        + " or " + IVApplogVO.KPZT + " =" + KpztEnum.ZFERR
                        + " )" + " and " + IVApplogVO.ISSYNC + " ='Y' ";
            }
            List<IVApplogVO> buleIVApplogVOS =
                    NCLocator
                            .getInstance()
                            .lookup(ApplicationLogService.class)
                            .queryApplicationLogByCondion(condition);
            if (buleIVApplogVOS != null && buleIVApplogVOS.size() > 0) {
                statusR.setApplyNumber(buleIVApplogVOS.get(0).getFpqqlsh());// 需要历史的发票流水号去刷新数据
            }
        } else {
            statusR.setApplyNumber(logvo.getFpqqlsh());
        }
        request.setData(statusR);

        return request;
    }

    /**
     * 发票单信息查询请求参数转换
     *
     * @param logvo
     * @return
     */
    public static RequestInfo<InvoiceBillStatusCommonRequest> getRequestInfo4Refresh4Bill(IVApplogVO logvo,
                                                                                          IVApplicationAggVO applyVO) {

        RequestInfo<InvoiceBillStatusCommonRequest> request = new RequestInfo<InvoiceBillStatusCommonRequest>();

        request.setUserCode(InvocationInfoProxy.getInstance().getUserCode());
        request.setUserid(InvocationInfoProxy.getInstance().getUserId());
        request.setBilltype(IVAWebConst.IVA_DJLXBM);
        request.setPk_org(applyVO.getParentVO().getPk_org());

        InvoiceBillStatusCommonRequest statusR = new InvoiceBillStatusCommonRequest();
        statusR.setLyid(logvo.getLyid());
        if (logvo.getKpzt() == KpztEnum.ZFING.intValue()) {
            // 查询原蓝字发票(红冲)的日志信息
            List<IVApplogVO> buleIVApplogVOS;
            try {
                String condition = " ( " + IVMInvoiceHeadVO.FPDM + " = '" + logvo.getFpdm() + "' and " + IVMInvoiceHeadVO.FPHM
                        + " = '" + logvo.getFphm() + "' ) " + " and " + IVApplogVO.KPZT + " =" + KpztEnum.ZFING
                        + " " + " and " + IVApplogVO.ISSYNC + " ='Y' ";
                if (logvo.getFpdm() == null) {
                    condition = " ( " + IVMInvoiceHeadVO.FPHM
                            + " = '" + logvo.getFphm() + "' ) " + " and " + IVApplogVO.KPZT + " =" + KpztEnum.ZFING
                            + " " + " and " + IVApplogVO.ISSYNC + " ='Y' ";
                }
                buleIVApplogVOS = NCLocator
                        .getInstance()
                        .lookup(ApplicationLogService.class)
                        .queryApplicationLogByCondion(condition);
                if (buleIVApplogVOS != null && buleIVApplogVOS.size() > 0) {
                    statusR.setLyid(buleIVApplogVOS.get(0).getLyid());
                }
            } catch (BusinessException e) {
                SSCIVMLogger.error(e.getMessage(), e);
            }
        }
        request.setData(statusR);
        return request;
    }

    /**
     * 根据开票申请转换成红冲请求
     *
     * @param vos
     * @return
     */
    public static RequestInfo<InvoiceRedApplyCommonRequest> getRequestInfo4InvoiceRed(IVApplicationAggVO[] vos) {

        RequestInfo<InvoiceRedApplyCommonRequest> requet = new RequestInfo<InvoiceRedApplyCommonRequest>();
        // 对于收票由于税务云入台账的接口不同需要再额外制定纳税人识别号、组织等信息，对于开票指定下面这些字段只是为了记录日志更清晰
        requet.setUserCode(InvocationInfoProxy.getInstance().getUserCode());
        requet.setUserid(InvocationInfoProxy.getInstance().getUserId());
        requet.setBilltype(IVAWebConst.IVA_DJLXBM);
        requet.setBillid(vos[0].getParentVO().getPk_ivapplication());
        InvoiceRedApplyCommonRequest redRequest = new InvoiceRedApplyCommonRequest();
        int isSpit = Integer.parseInt(IVAWebConst.IVA_KP_SSCIVA01_1);
        if (vos != null && vos.length > 0) {
            isSpit = vos[0].getParentVO().getKpfs();
            if (IVAWebConst.IVA_KP_SSCIVA01_1.equals(String.valueOf(isSpit))) {
                redRequest.setAutoAudit(UFBoolean.TRUE.booleanValue());// 是自动审核
            } else if (IVAWebConst.IVA_KP_SSCIVA01_2.equals(String.valueOf(isSpit))) {
                redRequest.setAutoAudit(UFBoolean.FALSE.booleanValue());// 否自动审核
            }
        }

        List<PInvoice> invoices = new ArrayList<PInvoice>();
        for (IVApplicationAggVO vo : vos) {
            requet.setPk_org(vo.getParentVO().getPk_org());
            redRequest.addEmail(vo.getParentVO().getPk_ivapplication(), new String[]{vo.getParentVO().getEmail()});
            redRequest.addSMS(vo.getParentVO().getPk_ivapplication(), new String[]{vo.getParentVO().getSms()});

            PInvoice invoice = getPInvoiceByApplyHead4Red(vo.getParentVO());

            List<PInvoiceDetail> details = new ArrayList<PInvoiceDetail>();
            for (IVApplicationBodyVO detailvo : vo.getBodyVOs()) {
                if (detailvo.getCaninvoice_xmjshj().compareTo(UFDouble.ZERO_DBL) == 0) {
                    continue;
                }
                PInvoiceDetail detail = getPInvoiceByApplybody4Red(detailvo);
                if (vo.getParentVO().getSgbz().booleanValue()) {
                    detailvo.setLslbs(IVAplocationLSLBS.LSLBS_MS.toStringValue());
                }
                details.add(detail);
            }
            invoice.setItems(details.toArray(new PInvoiceDetail[0]));
            invoices.add(invoice);

        }

        redRequest.setInvoices(invoices.toArray(new PInvoice[0]));
        requet.setData(redRequest);

        return requet;
    }

    /**
     * 根据发票转换作废请求参数
     *
     * @param vos
     * @return
     */
    public static RequestInfo<InvalidCommonRequest> getRequestInfo4InvoiceInvalid(IVApplicationAggVO apply) {

        RequestInfo<InvalidCommonRequest> requet = new RequestInfo<InvalidCommonRequest>();
        requet.setUserCode(InvocationInfoProxy.getInstance().getUserCode());
        requet.setUserid(InvocationInfoProxy.getInstance().getUserId());
        requet.setBilltype(IVAWebConst.IVA_DJLXBM);
        requet.setPk_org(apply.getParentVO().getPk_org());
        requet.setBillid(apply.getHeadVO().getPk_ivapplication());

        IVApplicationHeadVO invoice = apply.getParentVO();

        InvalidCommonRequest cr = new InvalidCommonRequest();
        cr.setFpHm(invoice.getFphm());
        cr.setFpDm(invoice.getFpdm());
        cr.setZfr(invoice.getKpr());// 获取开票人原始逻辑，为空则为当前操作人
        requet.setData(cr);

        return requet;
    }

    /**
     * 根据作废的请求解决作废对应的开票日志
     *
     * @param response
     * @param invoice
     * @param lyid
     * @return
     * @throws BusinessException
     */
    public static IVApplogVO getResult4InvoiceInvalid(ResponseInfo<InvalidCommonResponse> response,
                                                      IVApplicationAggVO apply) throws BusinessException {

        if (!IVMInvoiceConstant.SUCCESS_CODE.equals(response.getCode())) {
            throw new BusinessException(response.getMessage());
        }

        IVApplogVO logvo = new IVApplogVO();

        String condition = " " + IVMInvoiceHeadVO.FPDM + " = '" + apply.getParentVO().getFpdm() + "' and "
                + IVMInvoiceHeadVO.FPHM + " = '" + apply.getParentVO().getFphm() + "' and dr=0 and "
                + IVMInvoiceHeadVO.BILLTYPECODE + "='" + IVAWebConst.IVA_XXFP_JYLXBM + "' ";
        if (apply.getParentVO().getFpdm() == null) {
            condition = " " + IVMInvoiceHeadVO.FPHM + " = '" + apply.getParentVO().getFphm() + "' and dr=0 and "
                    + IVMInvoiceHeadVO.BILLTYPECODE + "='" + IVAWebConst.IVA_XXFP_JYLXBM + "' ";
        }
        IVMInvoiceAggVO[] ivMInvoiceAggVOS =
                NCLocator
                        .getInstance()
                        .lookup(IVMInvoiceQueryService.class)
                        .queryAggVOsByCondition(condition);

        logvo.setCode(IVMInvoiceConstant.SUCCESS_CODE);
        logvo.setKpzt(KpztEnum.ZFING);
        logvo.setIsremake(UFBoolean.TRUE);// 当前作废的单据不允许重开,原作废单据允许重开
        logvo.setLyid(apply.getParentVO().getPk_ivapplication());
        logvo.setFpqqlsh(apply.getParentVO().getPk_ivapplication());
        logvo.setFpdm(apply.getParentVO().getFpdm());
        logvo.setFphm(apply.getParentVO().getFphm());
        logvo.setKpr(apply.getParentVO().getKpr());
        logvo.setKprq(apply.getParentVO().getPreparedate().toLocalString());
        if (ivMInvoiceAggVOS != null && ivMInvoiceAggVOS.length > 0) {
            IVMInvoiceAggVO invoice = ivMInvoiceAggVOS[0];
            logvo.setInvoice_type(String.valueOf(invoice.getParentVO().getInvoice_type()));
            logvo.setGmfmc(invoice.getParentVO().getGmfmc());
            logvo.setXsfmc(invoice.getParentVO().getXsfmc());
            logvo.setJshj(invoice.getParentVO().getJshj());
            logvo.setHjje(invoice.getParentVO().getHjje());
            logvo.setHjse(invoice.getParentVO().getHjse());

            List<Map<String, String>> zfingStrMapList = new ArrayList<Map<String, String>>();// 原蓝字发票的作废查询条件
            Map<String, String> zfingStrMap = new HashMap<String, String>();
            zfingStrMap.put(IVMInvoiceHeadVO.FPDM, apply.getParentVO().getFpdm());
            zfingStrMap.put(IVMInvoiceHeadVO.FPHM, apply.getParentVO().getFphm());
            zfingStrMapList.add(zfingStrMap);
            InvoiceTransferUtil.modifyZfingStrMap(zfingStrMapList);
        }

        return logvo;
    }

    public static void modifyZfingStrMap(List<Map<String, String>> zfingStrMapList) throws BusinessException {
        // StringBuilder fpxxs = new StringBuilder();
        // for (int i = 0; i < zfingStrMapList.size(); i++) {
        // Map<String, String> vomap = zfingStrMapList.get(i);
        // fpxxs.append(" ( " + IVMInvoiceHeadVO.FPDM + " = '"
        // + vomap.get(IVMInvoiceHeadVO.FPDM) + "' and "
        // + IVMInvoiceHeadVO.FPHM + " = '"
        // + vomap.get(IVMInvoiceHeadVO.FPHM) + "' ) ");
        // if (i != zfingStrMapList.size() - 1) {
        // fpxxs.append(" or ");
        // }
        // }
        // IVMInvoiceAggVO[] ivmVos = NCLocator.getInstance()
        // .lookup(IVMInvoiceQueryService.class)
        // .queryAggVOsByCondition(fpxxs.toString());
        // for (IVMInvoiceAggVO ivmVo : ivmVos) {
        // IVMInvoiceHeadVO ivMInvoiceHeadVO = ivmVo.getParentVO();
        // ivMInvoiceHeadVO.setFpzt(InvoiceStatus.InvoiceStatus_2
        // .toIntValue());// 作废
        // ivMInvoiceHeadVO.setStatus(VOStatus.UPDATED);
        // }
        // IVMInvoiceAggVO[] oldivmVos = NCLocator.getInstance()
        // .lookup(IVMInvoiceQueryService.class)
        // .queryAggVOsByCondition(fpxxs.toString());
        // // 2、更新原被红冲蓝票为红冲，并补全红字发票信息
        // NCLocator.getInstance().lookup(IVMInvoiceService.class).updateBatch(ivmVos, oldivmVos);
        //
        //
        // // 3、查询原蓝字发票(红冲)的日志信息
        // List<IVApplogVO> buleIVApplogVOS =
        // NCLocator.getInstance().lookup(ApplicationLogService.class).queryApplicationLogByCondion(fpxxs.toString()+" and "+IVApplogVO.KPZT
        // +" ="+KpztEnum.ZFING+" ");
        //
        // // 4、更新原蓝字发票为红冲成功
        // if(buleIVApplogVOS!=null && buleIVApplogVOS.size()>0){
        // for(IVApplogVO buleIVApplogVO:buleIVApplogVOS){
        // buleIVApplogVO.setKpzt(KpztEnum.ZF);
        // if(buleIVApplogVO.getJshj().compareTo(new UFDouble(0.0))<0){
        // buleIVApplogVO.setIsremake(UFBoolean.TRUE);//如果为红字发票，则不允许重开
        // }
        // buleIVApplogVO.setStatus(VOStatus.UPDATED);
        // }
        // new BaseDAO().updateVOList(buleIVApplogVOS);
        //
        // // 5、确定当前作废动作对应的原发票为红字发票，则需要更新原红票对应的原蓝票的状态为开票成功
        // if(ivmVos!=null && ivmVos.length>0){
        // StringBuilder hzfpxxs = new StringBuilder();
        // hzfpxxs.append(" ( ");
        // for(IVMInvoiceAggVO hcivmVo:ivmVos){
        // //根据红冲信息联查红字申请单
        // if(hcivmVo.getParentVO().getYlzfpdm()!=null && hcivmVo.getParentVO().getYlzfphm()!=null){
        // hzfpxxs.append(" ( " + IVMInvoiceHeadVO.FPDM + " = '"
        // + hcivmVo.getParentVO().getYlzfpdm()+ "' and "
        // + IVMInvoiceHeadVO.FPHM + " = '"
        // + hcivmVo.getParentVO().getYlzfphm()+ "' )  or ");
        // }
        // }
        //
        // hzfpxxs.append(" 1=2 ) ");
        //
        // // 6、根据红冲的日志信息反查原蓝票信息
        // List<IVApplogVO> hcIVAplicationVOS =
        // NCLocator.getInstance().lookup(ApplicationLogService.class).queryApplicationLogByCondion(hzfpxxs.toString()+" and "+IVApplogVO.KPZT
        // +" ="+KpztEnum.HC+" ");
        // if(hcIVAplicationVOS!=null && hcIVAplicationVOS.size()>0){
        // for(IVApplogVO hcIVAplicationVO:hcIVAplicationVOS){
        // hcIVAplicationVO.setKpzt(KpztEnum.KP);//如果作废的是红字发票，则需要更新红字发票对应的蓝字发票状态为开票成功
        // hcIVAplicationVO.setStatus(VOStatus.UPDATED);
        // }
        // new BaseDAO().updateVOList(hcIVAplicationVOS);
        //
        // IVMInvoiceAggVO[] newivmVos =
        // NCLocator.getInstance().lookup(IVMInvoiceQueryService.class).queryAggVOsByCondition(hzfpxxs.toString());
        // if(newivmVos!=null && newivmVos.length>0){
        // for(IVMInvoiceAggVO newivmVo:newivmVos){
        // IVMInvoiceHeadVO ivMInvoiceHeadVO = newivmVo.getParentVO();
        // ivMInvoiceHeadVO.setFpzt(InvoiceStatus.InvoiceStatus_0
        // .toIntValue());// 改原蓝字发票为正常
        // ivMInvoiceHeadVO.setStatus(VOStatus.UPDATED);
        //
        // }
        // IVMInvoiceAggVO[] oldfirstivmVos =
        // NCLocator.getInstance().lookup(IVMInvoiceQueryService.class).queryAggVOsByCondition(hzfpxxs.toString());
        // // 7、更新原被红冲蓝票为红冲，并补全红字发票信息
        // NCLocator.getInstance().lookup(IVMInvoiceService.class).updateBatch(newivmVos, oldfirstivmVos);
        // }
        // }
        // }
        // }
    }

    /**
     * 将开票请求结果（传税务云发票）转换成开票情况
     *
     * @param response
     * @return
     * @throws BusinessException
     */
    public static List<IVApplogVO> getResult4BlueInvoiceApply(IVApplicationAggVO[] ivApplicationVOs, ResponseInfo<InvoiceApplyCommonResponse> response)
            throws BusinessException {

        if (!IVMInvoiceConstant.SUCCESS_CODE.equals(response.getCode())) {
            throw new BusinessException(response.getMessage());
        }
        // 是否NCC拆分合并
        boolean splitMerge = true;
        if (ivApplicationVOs[0] != null && ivApplicationVOs[0].getBodyVOs()[0].getPk_ivappdetail().length() == 20) {
            splitMerge = false;
        }

        List<IVApplogVO> logs = new ArrayList<IVApplogVO>();
        // 1、 平台处理后只有返回成功的数据，如果税务云返回失败会直接抛出异常
        PInvoice[] invoices = response.getData().getInvoices();

        if (invoices != null) {
            for (PInvoice invoice : invoices) {
                IVApplogVO logvo = getIVApplogVOFromPInvoice(invoice);
                logs.add(logvo);
            }
        }

        // 2、记录发票与开票申请行关联关系，并再次更新
        if (ivApplicationVOs.length > 0) {
            Set<IVApplicationRelationVO> addApplicationRelationVO = new HashSet<IVApplicationRelationVO>();// 汇总需要更新的内容
            Set<IVApplicationRelationVO> deleteApplicationRelationVO = new HashSet<IVApplicationRelationVO>();// 汇总需要删除的内容
            // 判断返回的每条开票申请对应的数据，如果出现下游税务云返回票据多于上游记录关系，或者上游无关系。(说明下游税务云存在自动拆分,或纯手工开票场景。也使用NCC的拆分合并关联关系表管理)
            for (IVApplicationAggVO aggVOOld : ivApplicationVOs) {
                IVApplicationAggVO aggVO = aggVOOld.clone();// 避免污染原始VO
                String pk_ivapplication = aggVO.getParentVO().getPk_ivapplication();
                boolean zffp = aggVO.getParentVO().getZffp() == null ? false : aggVO.getParentVO().getZffp().booleanValue();// 是否作废开票申请单
                boolean hzfp = aggVO.getParentVO().getHzfp() == null ? false : aggVO.getParentVO().getHzfp().booleanValue();// 是否红字开票申请单
                IVApplicationBodyVO[] iVApplicationBodyVOS = aggVO.getBodyVOs();
                Set<IVApplogVO> childIVApplogVOS = new HashSet<IVApplogVO>();
                // 2.1当前开票申请与开票情况的关系合集
                if (logs.size() > 0) {
                    for (IVApplogVO log : logs) {
                        if (Arrays.asList(TransSpiltMergePksUtil.transIvapplicationToLyid(new String[]{pk_ivapplication})).contains(log.getLyid())) {
                            childIVApplogVOS.add(log);
                        }
                    }
                }
                // 2.2蓝票或者重开场景重新设置值
                // 非作废申请，红冲申请
                if (!zffp && !hzfp && childIVApplogVOS.size() > 0) {
                    // 匹配到生成的开票情况有内容
                    for (IVApplogVO childIVApplogVO : childIVApplogVOS) {
                        PInvoiceDetail[] invoicedetails = childIVApplogVO.getItems();
                        if (invoicedetails.length > 0) {
                            for (PInvoiceDetail invoicedetail : invoicedetails) {
                                for (IVApplicationBodyVO iVApplicationBodyVO : iVApplicationBodyVOS) {
                                    if (iVApplicationBodyVO.getHh().equals(invoicedetail.getHh())) {
                                        UFDouble invoice_xmsl = new UFDouble(invoicedetail.getXmsl() == null ? new BigDecimal(0) : invoicedetail.getXmsl());
                                        UFDouble invoice_xmje = new UFDouble(invoicedetail.getXmje() == null ? new BigDecimal(0) : invoicedetail.getXmje());
                                        UFDouble invoice_xmjshj = new UFDouble(invoicedetail.getXmjshj() == null ? new BigDecimal(0) : invoicedetail.getXmjshj());
                                        boolean zkh = invoice_xmjshj.compareTo(UFDouble.ZERO_DBL) < 0;
                                        if (splitMerge) {// 判断NCC拆分合并场景
                                            JSONArray arr = JSONArray.parseArray(iVApplicationBodyVO.getPk_ivappdetail());
                                            // 对arr进行排序
                                            List<JSONObject> arrList = JSONArray.parseArray(arr.toJSONString(), JSONObject.class);
                                            Collections.sort(arrList, new Comparator<JSONObject>() {
                                                @Override
                                                public int compare(JSONObject o1, JSONObject o2) {
                                                    UFDouble jshj1 = new UFDouble(o1.getBigDecimal(IVApplicationBodyVO.XMJSHJ));
                                                    UFDouble jshj2 = new UFDouble(o2.getBigDecimal(IVApplicationBodyVO.XMJSHJ));
                                                    return jshj1.compareTo(jshj2);
                                                }
                                            });
                                            arr = JSONArray.parseArray(arrList.toString());

                                            JSONArray update_arr = new JSONArray();
                                            // 获取剩余的拆合列表，并还原到PK_IVAPPDETAIL中
                                            for (int i = 0; i < arr.size(); i++) {
                                                String pk_ivapplication_split = arr.getJSONObject(i).getString(IVApplicationBodyVO.PK_IVAPPLICATION);
                                                String pk_ivappdetail = arr.getJSONObject(i).getString(IVApplicationBodyVO.PK_IVAPPDETAIL);
                                                UFDouble split_xmsl = new UFDouble(arr.getJSONObject(i).getBigDecimal(IVApplicationBodyVO.XMSL));
                                                UFDouble split_xmje = new UFDouble(arr.getJSONObject(i).getBigDecimal(IVApplicationBodyVO.XMJE));
                                                UFDouble split_xmjshj = new UFDouble(arr.getJSONObject(i).getBigDecimal(IVApplicationBodyVO.XMJSHJ));
                                                // 按金额回写
                                                if (invoice_xmjshj.compareTo(UFDouble.ZERO_DBL) == 0) {
                                                    // 当前发票金额已用完
                                                    break;
                                                } else if ((split_xmjshj.compareTo(invoice_xmjshj) <= 0 && !zkh) || (split_xmjshj.compareTo(invoice_xmjshj) >= 0 && zkh)) {
                                                    // 当前拆分金额已用完
                                                    invoice_xmjshj = invoice_xmjshj.sub(split_xmjshj);
                                                    invoice_xmje = invoice_xmje.sub(split_xmje);
                                                    invoice_xmsl = invoice_xmsl.sub(split_xmsl);
                                                    if (split_xmjshj.compareTo(UFDouble.ZERO_DBL) != 0) {
                                                        addApplicationRelationVO.add(getApplicationRelationVO(aggVO, childIVApplogVO, pk_ivapplication_split, pk_ivappdetail, iVApplicationBodyVO.getHh(), split_xmsl, split_xmje, split_xmjshj, splitMerge));// 需要重新赋值的部分
                                                    }
                                                    arr.getJSONObject(i).put(IVApplicationBodyVO.XMSL, UFDouble.ZERO_DBL.toBigDecimal());
                                                    arr.getJSONObject(i).put(IVApplicationBodyVO.XMJE, UFDouble.ZERO_DBL.toBigDecimal());
                                                    arr.getJSONObject(i).put(IVApplicationBodyVO.XMJSHJ, UFDouble.ZERO_DBL.toBigDecimal());
                                                    arr.getJSONObject(i).put(IVApplicationBodyVO.SE, UFDouble.ZERO_DBL.toBigDecimal());
                                                    split_xmjshj = UFDouble.ZERO_DBL;
                                                    split_xmje = UFDouble.ZERO_DBL;
                                                    split_xmsl = UFDouble.ZERO_DBL;
                                                    update_arr.add(arr.getJSONObject(i));
                                                } else {
                                                    // 当前拆分金额部分用完
                                                    split_xmjshj = split_xmjshj.sub(invoice_xmjshj);
                                                    split_xmje = split_xmje.sub(invoice_xmje);
                                                    split_xmsl = split_xmsl.sub(invoice_xmsl);
                                                    arr.getJSONObject(i).put(IVApplicationBodyVO.XMSL, split_xmsl.toBigDecimal());
                                                    arr.getJSONObject(i).put(IVApplicationBodyVO.XMJE, split_xmje.toBigDecimal());
                                                    arr.getJSONObject(i).put(IVApplicationBodyVO.XMJSHJ, split_xmjshj.toBigDecimal());
                                                    arr.getJSONObject(i).put(IVApplicationBodyVO.SE, tranZeroAmount(split_xmjshj.sub(split_xmje)).toBigDecimal());
                                                    update_arr.add(arr.getJSONObject(i));
                                                    if (invoice_xmjshj.compareTo(UFDouble.ZERO_DBL) != 0) {
                                                        addApplicationRelationVO.add(getApplicationRelationVO(aggVO, childIVApplogVO, pk_ivapplication_split, pk_ivappdetail, iVApplicationBodyVO.getHh(), invoice_xmsl, invoice_xmje, invoice_xmjshj, splitMerge));// 需要重新赋值的部分
                                                    }
                                                    invoice_xmjshj = UFDouble.ZERO_DBL;
                                                    invoice_xmje = UFDouble.ZERO_DBL;
                                                    invoice_xmsl = UFDouble.ZERO_DBL;
                                                }
                                            }
                                            iVApplicationBodyVO.setPk_ivappdetail(arr.toJSONString());
                                        } else {// 非NCC拆分合并场景
                                            if (invoice_xmjshj.compareTo(UFDouble.ZERO_DBL) != 0) {
                                                addApplicationRelationVO.add(getApplicationRelationVO(aggVO, childIVApplogVO, iVApplicationBodyVO.getPk_ivapplication(), iVApplicationBodyVO.getPk_ivappdetail(), iVApplicationBodyVO.getHh(), invoice_xmsl, invoice_xmje, invoice_xmjshj, splitMerge));// 需要重新赋值的部分
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            IVApplicationRelationVO[] oldApplicationRelationVO = NCLocator.getInstance().lookup(InvoiceSplitMergeService.class).saveSpiltAndMergeRelation(ivApplicationVOs, splitMerge, addApplicationRelationVO);
            // 2.3当前开票申请的票据与申请关联关系合集
            Set<IVApplicationRelationVO> childApplicationRelationVOS = new HashSet<IVApplicationRelationVO>();
            if (oldApplicationRelationVO != null && oldApplicationRelationVO.length > 0) {
                for (IVApplicationRelationVO applicationRelationVO : oldApplicationRelationVO) {
                    for (IVApplogVO childIVApplogVO : logs) {
                        if (applicationRelationVO.getFpqqlsh().equals(childIVApplogVO.getLyid())) {
                            deleteApplicationRelationVO.add(applicationRelationVO);// 需要清空删除的关联关系部分
                            break;
                        }
                    }
                }
            }
            // 删除关联关系
            if (deleteApplicationRelationVO.size() > 0) {
                new IVApplicationRelationVODeleteBP().delete(deleteApplicationRelationVO.toArray(new IVApplicationRelationVO[deleteApplicationRelationVO.size()]));
            }
            // 更新关联关系
            if (addApplicationRelationVO.size() > 0) {
                new IVApplicationRelationVOInsertBP().insert(addApplicationRelationVO.toArray(new IVApplicationRelationVO[addApplicationRelationVO.size()]));
            }
        }
        return logs;
    }

    public static IVApplicationRelationVO getApplicationRelationVO(IVApplicationAggVO aggVO, IVApplogVO childIVApplogVO, String pk_ivapplication, String pk_ivappdetail, String hh, UFDouble invoice_xmsl, UFDouble invoice_xmje, UFDouble invoice_xmjshj, boolean splitMerge) {
        String kpfs = String.valueOf(aggVO.getParentVO().getKpfs());// 开票方式 1/直联开票、2/手工开票、3/发票拆分合并开票
        IVApplicationRelationVO vo = new IVApplicationRelationVO();
        vo.setPk_ivapplication(pk_ivapplication);
        vo.setPk_ivappdetail(pk_ivappdetail);
        vo.setIsplitmerge(splitMerge ? UFBoolean.TRUE : UFBoolean.FALSE);
        vo.setXmsl(invoice_xmsl);
        vo.setXmje(invoice_xmje);
        vo.setXmjshj(invoice_xmjshj);
        vo.setRowno(hh);
        vo.setFpqqlsh(childIVApplogVO.getLyid());// 税务云拆分的关联关系存储的是来源ID
        vo.setPk_ivapplog(childIVApplogVO.getPk_ivapplog());// 替换关联关系的生成，下游生成的部分会替换并按行赋值。便于找到回退的数据
        if (IVAWebConst.IVA_KP_SSCIVA01_1.equals(kpfs) || splitMerge) {
            vo.setKpfs(IVAplocationKPFS.ZLKP.toIntValue());// 直连开票
        } else {
            vo.setKpfs(IVAplocationKPFS.SGKP.toIntValue());// 手工开票
        }
        return vo;
    }

    /**
     * 将红冲结果转换成开票日志
     *
     * @param response
     * @return
     * @throws BusinessException
     */
    public static List<IVApplogVO> getResult4InvoiceRed(ResponseInfo<TaxCommonResponse> response,
                                                        IVApplicationAggVO[] ivApplicationVOs) throws BusinessException {

        if (!IVMInvoiceConstant.SUCCESS_CODE.equals(response.getCode())) {
            throw new BusinessException(response.getMessage());
        }

        List<IVApplogVO> logs = new ArrayList<IVApplogVO>();
        for (IVApplicationAggVO applyvo : ivApplicationVOs) {

            // IVMInvoiceAggVO invoice = applyvo.getInvoiceAggVO();
            IVApplogVO logvo = new IVApplogVO();

            logvo.setCode(IVMInvoiceConstant.SUCCESS_CODE);
            logvo.setKpzt(KpztEnum.KPING);
            logvo.setFpqqlsh(applyvo.getParentVO().getPk_ivapplication());
            logvo.setLyid(applyvo.getParentVO().getPk_ivapplication());
            logvo.setKpr(applyvo.getParentVO().getKpr());
            logvo.setJshj(applyvo.getParentVO().getJshj());
            logvo.setHjje(applyvo.getParentVO().getHjje());
            logvo.setHjse(applyvo.getParentVO().getHjse());
            logvo.setInvoice_type(String.valueOf(applyvo.getParentVO().getFplx()));
            logvo.setGmfmc(applyvo.getParentVO().getGmf_mc());
            logvo.setXsfmc(applyvo.getParentVO().getXsf_mc());
            if (applyvo.getHeadVO().getSgbz() != null && applyvo.getHeadVO().getSgbz().booleanValue()) {
                logvo.setGmfmc(applyvo.getParentVO().getXsf_mc());
                logvo.setXsfmc(applyvo.getParentVO().getGmf_mc());
            }

            // logvo.setGmfmc(invoice.getParentVO().getGmfmc());
            // logvo.setFpdm(invoice.getParentVO().getFpdm());
            // logvo.setFphm(invoice.getParentVO().getFphm());
            // logvo.setKprq(invoice.getParentVO().getKprq() == null ? "" :
            // invoice.getParentVO().getKprq().toStdString());
            // logvo.setInvoice_type(String.valueOf(invoice.getParentVO().getInvoice_type()));

            logs.add(logvo);
        }

        return logs;
    }

    /**
     * 根据开票结果转换发票，只有开票中和红冲中的日志需要转换
     *
     * @param pinvoice
     * @return
     * @throws BusinessException
     */
    public static IVMInvoiceAggVO getInvoiceAggVOFromPInvoice(IVApplicationHeadVO ivApplicationHeadVO,
                                                              PInvoice pinvoice, IVApplogVO logvo) throws BusinessException {
        IVMInvoiceAggVO aggvo = new IVMInvoiceAggVO();
        IVMInvoiceHeadVO head = new IVMInvoiceHeadVO();

        SequenceGenerator generator = new SequenceGenerator();
        String pk_invoice = generator.generate();
        head.setStatus(VOStatus.NEW);
        head.setPk_invoice(pk_invoice);

        // 票面信息
        head.setFphm(pinvoice.getFpHm());
        head.setFpdm(pinvoice.getFpDm());
        head.setJjm(pinvoice.getJqbh());
        head.setKprq(getUFDate(pinvoice.getKprq()));// pinvoice.getKprq(),待解析，20190525152311
        head.setFpmw(pinvoice.getFpMw());
        head.setJym(pinvoice.getJym());
        head.setJshj(getBigDecimalToUFDouble(pinvoice.getJshj()));
        head.setHjje(getBigDecimalToUFDouble(pinvoice.getHjje()));
        head.setHjse(getBigDecimalToUFDouble(pinvoice.getHjse()));
        head.setBz(pinvoice.getBz());
        head.setKpr(pinvoice.getKpr());
        head.setSkr(pinvoice.getSkr());
        head.setFhr(pinvoice.getFhr());
        head.setFilename(null);
        head.setViewurl(null);
        head.setBillstatus(IBillStatus.CHECKPASS);

        // 数电特殊票种
        head.setZsfs(pinvoice.getZsfs());
        head.setTspz(IVApplicationTspzUtil.getTspzPk(pinvoice.getTspz()));
        head.setTspzdef99(head.getTspz());
        head.setKdsbz(pinvoice.getKdsbz());
        head.setBdcdz(pinvoice.getBdcdz());
        head.setZlqq(pinvoice.getZlqq() == null ? null : getUFDate(pinvoice.getZlqq()));
        head.setZlqz(pinvoice.getZlqz() == null ? null : getUFDate(pinvoice.getZlqz()));
        head.setTdzzsxmbh(pinvoice.getTdzzsxmbh());
        head.setWqhtbabh(pinvoice.getWqhtbabh());
        head.setBdcdwdm(pinvoice.getBdcdwdm());
        head.setHdjsjg(getBigDecimalToUFDouble(pinvoice.getHdjsjg()));
        head.setSjcjhsje(getBigDecimalToUFDouble(pinvoice.getSjcjhsje()));
        head.setBxdh(pinvoice.getBxdh());
        head.setCphcbdjh(pinvoice.getCphcbdjh());
        head.setSkssq(pinvoice.getSkssq());
        head.setCjh(pinvoice.getCjh());
        head.setDsccsje(getBigDecimalToUFDouble(pinvoice.getDsccsje()));
        head.setZnj(getBigDecimalToUFDouble(pinvoice.getZnj()));
        head.setJehj(getBigDecimalToUFDouble(pinvoice.getJehj()));

        // 根据开票申请来源交易类型，获取来源系统，为销项发票来源系统赋值。
        String src_billtype = ivApplicationHeadVO.getSrc_billtype();
        BilltypeVO billtypeVO = NCLocator.getInstance().lookup(IBilltypeService.class).getBilltypeByid(src_billtype);
        if (billtypeVO != null) {
            src_billtype = billtypeVO.getPk_billtypecode();
        }
        if (src_billtype != null && !"".equals(src_billtype)) {
            String lyxt =
                    NCLocator.getInstance().lookup(IVMInvoiceQueryService.class).getLyxtBybilltypecode(src_billtype);
            head.setLyxt(lyxt);// 开票单来源单据
        }

        // NC辅助信息
        if (KpztEnum.KPING.intValue() == logvo.getKpzt() || KpztEnum.DKP.intValue() == logvo.getKpzt() || KpztEnum.KP.intValue() == logvo.getKpzt()) {
            if (ivApplicationHeadVO.getHzfp().booleanValue() == UFBoolean.TRUE.booleanValue()) {
                head.setFpzt(InvoiceStatus.InvoiceStatus_0.toIntValue());
                head.setRed_flag(IsHzfp.IsHzfp_1.toIntValue());
                head.setYlzfpdm(ivApplicationHeadVO.getFpdm());
                head.setYlzfphm(ivApplicationHeadVO.getFphm());
            } else {
                head.setFpzt(InvoiceStatus.InvoiceStatus_0.toIntValue());
                head.setRed_flag(IsHzfp.IsHzfp_0.toIntValue());
            }
        } else if (KpztEnum.HCING.intValue() == logvo.getKpzt() || KpztEnum.HC.intValue() == logvo.getKpzt()) {
            head.setFpzt(InvoiceStatus.InvoiceStatus_0.toIntValue());
            head.setRed_flag(IsHzfp.IsHzfp_1.toIntValue());
            head.setYlzfpdm(ivApplicationHeadVO.getFpdm());
            head.setYlzfphm(ivApplicationHeadVO.getFphm());
        }
        // 重新查询交易类型
        IUAPQueryBS iUAPQueryBS = (IUAPQueryBS) NCLocator.getInstance().lookup(IUAPQueryBS.class.getName());
        if (ivApplicationHeadVO.getSgbz() != null && ivApplicationHeadVO.getSgbz().booleanValue()) {
            @SuppressWarnings("unchecked")
            List<BilltypeVO> vos =
                    (List<BilltypeVO>) iUAPQueryBS.retrieveByClause(BilltypeVO.class, BilltypeVO.PK_BILLTYPECODE
                            + "='SSIV-Cxx-rec' " + " AND " + " pk_group ='" + ivApplicationHeadVO.getPk_group() + "' ");
            if (vos != null && vos.size() > 0) {
                String pk_billtypeid = vos.get(0).getPk_billtypeid();
                head.setPk_billtype(pk_billtypeid);// 交易类型主键
                head.setBilltypecode(vos.get(0).getPk_billtypecode());
            } else {
                head.setPk_billtype(IVAWebConst.IVA_JXFP_JYLXPK);// 交易类型主键
                head.setBilltypecode(IVAWebConst.IVA_JXFP_JYLXBM);
            }
            // 收票日期 NC系统日期
            head.setSprq(new UFDate());
            // 收票人取开票申请修改人
            head.setSpr(ivApplicationHeadVO.getModifier());
            // 收购标志
            head.setSgbz(UFBoolean.TRUE);
            // 默认为采购类发票
            head.setClasstype(ClassTypeEnum.ClassType_CGL.toIntValue());

            // 收购发票，购销信息对调
            head.setXsfmc(pinvoice.getGmfMc());
            head.setXsfnsrsbh(pinvoice.getGmfNsrsbh());
            head.setXsfdzdh(pinvoice.getGmfDzdh());
            head.setXsfyhzh(pinvoice.getGmfYhzh());
            head.setGmfmc(pinvoice.getXsfMc());
            head.setGmfnsrsbh(pinvoice.getXsfNsrsbh());
            head.setGmfdzdh(pinvoice.getXsfDzdh());
            head.setGmfyhzh(pinvoice.getXsfYhzh());
        } else {
            @SuppressWarnings("unchecked")
            List<BilltypeVO> vos =
                    (List<BilltypeVO>) iUAPQueryBS.retrieveByClause(BilltypeVO.class, BilltypeVO.PK_BILLTYPECODE
                            + "='SSIV-Cxx-sale' " + " AND " + " pk_group ='" + ivApplicationHeadVO.getPk_group() + "' ");
            if (vos != null && vos.size() > 0) {
                String pk_billtypeid = vos.get(0).getPk_billtypeid();
                head.setPk_billtype(pk_billtypeid);// 交易类型主键
                head.setBilltypecode(vos.get(0).getPk_billtypecode());
            } else {
                head.setPk_billtype(IVAWebConst.IVA_XXFP_JYLXPK);// 交易类型主键
                head.setBilltypecode(IVAWebConst.IVA_XXFP_JYLXBM);
            }
            // 非收购发票，购销信息直传
            head.setXsfmc(pinvoice.getXsfMc());
            head.setXsfnsrsbh(pinvoice.getXsfNsrsbh());
            head.setXsfdzdh(pinvoice.getXsfDzdh());
            head.setXsfyhzh(pinvoice.getXsfYhzh());
            head.setGmfmc(pinvoice.getGmfMc());
            head.setGmfnsrsbh(pinvoice.getGmfNsrsbh());
            head.setGmfdzdh(pinvoice.getGmfDzdh());
            head.setGmfyhzh(pinvoice.getGmfYhzh());
        }


        head.setInvoice_type(logvo.getInvoice_type() == null ? null : Integer.valueOf(logvo.getInvoice_type()));
        head.setBillno(null);// NC系统单据编号,发票单的单据编号
        head.setPk_customer(null);// 来源于开票申请
        head.setBilldate(new UFDate());// NC系统日期
        head.setDjdl(IVMInvoiceConstant.IVREC_SP_BILLTYPEID);// 单据类型主键
        head.setDjdlbm(IVMInvoiceConstant.IVREC_SP_BILLTYPECODE);// 单据类型编码
        head.setPk_org(ivApplicationHeadVO.getPk_org());// 来源于开票申请
        head.setPk_group(ivApplicationHeadVO.getPk_group());// 来源于开票申请

        List<IVMInvoiceDetailVO> details = new ArrayList<IVMInvoiceDetailVO>();
        if (pinvoice.getItems() != null) {
            for (int i = 0; i < pinvoice.getItems().length; i++) {
                PInvoiceDetail item = pinvoice.getItems()[i];

                IVMInvoiceDetailVO detail = new IVMInvoiceDetailVO();
                // detail.setPk_invoice(pk_invoice);
                // detail.setPk_invoicedetail(generator.generate());
                detail.setStatus(VOStatus.NEW);
                detail.setRowno(item.getHh());
                detail.setXmmc(item.getXmmc());
                detail.setGgxh(item.getGgxh());
                detail.setDw(item.getDw());
                detail.setXmsl(getBigDecimalToUFDouble(item.getXmsl()));// 需要改成UFDouble
                detail.setXmdj(getBigDecimalToUFDouble(item.getXmdj()));
                detail.setXmje(getBigDecimalToUFDouble(item.getXmje()));
                detail.setSl(item.getSl() == null ? "" : item.getSl().toString());
                detail.setSe(getBigDecimalToUFDouble(item.getSe()));
                detail.setXmjshj(getBigDecimalToUFDouble(item.getXmjshj()));
                detail.setSpbm(item.getSpbm());
                detail.setIsfee(UFBoolean.FALSE);
                detail.setFphxz(Integer.valueOf(item.getFphxz()));
                detail.setZkhhh(item.getZkhhh());
                // 数电特殊票种
                PInvoiceSDetail motor = item.getDetailMotor();
                if (motor != null) {
                    detail.setJzfwfsd(motor.getJzfwfsd());
                    detail.setJzxmmc(motor.getJzxmmc());
                    detail.setCqzsbh(motor.getCqzsbh());
                }
                details.add(detail);
            }
        }

        // 特殊票种
        List<IVMInvoiceTspzDetailVO> tspzDetails = new ArrayList<IVMInvoiceTspzDetailVO>();
        if (pinvoice.getTspzs() != null && pinvoice.getTspzs().length > 0) {
            for (PInvoiceTspz ptspz : pinvoice.getTspzs()) {
                IVMInvoiceTspzDetailVO tspz = new IVMInvoiceTspzDetailVO();

                // 货运
                tspz.setYsmxxh(ptspz.getYsmxxh());
                tspz.setYsgjzl(ptspz.getYsgjzl());
                tspz.setYsgjph(ptspz.getYsgjph());
                tspz.setQyd(ptspz.getQyd());
                tspz.setDdd(ptspz.getDdd());
                tspz.setYshwmc(ptspz.getYshwmc());

                // 客运
                tspz.setCxrxh(ptspz.getCxrxh());
                tspz.setCxr(ptspz.getCxr());
                tspz.setChuxrq(ptspz.getChuxrq() == null ? null : getUFDate(ptspz.getChuxrq()));
                tspz.setCxrzjlxdm(ptspz.getCxrzjlxDm());
                tspz.setSfzjhm(ptspz.getSfzjhm());
                tspz.setCfd(ptspz.getCfd());
                tspz.setLkddd(ptspz.getLkddd());
                tspz.setZwdj(ptspz.getZwdj());
                tspz.setJtgjlxdm(ptspz.getJtgjlxDm());

                tspzDetails.add(tspz);
            }
        }

        if (pinvoice.getCepzs() != null && pinvoice.getCepzs().length > 0) {
            for (PInvoiceCepz pcepz : pinvoice.getCepzs()) {
                IVMInvoiceTspzDetailVO cepz = new IVMInvoiceTspzDetailVO();
                cepz.setXh(pcepz.getXh());
                cepz.setPzlx(pcepz.getPzlx());
                cepz.setFphm(pcepz.getFphm());
                cepz.setFpdm(pcepz.getFpdm());
                cepz.setZzfphm(pcepz.getZzfphm());
                cepz.setPzhm(pcepz.getPzhm());
                cepz.setKjrq(pcepz.getKjrq() == null ? null : getUFDate(pcepz.getKjrq()));
                cepz.setHjje(getBigDecimalToUFDouble(pcepz.getHjje()));
                cepz.setKce(getBigDecimalToUFDouble(pcepz.getKce()));
                cepz.setBz(pcepz.getBz());
                cepz.setLy(pcepz.getLy());
                cepz.setBckcje(getBigDecimalToUFDouble(pcepz.getBckcje()));
                cepz.setPzhjje(getBigDecimalToUFDouble(pcepz.getPzhjje()));

                tspzDetails.add(cepz);
            }
        }


        aggvo.setParentVO(head);
        aggvo.setChildrenVO(details.toArray(new IVMInvoiceDetailVO[0]));
        if (tspzDetails.size() > 0) {
            aggvo.setIvmInvoiceTspzDetailVO(tspzDetails.toArray(new IVMInvoiceTspzDetailVO[0]));
        }

        initKhcje(aggvo);// 初始化可红冲金额
        return aggvo;
    }

    private static void initKhcje(IVMInvoiceAggVO aggvo) {
        IVMInvoiceHeadVO head = aggvo.getParentVO();
        if (head.getRed_flag() != null && head.getRed_flag().intValue() != IsHzfp.IsHzfp_0.toIntValue()) {
            return;
        }
        // 1. 初始化表头可红冲金额等于价税合计金额
        head.setKhcje(head.getJshj());
        head.setZthcje(UFDouble.ZERO_DBL);
        head.setYhcje(UFDouble.ZERO_DBL);

        // 2. 初始化表体可红冲金额
        IVMInvoiceDetailVO[] detailVOs = (IVMInvoiceDetailVO[]) aggvo.getChildrenVO();
        Map<String, UFDouble> rowNumAndJshjMap = new HashMap<>();
        for (IVMInvoiceDetailVO detail : detailVOs) {
            rowNumAndJshjMap.put(detail.getRowno(), detail.getXmjshj());
        }

        for (IVMInvoiceDetailVO detail : detailVOs) {
            detail.setYhcje(UFDouble.ZERO_DBL);
            detail.setZthcje(UFDouble.ZERO_DBL);
            int fphxz = detail.getFphxz().intValue();
            if (IVAplocationFPXZ.FPXZ_ZCH.toIntValue() == fphxz) {
                detail.setKhcje(detail.getXmjshj());// 正常行 可红冲金额等于价税合计
            } else if (IVAplocationFPXZ.PFPXZ_BZKH.toIntValue() == fphxz) {
                UFDouble zkhJshj = rowNumAndJshjMap.get(detail.getZkhhh());
                detail.setKhcje(detail.getXmjshj().add(zkhJshj));// 被折扣行 可红冲金额等于 价税合计减去折扣行价税合计
            } else {
                detail.setKhcje(UFDouble.ZERO_DBL);
            }
        }
    }

    /**
     * 根据开票结果转换生成发票关联关系
     *
     * @param pinvoice
     * @return
     * @throws BusinessException
     */
    public static HashSet<IVMInvoiceRelationVO> getIVMInvoiceRelationVOFromInvoice(IVMInvoiceAggVO pinvoice,
                                                                                   IVApplicationAggVO[] ivApplicationHeadVOS, String lyids) throws BusinessException {
        HashSet<IVMInvoiceRelationVO> heads = new HashSet<IVMInvoiceRelationVO>();
        Set<String> pk_ivapplicationSet = new HashSet<String>();
        if (lyids != null) {
            List<IVMInvoiceRelationVO> bhcInvoiceRelations = new ArrayList<IVMInvoiceRelationVO>();
            Map<String, IVMInvoiceRelationVO> billRelationMap = new HashMap<String, IVMInvoiceRelationVO>();
            // 红字发票，根据原蓝票回写金额需要提前
            boolean hzfp = "1".equals(String.valueOf(pinvoice.getParentVO().getRed_flag()));
            if (hzfp) {
                // 查询被红冲的发票的发票单据关联关系，丢失的关系直接从其中补
                StringBuilder queryReSql = new StringBuilder("");
                queryReSql.append(" select ion.* from sscivm_invoice_relation ion ");
                queryReSql.append(" left join sscivm_invoice ice on ion.pk_invoice = ice.pk_invoice ");
                queryReSql.append(" where ion.fphm = '" + pinvoice.getParentVO().getYlzfphm() + "' ");
                if (pinvoice.getParentVO().getYlzfpdm() != null) {
                    queryReSql.append(" and ion.fpdm = '" + pinvoice.getParentVO().getYlzfpdm() + "' ");
                }
                queryReSql.append(" and ice.dr = 0 ");
                queryReSql.append(" and (ice.billtypecode ='SSIV-Cxx-sale' or (ice.billtypecode ='SSIV-Cxx-rec' and ice.invoice_type in (109,309))) ");
                bhcInvoiceRelations = (List<IVMInvoiceRelationVO>) new BaseDAO().executeQuery(queryReSql.toString(), new BeanListProcessor(IVMInvoiceRelationVO.class));
                if (bhcInvoiceRelations.size() > 0) {
                    for (IVMInvoiceRelationVO bhcInvoiceRelation : bhcInvoiceRelations) {
                        billRelationMap.put(bhcInvoiceRelation.getBillid(), bhcInvoiceRelation);
                    }

                    // 业务单据红冲不记录关联关系
                    boolean ywdjhc = true;
                    for (IVApplicationAggVO ivApplicationHeadVO : ivApplicationHeadVOS) {
                        if (billRelationMap.containsKey(ivApplicationHeadVO.getParentVO().getSrc_pkbusibill())) {
                            ywdjhc = false;
                        }
                    }
                    if (ywdjhc) {
                        billRelationMap = new HashMap<String, IVMInvoiceRelationVO>();
                        bhcInvoiceRelations = new ArrayList<IVMInvoiceRelationVO>();
                    }
                }

            }

            List<IVApplicationAggVO> ivApplicationHeadVOList = new ArrayList<IVApplicationAggVO>();
            for (IVApplicationAggVO ivApplicationHeadVO : ivApplicationHeadVOS) {
                ivApplicationHeadVOList.add(ivApplicationHeadVO);
                // 处理批量红冲后重开的原始数据，需要增加关联关系
                if (ivApplicationHeadVO.getParentVO().getCkfp() != null
                        && ivApplicationHeadVO.getParentVO().getCkfp().booleanValue()) {

                    // 查找原发票的发票单据关联关系，从中补关系
                    StringBuilder queryReSql = new StringBuilder("");
                    queryReSql.append(" select rel.* from sscivm_invoice_relation rel ");
                    queryReSql.append(" left join sscivm_invoice ice on rel.pk_invoice = ice.pk_invoice ");
                    queryReSql.append(" left join sscivm_ivapplication iva on (iva.pk_ivapplication ='");
                    queryReSql.append(ivApplicationHeadVO.getParentVO().getPk_ivapplication());
                    queryReSql.append("') ");
                    queryReSql.append("  where iva.fpdm = rel.fpdm ");
                    queryReSql.append(" and iva.fphm = rel.fphm ");
                    queryReSql.append(" and rel.dr = 0 ");
                    queryReSql.append(" and (ice.billtypecode ='SSIV-Cxx-sale' or (ice.billtypecode ='SSIV-Cxx-rec' and ice.invoice_type in (109,309))) ");

                    @SuppressWarnings("unchecked")
                    List<IVMInvoiceRelationVO> yInvoiceRelations = (List<IVMInvoiceRelationVO>) new BaseDAO()
                            .executeQuery(queryReSql.toString(), new BeanListProcessor(IVMInvoiceRelationVO.class));

                    // 根据原发票的发票关联关系，生成 发票关联关系
                    if (yInvoiceRelations.size() > 0) {
                        for (IVMInvoiceRelationVO bhcInvoiceRelation : yInvoiceRelations) {
                            billRelationMap.put(bhcInvoiceRelation.getBillid(), bhcInvoiceRelation);
                            if (StringUtils.isBlank(bhcInvoiceRelation.getBillid()) || bhcInvoiceRelation.getBillid().equals(ivApplicationHeadVO.getParentVO().getSrc_pkbusibill())) {
                                continue;
                            }
                            IVMInvoiceRelationVO head = new IVMInvoiceRelationVO();
                            head.setStatus(VOStatus.NEW);
                            // 票面信息
                            head.setFphm(pinvoice.getParentVO().getFphm());
                            head.setFpdm(pinvoice.getParentVO().getFpdm());
                            head.setBillid(bhcInvoiceRelation.getBillid());
                            head.setBillno(bhcInvoiceRelation.getBillno());
                            head.setBilltype(bhcInvoiceRelation.getBilltype());
                            head.setTradetype(bhcInvoiceRelation.getTradetype());
                            head.setInvoiceamount(pinvoice.getParentVO().getJshj());
                            head.setPk_invoice(pinvoice.getParentVO().getPk_invoice());
                            head.setAmount(bhcInvoiceRelation.getAmount());
                            head.setJe(bhcInvoiceRelation.getJe());
                            head.setSe(bhcInvoiceRelation.getSe());
                            heads.add(head);
                        }
                    }

                }
            }


            String[] lyidarr = lyids.split(IVAWebConst.IVA_LYID_SPLIT);
            Map<String, String> map = TransSpiltMergePksUtil
                    .transLyidToIvapplicationStrMap(lyidarr);
            for (String lyidstr : lyidarr) {
                for (IVApplicationAggVO ivApplicationHeadVO : ivApplicationHeadVOList) {

                    if (lyidstr != null && map.get(lyidstr).contains(ivApplicationHeadVO.getParentVO().getPk_ivapplication())) {
                        IVMInvoiceRelationVO head = new IVMInvoiceRelationVO();
                        head.setStatus(VOStatus.NEW);
                        if (StringUtils.isBlank(ivApplicationHeadVO.getParentVO().getSrc_pkbusibill())) {
                            continue;
                        }
                        // 票面信息
                        head.setFphm(pinvoice.getParentVO().getFphm());
                        head.setFpdm(pinvoice.getParentVO().getFpdm());
                        head.setBillid(ivApplicationHeadVO.getParentVO().getSrc_pkbusibill());
                        head.setBillno(ivApplicationHeadVO.getParentVO().getSrc_billno());
                        head.setBilltype(ivApplicationHeadVO.getParentVO().getSrc_billtype());
                        head.setTradetype(ivApplicationHeadVO.getParentVO().getSrc_tradetype());
                        head.setInvoiceamount(pinvoice.getParentVO().getJshj());
                        head.setPk_invoice(pinvoice.getParentVO().getPk_invoice());
                        IVMInvoiceRelationVO oldvo = billRelationMap.get(head.getBillid());
                        if (oldvo != null) {
                            if (hzfp) {
                                if (oldvo.getAmount() != null) {
                                    head.setAmount(oldvo.getAmount().multiply(-1));
                                }
                                if (oldvo.getJe() != null) {
                                    head.setJe(oldvo.getJe().multiply(-1));
                                }
                                if (oldvo.getSe() != null) {
                                    head.setSe(oldvo.getSe().multiply(-1));
                                }
                            } else {
                                head.setAmount(oldvo.getAmount());
                                head.setJe(oldvo.getJe());
                                head.setSe(oldvo.getSe());
                            }
                        }
                        heads.add(head);
                        if (ivApplicationHeadVO.getParentVO().getSrc_pkbusibill() != null && ivApplicationHeadVO.getParentVO().getSrc_pkbusibill().length() > 0) {
                            pk_ivapplicationSet.add(ivApplicationHeadVO.getParentVO().getSrc_pkbusibill());
                        }
                    }
                }

            }

            // 合并场景联查对应的红字发票相关单据
            if (hzfp && pk_ivapplicationSet.size() > 0) {
                // 根据被红冲发票关联关系，生成 发票关联关系
                if (bhcInvoiceRelations.size() > 0) {
                    for (IVMInvoiceRelationVO bhcInvoiceRelation : bhcInvoiceRelations) {
                        IVMInvoiceRelationVO head = new IVMInvoiceRelationVO();
                        boolean continueAdd = true;
                        for (IVMInvoiceRelationVO headin : heads) {
                            if (headin.getBillid() != null && bhcInvoiceRelation.getBillid() != null && headin.getBillid().equals(bhcInvoiceRelation.getBillid())) {
                                continueAdd = false;
                            }
                        }
                        if (!continueAdd) {
                            continue;
                        }
                        head.setStatus(VOStatus.NEW);
                        // 票面信息
                        head.setFphm(pinvoice.getParentVO().getFphm());
                        head.setFpdm(pinvoice.getParentVO().getFpdm());
                        head.setBillid(bhcInvoiceRelation.getBillid());
                        head.setBillno(bhcInvoiceRelation.getBillno());
                        head.setBilltype(bhcInvoiceRelation.getBilltype());
                        head.setTradetype(bhcInvoiceRelation.getTradetype());
                        head.setInvoiceamount(pinvoice.getParentVO().getJshj());
                        head.setPk_invoice(pinvoice.getParentVO().getPk_invoice());
                        if (bhcInvoiceRelation.getAmount() != null) {
                            head.setAmount(bhcInvoiceRelation.getAmount().multiply(-1));
                        }
                        if (bhcInvoiceRelation.getJe() != null) {
                            head.setJe(bhcInvoiceRelation.getJe().multiply(-1));
                        }
                        if (bhcInvoiceRelation.getSe() != null) {
                            head.setSe(bhcInvoiceRelation.getSe().multiply(-1));
                        }
                        heads.add(head);
                    }
                }
            }
        }
        return heads;
    }

    /**
     * 根据平台发票申请返回结果（传税务云发票）转换开票日志
     *
     * @param pinvoice
     * @return
     * @throws BusinessException
     */
    public static IVApplogVO getIVApplogVOFromPInvoice(PInvoice pinvoice) throws BusinessException {

        return getIVApplogVOFromPInvoice(pinvoice, KpztEnum.KPING);
    }

    /**
     * 根据平台发票申请返回结果（传税务云发票单）转换开票日志
     *
     * @param pinvoice
     * @return
     * @throws BusinessException
     */
    public static IVApplogVO getIVApplogVOFromPInvoiceBill(PInvoice pinvoice) throws BusinessException {

        return getIVApplogVOFromPInvoice(pinvoice, KpztEnum.DKP);
    }

    /**
     * 根据发票生成开票日志
     *
     * @param pinvoice
     * @param kpzt
     * @return
     * @throws BusinessException
     */
    public static IVApplogVO getIVApplogVOFromPInvoice(PInvoice pinvoice, int kpzt) throws BusinessException {
        SequenceGenerator generator = new SequenceGenerator();
        IVApplogVO logvo = new IVApplogVO();
        logvo.setCode(IVMInvoiceConstant.SUCCESS_CODE);
        logvo.setKpzt(kpzt);// 待开票
        logvo.setLyid(pinvoice.getLyid());
        logvo.setStatus(VOStatus.NEW);
        logvo.setFpqqlsh(pinvoice.getApplyNumber());
        logvo.setInvoice_type(InvoiceTypeToTspzUtil.getInvoicetypeByFplxAndTspz(pinvoice.getFplx(), pinvoice.getTspz()));
        logvo.setKprq(pinvoice.getKprq());
        logvo.setGmfmc(pinvoice.getGmfMc());
        logvo.setXsfmc(pinvoice.getXsfMc());
        if (InvoiceTypeEnum.getSGFP().contains(Integer.parseInt(logvo.getInvoice_type())) || (pinvoice.getSgbz() != null && "2".equals(pinvoice.getSgbz()))) {
            logvo.setGmfmc(pinvoice.getXsfMc());
            logvo.setXsfmc(pinvoice.getGmfMc());
        }
        logvo.setJshj(getBigDecimalToUFDouble(pinvoice.getJshj()));
        logvo.setHjje(getBigDecimalToUFDouble(pinvoice.getHjje()));
        logvo.setHjse(getBigDecimalToUFDouble(pinvoice.getHjse()));
        logvo.setKpr(pinvoice.getKpr());
        logvo.setPk_ivapplog(generator.generate());
        logvo.setItems(pinvoice.getItems());
        return logvo;
    }

    public static IVApplogVO getIVApplogVOFromInvoiceBillInfo(InvoiceBillInfo billinfo) throws BusinessException {
        IVApplogVO logvo = new IVApplogVO();

        PInvoice pinvoice = billinfo.getInvoice();

        logvo.setCode(IVMInvoiceConstant.SUCCESS_CODE);
        if ("4".equals(billinfo.getStatuscode())) {
            // 开票成功
            logvo.setKpzt(KpztEnum.KP);
        } else if ("2".equals(billinfo.getStatuscode())) {
            // 开票中
            logvo.setKpzt(KpztEnum.KPING);// 开票中
        } else if ("3".equals(billinfo.getStatuscode())) {
            logvo.setKpzt(KpztEnum.KPERR);// 开票失败
            logvo.setErrmsg(billinfo.getErrmsg());
        }
        if (pinvoice != null) {
            // Statuscode=1的时候pinvoice为空
            logvo.setLyid(pinvoice.getLyid());
            logvo.setFpqqlsh(pinvoice.getApplyNumber());
            logvo.setInvoice_type(InvoiceTypeToTspzUtil.getInvoicetypeByFplxAndTspz(pinvoice.getFplx(), pinvoice.getTspz()));
            logvo.setKprq(pinvoice.getKprq());
            logvo.setGmfmc(pinvoice.getGmfMc());
            logvo.setXsfmc(pinvoice.getXsfMc());
            if (InvoiceTypeEnum.getSGFP().contains(Integer.parseInt(logvo.getInvoice_type())) || (pinvoice.getSgbz() != null && "2".equals(pinvoice.getSgbz()))) {
                logvo.setGmfmc(pinvoice.getXsfMc());
                logvo.setXsfmc(pinvoice.getGmfMc());
            }
            logvo.setJshj(getBigDecimalToUFDouble(pinvoice.getJshj()));
            logvo.setHjje(getBigDecimalToUFDouble(pinvoice.getHjje()));
            logvo.setHjse(getBigDecimalToUFDouble(pinvoice.getHjse()));
            logvo.setKpr(pinvoice.getKpr());

            logvo.setFphm(pinvoice.getFpHm());
            logvo.setFpdm(pinvoice.getFpDm());
        }
        logvo.setStatus(VOStatus.NEW);

        return logvo;
    }

    /**
     * 根据开票申请转换成发票平台VO
     *
     * @return
     */
    private static PInvoice getPInvoiceByApplyHead(IVApplicationHeadVO headvo) {

        PInvoice pinvoice = new PInvoice();

        pinvoice.setApplyNumber(headvo.getPk_ivapplication());
        pinvoice.setLyid(headvo.getPk_ivapplication());
        pinvoice.setFplx(InvoiceTypeToTspzUtil.getRealInvoicetype(headvo.getFplx()));
        String tspz = InvoiceTypeToTspzUtil.getTspz(headvo.getFplx());
        if (StringUtils.isEmpty(tspz) && StringUtils.isNotEmpty(headvo.getTspz())) {
            try {
                Collection<DefdocVO> defdocVOS = ((IUAPQueryBS) NCLocator.getInstance().lookup(IUAPQueryBS.class.getName())).retrieveByClause(DefdocVO.class, " " + DefdocVO.PK_DEFDOC + "='" + headvo.getTspz() + "' ");
                if (defdocVOS != null && defdocVOS.size() > 0) {
                    for (DefdocVO DefdocVO : defdocVOS) {
                        tspz = DefdocVO.getCode();
                        break;
                    }
                }
            } catch (BusinessException e) {
                SSCIVMLogger.error(e.getMessage(), e);
            }
        }

        pinvoice.setTspz(tspz);
        // 目前传值，后续应该不传，税务云都通过组织编码解析，销售方的其他信息不需要传值
        if (headvo.getSgbz() != null && headvo.getSgbz().booleanValue()) {// 收购销方转购方
            pinvoice.setGmf_dz(headvo.getXsf_dz());
            pinvoice.setGmf_dh(headvo.getXsf_dh());
            pinvoice.setGmf_yh(headvo.getXsf_yh());
            pinvoice.setGmf_zh(headvo.getXsf_zhh());
            pinvoice.setGmfNsrsbh(headvo.getXsf_nsrsbh());
            pinvoice.setGmfMc(headvo.getXsf_mc());
            pinvoice.setGmfDzdh(headvo.getXsf_dzdh());
            pinvoice.setGmfYhzh(headvo.getXsf_yhzh());
            pinvoice.setXsfNsrsbh(headvo.getGmf_nsrsbh());
        } else {
            pinvoice.setXsfYhzh((headvo.getXsf_yhzh() == null ? "" : headvo.getXsf_yhzh()));
            pinvoice.setXsfNsrsbh(headvo.getXsf_nsrsbh());
            pinvoice.setXsf_dz(headvo.getXsf_dz());
            pinvoice.setXsf_dh(headvo.getXsf_dh());
            pinvoice.setXsf_yh(headvo.getXsf_yh());
            pinvoice.setXsf_zh(headvo.getXsf_zhh());
            pinvoice.setGmf_dz(headvo.getGmf_dz());
            pinvoice.setGmf_dh(headvo.getGmf_dh());
            pinvoice.setGmf_yh(headvo.getGmf_yh());
            pinvoice.setGmf_zh(headvo.getGmf_zhh());
            pinvoice.setGmfNsrsbh(headvo.getGmf_nsrsbh());
            pinvoice.setGmfMc(headvo.getGmf_mc());
            pinvoice.setGmfDzdh(headvo.getGmf_dzdh());
            pinvoice.setGmfYhzh(headvo.getGmf_yhzh());
        }

        // 收购标志处理
        if (headvo.getSgbz().booleanValue()) {
            pinvoice.setSgbz("2");
        }

        pinvoice.setKpr(headvo.getKpr());
        pinvoice.setSkr(headvo.getSkr());
        pinvoice.setFhr(headvo.getFhr());
        pinvoice.setJshj(getUFDoubleToBigDecimal(headvo.getCaninvoice_jshj()).setScale(2, UFDouble.ROUND_HALF_UP));

        pinvoice.setSrcBillNo(headvo.getSrc_billno());
        // pinvoice.setHjje(getUFDoubleToBigDecimal(headvo.getHjje()).setScale(2,
        // UFDouble.ROUND_HALF_UP));//存在含税和不含税单价，统一交由税务云反算
        // pinvoice.setHjse(getUFDoubleToBigDecimal(headvo.getHjse()).setScale(2,
        // UFDouble.ROUND_HALF_UP));//存在含税和不含税单价，统一交由税务云反算
        pinvoice.setBz(headvo.getBz());
        pinvoice.setZdybz(headvo.getZdybz());
        pinvoice.setOrgcode(headvo.getOrgcode());

        // 税率说明
        pinvoice.setSlsm(headvo.getSlsm());

        pinvoice.setAllelcusername(headvo.getAllelcusername());
        pinvoice.setAllelcpassword(headvo.getAllelcpassword());

        pinvoice.setZsfs(headvo.getZsfs() == null ? "" : headvo.getZsfs());

        // 数电特殊票种字段
        pinvoice.setBdcdz(headvo.getBdcdz());
        pinvoice.setZlqq(getFormatDate(headvo.getZlqq()));
        pinvoice.setZlqz(getFormatDate(headvo.getZlqz()));
        pinvoice.setKdsbz(headvo.getKdsbz());
        pinvoice.setTdzzsxmbh(headvo.getTdzzsxmbh());
        pinvoice.setWqhtbabh(headvo.getWqhtbabh());
        pinvoice.setBdcdwdm(headvo.getBdcdwdm());
        pinvoice.setHdjsjg(headvo.getHdjsjg() == null ? null : getUFDoubleToBigDecimal(headvo.getHdjsjg()).setScale(2, UFDouble.ROUND_HALF_UP));
        pinvoice.setSjcjhsje(headvo.getSjcjhsje() == null ? null : getUFDoubleToBigDecimal(headvo.getSjcjhsje()).setScale(2, UFDouble.ROUND_HALF_UP));
        pinvoice.setBxdh(headvo.getBxdh());
        pinvoice.setCphcbdjh(headvo.getCphcbdjh());
        pinvoice.setSkssq(headvo.getSkssq());
        pinvoice.setDsccsje(headvo.getDsccsje() == null ? null : getUFDoubleToBigDecimal(headvo.getDsccsje()).setScale(2, UFDouble.ROUND_HALF_UP));
        pinvoice.setZnj(headvo.getZnj() == null ? null : getUFDoubleToBigDecimal(headvo.getZnj()).setScale(2, UFDouble.ROUND_HALF_UP));
        pinvoice.setJehj(headvo.getJehj() == null ? null : getUFDoubleToBigDecimal(headvo.getJehj()).setScale(2, UFDouble.ROUND_HALF_UP));
        pinvoice.setCjh(headvo.getCjh());
        // pinvoice.setKqysssxbgglbm(headvo.getKqysssxbgglbm());

        setOtherField(headvo, pinvoice);
        return pinvoice;
    }

    private static void setOtherField(IVApplicationHeadVO headvo, PInvoice pinvoice) {
        // 是否展示销售方开户银行及账号 Y-是/N-否
        String def3 = headvo.getDef3();
        // 是否展示销售方地址电话
        String def4 = headvo.getDef4();
        // 是否填写收款人及复核人
        String def16 = headvo.getDef16();
        // 是否展示购买方单位、地址电话
        String def17 = headvo.getDef17();
        // 是否展示购买方开户行、银行账号
        String def18 = headvo.getDef18();

        // einvoiceShowGxfDzDh 表示是否显示购方和销方的地址电话
        // 根据需求：0: 不显示 1: 显示购方地址电话 2: 显示销方地址电话 3: 显示购方和销方地址电话
        int einvoiceShowGxfDzDh = 0;

        if ("Y".equals(def3)) {
            einvoiceShowGxfDzDh += 1; // 购方地址电话显示
        }
        if ("Y".equals(def17)) {
            einvoiceShowGxfDzDh += 2; // 销方地址电话显示
        }

        // einvoiceShowGxfYhZh 表示是否显示购方和销方的小银行账户
        // 根据需求：0: 不显示 1: 显示购方银行账户 2: 显示销方银行账户 3: 显示购方和销方银行账户
        int einvoiceShowGxfYhZh = 0;

        if ("Y".equals(def4)) {
            einvoiceShowGxfYhZh += 1; // 购方银行账户显示
        }
        if ("Y".equals(def18)) {
            einvoiceShowGxfYhZh += 2; // 销方银行账户显示
        }
        // 数电发票是否显示购销方地址电话 0:不显示 1:仅显示销地址、电话 2:仅显示购买方地址、电话 3:购销方地址、电话都显示
        pinvoice.setEinvoiceShowGxfDzDh(String.valueOf(einvoiceShowGxfDzDh));
        // 数电发票是否显示购销方银行、账号: 0:不显示 1:仅显示销售方银行、账号 2:仅显示购买方银行、账号 3:购销方银行、账号都显示
        pinvoice.setEinvoiceShowGxfYhZh(String.valueOf(einvoiceShowGxfYhZh));

        pinvoice.setGmf_dh(headvo.getGmf_dh());
        pinvoice.setGmf_dz(headvo.getGmf_dz());
        pinvoice.setXsf_dz(headvo.getXsf_dz());
        pinvoice.setXsf_dz(headvo.getXsf_dh());
    }

    /**
     * 根据红冲申请转换成发票平台VO
     *
     * @return
     */
    private static PInvoice getPInvoiceByApplyHead4Red(IVApplicationHeadVO headvo) {

        PInvoice pinvoice = new PInvoice();
        pinvoice.setApplyNumber(headvo.getPk_ivapplication());
        pinvoice.setLyid(headvo.getPk_ivapplication());
        pinvoice.setFplx(String.valueOf(headvo.getFplx()));
        pinvoice.setXsfNsrsbh(headvo.getXsf_nsrsbh());
        pinvoice.setFpHm(headvo.getFphm());
        pinvoice.setFpDm(headvo.getFpdm());
        pinvoice.setKpr(headvo.getKpr());
        pinvoice.setJshj(getUFDoubleToBigDecimal(headvo.getCaninvoice_jshj()).setScale(2, UFDouble.ROUND_HALF_UP));
        pinvoice.setXsfYhzh((headvo.getXsf_yhzh() == null ? "" : headvo.getXsf_yhzh()));
        pinvoice.setHzxxbbh(headvo.getHzxxsqb());
        // pinvoice.setHjje(getUFDoubleToBigDecimal(headvo.getHjje()).setScale(2,
        // UFDouble.ROUND_HALF_UP));//存在含税和不含税单价，统一交由税务云反算
        // pinvoice.setHjse(getUFDoubleToBigDecimal(headvo.getHjse()).setScale(2,
        // UFDouble.ROUND_HALF_UP));//存在含税和不含税单价，统一交由税务云反算
        pinvoice.setOrgcode(headvo.getOrgcode());

        // 税率说明红冲原因
        pinvoice.setSlsm(headvo.getSlsm());
        pinvoice.setHcyy(headvo.getHcyy());

        pinvoice.setAllelcusername(headvo.getAllelcusername());
        pinvoice.setAllelcpassword(headvo.getAllelcpassword());
        pinvoice.setXsf_dz(headvo.getXsf_dz());
        pinvoice.setXsf_dh(headvo.getXsf_dh());
        pinvoice.setXsf_yh(headvo.getXsf_yh());
        pinvoice.setXsf_zh(headvo.getXsf_zhh());
        return pinvoice;
    }

    /**
     * 根据开票申请明细转成成发票平台明细VO
     *
     * @param body
     * @return
     */
    private static PInvoiceDetail getPInvoiceByApplyHead(IVApplicationHeadVO headvo, IVApplicationBodyVO body) {

        PInvoiceDetail detailvo = new PInvoiceDetail();
        // 开票神申请规格型号自动截取40位长度
        detailvo.setGgxh((body.getGgxh() != null && body.getGgxh().length() > 40) ? body.getGgxh().substring(0, 40) : body.getGgxh());
        detailvo.setDw(body.getDw());
        detailvo.setXmsl(getUFDoubleToBigDecimal(body.getCaninvoice_xmsl()));
        detailvo.setZkhhh(body.getZkhhh());
        detailvo.setFphxz(body.getFphxz() == null ? IVAplocationFPXZ.FPXZ_ZCH.toIntValue() : body.getFphxz());
        detailvo.setHh(body.getHh());
        // detailvo.setXmdj(getUFDoubleToBigDecimal(body.getXmdj())); //存在含税和不含税单价，统一交由税务云反算
        // detailvo.setXmje(getUFDoubleToBigDecimal(body.getCaninvoice_xmje()).setScale(2, UFDouble.ROUND_HALF_UP)); //税务云反算
        detailvo.setXmjshj(getUFDoubleToBigDecimal(body.getCaninvoice_xmjshj()).setScale(2, UFDouble.ROUND_HALF_UP));
        detailvo.setSl(getUFDoubleToBigDecimal(body.getSl()).multiply(new BigDecimal(0.01)));
        // detailvo.setSe(detailvo.getXmjshj().subtract(detailvo.getXmje())); //税务云反算
        if (body.getSsflbm() != null && body.getSsflbm().length() > 0) {
            // 传税收分类编码的开票
            detailvo.setSpbm(body.getSsflbm());
            detailvo.setXmmc(body.getXmmc());
        } else if ((body.getPk_materiel() == null || body.getPk_materiel().length() == 0)) {
            // 重开的场景
            String xmmc = body.getXmmc();
            if (xmmc != null && headvo.getCkfp() != null && headvo.getCkfp().booleanValue()) {
                xmmc = xmmc.replace("*", "");// 按税务云清除第一个*号
                xmmc = xmmc.replace("*", "");// 按税务云清除第二个*号
            }
            detailvo.setXmmc(xmmc);
            detailvo.setSpbm(body.getSpbm());
        } else {
            // 正常开票的场景
            detailvo.setXmbm(body.getSpbm());
            detailvo.setXmmc(body.getXmmc());
        }
        detailvo.setLslbs(body.getLslbs());
        if (headvo.getSgbz().booleanValue()) {
            detailvo.setLslbs(IVAplocationLSLBS.LSLBS_MS.toStringValue());
        }
        if (body.getYhzcbs() != null) {
            detailvo.setYhzcbs(body.getYhzcbs());
            detailvo.setZzstsgl(body.getZzstsgl());
        }
        detailvo.setKce(body.getKce() == null ? null : getUFDoubleToBigDecimal(body.getKce()));
        // 简易征收
        if (body.getYhzcbs() != null) {
            detailvo.setYhzcbs(body.getYhzcbs());
        }
        detailvo.setZzstsgl(body.getZzstsgl());

        // motor 明细数据处理
        PInvoiceSDetail motor = new PInvoiceSDetail();
        motor.setCqzsbh(body.getCqzsbh());
        motor.setJzfwfsd(body.getJzfwfsd());
        motor.setJzxmmc(body.getJzxmmc());
        // **************************2024-07-10 新增   对应税务云,开票申请表体增加9个自定义项
        if (!StringUtils.isEmpty(body.getDef24())) {// CD 产地
            motor.setCd(body.getDef24());
        }

        if (!StringUtils.isEmpty(body.getDef25())) {// CJHM 车架号码!
            motor.setCjhm(body.getDef25());
        }

        if (!StringUtils.isEmpty(body.getDef26())) {// 车辆类型 CLLX
            motor.setCllx(body.getDef26());
        }

        if (!StringUtils.isEmpty(body.getDef27())) {// CPXH 厂牌型号
            motor.setCpxh(body.getDef27());
        }

        if (!StringUtils.isEmpty(body.getDef28())) {// SCQYMC 生产企业名称
            motor.setScqymc(body.getDef28());
        }

        if (!StringUtils.isEmpty(body.getDef29())) {// XCRS 限乘人数
            motor.setXcrs(body.getDef29());
        }

        if (!StringUtils.isEmpty(body.getDef17())) {//  HGZH 合格证号
            motor.setHgzh(body.getDef17());
        }

        if (!StringUtils.isEmpty(body.getDef17())) {//  HGZH 合格证号
            motor.setHgzh(body.getDef17());
        }

        if (!StringUtils.isEmpty(body.getDef20())) {//  FDJHM     发动机号码
            motor.setFdjhm(body.getDef20());
        }

        if (!StringUtils.isEmpty(body.getDef30())) {//  DUNWEI      吨位
            motor.setDunwei(body.getDef30());
        }


        detailvo.setDetailMotor(motor);
        //@特殊票种电子凭证@end
        return detailvo;
    }

    /**
     * 特殊票种发票信息转换
     *
     * @param tspzVOs
     * @param invoice
     * @return
     */
    private static PInvoice getPInvoiceByApplyTspz(IVTspzsBodyVO[] tspzVOs, PInvoice invoice) {
        List<PInvoiceTspz> tspzs = new ArrayList<PInvoiceTspz>();
        List<PInvoiceCepz> cepzs = new ArrayList<PInvoiceCepz>();
        for (IVTspzsBodyVO tspzVO : tspzVOs) {
            // 差额开票
            if (StringUtils.isNotEmpty(tspzVO.getPzlx()) && (IVAplocationZSFS.HCYY_CEZS.toStringValue().equals(invoice.getZsfs()) || IVAplocationZSFS.HCYY_QEZS.toStringValue().equals(invoice.getZsfs()))) {
                PInvoiceCepz cepz = new PInvoiceCepz();
                cepz.setXh(tspzVO.getXh());
                cepz.setPzlx(tspzVO.getPzlx());
                cepz.setFphm(tspzVO.getFphm());
                cepz.setFpdm(tspzVO.getFpdm());
                cepz.setZzfphm(tspzVO.getZzfphm());
                cepz.setPzhm(tspzVO.getPzhm());
                cepz.setKjrq(getFormatDate(tspzVO.getKjrq()));
                cepz.setHjje(tspzVO.getHjje() == null ? null : getUFDoubleToBigDecimal(tspzVO.getHjje()).setScale(2, UFDouble.ROUND_HALF_UP));
                cepz.setKce(tspzVO.getKce() == null ? null : getUFDoubleToBigDecimal(tspzVO.getKce()).setScale(2, UFDouble.ROUND_HALF_UP));
                cepz.setBz(tspzVO.getBz());
                cepz.setLy(tspzVO.getLy());
                cepz.setBckcje(tspzVO.getBckcje() == null ? null : getUFDoubleToBigDecimal(tspzVO.getBckcje()).setScale(2, UFDouble.ROUND_HALF_UP));
                cepz.setPzhjje(tspzVO.getPzhjje() == null ? null : getUFDoubleToBigDecimal(tspzVO.getPzhjje()).setScale(2, UFDouble.ROUND_HALF_UP));
                cepzs.add(cepz);
            }

            // 货物运输
            if (StringUtils.isNotEmpty(tspzVO.getYsgjzl()) && IVAWebConst.TSPZ_HWYS.equals(invoice.getTspz())) {
                PInvoiceTspz tspz = new PInvoiceTspz();
                tspz.setYsmxxh(tspzVO.getYsmxxh());
                tspz.setYsgjzl(tspzVO.getYsgjzl());
                tspz.setYsgjph(tspzVO.getYsgjph());
                tspz.setQyd(tspzVO.getQyd());
                tspz.setDdd(tspzVO.getDdd());
                tspz.setYshwmc(tspzVO.getYshwmc());
                tspzs.add(tspz);
            }

            // 旅客运输
            if (StringUtils.isNotEmpty(tspzVO.getCxr()) && IVAWebConst.TSPZ_LKYS.equals(invoice.getTspz())) {
                PInvoiceTspz tspz = new PInvoiceTspz();
                tspz.setCxrxh(tspzVO.getCxrxh());
                tspz.setCxr(tspzVO.getCxr());
                tspz.setChuxrq(getFormatDate(tspzVO.getChuxrq()));
                tspz.setCxrzjlxDm(tspzVO.getCxrzjlxdm());
                tspz.setSfzjhm(tspzVO.getSfzjhm());
                tspz.setCfd(tspzVO.getCfd());
                tspz.setLkddd(tspzVO.getLkddd());
                tspz.setZwdj(tspzVO.getZwdj());
                tspz.setJtgjlxDm(tspzVO.getJtgjlxdm());
                tspzs.add(tspz);
            }
        }

        if (tspzs.size() > 0) {
            invoice.setTspzs(tspzs.toArray(new PInvoiceTspz[0]));
        }
        if (cepzs.size() > 0) {
            invoice.setCepzs(cepzs.toArray(new PInvoiceCepz[0]));
        }
        return invoice;
    }

    /**
     * 根据开票申请明细转成成发票平台明细VO
     *
     * @param body
     * @return
     */
    private static PInvoiceDetail getPInvoiceByApplybody4Red(IVApplicationBodyVO body) {

        PInvoiceDetail detailvo = new PInvoiceDetail();

        detailvo.setXmmc(body.getXmmc());
        // 开票神申请规格型号自动截取40位长度
        detailvo.setGgxh((body.getGgxh() != null && body.getGgxh().length() > 40) ? body.getGgxh().substring(0, 40) : body.getGgxh());
        detailvo.setDw(body.getDw());
        detailvo.setXmsl(getUFDoubleToBigDecimal(body.getCaninvoice_xmsl()));
        detailvo.setZkhhh(body.getZkhhh());
        detailvo.setFphxz(body.getFphxz() == null ? IVAplocationFPXZ.FPXZ_ZCH.toIntValue() : body.getFphxz());
        detailvo.setHh(body.getHh());
        // detailvo.setXmdj(getUFDoubleToBigDecimal(body.getXmdj())); //存在含税和不含税单价，统一交由税务云反算
        // detailvo.setXmje(getUFDoubleToBigDecimal(body.getXmje()));//存在含税和不含税单价，统一交由税务云反算
        detailvo.setXmjshj(getUFDoubleToBigDecimal(body.getCaninvoice_xmjshj()).setScale(2, UFDouble.ROUND_HALF_UP));
        detailvo.setSl(getUFDoubleToBigDecimal(body.getSl()).multiply(new BigDecimal(0.01)));
        // detailvo.setSe(getUFDoubleToBigDecimal(body.getSe()));//存在含税和不含税单价，统一交由税务云反算
        if (body.getSsflbm() != null && body.getSsflbm().length() > 0) {
            // 传税收分类编码的开票
            detailvo.setSpbm(body.getSsflbm());
        } else {
            detailvo.setSpbm(body.getSpbm());
        }
        return detailvo;
    }

    /**
     * 根据平台发票开票后返回的数据获取来源id数组
     *
     * @param pinvoice
     * @return
     * @throws BusinessException
     */
    public static String[] getInvoiceApplyStatusCallBack(RequestInfo<InvoiceApplyStatusCallBackRequest> request)
            throws BusinessException {
        String[] lyidarr = null;
        String lyids = request.getData().getLyid();
        if (lyids != null && lyids.length() > 0) {
            lyidarr = lyids.split(IVAWebConst.IVA_LYID_SPLIT);
        }
        return lyidarr;
    }

    public static UFDouble getBigDecimalToUFDouble(BigDecimal in) {
        UFDouble out = new UFDouble(0.00);
        out = in == null ? new UFDouble(0.00) : new UFDouble(in);
        return out;
    }

    public static BigDecimal getUFDoubleToBigDecimal(UFDouble in) {
        BigDecimal out = new BigDecimal(0.00);
        out = in == null ? out : new BigDecimal(in.toString());
        return out;
    }

    /**
     * 获取开票日期
     *
     * @param kprq 税务云传递过来的开票日期
     * @return UFDate 转换后的开票日期
     */
    public static UFDate getUFDate(String kprq) {
        // 日期为空或长度不对，直接取当前日期
        if (kprq != null && kprq.length() == 10) {
            return new UFDate(kprq);
        }
        if (kprq == null || kprq.length() != 14) {
            return new UFDate();
        } else {
            StringBuffer date = new StringBuffer();
            date.append(kprq.substring(0, 4));
            date.append("-");
            date.append(kprq.substring(4, 6));
            date.append("-");
            date.append(kprq.substring(6, 8));
            date.append(" ");
            date.append(kprq.substring(8, 10));
            date.append(":");
            date.append(kprq.substring(10, 12));
            date.append(":");
            date.append(kprq.substring(12, 14));
            return new UFDateTime(date.toString()).getDate();
        }
    }


    public static UFDouble tranZeroAmount(UFDouble amount) {
        if (amount == null) {
            return UFDouble.ZERO_DBL;
        }
        amount = (amount.compareTo(UFDouble.ZERO_DBL) < 0) ? UFDouble.ZERO_DBL : amount;
        if (amount.abs().compareTo(new UFDouble(0.005)) < 0) {
            amount = UFDouble.ZERO_DBL;
        }
        return amount;
    }

    /**
     * 把UFDate转换成yyyy-MM-dd格式
     *
     * @param ufDate
     * @return
     */
    public static String getFormatDate(UFDate ufDate) {
        if (ufDate == null) {
            return null;
        }
        Date date = ufDate.toDate();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.format(date);
    }

}
