package cn.superdesk.uniorder.service.thirdpart.szhtxx.electronicInvoice.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.superdesk.uniorder.common.enums.common.CommonServiceNoEnum;
import cn.superdesk.uniorder.common.enums.common.CommonSoftDeleteEnum;
import cn.superdesk.uniorder.common.enums.common.CommonSourceFromEnum;
import cn.superdesk.uniorder.common.enums.invoice.InvoiceInvoicedIsRedWriteOffEnum;
import cn.superdesk.uniorder.common.enums.invoice.common.InvoiceTypeEnum;
import cn.superdesk.uniorder.common.enums.invoice.common.InvoiceTypeMoudelXModeEnum;
import cn.superdesk.uniorder.common.enums.invoice.common.PurchaserCompanyTypeEnum;
import cn.superdesk.uniorder.common.enums.invoice.customer.InvoiceApplyBecomeInvalidEnum;
import cn.superdesk.uniorder.common.enums.invoice.customer.InvoiceApplyCustomerBackAccountStatusEnum;
import cn.superdesk.uniorder.common.enums.thirdpart.szhtxx.electronicInvoice.*;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.common.numerical.*;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.security.JwtUtil;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.invoice.common.InvoiceType;
import cn.superdesk.uniorder.dao.entity.invoice.customer.InvoiceApply;
import cn.superdesk.uniorder.dao.entity.organisation.SysEnterprise;
import cn.superdesk.uniorder.dao.entity.sys.SysUser;
import cn.superdesk.uniorder.dao.entity.sys.notify.SysNotify;
import cn.superdesk.uniorder.dao.entity.thirdpart.szhtxx.electronicInvoice.*;
import cn.superdesk.uniorder.dao.mapper.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxMapper;
import cn.superdesk.uniorder.dao.mapper.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxMapperEx;
import cn.superdesk.uniorder.dto.param.thirdpart.szhtxx.common.singleBilling.SzhtxxInvoiceFptxxOpSingleBillingForm;
import cn.superdesk.uniorder.dto.param.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxOpSendEmailPdfAttachmentForm;
import cn.superdesk.uniorder.dto.param.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxQueryCriteria;
import cn.superdesk.uniorder.dto.param.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxXmxxQueryCriteria;
import cn.superdesk.uniorder.dto.vo.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxDetailVo;
import cn.superdesk.uniorder.dto.vo.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxHeadDataVo;
import cn.superdesk.uniorder.dto.vo.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxListItemVo;
import cn.superdesk.uniorder.dto.vo.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxXmxxListItemVo;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.electronicInvoice.dto.request.*;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.electronicInvoice.dto.response.DeliverResponse;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.electronicInvoice.dto.response.SingleBillingResponse;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.electronicInvoice.dto.response.SingleBillingResponseBody;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.electronicInvoice.dto.response.TaxInfoResponse;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.electronicInvoice.service.DeliverCallService;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.electronicInvoice.service.SingleBillingCallService;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.electronicInvoice.service.TaxInfoCallService;
import cn.superdesk.uniorder.service.invoice.common.InvoiceTypeService;
import cn.superdesk.uniorder.service.invoice.customer.InvoiceApplyCustomerService;
import cn.superdesk.uniorder.service.invoice.customer.state.*;
import cn.superdesk.uniorder.service.organisation.SysEnterpriseService;
import cn.superdesk.uniorder.service.sys.SysUserService;
import cn.superdesk.uniorder.service.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxExtendInfoService;
import cn.superdesk.uniorder.service.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxResultService;
import cn.superdesk.uniorder.service.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxService;
import cn.superdesk.uniorder.service.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxXmxxService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Author: linjinyu
 * @Email linjinyu@avic-s.com
 * @CreateDate: 2022-01-24 11:50:43
 * @UpdateUser: linjinyu
 * @UpdateDate: 2022-01-24 11:50:43
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class SzhtxxElectronicInvoiceFptxxServiceImpl implements SzhtxxElectronicInvoiceFptxxService {

    @Autowired
    private SzhtxxElectronicInvoiceFptxxMapper szhtxxElectronicInvoiceFptxxMapper;
    @Autowired
    private SzhtxxElectronicInvoiceFptxxMapperEx szhtxxElectronicInvoiceFptxxMapperEx;

    @Autowired
    private SzhtxxElectronicInvoiceFptxxExtendInfoService szhtxxElectronicInvoiceFptxxExtendInfoService;
    @Autowired
    private SzhtxxElectronicInvoiceFptxxResultService szhtxxElectronicInvoiceFptxxResultService;
    @Autowired
    private SzhtxxElectronicInvoiceFptxxXmxxService szhtxxElectronicInvoiceFptxxXmxxService;

    @Autowired
    private InvoiceApplyCustomerService invoiceApplyCustomerService;
    @Autowired
    private InvoiceApplyCustomerFieldMakeInvoiceStatusService invoiceApplyCustomerFieldMakeInvoiceStatusService;

    @Autowired
    private InvoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingOffLineService invoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingOffLineService;
    @Autowired
    private InvoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxElectronicInvoiceService invoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxElectronicInvoiceService;
    @Autowired
    private InvoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxPaperInvoiceService invoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxPaperInvoiceService;

    @Autowired
    private InvoiceApplyCustomerFieldBackAccountStatusService invoiceApplyCustomerFieldBackAccountStatusService;

    /**************************************** thirdpart service start ****************************************/

    /**
     * 1.1.1_单张开具接口
     */
    @Autowired
    private SingleBillingCallService singleBillingCallService;
    /**
     * 1.1.6_发票交付接口
     */
    @Autowired
    private DeliverCallService deliverCallService;
    /**
     * 1.1.7_金税盘信息查询接口
     */
    @Autowired
    private TaxInfoCallService taxInfoCallService;

    /**************************************** thirdpart service   end ****************************************/


    @Autowired
    private InvoiceTypeService invoiceTypeService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysEnterpriseService sysEnterpriseService;

    @Resource
    private Snowflake snowflake;


    /****************************************** extends BaseService 部分 start ******************************************/

    @Override
    public int insertSelective(SzhtxxElectronicInvoiceFptxx entity) {
        return szhtxxElectronicInvoiceFptxxMapper.insertSelective(entity);
    }

    @Override
    public int updateByPrimaryKeySelective(SzhtxxElectronicInvoiceFptxx entity) {
        return szhtxxElectronicInvoiceFptxxMapper.updateByPrimaryKeySelective(entity);
    }

    @Override
    public void deleteObj(Long id) {
    }

    @Override
    public SzhtxxElectronicInvoiceFptxx findById(Long id) {
        return szhtxxElectronicInvoiceFptxxMapper.selectByPrimaryKey(id);
    }

    @Override
    public PageInfo<SzhtxxElectronicInvoiceFptxx> findByPaging(Map<String, Object> conditions, Integer pageNun, Integer pageSize) {
        return null;
    }

    @Override
    public List<SzhtxxElectronicInvoiceFptxx> findAll(Map<String, Object> queryMap) {
        return null;
    }

    /****************************************** extends BaseService 部分   end ******************************************/


    @Override
    public int addSzhtxxElectronicInvoiceFptxx(SzhtxxElectronicInvoiceFptxx entity) {
        return szhtxxElectronicInvoiceFptxxMapper.insertSelective(entity);
    }

    @Override
    public int updateSzhtxxElectronicInvoiceFptxx(SzhtxxElectronicInvoiceFptxx entity) {

        SzhtxxElectronicInvoiceFptxx originEntity = szhtxxElectronicInvoiceFptxxMapper.selectByPrimaryKey(entity.getId());
//		AssertUtil.notNull(originEntity);
        AnBeanUtils.copy(entity, originEntity);
        return szhtxxElectronicInvoiceFptxxMapper.updateByPrimaryKeySelective(originEntity);
    }

    @Override
    public int updateSzhtxxElectronicInvoiceFptxxByPrimaryKeySelective(SzhtxxElectronicInvoiceFptxx entity) {

        return szhtxxElectronicInvoiceFptxxMapper.updateByPrimaryKeySelective(entity);
    }

    @Override
    public int deleteSzhtxxElectronicInvoiceFptxx(Long id) {
        return szhtxxElectronicInvoiceFptxxMapper.deleteByPrimaryKey(id);
    }

//	public int opPhysicsDelete(Long id, LoginSysUser loginSysUser){
//
//	}

    /**
     * FROM szhtxx_electronic_invoice_fptxx
     *
     * @param batchId
     * @param fpqqlsh
     * @param loginSysUser
     * @return
     */
    @Override
    public int opUpdateLogicalTemp2Normal(String batchId, String fpqqlsh, LoginSysUser loginSysUser) {

        SzhtxxElectronicInvoiceFptxxExample example = new SzhtxxElectronicInvoiceFptxxExample();
        SzhtxxElectronicInvoiceFptxxExample.Criteria criteria = example.createCriteria();

        criteria
                .andBatchIdEqualTo(batchId)
                .andFpqqlshEqualTo(fpqqlsh)
                .andDeletedEqualTo(CommonSoftDeleteEnum.临时.getKey());

        return szhtxxElectronicInvoiceFptxxMapper.updateByExampleSelective(
                SzhtxxElectronicInvoiceFptxx
                        .builder()
                        .deleted(CommonSoftDeleteEnum.正常.getKey())
                        .build(),
                example
        );

    }

    public int opLogicalDelete(String batchId, String fpqqlsh, LoginSysUser loginSysUser) {

        SzhtxxElectronicInvoiceFptxxExample example = new SzhtxxElectronicInvoiceFptxxExample();
        SzhtxxElectronicInvoiceFptxxExample.Criteria criteria = example.createCriteria();

        criteria
                .andFpqqlshEqualTo(fpqqlsh)
                .andDeletedEqualTo(CommonSoftDeleteEnum.正常.getKey())
                .andBatchIdNotEqualTo(batchId);

        return szhtxxElectronicInvoiceFptxxMapper.updateByExampleSelective(
                SzhtxxElectronicInvoiceFptxx.builder().deleted(CommonSoftDeleteEnum.删除.getKey()).build(),
                example
        );

    }

    @Override
    public SzhtxxElectronicInvoiceFptxx findSzhtxxElectronicInvoiceFptxxById(Long id) {

        SzhtxxElectronicInvoiceFptxx entity = szhtxxElectronicInvoiceFptxxMapper.selectByPrimaryKey(id);
//		AssertUtil.notNull(entity);
        return entity;
    }

    /**
     * 场景用于 深圳航信电子发票
     *
     * @param fpqqlsh
     * @return
     */
    @Override
    public SzhtxxElectronicInvoiceFptxx findByFpqqlsh(String fpqqlsh) {

        return findByFpqqlshAndDeleted(fpqqlsh, CommonSoftDeleteEnum.正常);

    }

    @Override
    public SzhtxxElectronicInvoiceFptxx findByFpqqlshAndDeleted(String fpqqlsh, CommonSoftDeleteEnum commonSoftDeleteEnum) {

        SzhtxxElectronicInvoiceFptxxExample example = new SzhtxxElectronicInvoiceFptxxExample();
        SzhtxxElectronicInvoiceFptxxExample.Criteria criteria = example.createCriteria();

        criteria
                .andFpqqlshEqualTo(fpqqlsh)
                .andDeletedEqualTo(commonSoftDeleteEnum.getKey());

        List<SzhtxxElectronicInvoiceFptxx> resultList = szhtxxElectronicInvoiceFptxxMapper.selectByExample(example);

        if (CollUtil.isNotEmpty(resultList)) {
            return resultList.get(0);
        } else {
            return null;
        }

    }

    /**
     * 场景用于 深圳航信纸质发票
     *
     * @param fpqqlsh
     * @param batchId
     * @return
     */
    @Override
    public SzhtxxElectronicInvoiceFptxx findByFpqqlshAndBatchId(String fpqqlsh, String batchId) {

        SzhtxxElectronicInvoiceFptxxExample example = new SzhtxxElectronicInvoiceFptxxExample();
        SzhtxxElectronicInvoiceFptxxExample.Criteria criteria = example.createCriteria();

        criteria
                .andFpqqlshEqualTo(fpqqlsh)
                .andBatchIdEqualTo(batchId);

        List<SzhtxxElectronicInvoiceFptxx> resultList = szhtxxElectronicInvoiceFptxxMapper.selectByExample(example);

        if (CollUtil.isNotEmpty(resultList)) {
            return resultList.get(0);
        } else {
            return null;
        }
    }

    @Override
    public R<List<SzhtxxElectronicInvoiceFptxx>> pageQuery(Map<String, Object> conditions, int pageNun, int pageSize) {

        SzhtxxElectronicInvoiceFptxxExample example = new SzhtxxElectronicInvoiceFptxxExample();
        SzhtxxElectronicInvoiceFptxxExample.Criteria criteria = example.createCriteria();

        // TODO 喜欢用Map 还是 Bean 自己喜欢... 后期添加 转 SzhtxxElectronicInvoiceFptxxExample.Criteria
        // SzhtxxElectronicInvoiceFptxx szhtxxElectronicInvoiceFptxxConditions = BeanUtils.mapToBean(conditions,SzhtxxElectronicInvoiceFptxx.class);

        PageHelper.startPage(pageNun, pageSize);
        List<SzhtxxElectronicInvoiceFptxx> resultList = szhtxxElectronicInvoiceFptxxMapper.selectByExample(example);
        PageInfo<SzhtxxElectronicInvoiceFptxx> page = new PageInfo<SzhtxxElectronicInvoiceFptxx>(resultList);
        PageHelper.clearPage();

        return new R<List<SzhtxxElectronicInvoiceFptxx>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), resultList);

    }

    @Override
    public R<List<SzhtxxElectronicInvoiceFptxxListItemVo>> pageQueryGenericParam(SzhtxxElectronicInvoiceFptxxQueryCriteria queryCriteria, LoginSysUser loginSysUser) {

        PageHelper.startPage(queryCriteria.getPageNumber(), queryCriteria.getPageSize());
        List<SzhtxxElectronicInvoiceFptxxListItemVo> resultList = queryGenericParam(queryCriteria, loginSysUser);
        PageInfo<SzhtxxElectronicInvoiceFptxxListItemVo> page = new PageInfo<SzhtxxElectronicInvoiceFptxxListItemVo>(resultList);
        PageHelper.clearPage();

        return new R<List<SzhtxxElectronicInvoiceFptxxListItemVo>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), resultList);

    }


    @Override
    public List<SzhtxxElectronicInvoiceFptxxListItemVo> queryGenericParam(SzhtxxElectronicInvoiceFptxxQueryCriteria queryCriteria, LoginSysUser loginSysUser) {

        List<SzhtxxElectronicInvoiceFptxxListItemVo> resultList = szhtxxElectronicInvoiceFptxxMapperEx.pageQueryGenericParam(queryCriteria);

        additionalInfoSzhtxxElectronicInvoiceFptxxListItemVo(resultList);

        // 修正数据 不要打开
//        @ApiModelProperty(value = "需修正标记:0-正常;1-修正;")
//        private Integer needReviseMark;
//        patchRevise(resultList);


        return resultList;
    }

    @Override
    public SzhtxxElectronicInvoiceFptxxListItemVo queryOneByFpqqlsh(String fpqqlsh, LoginSysUser loginSysUser) {

        List<SzhtxxElectronicInvoiceFptxxListItemVo> resultList = queryGenericParam(SzhtxxElectronicInvoiceFptxxQueryCriteria
                .builder()
                .fpqqlsh(fpqqlsh)
                .build(), loginSysUser);

        if (CollUtil.isNotEmpty(resultList)) {
            return resultList.get(0);
        } else {
            return null;
        }

    }

    /**
     * 补丁程序 修正数据
     * patchRevise
     * patchReviseMark
     *
     * @param resultList
     */
    @Deprecated
    private void patchRevise(List<SzhtxxElectronicInvoiceFptxxListItemVo> resultList) {

        if (CollUtil.isEmpty(resultList)) {
            return;
        }


        // szhtxx_electronic_invoice_fptxx_extend_info 后加表的问题
        resultList.forEach(fptxxListItemVo -> {

            String invoiceApplySn = "";
            // 先是简单判定

            /******************************************** szhtxx_electronic_invoice_fptxx_extend_info start ********************************************/

//            @ApiModelProperty("bill_sent_sign - 交付标志^_^0-不交付;1-交付邮箱;2-交付手机;3-手机邮箱都交付;默认:0")
//            private String  billSentSignName;
//            @ApiModelProperty("状态回调地址^_^为空时不回调,不为空时回调,若提供的接收回调地址有误,则最多回调三次,回调成功需返回格式{returnCode:`0000`,returnMsg:`原因`}其他都视为失败")
//            private String  pdfUrlOriginal;
//            @ApiModelProperty("状态回调地址^_^为空时不回调,不为空时回调,若提供的接收回调地址有误,则最多回调三次,回调成功需返回格式{returnCode:`0000`,returnMsg:`原因`}其他都视为失败")
//            private String  pdfUrlSaved;
//            @ApiModelProperty("ghfqylx - 购货方企业类型^_^购货方企业类型`01, 02`代表企业,两者没区别,`03` 代表个人")
//            private String  ghfqylxName;
//            @ApiModelProperty("kplx - 开票类型^_^开票类型(1-蓝票;2-红票;10-特殊冲红)")
//            private String  kplxName;
//            @ApiModelProperty("qd_bz - 清单标志^_^0-普通电子发票;1-普通电子发票(清单);2-收购电子发票;3-收购电子发票(清单);4-成品油电子发票(成品油无清单);备注:默认为0;1,3-清单是指强制清单;0,2-如果超出8行自动打印清单;4-成品油,则商品明细行不能有其他商品,一个商品是成品油,另一个不是成品油,开不出来票.并且成品油的发票的商品行中,单价;数量;单位必填,其中单位为升或者吨")
//            private String  qdBzName;
//            @ApiModelProperty("后台操作人员备注")
//            private String  remark2;
//            @ApiModelProperty("红冲原因")
//            private String  reasonRedWrite;
//            @ApiModelProperty("是否红冲:0-否;1-是;")
//            private Integer isRedWriteOff;
//            @ApiModelProperty("是否红冲:0-否;1-是;")
//            private String  isRedWriteOffName;
//
//            @ApiModelProperty(value = "原/红冲发票号")
//            private String  productManagerRequirementsBlueOrRedInvoiceNumber;
//            @ApiModelProperty(value = "原/红冲发票代码")
//            private String  productManagerRequirementsBlueOrRedInvoiceCode;
//            @ApiModelProperty(value = "报送状态:0-未报送;1-已报送;-1报送失败")
//            private Integer pushedOutStatus;
//            @ApiModelProperty(value = "报送状态:0-未报送;1-已报送;-1报送失败; 引用 enum SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum")
//            private String  pushedOutStatusName;
//            @ApiModelProperty(value = "send过去分词 sent 邮件状态:0-未发送;1-已发送;")
//            private Integer sentEmailStatus;
//            @ApiModelProperty(value = "send过去分词 sent 邮件状态:0-未发送;1-已发送; 引用 enum SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum")
//            private String  sentEmailStatusName;

            /******************************************** szhtxx_electronic_invoice_fptxx_extend_info   end ********************************************/

//            UPDATE `szhtxx_electronic_invoice_fptxx_extend_info`
//            SET
//	`product_manager_requirements_blue_or_red_invoice_number`='',
//    `product_manager_requirements_blue_or_red_invoice_code`=''
//            WHERE 1


            // 如果它是个红 关键信息 如果这两个字段 isNotBlank 时, record的为 `红票`
            if (StrUtil.isNotBlank(fptxxListItemVo.getYfpDm()) && StrUtil.isNotBlank(fptxxListItemVo.getYfpHm())) {

                // 要找回蓝票信息 更新 isRedWriteOff
                // 为什么要截呢?
                // 因为 红票与蓝票是共用 Fpqqlsh 差异点是红票尾部多个R
                // CIA2022032341918464
                // CIA2022032341918464R

                String fpqqlshBlue = StrUtil.sub(fptxxListItemVo.getFpqqlsh(), 0, fptxxListItemVo.getFpqqlsh().length() - 1);
                invoiceApplySn = fpqqlshBlue;


//                SzhtxxElectronicInvoiceFptxxExtendInfo extendInfoBlue  = szhtxxElectronicInvoiceFptxxExtendInfoService.findByFpqqlsh(fpqqlshBlue);
                SzhtxxElectronicInvoiceFptxxResult fptxxResultBlue = szhtxxElectronicInvoiceFptxxResultService.findByFpqqlsh(fpqqlshBlue);


                szhtxxElectronicInvoiceFptxxExtendInfoService.saveOrUpdateByFpqqlsh(
                        SzhtxxElectronicInvoiceFptxxExtendInfo
                                .builder()
                                .fpqqlsh(fpqqlshBlue)
                                .isRedWriteOff(InvoiceInvoicedIsRedWriteOffEnum.是.getKey())
                                // 反向更新
                                .productManagerRequirementsBlueOrRedInvoiceCode(fptxxListItemVo.getFpdm())
                                .productManagerRequirementsBlueOrRedInvoiceNumber(fptxxListItemVo.getFphm())

                                .build()
                );

//                红票的情况
                fptxxListItemVo.setPushedOutStatus(SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum.已报送.getKey());
                fptxxListItemVo.setSentEmailStatus(SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum.已发送.getKey());

                if (ObjectUtil.isNotNull(fptxxListItemVo.getRedReason()) && fptxxListItemVo.getRedReason().compareTo(0) == 0) {
                    fptxxListItemVo.setRedReason(SzhtxxElectronicInvoiceFptxxRedReasonEnum.销售折让.getKey());
                }

                // 修 开票申请 回款状态 -> 发票红冲
                InvoiceApply invoiceApplyCustomer = invoiceApplyCustomerService.findByInvoiceApplySn(fpqqlshBlue, JwtUtil.getLoginSysUserBackendRoot());
                if (ObjectUtil.isNotNull(invoiceApplyCustomer)) {
                    if (invoiceApplyCustomer.getBackAccountStatus().compareTo(InvoiceApplyCustomerBackAccountStatusEnum.发票红冲.getKey()) != 0) {
                        invoiceApplyCustomerFieldBackAccountStatusService.opRedWriteByStateMachine(
                                fpqqlshBlue,
                                LoginSysUser
                                        .builder()
                                        .sysUserId(invoiceApplyCustomer.getBackAccountUserId())
                                        .build()
                        );
                    }
                }


            }
            // 如果它是个蓝
            else {

                // 要找回蓝票信息 更新 isRedWriteOff

                String fpqqlshRed = fptxxListItemVo.getFpqqlsh() + "R";
                invoiceApplySn = fptxxListItemVo.getFpqqlsh();

//                SzhtxxElectronicInvoiceFptxx           fptxxRed           = findByFpqqlsh(fpqqlshRed);
//                SzhtxxElectronicInvoiceFptxxExtendInfo fptxxExtendInfoRed = szhtxxElectronicInvoiceFptxxExtendInfoService.findByFpqqlsh(fpqqlshRed);
                SzhtxxElectronicInvoiceFptxxResult fptxxResultRed = szhtxxElectronicInvoiceFptxxResultService.findByFpqqlsh(fpqqlshRed);

                // 判定有没有红票
                if (ObjectUtil.isNotNull(fptxxResultRed)) {

                    szhtxxElectronicInvoiceFptxxExtendInfoService.saveOrUpdateByFpqqlsh(
                            SzhtxxElectronicInvoiceFptxxExtendInfo
                                    .builder()
                                    .fpqqlsh(fptxxResultRed.getFpqqlsh())
                                    .productManagerRequirementsBlueOrRedInvoiceCode(fptxxListItemVo.getFpdm())
                                    .productManagerRequirementsBlueOrRedInvoiceNumber(fptxxListItemVo.getFphm())
                                    .build()
                    );
                }

                fptxxListItemVo.setPushedOutStatus(SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum.已报送.getKey());
                fptxxListItemVo.setSentEmailStatus(SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum.已发送.getKey());


            }

            if (ObjectUtil.isNull(fptxxListItemVo.getInvReason())) {
                fptxxListItemVo.setInvReason(SzhtxxElectronicInvoiceFptxxInvReasonEnum.无理由.getKey());
            }

            /**************************************** 产品经理要的逻辑 start ****************************************/

            if (ObjectUtil.isNull(fptxxListItemVo.getIsRedWriteOff())) {
                fptxxListItemVo.setIsRedWriteOff(InvoiceInvoicedIsRedWriteOffEnum.否.getKey());
            }
//            fptxxListItemVo.setIsRedWriteOffName(InvoiceInvoicedIsRedWriteOffEnum.get(fptxxListItemVo.getIsRedWriteOff()).getDesc());

//            if (ObjectUtil.isNull(fptxxListItemVo.getPushedOutStatus())) {
//                fptxxListItemVo.setPushedOutStatus(SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum.未报送.getKey());
//            }
//            if (ObjectUtil.isNull(fptxxListItemVo.getSentEmailStatus())) {
//                fptxxListItemVo.setSentEmailStatus(SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum.未发送.getKey());
//            }
//            // 再修个数据 开票种类 = 电子普通发票 开票方式 = 深圳航信电子发票
//            if (ObjectUtil.isNotNull(fptxxListItemVo.getInvoiceApplyId())
//                    && ObjectUtil.isNotNull(fptxxListItemVo.getInvoiceMode())
//                    && fptxxListItemVo.getInvoiceApplyId().equals(1)
//                    && fptxxListItemVo.getInvoiceMode().equals(InvoiceTypeMoudelXModeEnum.深圳航信电子发票.getKey())) {
//                fptxxListItemVo.setPushedOutStatus(SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum.已报送.getKey());
//                fptxxListItemVo.setSentEmailStatus(SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum.已发送.getKey());
//            }


//            fptxxListItemVo.setPushedOutStatusName(SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum.get(fptxxListItemVo.getPushedOutStatus()).getDesc());
//            fptxxListItemVo.setSentEmailStatusName(SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum.get(fptxxListItemVo.getSentEmailStatus()).getDesc());

            /**************************************** 产品经理要的逻辑 start ****************************************/

            SzhtxxElectronicInvoiceFptxxExtendInfo extendInfo = SzhtxxElectronicInvoiceFptxxExtendInfo.builder()
                    .fpqqlsh(fptxxListItemVo.getFpqqlsh())
                    .billSentSignName(SzhtxxElectronicInvoiceFptxxBillSentSignEnum.get(AnIntegerUtils.getInteger(fptxxListItemVo.getBillSentSign())).getDesc())
//                    .pdfUrlOriginal("")
//                    .pdfUrlSaved("")
                    .ghfqylxName(PurchaserCompanyTypeEnum.getByPurchaserCompanyType(fptxxListItemVo.getGhfqylx()).getPurchaserCompanyTypeName())
                    .kplxName(SzhtxxElectronicInvoiceFptxxKplxEnum.get(AnIntegerUtils.getInteger(fptxxListItemVo.getKplx())).getDesc())
                    .qdBzName(SzhtxxElectronicInvoiceFptxxQdBzEnum.get(AnIntegerUtils.getInteger(fptxxListItemVo.getQdBz())).getDesc())
                    .remark2(fptxxListItemVo.getRemark2())
//                    .reasonRedWrite(form.getReason())

//                    .isRedWriteOff(InvoiceInvoicedIsRedWriteOffEnum.否.getKey())
//                    .productManagerRequirementsBlueOrRedInvoiceCode(fptxxListItemVo.getYfpDm())
//                    .productManagerRequirementsBlueOrRedInvoiceNumber(fptxxListItemVo.getYfpHm())

                    .pushedOutStatus(fptxxListItemVo.getPushedOutStatus())
                    .sentEmailStatus(fptxxListItemVo.getSentEmailStatus())

//                    .updateTime(DateUtil.date())
//                    .updateUserId(loginSysUser.getSysUserId())
//                    .updateUserName(loginSysUser.getFullName())
                    .deleted(CommonSoftDeleteEnum.正常.getKey())
                    .invoiceApplySn(invoiceApplySn)
//                    .batchId(batchId)
                    .build();

            int ret = szhtxxElectronicInvoiceFptxxExtendInfoService.saveOrUpdateByFpqqlsh(extendInfo);

            updateByPrimaryKeySelective(SzhtxxElectronicInvoiceFptxx
                    .builder()
                    .id(fptxxListItemVo.getId())
                    .invoiceType(SzhtxxElectronicInvoiceFptxxInvoiceTypeEnum.电子票.getKey())
                    .invReason(fptxxListItemVo.getInvReason())
                    .redReason(fptxxListItemVo.getRedReason())
                    .build()
            );


        });

    }

    /**
     * 附加信息
     *
     * @param resultList
     */
    private void additionalInfoSzhtxxElectronicInvoiceFptxxListItemVo(List<SzhtxxElectronicInvoiceFptxxListItemVo> resultList) {

        if (CollUtil.isEmpty(resultList)) {
            return;
        }

        List<Long> sysUserIds = new ArrayList<>();

//		List<Long> applyUserIds              = resultList.stream().filter(o -> o.getApplyUserId() != null).filter(AnLamdaUtils.distinctByKey(o -> o.getApplyUserId())).map(o -> o.getApplyUserId()).collect(Collectors.toList());
//		List<Long> auditUserIds              = resultList.stream().filter(o -> o.getAuditUserId() != null).filter(AnLamdaUtils.distinctByKey(o -> o.getAuditUserId())).map(o -> o.getAuditUserId()).collect(Collectors.toList());
//		List<Long> invoiceProgressingUserIds = resultList.stream().filter(o -> o.getInvoiceProgressingUserId() != null).filter(AnLamdaUtils.distinctByKey(o -> o.getInvoiceProgressingUserId())).map(o -> o.getInvoiceProgressingUserId()).collect(Collectors.toList());
//		List<Long> makeInvoiceUserIds        = resultList.stream().filter(o -> o.getMakeInvoiceUserId() != null).filter(AnLamdaUtils.distinctByKey(o -> o.getMakeInvoiceUserId())).map(o -> o.getMakeInvoiceUserId()).collect(Collectors.toList());
//		List<Long> receiveInvoiceUserIds     = resultList.stream().filter(o -> o.getReceiveInvoiceUserId() != null).filter(AnLamdaUtils.distinctByKey(o -> o.getReceiveInvoiceUserId())).map(o -> o.getReceiveInvoiceUserId()).collect(Collectors.toList());
//		List<Long> mailTickUserIds           = resultList.stream().filter(o -> o.getMailTickUserId() != null).filter(AnLamdaUtils.distinctByKey(o -> o.getMailTickUserId())).map(o -> o.getMailTickUserId()).collect(Collectors.toList());
        List<Long> backAccountUserIds = resultList.stream().filter(o -> o.getBackAccountUserId() != null).filter(AnLamdaUtils.distinctByKey(o -> o.getBackAccountUserId())).map(o -> o.getBackAccountUserId()).collect(Collectors.toList());
        List<Long> updateUserIds = resultList.stream().filter(o -> o.getUpdateUserId() != null).filter(AnLamdaUtils.distinctByKey(o -> o.getUpdateUserId())).map(o -> o.getUpdateUserId()).collect(Collectors.toList());
        List<Long> extendInfoOpUpdateUserIds = resultList.stream().filter(o -> o.getExtendInfoOpUpdateUserId() != null).filter(AnLamdaUtils.distinctByKey(o -> o.getExtendInfoOpUpdateUserId())).map(o -> o.getExtendInfoOpUpdateUserId()).collect(Collectors.toList());
        List<Long> becomeInvalidUserIds = resultList.stream().filter(o -> o.getBecomeInvalidUserId() != null).filter(AnLamdaUtils.distinctByKey(o -> o.getBecomeInvalidUserId())).map(o -> o.getBecomeInvalidUserId()).collect(Collectors.toList());


//		sysUserIds.addAll(applyUserIds);
//		sysUserIds.addAll(auditUserIds);
//		sysUserIds.addAll(invoiceProgressingUserIds);
//		sysUserIds.addAll(makeInvoiceUserIds);
//		sysUserIds.addAll(receiveInvoiceUserIds);
//		sysUserIds.addAll(mailTickUserIds);
        sysUserIds.addAll(backAccountUserIds);
        sysUserIds.addAll(updateUserIds);
        sysUserIds.addAll(extendInfoOpUpdateUserIds);
        sysUserIds.addAll(becomeInvalidUserIds);

        sysUserIds = sysUserIds.stream().distinct().collect(Collectors.toList());
        log.info("\n{}", JSONUtil.toJsonStr(sysUserIds));
        Map<Long, SysUser> sysUserMap = sysUserService.convertSysUserIds2MapSysUserId2Entity(sysUserIds);

        List<Long> outVirtIds = resultList.stream().map(SzhtxxElectronicInvoiceFptxxListItemVo::getOutVirtId).distinct().collect(Collectors.toList());
        Map<Long, SysEnterprise> sysEnterpriseMap = sysEnterpriseService.findByOutVirtIdsConvertKV(outVirtIds);

        // 统一订单
        Map<Long, InvoiceType> invoiceTypeMap = invoiceTypeService.convertToMapFieldId2Entity();

        for (SzhtxxElectronicInvoiceFptxxListItemVo vo : resultList) {

            /**************************************** 统一订单业务流程逻辑 start ****************************************/

            // 补状态名称
//			vo.setAuditStatusName(InvoiceApplyAuditStatusEnum.getDesc(vo.getAuditStatus()));
//			vo.setInvoiceProgressingStatusName(InvoiceApplyCustomerInvoiceProgressingStatusEnum.getDesc(vo.getInvoiceStatus()));
//			vo.setMakeInvoiceStatusName(InvoiceApplyCustomerMakeInvoiceStatusEnum.getDesc(vo.getMakeInvoiceStatus()));
//			vo.setReceiveInvoiceStatusName(InvoiceApplyCustomerReceiveInvoiceStatusEnum.getDesc(vo.getReceiveInvoiceStatus()));
//			vo.setMailTickStatusName(InvoiceApplyCustomerMailTickStatusEnum.getDesc(vo.getMailTickStatus()));
            vo.setBackAccountStatusName(InvoiceApplyCustomerBackAccountStatusEnum.getDesc(vo.getBackAccountStatus()));

            /**************************************** 统一订单业务流程逻辑 start ****************************************/

            /**************************************** 深圳航信电子发票属性 start ****************************************/

            if (StrUtil.isNotBlank(vo.getKplx())) {
                vo.setKplxName(SzhtxxElectronicInvoiceFptxxKplxEnum.get(AnIntegerUtils.getInteger(vo.getKplx())).getDesc());
            }
            if (StrUtil.isNotBlank(vo.getBillSentSign())) {
                vo.setBillSentSignName(SzhtxxElectronicInvoiceFptxxBillSentSignEnum.get(AnIntegerUtils.getInteger(vo.getBillSentSign())).getDesc());
            }
            if (StrUtil.isNotBlank(vo.getGhfqylx())) {
                vo.setGhfqylxName(PurchaserCompanyTypeEnum.getByPurchaserCompanyType(vo.getGhfqylx()).getPurchaserCompanyTypeName());
            }
            if (StrUtil.isNotBlank(vo.getQdBz())) {
                vo.setQdBzName(SzhtxxElectronicInvoiceFptxxQdBzEnum.get(AnIntegerUtils.getInteger(vo.getQdBz())).getDesc());

            }


            if (ObjectUtil.isNull(vo.getInvoiceType())) {
                vo.setInvoiceType(SzhtxxElectronicInvoiceFptxxInvoiceTypeEnum.电子票.getKey());
            }
            vo.setInvoiceTypeName(SzhtxxElectronicInvoiceFptxxInvoiceTypeEnum.get(vo.getInvoiceType()).getDesc());

            if (ObjectUtil.isNotNull(vo.getRedReason()) && vo.getRedReason().compareTo(0) != 0) {
                vo.setRedReasonName(SzhtxxElectronicInvoiceFptxxRedReasonEnum.get(vo.getRedReason()).getDesc());
            }

            if (ObjectUtil.isNull(vo.getInvReason())) {
                vo.setInvReason(SzhtxxElectronicInvoiceFptxxInvReasonEnum.无理由.getKey());
            }
            vo.setInvReasonName(SzhtxxElectronicInvoiceFptxxInvReasonEnum.get(vo.getInvReason()).getDesc());

            /**************************************** 深圳航信电子发票属性 start ****************************************/


            /**************************************** 产品经理要的逻辑 start ****************************************/

            if (ObjectUtil.isNull(vo.getIsRedWriteOff())) {
                vo.setIsRedWriteOff(InvoiceInvoicedIsRedWriteOffEnum.否.getKey());
            }
            vo.setIsRedWriteOffName(InvoiceInvoicedIsRedWriteOffEnum.get(vo.getIsRedWriteOff()).getDesc());

            if (ObjectUtil.isNull(vo.getPushedOutStatus())) {
                vo.setPushedOutStatus(SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum.未报送.getKey());
            }
            // 再修个数据 开票种类 = 电子普通发票 开票方式 = 深圳航信电子发票
//            if (vo.getInvoiceApplyId().equals(1) && vo.getInvoiceMode().equals(InvoiceTypeMoudelXModeEnum.深圳航信电子发票.getKey())) {
//                vo.setPushedOutStatus(SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum.已报送.getKey());
//            }

            if (ObjectUtil.isNull(vo.getSentEmailStatus())) {
                vo.setSentEmailStatus(SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum.未发送.getKey());
            }
            vo.setPushedOutStatusName(SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum.get(vo.getPushedOutStatus()).getDesc());
            vo.setSentEmailStatusName(SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum.get(vo.getSentEmailStatus()).getDesc());

            /**************************************** 作废标志 start ****************************************/

            if (ObjectUtil.isNull(vo.getFlagVoidSign())) {
                vo.setFlagVoidSign(InvoiceApplyBecomeInvalidEnum.未作废.getKey());
            }
            vo.setFlagVoidSignName(InvoiceApplyBecomeInvalidEnum.get(vo.getFlagVoidSign()).getDesc());

            /**************************************** 产品经理要的逻辑   end ****************************************/


//			.pdfUrlOriginal("")
//			.pdfUrlSaved("")

            // yyyyMMddHHmmss yyyy年MM月dd日
            vo.setKprqFormat(DateUtil.parse(vo.getKprq(), "yyyyMMddHHmmss").toString("yyyy年MM月dd日"));

            if (ObjectUtil.isNotNull(vo.getBecomeInvalidTime())) {
                vo.setBecomeInvalidTimeFormat(DateUtil.date(vo.getBecomeInvalidTime()).toString("yyyy年MM月dd日"));
            }


//			if (ObjectUtil.isNotNull(vo.getAccountingOrderInvoiceStatus())) {
//				vo.setAccountingOrderInvoiceStatusName(AccountingOrderInvoiceApplyStatusEnum.get(vo.getAccountingOrderInvoiceStatus()).getDesc());
//			}

            // 补 开票方式
            if (ObjectUtil.isNotNull(vo.getInvoiceMode())) {
                vo.setInvoiceModeName(InvoiceTypeMoudelXModeEnum.get(vo.getInvoiceMode()).getDesc());
            } else {
                vo.setInvoiceModeName("异常");
            }

            // 补 发票种类
            if (invoiceTypeMap.get(AnLongUtils.getLong(vo.getInvoiceTypeId())) != null) {
                vo.setInvoiceTypeIdName(invoiceTypeMap.get(AnLongUtils.getLong(vo.getInvoiceTypeId())).getTypeName());
            } else {
                vo.setInvoiceTypeIdName("异常");
            }

            // 补 企业信息
            if (ObjectUtil.isNotNull(sysEnterpriseMap.get(vo.getOutVirtId()))) {
                vo.setOutVirtName(sysEnterpriseMap.get(vo.getOutVirtId()).getEnterpriseName());
            } else {
                vo.setOutVirtName("异常");
            }

            /**************************************** mark by linjinyu at 20220516 v2.3 start ****************************************/

            // 补 订单类型-订单来源-引用enum CommonServiceNoEnum
            if (ObjectUtil.isNotNull(vo.getServiceNo())) {
                vo.setServiceNoName(CommonServiceNoEnum.getByServiceNo(vo.getServiceNo()).getServiceName());
            } else {
                vo.setServiceNoName(CommonServiceNoEnum.UNKNOW.getServiceName());
            }
            // 补 操作来源-引用enum CommonSourceFromEnum
            if (ObjectUtil.isNotNull(vo.getSourceFrom())) {
                vo.setSourceFromName(CommonSourceFromEnum.getBySourceFromCode(vo.getSourceFrom()).getSourceFromName());
            } else {
                vo.setSourceFromName(CommonSourceFromEnum.UNKNOW.getSourceFromName());
            }

            /**************************************** mark by linjinyu at 20220516 v2.3 start ****************************************/


            // 补人员信息
//			if (sysUserMap.get(vo.getApplyUserId()) != null) {
//				vo.setApplyUserName(sysUserMap.get(vo.getApplyUserId()).getFullname());
//			}
//			if (sysUserMap.get(vo.getAuditUserId()) != null) {
//				vo.setAuditUserName(sysUserMap.get(vo.getAuditUserId()).getFullname());
//			}
//			if (sysUserMap.get(vo.getInvoiceProgressingUserId()) != null) {
//				vo.setInvoiceProgressingUserName(sysUserMap.get(vo.getInvoiceProgressingUserId()).getFullname());
//			}
//			if (sysUserMap.get(vo.getMakeInvoiceUserId()) != null) {
//				vo.setMakeInvoiceUserName(sysUserMap.get(vo.getMakeInvoiceUserId()).getFullname());
//			}
//			if (sysUserMap.get(vo.getReceiveInvoiceUserId()) != null) {
//				vo.setReceiveInvoiceUserName(sysUserMap.get(vo.getReceiveInvoiceUserId()).getFullname());
//			}
//			if (sysUserMap.get(vo.getMailTickUserId()) != null) {
//				vo.setMailTickUserName(sysUserMap.get(vo.getMailTickUserId()).getFullname());
//			}
            if (sysUserMap.get(vo.getBackAccountUserId()) != null) {
                vo.setBackAccountUserName(sysUserMap.get(vo.getBackAccountUserId()).getFullname());
            }
            if (sysUserMap.get(vo.getUpdateUserId()) != null) {
                vo.setUpdateUserName(sysUserMap.get(vo.getUpdateUserId()).getFullname());
            }
            if (sysUserMap.get(vo.getExtendInfoOpUpdateUserId()) != null) {
                vo.setExtendInfoOpUpdateUserName(sysUserMap.get(vo.getExtendInfoOpUpdateUserId()).getFullname());
            }
            if (sysUserMap.get(vo.getBecomeInvalidUserId()) != null) {
                vo.setBecomeInvalidUserName(sysUserMap.get(vo.getBecomeInvalidUserId()).getFullname());
            }

        }
    }

    @Override
    public SzhtxxElectronicInvoiceFptxxHeadDataVo headDataGenericParam(SzhtxxElectronicInvoiceFptxxQueryCriteria queryCriteria, LoginSysUser loginSysUser) {
        return szhtxxElectronicInvoiceFptxxMapperEx.headDataGenericParam(queryCriteria);
    }

    @Override
    public SzhtxxElectronicInvoiceFptxxDetailVo detailGenericParam(SzhtxxElectronicInvoiceFptxxQueryCriteria queryCriteria, LoginSysUser loginSysUser) {

        SzhtxxElectronicInvoiceFptxxListItemVo fptxx = null;
        List<SzhtxxElectronicInvoiceFptxxXmxxListItemVo> xmxx = new ArrayList<>();

        /****************************************** 发票主体信息 start ******************************************/

        List<SzhtxxElectronicInvoiceFptxxListItemVo> pageFptxxList = queryGenericParam(queryCriteria, loginSysUser);
        if (CollUtil.isEmpty(pageFptxxList)) {
            return SzhtxxElectronicInvoiceFptxxDetailVo.builder().build();
        } else {
            fptxx = pageFptxxList.get(0);
        }

        /****************************************** 发票主体信息   end ******************************************/

        /****************************************** 发票项目信息 start ******************************************/

        xmxx = szhtxxElectronicInvoiceFptxxXmxxService.queryGenericParam(
                SzhtxxElectronicInvoiceFptxxXmxxQueryCriteria
                        .builder()
                        .fpqqlsh(fptxx.getFpqqlsh())
                        .build(),
                loginSysUser
        );

        /****************************************** 发票项目信息   end ******************************************/


        return SzhtxxElectronicInvoiceFptxxDetailVo.builder()
                .fptxx(fptxx)
                .xmxx(xmxx)
                .build();
    }

    /****************************************** 记录 start ******************************************/


    /**************************************** 金税盘页面-发起-op红冲发票(电子普通发票)(深圳航信电子票) start ****************************************/

    /**
     * op发起红冲
     * 在上一层已经实现
     *
     * @param form
     * @param loginSysUser
     * @return
     */
