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

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.inkasso.adapter.bean.AbstractUser;
import com.inkasso.adapter.exception.BusinessException;
import com.inkasso.adapter.util.CodeUtil;
import com.inkasso.adapter.util.CollectionUtil;
import com.inkasso.adapter.web.LoginUserHolder;
import com.inkasso.auth.exception.ValidatorException;
import com.inkasso.factoring.common.dict.impl.AmountKindDict;
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.creditmanagement.entity.Enterprise;
import com.inkasso.factoring.creditmanagement.entity.ProjectInformation;
import com.inkasso.factoring.creditmanagement.entity.SupplierInfo;
import com.inkasso.factoring.creditmanagement.service.IEnterpriseService;
import com.inkasso.factoring.creditmanagement.service.IProjectInformationService;
import com.inkasso.factoring.creditmanagement.service.ISupplierInfoService;
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.service.FileService;
import com.inkasso.factoring.file.service.FileStorageService;
import com.inkasso.factoring.file.util.FileStorageUtil;
import com.inkasso.factoring.invoicemanage.dao.InvoiceBasicInfoMapper;
import com.inkasso.factoring.invoicemanage.entity.*;
import com.inkasso.factoring.invoicemanage.model.request.SearchBusiness;
import com.inkasso.factoring.invoicemanage.model.request.SearchGoodsVo;
import com.inkasso.factoring.invoicemanage.service.*;
import com.inkasso.factoring.purchManagement.entity.vo.PurchContractCompletedVo;
import com.inkasso.factoring.purchManagement.service.ICPurchContractManagementService;
import com.inkasso.factoring.settlement.entity.SettlementBasicInfo;
import com.inkasso.factoring.settlement.entity.SettlementGoodsInfo;
import com.inkasso.factoring.settlement.model.dto.BusinessProcessingTaskDTO;
import com.inkasso.factoring.system.user.model.dto.UserDTO;
import com.inkasso.factoring.tradingPlatform.service.ITradingPlatformService;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class InvoiceBasicInfoServiceImpl extends ServiceImpl<InvoiceBasicInfoMapper, InvoiceBasicInfo>
        implements InvoiceBasicInfoService{
    @Autowired
    private DictionaryService dictService;
    @Autowired
    private InvoiceGoodsInfoService invoiceGoodsInfoService;
    @Autowired
    private InvoicePossessionCostInfoService invoicePossessionCostInfoService;

    @Autowired
    private InvoiceSupplierInfoService invoiceSupplierInfoService;

    @Autowired
    private ISupplierInfoService iSupplierInfoService;

    @Autowired
    private IEnterpriseService iEnterpriseService;

    @Autowired
    private InvoiceCustomerInfoService invoiceCustomerInfoService;

    @Autowired
    private PurchaseInvoiceInfoService purchaseInvoiceInfoService;

    @Autowired
    private SalesInvoiceInfoService salesInvoiceInfoService;

    @Autowired
    private FileService fileService;
    @Autowired
    private FileStorageService fileStorageService;
    @Autowired
    private InvoiceApprovalService invoiceApprovalService;
    @Autowired
    private ITradingPlatformService platformService;

    @Autowired
    private ICPurchContractManagementService purchContractService;
    @Autowired
    private IProjectInformationService projectInformationService;

    @Autowired
    private RestTemplate restTemplate;
    @Value("${trade.addSaleInvoice}")
    private String addSaleInvoice;
    @Value("${trade.updateSaleInvoice}")
    private String updateSaleInvoice;

    @Override
    public InvoiceBasicInfo get(Long id) {
        return null;
    }

    @Override
    @Transactional
    public void add(InvoiceBasicInfo invoiceBasicInfo) throws IOException {
        //保存发票有关信息
        InvoiceBasicInfo savedSaleInvoiceVo = saveSaleInvoice(invoiceBasicInfo);
        //调用B端，开启开票流程
        String result = restTemplate.postForObject(addSaleInvoice, savedSaleInvoiceVo, String.class);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject.getString("code").equals("500")){
            throw new BusinessException(CodeUtil.FAIL,jsonObject.getString("msg"));
        }
    }

    @Override
    public InvoiceBasicInfo getDetail(Long businessKey) {
//销售发票信息
        InvoiceBasicInfo invoiceBasicInfo = this.getById(businessKey);
        //查询项目信息
        ProjectInformation one = projectInformationService.lambdaQuery()
            .eq(ProjectInformation::getBusinessNumber, invoiceBasicInfo.getBusinessNumber()).one();
        invoiceBasicInfo.setBusinessBasicInfoId(one.getId());
        PurchContractCompletedVo purchContractCompletedVo = purchContractService.getCompletedPurchContractByBusinessNumber(invoiceBasicInfo.getBusinessNumber());
        invoiceBasicInfo.setPurchContractCompletedVo(purchContractCompletedVo);
        //字典项
        invoiceBasicInfo.setAmountKindDic(dictService.getByCode(invoiceBasicInfo.getAmountKind()));
        invoiceBasicInfo.setInvoiceTypeDic(dictService.getByCode(invoiceBasicInfo.getInvoiceType()));
        //核心企业
        Enterprise enterprise = iEnterpriseService.getById(invoiceBasicInfo.getEnterpriseCustomerInfoId());
        invoiceBasicInfo.setEnterpriseCorporateName(enterprise.getCorporateName());
        invoiceBasicInfo.setCompanyName(enterprise.getCorporateName());
        //发票货物信息
        List<InvoiceGoodsInfo> invoiceGoodsInfoList = invoiceGoodsInfoService.list(new QueryWrapper<InvoiceGoodsInfo>().eq("c_invoice_basic_info_id", invoiceBasicInfo.getId()));
        invoiceBasicInfo.setInvoiceGoodsInfos(invoiceGoodsInfoList);
        //资金占用费信息
        InvoicePossessionCostInfo invoicePossessionCostInfo = invoicePossessionCostInfoService.getOne(new QueryWrapper<InvoicePossessionCostInfo>().eq("c_invoice_basic_info_id", invoiceBasicInfo.getId()));
        invoiceBasicInfo.setInvoicePossessionCostInfos(invoicePossessionCostInfo);
        //采购发票信息
//        List<PurchaseInvoiceInfo> purchaseInvoiceInfos = purchaseInvoiceInfoService.list(new QueryWrapper<PurchaseInvoiceInfo>().eq("c_invoice_basic_info_id", invoiceBasicInfo.getId()));
//        invoiceBasicInfo.setPurchaseInvoiceInfos(purchaseInvoiceInfos);
        //供应商信息
        List<InvoiceSupplierInfo> invoiceHisSupplierInfos = invoiceSupplierInfoService.list(new QueryWrapper<InvoiceSupplierInfo>().eq("c_invoice_basic_info_id", invoiceBasicInfo.getId()));
        invoiceBasicInfo.setInvoiceSupplierInfos(invoiceHisSupplierInfos);
        //发票附件信息
//        AttachmentDto attachmentDto = AttachmentDto.builder()
//                .setEntityId(invoiceHisInfo.getId())
//                .setChildEnum(FileModuleDict.ChildEnum.INVOICE_PURCHASE_HIS_FILE)
//                .build();
        List<FileStorageDO> files = fileService.findByBusinessId(businessKey, FileModuleDict.ChildEnum.INVOICE_PURCHASE_FILE.getCode());
        invoiceBasicInfo.setFiles(files);
        //采购发票附件

        //发票明细
        List<FileStorageDO> file2 = fileService.findByBusinessId(businessKey, FileModuleDict.ChildEnum.INVOICE_DETAIL_FILE.getCode());
        invoiceBasicInfo.setInvoiceDetailList(file2);

        //销售发票附件信息
        List<FileStorageDO> fileStorageDOS = fileService.findByBusinessId(businessKey, FileModuleDict.ChildEnum.INVOICE_SALES_FILE.getCode());
        invoiceBasicInfo.setSalesInvoicFile(fileStorageDOS);
        return invoiceBasicInfo;
    }

    @Override
    @Transactional
    public void doUpdate(InvoiceBasicInfo invoiceBasicInfo,HttpServletRequest request) throws IOException {
        invoiceBasicInfo = updateSaleInvoice(invoiceBasicInfo, request);
        //调用B端，开启开票流程
        String result = restTemplate.postForObject(updateSaleInvoice, invoiceBasicInfo, String.class);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject.getString("code").equals("500")){
            throw new BusinessException(CodeUtil.FAIL,jsonObject.getString("发票录入异常"));
        }
    }

    private InvoiceBasicInfo updateSaleInvoice(InvoiceBasicInfo invoiceBasicInfo, HttpServletRequest request) throws IOException {
        //修改销售发票信息
        //修改销售状态置为：已创建
        invoiceBasicInfo.setInvoiceStatus(dictService.getByCode(InvoiceDict.ChildEnum.CREATE.getCode()).getId());
        updateById(invoiceBasicInfo);

        // 2023.8.4 开票信息与业务关联 历史数据处理
        if (invoiceBasicInfo.getEnterpriseCustomerInfoId() != null && invoiceBasicInfo.getBusinessBasicInfoId() != null) {
            InvoiceCustomerInfo newInvoiceCustomerInfo = new InvoiceCustomerInfo(invoiceBasicInfo);
            InvoiceCustomerInfo invoiceCustomerInfo = invoiceCustomerInfoService.getOne(new QueryWrapper<InvoiceCustomerInfo>()
                .eq("customer_id", invoiceBasicInfo.getEnterpriseCustomerInfoId())
                .eq("business_basic_info_id", invoiceBasicInfo.getBusinessBasicInfoId()));
            if (invoiceCustomerInfo == null) {
                invoiceCustomerInfo = invoiceCustomerInfoService.getOne(new QueryWrapper<InvoiceCustomerInfo>()
                    .eq("customer_id", invoiceBasicInfo.getEnterpriseCustomerInfoId())
                    .last("and business_basic_info_id is null"));
            }
            if (invoiceCustomerInfo != null) {
                newInvoiceCustomerInfo.setId(invoiceCustomerInfo.getId());
            }
            invoiceCustomerInfoService.saveOrUpdate(newInvoiceCustomerInfo);
        }

        //修改销售发票的货物信息  先删除，再修改
        invoiceGoodsInfoService.remove(new QueryWrapper<InvoiceGoodsInfo>().eq("c_invoice_basic_info_id", invoiceBasicInfo.getId()));
        Boolean flag = false;
        BigDecimal num = BigDecimal.ZERO,amount = BigDecimal.ZERO,taxAmount = BigDecimal.ZERO,priceTaxTotal = BigDecimal.ZERO;
        List<InvoiceGoodsInfo> invoiceGoodsInfoList = invoiceBasicInfo.getInvoiceGoodsInfos();
        if (invoiceGoodsInfoList != null && invoiceGoodsInfoList.size() > 0) {
            for (InvoiceGoodsInfo invoiceGoodsInfo : invoiceGoodsInfoList) {
                if (invoiceGoodsInfo.getGoodsQuantity() != null) {
                    flag = true;
                }
                //如果是货物判断开票数量
                if (invoiceBasicInfo.getAmountKind().equals(AmountKindDict.ChildEnum.PAYMENT.getCode())) {
                    BigDecimal usedNum = invoiceGoodsInfo.getUsedNum() == null?BigDecimal.ZERO: invoiceGoodsInfo.getUsedNum();
                    if (-1 == invoiceGoodsInfo.getGoodsQuantity().compareTo(usedNum.add(invoiceGoodsInfo.getOpenQuantity()))) {
                        throw new BusinessException(CodeUtil.FAIL, "开票数量 + 已开数量 不能大于 数量，请修改 “开票数量”");
                    }
                }
                invoiceGoodsInfo.setInvoiceBasicInfoId(invoiceBasicInfo.getId());
                num = num.add(invoiceGoodsInfo.getOpenQuantity() == null? BigDecimal.ZERO : invoiceGoodsInfo.getOpenQuantity());
            }
            invoiceGoodsInfoService.saveBatch(invoiceGoodsInfoList);
        }
        //保存采购发票信息
        //采购发票合计数量
//        BigDecimal openNum = BigDecimal.ZERO;
        //List<PurchaseInvoiceInfo> purchaseInvoiceInfos = invoiceBasicInfo.getPurchaseInvoiceInfos();
//        if(CollectionUtil.isNotEmpty(purchaseInvoiceInfos)){
//            for (PurchaseInvoiceInfo purchaseInvoiceInfo:purchaseInvoiceInfos) {
//                purchaseInvoiceInfo.setInvoiceBasicInfoId(invoiceBasicInfo.getId());
//                amount = amount.add(purchaseInvoiceInfo.getAmount() == null ? BigDecimal.ZERO : purchaseInvoiceInfo.getAmount());
//                taxAmount = taxAmount.add(purchaseInvoiceInfo.getTaxAmount() == null ? BigDecimal.ZERO : purchaseInvoiceInfo.getTaxAmount());
//                priceTaxTotal = priceTaxTotal.add(purchaseInvoiceInfo.getTaxAmount() == null ? BigDecimal.ZERO : purchaseInvoiceInfo.getTaxAmount());
//                openNum = openNum.add(purchaseInvoiceInfo.getNvoiceNum() == null? BigDecimal.ZERO : purchaseInvoiceInfo.getNvoiceNum());
//                if(purchaseInvoiceInfo.getId() != null){
//                    purchaseInvoiceInfoService.updateById(purchaseInvoiceInfo);
//                }else {
//                    purchaseInvoiceInfoService.save(purchaseInvoiceInfo);
//                }
//            }
////            purchaseInvoiceInfoService.updateBatchById(purchaseInvoiceInfos);
//        }
//        if(openNum.compareTo(num) != 0){
//            throw new BusinessException(CodeUtil.FAIL, "开票申请货物数量合计与采购发票数量合计不符,请确认后提交");
//        }

        //保存资金占用费 先删除，再修改
        invoicePossessionCostInfoService.remove(new QueryWrapper<InvoicePossessionCostInfo>().eq("c_invoice_basic_info_id", invoiceBasicInfo.getId()));
        InvoicePossessionCostInfo invoicePossessionCostInfos = invoiceBasicInfo.getInvoicePossessionCostInfos();
        if (invoicePossessionCostInfos != null) {
            invoicePossessionCostInfos.setInvoiceBasicInfoId(invoiceBasicInfo.getId());
            invoicePossessionCostInfoService.save(invoicePossessionCostInfos);
        }
        //保存发票供应商信息 先删除，再修改
        invoiceSupplierInfoService.remove(new QueryWrapper<InvoiceSupplierInfo>().eq("c_invoice_basic_info_id", invoiceBasicInfo.getId()));
        List<InvoiceSupplierInfo> invoiceSupplierInfos = invoiceBasicInfo.getInvoiceSupplierInfos();
        if (invoiceSupplierInfos != null && invoiceSupplierInfos.size() > 0) {
            for (InvoiceSupplierInfo invoiceSupplierInfo : invoiceSupplierInfos) {
                invoiceSupplierInfo.setInvoiceBasicInfoId(invoiceBasicInfo.getId());
                SupplierInfo supplierInfo= iSupplierInfoService.getById(invoiceSupplierInfo.getSupplierId());
                Enterprise enterprise = iEnterpriseService.getById(supplierInfo.getcEnterpriseId());
                invoiceSupplierInfo.setSupplierName(enterprise.getCorporateName());
            }
            invoiceSupplierInfoService.saveBatch(invoiceSupplierInfos);
        }
        //先删除所有需要删除的文件
        List<Long> deleteFileIds = invoiceBasicInfo.getDeleteIds();
        if (deleteFileIds != null && deleteFileIds.size() > 0) {
            fileService.removeBatchByIds(deleteFileIds);
        }
        //保存采购发票附件
        List<Long> purchaseInvoiceFiles = invoiceBasicInfo.getPurchaseInvoiceFiles();
        //先删除旧的
        List<FileStorageDO> fileStorageDOS1 = fileService.findByBusinessId(invoiceBasicInfo.getId(), FileTypeEnum.INVOICE_PURCHASE_FILE.getCode());
        for (FileStorageDO fileStorageDO:fileStorageDOS1) {
            fileService.updateBusinessId(fileStorageDO.getId(),null);
        }
        if(CollectionUtil.isNotEmpty(purchaseInvoiceFiles)){
            for (Long fileId:purchaseInvoiceFiles ) {
                fileService.updateBusinessId(fileId,invoiceBasicInfo.getId());
            }
        }
        //报错发票明细
        List<Long> invoiceDetailFiles = invoiceBasicInfo.getInvoiceDetailFiles();
        //先删除旧的
        List<FileStorageDO> fileStorageDOS2 = fileService.findByBusinessId(invoiceBasicInfo.getId(), FileTypeEnum.INVOICE_DETAIL_FILE.getCode());
        for (FileStorageDO fileStorageDO:fileStorageDOS2) {
            fileService.updateBusinessId(fileStorageDO.getId(),null);
        }
        if(CollectionUtil.isNotEmpty(invoiceDetailFiles)){
            for (Long fileId:invoiceDetailFiles ) {
                fileService.updateBusinessId(fileId,invoiceBasicInfo.getId());
            }
        }

        // 生成参考的待开发票
//        if (invoiceGoodsInfoList != null && invoiceGoodsInfoList.size() > 0 && flag) {
//            //先删除旧的
//            List<FileStorageDO> fileStorageDOS = fileService.findByBusinessId(invoiceBasicInfo.getId(), FileTypeEnum.INVOICE_SALES_FILE.getCode());
//            for (FileStorageDO fileStorageDO:fileStorageDOS) {
//                fileService.updateBusinessId(fileStorageDO.getId(),null);
//            }
//            File file = inputData(invoiceBasicInfo);
//            FileStorageDO fileStorage= FileStorageUtil.createFileStorage3(invoiceBasicInfo.getId()+"",FileTypeEnum.INVOICE_SALES_FILE,file.getName(),".xlsx");
//            fileStorage.setBusinessId(invoiceBasicInfo.getId());
//            fileService.save(fileStorage);
//        }
        return invoiceBasicInfo;
    }


    @Override
    public InvoiceBasicInfo getUpdateDetail(Long businessKey) {
        //销售发票信息
        InvoiceBasicInfo invoiceBasicInfo = getById(businessKey);
        //贸易平台
        invoiceBasicInfo.setTradingPlatformName(platformService.getById(invoiceBasicInfo.getTradingPlatformId()).getPlatformName());
        //字典项
        invoiceBasicInfo.setAmountKindDic(dictService.getByCode(invoiceBasicInfo.getAmountKind()));
        //销售发票货物信息
        List<InvoiceGoodsInfo> invoiceGoodInfos = invoiceGoodsInfoService.findListGoods(invoiceBasicInfo.getId());
        invoiceBasicInfo.setInvoiceGoodsInfos(invoiceGoodInfos);
        //资金占用费
        InvoicePossessionCostInfo invoicePossessionCostInfos = invoicePossessionCostInfoService.getOne(new QueryWrapper<InvoicePossessionCostInfo>().eq("invoice_basic_info_id", invoiceBasicInfo.getId()));
        invoiceBasicInfo.setInvoicePossessionCostInfos(invoicePossessionCostInfos);
        //发票供应商信息
        List<InvoiceSupplierInfo> invoiceSupplierInfosuppliers = invoiceSupplierInfoService.list(new QueryWrapper<InvoiceSupplierInfo>().eq("invoice_basic_info_id", invoiceBasicInfo.getId()));
        invoiceBasicInfo.setInvoiceSupplierInfos(invoiceSupplierInfosuppliers);
        //采购发票附件
        List<FileStorageDO> files = fileService.findByBusinessId(invoiceBasicInfo.getId(),FileModuleDict.ChildEnum.INVOICE_PURCHASE_FILE.getCode());
        invoiceBasicInfo.setFiles(files);
        //发票明细
        List<FileStorageDO> files2 = fileService.findByBusinessId(invoiceBasicInfo.getId(),FileModuleDict.ChildEnum.INVOICE_DETAIL_FILE.getCode());
        invoiceBasicInfo.setInvoiceDetailList(files2);

        //参考的待开发票
        List<FileStorageDO> pendingFiles = fileService.findByBusinessId(invoiceBasicInfo.getId(),FileModuleDict.ChildEnum.INVOICE_SALES_FILE.getCode());
        invoiceBasicInfo.setPendingInvoice(pendingFiles);
        return invoiceBasicInfo;
    }

    @Override
    public void init(Long businessBasicId, Model model) {

    }

    @Override
    public void downloadAllInvoiceFile(Long id, HttpServletResponse response) {
        List<FileStorageDO> allInvoiceFiles = new ArrayList<>();
        InvoiceApproval invoiceApproval = invoiceApprovalService.getFileList(id);
        //待开发票
        allInvoiceFiles.addAll(invoiceApproval.getPendingInvoice());
        //下游结算单附件
        allInvoiceFiles.addAll(invoiceApproval.getSettlementFile());
        //上游结算单附件
        allInvoiceFiles.addAll(invoiceApproval.getSettlementUpstreamSignedFile());
        //采购合同附件
        allInvoiceFiles.addAll(invoiceApproval.getPurchContract());
        //销售合同附件
        allInvoiceFiles.addAll(invoiceApproval.getSalesContract());
        //采购发票附件
        List<FileStorageDO> invoicePurchaseFiles = fileService.findByBusinessId(id,FileModuleDict.ChildEnum.INVOICE_PURCHASE_FILE.getCode());
        allInvoiceFiles.addAll(invoicePurchaseFiles);
        List<FileStorageDO> invoiceDetailFiles = fileService.findByBusinessId(id,FileModuleDict.ChildEnum.INVOICE_DETAIL_FILE.getCode());
        allInvoiceFiles.addAll(invoiceDetailFiles);

        fileService.renameFileStorageList(allInvoiceFiles);
        fileService.downloadZipFile(allInvoiceFiles, FileTypeEnum.INVOICE_ZIP_FILE.getDesc(),
                FileTypeEnum.INVOICE_ZIP_FILE, response);
    }

    @Override
    public List<FileStorage> showSaleInvoice(Long id) {

        //销售发票信息
        QueryWrapper<SalesInvoiceInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("c_invoice_basic_info_id", id);
        queryWrapper.orderByDesc("gmt_modified").last("limit 1");
        SalesInvoiceInfo salesInvoiceInfo = salesInvoiceInfoService.getOne(queryWrapper);
        List<FileStorage> list = fileStorageService.lambdaQuery()
            .eq(FileStorage::getBelongType, FileModuleDict.ChildEnum.INVOICE_SALES_FILE.getCode())
            .eq(FileStorage::getBelongId, salesInvoiceInfo.getId()).list();
        return list;
    }

    @Override
    public void downLoadSaleInvoice(Long id,HttpServletResponse response) {
        List<FileStorage> fileStorages = this.showSaleInvoice(id);
        InvoiceBasicInfo byId = this.getById(id);
        //打包下载文件
        fileStorageService.downloadZipFile(fileStorages, byId.getBusinessNumber()+FileModuleDict.ChildEnum.INVOICE_SALES_FILE.getCname(), response);
    }

    @Override
    public GridPage<BusinessProcessingTaskDTO> findList(SearchBusiness searchBusiness) {
        UserDTO abstractUser = (UserDTO) LoginUserHolder.get();
        if(abstractUser != null){
            Long userId = abstractUser.getId();
            List<Long> userIds = new ArrayList<>();
            userIds.add(userId);
            searchBusiness.setUserIds(userIds);
        }
        Page<SearchBusiness> page = PageHelper.startPage(searchBusiness.getPage(), searchBusiness.getRows());
        List<BusinessProcessingTaskDTO> list = baseMapper.findAllList(searchBusiness);
        return new GridPage<>(searchBusiness.getRows(), searchBusiness.getPage(), page.getTotal(), list);
    }

    @Override
    public GridPage saleSelectGoodsOfPayment(SearchGoodsVo searchGoodsVo) {
        Page<SearchGoodsVo> page = PageHelper.startPage(searchGoodsVo.getPage(), searchGoodsVo.getRows());
        //获取符合条件结算单
        List<SettlementBasicInfo> settlementBasicInfos = baseMapper.saleSelectSettlementOfPayment(searchGoodsVo);
        //获取符合条件的货物
        List<InvoiceGoodsInfo> invoiceGoodsInfoList = baseMapper.saleSelectSettlementOfPaymentGoods(searchGoodsVo.getBusinessNumber());
        //将货物放入对应的结算单
        for (SettlementBasicInfo settlementBasicInfo : settlementBasicInfos) {
//            settlementBasicInfo.setSupplier(customerService.getById(settlementBasicInfo.getSupplierId()));
            List<InvoiceGoodsInfo> invoiceGoodsInfos = new ArrayList<>();
            for (InvoiceGoodsInfo invoiceGoodsInfo : invoiceGoodsInfoList) {
                //前端显示用  预填充开票数量
                invoiceGoodsInfo.setOpenQuantity(invoiceGoodsInfo.getGoodsQuantity().subtract(invoiceGoodsInfo.getUsedNum()));
                if (invoiceGoodsInfo.getAcceptanceGoodsNumber().equals(settlementBasicInfo.getAcceptanceGoodsNumber())) {
                    invoiceGoodsInfos.add(invoiceGoodsInfo);
                }
            }
            settlementBasicInfo.setInvoiceGoodsInfos(invoiceGoodsInfos);
        }
        return new GridPage<>(searchGoodsVo.getRows(), searchGoodsVo.getPage(), page.getTotal(), settlementBasicInfos);
    }

    @Override
    public GridPage<SettlementGoodsInfo> saleSelectGoodsOfDiscount(SearchGoodsVo searchGoodsVo) {
        Page<SearchGoodsVo> page = PageHelper.startPage(searchGoodsVo.getPage(), searchGoodsVo.getRows());
        List<SettlementGoodsInfo> settlementGoodsInfoList = baseMapper.saleSelectGoodsOfDiscount(searchGoodsVo.getBusinessNumber());
        return new GridPage<>(searchGoodsVo.getRows(), searchGoodsVo.getPage(), page.getTotal(), settlementGoodsInfoList);
    }

    @Override
    public InvoiceCustomerInfo findByCustomer(Long customerId, Long businessBasicInfoId) {

        InvoiceCustomerInfo invoiceCustomerInfo = invoiceCustomerInfoService.getOne(new QueryWrapper<InvoiceCustomerInfo>()
                .eq("customer_id", customerId).eq("business_basic_info_id", businessBasicInfoId));
        if (invoiceCustomerInfo == null) {
            invoiceCustomerInfo = invoiceCustomerInfoService.getOne(new QueryWrapper<InvoiceCustomerInfo>()
                    .eq("customer_id", customerId)
                    .last("and business_basic_info_id is null"));
        }
        if (invoiceCustomerInfo == null) {
            Enterprise enterprise = iEnterpriseService.getById(customerId);
            if (enterprise != null) {
                invoiceCustomerInfo = new InvoiceCustomerInfo(enterprise);
            }
        }

        return invoiceCustomerInfo;
    }

    private InvoiceBasicInfo saveSaleInvoice(InvoiceBasicInfo invoiceBasicInfo) throws IOException {
        //保存销售发票信息
        invoiceBasicInfo.setInvoiceStatus(dictService.getByCode(InvoiceDict.ChildEnum.CREATE.getCode()).getId());
        save(invoiceBasicInfo);
        // 2023.8.4 开票信息与业务关联 历史数据处理
        if (invoiceBasicInfo.getEnterpriseCustomerInfoId() != null && invoiceBasicInfo.getBusinessBasicInfoId() != null) {
            InvoiceCustomerInfo newInvoiceCustomerInfo = new InvoiceCustomerInfo(invoiceBasicInfo);
            InvoiceCustomerInfo invoiceCustomerInfo = invoiceCustomerInfoService.getOne(new QueryWrapper<InvoiceCustomerInfo>()
                    .eq("customer_id", invoiceBasicInfo.getEnterpriseCustomerInfoId())
                    .eq("business_basic_info_id", invoiceBasicInfo.getBusinessBasicInfoId()));
            if (invoiceCustomerInfo == null) {
                invoiceCustomerInfo = invoiceCustomerInfoService.getOne(new QueryWrapper<InvoiceCustomerInfo>()
                        .eq("customer_id", invoiceBasicInfo.getEnterpriseCustomerInfoId())
                        .last("and business_basic_info_id is null"));
            }
            if (invoiceCustomerInfo != null) {
                newInvoiceCustomerInfo.setId(invoiceCustomerInfo.getId());
            }
            invoiceCustomerInfoService.saveOrUpdate(newInvoiceCustomerInfo);
        }

        //保存销售发票的货物信息
        List<InvoiceGoodsInfo> invoiceGoodsInfoList = invoiceBasicInfo.getInvoiceGoodsInfos();
        Boolean flag = false;
        BigDecimal num = BigDecimal.ZERO,amount = BigDecimal.ZERO,taxAmount = BigDecimal.ZERO,priceTaxTotal = BigDecimal.ZERO;

        if (invoiceGoodsInfoList != null && invoiceGoodsInfoList.size() > 0) {
            for (InvoiceGoodsInfo invoiceGoodsInfo : invoiceGoodsInfoList) {
                if (invoiceGoodsInfo.getGoodsQuantity() != null) {
                    flag = true;
                }
                //如果是货物判断开票数量
                if (invoiceBasicInfo.getAmountKind().equals(AmountKindDict.ChildEnum.PAYMENT.getCode())) {
                    BigDecimal usedNum = invoiceGoodsInfo.getUsedNum() == null?BigDecimal.ZERO: invoiceGoodsInfo.getUsedNum();
                    if (-1 == invoiceGoodsInfo.getGoodsQuantity().compareTo(usedNum.add(invoiceGoodsInfo.getOpenQuantity()))) {
                        throw new BusinessException(CodeUtil.FAIL, "开票数量 + 已开数量 不能大于 数量，请修改 “开票数量”");
                    }
                }
                invoiceGoodsInfo.setInvoiceBasicInfoId(invoiceBasicInfo.getId());
                num = num.add(invoiceGoodsInfo.getOpenQuantity() == null? BigDecimal.ZERO : invoiceGoodsInfo.getOpenQuantity());
            }
            invoiceGoodsInfoService.saveBatch(invoiceGoodsInfoList);
        }
        //保存采购发票信息
        //采购发票合计数量
//        BigDecimal openNum = BigDecimal.ZERO;
       // List<PurchaseInvoiceInfo> purchaseInvoiceInfos = invoiceBasicInfo.getPurchaseInvoiceInfos();
//        if(CollectionUtil.isNotEmpty(purchaseInvoiceInfos)){
//            for (PurchaseInvoiceInfo purchaseInvoiceInfo:purchaseInvoiceInfos) {
//                purchaseInvoiceInfo.setInvoiceBasicInfoId(invoiceBasicInfo.getId());
//                amount = amount.add(purchaseInvoiceInfo.getAmount() == null ? BigDecimal.ZERO : purchaseInvoiceInfo.getAmount());
//                taxAmount = taxAmount.add(purchaseInvoiceInfo.getTaxAmount() == null ? BigDecimal.ZERO : purchaseInvoiceInfo.getTaxAmount());
//                priceTaxTotal = priceTaxTotal.add(purchaseInvoiceInfo.getTaxAmount() == null ? BigDecimal.ZERO : purchaseInvoiceInfo.getTaxAmount());
//                openNum = openNum.add(purchaseInvoiceInfo.getNvoiceNum() == null? BigDecimal.ZERO : purchaseInvoiceInfo.getNvoiceNum());
//            }
//
//            purchaseInvoiceInfoService.saveBatch(purchaseInvoiceInfos);
//        }
//        if(openNum.compareTo(num) != 0){
//            throw new BusinessException(CodeUtil.FAIL, "开票申请货物数量合计与采购发票数量合计不符,请确认后提交");
//        }
        //财务审核-销售发票信息
      /*  SalesInvoiceInfo salesInvoiceInfo = new SalesInvoiceInfo();
        salesInvoiceInfo.setNvoiceNum(num);
        salesInvoiceInfo.setAmount(amount);
        salesInvoiceInfoService.save(salesInvoiceInfo);*/
        //保存资金占用费
        InvoicePossessionCostInfo invoicePossessionCostInfos = invoiceBasicInfo.getInvoicePossessionCostInfos();
        if (invoicePossessionCostInfos != null) {
            invoicePossessionCostInfos.setInvoiceBasicInfoId(invoiceBasicInfo.getId());
            invoicePossessionCostInfoService.save(invoicePossessionCostInfos);
        }
        //保存发票供应商信息
        List<InvoiceSupplierInfo> invoiceSupplierInfos = invoiceBasicInfo.getInvoiceSupplierInfos();
        if (invoiceSupplierInfos != null && invoiceSupplierInfos.size() > 0) {
            for (InvoiceSupplierInfo invoiceSupplierInfo : invoiceSupplierInfos) {
                invoiceSupplierInfo.setInvoiceBasicInfoId(invoiceBasicInfo.getId());
                SupplierInfo supplierInfo = iSupplierInfoService.getById(invoiceSupplierInfo.getSupplierId());
                Enterprise enterprise = iEnterpriseService.getById(supplierInfo.getcEnterpriseId());
                invoiceSupplierInfo.setSupplierName(enterprise.getCorporateName());
            }
            invoiceSupplierInfoService.saveBatch(invoiceSupplierInfos);
        }
        //保存采购发票附件
        List<Long> purchaseInvoiceFiles = invoiceBasicInfo.getPurchaseInvoiceFiles();
        if(CollectionUtil.isNotEmpty(purchaseInvoiceFiles)){
            for (Long fileId:purchaseInvoiceFiles ) {
//                FileStorageDO fileStorageDO = fileService.getById(fileId);
//                fileStorageDO.setBusinessId(invoiceBasicInfo.getId());
                fileService.updateBusinessId(fileId,invoiceBasicInfo.getId());
            }
        }
        //保存发票明细附件
        List<Long> invoiceDetailFiles = invoiceBasicInfo.getInvoiceDetailFiles();
        if(CollectionUtil.isNotEmpty(invoiceDetailFiles)){
            for (Long fileId:invoiceDetailFiles ) {
                fileService.updateBusinessId(fileId,invoiceBasicInfo.getId());
            }
        }

        // 生成参考的待开发票
//        if (invoiceGoodsInfoList != null && invoiceGoodsInfoList.size() > 0 && flag) {
//            //先删除旧的
//            List<FileStorageDO> fileStorageDOS = fileService.findByBusinessId(invoiceBasicInfo.getId(), FileTypeEnum.INVOICE_SALES_FILE.getCode());
//            for (FileStorageDO fileStorageDO:fileStorageDOS) {
//                fileService.updateBusinessId(fileStorageDO.getId(),null);
//            }
//            File file = inputData(invoiceBasicInfo);
//            FileStorageDO fileStorage =  FileStorageUtil.createFileStorage3(invoiceBasicInfo.getId()+"",FileTypeEnum.INVOICE_SALES_FILE,file.getName(),".xlsx");
//            fileStorage.setBusinessId(invoiceBasicInfo.getId());
//            fileService.save(fileStorage);
//        }
        return invoiceBasicInfo;
    }

    private File inputData(InvoiceBasicInfo invoiceBasicInfo) throws IOException {
        //创建工作簿
        Workbook workbook = new SXSSFWorkbook();
        //创建表
        Sheet sheet = workbook.createSheet();
        Enterprise enterprise = iEnterpriseService.getById(invoiceBasicInfo.getEnterpriseCustomerInfoId());
        List<InvoiceGoodsInfo> invoiceGoodsInfos = invoiceBasicInfo.getInvoiceGoodsInfos();
        InvoicePossessionCostInfo invoicePossessionCostInfos = invoiceBasicInfo.getInvoicePossessionCostInfos();
        //加价款
        BigDecimal goodsPlusPrice;
        //总开票货物数量
        BigDecimal openQuantitySum = BigDecimal.ZERO;
        for (InvoiceGoodsInfo invoiceGoodsInfo : invoiceGoodsInfos) {
            openQuantitySum = openQuantitySum.add(invoiceGoodsInfo.getOpenQuantity());
        }
        String fileName = FileStorageUtil.getAbsolutePath(invoiceBasicInfo.getTaxIdentifyNumber() + System.currentTimeMillis(), ".xlsx", FileTypeEnum.INVOICE_SALES_FILE);
        File file = new File(fileName);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        file.deleteOnExit();
        for (int i = 0; i < 14; i++) {
            Row row = sheet.createRow(0);
            Cell cell = row.createCell(0);
            cell.setCellValue("购方企业名称");
            Cell cell1 = row.createCell(1);
            cell1.setCellValue("购方税号");
            Cell cell2 = row.createCell(2);
            cell2.setCellValue("银行账户");
            Cell cell3 = row.createCell(3);
            cell3.setCellValue("地址电话");
            Cell cell4 = row.createCell(4);
            cell4.setCellValue("备注");
            Cell cell5 = row.createCell(5);
            cell5.setCellValue("商品名称");
            Cell cell6 = row.createCell(6);
            cell6.setCellValue("规格");
            Cell cell7 = row.createCell(7);
            cell7.setCellValue("单位");
            Cell cell8 = row.createCell(8);
            cell8.setCellValue("数量");
            Cell cell9 = row.createCell(9);
            cell9.setCellValue("单价");
            Cell cell10 = row.createCell(10);
            cell10.setCellValue("金额");
            Cell cell11 = row.createCell(11);
            cell11.setCellValue("税率");
            Cell cell12 = row.createCell(12);
            cell12.setCellValue("税额");
            Cell cell13 = row.createCell(13);
            cell13.setCellValue("价税合计");
        }
        for (int i = 0; i < invoiceGoodsInfos.size(); i++) {
            Row row = sheet.createRow(i + 1);
            Cell cell = row.createCell(0);
            cell.setCellValue(enterprise.getCorporateName());
            Cell cell1 = row.createCell(1);
            cell1.setCellValue(invoiceBasicInfo.getTaxIdentifyNumber());
            Cell cell2 = row.createCell(2);
            cell2.setCellValue(invoiceBasicInfo.getAccountBankName() + " " + invoiceBasicInfo.getAccountNumber());
            Cell cell3 = row.createCell(3);
            cell3.setCellValue(invoiceBasicInfo.getAddress() + " " + invoiceBasicInfo.getPhone());
            Cell cell4 = row.createCell(4);
            cell4.setCellValue(invoiceBasicInfo.getRemark());
            Cell cell5 = row.createCell(5);
            cell5.setCellValue(invoiceGoodsInfos.get(i).getGoodsName());
            Cell cell6 = row.createCell(6);
            cell6.setCellValue(invoiceGoodsInfos.get(i).getGoodsType());
            Cell cell7 = row.createCell(7);
            cell7.setCellValue(invoiceGoodsInfos.get(i).getGoodsUnit());
            Cell cell8 = row.createCell(8);
            cell8.setCellValue(invoiceGoodsInfos.get(i).getOpenQuantity().toString());
            Cell cell9 = row.createCell(9);
            Cell cell10 = row.createCell(10);
            //有加价款
            BigDecimal amount;
            if (invoicePossessionCostInfos != null && invoicePossessionCostInfos.getPossessionCostType().equals(1L)) {
                //单价 = 销售单价 + 加价款
                goodsPlusPrice = invoicePossessionCostInfos.getPossessionCost().divide(openQuantitySum, 2, RoundingMode.FLOOR);
                cell9.setCellValue(invoiceGoodsInfos.get(i).getSalesPrice().add(goodsPlusPrice).setScale(2, RoundingMode.FLOOR).toString());
                if (i == invoiceGoodsInfos.size() - 1) {
                    //最后一个货物时货物总价 = 总开票金额 + 剩余加价款
                    BigDecimal subtract = invoicePossessionCostInfos.getPossessionCost().subtract(goodsPlusPrice.multiply(openQuantitySum.subtract(invoiceGoodsInfos.get(i).getOpenQuantity())));
                    amount = invoiceGoodsInfos.get(i).getSalesPrice().multiply(invoiceGoodsInfos.get(i).getOpenQuantity()).add(subtract);
                    cell10.setCellValue(amount.divide(new BigDecimal("1.13"), 2, BigDecimal.ROUND_HALF_UP).toString());
                } else {
                    amount = invoiceGoodsInfos.get(i).getSalesPrice().multiply(invoiceGoodsInfos.get(i).getOpenQuantity()).add(goodsPlusPrice.multiply(invoiceGoodsInfos.get(i).getOpenQuantity()));
                    cell10.setCellValue(amount.divide(new BigDecimal("1.13"), 2, BigDecimal.ROUND_HALF_UP).toString());
                }
                //没有加价款
            } else {
                cell9.setCellValue(invoiceGoodsInfos.get(i).getSalesPrice().setScale(2, RoundingMode.FLOOR).toString());
                amount = invoiceGoodsInfos.get(i).getSalesPrice().multiply(invoiceGoodsInfos.get(i).getOpenQuantity());
                cell10.setCellValue(amount.divide(new BigDecimal("1.13"), 2, BigDecimal.ROUND_HALF_UP).toString());
            }
            Cell cell11 = row.createCell(11);
            cell11.setCellValue(0.13d);
            Cell cell12 = row.createCell(12);
            cell12.setCellValue(new BigDecimal("0.13").multiply(amount).divide(new BigDecimal("1.13"), 2, BigDecimal.ROUND_HALF_UP).toString());
            Cell cell13 = row.createCell(13);
            cell13.setCellValue(amount.setScale(2, RoundingMode.FLOOR).toString());

        }
        FileOutputStream fileOutputStream = new FileOutputStream(fileName);
        workbook.write(fileOutputStream);
        fileOutputStream.close();
        return new File(fileName);
    }
}
