package com.sunxung.factoring.service.purchcontractmanagement.impl;

import cn.hutool.core.date.DateUnit;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.data.Rows;
import com.deepoove.poi.data.TableRenderData;
import com.deepoove.poi.data.Tables;
import com.deepoove.poi.data.style.BorderStyle;
import com.deepoove.poi.data.style.TableStyle;
import com.sunxung.factoring.component.datatransfer.WordWriter;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.*;
import com.sunxung.factoring.component.util.fdd.TransactionIdCache;
import com.sunxung.factoring.dict.impl.FileModuleDict;
import com.sunxung.factoring.entity.customerinformation.Customer;
import com.sunxung.factoring.entity.electronicsignature.FddSignData;
import com.sunxung.factoring.entity.entprise.Enterprise;
import com.sunxung.factoring.entity.purchcontractmanagement.*;
import com.sunxung.factoring.entity.supplier.SupplierInfo;
import com.sunxung.factoring.entity.sys.Dictionary;
import com.sunxung.factoring.entity.sys.FileStorage;
import com.sunxung.factoring.entity.tradingPlatform.Platform;
import com.sunxung.factoring.entity.tradingPlatform.TradingPlatformInvoiceInfo;
import com.sunxung.factoring.mapper.purchcontractmanagement.PurchContractElectronicInfoMapper;
import com.sunxung.factoring.service.businessmanagement.BusinessBasicInfoService;
import com.sunxung.factoring.service.customerinformation.CustomerService;
import com.sunxung.factoring.service.entprise.IEnterpriseService;
import com.sunxung.factoring.service.purchcontractmanagement.*;
import com.sunxung.factoring.service.supplier.ISupplierInfoService;
import com.sunxung.factoring.service.sys.DictionaryService;
import com.sunxung.factoring.service.sys.FileStorageService;
import com.sunxung.factoring.service.sys.ISysAttachmentRefService;
import com.sunxung.factoring.service.sys.UserService;
import com.sunxung.factoring.service.sys.dto.AttachmentDto;
import com.sunxung.factoring.service.tradingPlatform.PlatformService;
import com.sunxung.factoring.service.tradingPlatform.TradingPlatformInvoiceInfoService;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Description : 采购合同电子合同信息service实现类
 * @Author : JiaYf
 * @Date: 2021-09-22 18:05
 */
