package com.inkasso.factoring.acceptanceManagement.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil;
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.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import com.google.common.collect.Lists;
import com.inkasso.adapter.exception.BusinessException;
import com.inkasso.adapter.exception.ServiceException;
import com.inkasso.adapter.util.CodeUtil;
import com.inkasso.adapter.util.CollectionUtil;
import com.inkasso.adapter.util.ValidatorUtil;
import com.inkasso.adapter.web.LoginUserHolder;
import com.inkasso.auth.exception.ValidatorException;
import com.inkasso.factoring.acceptanceManagement.dao.CAcceptanceBasicInfoMapper;
import com.inkasso.factoring.acceptanceManagement.entity.*;
import com.inkasso.factoring.acceptanceManagement.entity.vo.AcceptanceListVo;
import com.inkasso.factoring.acceptanceManagement.entity.vo.CAcceptanceGoodsExcelInfo;
import com.inkasso.factoring.acceptanceManagement.service.ICAcceptanceBasicInfoService;
import com.inkasso.factoring.acceptanceManagement.service.ICAcceptanceGoodsInfoService;
import com.inkasso.factoring.acceptanceManagement.service.ICAcceptancePersonInfoService;
import com.inkasso.factoring.acceptanceManagement.service.ICAcceptanceSellBillRefService;
import com.inkasso.factoring.biddingManagement.entity.vo.BiddingBasicInfoResultVo;
import com.inkasso.factoring.common.constant.ConstantUtil;
import com.inkasso.factoring.common.dict.impl.FileModuleDict;
import com.inkasso.factoring.common.dict.impl.InvoiceDict;
import com.inkasso.factoring.common.entity.GridPage;
import com.inkasso.factoring.common.entity.ResponseJson;
import com.inkasso.factoring.common.entity.ValidatorEntity;
import com.inkasso.factoring.common.enums.AcceptanceStageEnum;
import com.inkasso.factoring.common.enums.ProjectInitiationStatusEnum;
import com.inkasso.factoring.common.enums.SalesContractPersonTypeEnum;
import com.inkasso.factoring.common.service.SerialNumberGenerator;
import com.inkasso.factoring.common.util.DateUtil;
import com.inkasso.factoring.common.util.WordWriter;
import com.inkasso.factoring.common.util.excel.ExcelLogs;
import com.inkasso.factoring.common.util.excel.ExcelUtil;
import com.inkasso.factoring.common.util.onlineConverter.OfficeConverterUtil;
import com.inkasso.factoring.common.util.xml.XMlToDoc;
import com.inkasso.factoring.creditmanagement.entity.Enterprise;
import com.inkasso.factoring.creditmanagement.service.IEnterpriseService;
import com.inkasso.factoring.creditmanagement.service.ISupplierInfoService;
import com.inkasso.factoring.dict.entity.Dictionary;
import com.inkasso.factoring.dict.service.DictionaryService;
import com.inkasso.factoring.file.entity.FileStorage;
import com.inkasso.factoring.file.entity.FileStorageDO;
import com.inkasso.factoring.file.enums.FileTypeEnum;
import com.inkasso.factoring.file.model.dto.AttachmentDto;
import com.inkasso.factoring.file.service.FileService;
import com.inkasso.factoring.file.service.FileStorageService;
import com.inkasso.factoring.file.service.ISysAttachmentRefService;
import com.inkasso.factoring.file.util.FileStorageUtil;
import com.inkasso.factoring.invoicemanage.entity.InvoiceBasicInfo;
import com.inkasso.factoring.invoicemanage.service.InvoiceBasicInfoService;
import com.inkasso.factoring.purchManagement.entity.*;
import com.inkasso.factoring.purchManagement.entity.vo.PurchContractCompletedVo;
import com.inkasso.factoring.purchManagement.service.*;
import com.inkasso.factoring.salesManagement.entity.CSalesContractBasicInfo;
import com.inkasso.factoring.salesManagement.entity.CSalesContractManagement;
import com.inkasso.factoring.salesManagement.entity.CSalesContractPersonInfo;
import com.inkasso.factoring.salesManagement.service.ICSalesContractBasicInfoService;
import com.inkasso.factoring.salesManagement.service.ICSalesContractManagementService;
import com.inkasso.factoring.salesManagement.service.ICSalesContractPersonInfoService;
import com.inkasso.factoring.settlement.entity.SettlementBasicInfo;
import com.inkasso.factoring.settlement.entity.SettlementGoodsInfo;
import com.inkasso.factoring.settlement.service.SettlementBasicInfoService;
import com.inkasso.factoring.settlement.service.SettlementGoodsInfoService;
import com.inkasso.factoring.steelwaiter.service.ISellBillFileRefService;
import com.inkasso.factoring.steelwaiter.service.ISellBillItemService;
import com.inkasso.factoring.steelwaiter.service.ISellBillService;
import com.inkasso.factoring.steelwaiter.service.SteelWaiterService;
import com.inkasso.factoring.tradingPlatform.entity.Platform;
import com.inkasso.factoring.tradingPlatform.service.ITradingPlatformService;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 下游验收单-基础信息表 服务实现类
 * </p>
 *
 * @author yafan
 * @since 2023-11-30
 */