//    public SingleBillingRequestBodyKpContent opRedWritePre(SzhtxxInvoiceFptxxOpSingleBillingForm form, LoginSysUser loginSysUser) {
//        return SingleBillingRequestBodyKpContent.builder().build();
//    }

    /**
     * op确认红冲
     *
     * @param form
     * @param fptxxListItemVo
     * @param invoiceApplyEntity
     * @param loginSysUser
     * @return
     */
    @Override
    public SysNotify opRedWrite(
            SzhtxxInvoiceFptxxOpSingleBillingForm form,
            SzhtxxElectronicInvoiceFptxxListItemVo fptxxListItemVo,
            InvoiceApply invoiceApplyEntity,
            LoginSysUser loginSysUser) {

        DateTime now = DateUtil.date();

        Map<Long, InvoiceType> invoiceTypeMap = invoiceTypeService.convertToMapFieldId2Entity();

        // 开票方式
        switch (InvoiceTypeMoudelXModeEnum.get(invoiceApplyEntity.getInvoiceMode())) {
            case 线下开票:


//				InvoiceApply forUpdate = new InvoiceApply();
//				forUpdate.setId(entity.getId());
//
//				// TODO 更新状态逻辑...
//
//				forUpdate.setInvoiceStatus(InvoiceApplyCustomerInvoiceProgressingStatusEnum.待开票.getKey());
//				forUpdate.setInvoiceProgressingUserId(loginSysUser.getSysUserId());
//				forUpdate.setInvoiceProgressingTime(now);
//
//				forUpdate.setMakeInvoiceStatus(InvoiceApplyCustomerMakeInvoiceStatusEnum.开票中.getKey());
//				forUpdate.setMakeInvoiceUserId(loginSysUser.getSysUserId());
//				forUpdate.setMakeInvoiceTime(now);
//
//				forUpdate.setUpdateUserId(loginSysUser.getSysUserId());
//				forUpdate.setUpdateTime(now);
//
//				invoiceApplyCustomerService.updateInvoiceApplyByPrimaryKeySelective(forUpdate);

                return SysNotify.builder()
                        .title(SzhtxxElectronicInvoiceResponseCodeEnum.SUCCESS.getReturnCode())
                        .content("金税盘红冲只能用于`深圳航信电子发票`")
                        .build();

            case 深圳航信电子发票:

                // 发票类型
                switch (InvoiceTypeEnum.get(invoiceApplyEntity.getInvoiceType())) {

                    case 电子普通发票:

                        log.info("opOngoingByStateMachine\n{}\n{}",
                                invoiceTypeMap.get(invoiceApplyEntity.getInvoiceType()).getTypeName(),
                                InvoiceTypeMoudelXModeEnum.get(invoiceApplyEntity.getInvoiceMode()).getDesc()
                        );

                        SingleBillingRequestBodyKpContent kpContent = invoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxElectronicInvoiceService
                                .opOngoingInvoiceTypeEq1InvoiceModeEqSzhtxxElectronicInvoiceRedWrite(
                                        form,
                                        fptxxListItemVo,
                                        invoiceApplyEntity,
                                        loginSysUser
                                );

                        SingleBillingRequest request = SingleBillingRequest
                                .builder()
                                .kpContent(kpContent)
                                .build();

                        SingleBillingResponse response = singleBillingCallService.callSingleBillingApi(request);

//			            {"returnCode":"1007","returnMsg":"000000100_CIA2022030892364288税额计算有误！","datas":null}
                        if (response.getReturnCode().equals(SzhtxxElectronicInvoiceResponseCodeEnum.SUCCESS.getReturnCode())) {

                            // 记录 红冲 作为新的记录
                            record(form, kpContent, response, loginSysUser);

                            InvoiceApply forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice = new InvoiceApply();
                            forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setId(invoiceApplyEntity.getId());

                            // TODO 更新状态逻辑... 这里是红冲


                            /**************************************** 深圳航信电子票-op红冲发票-逻辑说明20220511 start ****************************************/
                            /**
                             1. 深圳航信电子票-op红冲发票 后不是一口气打通的，在发票申请管理哪还得有一个操作，好像是叫 重新开票，op重新开票pre那有检验这个蓝票是否已红冲


                             forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setInvoiceStatus(InvoiceApplyCustomerInvoiceProgressingStatusEnum.已红冲.getKey());
                             forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setInvoiceProgressingUserId(loginSysUser.getSysUserId());
                             forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setInvoiceProgressingTime(now);

                             //	forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setMakeInvoiceStatus(InvoiceApplyCustomerMakeInvoiceStatusEnum.已开票.getKey());
                             //	forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setMakeInvoiceUserId(loginSysUser.getSysUserId());
                             //	forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setMakeInvoiceTime(now);
                             //
                             //	forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setReceiveInvoiceStatus(InvoiceApplyCustomerReceiveInvoiceStatusEnum.已领票.getKey());
                             //	forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setReceiveInvoiceUserId(loginSysUser.getSysUserId());
                             //	forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setReceiveInvoiceTime(now);
                             //	forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setInvoiceNumber(response.getDatas().getFphm());
                             //
                             //	forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setMailTickStatus(InvoiceApplyCustomerMailTickStatusEnum.已邮寄.getKey());
                             //	forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setMailTickUserId(loginSysUser.getSysUserId());
                             //	forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setMailTickTime(now);

                             forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setBackAccountStatus(InvoiceApplyCustomerBackAccountStatusEnum.发票红冲.getKey());
                             forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setBackAccountUserId(loginSysUser.getSysUserId());
                             forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setBackAccountTime(now);

                             // forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setRemark2();

                             forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setUpdateUserId(loginSysUser.getSysUserId());
                             forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice.setUpdateTime(now);

                             invoiceApplyCustomerService.updateInvoiceApplyByPrimaryKeySelective(forUpdateInvoiceTypeEq1InvoiceModeSzhtxxElectronicInvoice);
                             */

                            return SysNotify.builder()
                                    .title(response.getReturnCode())
                                    .content(response.getReturnMsg())
//									.messageBody(response.getReturnMsg())
                                    .build();
                        } else {
                            return SysNotify.builder()
                                    .title(response.getReturnCode())
                                    .content(response.getReturnMsg())
//									.messageBody(response.getReturnMsg())
                                    .build();
                        }

                    case 纸质专用发票:

                        return SysNotify.builder()
                                .title("0001")
                                .content("该发票种类无此开票方式")
                                .build();
                    case 纸质普通发票:

                        return SysNotify.builder()
                                .title("0001")
                                .content("该发票种类无此开票方式")
                                .build();
                    case 电子专用发票:

                        return SysNotify.builder()
                                .title("0001")
                                .content("该发票种类无此开票方式")
                                .build();
                    default:
                        return SysNotify.builder()
                                .title("0001")
                                .content("该发票种类无此开票方式")
                                .build();
                }


            default:
                return SysNotify.builder()
                        .title("0001")
                        .content("该发票种类无此开票方式")
                        .build();
        }
    }


    /**************************************** 金税盘页面-发起-op红冲发票(电子普通发票)(深圳航信电子票)   end ****************************************/


    /**
     * 深圳航信电子票 记录
     * TODO 简单实现 有空再优化 mark by linjinyu at 20220308
     * 成功才记录
     *
     * @param form
     * @param kpContent
     * @param response
     */
    @Override
    public void record(
            SzhtxxInvoiceFptxxOpSingleBillingForm form,
            SingleBillingRequestBodyKpContent kpContent,
            SingleBillingResponse response,
            LoginSysUser loginSysUser) {

        String batchId = snowflake.nextIdStr();
        String fpqqlsh = kpContent.getFptxx().getFpqqlsh();

        opLogicalDelete(batchId, fpqqlsh, loginSysUser);
        szhtxxElectronicInvoiceFptxxXmxxService.opLogicalDelete(batchId, fpqqlsh, loginSysUser);
        szhtxxElectronicInvoiceFptxxResultService.opLogicalDelete(batchId, fpqqlsh, loginSysUser);

        SzhtxxElectronicInvoiceFptxx fptxx = processSzhtxxElectronicInvoiceFptxx(batchId, form, kpContent.getFptxx(), response, loginSysUser);
        SzhtxxElectronicInvoiceFptxxExtendInfo fptxxExtendInfo = processSzhtxxElectronicInvoiceFptxxExtendInfo(batchId, form, kpContent.getFptxx(), response, loginSysUser);
        List<SzhtxxElectronicInvoiceFptxxXmxx> fptxxXmxxList = processSzhtxxElectronicInvoiceFptxxXmxx(batchId, form, fpqqlsh, kpContent.getXmxx(), loginSysUser);
        SzhtxxElectronicInvoiceFptxxResult fptxxResult = processSzhtxxElectronicInvoiceFptxxResult(batchId, form, fpqqlsh, response, loginSysUser);

        // TODO 要不要延迟呢?

        SzhtxxElectronicInvoiceFptxxListItemVo fptxxListItemVo = queryOneByFpqqlsh(fpqqlsh, loginSysUser);

        // 【后端部分完成-20220318-对映文档-2. 积分结算-2.7 金税盘发票-部分整理-20220318】
        // https://www.tapd.cn/33003868/prong/stories/view/1133003868001004003
        // 2.7.6.3.3.11 【确认红冲】
        // 无需调用深圳航信电子发票“发票交付接口”推送发票到购买方的邮箱中；
        if (fptxx.getKplx().equals(AnStringUtils.getString(SzhtxxElectronicInvoiceFptxxKplxEnum.正常发票.getKey()))) {


            if (SzhtxxElectronicInvoiceFptxxBillSentSignEnum.交付邮箱.getKey().compareTo(AnIntegerUtils.getInteger(fptxx.getBillSentSign())) == 0
                    && StrUtil.isNotBlank(fptxx.getGhfEmail())) {

                SzhtxxElectronicInvoiceFptxxExtendInfo extendInfo = SzhtxxElectronicInvoiceFptxxExtendInfo.builder()
                        .fpqqlsh(fptxx.getFpqqlsh())
                        .sentEmailStatus(SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum.已发送.getKey())
                        .build();

                int ret = szhtxxElectronicInvoiceFptxxExtendInfoService.saveOrUpdateByFpqqlsh(extendInfo);

            }

            /**************************************** 调用 深圳航信电子票 1.1.6_发票交付接口 start ****************************************/

            // 补刀
            // op发起开票-深圳航信电子票返回成功后-延迟60秒-调用深圳航信电子票-1.1.6_发票交付接口
            // 如果成功会更新金税盘对映流水号发票的
            // [邮件状态]已发送
            ThreadUtil.execAsync(new Runnable() {

                @Override
                public void run() {

                    // 延迟 60s
                    ThreadUtil.sleep(60000);

                    // 调用 发票交付接口
                    callDeliverApi(
                            SzhtxxElectronicInvoiceFptxxOpSendEmailPdfAttachmentForm
                                    .builder()
                                    .fpqqlsh(fpqqlsh)
                                    .targetEmail(fptxx.getGhfEmail())
                                    .build(),
                            fptxxListItemVo,
                            loginSysUser
                    );
                }
            });

            /**************************************** 调用 深圳航信电子票 1.1.6_发票交付接口   end ****************************************/

            /**************************************** 调用 深圳航信电子票 保存发票pdf start ****************************************/

            ThreadUtil.execAsync(new Runnable() {
                @Override
                public void run() {

                    // 延迟 180s
                    // 延迟 6s
                    ThreadUtil.sleep(6000);

                    szhtxxElectronicInvoiceFptxxResultService.savedPdfUrl(fptxxListItemVo, loginSysUser);
                }
            });

            /**************************************** 调用 深圳航信电子票 保存发票pdf   end ****************************************/
        }


    }

    private SzhtxxElectronicInvoiceFptxx processSzhtxxElectronicInvoiceFptxx(String batchId, SzhtxxInvoiceFptxxOpSingleBillingForm form, SingleBillingRequestBodyKpContentFptxxVo fptxxVo, SingleBillingResponse response, LoginSysUser loginSysUser) {


        SzhtxxElectronicInvoiceFptxx fptxx = SzhtxxElectronicInvoiceFptxx.builder()
                .batchId(batchId)
                .fpqqlsh(fptxxVo.getFpqqlsh())
                .kpxm(fptxxVo.getKpxm())
                .xhfNsrsbh(fptxxVo.getXhfNsrsbh())
                .xhfmc(fptxxVo.getXhfmc())
                .xhfDzdh(fptxxVo.getXhfDzdh())
                .xhfYhzh(fptxxVo.getXhfYhzh())
                .ghfmc(fptxxVo.getGhfmc())
                .ghfNsrsbh(fptxxVo.getGhfNsrsbh())
                .ghfYhzh(fptxxVo.getGhfYhzh())
                .ghfDzdh(fptxxVo.getGhfDzdh())
                .ghfSj(fptxxVo.getGhfSj())
                .ghfEmail(fptxxVo.getGhfEmail())
                .billSentSign(fptxxVo.getBillSentSign())
                .callBackUrl(fptxxVo.getCallBackUrl())
                .ghfqylx(fptxxVo.getGhfqylx())
                .dkbz(fptxxVo.getDkbz())
                .fjh(fptxxVo.getFjh())
                .kpy(fptxxVo.getKpy())
                .sky(fptxxVo.getSky())
                .fhr(fptxxVo.getFhr())
                .kplx(fptxxVo.getKplx())
                .yfpDm(fptxxVo.getYfpDm())
                .yfpHm(fptxxVo.getYfpHm())
                .qdBz(fptxxVo.getQdBz())
                .qdxmmc(fptxxVo.getQdxmmc())
                .kphjje(AnBigDecimalUtils.getBigDecimal(fptxxVo.getKphjje()))
                .hjbhsje(AnBigDecimalUtils.getBigDecimal(fptxxVo.getHjbhsje()))
                .hjse(AnBigDecimalUtils.getBigDecimal(fptxxVo.getHjse()))

//                .bz(fptxxVo.getBz())// 修改
                .bz(form.getBz()) // 前端交互

                /**************************************** 接口变动 20220323 start ****************************************/

                .invoiceType(fptxxVo.getInvoiceType())
                // 开据理由
//                .invReason(fptxxVo.getInvReason()) // 修改
                .invReason(form.getInvReason()) // 前端交互

                // 红冲时才会有
//                .redReason(fptxxVo.getRedReason()) // 修改
                .redReason(form.getRedReason()) // 前端交互

                .blueInvDate(fptxxVo.getBlueInvDate()) // 原蓝字发票的开具日期^_^redReason不为空时，则要求填写原蓝字发票的开具日期，格式:yyyyMMdd, 如:20211230注:如果原开票软件中原蓝票的开票时间不一致时，则以开票软件的为准，不作不一致的提示。

                /**************************************** 妈的，改错地方 - 问题处理 - 蓝字发票时间长度不合法 start ****************************************/

//                【【结算中心-测试环境】积分结算-金税盘发票-【深圳航信电子发票】红冲发票-【确认红冲】，提示“蓝字发票时间长度不合法”】
//                https://www.tapd.cn/33003868/bugtrace/bugs/view?bug_id=1133003868001005077
                // mark by linjinyu at 20220509

                // 他喵的不统一 这里要处理一下 数据库的为 yyyyMMddHHmmss
//                .blueInvDate(DateUtil.parse(fptxxVo.getBlueInvDate(), "yyyyMMddHHmmss").toString("yyyyMMdd"))

                /**************************************** 妈的，改错地方 - 问题处理 - 蓝字发票时间长度不合法 start ****************************************/


                .blueInvKind(fptxxVo.getBlueInvKind())

                /**************************************** 接口变动 20220323   end ****************************************/

                .returnCode(response.getReturnCode())
                .returnMsg(response.getReturnMsg())

                .createTime(DateUtil.date())
                .createUserId(loginSysUser.getSysUserId())
                .createUserName(loginSysUser.getFullName())
                .updateTime(DateUtil.date())
                .updateUserId(loginSysUser.getSysUserId())
                .updateUserName(loginSysUser.getFullName())
                .deleted(CommonSoftDeleteEnum.正常.getKey())
                .build();


//		SzhtxxElectronicInvoiceFptxx fptxxExistDb =

        addSzhtxxElectronicInvoiceFptxx(fptxx);

        return fptxx;
    }

    private SzhtxxElectronicInvoiceFptxxExtendInfo processSzhtxxElectronicInvoiceFptxxExtendInfo(
            String batchId,
            SzhtxxInvoiceFptxxOpSingleBillingForm form,
            SingleBillingRequestBodyKpContentFptxxVo fptxxVo,
            SingleBillingResponse response,
            LoginSysUser loginSysUser) {

        // TODO 处理 红票时要更新蓝票的 isRedWriteOff 字段


        String invoiceApplySn = "";

        InvoiceInvoicedIsRedWriteOffEnum isRedWriteOff = InvoiceInvoicedIsRedWriteOffEnum.否;
        SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum sentEmailStatus = SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum.未发送;
        SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum pushedOutStatus = SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum.未报送;

        // 关键信息 如果这两个字段 isNotBlank 时, record的为 `红票`
        // 红票情况
        if (StrUtil.isNotBlank(fptxxVo.getYfpDm()) && StrUtil.isNotBlank(fptxxVo.getYfpHm())) {

            // 要找回蓝票信息 更新 isRedWriteOff

            // 为什么要截呢?
            // 因为 红票与蓝票是共用 Fpqqlsh 差异点是红票尾部多个R
            // CIA2022032341918464
            // CIA2022032341918464R
            String fpqqlshBlue = StrUtil.sub(fptxxVo.getFpqqlsh(), 0, fptxxVo.getFpqqlsh().length() - 1);

            invoiceApplySn = fpqqlshBlue;
            isRedWriteOff = InvoiceInvoicedIsRedWriteOffEnum.是;
            sentEmailStatus = SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum.未发送;
            pushedOutStatus = SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum.未报送;

            SzhtxxElectronicInvoiceFptxxExtendInfo extendInfoBlue = szhtxxElectronicInvoiceFptxxExtendInfoService.findByFpqqlsh(fpqqlshBlue);

            szhtxxElectronicInvoiceFptxxExtendInfoService.saveOrUpdateByFpqqlsh(
                    SzhtxxElectronicInvoiceFptxxExtendInfo
                            .builder()

                            .fpqqlsh(extendInfoBlue.getFpqqlsh())

                            .isRedWriteOff(InvoiceInvoicedIsRedWriteOffEnum.是.getKey())

                            .productManagerRequirementsBlueOrRedInvoiceCode(response.getDatas().getFpdm())
                            .productManagerRequirementsBlueOrRedInvoiceNumber(response.getDatas().getFphm())

                            .updateUserId(loginSysUser.getSysUserId())
                            .updateUserName(loginSysUser.getFullName())
                            .updateTime(DateUtil.date())

                            .build()
            );

            // 如果是红冲发票 更新 发票申请的 回款状态 回款登记人 回款登记时间
            invoiceApplyCustomerFieldBackAccountStatusService.opRedWriteByStateMachine(fpqqlshBlue, loginSysUser);

        }
        // 蓝票情况
        else {
            invoiceApplySn = fptxxVo.getFpqqlsh();
        }

        SzhtxxElectronicInvoiceFptxxExtendInfo extendInfo = SzhtxxElectronicInvoiceFptxxExtendInfo.builder()
                .fpqqlsh(fptxxVo.getFpqqlsh())

                .pdfUrlOriginal("")
                .pdfUrlSaved("")

                .billSentSignName(SzhtxxElectronicInvoiceFptxxBillSentSignEnum.get(AnIntegerUtils.getInteger(fptxxVo.getBillSentSign())).getDesc())
                .ghfqylxName(PurchaserCompanyTypeEnum.getByPurchaserCompanyType(fptxxVo.getGhfqylx()).getPurchaserCompanyTypeName())
                .kplxName(SzhtxxElectronicInvoiceFptxxKplxEnum.get(AnIntegerUtils.getInteger(fptxxVo.getKplx())).getDesc())
                .qdBzName(SzhtxxElectronicInvoiceFptxxQdBzEnum.get(AnIntegerUtils.getInteger(fptxxVo.getQdBz())).getDesc())

                .remark2(form.getReason())
                .reasonRedWrite(form.getReason())
                .isRedWriteOff(InvoiceInvoicedIsRedWriteOffEnum.否.getKey())

                .productManagerRequirementsBlueOrRedInvoiceCode(fptxxVo.getYfpDm())
                .productManagerRequirementsBlueOrRedInvoiceNumber(fptxxVo.getYfpHm())

                .sentEmailStatus(SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum.未发送.getKey())
                .pushedOutStatus(SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum.已报送.getKey())

//                .becomeInvalidReason("")
//                .becomeInvalidUserId()
//                .becomeInvalidUserName()
//                .becomeInvalidTime()
                .flagVoidSign(InvoiceApplyBecomeInvalidEnum.未作废.getKey())

                .updateTime(DateUtil.date())
                .updateUserId(loginSysUser.getSysUserId())
                .updateUserName(loginSysUser.getFullName())

                .deleted(CommonSoftDeleteEnum.正常.getKey())
                .batchId(batchId)
                .invoiceApplySn(invoiceApplySn)
                .build();

        int ret = szhtxxElectronicInvoiceFptxxExtendInfoService.saveOrUpdateByFpqqlsh(extendInfo);

        return extendInfo;
    }

    private List<SzhtxxElectronicInvoiceFptxxXmxx> processSzhtxxElectronicInvoiceFptxxXmxx(String batchId, SzhtxxInvoiceFptxxOpSingleBillingForm form, String fpqqlsh, List<SingleBillingRequestBodyKpContentXmxxItemVo> xmxxItemVoList, LoginSysUser loginSysUser) {

        List<SzhtxxElectronicInvoiceFptxxXmxx> fptxxXmxxList = new ArrayList<>();

        xmxxItemVoList.forEach(xmxxVo -> {

            SzhtxxElectronicInvoiceFptxxXmxx xmxx = SzhtxxElectronicInvoiceFptxxXmxx.builder()
                    .batchId(batchId)
                    .fpqqlsh(fpqqlsh)
                    .xmmc(xmxxVo.getXmmc())
                    .xmdw(xmxxVo.getXmdw())
                    .ggxh(xmxxVo.getGgxh())
                    .xmsl(AnBigDecimalUtils.getBigDecimal(xmxxVo.getXmsl())) // 对错字段
                    .hsbz(xmxxVo.getHsbz())
                    .xmdj(xmxxVo.getXmdj())
                    .fphxz(xmxxVo.getFphxz())
                    .spbm(xmxxVo.getSpbm())
                    .yhzcbs(xmxxVo.getYhzcbs())
                    .lslbs(xmxxVo.getLslbs())
                    .zzstsgl(xmxxVo.getZzstsgl())
                    .kce(AnBigDecimalUtils.getBigDecimal(xmxxVo.getKce()))
                    .xmje(AnBigDecimalUtils.getBigDecimal(xmxxVo.getXmje()))
                    .sl(xmxxVo.getSl())
                    .se(AnBigDecimalUtils.getBigDecimal(xmxxVo.getSe()))
                    .deleted(CommonSoftDeleteEnum.正常.getKey())
                    .build();
            fptxxXmxxList.add(xmxx);

        });

        szhtxxElectronicInvoiceFptxxXmxxService.insertBatch(fptxxXmxxList);

        return fptxxXmxxList;
    }

    private SzhtxxElectronicInvoiceFptxxResult processSzhtxxElectronicInvoiceFptxxResult(String batchId, SzhtxxInvoiceFptxxOpSingleBillingForm form, String fpqqlsh, SingleBillingResponse response, LoginSysUser loginSysUser) {

        SingleBillingResponseBody datas = response.getDatas();

        SzhtxxElectronicInvoiceFptxxResult fptxxResult = SzhtxxElectronicInvoiceFptxxResult.builder()
                .batchId(batchId)
                .fpqqlsh(fpqqlsh)
                .hjbhsje(AnBigDecimalUtils.getBigDecimal(datas.getHjbhsje()))
                .hjse(AnBigDecimalUtils.getBigDecimal(datas.getHjse()))
                .kprq(datas.getKprq())
                .fpdm(datas.getFpdm())
                .fphm(datas.getFphm())
                .pdfUrl(datas.getPdfUrl())
                .jym(datas.getJym())
                .ssyf(datas.getSsyf())
                .fjh(datas.getFjh())
                .ewm(datas.getEwm())
                .szqm(datas.getSzqm())
                .returnCode(response.getReturnCode())
                .returnMsg(response.getReturnMsg())
                .createTime(DateUtil.date())
                .createUserId(loginSysUser.getSysUserId())
                .createUserName(loginSysUser.getFullName())
                .updateTime(DateUtil.date())
                .updateUserId(loginSysUser.getSysUserId())
                .updateUserName(loginSysUser.getFullName())
                .deleted(CommonSoftDeleteEnum.正常.getKey())
                .build();

        szhtxxElectronicInvoiceFptxxResultService.addSzhtxxElectronicInvoiceFptxxResult(fptxxResult);

        return fptxxResult;
    }

    /**************************************** 调用深圳航信电子票 start ****************************************/

    @Override
    public SysNotify callDeliverApi(SzhtxxElectronicInvoiceFptxxOpSendEmailPdfAttachmentForm form, SzhtxxElectronicInvoiceFptxxListItemVo fptxxListItemVo, LoginSysUser loginSysUser) {

        if (ObjectUtil.isNull(fptxxListItemVo)) {
            return SysNotify.builder()
                    .title("9999") // 魔法数值 待修正 mark by linjinyu at 20220329
                    .content("参数为空")
                    .build();
        }

        String fpqqlsh = fptxxListItemVo.getFpqqlsh();

        DeliverRequestBodyInvoiceContent invoiceContent = DeliverRequestBodyInvoiceContent
                .builder()
                .sjly("09") // 数据来源
                .jflx(SzhtxxElectronicInvoiceFptxxBillSentSignEnum.交付邮箱.getKey().toString()) // 交付类型 1-邮箱;2-短信
                .jfdz(form.getTargetEmail()) // 交付地址
                .fpDm(fptxxListItemVo.getFpdm()) // 发票代码
                .fpHm(fptxxListItemVo.getFphm()) // 发票号码
                .xsfNsrsbh(fptxxListItemVo.getXhfNsrsbh()) // 销售方纳税人识别号
                .gmfNsrsbh(fptxxListItemVo.getGhfNsrsbh()) // 购货方纳税人识别号
                .gmfMc(fptxxListItemVo.getGhfmc()) // 购货方名称
                // {"returnCode":"2034","returnMsg":"代码:044032000111,号码:21983804的发票,开票日期不是yyyyMMdd格式,不允许交付(20220328144335)","datas":null}
                .kprq(DateUtil.parse(fptxxListItemVo.getKprq(), "yyyyMMddHHmmss").toString("yyyyMMdd")) // 开票日期
                .hjje(AnStringUtils.getString(fptxxListItemVo.getHjbhsje())) // 合计不含税金额
                .hjse(AnStringUtils.getString(fptxxListItemVo.getHjse())) // 合计税额
                .jym(fptxxListItemVo.getJym()) // 校验码
                // TODO 深圳航信的人还没有回复 mark by linjinyu at 20220329
                .tsbz("0") // 推送标识 0-不需要推送交付结果;1-需要推送交付结果
                .tsdz("") // 推送地址
                .build();

        DeliverResponse response = deliverCallService.callDeliverApi(DeliverRequest
                .builder()
                .invoiceContent(invoiceContent)
                .build());

//        {"returnCode":"1000","returnMsg":"交付成功","datas":{"serialNum":"ufqf.yrs.ntkhg.g2hzsgwg5acs8.cxv","returnCode":"1000","returnMsg":"交付成功","fphm":null,"fpdm":null}}
        if (response.getReturnCode().equals(SzhtxxElectronicInvoiceResponseCodeEnum.SUCCESS.getReturnCode())
                || response.getReturnCode().equals("1000")) {

            /**************************************** 更新邮件状态 start ****************************************/

            szhtxxElectronicInvoiceFptxxExtendInfoService.saveOrUpdateByFpqqlsh(
                    SzhtxxElectronicInvoiceFptxxExtendInfo
                            .builder()
                            .fpqqlsh(fpqqlsh)

                            /**************************************** 更新内容 start ****************************************/

                            .updateTime(DateUtil.date())
//                              .updateUserId()
//                              .updateUserName()
                            .sentEmailStatus(SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum.已发送.getKey())
//                            .pushedOutStatus(SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum.已报送.getKey())

                            /**************************************** 更新内容 start ****************************************/

                            .build()
            );

            /**************************************** 更新邮件状态   end ****************************************/


            return SysNotify.builder()
                    .title(response.getReturnCode())
                    .content(response.getReturnMsg())
                    .build();
        } else {
            return SysNotify.builder()
                    .title(response.getReturnCode())
                    .content(response.getReturnMsg())
                    .build();
        }
    }

    @Override
    public SysNotify callTaxInfoApi(String nsrsbh, LoginSysUser loginSysUser) {

        TaxInfoResponse response = taxInfoCallService.callTaxInfoApi(TaxInfoRequest
                .builder()
                .goldTaxDev(TaxInfoRequestBody
                        .builder()
                        .nsrsbh(nsrsbh)
                        .fjh("") // fjh 分机号 int 4 是 空:查询所有分机; 查询指定分机传入正确的分机号
                        .qysj("") // qysj 启用时间 varchar 8 否 格式:YYYMMDD 为空时查询所有;不 为空时查询此时间后 启动的金税盘信息
                        .fpzlDm("51") // 目前对接的只有 51
                        .build())
                .build());


        if (response.getReturnCode().equals(SzhtxxElectronicInvoiceResponseCodeEnum.SUCCESS.getReturnCode())) {

            return SysNotify.builder()
                    .title(response.getReturnCode())
                    .content(response.getReturnMsg())
                    .build();
        } else {


            return SysNotify.builder()
                    .title(response.getReturnCode())
                    .content(response.getReturnMsg())
                    .build();
        }
    }

    /**************************************** 调用深圳航信电子票   end ****************************************/

}
