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

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.superdesk.uniorder.common.enums.common.CommonSoftDeleteEnum;
import cn.superdesk.uniorder.common.enums.invoice.InvoiceInvoicedIsRedWriteOffEnum;
import cn.superdesk.uniorder.common.enums.invoice.customer.InvoiceApplyBecomeInvalidEnum;
import cn.superdesk.uniorder.common.enums.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxKplxEnum;
import cn.superdesk.uniorder.common.enums.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxPushedOutStatusEnum;
import cn.superdesk.uniorder.common.enums.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxSentEmailStatusEnum;
import cn.superdesk.uniorder.common.enums.thirdpart.szhtxx.paperInvoice.SzhtxxPaperInvoiceUsedEnum;
import cn.superdesk.uniorder.common.numerical.AnBigDecimalUtils;
import cn.superdesk.uniorder.common.numerical.AnStringUtils;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxx;
import cn.superdesk.uniorder.dao.entity.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxExtendInfo;
import cn.superdesk.uniorder.dao.entity.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxResult;
import cn.superdesk.uniorder.dao.entity.thirdpart.szhtxx.electronicInvoice.SzhtxxElectronicInvoiceFptxxXmxx;
import cn.superdesk.uniorder.dto._constant.ResourceConstant;
import cn.superdesk.uniorder.dto.param.thirdpart.szhtxx.common.singleBilling.SzhtxxInvoiceFptxxOpSingleBillingForm;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.paperInvoice.dto.request.SID1SingleBilling.SID1SingleBillingRequestBody;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.paperInvoice.dto.request.SID1SingleBilling.SID1SingleBillingRequestBodyKpContentFptxxVo;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.paperInvoice.dto.request.SID1SingleBilling.SID1SingleBillingRequestBodyKpContentXmxxItemVo;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.paperInvoice.dto.response.SID1SingleBilling.SID1SingleBillingResponseBody;
import cn.superdesk.uniorder.openapicall.thirdpart.szhtxx.paperInvoice.dto.response.SID1SingleBilling.SID1SingleBillingResponseBodyEncmsgVo;
import cn.superdesk.uniorder.service.invoice.customer.InvoiceApplyCustomerService;
import cn.superdesk.uniorder.service.invoice.customer.InvoiceApplyXGoodsService;
import cn.superdesk.uniorder.service.invoice.customer.state.InvoiceApplyCustomerFieldBackAccountStatusService;
import cn.superdesk.uniorder.service.invoice.customer.state.InvoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxElectronicInvoiceService;
import cn.superdesk.uniorder.service.invoice.customer.state.InvoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxPaperInvoiceService;
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 cn.superdesk.uniorder.service.thirdpart.szhtxx.paperInvoice.SzhtxxPaperInvoiceFptxxLogService;
import cn.superdesk.uniorder.service.thirdpart.szhtxx.paperInvoice.SzhtxxPaperInvoiceFptxxSID1SingleBillingProcessService;
import cn.superdesk.uniorder.service.thirdpart.szhtxx.paperInvoice.SzhtxxPaperInvoiceRedTaxInfoService;
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;

@Slf4j
@Service
public class SzhtxxPaperInvoiceFptxxSID1SingleBillingProcessServiceImpl implements SzhtxxPaperInvoiceFptxxSID1SingleBillingProcessService {

    @Resource
    private Snowflake snowflake;

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

    @Autowired
    private SzhtxxPaperInvoiceRedTaxInfoService szhtxxPaperInvoiceRedTaxInfoService;

    @Autowired
    private SzhtxxPaperInvoiceFptxxLogService szhtxxPaperInvoiceFptxxLogService;

    @Autowired
    public  InvoiceApplyCustomerService invoiceApplyCustomerService;
    @Autowired
    private InvoiceApplyXGoodsService   invoiceApplyXGoodsService;

    @Autowired
    private InvoiceApplyCustomerFieldBackAccountStatusService                                 invoiceApplyCustomerFieldBackAccountStatusService;
    @Autowired
    private InvoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxElectronicInvoiceService invoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxElectronicInvoiceService;
    @Autowired
    private InvoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxPaperInvoiceService      invoiceApplyCustomerFieldMakeInvoiceStatusOpOngoingSzhtxxPaperInvoiceService;