@Service
public class CAcceptanceBasicInfoServiceImpl extends ServiceImpl<CAcceptanceBasicInfoMapper, CAcceptanceBasicInfo>
        implements ICAcceptanceBasicInfoService {

    private static final Integer SUBMIT = 1;

    @Autowired
    private ICPurchContractManagementService purchContractManagementService;
    @Autowired
    private ICPurchContractBasicInfoService purchContractBasicInfoService;
    @Autowired
    private ICSalesContractBasicInfoService salesContractBasicInfoService;
    @Autowired
    private ICSalesContractManagementService salesContractManagementService;
    @Autowired
    private ICPurchContractBuyerSellerService purchContractBuyerSellerService;
    @Autowired
    private IPurchContractNeedUserRelService purchContractNeedUserRelService;
    @Autowired
    private PurchContractApprovalService purchContractApprovalService;
    @Autowired
    private ICSalesContractPersonInfoService salesContractPersonInfoService;
    @Autowired
    private ICAcceptanceGoodsInfoService acceptanceGoodsInfoService;
    @Autowired
    private SerialNumberGenerator serialNumberGenerator;
    @Autowired
    private FileService fileService;
    @Autowired
    private IEnterpriseService enterpriseService;
    @Autowired
    private ITradingPlatformService platformService;
    @Autowired
    private ICAcceptancePersonInfoService acceptancePersonInfoService;
    @Autowired
    private ICSalesContractManagementService salesContractService;
    @Autowired
    private ICPurchContractManagementService purchContractService;
    @Autowired
    private RestTemplate restTemplate;
    //@Autowired
   // private SettlementBasicInfoService settlementBasicInfoService;
    @Autowired
    private SettlementGoodsInfoService settlementGoodsInfoService;
    @Autowired
    private InvoiceBasicInfoService invoiceBasicInfoService;
    @Autowired
    private DictionaryService dictionaryService;
    @Autowired
    private ISysAttachmentRefService attachmentRefService;
    @Autowired
    private FileStorageService fileStorageService;



    @Value("${trade.acceptanceStartProcessUrl}")
    private String acceptanceStartProcessUrl;
    @Value("${trade.acceptanceUpdateDetailHandleProcessUrl}")
    private String acceptanceUpdateDetailHandleProcessUrl;
    @Value("${trade.acceptanceDeleteUrl}")
    private String acceptanceDeleteUrl;
    @Value("${trade.doBusinessHistoryView}")
    private String doBusinessHistoryView;
    @Autowired
    private ICAcceptanceSellBillRefService acceptanceSellBillRefService;
    @Autowired
    private SteelWaiterService steelWaiterService;
    @Autowired
    private ISellBillService sellBillService;
    @Autowired
    private ISellBillItemService sellBillItemService;
    @Autowired
    private ISellBillFileRefService sellBillFileRefService;
    @Autowired
    private ISupplierInfoService supplierInfoService;

    @Override
    public List<CAcceptancePersonInfo> personInfoList(String businessNumber) {

        CPurchContractManagement purchContractManagement = purchContractManagementService.getOne(new QueryWrapper<CPurchContractManagement>()
                .eq("business_number", businessNumber));

        CPurchContractBasicInfo purchContractBasicInfo = purchContractBasicInfoService.getOne(new QueryWrapper<CPurchContractBasicInfo>()
                .eq("c_purch_contract_management_id", purchContractManagement.getId()));
        CSalesContractManagement salesContractManagement = salesContractManagementService
                .getOne(new QueryWrapper<CSalesContractManagement>().eq("business_number", businessNumber));
        CSalesContractBasicInfo salesContractBasicInfo = salesContractBasicInfoService.getOne(new QueryWrapper<CSalesContractBasicInfo>()
                .eq("c_sales_contract_management_id", salesContractManagement.getId()));

        //采购合同供应商发货人
        List<CPurchContractBuyerSeller> purchContractSellers = purchContractBuyerSellerService.lambdaQuery().eq(CPurchContractBuyerSeller::getBuyerOrSeller, 2)
                .eq(CPurchContractBuyerSeller::getPurchContractBasicInfoId, purchContractBasicInfo.getId()).list();
        //销售合同 验收经办人
        List<CSalesContractPersonInfo> salesContractPersonInfos = salesContractPersonInfoService.lambdaQuery()
                .eq(CSalesContractPersonInfo::getcSalesContractBasicInfoId, salesContractBasicInfo.getId())
                .eq(CSalesContractPersonInfo::getType, SalesContractPersonTypeEnum.SALESCONTRACTPERSONTYPE_ACCEPTANCE.getCode()).list();
        List<CAcceptancePersonInfo> acceptancePersonInfos = new ArrayList<>();
        purchContractSellers.forEach(r -> {
            CAcceptancePersonInfo acceptancePersonInfo = new CAcceptancePersonInfo();
            acceptancePersonInfo.setName(r.getName());
            acceptancePersonInfo.setCardType("身份证");
            acceptancePersonInfo.setMobile(r.getContact());
            acceptancePersonInfo.setSocialCreditCode(r.getIdCard());
            acceptancePersonInfo.setType("验收经办人（供应商）");
            acceptancePersonInfos.add(acceptancePersonInfo);
        });
        salesContractPersonInfos.forEach(r -> {
            CAcceptancePersonInfo acceptancePersonInfo = new CAcceptancePersonInfo();
            BeanUtils.copyProperties(r, acceptancePersonInfo, "id");
            acceptancePersonInfo.setType("验收经办人（核心企业）");
            acceptancePersonInfos.add(acceptancePersonInfo);
        });
        return acceptancePersonInfos;
    }

    @Override
    public CAcceptanceBasicInfo findDetail(Long acceptanceBasicInfoId) {
        //验收单基础信息
        CAcceptanceBasicInfo acceptanceBasicInfo = getById(acceptanceBasicInfoId);
        Long userId = LoginUserHolder.get().getId();
        PurchContractCompletedVo purchContractCompletedVo = this.baseMapper.getPurchContractByBusinessNumber(
                userId, acceptanceBasicInfo.getBusinessNumber());
        if (purchContractCompletedVo != null) {
            if (purchContractCompletedVo.getCoreEnterpriseId() != null) {
                Enterprise coreEnterprise = enterpriseService.getById(purchContractCompletedVo.getCoreEnterpriseId());
                if (coreEnterprise != null) {
                    purchContractCompletedVo.setCoreEnterpriseName(coreEnterprise.getCorporateName());
                }
            }
            if (purchContractCompletedVo.getMainEnterpriseId() != null) {
                Enterprise mainEnterprise = enterpriseService.getById(purchContractCompletedVo.getMainEnterpriseId());
                if (mainEnterprise != null) {
                    purchContractCompletedVo.setMainEnterpriseName(mainEnterprise.getCorporateName());
                }
            }
            if (purchContractCompletedVo.getPlatformId() != null) {
                Platform platform = platformService.getById(purchContractCompletedVo.getPlatformId());
                if (platform != null) {
                    purchContractCompletedVo.setPlatformName(platform.getPlatformName());
                }
            }
            //经办人（供应商）
            CPurchContractBuyerSeller cPurchContractBuyerSeller = purchContractBuyerSellerService.getOne(new QueryWrapper<CPurchContractBuyerSeller>().eq("c_purch_contract_basic_info_id", purchContractCompletedVo.getcPurchContractBasicInfoId()).orderByDesc("gmt_modified")
                    .last("limit 1"));
            purchContractCompletedVo.setOperatorSupplier(cPurchContractBuyerSeller.getName());
        }
        acceptanceBasicInfo.setPurchContractCompletedVo(purchContractCompletedVo);

        //验收单货物信息
        List<CAcceptanceGoodsInfo> businessGoods =
                acceptanceGoodsInfoService.list(new QueryWrapper<CAcceptanceGoodsInfo>()
                        .eq("c_acceptance_basic_info_id", acceptanceBasicInfo.getId()));
        if (CollectionUtil.isNotEmpty(businessGoods)) {
            businessGoods.stream().forEach(
                    u -> u.setSalesPriceStr(u.getSalesPrice() != null ? u.getSalesPrice().toString() : "")
            );
        }
        //查询钢小二的单号
        List<CAcceptanceSellBillRef> list = acceptanceSellBillRefService.lambdaQuery()
                .eq(CAcceptanceSellBillRef::getcAcceptanceBasicInfoId, acceptanceBasicInfoId).list();
        if (CollectionUtil.isNotEmpty(list)) {
            List<String> collect = list.stream().map(CAcceptanceSellBillRef::getSellBillNumber)
                    .collect(Collectors.toList());
            acceptanceBasicInfo.setSellBillNumber(collect);
        }
        acceptanceBasicInfo.setAcceptanceGoodInfos(businessGoods);
        //验收单附件信息
        List<FileStorageDO> fileStorageDOList = fileService.findByBusinessId(acceptanceBasicInfoId, FileTypeEnum.ACCEPTANCE_FILE.getCode());
        acceptanceBasicInfo.setFileStorageDOList(fileStorageDOList);

        List<FileStorageDO> supplementFileList = fileService.findByBusinessId(acceptanceBasicInfoId, FileTypeEnum.ACCEPTANCE_SUPPLEMENT_FILE.getCode());
        acceptanceBasicInfo.setSupplementFiles(supplementFileList);

        List<FileStorageDO> acceptanceUpstreamFile = fileService.findByBusinessId(acceptanceBasicInfoId, FileTypeEnum.ACCEPTANCE_UPSTREAM_FILE.getCode());
        acceptanceBasicInfo.setAcceptanceUpstreamFiles(acceptanceUpstreamFile);


        //供应商
        acceptanceBasicInfo.setMainEnterprise(enterpriseService.getById(acceptanceBasicInfo.getcSupplierInfoId()));
        //核心企业
        acceptanceBasicInfo.setCoreEnterprise(enterpriseService.getById(acceptanceBasicInfo.getcProjectCoreEnterpriseId()));
        //贸易平台
        acceptanceBasicInfo.setPlatform(platformService.getById(acceptanceBasicInfo.getTradingPlatformId()));
        //人员信息
        List<CAcceptancePersonInfo> acceptancePersonInfos = acceptancePersonInfoService.lambdaQuery().eq(CAcceptancePersonInfo::getcAcceptanceBasicInfoId, acceptanceBasicInfoId).list();
        acceptanceBasicInfo.setAcceptancePersonInfos(acceptancePersonInfos);
        return acceptanceBasicInfo;
    }

    /**
     * 时间轴
     * @param id
     */
    @Override
    public ResponseJson timeLine(Long id) {
        String url = doBusinessHistoryView +"?businessKey="+id+"&businessType=AcceptanceSheet";
        ResponseJson forObject = restTemplate.getForObject(url, ResponseJson.class);
        return  forObject;
    }


    /**
     *  新增页面 直接提交   或者暂存 后再提交 调用该接口
     * @param acceptanceBasicInfo
     * @param request
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseJson add(CAcceptanceBasicInfo acceptanceBasicInfo, HttpServletRequest request) throws Exception {
        if (acceptanceBasicInfo.getId() != null ) {
            //更新
            updateAcceptanceSheet(acceptanceBasicInfo,request);
            updateById(acceptanceBasicInfo);
        } else {
            //保存验收单信息
            addAcceptanceSheet(acceptanceBasicInfo, request);
        }
        //新建验收单完成后需要开启法务流程并完成第一步流程Z
        //SUBMIT.equals(acceptanceBasicInfo.getApproval()) &&
        if (SUBMIT.equals(acceptanceBasicInfo.getSubmitStatus())) {
            acceptanceBasicInfo.setStage(AcceptanceStageEnum.ACCEPTANCE_ENTER.getCode());
            acceptanceBasicInfo.setAcceptanceStatus(ProjectInitiationStatusEnum.PROCESSING.getCode());
            //更新一下业务状态
            updateById(acceptanceBasicInfo);
            // 发送JSON格式的POST请求
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<CAcceptanceBasicInfo> httpEntity = new HttpEntity<>(acceptanceBasicInfo, headers);
            try {
                ResponseEntity<ResponseJson> response = restTemplate.postForEntity(
                    acceptanceStartProcessUrl, httpEntity, ResponseJson.class);
                Integer code = response.getBody().getCode();
                if(code!=200){
                    throw new BusinessException(CodeUtil.FAIL, "贸理通B端处理失败!");
                }
            } catch (Exception e) {
                String result = e.getMessage().substring(7, e.getMessage().length() - 1);
                cn.hutool.json.JSONObject jsonObject = new cn.hutool.json.JSONObject(result);
                throw new BusinessException(CodeUtil.FAIL, jsonObject.get("msg").toString());
            }
        }

        return new ResponseJson(acceptanceBasicInfo);

    }

    /**
     * 申请审核
     * @param id
     * @return
     */
    @Override
    public ResponseJson applyApprval(Long id,Long taskId) {
        CAcceptanceBasicInfo acceptanceBasicInfo = findDetail(id);
        acceptanceBasicInfo.setSubmitStatus(1);
        acceptanceBasicInfo.setApproval(1);
        acceptanceBasicInfo.setTaskId(taskId.toString());
        acceptanceBasicInfo.setStage(AcceptanceStageEnum.ACCEPTANCE_ENTER.getCode());
        acceptanceBasicInfo.setAcceptanceStatus(ProjectInitiationStatusEnum.PROCESSING.getCode());

        this.updateById(acceptanceBasicInfo);
         // 发送JSON格式的POST请求
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<CAcceptanceBasicInfo> httpEntity = new HttpEntity<>(acceptanceBasicInfo, headers);
        try {
            ResponseEntity<ResponseJson> response = restTemplate.postForEntity(
                acceptanceUpdateDetailHandleProcessUrl, httpEntity, ResponseJson.class);
            Integer code = response.getBody().getCode();
            if(code!=200){
                throw new BusinessException(CodeUtil.FAIL, "贸理通B端处理失败!");
            }
        } catch (Exception e) {
            String result = e.getMessage().substring(7, e.getMessage().length() - 1);
            cn.hutool.json.JSONObject jsonObject = new cn.hutool.json.JSONObject(result);
            throw new BusinessException(CodeUtil.FAIL, jsonObject.get("msg").toString());
        }

        return new ResponseJson("操作成功！");
    }

    /**
     * 删除验收单
     * @param id
     */
    @Override
    public void deleteAcceptance(Long id) {
        String url = acceptanceDeleteUrl+"?id="+id;
        ResponseJson forObject = restTemplate.getForObject(url, ResponseJson.class);
        if(forObject!=null && forObject.getCode()==200){

        }else{
            new BusinessException(CodeUtil.FAIL, "验收单删除失败");
        }

    }


    @Override
    public List<FileStorageDO> createAcceptance(Long basicInfoId) {
        if (basicInfoId != null) {

            List<FileStorageDO> fileStorageDOS = new ArrayList<>();
            CAcceptanceBasicInfo acceptanceBasicInfo = getById(basicInfoId);
            try {
                XMlToDoc xmlDoc = new XMlToDoc();
                //模板中填充数据
                List<File> fileList = inputData(acceptanceBasicInfo, xmlDoc);

                if (CollectionUtil.isNotEmpty(fileList)) {
                    int a = 1;
                    for (File file : fileList) {
                        //int lastIndexOf = file.getName().lastIndexOf(".");
                        String fileName = file.getName().toLowerCase(Locale.ROOT);
                        //String name = fileName.substring(0, lastIndexOf);
//                       FileStorageDO fileStorage1 = FileStorageUtil.createFileStorage2(name, file.getName().substring(lastIndexOf),
////                                FileTypeEnum.ACCEPTANCE_UPSTREAM_FILE);
                        FileStorageDO fileStorage = new FileStorageDO();
                        fileStorage.setPath(FileTypeEnum.ACCEPTANCE_UPSTREAM_FILE.getCode() + File.separator + fileName);
                        fileStorage.setAbsolutePath(file.getPath());
                        fileStorage.setBusinessId(acceptanceBasicInfo.getId());
                        fileStorage.setBusinessType(FileTypeEnum.ACCEPTANCE_UPSTREAM_FILE.getCode());
                        fileStorage.setType(".pdf");
                        fileStorage.setStorageType("disk");
                        fileStorage.setOriginalName(acceptanceBasicInfo.getAcceptanceNumber() + "_" + a + ".pdf");
                        fileService.save(fileStorage);
                        fileStorageDOS.add(fileStorage);
                        a++;
                    }
                    ;
                }
                return fileStorageDOS;
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException(CodeUtil.FAIL, "生成验收单据出错");
            }
        } else {
            throw new BusinessException(CodeUtil.FAIL, "生成验收单据出错");
        }

    }

    @Override
    public List<File> inputData(CAcceptanceBasicInfo acceptanceBasicInfo, XMlToDoc xmlDoc) {

        List<File> fileList = new ArrayList<>();
        //业务信息
//        BusinessBasicInfo businessBasicInfo = businessBasicInfoService.getByBusinessNumber(acceptanceBasicInfo.getBusinessNumber());
        //供货商信息
        Enterprise supplier = enterpriseService.getById(acceptanceBasicInfo.getcSupplierInfoId());

        List<CAcceptanceGoodsInfo> goodsList;
        //货物信息
        if (acceptanceBasicInfo.getId() != null) {
            goodsList = acceptanceGoodsInfoService.list(new QueryWrapper<CAcceptanceGoodsInfo>().eq("c_acceptance_basic_info_id", acceptanceBasicInfo.getId()));
        } else {
            goodsList = acceptanceBasicInfo.getAcceptanceGoodInfos();
        }
        //合同信息
        CPurchContractManagement purchContractManagement = purchContractService.getOne(
                new QueryWrapper<CPurchContractManagement>()
                        .eq("business_number", acceptanceBasicInfo.getBusinessNumber()));
        CPurchContractBasicInfo purchContractBasicInfo = purchContractBasicInfoService.getOne(
                new QueryWrapper<CPurchContractBasicInfo>()
                        .eq("c_purch_contract_management_id", purchContractManagement.getId())
                        .orderByDesc("gmt_create").last("LIMIT 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()));

//        List<CPurchContractBuyerSeller> purchContractBuyerSellers = purchContractBuyerSellerService
//                .list(new QueryWrapper<CPurchContractBuyerSeller>()
//                        .eq("c_purch_contract_basic_info_id", purchContractBasicInfo.getId())
//                        .eq("buyer_or_seller", 1));

        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);


        Map<String, List<CAcceptanceGoodsInfo>> goodsMap = null;
        //以货物验收单号的维度生成验收单文件
        goodsMap = goodsList.stream().collect(Collectors.groupingBy(CAcceptanceGoodsInfo::getAcceptanceGoodsNumber));
        for (Map.Entry<String, List<CAcceptanceGoodsInfo>> goodsListEntry : goodsMap.entrySet()) {
            List<CAcceptanceGoodsInfo> goodsInfoList = goodsListEntry.getValue();
            String goodsNumber = goodsListEntry.getKey();
            //填充数据开始
            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<CAcceptancePersonInfo> acceptancePersonInfos = acceptanceBasicInfo.getAcceptancePersonInfos();
                if (CollectionUtil.isEmpty(acceptancePersonInfos)) {
                    acceptancePersonInfos = acceptancePersonInfoService.lambdaQuery()
                            .eq(CAcceptancePersonInfo::getcAcceptanceBasicInfoId, 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(goodsInfoList)) {
                    throw new ValidatorException(CodeUtil.FAIL, "请录入货物信息！");
                }
                //填充货物信息
                TableRenderData tableRenderData = makeGoodsList(goodsInfoList, dataMap);
                dataMap.put("dealGoodsList", tableRenderData);
                File docxFile = null;
                String fileName = goodsNumber == null ? "acceptance" + acceptanceBasicInfo.getBusinessNumber()
                        + DateUtil.getCurrentDate().replace("-", "").replace(":", "") +
                        LoginUserHolder.get().getId() : acceptanceBasicInfo.getAcceptanceNumber();
                docxFile = WordWriter.buildAcceptanceFile(fileName, dataMap);
                //将docx转为pdf
                // String suffix = FileUtil.getSuffix(docxFile.getName());
                //String newPath = docxFile.getAbsolutePath().replace(suffix, "pdf");
                String newPath = FileStorageUtil.getAbsoluteDir() + File.separator +
                        FileTypeEnum.ACCEPTANCE_UPSTREAM_FILE.getCode() + File.separator + UUID.randomUUID().toString() + ".pdf";

                File pdfFile = OfficeConverterUtil.office2Pdf(docxFile.getAbsolutePath(), newPath);
                docxFile.deleteOnExit();
                fileList.add(pdfFile);
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException(CodeUtil.FAIL, "下载验收清单错误" + e.getMessage());
            }
        }
        goodsMap.forEach((goodsNumber, goodsInfoList) -> {

        });
        return fileList;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<CAcceptanceGoodsExcelInfo> importGoodsInfo(MultipartFile file) {
        if (file.isEmpty()) {
            throw new BusinessException(CodeUtil.FAIL, "导入Excel文件不能为空");
        }
        try {
            InputStream inputStream = file.getInputStream();
            Collection<CAcceptanceGoodsExcelInfo> acceptanceGoodsInfo = ExcelUtil.importExcel(CAcceptanceGoodsExcelInfo.class,
                    inputStream, "yyyy-MM-dd", new ExcelLogs(), 0);
            for (CAcceptanceGoodsExcelInfo goodsInfo : acceptanceGoodsInfo) {
                int salesPriceLength = 0;
                int goodsQuantityLength = goodsInfo.getGoodsQuantity().stripTrailingZeros().scale();
                if ((salesPriceLength != 0 && salesPriceLength > 4) || goodsQuantityLength > 4) {
                    throw new ValidatorException(CodeUtil.FAIL, "导入失败，销售单价或数量小数位数过长！");
                }
                if (goodsInfo.getReferencePrice() != null) {
                    goodsInfo.setReferencePrice(goodsInfo.getReferencePrice().setScale(2, BigDecimal.ROUND_HALF_UP));
                }
                if (goodsInfo.getFloatingPrice() != null) {
                    goodsInfo.setFloatingPrice(goodsInfo.getFloatingPrice().setScale(2, BigDecimal.ROUND_HALF_UP));
                }
            }
            return (List<CAcceptanceGoodsExcelInfo>) acceptanceGoodsInfo;
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(CodeUtil.FAIL, "导入失败，请确认文件模板格式是否符合要求");
        }
    }

    @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(CodeUtil.FAIL, "下载模板失败!");
        } finally {
            try {
                inputStream.close();
                out.close();
            } catch (IOException e) {
                log.error("关闭文件流失败!");
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseJson updateDetail(CAcceptanceBasicInfo acceptanceBasicInfo, HttpServletRequest request) throws IOException {

        Long oldId = acceptanceBasicInfo.getId();
        //前端没有传验收单单号，自己查。
        String acceptanceNumber = getById(oldId).getAcceptanceNumber();
        acceptanceBasicInfo.setAcceptanceNumber(acceptanceNumber);
        //修改原始记录
        acceptanceBasicInfo = updateAcceptanceSheet(acceptanceBasicInfo, request);
        updateById(acceptanceBasicInfo);
        // Enterprise supplier = enterpriseService.getById(acceptanceBasicInfo.getcSupplierInfoId());

        acceptanceSellBillRefService.lambdaUpdate().eq(CAcceptanceSellBillRef::getcAcceptanceBasicInfoId, oldId).remove();
        if (acceptanceBasicInfo.getSteelWaiter() != null && acceptanceBasicInfo.getSteelWaiter().equals(1)) {
            List<String> sellBillNumber = acceptanceBasicInfo.getSellBillNumber();
            if (CollectionUtil.isNotEmpty(sellBillNumber)) {
                sellBillNumber.forEach(r -> {
//                    //保存钢小二订单信息
//                    SellBill sellBill = steelWaiterService.getSellBillByNumber(r, supplier.getCorporateName());
//                    sellBill.setAcceptanceBasicInfoId(oldId);
//                    sellBill.setId(null);
//                    sellBillService.save(sellBill);
//                    //保存钢小二订单货物信息
//                    List<SellBillItem> goodsByBillNumber = steelWaiterService.getGoodsByBillNumber(r, supplier.getCorporateName());
//                    for (SellBillItem sellBillItem : goodsByBillNumber) {
//                        sellBillItem.setId(null);
//                        sellBillItem.setSellBillId(sellBill.getId());
//                        sellBillItemService.save(sellBillItem);
//                    }
                    //保存钢小二订单附件信息
//                    List<FileStorageDO> fileByBillNumber = steelWaiterService.getFileByBillNumber(r, supplier.getCorporateName());
//                    for (FileStorageDO fileStorage : fileByBillNumber) {
//                        SellBillFileRef sellBillFileRef = new SellBillFileRef();
//                        sellBillFileRef.setFileId(fileStorage.getId());
//                        sellBillFileRef.setSellBillNumber(r);
//                        //sellBillFileRef.setSellBillId(sellBill.getId());
//                        sellBillFileRefService.save(sellBillFileRef);
//                    }
                    //保存验收单和钢小二订单关联关系
                    CAcceptanceSellBillRef acceptanceSellBillRef = new CAcceptanceSellBillRef();
                    acceptanceSellBillRef.setSellBillNumber(r);
                    acceptanceSellBillRef.setcAcceptanceBasicInfoId(oldId);
                    // acceptanceSellBillRef.setSellBillId(sellBill.getId());
                    acceptanceSellBillRefService.save(acceptanceSellBillRef);
                });
            } else {
                throw new ValidatorException(CodeUtil.FAIL, "钢小二单号必填！");
            }
        }

        //保存历史记录供getView方法使用
        if (SUBMIT.equals(acceptanceBasicInfo.getSubmitStatus())) {
//            if (acceptanceBasicInfo.getSignConfirm().equals(1) && acceptanceBasicInfo.getSigner() == null) {
//                throw new ValidatorException(CodeUtil.FAIL, "请选择一条验收经办人（核心企业）作为签署人！");
//            }
            // 发送JSON格式的POST请求
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            String s = JSONObject.toJSONString(acceptanceBasicInfo);
            HttpEntity<String> httpEntity = new HttpEntity<>(s, headers);

            //流程处理
            ResponseEntity<ResponseJson> jsonResponseEntity = restTemplate
                    .postForEntity(acceptanceUpdateDetailHandleProcessUrl, httpEntity, ResponseJson.class);
            return new ResponseJson(jsonResponseEntity.getBody());

        }
        return null;

    }


    @Override
    public GridPage<AcceptanceListVo> getBySearch(AcceptanceSearch search) {
        //开启分页
        //Dictionary dict = dictionaryService.getByCode(InvoiceDict.ChildEnum.PASS.getCode());
        search.setCustomerId(LoginUserHolder.get().getId());
        Page<BiddingBasicInfoResultVo> page = PageHelper.startPage(search.getPage(), search.getRows());
        List<AcceptanceListVo> list = baseMapper.getBySearch(search);
        if(CollectionUtil.isNotEmpty(list)){
            for(AcceptanceListVo v:list){
                if("业务经理审核通过".equals(v.getStage())){
                    v.setShowPriceChange(false);
                    continue;
                }
                //查询结算单的货物编号 已结算的货物无法进行价格调整
                List<SettlementGoodsInfo> list1 = settlementGoodsInfoService.lambdaQuery()
                    .likeRight(SettlementGoodsInfo::getAcceptanceGoodsNumber, v.getAcceptanceNumber())
                    .list();
                if(CollectionUtil.isEmpty(list1)){
                    v.setShowPriceChange(true);
                }else{
                    v.setShowPriceChange(false);
                }
            }
        }
        return new GridPage<>(search.getRows(), search.getPage(), page.getTotal(), list);

    }


//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public void deleteAcceptanceBasicInfo(Long id) {
//        CAcceptanceBasicInfo acceptanceBasicInfo = this.getById(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 void downLoadGoodsFile(Long id, HttpServletResponse response) {

        try {
            //验收单基础信息
            CAcceptanceBasicInfo basicInfo = getById(id);
            StringBuffer fileName = new StringBuffer("验收单货物模板");
            fileName.append(basicInfo.getAcceptanceNumber()).append(".xlsx");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName.toString(), "utf-8"));
            //创建工作簿
            SXSSFWorkbook workbook = new SXSSFWorkbook();
            //创建表
            SXSSFSheet sheet = workbook.createSheet();
            String filePath = FileStorageUtil.getFilePath(fileName.toString(), ".xlsl", FileTypeEnum.ACCEPTANCE_GOODS_FILE);
            File file = new File(filePath);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            //创建一个单元格样式
            CellStyle cellStyle = workbook.createCellStyle();
            CreationHelper createHelper = workbook.getCreationHelper();
            short dateFormat = createHelper.createDataFormat().getFormat("yyyy-MM-dd");
            cellStyle.setDataFormat(dateFormat);
            //把第二列全部设置为这个格式（0起算第一列）
            //  sheet.setDefaultColumnStyle((short)6, styleDate);

            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
            List<CAcceptanceGoodsInfo> goodsInfoList = acceptanceGoodsInfoService
                    .list(new QueryWrapper<CAcceptanceGoodsInfo>().eq("c_acceptance_basic_info_id", id));
            if (CollectionUtil.isNotEmpty(goodsInfoList)) {
                for (int i = 0; i < 9; i++) {
                    Row row = sheet.createRow(0);
                    //Cell cell = row.createCell(0);
                    //创建单元格样式对象
//                    CellStyle cellStyle = workbook.createCellStyle();
//                    Font font = workbook.createFont("*");//字体对象
//
//                    font.setColor(IndexedColors.RED.getIndex());
//                    cellStyle.setFont(font);
//
//                    cell.setCellStyle(cellStyle);

//                    cell.setCellValue("序号");
                    Cell cell1 = row.createCell(0);
                    cell1.setCellValue("货物名称");
                    Cell cell2 = row.createCell(1);
                    cell2.setCellValue("材质");
                    Cell cell3 = row.createCell(2);
                    cell3.setCellValue("型号");
                    Cell cell4 = row.createCell(3);
                    cell4.setCellValue("厂家");
                    Cell cell5 = row.createCell(4);
                    cell5.setCellValue("单位");
                    Cell cell6 = row.createCell(5);
                    cell6.setCellValue("数量");
                    Cell cell7 = row.createCell(6);
                    cell7.setCellValue("验收日期");
                    Cell cell8 = row.createCell(7);
                    cell8.setCellValue("参考价格");
                    Cell cell9 = row.createCell(8);
                    cell9.setCellValue("浮动价格");
//                    Cell cell10 = row.createCell(10);
//                    cell10.setCellValue("验收编号");
                    Cell cell11 = row.createCell(9);
                    cell11.setCellValue("货物唯一标识");
                }

                for (int i = 0; i < goodsInfoList.size(); i++) {

                    CAcceptanceGoodsInfo goods = goodsInfoList.get(i);

                    //填充货物信息
                    Row row = sheet.createRow(i + 1);
//                    Cell cell = row.createCell(0);
//                    cell.setCellValue(i + 1);
                    Cell cell1 = row.createCell(0);
                    cell1.setCellValue(goods.getGoodsName());
                    Cell cell2 = row.createCell(1);
                    cell2.setCellValue(goods.getGoodsMaterial());
                    Cell cell3 = row.createCell(2);
                    cell3.setCellValue(goods.getGoodsType());
                    Cell cell4 = row.createCell(3);
                    cell4.setCellValue(goods.getGoodsFactory());
                    Cell cell5 = row.createCell(4);
                    cell5.setCellValue(goods.getGoodsUnit());
                    Cell cell6 = row.createCell(5);
                    cell6.setCellValue(goods.getGoodsQuantity().doubleValue());
                    Cell cell7 = row.createCell(6);
                    cell7.setCellValue(goods.getAcceptanceDate());
                    cell7.setCellStyle(cellStyle);
                    Cell cell8 = row.createCell(7);
                    cell8.setCellValue(goods.getReferencePrice().doubleValue());
                    Cell cell9 = row.createCell(8);
                    cell9.setCellValue(goods.getFloatingPrice().doubleValue());
//                    Cell cell10 = row.createCell(10);
//                    cell10.setCellValue(goods.getAcceptanceGoodsNumber());
                    Cell cell11 = row.createCell(9);
                    cell11.setCellValue(goods.getId().toString());
                }

                FileOutputStream fileOutputStream = new FileOutputStream(filePath);
                workbook.write(fileOutputStream);
                fileOutputStream.close();
                OutputStream outputStream = response.getOutputStream();
                workbook.write(outputStream);
                outputStream.flush();
                outputStream.close();
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(CodeUtil.FAIL, "验收单货物信息导出失败");
        }
    }

    @Override
    public List<String> downloadPdf(CAcceptanceBasicInfo acceptanceBasicInfo) {

        List<CAcceptanceGoodsInfo> acceptanceGoodInfos = acceptanceBasicInfo.getAcceptanceGoodInfos();
        //遍历数组 计算超过200万，分一组
        List<List<CAcceptanceGoodsInfo>> lists = minGroup(acceptanceGoodInfos);
        if (lists != null && lists.size() > 0) {
            Integer i = 1;
            for (List<CAcceptanceGoodsInfo> list : lists) {
                for (CAcceptanceGoodsInfo goods : list) {
                    goods.setcAcceptanceBasicInfoId(acceptanceBasicInfo.getId());
                    goods.setAcceptanceGoodsNumber(acceptanceBasicInfo.getAcceptanceNumber() + "0" + i);
                }
                i++;
            }

        }
        try {
            XMlToDoc xmlDoc = new XMlToDoc();
            //模板中填充数据
            List<File> files = inputData(acceptanceBasicInfo, xmlDoc);
            List<String> list = Lists.newArrayList();
            for (File f : files) {
                FileInputStream inputFile = new FileInputStream(f);
                byte[] buffer = new byte[(int) f.length()];
                inputFile.read(buffer);
                inputFile.close();
                list.add("data:application/pdf;base64," + Base64.encode(buffer));
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(CodeUtil.FAIL, "生成验收单据出错");
        }
    }


    /**
     *  预览签署的文件
     * @param acceptanceId
     * @return
     */
    @Override
    public List<FileStorage> viewSignFile(Long acceptanceId) {

        AttachmentDto attachmentDto = AttachmentDto.builder()
            .setEntityId(acceptanceId)
            .setChildEnum(FileModuleDict.ChildEnum.ACCEPTANCE_UPSTREAM_FILE_SIGN)
            .build();
        List<FileStorage> files = attachmentRefService.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 files;
    }


    @Override
    public void downloadSignFile(Long acceptanceId,HttpServletResponse response) {
        CAcceptanceBasicInfo byId = this.getById(acceptanceId);
        List<FileStorage> fileStorages = viewSignFile(acceptanceId);
        //打包下载文件
        fileStorageService.downloadZipFile(fileStorages, byId.getAcceptanceNumber()+FileModuleDict.ChildEnum.ACCEPTANCE_UPSTREAM_FILE_SIGN.getCname(), response);
    }


    private CAcceptanceBasicInfo updateAcceptanceSheet(CAcceptanceBasicInfo acceptanceBasicInfo, HttpServletRequest request) throws IOException {

        List<Long> deleteFileIds = acceptanceBasicInfo.getDeleteFileIds();
        if (CollectionUtil.isNotEmpty(deleteFileIds)) {
            fileService.removeBatchByIds(acceptanceBasicInfo.getDeleteFileIds());
        }

//       该方法是否造成死锁 还未测试
//        List<FileStorageDO> oldFiles = fileService.lambdaQuery()
//            .in(FileStorageDO::getBusinessType, FileTypeEnum.ACCEPTANCE_FILE.getCode(),
//                FileTypeEnum.ACCEPTANCE_SUPPLEMENT_FILE.getCode(),
//                FileTypeEnum.ACCEPTANCE_UPSTREAM_FILE.getCode())
//            .eq(FileStorageDO::getBusinessId, acceptanceBasicInfo.getId()).list();
//        if(CollectionUtil.isNotEmpty(oldFiles)){
//            List<Long> collect = oldFiles.stream().map(x -> x.getId()).collect(Collectors.toList());
//            fileService.updateBusinessId(collect, null);
//        }

        // 删除旧附件  该方法会造成 线程死锁
//        fileService.lambdaUpdate().in(FileStorageDO::getBusinessType, FileTypeEnum.ACCEPTANCE_FILE.getCode(),
//                FileTypeEnum.ACCEPTANCE_SUPPLEMENT_FILE.getCode(),
//                FileTypeEnum.ACCEPTANCE_UPSTREAM_FILE.getCode())
//            .eq(FileStorageDO::getBusinessId, acceptanceBasicInfo.getId())
//            .set(FileStorageDO::getBusinessId, null).update();
        //上传附件
        List<Long> fileStorageIds = acceptanceBasicInfo.getFileStorageIds();
        if (CollectionUtil.isNotEmpty(fileStorageIds)) {
            fileService.updateBusinessId(fileStorageIds, acceptanceBasicInfo.getId());
        }
        //修改相关货物信息  先删除现有再新增
        acceptanceGoodsInfoService.remove(new QueryWrapper<CAcceptanceGoodsInfo>().eq("c_acceptance_basic_info_id",
                acceptanceBasicInfo.getId()));
        List<CAcceptanceGoodsInfo> acceptanceGoodInfos = acceptanceBasicInfo.getAcceptanceGoodInfos();
        //遍历数组 计算超过200万，分一组
        List<List<CAcceptanceGoodsInfo>> lists = minGroup(acceptanceGoodInfos);
        if (lists != null && lists.size() > 0) {
            Integer i = 1;
            for (List<CAcceptanceGoodsInfo> list : lists) {
                for (CAcceptanceGoodsInfo goods : list) {
                    goods.setcAcceptanceBasicInfoId(acceptanceBasicInfo.getId());
                    goods.setAcceptanceGoodsNumber(acceptanceBasicInfo.getAcceptanceNumber() + "0" + i);
                    acceptanceGoodsInfoService.save(goods);
                }
                i++;
            }
        }
        //删除旧的人员信息 在新增
        acceptancePersonInfoService.lambdaUpdate().eq(CAcceptancePersonInfo::getcAcceptanceBasicInfoId, acceptanceBasicInfo.getId()).remove();

        List<CAcceptancePersonInfo> acceptancePersonInfos = acceptanceBasicInfo.getAcceptancePersonInfos();

        if(acceptanceBasicInfo.getSubmitStatus()==1){


        if (CollectionUtil.isNotEmpty(acceptancePersonInfos)) {
            boolean anyMatch = acceptancePersonInfos.stream().anyMatch(r -> r.getType().equals("验收经办人（核心企业）"));
            boolean anyMatch1 = acceptancePersonInfos.stream().anyMatch(r -> r.getType().equals("验收经办人（供应商）"));
            if (!anyMatch1 || !anyMatch) {
                throw new ValidatorException(CodeUtil.FAIL, "验收经办人（核心企业）和验收经办人（供应商）至少各有一条数据");
            }
        } else {
            throw new ValidatorException(CodeUtil.FAIL, "验收经办人（核心企业）和验收经办人（供应商）至少各有一条数据");
        }

        if (CollectionUtil.isNotEmpty(acceptancePersonInfos)) {
            acceptancePersonInfos.forEach(r -> {
                r.setcAcceptanceBasicInfoId(acceptanceBasicInfo.getId());
                acceptancePersonInfoService.save(r);
                if (acceptanceBasicInfo.getSignConfirm() != null && acceptanceBasicInfo.getSignConfirm().equals(1)) {
                    if (r.getSigner() == 1) {
                        if (StringUtil.isEmpty(r.getName()) || StringUtil.isEmpty(r.getMobile())) {
                            throw new ValidatorException(CodeUtil.FAIL, "签署人信息必须填全！");
                        }
                        if (r.getType().equals("验收经办人（供应商）")) {
                            throw new ValidatorException(CodeUtil.FAIL, "签署人必须为：验收经办人（核心企业）");
                        }
                        acceptanceBasicInfo.setSigner(r.getId());
                    }
                }
            });
        }
        //提交
        //验证经办人和销售合同经办人是否一致
        ArrayList<String> additional = new ArrayList<>();
        if (request instanceof MultipartHttpServletRequest) {
            MultiValueMap<String, MultipartFile> multiValueMap = ((MultipartHttpServletRequest) request)
                    .getMultiFileMap();
            Set<String> keys = multiValueMap.keySet();
            for (String key : keys) {
                if (key.startsWith("additional")) {
                    additional.add(key);
                }
            }
        }
        //数据库中原来保存的验收单
        CSalesContractManagement salesContractManagement = salesContractService.getOne(
                new QueryWrapper<CSalesContractManagement>()
                        .eq("business_number", acceptanceBasicInfo.getBusinessNumber()));
        CSalesContractBasicInfo salesContractBasicInfo =
                salesContractBasicInfoService.getOne(
                        new QueryWrapper<CSalesContractBasicInfo>().eq("c_sales_contract_management_id",
                                salesContractManagement.getId()).orderByDesc("gmt_create").last("LIMIT 1"));
        List<CSalesContractPersonInfo> salesContractPersonInfos = salesContractPersonInfoService
                .lambdaQuery()
                .eq(CSalesContractPersonInfo::getcSalesContractBasicInfoId, salesContractBasicInfo.getId())
                .eq(CSalesContractPersonInfo::getType, "验收经办人").list();
        Boolean same = true;
        for (CSalesContractPersonInfo salesContractPersonInfo : salesContractPersonInfos) {
            boolean anyMatch = acceptancePersonInfos.stream().filter(r -> r.getType().equals("验收经办人（核心企业）"))
                    .anyMatch(s -> s.getName().equals(salesContractPersonInfo.getName()));
            if (!anyMatch) {
                same = false;
            }
        }
        long count = acceptancePersonInfos.stream().filter(r -> r.getType().equals("验收经办人（核心企业）")).count();
        if (salesContractPersonInfos.size() != count) {
            same = false;
        }
//            if (!same && acceptanceBasicInfo.getChangePerson().equals(0)) {
//                throw new ValidatorException(CodeUtil.FAIL, "不进行人员变更，不能更改验收经办人姓名");
//            }
//        if (!same && additional.size() == 0) {
//            if (CollectionUtil.isEmpty(supplementFileIds)) {
//                throw new ValidatorException(CodeUtil.FAIL, "验收单经办人和销售合同规定经办人不一致需要上传说明附件！");
//            }
//        }

           // 删除旧的上游验收单
            List<FileStorageDO> fileStorageDOS = fileService
                .findByBusinessId(acceptanceBasicInfo.getId(), FileTypeEnum.ACCEPTANCE_UPSTREAM_FILE.getCode());
            if (CollectionUtil.isNotEmpty(fileStorageDOS)) {
                fileService.removeBatchByIds(fileStorageDOS);
            }
            //生成验收单
            List<FileStorageDO> fileStorageDOs = createAcceptance(acceptanceBasicInfo.getId());
            //生成的上游验收单附件
            acceptanceBasicInfo.setAcceptanceUpstreamFiles(fileStorageDOs);
        }

        //因为 b 端要保存历史附件信息 所以这边需要查询附件
        List<FileStorageDO> file1 = fileService.findByBusinessId(
                acceptanceBasicInfo.getId(), FileTypeEnum.ACCEPTANCE_FILE.getCode());
        List<FileStorageDO> file2 = fileService.findByBusinessId(
                acceptanceBasicInfo.getId(), FileTypeEnum.ACCEPTANCE_SUPPLEMENT_FILE.getCode());

        acceptanceBasicInfo.setFileStorageDOList(file1);
        acceptanceBasicInfo.setSupplementFiles(file2);

        return acceptanceBasicInfo;
    }


    public List<CAcceptanceBasicInfo> findByCondition(CAcceptanceBasicInfo basicInfo, Boolean financing) {
        return baseMapper.findByCondition(basicInfo, financing);
    }

    private TableRenderData makeGoodsList(List<CAcceptanceGoodsInfo> 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 (CAcceptanceGoodsInfo 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;
    }


    private CAcceptanceBasicInfo addAcceptanceSheet(CAcceptanceBasicInfo acceptanceBasicInfo, HttpServletRequest request) {
        if (acceptanceBasicInfo.getBusinessNumber() != null) {
            //保存验收单基础信息
            String acceptanceNumber = serialNumberGenerator.nextValue(ConstantUtil.ACCEPTANCE_SHEET_CODE);
            acceptanceBasicInfo.setAcceptanceNumber(acceptanceNumber);
            acceptanceBasicInfo.setSettlement(false);
            acceptanceBasicInfo.setReceivables(false);
            acceptanceBasicInfo.setSysUserId(LoginUserHolder.get().getId());
            if (acceptanceBasicInfo.getSubmitStatus()==1) {
                ValidatorUtil.validator(ValidatorEntity.ValidatorType.ADD, acceptanceBasicInfo);
                save(acceptanceBasicInfo);
            } else {
                // 如果不申请审核 状态应该是空
                //acceptanceBasicInfo.setAcceptanceStatus(ProjectInitiationStatusEnum.PROCESSING.getCode());
                save(acceptanceBasicInfo);
            }
            //保存业务相关货物信息 需求：单份验收单销售总价金额限定200万
            List<CAcceptanceGoodsInfo> acceptanceGoodInfos = acceptanceBasicInfo.getAcceptanceGoodInfos();
            //遍历数组 计算超过200万，分一组
            List<List<CAcceptanceGoodsInfo>> lists = minGroup(acceptanceGoodInfos);


            if (lists != null && lists.size() > 0) {
                Integer i = 1;
                for (List<CAcceptanceGoodsInfo> list : lists) {
                    for (CAcceptanceGoodsInfo goods : list) {
                        goods.setcAcceptanceBasicInfoId(acceptanceBasicInfo.getId());
                        goods.setAcceptanceGoodsNumber(acceptanceBasicInfo.getAcceptanceNumber() + "0" + i);
                        acceptanceGoodsInfoService.save(goods);
                    }
                    i++;
                }

            }
            //上传附件(验收单文件)
            List<Long> acceptanceFileIds = acceptanceBasicInfo.getFileStorageIds();
            if (CollectionUtil.isNotEmpty(acceptanceFileIds)) {
                fileService.updateBusinessId(acceptanceFileIds, acceptanceBasicInfo.getId());
            }

            List<Long> deleteFileIds = acceptanceBasicInfo.getDeleteFileIds();
            if (CollectionUtil.isNotEmpty(deleteFileIds)) {
                fileService.removeBatchByIds(acceptanceFileIds);
            }

            //保存说明文件
            List<Long> supplementFileIds = acceptanceBasicInfo.getSupplementFileIds();
            if (CollectionUtil.isNotEmpty(supplementFileIds)) {
                fileService.updateBusinessId(supplementFileIds, acceptanceBasicInfo.getId());
            }

            List<Long> deleteSupplementIds = acceptanceBasicInfo.getDeleteSupplementIds();
            if (CollectionUtil.isNotEmpty(deleteSupplementIds)) {
                fileService.removeBatchByIds(deleteSupplementIds);
            }
            //判断是否是钢小二的货物单号- 如果是 则需要保存起来
            if (CollectionUtil.isNotEmpty(acceptanceBasicInfo.getSellBillNumber()) && acceptanceBasicInfo.getSteelWaiter() == 1) {
                List<CAcceptanceSellBillRef> sellList = Lists.newArrayList();
                acceptanceBasicInfo.getSellBillNumber().forEach(x -> {
                    CAcceptanceSellBillRef cAcceptanceSellBillRef = new CAcceptanceSellBillRef();
                    cAcceptanceSellBillRef.setSellBillNumber(x);
                    cAcceptanceSellBillRef.setcAcceptanceBasicInfoId(acceptanceBasicInfo.getId());
                    sellList.add(cAcceptanceSellBillRef);
                });
                acceptanceSellBillRefService.saveBatch(sellList);
            }
            //保存处理人员信息
            List<CAcceptancePersonInfo> acceptancePersonInfos = acceptanceBasicInfo.getAcceptancePersonInfos();
            //提交状态才校验
            if(acceptanceBasicInfo.getSubmitStatus()==1){
                if (CollectionUtil.isNotEmpty(acceptancePersonInfos)) {
                    boolean anyMatch = acceptancePersonInfos.stream().anyMatch(r -> r.getType().equals("验收经办人（核心企业）"));
                    boolean anyMatch1 = acceptancePersonInfos.stream().anyMatch(r -> r.getType().equals("验收经办人（供应商）"));
                    if (!anyMatch1 || !anyMatch) {
                        throw new BusinessException(CodeUtil.FAIL, "验收经办人（核心企业）和验收经办人（供应商）至少各有一条数据");
                    }
                } else {
                    throw new BusinessException(CodeUtil.FAIL, "验收经办人（核心企业）和验收经办人（供应商）至少各有一条数据");
                }

                if (CollectionUtil.isNotEmpty(acceptancePersonInfos)) {
                    acceptancePersonInfos.forEach(r -> {
                        r.setcAcceptanceBasicInfoId(acceptanceBasicInfo.getId());
                        acceptancePersonInfoService.save(r);
                        if (acceptanceBasicInfo.getSignConfirm() != null && acceptanceBasicInfo.getSignConfirm().equals(1)) {
                            if (r.getSigner() == 1) {
                                if (StringUtil.isEmpty(r.getName()) || StringUtil.isEmpty(r.getMobile())) {
                                    throw new BusinessException(CodeUtil.FAIL, "签署人信息必须填全！");
                                }
                                if (r.getType().equals("验收经办人（供应商）")) {
                                    throw new BusinessException(CodeUtil.FAIL, "签署人必须为：验收经办人（核心企业）");
                                }
                                acceptanceBasicInfo.setSigner(r.getId());
                            }
                        }
                    });
                }
            //验证经办人和销售合同经办人是否一致
            ArrayList<String> additional = new ArrayList<>();
            if (request instanceof MultipartHttpServletRequest) {
                MultiValueMap<String, MultipartFile> multiValueMap = ((MultipartHttpServletRequest) request)
                        .getMultiFileMap();
                Set<String> keys = multiValueMap.keySet();
                for (String key : keys) {
                    if (key.startsWith("additional")) {
                        additional.add(key);
                    }
                }
                CSalesContractManagement salesContractManagement = salesContractService.getOne(
                        new QueryWrapper<CSalesContractManagement>()
                                .eq("business_number", acceptanceBasicInfo.getBusinessNumber())
                                .last("LIMIT 1"));
                CSalesContractBasicInfo salesContractBasicInfo =
                        salesContractBasicInfoService.getOne(new QueryWrapper<CSalesContractBasicInfo>()
                                .eq("c_sales_contract_management_id", salesContractManagement.getId())
                                .orderByDesc("gmt_create").last("LIMIT 1"));
                List<CSalesContractPersonInfo> salesContractPersonInfos = salesContractPersonInfoService.lambdaQuery()
                        .eq(CSalesContractPersonInfo::getcSalesContractBasicInfoId, salesContractBasicInfo.getId())
                        .eq(CSalesContractPersonInfo::getType, SalesContractPersonTypeEnum.SALESCONTRACTPERSONTYPE_ACCEPTANCE.getCode()).list();
                Boolean same = true;
                for (CSalesContractPersonInfo salesContractPersonInfo : salesContractPersonInfos) {
                    boolean anyMatch = acceptancePersonInfos.stream().filter(r -> r.getType().equals("验收经办人（核心企业）"))
                            .anyMatch(s -> s.getName().equals(salesContractPersonInfo.getName()));
                    if (!anyMatch) {
                        same = false;
                    }
                }
                long count = acceptancePersonInfos.stream().filter(r -> r.getType().equals("验收经办人（核心企业）")).count();
                if (salesContractPersonInfos.size() != count) {
                    same = false;
                }
                if (!same && additional.size() == 0) {
                    List<FileStorageDO> supplementFiles = fileService.findByBusinessId(
                            acceptanceBasicInfo.getId(), FileTypeEnum.ACCEPTANCE_SUPPLEMENT_FILE.getCode());
                    if (CollectionUtil.isEmpty(supplementFiles)) {
                        throw new BusinessException(CodeUtil.FAIL, "验收单经办人和销售合同规定经办人不一致需要上传说明附件！");
                    }
                }
              }
             //生成验收单
             List<FileStorageDO> fileStorageDOs = createAcceptance(acceptanceBasicInfo.getId());
             acceptanceBasicInfo.setAcceptanceUpstreamFiles(fileStorageDOs);
            }
            //因为 b 端要保存历史附件信息 所以这边需要查询附件
            List<FileStorageDO> file1 = fileService.findByBusinessId(
                    acceptanceBasicInfo.getId(), FileTypeEnum.ACCEPTANCE_FILE.getCode());
            List<FileStorageDO> file2 = fileService.findByBusinessId(
                    acceptanceBasicInfo.getId(), FileTypeEnum.ACCEPTANCE_SUPPLEMENT_FILE.getCode());
            acceptanceBasicInfo.setFileStorageDOList(file1);
            acceptanceBasicInfo.setSupplementFiles(file2);

            return acceptanceBasicInfo;
        } else {
            throw new BusinessException(CodeUtil.FAIL, "请锁定业务编号后保存！");
        }


    }

    private List<List<CAcceptanceGoodsInfo>> minGroup(List<CAcceptanceGoodsInfo> list) {

        List<List<CAcceptanceGoodsInfo>> subList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(list)) {
            //先计算总价
            list.forEach(x -> {
                x.setSalesTotalPrice(x.getSalesPrice().multiply(x.getGoodsQuantity()));
            });
            List<List<CAcceptanceGoodsInfo>> resultList = new ArrayList<>();

            BigDecimal top = new BigDecimal(2000000);
            BigDecimal temp = BigDecimal.ZERO;

            List<CAcceptanceGoodsInfo> tempList = new ArrayList<>();
            //排序 正序
            list.sort((o1, o2) -> o2.getSalesTotalPrice().compareTo(o1.getSalesTotalPrice()));
            // int i = 0;
            for (CAcceptanceGoodsInfo goods : list) {
                if (temp.compareTo(top) < 0) {
                    //如果单价之和小于 200万
                    tempList.add(goods);
                    temp = temp.add(goods.getSalesTotalPrice());
                } else {
                    subList.add(tempList);
                    tempList = new ArrayList<>();
                    tempList.add(goods);
                    temp = goods.getSalesTotalPrice();
                }
            }
            subList.add(tempList);
        }

        return subList;
    }


}
