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

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.data.*;
import com.deepoove.poi.data.style.BorderStyle;
import com.google.common.collect.Lists;
import com.sunxung.factoring.component.datatransfer.WordWriter;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.exception.ServiceException;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.*;
import com.sunxung.factoring.component.util.excel.ExcelUtil;
import com.sunxung.factoring.component.util.onlineConverter.OfficeConverterUtil;
import com.sunxung.factoring.dict.impl.FileModuleDict;
import com.sunxung.factoring.dict.impl.ProjectInitiationStatusDict;
import com.sunxung.factoring.entity.acceptance.*;
import com.sunxung.factoring.entity.acceptance.vo.GoodsSearch;
import com.sunxung.factoring.entity.entprise.Enterprise;
import com.sunxung.factoring.entity.project.BusinessProcessingLog;
import com.sunxung.factoring.entity.project.ProjectInformation;
import com.sunxung.factoring.entity.project.vo.BusinessProcessingTaskVo;
import com.sunxung.factoring.entity.project.vo.SearchBusinessProcessingTask;
import com.sunxung.factoring.entity.purchcontractmanagement.*;
import com.sunxung.factoring.entity.salescontractmanagement.*;
import com.sunxung.factoring.entity.settlement.SettlementBasicInfo;
import com.sunxung.factoring.entity.settlement.SettlementGoodsInfo;
import com.sunxung.factoring.entity.steelwaiter.SearchVo;
import com.sunxung.factoring.entity.sys.Dictionary;
import com.sunxung.factoring.entity.sys.FileStorage;
import com.sunxung.factoring.entity.sys.FileStorageDO;
import com.sunxung.factoring.entity.sys.User;
import com.sunxung.factoring.entity.tradingPlatform.Platform;
import com.sunxung.factoring.mapper.acceptancesheet.AcceptanceBasicInfoMapper;
import com.sunxung.factoring.service.acceptancesheet.*;
import com.sunxung.factoring.service.entprise.IEnterpriseService;
import com.sunxung.factoring.service.project.*;
import com.sunxung.factoring.service.purchcontractmanagement.*;
import com.sunxung.factoring.service.salescontractmanagement.*;
import com.sunxung.factoring.service.settlement.SettlementGoodsInfoService;
import com.sunxung.factoring.service.steelwaiter.ISellBillFileRefService;
import com.sunxung.factoring.service.steelwaiter.ISellBillItemService;
import com.sunxung.factoring.service.steelwaiter.ISellBillService;
import com.sunxung.factoring.service.steelwaiter.SteelWaiterService;
import com.sunxung.factoring.service.supplier.ISupplierInfoService;
import com.sunxung.factoring.service.sys.*;
import com.sunxung.factoring.service.sys.dto.AttachmentDto;
import com.sunxung.factoring.service.sys.flowable.FlowableService;
import com.sunxung.factoring.service.tradingPlatform.PlatformService;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.BeanUtils;
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.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author liutao
 * @date 2021.9.10
 */
@Service(value = "acceptanceSheetService")
public class AcceptanceBasicInfoServiceImpl extends ServiceImpl<AcceptanceBasicInfoMapper, AcceptanceBasicInfo> implements AcceptanceBasicInfoService {

    @Autowired
    private ICSalesContractBasicInfoService salesContractBasicInfoService;

    @Autowired
    private ICSalesSignConfirmationService salesSignConfirmationService;

    @Autowired
    private ICSalesSignConfirmationElectronicInfoService signConfirmationElectronicInfoService;

    @Autowired
    private ICSalesSupplementSignConfirmationService salesSupplementSignConfirmationService;

    @Autowired
    private SalesContractService salesContractService;

    @Autowired
    private IPurchContractNeedUserRelService purchContractNeedUserRelService;
    @Autowired
    private PurchContractApprovalService purchContractApprovalService;


    @Autowired
    private AcceptanceGoodsInfoService acceptanceGoodsInfoService;

    @Autowired
    private BusinessAssigneeService assigneeService;

    @Autowired
    private UserService userService;

    @Autowired
    private FlowableService flowableService;

    @Autowired
    private AcceptanceApprovalService acceptanceApprovalService;

    @Autowired
    private DictionaryService dictService;

    @Autowired
    private PurchContractBasicInfoService purchContractBasicInfoService;

    @Autowired
    private PurchContractService purchContractService;

    @Autowired
    private AcceptanceHisInfoService acceptanceHisInfoService;

    @Autowired
    private AcceptanceHisGoodsInfoService acceptanceHisGoodsInfoService;

    @Autowired
    private PlatformService platformService;

    @Autowired
    private ISysAttachmentRefService sysAttachmentRefService;

    @Autowired
    private ICSalesSupplementSignConfirmationElectronicInfoService salesSupplementSignConfirmationElectronicInfoService;

    @Autowired
    private FileStorageService fileStorageService;

    @Autowired
    private IPurchContractBuyerSellerService purchContractBuyerSellerService;

    @Autowired
    private ISalesContractSupplementInfoService salesContractSupplementInfoService;

    @Autowired
    private ICSalesContractSupplementBasicInfoService salesContractSupplementBasicInfoService;

    @Autowired
    private IPurchContractSupplementInfoService purchContractSupplementInfoService;

    @Autowired
    private ISysAttachmentRefService attachmentRefService;

    @Autowired
    private BusinessProcessingTaskService businessProcessingTaskService;

    @Autowired
    private BusinessProcessingLogService businessProcessingLogService;

    @Autowired
    private SettlementGoodsInfoService settlementGoodsInfoService;

    @Autowired
    private IAcceptancePersonInfoService acceptancePersonInfoService;

    @Autowired
    private IAcceptancePersonInfoHistoryService acceptancePersonInfoHistoryService;

    @Autowired
    private ISalesContractPersonInfoService salesContractPersonInfoService;

    @Autowired
    private IAcceptanceSignConfirmationService acceptanceSignConfirmationService;

    @Autowired
    private IAcceptanceSignConfirmationElectronicInfoService acceptanceSignConfirmationElectronicInfoService;

    @Autowired
    private IAcceptanceSellBillRefHisService acceptanceSellBillRefHisService;

    @Autowired
    private IEnterpriseService enterpriseService;

    @Resource(name = "projectInformationService")
    private IProjectInformationService projectInformationService;

    @Autowired
    private FileService fileService;
    @Autowired
    private AcceptanceSheetBusinessReviewService  acceptanceBusinessApprovalService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(AcceptanceBasicInfo acceptanceBasicInfo) {

        //新建验收单完成后需要开启法务流程并完成第一步流程
        startProcess(acceptanceBasicInfo);
    }