    @Autowired
    private ResourceConstant resourceConstant;

//    private void tmpLog(String type,
//                        String fpqqlsh,
//                        String batchId,
//                        String messageBody, String now) {
//
//
//        /**
//         * 1. api前
//         * 2. api ---- 当前
//         * 3. excel
//         */
//
//        String excelExportPathRoot             = resourceConstant.getPathRoot();
//        String excelExportRelativePathTemplate = resourceConstant.getPathTemplate();
//        String excelExportRelativePathStorage  = resourceConstant.getPathStorage();
//
//        String relativePath = File.separator + "thirdpart" +
//                File.separator + "szhtxx" +
//                File.separator + "paperInvoice" +
//                File.separator + "SID1SingleBilling" +
//                File.separator + fpqqlsh +
//                File.separator;
//
////		String templateRelativePath = excelExportPathRoot + excelExportRelativePathTemplate + relativePath;
////		String templateFullPath;
//
//        String targetFullPath = excelExportPathRoot + excelExportRelativePathStorage;
//
//        // 请求记录
//        tmpLogWithFpqqlsh(targetFullPath, relativePath, type, fpqqlsh, batchId, messageBody, now);
//    }
//
//    protected void tmpLogWithFpqqlsh(
//            String targetFullPath,
//            String relativePath,
//            String type,
//            String fpqqlsh,
//            String batchId,
//            String jsonBody,
//            String now) {
//
//        String targetResponseFileName          = StrUtil.format("{}_{}_{}_{}.json", fpqqlsh, batchId, type, now);
//        String targetResponseWriteFileFullPath = targetFullPath + relativePath + targetResponseFileName;
//        FileUtil.touch(targetResponseWriteFileFullPath);
//        FileUtil.writeUtf8String(jsonBody, targetResponseWriteFileFullPath);// CharsetUtil.CHARSET_UTF_8
//
//    }

    /**
     * 深圳航信纸质票 记录 request
     *
     * @param form
     * @param requestBody
     * @param loginSysUser
     * @return
     */
    @Override
    public int recordSID1SingleBillingRequest(
            SzhtxxInvoiceFptxxOpSingleBillingForm form,
            SID1SingleBillingRequestBody requestBody,
            LoginSysUser loginSysUser) {


        // 注意

        int ret = 0;

        String   nowStr  = DateUtil.now();
        DateTime nowDate = DateUtil.date();
        String   batchId = requestBody.getBatchId();
        String   fpqqlsh = requestBody.getFpqqlsh();

        szhtxxPaperInvoiceFptxxLogService.tmpLog("recordRequestForm", "SID1SingleBilling", fpqqlsh, batchId, JSONUtil.toJsonPrettyStr(form), nowStr);
        szhtxxPaperInvoiceFptxxLogService.tmpLog("recordRequestBody", "SID1SingleBilling", fpqqlsh, batchId, JSONUtil.toJsonPrettyStr(requestBody.packing()), nowStr);
        szhtxxPaperInvoiceFptxxLogService.tmpLog("recordRequestUser", "SID1SingleBilling", fpqqlsh, batchId, JSONUtil.toJsonPrettyStr(loginSysUser), nowStr);


        /**
         * opLogicalDelete Fptxx -- 临时转正常 -- 当时处理 -- {@link #processSzhtxxElectronicInvoiceFptxx}
         * opLogicalDelete FptxxXmxx -- 临时转正常 -- 当时处理 -- {@link #processSzhtxxElectronicInvoiceFptxxXmxx}
         * opLogicalDelete FptxxResult -- {@link #processSzhtxxElectronicInvoiceFptxxResult}
         * opLogicalDelete // FptxxExtendInfo -- {@link #processSzhtxxElectronicInvoiceFptxxExtendInfo}
         */

        SzhtxxElectronicInvoiceFptxx           fptxx         = processSzhtxxElectronicInvoiceFptxx(batchId, fpqqlsh, form, requestBody, loginSysUser);
        List<SzhtxxElectronicInvoiceFptxxXmxx> fptxxXmxxList = processSzhtxxElectronicInvoiceFptxxXmxx(batchId, fpqqlsh, requestBody, loginSysUser);

        return ret;
    }