@Service
public class PurchContractElectronicInfoServiceImpl extends ServiceImpl<PurchContractElectronicInfoMapper, PurchContractElectronicInfo>
        implements PurchContractElectronicInfoService {


    @Autowired
    private PurchContractService purchContractService;

    @Autowired
    private PurchContractBasicInfoService purchContractBasicInfoService;

    @Autowired
    private PurchContractElectronicInfoService purchContractElectronicInfoService;

    @Autowired
    private PlatformService platformService;

    @Autowired
    private UserService userService;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private PurchContractGoodsInfoService purchContractGoodsInfoService;

    @Autowired
    private PurchContractReplenishInfoService purchContractReplenishInfoService;

    @Autowired
    private IPurchContractApprovalVatInfoService approvalVatInfoService;

    @Autowired
    private PurchContractQualityAcceptService purchContractQualityAcceptService;

    @Autowired
    private PurchContractSettlePaymentService purchContractSettlePaymentService;

    @Autowired
    private PurchContractDeliverClauseService purchContractDeliverClauseService;

    @Autowired
    private PurchContractSellerBlameService purchContractSellerBlameService;

    @Autowired
    private PurchContractPunishClauseService purchContractPunishClauseService;

    @Autowired
    private PurchContractOtherClauseService purchContractOtherClauseService;

    @Autowired
    private FileStorageService fileStorageService;

    @Autowired
    IPurchContractBuyerSellerService buyerSellerService;

    @Autowired
    private IPurchContractNeedUserRelService purchContractNeedUserRelService;

    @Autowired
    TransactionIdCache transactionIdCache;

    @Autowired
    private ISysAttachmentRefService sysAttachmentRefService;

    @Autowired
    private PurchContractApprovalService purchContractApprovalService;

    @Autowired
    private IPurchContractApprovalSettlePaymentService approvalSettlePaymentService;

    @Autowired
    private DictionaryService dicService;

    @Autowired
    private IUploadPurchContractService uploadPurchContractService;

    @Autowired
    private IPurchContractSignConclusionService purchContractSignConclusionService;

    @Autowired
    private TradingPlatformInvoiceInfoService tradingPlatformInvoiceInfoService;

    @Resource(name = "SupplierInfoService")
    private ISupplierInfoService supplierInfoService;

    @Autowired
    private IEnterpriseService enterpriseService;

    @Autowired
    private IPurchContractSupplementInfoService purchContractSupplementInfoService;

    @Override
    public List<PurchContractElectronicInfo> findByPurchContApprId(Long id) {
        return baseMapper.findByPurchContBasicId(id);
    }

    @Override
    public PurchContractElectronicInfo getView(Long id) {
        PurchContractElectronicInfo purchContractElectronicInfo = baseMapper.selectById(id);
        purchContractElectronicInfo.setHistory(1);
        return purchContractElectronicInfo;
    }

    private void doAotoSign(PurchContractBasicInfo purch, Platform platform, PurchContractManagement purchContractManagement, String taskId, Customer supplier, List<PurchContractElectronicInfo> electronicInfos, File purchContractPdfFile, List<FddSignData> fddSignDataList, String contractName) {
        //上传合同
        String contractId = UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
        purch.setContractId(contractId);
        purchContractBasicInfoService.updateById(purch);
        //采购合同自动签署
        String transactionIdAuto = UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
        ElectronicSignatureUtil.uploadContract(contractId, contractName, purchContractPdfFile);
        String signKeyword = "xf";
        ElectronicSignatureUtil.autoSign(transactionIdAuto, contractId, platform.getFddCustomerId(), contractName, signKeyword);

        FddSignData fddSignData = new FddSignData();
        fddSignData.setContractId(contractId);
        fddSignData.setContractType("Purch");
        fddSignData.setSignKeyword("gys");
        String transactionId = UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
        while (transactionId.contains("FDD")) {
            transactionId = UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
        }
        //transactionIdCache.saveObjBuildTransactionId(transactionId,"SIGNPURCHFDD" + purchContractManagement.getId() + "FDD" + purch.getId() + "FDD" + taskId + "FDD" + ThreadLocalUtil.getUserId());
        fddSignData.setTransactionId(transactionId);
        fddSignDataList.add(fddSignData);

        PurchContractElectronicInfo electronicInfo = new PurchContractElectronicInfo();
        electronicInfo.setSignStatus(false);
        electronicInfo.setCertifyStatus(false);
        electronicInfo.setContractId(contractId);
        electronicInfo.setTransactionId(transactionId);
        electronicInfo.setShortContractLinkCreate(new Date());
        electronicInfo.setCertifyLink(supplier.getShortAuthUrl());
        electronicInfo.setFddCustomerId(supplier.getFddCustomerId());
        //认证状态
        electronicInfo.setCertifyStatus(Boolean.valueOf(supplier.getAuthStatus().toString()));
        electronicInfo.setContractName(contractName);
        electronicInfo.setcPurchContractBasicInfoId(purch.getId());
        electronicInfos.add(electronicInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void doSignCallBack(String contractId) {
//        Long purchContractBasicId = Long.valueOf(fdds[2]);
//        Long userId = Long.valueOf(fdds[4]);
//        User user = userService.get(userId);
//        ThreadLocalUtil.setUser(user);
        PurchContractElectronicInfo electronicInfo = purchContractElectronicInfoService.lambdaQuery().eq(PurchContractElectronicInfo::getContractId, contractId).one();
        PurchContractBasicInfo purchContractBasicInfo = purchContractBasicInfoService.getById(electronicInfo.getcPurchContractBasicInfoId());
        if (electronicInfo.getCallBack() == 0) {
            //合同下载
            String contDownUrl = ElectronicSignatureUtil.downloadContract(contractId);
            FileStorage contractFile = fileStorageService.addFileStorageWithBelongAndName(contractId, FileModuleDict.ChildEnum.PURCHASE_CONTRACT_SIGN_FILE, contDownUrl, null);
            fileStorageService.saveAttachmentRefByFileStorage(contractFile, FileModuleDict.ChildEnum.PURCHASE_CONTRACT_FILE, purchContractBasicInfo.getId());
            //合同归档
            ElectronicSignatureUtil.contractFiled(contractId);
            //电子文件签署线上出证下载
            String reportDownUrl = ElectronicSignatureUtil.complianceContractReport(contractId);
            FileStorage contractReportFile = fileStorageService.addFileStorageWithBelongAndName(contractId, FileModuleDict.ChildEnum.PURCHASE_CONTRACT_SIGN_FILE_REPORT, reportDownUrl, null);
            fileStorageService.saveAttachmentRefByFileStorage(contractReportFile, FileModuleDict.ChildEnum.PURCHASE_CONTRACT_SIGN_FILE_REPORT, purchContractBasicInfo.getId());
            //获取最新签署信息，更新签署状态
            electronicInfo.setSignStatus(true);
            electronicInfo.setCallBack(1);
            purchContractElectronicInfoService.updateById(electronicInfo);
//            //清除用户信息
//            ThreadLocalUtil.clearThreadVariable();
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void doSignCallBackByQuery(String contractId, Boolean downloadContract) {
//        Long purchContractBasicId = Long.valueOf(fdds[2]);
        PurchContractElectronicInfo electronicInfo = purchContractElectronicInfoService.lambdaQuery().eq(PurchContractElectronicInfo::getContractId, contractId).one();
        PurchContractBasicInfo purchContractBasicInfo = purchContractBasicInfoService.getById(electronicInfo.getcPurchContractBasicInfoId());
        if (electronicInfo.getCallBack() == 0 && downloadContract) {
            //合同下载
            String contDownUrl = ElectronicSignatureUtil.downloadContract(contractId);
            FileStorage contractFile = fileStorageService.addFileStorageWithBelongAndName(contractId, FileModuleDict.ChildEnum.PURCHASE_CONTRACT_SIGN_FILE, contDownUrl, null);
            fileStorageService.saveAttachmentRefByFileStorage(contractFile, FileModuleDict.ChildEnum.PURCHASE_CONTRACT_SIGN_FILE, purchContractBasicInfo.getId());
            //合同归档
            ElectronicSignatureUtil.contractFiled(contractId);
            //电子文件签署线上出证下载
            String reportDownUrl = ElectronicSignatureUtil.complianceContractReport(contractId);
            FileStorage contractReportFile = fileStorageService.addFileStorageWithBelongAndName(contractId, FileModuleDict.ChildEnum.PURCHASE_CONTRACT_SIGN_FILE_REPORT, reportDownUrl, null);
            fileStorageService.saveAttachmentRefByFileStorage(contractReportFile, FileModuleDict.ChildEnum.PURCHASE_CONTRACT_SIGN_FILE_REPORT, purchContractBasicInfo.getId());
            electronicInfo.setCallBack(1);
            purchContractElectronicInfoService.updateById(electronicInfo);
        }
        if (!electronicInfo.getSignStatus()) {
            //获取最新签署信息，更新签署状态
            electronicInfo.setSignStatus(true);
            purchContractElectronicInfoService.updateById(electronicInfo);
        }
    }

//    //根据合同基本信息ID获取最新的签署信息
//    @Override
//    public PurchContractSignConfirm getLatestPurchContractEle(Long id){
//        return   getOne(new QueryWrapper<PurchContractSignConfirm>().eq("purch_contract_basic_info_id", id).orderByDesc("id").last("LIMIT 1"));
//    }

    /**
     * 制作合同：模板填充数据生成docx
     *
     * @param purchContractManagement
     * @param purch
     * @return
     */

    @Override
    @Transactional(rollbackFor = Exception.class)
    public File makePurchContractDocx(PurchContractManagement purchContractManagement, PurchContractBasicInfo purch) {
        try {
            XMlToDoc xmlDoc = new XMlToDoc();
            Map<String, Object> dataMap = new HashMap<>();
            // 合同名称
            String contractName = purch.getContractName();

            //合同模板数据填充 开始
            //获取平台信息
            Platform platform = platformService.getById(purch.getTradingPlatformId());

            //获取对应供货商的企业客户信息
            SupplierInfo supplierCustomer = supplierInfoService.get(purchContractManagement.getSupplierId());
            Enterprise supplier = enterpriseService.getById(supplierCustomer.getcEnterpriseId());

            //获取采购合同结算与付款
            PurchContractSettlePayment purchContractSettlePayment = purchContractSettlePaymentService.findByPurchContApprId(purch.getId());
            PurchContractApproval latestPurchContractApproval = purchContractApprovalService.lambdaQuery()
                    .eq(PurchContractApproval::getPurchContractBasicInfoId, purch.getId()).orderByDesc(PurchContractApproval::getId).list().get(0);
            PurchContractApprovalSettlePayment approvalSettlePayment = approvalSettlePaymentService.lambdaQuery()
                    .eq(PurchContractApprovalSettlePayment::getPurchContractApprovalId, latestPurchContractApproval.getId()).one();
            Dictionary settleMethodDic = dicService.getByCode(approvalSettlePayment.getSettleMethod());

            //合同名称
            dataMap.put("contractName", contractName);
            //合同编号
            dataMap.put("contractNumber", purch.getContractNumber());
            //签订日期  暂时给null，后边需处理
            dataMap.put("signDate", DateUtil.getDayStringFormat(new Date()));
            //需方公司名称
            dataMap.put("platformName", platform.getPlatformName());
            //需方统一社会信用代码
            dataMap.put("platformSocialCreditCode", platform.getSocialCreditCode());
            //供货公司名称
            dataMap.put("supplierName", supplier.getCorporateName());
            //供应商统一社会信用代码
            dataMap.put("supplierSocialCreditCode", supplier.getSocialCreditCode());
            //买方名称
            dataMap.put("purchaserName", purch.getBuyerName());
            //业务名称
            dataMap.put("businessName", purch.getProjectName());

            //交易标的物  开始
            List<Map<String, Object>> dealGoodsList = new ArrayList<>();
            //获取货物信息
            List<PurchContractGoodsInfo> purchGoodsList = purchContractGoodsInfoService.lambdaQuery().eq(PurchContractGoodsInfo::getPurchContractBasicInfoId, purch.getId()).list();
            dataMap.put("goods", buildTableRenderData(purchGoodsList));

            dataMap.put("dealGoodsList", dealGoodsList);
            //交易标的物  结束

            //获取采购合同补充信息
            //获取合同对应的最新审核信息
            PurchContractReplenishInfo purchContractReplenishInfo = purchContractReplenishInfoService.findByPurchContBasicId(purch.getId());
            //工程量类别
            dataMap.put("projectAmountCategory", dicService.getByCode(purchContractReplenishInfo.getProjectAmountCategory()).getName());
            //货物单价结算方式
            dataMap.put("goodsPriceSettleMethod", purchContractReplenishInfo.getGoodsPriceSettleMethod());

            //获取增值税要求
            PurchContractApprovalVatInfo purchContractVatInfo = approvalVatInfoService.lambdaQuery().eq(PurchContractApprovalVatInfo::getPurchContractApprovalId, latestPurchContractApproval.getId()).one();
            //增值税要求 税率
            dataMap.put("taxRate", purchContractVatInfo.getTaxRate());
            //增值税要求 发票类型
            dataMap.put("receiptType", dicService.getByCode(purchContractVatInfo.getReceiptType()).getName());
            //增值税要求 开票周期
            dataMap.put("openCycle", purchContractVatInfo.getOpenCycle());
            //开票信息
            TradingPlatformInvoiceInfo tradingPlatformInvoiceInfo = tradingPlatformInvoiceInfoService.getOne(new QueryWrapper<TradingPlatformInvoiceInfo>()
                    .eq("trading_platform_id", platform.getId()));
            if (tradingPlatformInvoiceInfo == null || StringUtil.isEmpty(tradingPlatformInvoiceInfo.getPhoneNumber()) || StringUtil.isEmpty(tradingPlatformInvoiceInfo.getAddress())) {
                throw new ValidatorException(CodeUtil.FAIL, "请先前往贸易平台，维护开票信息！");
            }
            //开票信息 开票单位名称(需方)
            dataMap.put("openCompanyName", platform.getPlatformName());
            //开票信息 开票单位统一社会信用代码
            dataMap.put("openCompanySocialCreditCode", platform.getSocialCreditCode());
            //开票信息 地址
            dataMap.put("openCompanyAddress", tradingPlatformInvoiceInfo.getAddress());
            //开票信息 电话
            dataMap.put("openCompanyPhoneNumber", StringUtil.isEmpty(tradingPlatformInvoiceInfo.getPhoneNumber()) ? "/" : tradingPlatformInvoiceInfo.getPhoneNumber());
            //开票信息 发票开户行
            dataMap.put("openBank", purchContractVatInfo.getOpenBank());
            //开票信息 发票账号
            dataMap.put("receiptAccount", purchContractVatInfo.getReceiptAccount());
            //发票备注
            dataMap.put("receiptRemark", purchContractVatInfo.getReceiptRemark());

            //获取采购合同质量与验收
            PurchContractQualityAccept purchContractQualityAccept = purchContractQualityAcceptService
                    .lambdaQuery().eq(PurchContractQualityAccept::getPurchContractApprovalId, latestPurchContractApproval.getId()).one();
            //验收标准
            dataMap.put("acceptCriteria", purchContractQualityAccept.getAcceptCriteria());
            //质量标准
            dataMap.put("qualityCriteria", purchContractQualityAccept.getQualityCriteria());

            //结算方式
            dataMap.put("settleMethod", settleMethodDic.getName());
            //付款方式
            dataMap.put("paymentMethod", approvalSettlePayment.getPaymentMethod());
            //供应商账户名
            dataMap.put("bankAccountName", purchContractSettlePayment.getBankAccountName() == null ? "" : purchContractSettlePayment.getBankAccountName());
            //账号
            dataMap.put("bankAccount", purchContractSettlePayment.getBankAccount() == null ? "" : purchContractSettlePayment.getBankAccount());
            //开户行
            dataMap.put("bankName", purchContractSettlePayment.getBankName() == null ? "" : purchContractSettlePayment.getBankName());

            //获取采购合同交货规定
            PurchContractDeliverClause purchContractDeliverClause = purchContractDeliverClauseService
                    .lambdaQuery().eq(PurchContractDeliverClause::getPurchContractApprovalId, latestPurchContractApproval.getId()).one();
            //交货方式
            dataMap.put("deliverMethod", purchContractDeliverClause.getDeliverMethod());
            //交货地点
            dataMap.put("deliverSite", purchContractDeliverClause.getDeliverSite());

            //交货规定 交货日期
            dataMap.put("deliverDate", purchContractDeliverClause.getDeliverDate());
            //交货规定 运输及保险费
            dataMap.put("transportPremium", purchContractDeliverClause.getTransportPremium());

            //获取采购合同需方收货人
            List<PurchContractNeedUserRel> needUserRelList = purchContractNeedUserRelService
                    .lambdaQuery().eq(PurchContractNeedUserRel::getPurchContractApprovalId, latestPurchContractApproval.getId()).list();
            if (CollectionUtil.isNotEmpty(needUserRelList)) {
                dataMap.put("receiver", buildsenderTableRenderReceiverData(needUserRelList));
            }

            //采购合同供货商发货人
            List<PurchContractBuyerSeller> sellerSenderList = buyerSellerService.lambdaQuery()
                    .eq(PurchContractBuyerSeller::getPurchContractBasicInfoId, purch.getId())
                    .list();
            dataMap.put("sender", buildsenderTableRenderData(sellerSenderList));

            // 业务要求删除
//            //需方指定验收人
//            dataMap.put("buyerReceiverList",buildBuyerReceiverList(buyerReceiverList));
            // 业务要求删除
//            //需方指定结算人
//            dataMap.put("buyerReceiverSettleList",buildBuyerReceiverSettleList(buyerReceiverList));

//            dataMap.put("acceptName", buyerReceiverList.get(0).getName());
//            //身份证号
//            dataMap.put("acceptCertno", buyerReceiverList.get(0).getIdCard());
//            //联系方式
//            dataMap.put("acceptContact", buyerReceiverList.get(0).getContact());
//
//            //姓名
//            dataMap.put("paymentName", buyerReceiverList.get(0).getName());
//            //身份证号
//            dataMap.put("paymentCertno", buyerReceiverList.get(0).getIdCard());
//            //联系方式
//            dataMap.put("paymentContact", buyerReceiverList.get(0).getContact());

            //买方名称
            dataMap.put("toWhoPurchaserName", purch.getBuyerName());

            //获取其他条款
            List<PurchContractOtherClause> contractOtherClauseList = purchContractOtherClauseService
                    .findByPurchContApprId(latestPurchContractApproval.getId());
            if (CollectionUtil.isNotEmpty(contractOtherClauseList)){
                dataMap.put("otherClause", buildOtherClauseRenderData(contractOtherClauseList));
            }else {
                dataMap.put("otherClauseStr", "无");
            }
            //单位名称需方公司名称
            dataMap.put("companyPlatformName", platform.getPlatformName());
            //单位名称供应商名称
            dataMap.put("companySupplierName", supplier.getCorporateName());

            //需方签订日期  需处理
            dataMap.put("companyPlatformDate", DateUtil.getDayStringFormat(new Date()));
            //供应商签订日期  需处理
            dataMap.put("companySupplierDate", DateUtil.getDayStringFormat(new Date()));

            return WordWriter.buildPurchContractFile(purch.getContractNumber() + "-" + purch.getContractName(), dataMap);

        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(CodeUtil.FAIL, "制作采购合同出错" + e.getMessage());
        }
    }

    private TableRenderData buildBuyerReceiverSettleList(List<PurchContractBuyerSeller> buyerReceiverList) {
        Tables.TableBuilder tableBuilder = Tables.ofA4MediumWidth();
        BorderStyle borderStyle = new BorderStyle();
        borderStyle.setSize(5);
        borderStyle.setType(XWPFTable.XWPFBorderType.NONE);

        int indexNumber = 1;
        for (PurchContractBuyerSeller seller : buyerReceiverList) {
            RowRenderData data = Rows.of("需方指定结算人（结算单据）：" + indexNumber + "：" +
                            seller.getName() + "," +
                            "身份证号：" +
                            seller.getIdCard() + "," +
                            "联系电话：" +
                            seller.getContact()
                    )
                    .textFontFamily("宋体")
                    .textFontSize(10)
                    .create();
            tableBuilder.addRow(data);
            indexNumber++;
        }

        TableRenderData goodsTable = tableBuilder.border(borderStyle).create();
        TableStyle tableStyle = goodsTable.getTableStyle();
        tableStyle.setIndentation(1.0);
        tableStyle.setTopCellMargin(10);
        return goodsTable;
    }

    private TableRenderData buildBuyerReceiverList(List<PurchContractBuyerSeller> buyerReceiverList) {
        Tables.TableBuilder tableBuilder = Tables.ofA4MediumWidth();
        BorderStyle borderStyle = new BorderStyle();
        borderStyle.setSize(5);
        borderStyle.setType(XWPFTable.XWPFBorderType.NONE);

        int indexNumber = 1;
        for (PurchContractBuyerSeller seller : buyerReceiverList) {
            RowRenderData data = Rows.of("需方指定验收人（验收单据）：" + indexNumber + "：" +
                            seller.getName() + "," +
                            "身份证号：" +
                            seller.getIdCard() + "," +
                            "联系电话：" +
                            seller.getContact()
                    )
                    .textFontFamily("宋体")
                    .textFontSize(10)
                    .create();
            tableBuilder.addRow(data);
            indexNumber++;
        }

        TableRenderData goodsTable = tableBuilder.border(borderStyle).create();
        TableStyle tableStyle = goodsTable.getTableStyle();
        tableStyle.setIndentation(1.0);
        tableStyle.setTopCellMargin(10);
        return goodsTable;
    }

    private TableRenderData buildOtherClauseRenderData(List<PurchContractOtherClause> contractOtherClauseList) {
        Tables.TableBuilder tableBuilder = Tables.ofA4MediumWidth();
        BorderStyle borderStyle = new BorderStyle();
        borderStyle.setSize(5);
        borderStyle.setType(XWPFTable.XWPFBorderType.NONE);

        int indexNumber = 1;
        for (PurchContractOtherClause otherClause : contractOtherClauseList) {
            RowRenderData data = Rows.of("(" + otherClause.getSerialNumber() + ")" +
                            otherClause.getPaymentCondition()
                    )
                    .textFontFamily("宋体")
                    .textFontSize(11)
                    .create();
            tableBuilder.addRow(data);
            indexNumber++;
        }

        TableRenderData goodsTable = tableBuilder.border(borderStyle).create();
        TableStyle tableStyle = goodsTable.getTableStyle();
//        tableStyle.setIndentation(2.0);
        tableStyle.setTopCellMargin(50);
        tableStyle.setBottomCellMargin(50);
        return goodsTable;
    }

    private TableRenderData buildTableRenderData(List<PurchContractGoodsInfo> goodsInfoList) {
        Tables.TableBuilder tableBuilder = Tables.ofA4MediumWidth();

        BorderStyle borderStyle = new BorderStyle();
        borderStyle.setSize(5);
        borderStyle.setType(XWPFTable.XWPFBorderType.SINGLE);

        RowRenderData header = Rows.of("序号", "材料名称", "规格型号", "生产厂家", "计量单位", "数量", "暂定单价（元/吨）", "备注")
                .center()
                .textFontFamily("宋体")
                .textFontSize(10)
                .create();
        ;
        tableBuilder.addRow(header);
        int indexNumber = 1;
        BigDecimal unitsTotal = new BigDecimal(0);

        for (PurchContractGoodsInfo goodsInfo : goodsInfoList) {
            RowRenderData data = Rows.of(indexNumber + "",
                            goodsInfo.getGoodsName(),
                            goodsInfo.getModelNumber(),
                            goodsInfo.getGoodsFactory(),
                            goodsInfo.getUnits(),
                            goodsInfo.getQuantity(),
                            goodsInfo.getPrice(),
                            goodsInfo.getRemark()
                    )
                    .center()
                    .textFontFamily("宋体")
                    .textFontSize(10)
                    .create();
            tableBuilder.addRow(data);
            indexNumber++;
        }


        TableRenderData goodsTable = tableBuilder.center().border(borderStyle).create();
        return goodsTable;
    }


    private TableRenderData buildsenderTableRenderData(List<PurchContractBuyerSeller> sellerSenderList) {
        Tables.TableBuilder tableBuilder = Tables.ofA4MediumWidth();
        BorderStyle borderStyle = new BorderStyle();
        borderStyle.setSize(5);
        borderStyle.setType(XWPFTable.XWPFBorderType.NONE);

        int indexNumber = 1;
        for (PurchContractBuyerSeller seller : sellerSenderList) {
            RowRenderData data = Rows.of("发货人" + indexNumber + "：" +
                            seller.getName() + "," +
                            "身份证号：" +
                            seller.getIdCard() + "," +
                            "联系电话：" +
                            seller.getContact()
                    )
                    .textFontFamily("宋体")
                    .textFontSize(10)
                    .create();
            tableBuilder.addRow(data);
            indexNumber++;
        }

        TableRenderData goodsTable = tableBuilder.border(borderStyle).create();
        TableStyle tableStyle = goodsTable.getTableStyle();
        tableStyle.setIndentation(1.0);
        tableStyle.setTopCellMargin(10);
        return goodsTable;
    }

    private TableRenderData buildsenderTableRenderReceiverData(List<PurchContractNeedUserRel> needUserRelLists) {
        Tables.TableBuilder tableBuilder = Tables.ofA4MediumWidth();
        BorderStyle borderStyle = new BorderStyle();
        borderStyle.setSize(5);
        borderStyle.setType(XWPFTable.XWPFBorderType.NONE);

        int indexNumber = 1;
        for (PurchContractNeedUserRel receiver : needUserRelLists) {
            RowRenderData data = Rows.of("发货人" + indexNumber + "：" +
                            receiver.getName() + "," +
                            "身份证号：" +
                            receiver.getIdCard() + "," +
                            "联系电话：" +
                            receiver.getMobile()
                    )
                    .textFontFamily("宋体")
                    .textFontSize(10)
                    .create();
            tableBuilder.addRow(data);
            indexNumber++;
        }

        TableRenderData goodsTable = tableBuilder.border(borderStyle).create();
        TableStyle tableStyle = goodsTable.getTableStyle();
        tableStyle.setIndentation(1.0);
        tableStyle.setTopCellMargin(10);
        return goodsTable;
    }

    //根据合同基本信息ID获取最新的签署信息
    @Override
    public PurchContractElectronicInfo getLatestPurchContractSignConfirm(Long id) {
        return getOne(new QueryWrapper<PurchContractElectronicInfo>().eq("purch_contract_basic_info_id", id).orderByDesc("id").last("LIMIT 1"));
    }

    @Override
    public void updateShortUrl(Date date) {
        List<PurchContractElectronicInfo> list = lambdaQuery().eq(PurchContractElectronicInfo::getCertifyStatus,1).eq(PurchContractElectronicInfo::getSignStatus,0).list();
        if (list != null && list.size() > 0) {
            for (PurchContractElectronicInfo electronicInfo : list) {
                Date shortContractLinkCreate = electronicInfo.getShortContractLinkCreate();
                long between = cn.hutool.core.date.DateUtil.between(shortContractLinkCreate, date, DateUnit.DAY);
                if (between >= 6) {
                    String newShortUrl = ElectronicSignatureUtil.shortUrl(null, electronicInfo.getContractLink());
                    electronicInfo.setShortContractLink(newShortUrl);
                    electronicInfo.setShortContractLinkCreate(date);
                    updateById(electronicInfo);
                }
            }
        }
    }

    @Override
    public ResponseEntity<Object> downloadReportUrl(Long managementId, HttpServletResponse res) throws IOException {
        String fileName = "出证文件.zip";
//        res.setContentType("application/zip");
//        res.setHeader("Content-Type", "application/vnd.ms-exce");
//        res.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
//        res.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
//        res.setHeader("Content-disposition", String.format("attachment; filename=" + fileName));
        PurchContractBasicInfo purchContractBasicInfo = purchContractBasicInfoService
                .lambdaQuery().eq(PurchContractBasicInfo::getPurchContractManagementId,managementId).one();
        AttachmentDto attachmentDto = AttachmentDto.builder()
                .setEntityId(purchContractBasicInfo.getId())
                .setChildEnum(FileModuleDict.ChildEnum.PURCHASE_CONTRACT_SIGN_FILE_REPORT)
                .build();
        List<PurchContractSupplementInfo> supplementInfos = purchContractSupplementInfoService
                .lambdaQuery().eq(PurchContractSupplementInfo::getPurchContractManagementId,managementId).list();
        List<AttachmentDto> attachmentDtoChanges = new ArrayList<>();
        for (PurchContractSupplementInfo supplementInfo : supplementInfos) {
            AttachmentDto attachmentDtoChange = AttachmentDto.builder()
                    .setEntityId(supplementInfo.getId())
                    .setChildEnum(FileModuleDict.ChildEnum.PURCHASE_CONTRACT_SUPPLEMENT_FILE_REPORT)
                    .build();
            attachmentDtoChanges.add(attachmentDtoChange);
        }
        List<FileStorage> fileStorages = sysAttachmentRefService.getFiles(attachmentDto);
        for (AttachmentDto attachmentDtoChange : attachmentDtoChanges) {
            fileStorages.addAll(sysAttachmentRefService.getFiles(attachmentDtoChange));
        }

        if (CollectionUtil.isEmpty(fileStorages)) {
            throw new BusinessException(CodeUtil.FAIL, "未查询到出证文件！");
        }
        //文件名去重
        fileStorageService.renameFileStorageList(fileStorages);
        //打包下载文件
        fileStorageService.downloadZipFile(fileStorages, fileName,
                FileModuleDict.ChildEnum.PURCHASE_CONTRACT_ZIP_FILE, res);
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void checkCallBack(Long businessKey) {
        PurchContractManagement purchContractManagement = purchContractService.getById(businessKey);
        PurchContractBasicInfo purch = purchContractBasicInfoService.lambdaQuery()
                .eq(PurchContractBasicInfo::getPurchContractManagementId, purchContractManagement.getId()).one();
        List<PurchContractElectronicInfo> purchContractElectronicInfos = lambdaQuery().eq(PurchContractElectronicInfo::getcPurchContractBasicInfoId, purch.getId()).list();
        if (CollectionUtil.isNotEmpty(purchContractElectronicInfos)) {
            for (PurchContractElectronicInfo purchContractElectronicInfo : purchContractElectronicInfos) {
                if (purchContractElectronicInfo.getCallBack().equals(0)) {
                    doSignCallBackByQuery(purchContractElectronicInfo.getContractId(), true);
                }
            }
        }
    }

    @Override
    public void flushUrl(Long businessKey) {
        PurchContractManagement purchContractManagement = purchContractService.getById(businessKey);
        PurchContractBasicInfo purch = purchContractBasicInfoService
                .lambdaQuery().eq(PurchContractBasicInfo::getPurchContractManagementId, purchContractManagement.getId()).one();

        //删除合同对应的最新签署信息
        purchContractElectronicInfoService.lambdaUpdate().eq(PurchContractElectronicInfo::getcPurchContractBasicInfoId, purch.getId()).remove();
    }
}