    @Override
    public AcceptanceBasicInfo getDetail(Long id) {
        AcceptanceBasicInfo acceptanceBasicInfo = this.baseMapper.getSpecialOneById(id);

        List<FileStorageDO> files1 = fileService.findByBusinessId(id,
                FileModuleDict.ChildEnum.ACCEPTANCE_FILE.getCode());
        List<FileStorageDO> files2 = fileService.findByBusinessId(id,
                FileModuleDict.ChildEnum.ACCEPTANCE_SUPPLEMENT_FILE.getCode());
        List<FileStorageDO> files3 = fileService.findByBusinessId(id,
                FileModuleDict.ChildEnum.ACCEPTANCE_UPSTREAM_FILE.getCode());


        List<FileStorage> signConfirmFiles = Lists.newArrayList();
        //下游验收单(已签署)
        AcceptanceSignConfirmation acceptanceSignConfirmation = acceptanceSignConfirmationService.lambdaQuery().eq(AcceptanceSignConfirmation::getAcceptanceBasicInfoId, id).one();
        if (acceptanceSignConfirmation != null) {
            List<AcceptanceSignConfirmationElectronicInfo> acceptanceSignConfirmationElectronicInfos = acceptanceSignConfirmationElectronicInfoService.lambdaQuery()
                    .eq(AcceptanceSignConfirmationElectronicInfo::getAcceptanceSignConfirmationId, acceptanceSignConfirmation.getId())
                    .eq(AcceptanceSignConfirmationElectronicInfo::getCallBack, 1)
                    .list();
            if (CollectionUtil.isNotEmpty(acceptanceSignConfirmationElectronicInfos)) {
                acceptanceSignConfirmationElectronicInfos.forEach(x -> {
//                    List<FileStorage> files = fileStorageService.findByBelongIdAndBelongType(
//                        x.getContractId(),
//                        FileModuleDict.ChildEnum.ACCEPTANCE_SIGN_CONFIRM_BACK_FILE.getCode());
//                    if(CollectionUtil.isNotEmpty(files)){
//                        signConfirmFiles.addAll(files);
//                    }
                    //获取已签署文件
                    AttachmentDto attachmentDto = AttachmentDto.builder()
                            .setEntityId(x.getId())
                            .setChildEnum(FileModuleDict.ChildEnum.ACCEPTANCE_SIGN_CONFIRM_BACK_FILE)
                            .build();
                    List<FileStorage> files = attachmentRefService.getFiles(attachmentDto);
                    if (CollectionUtil.isNotEmpty(files)) {
                        signConfirmFiles.addAll(files);
                    }
                });
            }
            acceptanceBasicInfo.setSignConfirmFiles(signConfirmFiles);
        }

//        CSalesContract salesContract = salesContractService.getByBusinessNumber(
//            acceptanceBasicInfo.getBusinessNumber());
//
//        CSalesContractBasicInfo salesContractBasicInfo = salesContractBasicInfoService.getOne(
//            new LambdaQueryWrapper<CSalesContractBasicInfo>().eq(
//                CSalesContractBasicInfo::getcSalesContractManagementId,
//                salesContract.getId()));
//        //销售合同附件
//        List<FileStorageDO> files4 = fileService.findByBusinessId(
//            salesContractBasicInfo.getId(), FileModuleDict.ChildEnum.SALES_CONTRACT_FILE.getCode());
//
//        //采购合同附件
//        PurchContractManagement purchContractManagement = purchContractService.lambdaQuery()
//            .eq(PurchContractManagement::getBusinessNumber,
//                acceptanceBasicInfo.getBusinessNumber()).one();
//        PurchContractBasicInfo purchContractBasicInfo = purchContractBasicInfoService.lambdaQuery()
//            .eq(PurchContractBasicInfo::getPurchContractManagementId,
//                purchContractManagement.getId()).one();

//        List<FileStorageDO> files5 = fileService.findByBusinessId(
//            purchContractBasicInfo.getId(), FileModuleDict.ChildEnum.PURCHASE_CONTRACT_FILE.getCode());

        autoSalesFiles(acceptanceBasicInfo);
        autoPurchFiles(acceptanceBasicInfo);

        acceptanceBasicInfo.setFileStorageDOList(files1);
        acceptanceBasicInfo.setSupplementFiles(files2);

        acceptanceBasicInfo.setAcceptanceUpstreamFiles(files3);

        return acceptanceBasicInfo;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<BusinessProcessingTaskVo> findMyCompletedList(SearchBusinessProcessingTask search) {
        List<BusinessProcessingTaskVo> list = baseMapper.findMyCompletedList(search);
        list.forEach(r -> autoInfo(r));
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<BusinessProcessingTaskVo> findAllList(SearchBusinessProcessingTask search) {
        List<BusinessProcessingTaskVo> processingTaskVoList = baseMapper.findAllList(search);
        processingTaskVoList.stream().forEach(p -> {
            //  p.setStatusStr(p.getStatus().getCode());
            autoButtonFlag(p);
            autoInfo(p);
        });
        return processingTaskVoList;
    }

    private void autoInfo(BusinessProcessingTaskVo p) {
        if (!p.getStatus().getCode().equals(ProjectInitiationStatusDict.ChildEnum.COMPLETED.getCode())) {
            BusinessProcessingLog processingLog = businessProcessingLogService.getByBusinessTypeBusinessKey(ConstantUtil.ACCEPTANCE_SHEET, p.getId());
            p.setTaskName(processingLog.getTaskName());
            if (processingLog.getTaskName().equals("法务审核") || processingLog.getTaskName().equals("单价变更审核")) {
                p.setAssigneeName("法务专员");
            } else if(processingLog.getTaskName().equals("业务审核")) {
                p.setAssigneeName("业务经理");
            }else{
                //Long userId = assigneeService.getIdByBusiness(processingLog.getBusnessKey(), ConstantUtil.ACCEPTANCE_SHEET, ConstantUtil.ASSIGNEE_PROJECT_MANAGER);
                p.setAssigneeName(userService.get(processingLog.getAssignee().getId()).getName());
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<Object> downloadPdfSign(Long acceptanceBasicInfoId, HttpServletResponse res) throws Exception {
        AttachmentDto attachmentDto = AttachmentDto.builder()
                .setEntityId(acceptanceBasicInfoId)
                .setChildEnum(FileModuleDict.ChildEnum.ACCEPTANCE_UPSTREAM_FILE_SIGN)
                .build();
        List<FileStorage> files = sysAttachmentRefService.getFiles(attachmentDto);
        if(CollectionUtil.isNotEmpty(files)){
            //文件名去重
            fileStorageService.renameFileStorageList(files);
            //打包下载文件
            fileStorageService.downloadZipFile(files, FileModuleDict.ChildEnum.ACCEPTANCE_UPSTREAM_FILE_SIGN.getCname(),
                FileModuleDict.ChildEnum.ACCEPTANCE_UPSTREAM_FILE_SIGN, res);
        }
        return null;
    }

    @Override
    public ResponseEntity<Object>  downloadCertificate(Long acceptanceBasicInfoId, HttpServletResponse res) {

        AcceptanceSignConfirmation one = acceptanceSignConfirmationService.lambdaQuery()
            .eq(AcceptanceSignConfirmation::getAcceptanceBasicInfoId, acceptanceBasicInfoId).one();

        List<AcceptanceSignConfirmationElectronicInfo> list = acceptanceSignConfirmationElectronicInfoService.lambdaQuery()
            .eq(AcceptanceSignConfirmationElectronicInfo::getAcceptanceSignConfirmationId,
                one.getId()).list();
        List<FileStorage> files = Lists.newArrayList();
        for(AcceptanceSignConfirmationElectronicInfo o:list){
            AttachmentDto attachmentDto = AttachmentDto.builder()
                .setEntityId(o.getId())
                .setChildEnum(FileModuleDict.ChildEnum.ACCEPTANCE_SIGN_CONFIRM_REPORT_FILE)
                .build();
            List<FileStorage> f = sysAttachmentRefService.getFiles(attachmentDto);
            if(CollectionUtil.isNotEmpty(f)){
                files.addAll(f);
            }
        }
        if(CollectionUtil.isNotEmpty(files)){
            //文件名去重
            fileStorageService.renameFileStorageList(files);
            //打包下载文件
            fileStorageService.downloadZipFile(files, FileModuleDict.ChildEnum.ACCEPTANCE_SIGN_CONFIRM_REPORT_FILE.getCname(),
                FileModuleDict.ChildEnum.ACCEPTANCE_SIGN_CONFIRM_REPORT_FILE, res);
        }
        return null;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public AcceptanceApproval findFileList(Long acceptanceBasicInfoId) {
        AcceptanceApproval acceptanceApproval = autoAllfiles(acceptanceBasicInfoId);
        return acceptanceApproval;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<SettlementBasicInfo> findGoodsBySettlement(GoodsSearch goodsSearch) {
        return baseMapper.findGoodsBySettlement(goodsSearch);
    }

//    @Override
//    public void downloadFile(HttpServletResponse response) {
//        OutputStream out = null;
////        BufferedInputStream缓冲输入流
//        BufferedInputStream inputStream = null;
//        try {
//            ClassPathResource classPathResource = new ClassPathResource("templateFiles/验收单货物模板.xlsx");
//            response.setHeader("Content-Type", "application/vnd.ms-exce");
//            response.setHeader("Content-Length", String.valueOf(classPathResource.contentLength()));
//            response.setHeader("Content-disposition", "attachment;filename=" + java.net.URLEncoder.encode(classPathResource.getFilename(), "UTF-8"));
//            out = response.getOutputStream();
////classPathResource.getInputStream() 通过类加载器将文件加载到内存InputStream中
//            inputStream = new BufferedInputStream(classPathResource.getInputStream());
//            byte[] buffer = new byte[1024];
//            while ((inputStream.read(buffer)) > 0) {
//                out.write(buffer);
//                out.flush();
//            }
//
//        } catch (Exception e) {
//            throw new BusinessException("500", "下载模板失败!");
//        } finally {
//            try {
//                inputStream.close();
//                out.close();
//            } catch (IOException e) {
//                log.error("关闭文件流失败!");
//            }
//        }
//    }

    @Override
    public List<AcceptanceBasicInfo> getCanBeBillGoodsInformation(String businessNumber, Long supplierId, Long status) {
        return baseMapper.getCanBeBillGoodsInformation(businessNumber, supplierId, status);
    }

    @Override
    public List<BusinessProcessingTaskVo> findAllListSupplier(SearchBusinessProcessingTask search) {
        return baseMapper.findAllListSupplier(search);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAcceptanceBasicInfo(Long id) {
        AcceptanceBasicInfo acceptanceBasicInfo = get(id);
        if (acceptanceBasicInfo.getAcceptanceStatus().equals(ProjectInitiationStatusDict.ChildEnum.PROCESSING.getCode())) {
            //如果状态为处理中
            BusinessProcessingLog acceptanceBasicInfoLog = businessProcessingLogService.getByBusinessTypeBusinessKey(ConstantUtil.ACCEPTANCE_SHEET, id);
            businessProcessingTaskService.terminate(acceptanceBasicInfoLog.getHistoricTaskId(), id, ConstantUtil.ACCEPTANCE_SHEET,
                    acceptanceBasicInfoLog.getTaskName(), acceptanceBasicInfoLog.getTaskDefKey());
            removeById(acceptanceBasicInfo);
        } else {
            //状态为已审核 判断是都在结算和底层被占用
            List<SettlementGoodsInfo> settlementGoodsInfos = settlementGoodsInfoService.listByAcceptanceId(id);
            if (CollectionUtil.isNotEmpty(settlementGoodsInfos)) {
                throw new ValidatorException(CodeUtil.FAIL, "该笔验收单存在业务数据，不可删除");
            } else {
                removeById(acceptanceBasicInfo);
            }
        }

    }

    @Override
    public AcceptanceApproval autoAllfiles(Long acceptanceBasicInfoId) {
        AcceptanceApproval acceptanceApproval = new AcceptanceApproval();
//        //验收单文件
//        acceptanceApproval.setFile(sysAttachmentRefService.getFiles(AttachmentDto.builder()
//                .setChildEnum(FileModuleDict.ChildEnum.ACCEPTANCE_FILE).setEntityId(acceptanceBasicInfoId).build()));
//        //验收单补充说明
//        acceptanceApproval.setAdditional(sysAttachmentRefService.getFiles(AttachmentDto.builder()
//                .setChildEnum(FileModuleDict.ChildEnum.ACCEPTANCE_SUPPLEMENT_FILE).setEntityId(acceptanceBasicInfoId).build()));
//        //上游验收单
//        acceptanceApproval.setAcceptanceUpstreamFile(sysAttachmentRefService.getFiles(AttachmentDto.builder()
//                .setChildEnum(FileModuleDict.ChildEnum.ACCEPTANCE_UPSTREAM_FILE).setEntityId(acceptanceBasicInfoId).build()));


        //下游验收单
        AcceptanceSignConfirmation acceptanceSignConfirmation = acceptanceSignConfirmationService.lambdaQuery().eq(AcceptanceSignConfirmation::getAcceptanceBasicInfoId, acceptanceBasicInfoId).one();
        if (acceptanceSignConfirmation != null) {
            List<AcceptanceSignConfirmationElectronicInfo> acceptanceSignConfirmationElectronicInfos = acceptanceSignConfirmationElectronicInfoService.lambdaQuery().eq(AcceptanceSignConfirmationElectronicInfo::getAcceptanceSignConfirmationId, acceptanceSignConfirmation.getId()).list();
            List<FileStorage> signConfirmFiles = acceptanceSignConfirmationElectronicInfos.stream().filter(r -> r.getBackFileId() != null).map(r ->
                    fileStorageService.get(r.getBackFileId())
            ).collect(Collectors.toList());
            acceptanceApproval.setSignConfirmFiles(signConfirmFiles);
        }

        AcceptanceBasicInfo acceptanceBasicInfo = getById(acceptanceBasicInfoId);
        autoSalesFiles(acceptanceBasicInfo);
        autoPurchFiles(acceptanceBasicInfo);

        return acceptanceApproval;
    }

    @Override
    public void downloadAllfile(Long id, HttpServletResponse response) {
        List<FileStorage> acceptanceFiles = new ArrayList<>();
        AcceptanceBasicInfo detail = this.getDetail(id);
        // AcceptanceApproval acceptanceApproval = autoAllfiles(id);

        if(CollectionUtil.isNotEmpty(detail.getFileStorageDOList())){
           List<FileStorage> fileStorage = BeanUtilsProxy.copyPropertiesList(detail.getFileStorageDOList(),
                FileStorage.class);
            //验收单附件
            acceptanceFiles.addAll(fileStorage);
        }
        if(CollectionUtil.isNotEmpty(detail.getSupplementFiles())){
            List<FileStorage> fileStorage = BeanUtilsProxy.copyPropertiesList(detail.getSupplementFiles(),
                FileStorage.class);
            //补充文件
            acceptanceFiles.addAll(fileStorage);
        }
        if(CollectionUtil.isNotEmpty(detail.getProcureContractFile())){
            //采购合同附件
            acceptanceFiles.addAll(detail.getProcureContractFile());
        }
        if(CollectionUtil.isNotEmpty(detail.getSaleContractFiles())){
            //销售合同附件
            acceptanceFiles.addAll(detail.getSaleContractFiles());
        }
        if(CollectionUtil.isNotEmpty(detail.getSignConfirmFiles())){
            //签署的附件
            acceptanceFiles.addAll(detail.getSignConfirmFiles());
        }
        //文件名去重 打包下载
        fileStorageService.renameFileStorageList(acceptanceFiles);
        fileStorageService.downloadZipFile(acceptanceFiles, FileModuleDict.ChildEnum.ACCEPTANCE_ZIP_FILE.getCname(),
                FileModuleDict.ChildEnum.ACCEPTANCE_ZIP_FILE, response);
    }

    @Override
    public List<AcceptancePersonInfo> personInfoList(Long supplierId, Long customerId, String businessNumber) {
        PurchContractBasicInfo purchContractBasicInfo = purchContractBasicInfoService.findByBusinessNumberAndSupplierId(businessNumber, supplierId);
        CSalesContract salesManagement = salesContractService.getOne(new QueryWrapper<CSalesContract>()
                .eq("business_number", businessNumber));
        CSalesContractBasicInfo salesContractBasicInfo = salesContractBasicInfoService
                .getOne(new QueryWrapper<CSalesContractBasicInfo>().eq("c_sales_contract_management_id", salesManagement.getId()));
        //采购合同供应商发货人
        List<PurchContractBuyerSeller> purchContractSellers = purchContractBuyerSellerService.lambdaQuery()
                .eq(PurchContractBuyerSeller::getPurchContractBasicInfoId, purchContractBasicInfo.getId()).list();
        //销售合同 验收经办人
        List<CSalesContractPersonInfo> salesContractPersonInfos = salesContractPersonInfoService.lambdaQuery()
                .eq(CSalesContractPersonInfo::getcSalesContractBasicInfoId, salesContractBasicInfo.getId())
                .eq(CSalesContractPersonInfo::getType, "验收经办人").list();
        List<AcceptancePersonInfo> acceptancePersonInfos = new ArrayList<>();
        purchContractSellers.forEach(r -> {
            AcceptancePersonInfo acceptancePersonInfo = new AcceptancePersonInfo();
            acceptancePersonInfo.setName(r.getName());
            acceptancePersonInfo.setCardType("身份证");
            acceptancePersonInfo.setMobile(r.getContact());
            acceptancePersonInfo.setSocialCreditCode(r.getIdCard());
            acceptancePersonInfo.setType("验收经办人（供应商）");
            acceptancePersonInfos.add(acceptancePersonInfo);
        });
        salesContractPersonInfos.forEach(r -> {
            AcceptancePersonInfo acceptancePersonInfo = new AcceptancePersonInfo();
            BeanUtils.copyProperties(r, acceptancePersonInfo, "id");
            acceptancePersonInfo.setType("验收经办人（核心企业）");
            acceptancePersonInfos.add(acceptancePersonInfo);
        });
        return acceptancePersonInfos;
    }

    @Override
    public void downloadGoodsInfos(SearchVo searchVo, HttpServletResponse response) {
        //方式一
        List<AcceptanceGoodsInfo> goodsInfos = searchVo.getGoodsInfoList();
        List<JSONObject> jsonObjects = goodsInfos.stream().map(r -> {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("goodsName", r.getGoodsName());
            jsonObject.put("goodsMaterial", r.getGoodsMaterial());
            jsonObject.put("goodsType", r.getGoodsType());
            jsonObject.put("goodsFactory", r.getGoodsFactory());
            jsonObject.put("goodsUnit", r.getGoodsUnit());
            jsonObject.put("goodsQuantity", r.getGoodsQuantity());
            jsonObject.put("salesPrice", r.getSalesPrice());
            jsonObject.put("acceptanceDate", r.getAcceptanceDate());
            return jsonObject;
        }).collect(Collectors.toList());
        try {
            ServletOutputStream outputStream = response.getOutputStream();
            Map<String, String> headers = new LinkedHashMap<>();
            headers.put("goodsName", "名称");
            headers.put("goodsMaterial", "材质");
            headers.put("goodsType", "型号");
            headers.put("goodsFactory", "厂家");
            headers.put("goodsUnit", "单位");
            headers.put("goodsQuantity", "数量");
            headers.put("salesPrice", "销售单价/元");
            headers.put("acceptanceDate", "验收日期");
            ExcelUtil.exportExcel(headers, jsonObjects, outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    @Transactional
    public void updateDetailHandleProcess(AcceptanceBasicInfo acceptanceBasicInfo) {

        if (acceptanceBasicInfo == null) {
            throw new ValidatorException(CodeUtil.FAIL, "验收单信息不能为空！");
        }
        if(acceptanceBasicInfo.getBusinessApprovalStatus()!=null && acceptanceBasicInfo.getBusinessApprovalStatus()==1 && acceptanceBasicInfo.getApproval()==0){
            throw new ServiceException(CodeUtil.FAIL,"业务审核通过后必须要申请融资");
        }
        List<Long> legalSpecialists = userService.findUserIdByRole(ConstantUtil.LEGAL_SPECIALIST);
        List<Long> projectManage = userService.findUserIdByRole(ConstantUtil.PROJECT_MANAGER);
        String legalSpecias = legalSpecialists.stream().map(c -> c.toString()).collect(Collectors.joining(","));
        String projectManageStr = projectManage.stream().map(c -> c.toString()).collect(Collectors.joining(","));
        //保存历史
        Long historyId = addHistoryAcceptanceSheet(acceptanceBasicInfo);
        User admin = userService.getByLoginName("admin");
        Map<String, Object> procVariables = new HashMap<>();
        Map<String, Object> msgVariables = new HashMap<>();
        Task task = flowableService.getByTaskQuery(acceptanceBasicInfo.getTaskId());
//        if (acceptanceBasicInfo.getSignConfirm().equals(1)) {
//            procVariables.put(ConstantUtil.ACCEPTANCE_SIGN_CONFIRM_ASSIGNEE, admin.getId());
//            procVariables.put("result", "签署确认");
//            flowableService.completeMyTask(acceptanceBasicInfo.getTaskId(), acceptanceBasicInfo, procVariables,
//                    null, historyId, msgVariables, ConstantUtil.ACCEPTANCE_SHEET);
//        } else if (acceptanceBasicInfo.getSignConfirm().equals(0)) {
//            procVariables.put(ConstantUtil.ACCEPTANCE_SHEET_APPROVAL_CANDIDATE, legalSpecias);
//            procVariables.put("result", "法务审核");
//            msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "验收单编号：" + acceptanceBasicInfo.getAcceptanceNumber());
//            msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
//                    "验收单编号为“" + acceptanceBasicInfo.getAcceptanceNumber() + "”的验收单已进入“"
//                            + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.ACCEPTANCE_SHEET) + "—法务审核阶段，"
//                            + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
//            Task task = flowableService.getByTaskQuery(acceptanceBasicInfo.getTaskId());
//            User u = new User();
//            u.setId(Long.parseLong(task.getAssignee()));
//            ThreadLocalUtil.setUser(u);
//            flowableService.completeMyTask(acceptanceBasicInfo.getTaskId(), acceptanceBasicInfo, procVariables,
//                    null, historyId, msgVariables, ConstantUtil.ACCEPTANCE_SHEET, legalSpecialists);
//        }
        if (acceptanceBasicInfo.getApproval().equals(1)) {
            User user = new User();
            user.setId(Long.parseLong(task.getAssignee()));
            ThreadLocalUtil.setUser(user);
            if(acceptanceBasicInfo.getSignConfirm().equals(1)){
                procVariables.put(ConstantUtil.ACCEPTANCE_SIGN_CONFIRM_ASSIGNEE, admin.getId());
                procVariables.put("result", "签署确认");
                msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "验收单编号：" + acceptanceBasicInfo.getAcceptanceNumber());
                msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                    "验收单编号为“" + acceptanceBasicInfo.getAcceptanceNumber() + "”的验收单已进入“"
                        + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.ACCEPTANCE_SHEET) + "—签署确认阶段，"
                        + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
                flowableService.completeMyTask(task.getId(), acceptanceBasicInfo, procVariables, null, historyId, msgVariables, ConstantUtil.ACCEPTANCE_SHEET);
            }else if(acceptanceBasicInfo.getSignConfirm().equals(0)){

                procVariables.put(ConstantUtil.ACCEPTANCE_SHEET_APPROVAL_CANDIDATE, legalSpecias);
                procVariables.put("result", "法务审核");
                msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "验收单编号：" + acceptanceBasicInfo.getAcceptanceNumber());
                msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                    "验收单编号为“" + acceptanceBasicInfo.getAcceptanceNumber() + "”的验收单已进入“"
                        + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.ACCEPTANCE_SHEET) + "—法务审核阶段，"
                        + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
                flowableService.completeMyTask(task.getId(), acceptanceBasicInfo, procVariables, null, historyId, msgVariables, ConstantUtil.ACCEPTANCE_SHEET, legalSpecialists);
            }
        } else if (acceptanceBasicInfo.getApproval().equals(0)) {
            //如果不申请审核 则由业务经理处理 下一步内容
            procVariables.put(ConstantUtil.ACCEPTANCE_BUSINESS_APPROVAL_CANDIDATE, projectManageStr);
            procVariables.put("result", "否");
            msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "验收单编号：" + acceptanceBasicInfo.getAcceptanceNumber());
            msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                "验收单编号为“" + acceptanceBasicInfo.getAcceptanceNumber() + "”的验收单已进入“"
                    + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.ACCEPTANCE_SHEET) + "—业务经理审核阶段，"
                    + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
            User user = new User();
            user.setId(Long.parseLong(task.getAssignee()));
            ThreadLocalUtil.setUser(user);
            flowableService.completeMyTask(task.getId(), acceptanceBasicInfo, procVariables, null, historyId, msgVariables, ConstantUtil.ACCEPTANCE_SHEET,projectManage);
        }

    }

    private TableRenderData makeGoddsList(List<AcceptanceGoodsInfo> goodsList, Map<String, Object> dataMap) {
        int number = 0;
        //合计
        BigDecimal sum = new BigDecimal("0.0000");

        Tables.TableBuilder tableBuilder = Tables.ofA4MediumWidth();

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

        String supplierName = (String) dataMap.get("supplierName");

        RowRenderData header0 = Rows.of("供货单位：", null, supplierName, null, null, null)
                .center()
                .textFontFamily("宋体")
                .textFontSize(10)
                .create();

        tableBuilder.addRow(header0);

        String contractNumber = (String) dataMap.get("contractNumber");

        RowRenderData header1 = Rows.of("合同编号：", null, contractNumber, null, null, null)
                .center()
                .textFontFamily("宋体")
                .textFontSize(10)
                .create();

        tableBuilder.addRow(header1);

        RowRenderData header = Rows.of("物资名称", "厂家", "型号", "单位", "数量", "验收日期")
                .center()
                .textFontFamily("宋体")
                .textFontSize(10)
                .create();

        tableBuilder.addRow(header);
        int indexNumber = 1;

        for (AcceptanceGoodsInfo acceptanceGoodsInfo : goodsList) {
            sum = sum.add(acceptanceGoodsInfo.getGoodsQuantity());

            RowRenderData data = Rows.of(acceptanceGoodsInfo.getGoodsName(), acceptanceGoodsInfo.getGoodsFactory()
                            , acceptanceGoodsInfo.getGoodsType(), acceptanceGoodsInfo.getGoodsUnit()
                            , acceptanceGoodsInfo.getGoodsQuantity().toString(), DateUtil.dateToString(acceptanceGoodsInfo.getAcceptanceDate(), "yyyy-MM-dd"))
                    .center()
                    .textFontFamily("宋体")
                    .textFontSize(10)
                    .create();
            tableBuilder.addRow(data);
            indexNumber++;
        }

        RowRenderData foot = Rows.of("合计", null, null, null, sum.toString(), null)
                .center()
                .textFontFamily("宋体")
                .textFontSize(10)
                .create();

        tableBuilder.addRow(foot);

        MergeCellRule rule = MergeCellRule.builder().map(MergeCellRule.Grid.of(0, 0), MergeCellRule.Grid.of(0, 1))
                .map(MergeCellRule.Grid.of(0, 2), MergeCellRule.Grid.of(0, 5))
                .map(MergeCellRule.Grid.of(1, 0), MergeCellRule.Grid.of(1, 1))
                .map(MergeCellRule.Grid.of(1, 2), MergeCellRule.Grid.of(1, 5))
                .build();

        tableBuilder.mergeRule(rule);

        int[] colWidthsPercent = {17, 17, 17, 16, 16, 17};


        TableRenderData goodsTable = tableBuilder.center().percentWidth("100%", colWidthsPercent).border(borderStyle).create();
        return goodsTable;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void legalReview(AcceptanceApproval acceptanceApproval) throws Exception {
        //判断审核结果
        AcceptanceBasicInfo acceptanceBasicInfo = this.baseMapper.getSpecialOneById(acceptanceApproval.getAcceptanceBasicInfoId());
        //查询历史 把该次审批对应的  验收单基础历史信息表 绑定起来
        AcceptanceHisInfo hisInfo = acceptanceHisInfoService.lambdaQuery()
            .eq(AcceptanceHisInfo::getAcceptanceNumber, acceptanceBasicInfo.getAcceptanceNumber())
            .orderByDesc(AcceptanceHisInfo::getGmtCreate).last("limit 1").one();
        acceptanceApproval.setAcceptanceBasicHisId(hisInfo.getId());
        String result;
        switch (acceptanceApproval.getApprovalConclusion()) {
            case ConstantConversionUtil.APPROVAL_RESULT_PASS:
                result = ConstantUtil.APPROVAL;
                acceptanceBasicInfo.setReceivables(false);
                acceptanceBasicInfo.setSettlement(false);
                acceptanceBasicInfo.setAcceptanceStatus(ProjectInitiationStatusDict.ChildEnum.COMPLETED.getCode());
                List<FileStorageDO> fileDOs = null;
                try {
                    //XMlToDoc xmlDoc = new XMlToDoc();
                    //模板中填充数据-c端其实已经生成了
                    //file = inputData(acceptanceBasicInfo, xmlDoc);
                    fileDOs = fileService.findByBusinessId(
                            acceptanceApproval.getAcceptanceBasicInfoId(),
                            FileModuleDict.ChildEnum.ACCEPTANCE_UPSTREAM_FILE.getCode());
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new BusinessException(CodeUtil.FAIL, "生成验收单据出错");
                }
                for (FileStorageDO file : fileDOs) {
                    File f = new File(file.getAbsolutePath());

                    String contractId = UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
                    String docTitle = "上游验收单" + acceptanceBasicInfo.getAcceptanceNumber();
                    String transactionId = UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
                    ElectronicSignatureUtil.uploadContract(contractId, docTitle, f);
                    //验收单自动签署
                    Platform platform = platformService.getById(acceptanceBasicInfo.getTradingPlatformId());
                    String signKeyword = "gz";
                    ElectronicSignatureUtil.autoSign(transactionId, contractId, platform.getFddCustomerId(), docTitle, signKeyword);
                    //合同下载
                    String contDownUrl = ElectronicSignatureUtil.downloadContract(contractId);
                    FileStorage contractSupplementFile = fileStorageService.addFileStorageWithBelongAndName(contractId, FileModuleDict.ChildEnum.ACCEPTANCE_UPSTREAM_FILE_SIGN, contDownUrl, null);
                    fileStorageService.saveAttachmentRefByFileStorage(contractSupplementFile, FileModuleDict.ChildEnum.ACCEPTANCE_UPSTREAM_FILE_SIGN, acceptanceBasicInfo.getId());
                    //合同归档
                    ElectronicSignatureUtil.contractFiled(contractId);
//
//                    //电子文件签署线上出证下载
//                    String reportDownUrl = ElectronicSignatureUtil.complianceContractReport(contractId);
//                    FileStorage reportFile = fileStorageService.addFileStorageWithBelongAndName(contractId, FileModuleDict.ChildEnum.SIGN_CONFIRM_REPORT_FILE, reportDownUrl, null);
//                    fileStorageService.saveAttachmentRefByFileStorage(reportFile, FileModuleDict.ChildEnum.SIGN_CONFIRM_REPORT_FILE, signConfirmationElectronicInfo.getId());

                }
                break;
            case ConstantConversionUtil.APPROVAL_RESULT_BACK:
                if (acceptanceBasicInfo.getSignConfirm().equals(1)) {
                    throw new ValidatorException(CodeUtil.FAIL, "已签署过签署确认文件，不能驳回！");
                }
                result = ConstantUtil.OVERRULE;
                acceptanceBasicInfo.setAcceptanceStatus(ProjectInitiationStatusDict.ChildEnum.PROCESSING.getCode());
                break;
            case ConstantConversionUtil.APPROVAL_RESULT_VETO:
                result = ConstantUtil.TERMINATE;
                acceptanceBasicInfo.setAcceptanceStatus(ProjectInitiationStatusDict.ChildEnum.TERMINATED.getCode());
                break;
            default:
                result = "";

        }
        //修改验收单信息
        updateById(acceptanceBasicInfo);
        //保存审核结果
        acceptanceApproval.setAuditorId(ThreadLocalUtil.getUserId());
        acceptanceApprovalService.save(acceptanceApproval);

        //完成审核流程流转到下一流程或者完成流程
        Map<String, Object> msgVariables = new HashMap<>();
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "验收单编号：" + acceptanceBasicInfo.getAcceptanceNumber());
//        result = ConstantUtil.APPROVAL;
        if (result.equals(ConstantUtil.OVERRULE)) {
            msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                    "验收单编号为“" + acceptanceBasicInfo.getAcceptanceNumber() + "”的验收单已驳回，进入“"
                            + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.ACCEPTANCE_SHEET) + "—退回修改”阶段，"
                            + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
            //电子签信息
            AcceptanceSignConfirmation acceptanceSignConfirmation = acceptanceSignConfirmationService.lambdaQuery()
                    .eq(AcceptanceSignConfirmation::getAcceptanceBasicInfoId, acceptanceApproval.getAcceptanceBasicInfoId()).one();
            if (acceptanceSignConfirmation != null) {
                acceptanceSignConfirmationElectronicInfoService.lambdaUpdate().eq(AcceptanceSignConfirmationElectronicInfo::getAcceptanceSignConfirmationId, acceptanceSignConfirmation.getId()).remove();
                acceptanceSignConfirmationService.lambdaUpdate().eq(AcceptanceSignConfirmation::getAcceptanceBasicInfoId,
                        acceptanceApproval.getAcceptanceBasicInfoId()).remove();
            }
        } else if (result.equals(ConstantUtil.APPROVAL) || result.equals(ConstantUtil.TERMINATE)) {
            msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                    "验收单编号为“" + acceptanceBasicInfo.getAcceptanceNumber() + "”的验收单已通过验收审核");
        }
        flowableService.completeMyTask(acceptanceApproval.getTaskId(), acceptanceBasicInfo, null, result, acceptanceApproval.getId(), msgVariables, ConstantUtil.ACCEPTANCE_SHEET);
    }

    /**
     * 业务审核
     * @param businessApproval
     */
    @Override
    @Transactional
    public void businessReview(AcceptanceBusinessApproval businessApproval) {
        //拾取task
        flowableService.claimTask(businessApproval.getTaskId(), ThreadLocalUtil.getUserId(), ConstantUtil.PROJECT_MANAGER);
        //判断审核结果
        AcceptanceBasicInfo acceptanceBasicInfo = this.baseMapper.getSpecialOneById(businessApproval.getAcceptanceBasicInfoId());
        //查询历史 把该次审批对应的  验收单基础历史信息表 绑定起来
        AcceptanceHisInfo hisInfo = acceptanceHisInfoService.lambdaQuery()
            .eq(AcceptanceHisInfo::getAcceptanceNumber, acceptanceBasicInfo.getAcceptanceNumber())
            .orderByDesc(AcceptanceHisInfo::getGmtCreate).last("limit 1").one();
        businessApproval.setAcceptanceBasicHisId(hisInfo.getId());

        //无论业务审核 通过还是 退回 都会到 c端 录入验收单 节点， 但是会修改 业务审核状态字段
        String result = "业务审核";
        if(ConstantConversionUtil.APPROVAL_RESULT_PASS.equals(businessApproval.getApprovalConclusion())){
            //审核通过
            acceptanceBasicInfo.setBusinessApprovalStatus(1);
        }else  if(ConstantConversionUtil.APPROVAL_RESULT_BACK.equals(businessApproval.getApprovalConclusion())){
             //审核退回
            acceptanceBasicInfo.setBusinessApprovalStatus(0);
        }else{
            throw new ServiceException("500","审批结论参数错误");
        }
        //修改验收单信息
        updateById(acceptanceBasicInfo);
        //保存审核结果
        businessApproval.setAuditorId(ThreadLocalUtil.getUserId());
        acceptanceBusinessApprovalService.save(businessApproval);

        //完成审核流程流转到下一流程或者完成流程
        Map<String, Object> msgVariables = new HashMap<>();
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "验收单编号：" + acceptanceBasicInfo.getAcceptanceNumber());
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
            "验收单编号为“" + acceptanceBasicInfo.getAcceptanceNumber() + "”的验收单已进入“"
                + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.ACCEPTANCE_SHEET) + "—验收单填写阶段，"
                + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
        if (result.equals(ConstantUtil.OVERRULE)) {
            msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                "验收单编号为“" + acceptanceBasicInfo.getAcceptanceNumber() + "”的验收单已驳回，进入“"
                    + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.ACCEPTANCE_SHEET) + "—退回修改”阶段，"
                    + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);

        } else if (result.equals(ConstantUtil.APPROVAL) || result.equals(ConstantUtil.TERMINATE)) {
            msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                "验收单编号为“" + acceptanceBasicInfo.getAcceptanceNumber() + "”的验收单已通过业务经理审核");
        }
        flowableService.completeMyTask(businessApproval.getTaskId(), acceptanceBasicInfo, null, result, businessApproval.getId(), msgVariables, ConstantUtil.ACCEPTANCE_SHEET);
    }

    @Override
    public File inputData(AcceptanceBasicInfo acceptanceBasicInfo, XMlToDoc xmlDoc) {
        //业务信息
        Enterprise supplier = enterpriseService.getById(acceptanceBasicInfo.getcSupplierInfoId());
        List<AcceptanceGoodsInfo> goodsList;
        //货物信息
        if (acceptanceBasicInfo.getId() != null) {
            goodsList = acceptanceGoodsInfoService.list(
                    new QueryWrapper<AcceptanceGoodsInfo>().eq("c_acceptance_basic_info_id", acceptanceBasicInfo.getId()));
        } else {
            goodsList = acceptanceBasicInfo.getAcceptanceGoodInfos();
        }
        //合同信息
        PurchContractManagement purchContractManagement = purchContractService.getOne(
                new QueryWrapper<PurchContractManagement>()
                        .eq("business_number", acceptanceBasicInfo.getBusinessNumber()));
        PurchContractBasicInfo purchContractBasicInfo = purchContractBasicInfoService.getOne(
                new QueryWrapper<PurchContractBasicInfo>()
                        .eq("c_purch_contract_management_id", purchContractManagement.getId())
                        .orderByDesc("gmt_create").last("LIMIT 1")
        );
//        List<PurchContractBuyerSeller> purchContractBuyerSellers = purchContractBuyerSellerService
//            .list(new QueryWrapper<PurchContractBuyerSeller>()
//                .eq("c_purch_contract_basic_info_id", purchContractBasicInfo.getId())
//                .eq("buyer_or_seller", 1));

        //最后一次审核的信息
        PurchContractApproval purchContractApproval = purchContractApprovalService.getOne(
                new LambdaQueryWrapper<PurchContractApproval>()
                        .eq(PurchContractApproval::getPurchContractBasicInfoId,
                                purchContractBasicInfo.getId())
                        .orderByDesc(PurchContractApproval::getGmtCreate).last("LIMIT 1"));

        List<PurchContractNeedUserRel> buyers = purchContractNeedUserRelService.list(
                new LambdaQueryWrapper<PurchContractNeedUserRel>()
                        .eq(PurchContractNeedUserRel::getPurchContractApprovalId,
                                purchContractApproval.getId()));


        StringBuffer names = new StringBuffer();
        for (PurchContractNeedUserRel buyer : buyers) {
            String name = buyer.getName() + ",";
            names.append(name);
        }
        String name = names.toString();
        name = name.substring(0, names.length() - 1);
        //填充数据开始
        try {
            Map<String, Object> dataMap = new HashMap<>();
            //供货单位
            dataMap.put("supplierName", supplier.getCorporateName());
            //合同编号
            dataMap.put("contractNumber", purchContractBasicInfo.getContractNumber());//采购
            //收货单位 业务对应的贸易平台
            dataMap.put("customer", platformService.getById(acceptanceBasicInfo.getTradingPlatformId()).getPlatformName());
            //经办人 需方收货人姓名
            dataMap.put("checkOperatorEnterprise", name);
            //供货单位：【验收单>供应商名称】
            dataMap.put("supplier", supplier.getCorporateName());
            List<AcceptancePersonInfo> acceptancePersonInfos = acceptanceBasicInfo.getAcceptancePersonInfos();
            if (CollectionUtil.isEmpty(acceptancePersonInfos)) {
                acceptancePersonInfos = acceptancePersonInfoService.lambdaQuery()
                        .eq(AcceptancePersonInfo::getAcceptanceBasicInfoId, acceptanceBasicInfo.getId())
                        .list();
            }
            String checkOperatorSupplier = acceptancePersonInfos.stream().filter(r -> r.getType().equals("验收经办人（供应商）")).map(r -> r.getName()).collect(Collectors.joining("、"));
            //经办人 验收经办人（供应商)
            dataMap.put("checkOperatorSupplier", checkOperatorSupplier);
            //
            //填充货物信息
            BigDecimal sum = new BigDecimal("0.00");
            List<Map<String, Object>> dealGoodsList = new ArrayList<>();
            if (CollectionUtil.isEmpty(goodsList)) {
                throw new ValidatorException(CodeUtil.FAIL, "请录入货物信息！");
            }
            //填充货物信息
            TableRenderData tableRenderData = makeGoddsList(goodsList, dataMap);
            dataMap.put("dealGoodsList", tableRenderData);
            File docxFile = null;
            String fileName = acceptanceBasicInfo.getAcceptanceNumber() == null ? "acceptance" + purchContractManagement.getBusinessNumber()
                    + DateUtil.getCurrentDate().replace("-", "").replace(":", "") + ThreadLocalUtil.getUserId() : acceptanceBasicInfo.getAcceptanceNumber();
            docxFile = WordWriter.buildAcceptanceFile(fileName, dataMap);
            //将docx转为pdf
            String suffix = FileUtil.getSuffix(docxFile.getName());
            String newPath = docxFile.getAbsolutePath().replace(suffix, ".pdf");
            File pdfFile = OfficeConverterUtil.office2Pdf(docxFile.getAbsolutePath(), newPath);
            docxFile.deleteOnExit();
            return pdfFile;
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(CodeUtil.FAIL, "下载验收清单错误" + e.getMessage());
        }
    }

    @Override
    public AcceptanceBasicInfo get(Long id) {
        return baseMapper.getListPage(id);
    }

    private void startProcess(AcceptanceBasicInfo acceptanceBasicInfo) {
        Long odlId = acceptanceBasicInfo.getId();
        //2.新增处理人-- 当前线程
        //项目信息
        ProjectInformation projectInformation = projectInformationService
                .getOne(new QueryWrapper<ProjectInformation>().eq("business_number", acceptanceBasicInfo.getBusinessNumber()));

        List<Long> legalSpecialists = userService.findUserIdByRole(ConstantUtil.LEGAL_SPECIALIST);
        if (legalSpecialists == null || legalSpecialists.size() == 0) {
            throw new ValidatorException(CodeUtil.FAIL, ConstantUtil.LEGAL_SPECIALIST + "角色内无任何用户！");
        }
        List<Long> projectManage  = userService.findUserIdByRole(ConstantUtil.PROJECT_MANAGER);
        if(projectManage==null || projectManage.size()==0){
            throw new ValidatorException(CodeUtil.FAIL, ConstantUtil.PROJECT_MANAGER + "角色内无任何用户！");
        }

        String legalSpecias = legalSpecialists.stream().map(c -> c.toString()).collect(Collectors.joining(","));
        String projectManageStr = projectManage.stream().map(c -> c.toString()).collect(Collectors.joining(","));

        User admin = userService.getByLoginName("admin");
        //3.开启流程实例
        Map<String, Object> procVariables = new HashMap<>();
        procVariables.put(ConstantUtil.ACCEPTANCE_SHEET_ASSIGNEE, admin.getId());
        //查询条件：验收单编号/业务编号/核心企业名称/业务名称/供应商名称

//        Enterprise supplier = enterpriseService.getById(acceptanceBasicInfo.getSupplierId());
        Enterprise supplier = enterpriseService.getById(acceptanceBasicInfo.getcSupplierInfoId());
//        ProjectCoreEnterprise projectCoreEnterprise = projectCoreEnterpriseService.get(
//            acceptanceBasicInfo.getcProjectCoreEnterpriseId());
        Enterprise customer = enterpriseService.getById(acceptanceBasicInfo.getcProjectCoreEnterpriseId());

        String queryBusiness = acceptanceBasicInfo.getAcceptanceNumber() + FlowableUtil.splitChar + acceptanceBasicInfo.getBusinessNumber()
                + FlowableUtil.splitChar + customer.getCorporateName() + FlowableUtil.splitChar + projectInformation.getProjectName()
                + FlowableUtil.splitChar + supplier.getCorporateName();
        ProcessInstance processInst = flowableService.startProcessInstance(acceptanceBasicInfo, procVariables,
                FlowableUtil.generateBusinessKey(acceptanceBasicInfo, ConstantUtil.ACCEPTANCE_SHEET, queryBusiness), null, ConstantUtil.ACCEPTANCE_SHEET);
        if (processInst == null) {
            throw new BusinessException(CodeUtil.FAIL, "流程启动失败");
        }
        //添加历史信息
        Long historyId = addHistoryAcceptanceSheet(acceptanceBasicInfo);
        acceptanceBasicInfo.setId(odlId);
        //完成流程第一步
        // 步提交验收单，开启下一步法务验收
        String processInstId = processInst.getId();
        Map<String, Object> msgVariables = new HashMap<>();
        Task task = flowableService.findRuntimeTaskByProcessInstId(processInstId).get(0);
        if (acceptanceBasicInfo.getApproval().equals(1)) {
            User user = new User();
            user.setId(Long.parseLong(task.getAssignee()));
            ThreadLocalUtil.setUser(user);
            if(acceptanceBasicInfo.getSignConfirm().equals(1)){
                procVariables.put(ConstantUtil.ACCEPTANCE_SIGN_CONFIRM_ASSIGNEE, admin.getId());
                procVariables.put("result", "签署确认");
                msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "验收单编号：" + acceptanceBasicInfo.getAcceptanceNumber());
                msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                    "验收单编号为“" + acceptanceBasicInfo.getAcceptanceNumber() + "”的验收单已进入“"
                        + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.ACCEPTANCE_SHEET) + "—签署确认阶段，"
                        + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
                flowableService.completeMyTask(task.getId(), acceptanceBasicInfo, procVariables, null, historyId, msgVariables, ConstantUtil.ACCEPTANCE_SHEET);
            }else if(acceptanceBasicInfo.getSignConfirm().equals(0)){

                procVariables.put(ConstantUtil.ACCEPTANCE_SHEET_APPROVAL_CANDIDATE, legalSpecias);
                procVariables.put("result", "法务审核");
                msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "验收单编号：" + acceptanceBasicInfo.getAcceptanceNumber());
                msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                    "验收单编号为“" + acceptanceBasicInfo.getAcceptanceNumber() + "”的验收单已进入“"
                        + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.ACCEPTANCE_SHEET) + "—法务审核阶段，"
                        + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
                 flowableService.completeMyTask(task.getId(), acceptanceBasicInfo, procVariables, null, historyId, msgVariables, ConstantUtil.ACCEPTANCE_SHEET, legalSpecialists);
            }
        } else if (acceptanceBasicInfo.getApproval().equals(0)) {
            //如果不申请审核 则由业务经理处理 下一步内容
            procVariables.put(ConstantUtil.ACCEPTANCE_BUSINESS_APPROVAL_CANDIDATE, projectManageStr);
            procVariables.put("result", "否");
            msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "验收单编号：" + acceptanceBasicInfo.getAcceptanceNumber());
            msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                "验收单编号为“" + acceptanceBasicInfo.getAcceptanceNumber() + "”的验收单已进入“"
                    + ConstantConversionUtil.flowBusinessKeyNames.get(ConstantUtil.ACCEPTANCE_SHEET) + "—业务经理审核阶段，"
                    + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
            User user = new User();
            user.setId(Long.parseLong(task.getAssignee()));
            ThreadLocalUtil.setUser(user);
            flowableService.completeMyTask(task.getId(), acceptanceBasicInfo, procVariables, null, historyId, msgVariables, ConstantUtil.ACCEPTANCE_SHEET,projectManage);
        }

    }


    //填充是否展示下载文件按钮
    private void autoButtonFlag(BusinessProcessingTaskVo processingTaskVo) {
        Dictionary approvalDict = dictService.getByCode(ProjectInitiationStatusDict.ChildEnum.COMPLETED.getCode());
        processingTaskVo.setDownloadFileFlag(false);
        if (approvalDict.getId().equals(processingTaskVo.getStatus().getId())) {
            processingTaskVo.setDownloadFileFlag(true);
        }
    }

    /**
     * @param oldAcceptanceBasicInfo
     * @return
     */
    public Long addHistoryAcceptanceSheet(AcceptanceBasicInfo oldAcceptanceBasicInfo) {
        Integer steelWaiter = oldAcceptanceBasicInfo.getSteelWaiter();
        List<String> sellBillNumber = oldAcceptanceBasicInfo.getSellBillNumber();
        Long oldId = oldAcceptanceBasicInfo.getId();
        //保存基础信息
        AcceptanceHisInfo acceptanceHisInfo = new AcceptanceHisInfo();
        BeanUtils.copyProperties(oldAcceptanceBasicInfo, acceptanceHisInfo, "id");
        //保存历史基础信息
        acceptanceHisInfoService.save(acceptanceHisInfo);
        //保存相关货物信息
        List<AcceptanceGoodsInfo> acceptanceGoodInfos = oldAcceptanceBasicInfo.getAcceptanceGoodInfos();
        List goodList = new ArrayList();
        if (CollectionUtil.isNotEmpty(acceptanceGoodInfos)) {
            for (AcceptanceGoodsInfo acceptanceBusinessGood : acceptanceGoodInfos) {
                AcceptanceHisGoodsInfo acceptanceHisGoodsInfo = new AcceptanceHisGoodsInfo();
                BeanUtils.copyProperties(acceptanceBusinessGood, acceptanceHisGoodsInfo);
                acceptanceHisGoodsInfo.setAcceptanceHisInfoId(acceptanceHisInfo.getId());
                goodList.add(acceptanceHisGoodsInfo);
            }
        }
        //保存历史货物信息
        acceptanceHisGoodsInfoService.saveBatch(goodList);

        //历史附件信息
        List<FileStorageDO> fileStorageDOs = oldAcceptanceBasicInfo.getFileStorageDOList();
        List<FileStorageDO> supplementFileDos = oldAcceptanceBasicInfo.getSupplementFiles();

        //保存验收单文件历史
        if (CollectionUtil.isNotEmpty(fileStorageDOs)) {
            for(FileStorageDO fileStorageDO:fileStorageDOs){
                FileStorageDO fileStorageDOHis = new FileStorageDO();
                BeanUtils.copyProperties(fileStorageDO, fileStorageDOHis,"id");
                fileStorageDOHis.setBusinessType(FileModuleDict.ChildEnum.ACCEPTANCE_HIS_FILE.getCode());
                fileStorageDOHis.setBusinessId(acceptanceHisInfo.getId());
                fileService.save(fileStorageDOHis);
            }

        }

        if (CollectionUtil.isNotEmpty(supplementFileDos)) {
            supplementFileDos.forEach(fileStorageDO -> {
                FileStorageDO fileStorageDOHis = new FileStorageDO();
                BeanUtils.copyProperties(fileStorageDO, fileStorageDOHis,"id");
                fileStorageDOHis.setBusinessType(FileModuleDict.ChildEnum.ACCEPTANCE_HIS_SUPPLEMENT_FILE.getCode());
                fileStorageDOHis.setBusinessId(acceptanceHisInfo.getId());
                fileService.save(fileStorageDOHis);
            });
        }
        //保存生成的验收单历史
        if (CollectionUtil.isNotEmpty(oldAcceptanceBasicInfo.getAcceptanceUpstreamFiles())) {
            for (FileStorageDO f : oldAcceptanceBasicInfo.getAcceptanceUpstreamFiles()) {
                FileStorageDO fileStorageDOHis = new FileStorageDO();
                BeanUtils.copyProperties(f, fileStorageDOHis,"id");
                fileStorageDOHis.setBusinessType(FileModuleDict.ChildEnum.ACCEPTANCE_HIS_UPSTREAM_FILE.getCode());
                fileStorageDOHis.setBusinessId(acceptanceHisInfo.getId());
                fileService.save(fileStorageDOHis);
            }
        }

        //保存历史人员信息
//        List<AcceptancePersonInfo> acceptancePersonInfos = acceptancePersonInfoService.lambdaQuery()
//                .eq(AcceptancePersonInfo::getAcceptanceBasicInfoId, oldId).list();
        List<AcceptancePersonInfo> acceptancePersonInfos = oldAcceptanceBasicInfo.getAcceptancePersonInfos();
        acceptancePersonInfos.forEach(r -> {
            AcceptancePersonInfoHistory acceptancePersonInfoHistory = new AcceptancePersonInfoHistory();
            BeanUtils.copyProperties(r, acceptancePersonInfoHistory, "id");
            acceptancePersonInfoHistory.setAcceptanceBasicInfoId(acceptanceHisInfo.getId());
            acceptancePersonInfoHistoryService.save(acceptancePersonInfoHistory);
        });
        if (steelWaiter.equals(1)) {
            if (CollectionUtil.isNotEmpty(sellBillNumber)) {
                sellBillNumber.forEach(r -> {
                    //保存验收单和钢小二订单关联关系
                    AcceptanceSellBillRefHis acceptanceSellBillRefHis = new AcceptanceSellBillRefHis();
                    acceptanceSellBillRefHis.setAcceptanceHisInfoId(acceptanceHisInfo.getId());
                    acceptanceSellBillRefHis.setSellBillNumber(r);
                    acceptanceSellBillRefHisService.save(acceptanceSellBillRefHis);
                });

            } else {
                throw new ValidatorException(CodeUtil.FAIL, "钢小二单号必填！");
            }
        }
        return acceptanceHisInfo.getId();
    }

    /**
     * 填充销售合同附件
     *
     * @param acceptanceBasicInfo
     */
    void autoSalesFiles(AcceptanceBasicInfo acceptanceBasicInfo) {
        //销售合同 文件
        List<FileStorage> salesContract = new ArrayList<>();
        CSalesContract salesContractManagement = salesContractService.getByBusinessNumber(acceptanceBasicInfo.getBusinessNumber());
        CSalesContractBasicInfo salesContractBasicInfo = salesContractBasicInfoService
                .getOne(new QueryWrapper<CSalesContractBasicInfo>().eq("c_sales_contract_management_id", salesContractManagement.getId()));
        //销售合同原件
        //合同文件
        List<FileStorageDO> fileStorageDOS = fileService.findByBusinessId(salesContractBasicInfo.getId(), FileModuleDict.ChildEnum.SALES_CONTRACT_FILE.getCode());
        if (CollectionUtil.isNotEmpty(fileStorageDOS)) {
            fileStorageDOS.forEach(fileStorageDO -> {
                FileStorage fileStorage = new FileStorage();
                fileStorage.setAbsolutePath(fileStorageDO.getAbsolutePath());
                fileStorage.setName(fileStorageDO.getOriginalName());
                fileStorage.setPath(fileStorageDO.getPath());
                fileStorage.setId(fileStorageDO.getId());
                fileStorage.setOriginalName(fileStorageDO.getOriginalName());
                salesContract.add(fileStorage);
            });
        }
        //已签署的文件
        CSalesSignConfirmation salesSignConfirmation = salesSignConfirmationService
                .lambdaQuery().eq(CSalesSignConfirmation::getcSalesContractManagementId, salesContractManagement.getId()).one();
        if (salesSignConfirmation != null) {
            List<CSalesSignConfirmationElectronicInfo> signElectronicInfos = signConfirmationElectronicInfoService
                    .list(new QueryWrapper<CSalesSignConfirmationElectronicInfo>().eq("c_sales_sign_confirmation_id", salesSignConfirmation.getId()));
            if (CollectionUtil.isNotEmpty(signElectronicInfos)) {
                signElectronicInfos.forEach(signElectronicInfo -> {
                    salesContract.addAll(sysAttachmentRefService.getFiles(AttachmentDto.builder()
                            .setChildEnum(FileModuleDict.ChildEnum.SIGN_CONFIRM_BACK_FILE).setEntityId(signElectronicInfo.getId()).build()));
                });
            }
        }
        //销售合同补充文件
        List<CSalesContractSupplementInfo> salesContractSupplementInfos = salesContractSupplementInfoService
                .list(new QueryWrapper<CSalesContractSupplementInfo>().eq("c_sales_contract_management_id", salesContractManagement.getId()));
        if (CollectionUtil.isNotEmpty(salesContractSupplementInfos)) {
            salesContractSupplementInfos.stream().forEach(s -> {
                if (salesContractManagement.getContractStatus().equals(ProjectInitiationStatusDict.ChildEnum.COMPLETED.getCode())) {

                    //补充合同原件
                    CSalesContractSupplementBasicInfo salesContractSupplementBasicInfo = salesContractSupplementBasicInfoService.lambdaQuery()
                            .eq(CSalesContractSupplementBasicInfo::getcSalesContractSupplementInfoId, s.getId())
                            .one();
                    List<FileStorageDO> SupplementFileStorageDOS = fileService.findByBusinessId(salesContractSupplementBasicInfo.getId(),
                            FileModuleDict.ChildEnum.SALES_CONTRACT_SUPPLEMENT_CONTRACT_FILE.getCode());
                    if (CollectionUtil.isNotEmpty(SupplementFileStorageDOS)) {
                        SupplementFileStorageDOS.forEach(fileStorageDO -> {
                            FileStorage fileStorage = new FileStorage();
                            fileStorage.setAbsolutePath(fileStorageDO.getAbsolutePath());
                            fileStorage.setName(fileStorageDO.getOriginalName());
                            fileStorage.setPath(fileStorageDO.getPath());
                            fileStorage.setId(fileStorageDO.getId());
                            fileStorage.setOriginalName(fileStorageDO.getOriginalName());
                            salesContract.add(fileStorage);
                        });
                    }

                    CSalesSupplementSignConfirmation salesSupplementSignConfirmation = salesSupplementSignConfirmationService
                            .lambdaQuery().eq(CSalesSupplementSignConfirmation::getcSalesContractSupplementInfoId, s.getId()).one();
                    if (salesSupplementSignConfirmation != null) {
                        List<CSalesSupplementSignConfirmationElectronicInfo> supplementSignConfirmationElectronicInfos = salesSupplementSignConfirmationElectronicInfoService
                                .lambdaQuery().eq(CSalesSupplementSignConfirmationElectronicInfo::getcSalesSupplementSignConfirmationId, salesSupplementSignConfirmation.getId()).list();
                        if (CollectionUtil.isNotEmpty(supplementSignConfirmationElectronicInfos)) {
                            //获取销售合同补充签署的附件
                            supplementSignConfirmationElectronicInfos.forEach(supplementSignConfirmationElectronicInfo -> {
                                List<FileStorage> salesContractSupplementFiles = sysAttachmentRefService.getFiles(AttachmentDto.builder()
                                        .setChildEnum(FileModuleDict.ChildEnum.SALES_SUPPLEMENT_SIGN_CONFIRM_BACK_FILE)
                                        .setEntityId(supplementSignConfirmationElectronicInfo.getId()).build());
                                salesContract.addAll(salesContractSupplementFiles);
                            });
                        }

                    }
                }
            });
        }
        acceptanceBasicInfo.setSaleContractFiles(salesContract);
    }

    /**
     * 填充采购合同附件
     *
     * @param acceptanceBasicInfo
     */
    void autoPurchFiles(AcceptanceBasicInfo acceptanceBasicInfo) {
        //采购合同 文件
        PurchContractManagement purchContractManagement = purchContractService
                .getOne(new QueryWrapper<PurchContractManagement>().eq("business_number", acceptanceBasicInfo.getBusinessNumber())
                );  //.eq("c_supplier_info_id", acceptanceBasicInfo.getcSupplierInfoId())
        PurchContractBasicInfo purchContractBasicInfo = purchContractBasicInfoService.lambdaQuery().eq(PurchContractBasicInfo::getPurchContractManagementId, purchContractManagement.getId()).one();

        List<FileStorage> purchaseContract = sysAttachmentRefService.getFiles(AttachmentDto.builder()
                .setChildEnum(FileModuleDict.ChildEnum.PURCHASE_CONTRACT_SIGN_FILE)
                .setEntityId(purchContractBasicInfo.getId()).build());

        //采购合同补充合同
        List<PurchContractSupplementInfo> contractSupplementInfos = purchContractSupplementInfoService
                .list(new QueryWrapper<PurchContractSupplementInfo>().eq("c_purch_contract_management_id", purchContractManagement.getId()));
        //采购合同状态
        if (purchContractManagement.getContractStatus().equals(ProjectInitiationStatusDict.ChildEnum.COMPLETED.getCode())) {
            if (CollectionUtil.isNotEmpty(contractSupplementInfos)) {
                contractSupplementInfos.stream().forEach(contractSupplementInfo -> {
                    //采购合同变更已签署文件
                    AttachmentDto attachmentDto = AttachmentDto.builder()
                            .setEntityId(contractSupplementInfo.getId())
                            .setChildEnum(FileModuleDict.ChildEnum.PURCHASE_CONTRACT_SUPPLEMENT_SIGN_FILE).build();
                    purchaseContract.addAll(attachmentRefService.getFiles(attachmentDto));

                });
            }
        }
        acceptanceBasicInfo.setProcureContractFile(purchaseContract);
    }

}