    private SzhtxxElectronicInvoiceFptxx processSzhtxxElectronicInvoiceFptxx(
            String batchId,
            String fpqqlsh,
            SzhtxxInvoiceFptxxOpSingleBillingForm form,
            SID1SingleBillingRequestBody requestBody,
            LoginSysUser loginSysUser) {

        // 开票类型^_^开票类型(1-蓝票;2-红票;10-特殊冲红)
        SzhtxxElectronicInvoiceFptxxKplxEnum szhtxxElectronicInvoiceFptxxKplxEnum = form.getSzhtxxElectronicInvoiceFptxxKplxEnum();

        SID1SingleBillingRequestBodyKpContentFptxxVo fptxxVo = requestBody.getFptxx();

        SzhtxxElectronicInvoiceFptxx fptxx = SzhtxxElectronicInvoiceFptxx
                .builder()
                .batchId(batchId)
                .fpqqlsh(fptxxVo.getFpqqlsh())
//                .kpxm(fptxxVo.getKpxm()) // ---- 冲突待处理 mark by linjinyu at 20220426 - 主要开票项目^_^主要开票商品,或者第一条商品,取项目信息中第一条数据的项目名称(或传递大类例如:办公用品)
                .xhfNsrsbh(fptxxVo.getXhfNsrsbh())
                .xhfmc(fptxxVo.getXhfmc()) // ---- 冲突待处理 mark by linjinyu at 20220426
                .xhfDzdh(fptxxVo.getXhfDzdh())
                .xhfYhzh(fptxxVo.getXhfYhzh())
                .ghfmc(fptxxVo.getGhfmc())
                .ghfNsrsbh(fptxxVo.getGhfNsrsbh())
                .ghfYhzh(fptxxVo.getGhfYhzh())
                .ghfDzdh(fptxxVo.getGhfDzdh())

//                .ghfSj(fptxxVo.getGhfSj()) // ---- 冲突待处理 mark by linjinyu at 20220426 - 购货方手机^_^购货方手机号(交付手机)
//                .ghfEmail(fptxxVo.getGhfEmail()) // ---- 冲突待处理 mark by linjinyu at 20220426 - 购货方邮箱^_^购货方邮箱(交付邮箱)

                .billSentSign(fptxxVo.getBillSentSign()) // ---- 冲突待处理 mark by linjinyu at 20220426

//                .callBackUrl(fptxxVo.getCallBackUrl()) // ---- 冲突待处理 mark by linjinyu at 20220426 - pdf状态回调地址^_^为空时不回调,不为空时回调,若提供的接收回调地址有误,则最多回调三次,回调成功需返回格式{returnCode:'0000',returnMsg:'原因'}其他都视为失败

                .ghfqylx(fptxxVo.getGhfqylx()) // ---- 冲突待处理 mark by linjinyu at 20220426
                .dkbz(fptxxVo.getDkbz())
                .fjh(fptxxVo.getFjh()) // ---- 冲突待处理 mark by linjinyu at 20220426
                .kpy(fptxxVo.getKpy())
                .sky(fptxxVo.getSky())
                .fhr(fptxxVo.getFhr())
                .kplx(fptxxVo.getKplx()) // ---- 冲突待处理 mark by linjinyu at 20220426
                .yfpDm(fptxxVo.getYfpDm()) // ---- 冲突待处理 mark by linjinyu at 20220426
                .yfpHm(fptxxVo.getYfpHm()) // ---- 冲突待处理 mark by linjinyu at 20220426
                .qdBz(fptxxVo.getQdBz())
                .qdxmmc(fptxxVo.getQdxmmc()) // ---- 冲突待处理 mark by linjinyu at 20220426

                .kphjje(AnBigDecimalUtils.getBigDecimal(fptxxVo.getKphjje())) // ---- 冲突待处理 mark by linjinyu at 20220426
                .hjbhsje(AnBigDecimalUtils.getBigDecimal(fptxxVo.getHjbhsje())) // ---- 冲突待处理 mark by linjinyu at 20220426
                .hjse(AnBigDecimalUtils.getBigDecimal(fptxxVo.getHjse())) // ---- 冲突待处理 mark by linjinyu at 20220426

                .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())
//                .blueInvKind(fptxxVo.getBlueInvKind())


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

//                .returnCode(response.getReturnCode()) ---- response 时才填充
//                .returnMsg(response.getReturnMsg()) ---- response 时才填充

                .createTime(DateUtil.date())
                .createUserId(loginSysUser.getSysUserId())
                .createUserName(loginSysUser.getFullName())
                .updateTime(DateUtil.date())
                .updateUserId(loginSysUser.getSysUserId())
                .updateUserName(loginSysUser.getFullName())
                .deleted(CommonSoftDeleteEnum.临时.getKey()) // ---- 注意
                .build();


        if (SzhtxxElectronicInvoiceFptxxKplxEnum.红冲发票.equals(form.getSzhtxxElectronicInvoiceFptxxKplxEnum())) {
            // 开据理由 -- 电子普通发票-才有
//            无理由(0, "无理由"),
//            政策出台前发生纳税义务(1, "政策出台前发生纳税义务"),
//            前期已开具相应征收率发票_发生销售折让_中止或者退回等情形需要开具红字发票_或者开票有误需要重新开具(2, "前期已开具相应征收率发票，发生销售折让、中止或者退回等情形需要开具红字发票，或者开票有误需要重新开具"),
//            因为实际经营业务需要_放弃享受免征增值税政策(3, "因为实际经营业务需要，放弃享受免征增值税政策"),
            fptxx.setInvReason(form.getInvReason()); // 前端交互 -- 这里没有交互

            // 冲红原因 -- 电子普通发票-才有
            // 红冲时才会有
            fptxx.setRedReason(form.getRedReason()); // 前端交互 -- 这里没有交互 // 1-销货退回;2-开票有误;3-服务中止;4-销售折让;
//            fptxx.setBlueInvDate();
            fptxx.setBlueInvKind(AnStringUtils.getString(fptxxVo.getInvoiceType()));

            fptxx.setYfpDm(fptxxVo.getYfpDm());
            fptxx.setYfpHm(fptxxVo.getYfpHm());
        }


        szhtxxElectronicInvoiceFptxxService.addSzhtxxElectronicInvoiceFptxx(fptxx);

        return fptxx;
    }

    private List<SzhtxxElectronicInvoiceFptxxXmxx> processSzhtxxElectronicInvoiceFptxxXmxx(
            String batchId,
            String fpqqlsh,
            SID1SingleBillingRequestBody requestBody,
            LoginSysUser loginSysUser) {

        List<SID1SingleBillingRequestBodyKpContentXmxxItemVo> xmxxItemVoList = requestBody.getFptxx().getInvoiceItems();

        List<SzhtxxElectronicInvoiceFptxxXmxx> fptxxXmxxList = new ArrayList<>();
        String hsbz = "false".equals(xmxxItemVoList.get(0).getHsbz())?"0":"1";
        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(hsbz)
                    .xmdj(xmxxVo.getXmdj())
                    .fphxz(xmxxVo.getFphxz())
                    .spbm(xmxxVo.getSpbm())
                    .yhzcbs(xmxxVo.getYhzcbs())
                    .lslbs(xmxxVo.getLslbs())
//                    .zzstsgl(xmxxVo.getZzstsgl()) // 增值税特殊管理 // ---- 冲突待处理 mark by linjinyu at 20220426
                    .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,
            String fpqqlsh,
            SzhtxxInvoiceFptxxOpSingleBillingForm form,
            SID1SingleBillingResponseBody response,
            LoginSysUser loginSysUser) {

        // 开票类型^_^开票类型(1-蓝票;2-红票;10-特殊冲红)
        SzhtxxElectronicInvoiceFptxxKplxEnum szhtxxElectronicInvoiceFptxxKplxEnum = form.getSzhtxxElectronicInvoiceFptxxKplxEnum();

        SID1SingleBillingResponseBodyEncmsgVo encmsgVo = response.getEncmsgVo();

        // 原
//    {"SID":"1","hisInfoKind":"0","Cipher":"","InfoAmount":65.48,"retcode":"4011","retmsg":"发票填开成功。","InfoNumber":"06560155","InfoDate":"2022-04-25 19:11:34","hisInfoNumber":"","Sign":"","CheckCode":"","InfoTaxAmount":8.51,"hisInfoTypeCode":"","ListFlag":0,"InfoTypeCode":"1100192130","nsrsbh":"440301999999122","cancelFlag":"0","kpfwqh":"0","kpdh":"0","deviceNO":"661101965942","ofdpreviewurl":"","ofddownloadurl":"","ofdstream":""}
//    {"SID":"1","hisInfoKind":"0","Cipher":"","InfoAmount":65.48,"retcode":"4011","retmsg":"开票成功（该销售单据编号的发票已开具）","InfoNumber":"06560155","InfoDate":"2022-04-25 19:11:34","hisInfoNumber":"","Sign":"","CheckCode":"","InfoTaxAmount":8.51,"hisInfoTypeCode":"","ListFlag":0,"InfoTypeCode":"1100192130","nsrsbh":"440301999999122","deviceNO":"661101965942","kpfwqh":"0","kpdh":"0"}

//    {"SID":"1","hisInfoKind":"0","Cipher":"","InfoAmount":65.48,"retcode":"4011","retmsg":"发票填开成功。","InfoNumber":"06560155","InfoDate":"2022-04-25 19:11:34","hisInfoNumber":"","Sign":"","CheckCode":"","InfoTaxAmount":8.51,"hisInfoTypeCode":"","ListFlag":0,"InfoTypeCode":"1100192130","nsrsbh":"440301999999122","cancelFlag":"0","kpfwqh":"0","kpdh":"0","deviceNO":"661101965942","ofdpreviewurl":"","ofddownloadurl":"","ofdstream":""}
//    {"SID":"1","hisInfoKind":"0","Cipher":"","InfoAmount":65.48,"retcode":"4011","retmsg":"开票成功（该销","InfoNumber":"06560155","InfoDate":"2022-04-25 19:11:34","hisInfoNumber":"","Sign":"","CheckCode":"","InfoTaxAmount":8.51,"hisInfoTypeCode":"","ListFlag":0,"InfoTypeCode":"1100192130","nsrsbh":"440301999999122",                 "kpfwqh":"0","kpdh":"0","deviceNO":"661101965942"}


        SzhtxxElectronicInvoiceFptxxResult fptxxResult = SzhtxxElectronicInvoiceFptxxResult.builder()
                .batchId(batchId)
                .fpqqlsh(fpqqlsh)

                .hjbhsje(encmsgVo.getInfoAmount()) // ---- 合计不含税金额^_^默认为0,小数点后2位,以元为单位精确到分开票成功,必填项 ---- 3. InfoAmount double 开具的金额
                .hjse(encmsgVo.getInfoTaxAmount()) // ---- 合计税额^_^默认为0,小数点后2位,以元为单位精确到分,开票成功,必填项 ---- 4. InfoTaxAmount double 开具的税额

                // 该销售单据编号的发票已开具 情况下不返回了
                .kprq(StrUtil.isNotBlank(encmsgVo.getInfoDate()) ? DateUtil.format(DateUtil.parse(encmsgVo.getInfoDate(), "yyyy-MM-dd HH:mm:ss"), "yyyyMMddHHmmss") : null) // --- 开票日期^_^YYYYMMDDHHMISS(14) --- 5. InfoDate string (格式:yyyy-MM-dd)//开票日期 实际上 yyyy-MM-dd HH:mm:ss

                // 该销售单据编号的发票已开具 情况下不返回了
                .fpdm(StrUtil.isNotBlank(encmsgVo.getInfoTypeCode()) ? encmsgVo.getInfoTypeCode() : null) // ---- 发票代码^_^开票成功,必填项 ---- 6. InfoTypeCode string 开具的发票代码
                // 该销售单据编号的发票已开具 情况下不返回了
                .fphm(StrUtil.isNotBlank(encmsgVo.getInfoNumber()) ? encmsgVo.getInfoNumber() : null) // ---- 发票号码^_^开票成功,必填项 ---- 7. InfoNumber string 开具的发票号码

//                .pdfUrl(encmsgVo.getPdfUrl()) // ---- PDF下载链接^_^开票成功,必填项 ---- 19. ofdstream string 返回文件 base64 内容

                // 大概是错的 接口 13. 单张发票查询 SID=17 反证
//                .jym(StrUtil.isNotBlank(encmsgVo.getCipher()) ? encmsgVo.getCipher() : null) // ---- 校验码^_^开票成功,必填项 ---- 15. cipher string 密文
                .jym(StrUtil.isNotBlank(encmsgVo.getCheckCode()) ? encmsgVo.getCheckCode() : null) // ---- 校验码^_^开票成功,必填项 ---- 15. cipher string 密文
                .ssyf(StrUtil.isNotBlank(encmsgVo.getInfoDate()) ? DateUtil.format(DateUtil.parse(encmsgVo.getInfoDate(), "yyyy-MM-dd HH:mm:ss"), "yyyyMM") : null) // ---- 所属月份^_^yyyyMM ----
                .fjh(StrUtil.isNotBlank(encmsgVo.getKpfwqh()) ? encmsgVo.getKpfwqh() : null) // ---- 分机号^_^分机号 ---- 13. kpfwqh string 开票服务器号

                // 大概是错的 接口 13. 单张发票查询 SID=17 反证
//                .ewm(StrUtil.isNotBlank(encmsgVo.getSign()) ? encmsgVo.getSign() : null) // ---- 签名值^_^签名值 ---- 16. Sign string 签名值
                .ewm(StrUtil.isNotBlank(encmsgVo.getCipher()) ? encmsgVo.getCipher() : null) // ---- 签名值^_^签名值 ---- 16. Sign string 签名值
//                .szqm(encmsgVo.getSzqm()) // ---- 二维码^_^开票成功必填 ----


                .returnCode(encmsgVo.getReturnCode())
                .returnMsg(encmsgVo.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);
        szhtxxElectronicInvoiceFptxxResultService.saveOrUpdate(fptxxResult);// 保证只有一条

        int retFptxxOpUpdateLogicalTemp2Normal     = szhtxxElectronicInvoiceFptxxService.opUpdateLogicalTemp2Normal(batchId, fpqqlsh, loginSysUser);
        int retFptxxXmxxOpUpdateLogicalTemp2Normal = szhtxxElectronicInvoiceFptxxXmxxService.opUpdateLogicalTemp2Normal(batchId, fpqqlsh, loginSysUser);


        if (SzhtxxElectronicInvoiceFptxxKplxEnum.红冲发票.equals(form.getSzhtxxElectronicInvoiceFptxxKplxEnum())) {

        }

        return fptxxResult;
    }

    private SzhtxxElectronicInvoiceFptxxExtendInfo processSzhtxxElectronicInvoiceFptxxExtendInfo(
            String batchId,
            String fpqqlsh,
            SzhtxxInvoiceFptxxOpSingleBillingForm form,
            SID1SingleBillingResponseBody response,
            LoginSysUser loginSysUser) {

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

        // 开票类型^_^开票类型(1-蓝票;2-红票;10-特殊冲红)
        SzhtxxElectronicInvoiceFptxxKplxEnum szhtxxElectronicInvoiceFptxxKplxEnum = form.getSzhtxxElectronicInvoiceFptxxKplxEnum();


        String invoiceApplySn = "";

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

        // 红票情况
        if (SzhtxxElectronicInvoiceFptxxKplxEnum.红冲发票.equals(szhtxxElectronicInvoiceFptxxKplxEnum)) {

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

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

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


            /**************************************** 蓝票信息-找回来 start ****************************************/

            SzhtxxElectronicInvoiceFptxx           fptxxBlueEntity       = szhtxxElectronicInvoiceFptxxService.findByFpqqlsh(fpqqlshBlue);
            SzhtxxElectronicInvoiceFptxxResult     fptxxResultBlueEntity = szhtxxElectronicInvoiceFptxxResultService.findByFpqqlsh(fpqqlshBlue);
            SzhtxxElectronicInvoiceFptxxExtendInfo extendInfoBlueEntity  = szhtxxElectronicInvoiceFptxxExtendInfoService.findByFpqqlsh(fpqqlshBlue);

            /**************************************** 蓝票信息-找回来   end ****************************************/

            /**************************************** 红票信息-要更新 start ****************************************/

            szhtxxElectronicInvoiceFptxxExtendInfoService.saveOrUpdateByFpqqlsh(
                    SzhtxxElectronicInvoiceFptxxExtendInfo
                            .builder()
                            .fpqqlsh(extendInfoBlueEntity.getFpqqlsh())
                            .isRedWriteOff(InvoiceInvoicedIsRedWriteOffEnum.是.getKey())

                            .productManagerRequirementsBlueOrRedInvoiceCode(fptxxResultBlueEntity.getFpdm())
                            .productManagerRequirementsBlueOrRedInvoiceNumber(fptxxResultBlueEntity.getFphm())

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

                            .build()
            );

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

            szhtxxPaperInvoiceRedTaxInfoService.updateFieldUsedByRedTaxInfoSn(
                    extendInfoBlueEntity.getRedTaxInfoSn(),
                    SzhtxxPaperInvoiceUsedEnum.已使用,
                    loginSysUser
            );

            /**************************************** 红票信息-要更新   end ****************************************/


        }
        // 蓝票情况
        else {
            invoiceApplySn = fpqqlsh;
        }

        // 蓝票情况
        invoiceApplySn = fpqqlsh;

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

                .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()) // 发票上传不做 mark by linjinyu at 20220428
                .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;
    }


    /**
     * 深圳航信纸质票 记录(蓝票) response
     * 深圳航信纸质票 记录(红票) response 希望共用 // TODO mark by linjinyu at 2022-05-146 07:20:31 - 未验证
     *
     * @param form
     * @param responseBody
     * @param loginSysUser
     * @return
     */
    @Override
    public int recordSID1SingleBillingResponse(
            SzhtxxInvoiceFptxxOpSingleBillingForm form,
            SID1SingleBillingResponseBody responseBody,
            LoginSysUser loginSysUser) {

        // 开票类型^_^开票类型(1-蓝票;2-红票;10-特殊冲红)
        SzhtxxElectronicInvoiceFptxxKplxEnum szhtxxElectronicInvoiceFptxxKplxEnum = form.getSzhtxxElectronicInvoiceFptxxKplxEnum();

        log.info("\n{}\n{}\n{}\n{}", "op确认发起(纸质专用发票)(深圳航信纸质票)->recordResponse",
                JSONUtil.toJsonStr(form),
                JSONUtil.toJsonStr(responseBody),
                JSONUtil.toJsonStr(loginSysUser)
        );

        int ret              = 0;
        int retUpdateFptxxBz = 0;

        String   nowStr  = DateUtil.now();
        DateTime nowDate = DateUtil.date();
        String   batchId = responseBody.getBatchId();
        String   fpqqlsh = responseBody.getFpqqlsh();

        szhtxxPaperInvoiceFptxxLogService.tmpLog("recordResponseForm", "SID1SingleBilling", fpqqlsh, batchId, JSONUtil.toJsonPrettyStr(form), nowStr);
        szhtxxPaperInvoiceFptxxLogService.tmpLog("recordResponseBody", "SID1SingleBilling", fpqqlsh, batchId, JSONUtil.toJsonPrettyStr(responseBody.unPacking()), nowStr);
        szhtxxPaperInvoiceFptxxLogService.tmpLog("recordResponseUser", "SID1SingleBilling", fpqqlsh, batchId, JSONUtil.toJsonPrettyStr(loginSysUser), nowStr);

        /**
         * opLogicalDelete Fptxx {@link #processSzhtxxElectronicInvoiceFptxx}
         * opLogicalDelete FptxxXmxx -- {@link #processSzhtxxElectronicInvoiceFptxxXmxx}
         * opLogicalDelete FptxxResult -- 临时转正常 -- 当时处理 -- {@link #processSzhtxxElectronicInvoiceFptxxResult}
         * opLogicalDelete // FptxxExtendInfo -- 临时转正常 -- 当时处理 -- {@link #processSzhtxxElectronicInvoiceFptxxExtendInfo}
         */
        SzhtxxElectronicInvoiceFptxxResult     fptxxResult     = processSzhtxxElectronicInvoiceFptxxResult(batchId, fpqqlsh, form, responseBody, loginSysUser);
        SzhtxxElectronicInvoiceFptxxExtendInfo fptxxExtendInfo = processSzhtxxElectronicInvoiceFptxxExtendInfo(batchId, fpqqlsh, form, responseBody, loginSysUser);

        /**************************************** 更新发票备注 start ****************************************/

        SzhtxxElectronicInvoiceFptxx entityExistDb = szhtxxElectronicInvoiceFptxxService.findByFpqqlshAndBatchId(fpqqlsh, batchId);

        if (ObjectUtil.isNotNull(entityExistDb)) {
            retUpdateFptxxBz = szhtxxElectronicInvoiceFptxxService.updateSzhtxxElectronicInvoiceFptxxByPrimaryKeySelective(
                    SzhtxxElectronicInvoiceFptxx
                            .builder()
                            .id(entityExistDb.getId())

                            .bz(form.getBz())

                            .build()
            );
        }

        /**************************************** 更新发票备注 start ****************************************/

        return ret;
    }
}
