package com.jeeplus.finance.invoice.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.jeeplus.common.TokenProvider;
import com.jeeplus.core.query.QueryWrapperGenerator;
import com.jeeplus.finance.invoice.domain.*;
import com.jeeplus.finance.invoice.mapper.*;
import com.jeeplus.finance.invoice.service.dto.*;
import com.jeeplus.finance.invoice.service.mapstruct.*;
import com.jeeplus.finance.projectRecords.mapper.CwProjectRecordsMapper;
import com.jeeplus.finance.projectRecords.service.dto.CwProjectRecordsDTO;
import com.jeeplus.finance.projectReport.domain.CwProjectReportData;
import com.jeeplus.finance.projectReport.mapper.CwProjectReportMapper;
import com.jeeplus.finance.workClientInfo.domain.CwWorkClientBase;
import com.jeeplus.finance.workClientInfo.domain.CwWorkClientBilling;
import com.jeeplus.finance.workClientInfo.mapper.CwWorkClientBaseMapper;
import com.jeeplus.finance.workClientInfo.mapper.CwWorkClientBillingMapper;
import com.jeeplus.finance.workClientInfo.service.CwWorkClientBillingService;
import com.jeeplus.finance.workClientInfo.service.CwWorkClientService;
//import com.jeeplus.pubmodules.oss.mapper.OssServiceMapper;
//import com.jeeplus.pubmodules.oss.service.OssService;
//import com.jeeplus.pubmodules.serialNumTpl.service.SerialnumTplService;
import com.jeeplus.finance.workClientInfo.service.dto.CwWorkClientBaseDTO;
import com.jeeplus.finance.workClientInfo.service.dto.CwWorkClientBillingDTO;
import com.jeeplus.sys.domain.User;
import com.jeeplus.sys.feign.*;
//import com.jeeplus.sys.service.UserService;
import com.jeeplus.sys.service.dto.AreaDTO;
import com.jeeplus.sys.service.dto.RoleDTO;
import com.jeeplus.sys.service.dto.UserDTO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)
public class CwFinanceInvoiceService extends ServiceImpl<CwFinanceInvoiceMapper, CwFinanceInvoice> {

    @Resource
    private CwFinanceInvoiceMapper cwFinanceInvoiceMapper;
    @Resource
    private CwFinanceInvoiceBaseMapper cwFinanceInvoiceBaseMapper;
    @Resource
    private CwFinanceInvoiceDetailMapper cwFinanceInvoiceDetailMapper;
    @Resource
    private CwFinanceInvoiceReceivablesMapper cwFinanceInvoiceReceivablesMapper;
    @Resource
    private CwFinanceInvoiceInvalidMapper cwFinanceInvoiceInvalidMapper;
    @Resource
    private CwProjectRecordsMapper cwProjectRecordsMapper;
    @Resource
    private CwProjectReportMapper cwProjectReportMapper;
    @Resource
    private CwWorkClientBaseMapper cwWorkClientBaseMapper;


//    @Resource
//    private SerialnumTplService serialnumTplService;
//    @Resource
//    private OssServiceMapper ossServiceMapper;
//    @Resource
//    private UserService userService;
//    @Resource
//    private OssService ossService;
    @Resource
    private CwWorkClientBillingService cwWorkClientBillingService;
    @Resource
    private CwWorkClientService cwWorkClientService;

    public List<String> getSearchList(ArrayList<String> searchIdList, List<String> ids) {
        List<String> newSearchIdList = searchIdList.stream().filter(item -> {
            AtomicInteger num = new AtomicInteger();
            ids.stream().forEach(id -> {
                if (item.equals(id)) {
                    num.getAndIncrement();
                }
            });
            if (num.get() > 0) {
                return true;
            }
            return false;
        }).collect(Collectors.toList());
        return newSearchIdList;
    }

    public IPage<CwFinanceInvoiceDTO> findList(Page<CwFinanceInvoiceDTO> page, CwFinanceInvoiceDTO cwFinanceInvoiceDTO,String export) throws Exception{
        QueryWrapper<CwFinanceInvoice> queryWrapper = QueryWrapperGenerator.buildQueryCondition ( CwFinanceInvoiceWrapper.INSTANCE.toEntity(cwFinanceInvoiceDTO), CwFinanceInvoice.class );
        queryWrapper.eq("fi.del_flag","0");
        queryWrapper.eq("a.del_flag","0");
        ArrayList<String> searchIdList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        AtomicInteger checkNum = new AtomicInteger();
        if (ObjectUtil.isNotEmpty(cwFinanceInvoiceDTO)) {
            //状态查询
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getStatus())){
                queryWrapper.eq("fi.status",cwFinanceInvoiceDTO.getStatus());
            }
            // 发票号查询
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getNumber())) {
                List<CwFinanceInvoiceDetail> cwFinanceInvoiceDetails = cwFinanceInvoiceDetailMapper.selectList(new LambdaQueryWrapper<CwFinanceInvoiceDetail>().like(CwFinanceInvoiceDetail::getNumber, cwFinanceInvoiceDTO.getNumber()));
                List<String> ids = cwFinanceInvoiceDetails.stream().distinct().map(CwFinanceInvoiceDetail::getInvoiceId).collect(Collectors.toList());
                if(CollectionUtil.isEmpty(ids)) {
                    return new Page<CwFinanceInvoiceDTO>();
                }else{
                    if (CollectionUtil.isNotEmpty(searchIdList)){
                        List<String> newSearchIdList = getSearchList(searchIdList,ids);
                        searchIdList = new ArrayList<String>();
                        for (String item : newSearchIdList) {
                            searchIdList.add(item);
                        }
                    }else{
                        if (checkNum.get() > 0){
                            return new Page<CwFinanceInvoiceDTO>();
                        }else{
                            for (String item : ids) {
                                searchIdList.add(item);
                            }
                        }
                    }
                    checkNum.getAndIncrement();
                }
            }
            // 开票总金额
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getAccountBegin())&&StringUtils.isNotBlank(cwFinanceInvoiceDTO.getAccountEnd())) {
                List<CwFinanceInvoice> cwFinanceInvoices = cwFinanceInvoiceMapper.selectList(new LambdaQueryWrapper<CwFinanceInvoice>()
                        .between(CwFinanceInvoice::getAccount, new BigDecimal(cwFinanceInvoiceDTO.getAccountBegin()), new BigDecimal(cwFinanceInvoiceDTO.getAccountEnd())));
                List<String> ids = cwFinanceInvoices.stream().distinct().map(CwFinanceInvoice::getId).collect(Collectors.toList());
                if(CollectionUtil.isEmpty(ids)) {
                    return new Page<CwFinanceInvoiceDTO>();
                }else{
                    if (CollectionUtil.isNotEmpty(searchIdList)){
                        List<String> newSearchIdList = getSearchList(searchIdList,ids);
                        searchIdList = new ArrayList<String>();
                        for (String item : newSearchIdList) {
                            searchIdList.add(item);
                        }
                    }else{
                        if (checkNum.get() > 0){
                            return new Page<CwFinanceInvoiceDTO>();
                        }else{
                            for (String item : ids) {
                                searchIdList.add(item);
                            }
                        }
                    }
                    checkNum.getAndIncrement();
                }
            }
            // 开票日期
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getBillingDateBegin())&&StringUtils.isNotBlank(cwFinanceInvoiceDTO.getBillingDateEnd())) {
                List<CwFinanceInvoice> cwFinanceInvoices = cwFinanceInvoiceMapper.selectList(new LambdaQueryWrapper<CwFinanceInvoice>()
                        .between(CwFinanceInvoice::getBillingDate, sdf.parse(cwFinanceInvoiceDTO.getBillingDateBegin()), sdf.parse(cwFinanceInvoiceDTO.getBillingDateEnd())));
                List<String> ids = cwFinanceInvoices.stream().distinct().map(CwFinanceInvoice::getId).collect(Collectors.toList());
                if(CollectionUtil.isEmpty(ids)) {
                    return new Page<CwFinanceInvoiceDTO>();
                }else{
                    if (CollectionUtil.isNotEmpty(searchIdList)){
                        List<String> newSearchIdList = getSearchList(searchIdList,ids);
                        searchIdList = new ArrayList<String>();
                        for (String item : newSearchIdList) {
                            searchIdList.add(item);
                        }
                    }else{
                        if (checkNum.get() > 0){
                            return new Page<CwFinanceInvoiceDTO>();
                        }else{
                            for (String item : ids) {
                                searchIdList.add(item);
                            }
                        }
                    }
                    checkNum.getAndIncrement();
                }
            }
            // 收款日期
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getRemittanceDateBegin())&&StringUtils.isNotBlank(cwFinanceInvoiceDTO.getRemittanceDateEnd())) {
                List<CwFinanceInvoice> cwFinanceInvoices = cwFinanceInvoiceMapper.selectList(new LambdaQueryWrapper<CwFinanceInvoice>()
                        .between(CwFinanceInvoice::getReceivablesDate, sdf.parse(cwFinanceInvoiceDTO.getRemittanceDateBegin()), sdf.parse(cwFinanceInvoiceDTO.getRemittanceDateEnd())));
                List<String> ids = cwFinanceInvoices.stream().distinct().map(CwFinanceInvoice::getId).collect(Collectors.toList());
                if(CollectionUtil.isEmpty(ids)) {
                    return new Page<CwFinanceInvoiceDTO>();
                }else{
                    if (CollectionUtil.isNotEmpty(searchIdList)){
                        List<String> newSearchIdList = getSearchList(searchIdList,ids);
                        searchIdList = new ArrayList<String>();
                        for (String item : newSearchIdList) {
                            searchIdList.add(item);
                        }
                    }else{
                        if (checkNum.get() > 0){
                            return new Page<CwFinanceInvoiceDTO>();
                        }else{
                            for (String item : ids) {
                                searchIdList.add(item);
                            }
                        }
                    }
                    checkNum.getAndIncrement();
                }
            }
            // 项目名称
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getProgramId())){
                    List<CwFinanceInvoiceBase> cwFinanceInvoiceBaseList = cwFinanceInvoiceBaseMapper.selectList(new LambdaQueryWrapper<CwFinanceInvoiceBase>()
                            .eq(CwFinanceInvoiceBase::getProgramId, cwFinanceInvoiceDTO.getProgramId()));
                    List<String> ids = cwFinanceInvoiceBaseList.stream().distinct().map(CwFinanceInvoiceBase::getInvoiceId).collect(Collectors.toList());
                    if(CollectionUtil.isEmpty(ids)) {
                        return new Page<CwFinanceInvoiceDTO>();
                    }else{
                        if (CollectionUtil.isNotEmpty(searchIdList)){
                            List<String> newSearchIdList = getSearchList(searchIdList,ids);
                            searchIdList = new ArrayList<String>();
                            for (String item : newSearchIdList) {
                                searchIdList.add(item);
                            }
                        }else{
                            if (checkNum.get() > 0){
                                return new Page<CwFinanceInvoiceDTO>();
                            }else{
                                for (String item : ids) {
                                    searchIdList.add(item);
                                }
                            }
                        }
                        checkNum.getAndIncrement();

                    }
            }else{
                if(StringUtils.isNotBlank(cwFinanceInvoiceDTO.getProgramName())){
                    //根据项目名称先查询项目对应的id集合
                    List<String> projectIdList = cwProjectRecordsMapper.getByProgramName(cwFinanceInvoiceDTO.getProgramName());
                    if(projectIdList.size()>0){
                        queryWrapper.in("a.program_id",projectIdList).or().like("a.program_name",cwFinanceInvoiceDTO.getProgramName());
                    }else{
                        queryWrapper.like("a.program_name",cwFinanceInvoiceDTO.getProgramName());
                    }
                }
            }
            // 经办人
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getOperator())){
                queryWrapper.and(q -> q.like("su.id", cwFinanceInvoiceDTO.getOperator())
                        .or().like("su.name", cwFinanceInvoiceDTO.getOperator()));
            }
            //报备类型
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getReportType())){
                queryWrapper.and(q ->q.eq("fi.report_type",cwFinanceInvoiceDTO.getReportType()).or().eq("pr.report_type",cwFinanceInvoiceDTO.getReportType()));
            }
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getName())){
                queryWrapper.like("fi.name",cwFinanceInvoiceDTO.getName());
            }

            // 对账人
//            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getReconciliationPeopleName())) {
//                List<User> users = SpringUtil.getBean ( IUserApi.class ).selectListByName(cwFinanceInvoiceDTO.getReconciliationPeopleName());
//                List<String> userIdList = users.stream().distinct().map(User::getId).collect(Collectors.toList());
//                if (CollectionUtil.isNotEmpty(userIdList)) {
//                    queryWrapper.in("fi.reconciliation_people",userIdList);
//                } else {
//                    return new Page<CwFinanceInvoiceDTO>();
//                }
//            }
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getReconciliationPeopleName())) {
                queryWrapper.and(q ->q.eq("fi.reconciliation_people",cwFinanceInvoiceDTO.getReconciliationPeopleName()).or().like("su1.name",cwFinanceInvoiceDTO.getReconciliationPeopleName()));
            }
            // 经办人部门
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getOperatorOffice())){
                List<User> userList = SpringUtil.getBean ( IUserApi.class ).getUserByOfficeAll(cwFinanceInvoiceDTO.getOperatorOffice());
                if (CollectionUtil.isNotEmpty(userList)) {
                    List<String> userIdList = userList.stream().distinct().map(User::getId).collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(userIdList)) {
                        queryWrapper.in("fi.create_by_id",userIdList);
                    } else {
                        return new Page<CwFinanceInvoiceDTO>();
                    }
                } else {
                    return new Page<CwFinanceInvoiceDTO>();
                }
            }
        }
        if (CollectionUtil.isNotEmpty(searchIdList)){
            List<String> ids = searchIdList.stream().distinct().collect(Collectors.toList());
            queryWrapper.in("fi.id",ids);
        } else{
            if (checkNum.get() > 0) {
                return new Page<CwFinanceInvoiceDTO>();
            }
        }
        // 如果当前用户是部门主任，则可以查看部门所有的项目、自己创建的项目以及所属项目组的项目
        // 如果当前用户是员工，则可以查看自己创建的项目以及所属项目组的项目
        StringBuilder officeIds = new StringBuilder();
//        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken());
        List<String> manageOfficeIdList= Lists.newArrayList();
        //判定是否为会计所长
//        if(CommonUtils.haveRoleKjsz()){
//            //获取当前人管理的部门id
//            if(StringUtils.isNotBlank(userDTO.getManageOfficeIds())){
//                manageOfficeIdList = Arrays.asList(userDTO.getManageOfficeIds().split(","));
//            }else{
//                manageOfficeIdList.add(userDTO.getOfficeDTO().getId());
//            }
//            for (int i = 0; i <manageOfficeIdList.size(); i++){
//                officeIds.append("'").append(manageOfficeIdList.get(i)).append("'");
//                if(i < manageOfficeIdList.size()-1){
//                    officeIds.append(",");
//                }
//            }
//        }


        //获取当前登录人信息
//        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken ( ));
        //获取当前登录人所属角色
        //若是评估部门主任，则仅展示部门主任信息
        //若是评估员工，则仅展示自己的数据信息
//        List<RoleDTO> roleDTOList = userDTO.getRoleDTOList();
//        for (RoleDTO roleDTO : roleDTOList) {
//            //根据角色id查询角色信息
//            RoleDTO roleDTOById = SpringUtil.getBean(IRoleApi.class).getRoleDTOById(roleDTO.getId());
//            if("cwyg".equals(roleDTOById.getEnName()) && "兴光会计员工".equals(roleDTOById.getName())){
//                queryWrapper.eq("a.create_by_id", userDTO.getId());
//                break;
//            }else if("cw_bmzr".equals(roleDTOById.getEnName()) && "兴光会计部门主任".equals(roleDTOById.getName())){
//                queryWrapper.eq("sumo.user_id", userDTO.getId());
//                break;
//            }else if("szfbdagly".equals(roleDTOById.getEnName()) && "苏州分部档案管理员".equals(roleDTOById.getName())){
//                queryWrapper.eq("d.office_id", "1613800824395530242");
//                break;
//            }
//        }
        IPage<CwFinanceInvoiceDTO> list = null;
        //获取当前登录人角色是否是苏州报告签字盖章代办
        UserDTO userDTO = SpringUtil.getBean(IUserApi.class).getByToken(TokenProvider.getCurrentToken());
        if (CollectionUtil.isNotEmpty(userDTO.getRoleDTOList())){
            for (RoleDTO roleDTO : userDTO.getRoleDTOList()) {
                RoleDTO dtoById = SpringUtil.getBean(IRoleApi.class).getRoleDTOById(roleDTO.getId());
                if ("szbgqzgzdb".equals(dtoById.getEnName())){
                    queryWrapper.orderByDesc("fi.billing_date");
                    list = cwFinanceInvoiceMapper.findList(page,queryWrapper);
                    break;
                }
            }
        }
        if (null == list){
            queryWrapper.orderByDesc("fi.create_time").orderByAsc("cfid.number");
            if(StringUtils.isNotBlank(export) && "export".equals(export)){
                list = cwFinanceInvoiceMapper.findExportList(page, queryWrapper);
                list.getRecords().forEach(item->{
                    //预开票且报告与发票关联完成的则已完成关联
                    if(StringUtils.isNotBlank(item.getIsPreInvoice()) && StringUtils.isNotBlank(item.getReportNos()) && StringUtils.isNotBlank(item.getNo())){
                        if ("1".equals(item.getIsPreInvoice())){
                            item.setIsCompleteInvoice("2");
                        }
                    }else if (StringUtils.isNotBlank(item.getIsPreInvoice()) && StringUtils.isBlank(item.getReportNos()) && StringUtils.isNotBlank(item.getNo())){
                        if ("1".equals(item.getIsPreInvoice())){
                            item.setIsCompleteInvoice("0");
                        }
                    }
                });
            }else{
                list = cwFinanceInvoiceMapper.findList(page, queryWrapper);
            }
        }
        for (CwFinanceInvoiceDTO record : list.getRecords()) {
            double aDouble = Double.parseDouble(record.getAccountDetail());
            BigDecimal bd = new BigDecimal(aDouble).setScale(2, BigDecimal.ROUND_HALF_UP);
            String string = bd.toString();
            record.setAccountDetail(string);
        }



        return list;
    }


    public IPage<CwFinanceInvoiceDTO> findRedList(Page<CwFinanceInvoiceDTO> page, CwFinanceInvoiceDTO cwFinanceInvoiceDTO,String export) throws Exception{
        QueryWrapper<CwFinanceInvoice> queryWrapper = QueryWrapperGenerator.buildQueryCondition ( CwFinanceInvoiceWrapper.INSTANCE.toEntity(cwFinanceInvoiceDTO), CwFinanceInvoice.class );
        queryWrapper.eq("fi.del_flag","0");
        queryWrapper.eq("a.del_flag","0");
        //判定开票金额大于等于0 的发票信息
        queryWrapper.ge("fi.account","0");
        ArrayList<String> searchIdList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        AtomicInteger checkNum = new AtomicInteger();
        if (ObjectUtil.isNotEmpty(cwFinanceInvoiceDTO)) {
            // 发票号查询
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getNumber())) {
                List<CwFinanceInvoiceDetail> cwFinanceInvoiceDetails = cwFinanceInvoiceDetailMapper.selectList(new LambdaQueryWrapper<CwFinanceInvoiceDetail>().like(CwFinanceInvoiceDetail::getNumber, cwFinanceInvoiceDTO.getNumber()));
                List<String> ids = cwFinanceInvoiceDetails.stream().distinct().map(CwFinanceInvoiceDetail::getInvoiceId).collect(Collectors.toList());
                if(CollectionUtil.isEmpty(ids)) {
                    return new Page<CwFinanceInvoiceDTO>();
                }else{
                    if (CollectionUtil.isNotEmpty(searchIdList)){
                        List<String> newSearchIdList = getSearchList(searchIdList,ids);
                        searchIdList = new ArrayList<String>();
                        for (String item : newSearchIdList) {
                            searchIdList.add(item);
                        }
                    }else{
                        if (checkNum.get() > 0){
                            return new Page<CwFinanceInvoiceDTO>();
                        }else{
                            for (String item : ids) {
                                searchIdList.add(item);
                            }
                        }
                    }
                    checkNum.getAndIncrement();
                }
            }
            // 开票总金额
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getAccountBegin())&&StringUtils.isNotBlank(cwFinanceInvoiceDTO.getAccountEnd())) {
                List<CwFinanceInvoice> cwFinanceInvoices = cwFinanceInvoiceMapper.selectList(new LambdaQueryWrapper<CwFinanceInvoice>()
                        .between(CwFinanceInvoice::getAccount, new BigDecimal(cwFinanceInvoiceDTO.getAccountBegin()), new BigDecimal(cwFinanceInvoiceDTO.getAccountEnd())));
                List<String> ids = cwFinanceInvoices.stream().distinct().map(CwFinanceInvoice::getId).collect(Collectors.toList());
                if(CollectionUtil.isEmpty(ids)) {
                    return new Page<CwFinanceInvoiceDTO>();
                }else{
                    if (CollectionUtil.isNotEmpty(searchIdList)){
                        List<String> newSearchIdList = getSearchList(searchIdList,ids);
                        searchIdList = new ArrayList<String>();
                        for (String item : newSearchIdList) {
                            searchIdList.add(item);
                        }
                    }else{
                        if (checkNum.get() > 0){
                            return new Page<CwFinanceInvoiceDTO>();
                        }else{
                            for (String item : ids) {
                                searchIdList.add(item);
                            }
                        }
                    }
                    checkNum.getAndIncrement();
                }
            }
            // 开票日期
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getBillingDateBegin())&&StringUtils.isNotBlank(cwFinanceInvoiceDTO.getBillingDateEnd())) {
                List<CwFinanceInvoice> cwFinanceInvoices = cwFinanceInvoiceMapper.selectList(new LambdaQueryWrapper<CwFinanceInvoice>()
                        .between(CwFinanceInvoice::getBillingDate, sdf.parse(cwFinanceInvoiceDTO.getBillingDateBegin()), sdf.parse(cwFinanceInvoiceDTO.getBillingDateEnd())));
                List<String> ids = cwFinanceInvoices.stream().distinct().map(CwFinanceInvoice::getId).collect(Collectors.toList());
                if(CollectionUtil.isEmpty(ids)) {
                    return new Page<CwFinanceInvoiceDTO>();
                }else{
                    if (CollectionUtil.isNotEmpty(searchIdList)){
                        List<String> newSearchIdList = getSearchList(searchIdList,ids);
                        searchIdList = new ArrayList<String>();
                        for (String item : newSearchIdList) {
                            searchIdList.add(item);
                        }
                    }else{
                        if (checkNum.get() > 0){
                            return new Page<CwFinanceInvoiceDTO>();
                        }else{
                            for (String item : ids) {
                                searchIdList.add(item);
                            }
                        }
                    }
                    checkNum.getAndIncrement();
                }
            }
            // 收款日期
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getRemittanceDateBegin())&&StringUtils.isNotBlank(cwFinanceInvoiceDTO.getRemittanceDateEnd())) {
                List<CwFinanceInvoice> cwFinanceInvoices = cwFinanceInvoiceMapper.selectList(new LambdaQueryWrapper<CwFinanceInvoice>()
                        .between(CwFinanceInvoice::getReceivablesDate, sdf.parse(cwFinanceInvoiceDTO.getRemittanceDateBegin()), sdf.parse(cwFinanceInvoiceDTO.getRemittanceDateEnd())));
                List<String> ids = cwFinanceInvoices.stream().distinct().map(CwFinanceInvoice::getId).collect(Collectors.toList());
                if(CollectionUtil.isEmpty(ids)) {
                    return new Page<CwFinanceInvoiceDTO>();
                }else{
                    if (CollectionUtil.isNotEmpty(searchIdList)){
                        List<String> newSearchIdList = getSearchList(searchIdList,ids);
                        searchIdList = new ArrayList<String>();
                        for (String item : newSearchIdList) {
                            searchIdList.add(item);
                        }
                    }else{
                        if (checkNum.get() > 0){
                            return new Page<CwFinanceInvoiceDTO>();
                        }else{
                            for (String item : ids) {
                                searchIdList.add(item);
                            }
                        }
                    }
                    checkNum.getAndIncrement();
                }
            }
            // 项目名称
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getProgramId())){
                List<CwFinanceInvoiceBase> cwFinanceInvoiceBaseList = cwFinanceInvoiceBaseMapper.selectList(new LambdaQueryWrapper<CwFinanceInvoiceBase>()
                        .eq(CwFinanceInvoiceBase::getProgramId, cwFinanceInvoiceDTO.getProgramId()));
                List<String> ids = cwFinanceInvoiceBaseList.stream().distinct().map(CwFinanceInvoiceBase::getInvoiceId).collect(Collectors.toList());
                if(CollectionUtil.isEmpty(ids)) {
                    return new Page<CwFinanceInvoiceDTO>();
                }else{
                    if (CollectionUtil.isNotEmpty(searchIdList)){
                        List<String> newSearchIdList = getSearchList(searchIdList,ids);
                        searchIdList = new ArrayList<String>();
                        for (String item : newSearchIdList) {
                            searchIdList.add(item);
                        }
                    }else{
                        if (checkNum.get() > 0){
                            return new Page<CwFinanceInvoiceDTO>();
                        }else{
                            for (String item : ids) {
                                searchIdList.add(item);
                            }
                        }
                    }
                    checkNum.getAndIncrement();

                }
            }
            // 经办人
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getOperator())){
                queryWrapper.and(q -> q.like("su.id", cwFinanceInvoiceDTO.getOperator())
                        .or().like("su.name", cwFinanceInvoiceDTO.getOperator()));
            }
            //报备类型
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getReportType())){
                queryWrapper.eq("fi.report_type",cwFinanceInvoiceDTO.getReportType()).or(i->i.eq("pr.report_type",cwFinanceInvoiceDTO.getReportType()));
            }
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getReconciliationPeopleName())) {
                queryWrapper.and(q ->q.eq("fi.reconciliation_people",cwFinanceInvoiceDTO.getReconciliationPeopleName()).or().like("su1.name",cwFinanceInvoiceDTO.getReconciliationPeopleName()));
            }
            // 经办人部门
            if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getOperatorOffice())){
                List<User> userList = SpringUtil.getBean ( IUserApi.class ).getUserByOfficeAll(cwFinanceInvoiceDTO.getOperatorOffice());
                if (CollectionUtil.isNotEmpty(userList)) {
                    List<String> userIdList = userList.stream().distinct().map(User::getId).collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(userIdList)) {
                        queryWrapper.in("fi.create_by_id",userIdList);
                    } else {
                        return new Page<CwFinanceInvoiceDTO>();
                    }
                } else {
                    return new Page<CwFinanceInvoiceDTO>();
                }
            }
        }
        if (CollectionUtil.isNotEmpty(searchIdList)){
            List<String> ids = searchIdList.stream().distinct().collect(Collectors.toList());
            queryWrapper.in("fi.id",ids);
        } else{
            if (checkNum.get() > 0) {
                return new Page<CwFinanceInvoiceDTO>();
            }
        }
        IPage<CwFinanceInvoiceDTO> list = null;
        if(StringUtils.isNotBlank(export) && "export".equals(export)){
            list = cwFinanceInvoiceMapper.findExportList(page, queryWrapper);
            list.getRecords().forEach(item->{
                //预开票且报告与发票关联完成的则已完成关联
                if(StringUtils.isNotBlank(item.getIsPreInvoice()) && StringUtils.isNotBlank(item.getReportNos()) && StringUtils.isNotBlank(item.getNo())){
                    if ("1".equals(item.getIsPreInvoice())){
                        item.setIsCompleteInvoice("2");
                    }
                }else if (StringUtils.isNotBlank(item.getIsPreInvoice()) && StringUtils.isBlank(item.getReportNos()) && StringUtils.isNotBlank(item.getNo())){
                    if ("1".equals(item.getIsPreInvoice())){
                        item.setIsCompleteInvoice("0");
                    }
                }
            });
        }else{
            list = cwFinanceInvoiceMapper.findList(page, queryWrapper);
        }

        return list;
    }



    public CwFinanceInvoiceDTO queryById(String id) {

        CwFinanceInvoiceDTO cwFinanceInvoiceDTO = cwFinanceInvoiceMapper.queryById(id);
        if(ObjectUtil.isNotEmpty(cwFinanceInvoiceDTO) && ObjectUtil.isNotEmpty(cwFinanceInvoiceDTO.getRedInvoiceFlag()) && 1 == cwFinanceInvoiceDTO.getRedInvoiceFlag()){
            //此处为红冲数据 需要获取发票号
            if(StringUtils.isNotBlank(cwFinanceInvoiceDTO.getRedInvoiceRelevancyId())){
                CwFinanceInvoiceDTO redCwFinanceInvoiceDTO = cwFinanceInvoiceMapper.queryById(cwFinanceInvoiceDTO.getRedInvoiceRelevancyId());
                String invoiceNumberStr = cwFinanceInvoiceMapper.getInvoiceNumberStr(redCwFinanceInvoiceDTO.getId());
                cwFinanceInvoiceDTO.setInvoiceNumberStr(invoiceNumberStr);
            }
        }
        //获取项目是否预开票
        if (ObjectUtil.isNotEmpty(cwFinanceInvoiceDTO)){
            for (CwFinanceInvoiceBaseDTO cwFinanceInvoiceBaseDTO : cwFinanceInvoiceDTO.getFinanceInvoiceBaseDTOList()) {
                CwProjectRecordsDTO projectRecordsDTO = cwProjectRecordsMapper.queryById(cwFinanceInvoiceBaseDTO.getProgramId());
                if (ObjectUtil.isNotEmpty(projectRecordsDTO)){
                    if (StringUtils.isNotBlank(projectRecordsDTO.getIsPreInvoice()) && "1".equals(projectRecordsDTO.getIsPreInvoice())){
                        cwFinanceInvoiceBaseDTO.setIsPreInvoice(projectRecordsDTO.getIsPreInvoice());
                        cwFinanceInvoiceDTO.setIsPreInvoice(projectRecordsDTO.getIsPreInvoice());
                    }
                }
                List<CwProjectReportData> reportData = cwProjectReportMapper.getByProjectId(cwFinanceInvoiceBaseDTO.getProgramId());
                if (CollectionUtils.isNotEmpty(reportData)){
                    for (CwFinanceInvoiceDetailDTO cwFinanceInvoiceDetailDTO : cwFinanceInvoiceDTO.getFinanceInvoiceDetailDTOList()) {
                        for (CwProjectReportData reportDatum : reportData) {
                            if (StringUtils.isNotBlank(reportDatum.getReportNo()) && StringUtils.isNotBlank(reportDatum.getInvoiceNumber()) && StringUtils.isNotBlank(cwFinanceInvoiceDetailDTO.getNumber()) &&
                                    reportDatum.getInvoiceNumber().equals(cwFinanceInvoiceDetailDTO.getNumber())) {
                                cwFinanceInvoiceBaseDTO.setReportNo(reportDatum.getReportNo());
                                break;
                            }
                        }

                    }
                }
                break;
            }


        }
        // 电话号获取
        if (ObjectUtil.isNotEmpty(cwFinanceInvoiceDTO) && StringUtils.isNotBlank(cwFinanceInvoiceDTO.getBillingId())) {
            CwWorkClientBilling cwWorkClientBilling = cwWorkClientBillingService.getById(cwFinanceInvoiceDTO.getBillingId());
            if (ObjectUtil.isNotEmpty(cwWorkClientBilling) && StringUtils.isNotBlank(cwWorkClientBilling.getPhone())) {
                // 如果通过billingId(开票信息id)可以查询到数据，并且数据的phone(电话)有值的话，那么就将方法返回结果的telPhone替换为查询到的phone
                cwFinanceInvoiceDTO.setTelPhone(cwWorkClientBilling.getPhone());
            } else {
                // 如果通过billingId(开票信息id)查询不到数据或者查询到数据的phone值为空
                // 将billingId(开票信息id)置空，因为前端根据billingId是否有值来判断->是否允许电话号码可以手填
                cwFinanceInvoiceDTO.setBillingId("");
                // 将telPhone(电话号)置空
//                cwFinanceInvoiceDTO.setTelPhone("");
            }
        }

        // 实际开票单位名称获取
        if (ObjectUtil.isNotEmpty(cwFinanceInvoiceDTO) && StringUtils.isNotBlank(cwFinanceInvoiceDTO.getBillingWorkplaceRealId())) {
            CwWorkClientBase cwWorkClientBase = cwWorkClientService.getById(cwFinanceInvoiceDTO.getBillingWorkplaceRealId());
            if (ObjectUtil.isNotEmpty(cwWorkClientBase) && StringUtils.isNotBlank(cwWorkClientBase.getName())) {
                // 如果通过billingWorkplaceRealId(实际开票单位id)可以查询到数据，并且数据的name(实际开票单位名称)有值的话，
                // 那么就将方法返回结果的billingWorkplaceReal替换
                cwFinanceInvoiceDTO.setBillingWorkplaceReal(cwWorkClientBase.getName());
            }
        }





        return cwFinanceInvoiceDTO;
    }

    public CwFinanceInvoice saveForm(CwFinanceInvoiceDTO cwFinanceInvoiceDTO) throws Exception{
        CwFinanceInvoice cwFinanceInvoice = CwFinanceInvoiceWrapper.INSTANCE.toEntity(cwFinanceInvoiceDTO);
        //获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken());
        if (ObjectUtil.isNotEmpty(cwFinanceInvoice)) {
            if(StringUtils.isBlank(cwFinanceInvoice.getId())){

                //发票编号生成
                String serialNum = SpringUtil.getBean ( IWorkAttachmentApi.class ).genSerialNum(userDTO.getCompanyDTO().getId(), CwFinanceInvoiceDTO.BIZ_CODE,TokenProvider.getCurrentToken());
                cwFinanceInvoice.setNo(serialNum);
                if (StringUtils.isBlank(cwFinanceInvoice.getInvalidStatus())){
                    cwFinanceInvoice.setInvalidStatus("0");
                }
                if (StringUtils.isBlank(cwFinanceInvoice.getReceivablesStatus())){
                    cwFinanceInvoice.setReceivablesStatus("0");
                }
                if(StringUtils.isNotEmpty(cwFinanceInvoice.getReportType())){
                    cwFinanceInvoice.setReportType(cwFinanceInvoiceDTO.getReportType());
                }
            }
        }
        if (StringUtils.isBlank(cwFinanceInvoice.getNo())){
            String serialNum = SpringUtil.getBean ( IWorkAttachmentApi.class ).genSerialNum(userDTO.getCompanyDTO().getId(), CwFinanceInvoiceDTO.BIZ_CODE,TokenProvider.getCurrentToken());
            cwFinanceInvoice.setNo(serialNum);
        }
        if(StringUtils.isNotEmpty(cwFinanceInvoiceDTO.getActualDrawerEmailAddress())){
            cwFinanceInvoice.setActualDrawerEmailAddress(cwFinanceInvoiceDTO.getActualDrawerEmailAddress());
        }
        if(StringUtils.isNotBlank(cwFinanceInvoiceDTO.getId())){
            cwFinanceInvoiceMapper.updateInfoById(cwFinanceInvoice);
        }else{
            cwFinanceInvoiceMapper.insert(cwFinanceInvoice);
        }

        if (ObjectUtil.isNotEmpty(cwFinanceInvoiceDTO)) {
            // 如果当前是执行的是收款页面的保存方法
            if ("1".equals(cwFinanceInvoiceDTO.getIsReceivables())) {
                // 如果传过来的收款日期为空，则将本条发票的收款日期置空
                if (ObjectUtil.isEmpty(cwFinanceInvoiceDTO.getReceivablesDate())) {
                    // 根据发票id，置空发票的收款日期
                    cwFinanceInvoiceMapper.setReceivablesDateNull(cwFinanceInvoice.getId());
                }
            }
            // 基本信息保存
            if(CollectionUtil.isNotEmpty(cwFinanceInvoiceDTO.getFinanceInvoiceBaseDTOList())){
                List<String> delIds = cwFinanceInvoiceDTO.getFinanceInvoiceBaseDTOList().stream().distinct().filter(item->{
                    if(StringUtils.isNotBlank(item.getId())){
                        return true;
                    }
                    return false;
                }).map(CwFinanceInvoiceBaseDTO::getId).collect(Collectors.toList());
                if(CollectionUtil.isNotEmpty(delIds)){
                    cwFinanceInvoiceBaseMapper.delete(new QueryWrapper<CwFinanceInvoiceBase>().lambda()
                            .eq(CwFinanceInvoiceBase::getInvoiceId, cwFinanceInvoice.getId()).notIn(CwFinanceInvoiceBase::getId,delIds));
                }else{
                    cwFinanceInvoiceBaseMapper.delete(new QueryWrapper<CwFinanceInvoiceBase>().lambda()
                            .eq(CwFinanceInvoiceBase::getInvoiceId, cwFinanceInvoice.getId()));
                }
                cwFinanceInvoiceDTO.getFinanceInvoiceBaseDTOList().stream().forEach(item->{
                    CwFinanceInvoiceBase cwFinanceInvoiceBase = CwFinanceInvoiceBaseWrapper.INSTANCE.toEntity(item);

                    cwFinanceInvoiceBase.setAccount(item.getAccount());
                    if(StringUtils.isNotBlank(cwFinanceInvoiceBase.getId())){
                        cwFinanceInvoiceBaseMapper.updateById(cwFinanceInvoiceBase);
                    }else{
                        cwFinanceInvoiceBase.setInvoiceId(cwFinanceInvoice.getId());
                        cwFinanceInvoiceBaseMapper.insert(cwFinanceInvoiceBase);
                    }
                    if (StringUtils.isNotEmpty(cwFinanceInvoiceBase.getProgramId())){
                        CwProjectRecordsDTO projectRecordsDTO = cwProjectRecordsMapper.queryById(cwFinanceInvoiceBase.getProgramId());
                        //普通项目
                        if (null!=projectRecordsDTO){
                            cwFinanceInvoiceBase.setType("1");
                            cwFinanceInvoiceBaseMapper.updateById(cwFinanceInvoiceBase);
                            cwFinanceInvoice.setRecordType(cwFinanceInvoiceBase.getType());
                        }
                        if (null!=cwProjectReportMapper.queryById(cwFinanceInvoiceBase.getProgramId())){
                            cwFinanceInvoiceBase.setType("2");
                            cwFinanceInvoiceBaseMapper.updateById(cwFinanceInvoiceBase);
                            cwFinanceInvoice.setRecordType(cwFinanceInvoiceBase.getType());
                        }
                        //预开票项目
                        if (null != projectRecordsDTO && "1".equals(projectRecordsDTO.getIsPreInvoice())){
                            cwFinanceInvoiceBase.setType("4");
                            cwFinanceInvoiceBaseMapper.updateById(cwFinanceInvoiceBase);
                            cwFinanceInvoice.setRecordType(cwFinanceInvoiceBase.getType());
                        }
                    }else {
                        cwFinanceInvoiceBase.setType("0");
                        cwFinanceInvoiceBaseMapper.updateById(cwFinanceInvoiceBase);
                        cwFinanceInvoice.setRecordType(cwFinanceInvoiceBase.getType());
                    }

                });
            }else{
                cwFinanceInvoiceBaseMapper.delete(new QueryWrapper<CwFinanceInvoiceBase>().lambda()
                        .eq(CwFinanceInvoiceBase::getInvoiceId, cwFinanceInvoice.getId()));
            }
            // 附件
            Map<String,String> map = new HashMap<>();
            String fileList = JSON.toJSONString((cwFinanceInvoiceDTO.getWorkAttachmentDtoList()));
            String attachmentId = cwFinanceInvoice.getId();
            String attachmentFlag = "cw_invoice";
            map.put("fileList",fileList);
            map.put("attachmentId",attachmentId);
            map.put("attachmentFlag",attachmentFlag);
            map.put("currentToken", TokenProvider.getCurrentToken ( ));
            SpringUtil.getBean ( IWorkAttachmentApi.class ).saveOrUpdateFileListFlag(map);

            // 签约合同附件
            Map<String,String> map1 = new HashMap<>();
            String fileList1 = JSON.toJSONString((cwFinanceInvoiceDTO.getWorkAttachmenSignContract()));
            String attachmentId1 = cwFinanceInvoice.getId();
            String attachmentFlag1 = "cw_invoice_sign_contract";
            map1.put("fileList",fileList1);
            map1.put("attachmentId",attachmentId1);
            map1.put("attachmentFlag",attachmentFlag1);
            map1.put("currentToken", TokenProvider.getCurrentToken ( ));
            SpringUtil.getBean ( IWorkAttachmentApi.class ).saveOrUpdateFileListFlag(map1);

            // 发票明细保存
            if(CollectionUtil.isNotEmpty(cwFinanceInvoiceDTO.getFinanceInvoiceDetailDTOList())){
                List<String> delIds = cwFinanceInvoiceDTO.getFinanceInvoiceDetailDTOList().stream().distinct().filter(item -> {
                    if (StringUtils.isNotBlank(item.getId())) {
                        return true;
                    }
                    return false;
                }).map(CwFinanceInvoiceDetailDTO::getId).collect(Collectors.toList());
                if(CollectionUtil.isNotEmpty(delIds)){
                    cwFinanceInvoiceDetailMapper.delete(new QueryWrapper<CwFinanceInvoiceDetail>().lambda()
                            .eq(CwFinanceInvoiceDetail::getInvoiceId, cwFinanceInvoice.getId())
                            .notIn(CwFinanceInvoiceDetail::getId,delIds));
                }else{
                    cwFinanceInvoiceDetailMapper.delete(new QueryWrapper<CwFinanceInvoiceDetail>().lambda().eq(CwFinanceInvoiceDetail::getInvoiceId, cwFinanceInvoice.getId()));
                }
                cwFinanceInvoiceDTO.getFinanceInvoiceDetailDTOList().stream().forEach(item->{
                    CwFinanceInvoiceDetail cwFinanceInvoiceDetail = CwFinanceInvoiceDetailWrapper.INSTANCE.toEntity(item);
                    if(StringUtils.isNotBlank(cwFinanceInvoiceDetail.getId())){
                        cwFinanceInvoiceDetailMapper.updateById(cwFinanceInvoiceDetail);
                    }else{
                        cwFinanceInvoiceDetail.setInvoiceId(cwFinanceInvoice.getId());
                        cwFinanceInvoiceDetailMapper.insert(cwFinanceInvoiceDetail);
                    }
                });
            }else{
                cwFinanceInvoiceDetailMapper.delete(new QueryWrapper<CwFinanceInvoiceDetail>().lambda().eq(CwFinanceInvoiceDetail::getInvoiceId, cwFinanceInvoice.getId()));
            }
            // 收款明细保存
            if(CollectionUtil.isNotEmpty(cwFinanceInvoiceDTO.getFinanceInvoiceReceivablesDTOList())){
                List<String> delIds = cwFinanceInvoiceDTO.getFinanceInvoiceReceivablesDTOList().stream().distinct().filter(item -> {
                    if (StringUtils.isNotBlank(item.getId())) {
                        return true;
                    }
                    return false;
                }).map(CwFinanceInvoiceReceivablesDTO::getId).collect(Collectors.toList());
                if(CollectionUtil.isNotEmpty(delIds)){
                    cwFinanceInvoiceReceivablesMapper.delete(new QueryWrapper<CwFinanceInvoiceReceivables>().lambda()
                            .eq(CwFinanceInvoiceReceivables::getInvoiceId, cwFinanceInvoice.getId())
                            .notIn(CwFinanceInvoiceReceivables::getId,delIds));
                }else{
                    cwFinanceInvoiceReceivablesMapper.delete(new QueryWrapper<CwFinanceInvoiceReceivables>().lambda().eq(CwFinanceInvoiceReceivables::getInvoiceId, cwFinanceInvoice.getId()));
                }
                cwFinanceInvoiceDTO.getFinanceInvoiceReceivablesDTOList().stream().forEach(item->{
                    CwFinanceInvoiceReceivables cwFinanceInvoiceReceivables = CwFinanceInvoiceReceivablesWrapper.INSTANCE.toEntity(item);
                    if(StringUtils.isNotBlank(cwFinanceInvoiceReceivables.getId())){
                        cwFinanceInvoiceReceivablesMapper.updateById(cwFinanceInvoiceReceivables);
                    }else{
                        cwFinanceInvoiceReceivables.setInvoiceId(cwFinanceInvoice.getId());
                        cwFinanceInvoiceReceivablesMapper.insert(cwFinanceInvoiceReceivables);
                    }
                });
            }else{
                cwFinanceInvoiceReceivablesMapper.delete(new QueryWrapper<CwFinanceInvoiceReceivables>().lambda().eq(CwFinanceInvoiceReceivables::getInvoiceId, cwFinanceInvoice.getId()));
            }
            // 作废信息保存
            if(ObjectUtil.isNotEmpty(cwFinanceInvoiceDTO.getFinanceInvoiceInvalidDTO())){
                CwFinanceInvoiceInvalid cwFinanceInvoiceInvalid = CwFinanceInvoiceInvalidWrapper.INSTANCE.toEntity(cwFinanceInvoiceDTO.getFinanceInvoiceInvalidDTO());
                if(StringUtils.isNotBlank(cwFinanceInvoiceInvalid.getId())){
                    cwFinanceInvoiceInvalidMapper.update(cwFinanceInvoiceInvalid,
                            new QueryWrapper<CwFinanceInvoiceInvalid>().lambda().eq(CwFinanceInvoiceInvalid::getId, cwFinanceInvoiceInvalid.getId()));
                }else{
                    cwFinanceInvoiceInvalid.setInvalidStatus("0");
                    cwFinanceInvoiceInvalid.setInvoiceId(cwFinanceInvoice.getId());
                    cwFinanceInvoiceInvalidMapper.insert(cwFinanceInvoiceInvalid);
                }
            }else{
                cwFinanceInvoiceInvalidMapper.delete(new QueryWrapper<CwFinanceInvoiceInvalid>().lambda().eq(CwFinanceInvoiceInvalid::getInvoiceId, cwFinanceInvoice.getId()));
                CwFinanceInvoiceInvalid cwFinanceInvoiceInvalid = new CwFinanceInvoiceInvalid();
                cwFinanceInvoiceInvalid.setInvalidStatus("0");
                cwFinanceInvoiceInvalid.setInvoiceId(cwFinanceInvoice.getId());
                cwFinanceInvoiceInvalidMapper.insert(cwFinanceInvoiceInvalid);
            }
        }
        return cwFinanceInvoice;
    }

    public ResponseEntity saveInvoice(CwFinanceInvoiceDTO cwFinanceInvoiceDTO) throws Exception{
        this.saveForm(cwFinanceInvoiceDTO);
        return ResponseEntity.ok("保存成功");
    }

    public String saveFormInvalid(CwFinanceInvoiceDTO cwFinanceInvoiceDTO) throws Exception{
        String invoiceId = this.saveForm(cwFinanceInvoiceDTO).getId();
        List<CwFinanceInvoiceInvalid> cwFinanceInvoiceInvalids = cwFinanceInvoiceInvalidMapper.selectList(
                new QueryWrapper<CwFinanceInvoiceInvalid>().lambda().eq(CwFinanceInvoiceInvalid::getInvoiceId, invoiceId));
        return cwFinanceInvoiceInvalids.get(0).getId();
    }

    public ResponseEntity deleteByIds(String ids) {
        String idArray[] =ids.split(",");
        this.removeByIds (Lists.newArrayList (idArray));
        return ResponseEntity.ok ("删除成功");
    }

    public Boolean queryByNumber(String number, String id) {
        List<CwFinanceInvoiceDetail> cwFinanceInvoiceDetails = cwFinanceInvoiceDetailMapper.selectList(new QueryWrapper<CwFinanceInvoiceDetail>().lambda()
                .eq(CwFinanceInvoiceDetail::getNumber, number)
                .eq(CwFinanceInvoiceDetail::getDelFlag, '0')
                .ne(StringUtils.isNotBlank(id), CwFinanceInvoiceDetail::getId,id));
        if (CollectionUtil.isNotEmpty(cwFinanceInvoiceDetails)) {
            return true;
        }
        return false;
    }

    public String queryIdByInvalidId(String id) {
        CwFinanceInvoiceInvalid cwFinanceInvoiceInvalid = cwFinanceInvoiceInvalidMapper.selectById(id);
        return cwFinanceInvoiceInvalid.getInvoiceId();
    }

    public String updateStatusById(CwFinanceInvoiceDTO cwFinanceInvoiceDTO) {
        CwFinanceInvoice cwFinanceInvoice = CwFinanceInvoiceWrapper.INSTANCE.toEntity(cwFinanceInvoiceDTO);
        if ("4".equals(cwFinanceInvoice.getStatus())) {
            cwFinanceInvoiceMapper.updateInfoById(cwFinanceInvoice);
        }else{
            cwFinanceInvoiceMapper.update(cwFinanceInvoice, new QueryWrapper<CwFinanceInvoice>().lambda().eq(CwFinanceInvoice::getId, cwFinanceInvoice.getId()));
        }
        return "操作成功";
    }

    public String isReceivables(CwFinanceInvoiceDTO cwFinanceInvoiceDTO) {
        CwFinanceInvoice cwFinanceInvoice = CwFinanceInvoiceWrapper.INSTANCE.toEntity(cwFinanceInvoiceDTO);
        cwFinanceInvoice.setReceivablesDate(new Date());
        cwFinanceInvoiceMapper.update(cwFinanceInvoice, new QueryWrapper<CwFinanceInvoice>().lambda().eq(CwFinanceInvoice::getId, cwFinanceInvoice.getId()));
        return "操作成功";
    }

    public String importDecide(List<CwFinanceInvoiceDetailDTO> list, ArrayList<CwFinanceInvoiceDetailDTO> arrayList, HashMap<String,String> hashMap){
        for (CwFinanceInvoiceDetailDTO cwFinanceInvoiceDetailDTO : list) {
            if(ObjectUtil.isEmpty(cwFinanceInvoiceDetailDTO)){
                continue;
            }

            if(StringUtils.isBlank(cwFinanceInvoiceDetailDTO.getNumber())){
                return "文件中有发票号为空，请重新填写";
            }
            if(StringUtils.isNotBlank(cwFinanceInvoiceDetailDTO.getNumber())){
                try {
                    Integer integer = new Integer(cwFinanceInvoiceDetailDTO.getNumber());
                    if (integer < 0) {
                        return "文件中有发票号填写不正确，请重新填写";
                    }
                }catch (Exception e){
                    return "文件中有发票号填写不正确，请重新填写";
                }
                List<CwFinanceInvoiceDetail> cwFinanceInvoiceDetailList = cwFinanceInvoiceDetailMapper.selectList(new QueryWrapper<CwFinanceInvoiceDetail>().eq("number", cwFinanceInvoiceDetailDTO.getNumber()));
                if(CollectionUtil.isNotEmpty(cwFinanceInvoiceDetailList)){
                    return "文件中有发票号已在系统中存在，请重新填写";
                }
            }
//            if (StringUtils.isBlank(financeInvoiceDetailDTO.getRate())) {
//                return "文件中有税率为空，请重新填写";
//            }
            if (StringUtils.isNotBlank(cwFinanceInvoiceDetailDTO.getRate())) {
                try {
                    if ((new BigDecimal(cwFinanceInvoiceDetailDTO.getRate())).compareTo(new BigDecimal(1)) == -1
                            || (new BigDecimal(cwFinanceInvoiceDetailDTO.getRate())).compareTo(new BigDecimal(100)) == 1) {
                        return "文件中有税率填写不正确，请重新填写";
                    }
                }catch (Exception e){
                    return "文件中有税率填写不正确，请重新填写";
                }
            }
            if (StringUtils.isBlank(cwFinanceInvoiceDetailDTO.getAccount())) {
                return "文件中有开票金额为空，请重新填写";
            } else {
                try {
                    cwFinanceInvoiceDetailDTO.setAccount(new BigDecimal(cwFinanceInvoiceDetailDTO.getAccount()).toString());
                }catch (Exception e){
                    return "文件中有开票金额填写不正确，请重新填写";
                }
            }

            hashMap.put(cwFinanceInvoiceDetailDTO.getNumber(),null);

            arrayList.add(cwFinanceInvoiceDetailDTO);
        }
        return null;
    }

    public List<CwFinanceInvoiceDTO> getByIds(String projectId,CwFinanceInvoiceDTO cwFinanceInvoiceDTO) throws Exception{
        if(StringUtils.isNotBlank(projectId)){
            List<String> idByProjectId = cwFinanceInvoiceMapper.getIdByProjectId(projectId);
            if (CollectionUtil.isNotEmpty(idByProjectId)){
                QueryWrapper<CwFinanceInvoice> queryWrapper = QueryWrapperGenerator.buildQueryCondition ( CwFinanceInvoiceWrapper.INSTANCE.toEntity(cwFinanceInvoiceDTO), CwFinanceInvoice.class );
                queryWrapper.in("fi.id", idByProjectId);
                queryWrapper.eq("fi.del_flag","0");
                queryWrapper.eq("fi.status","5"); // 发票申请流程已通过
                queryWrapper.orderByDesc("fi.create_time");
                queryWrapper.eq("fi.invalid_status","0"); // 未作废
                return cwFinanceInvoiceMapper.getByIds(queryWrapper);
            }
        }
        return new ArrayList<>();
    }

    public List<CwFinanceInvoiceDTO> getByIds2(String projectId,CwFinanceInvoiceDTO cwFinanceInvoiceDTO) throws Exception{
        if(StringUtils.isNotBlank(projectId)){
            List<String> idByProjectId = cwFinanceInvoiceMapper.getIdByProjectId(projectId);
            if (CollectionUtil.isNotEmpty(idByProjectId)){
                QueryWrapper<CwFinanceInvoice> queryWrapper = QueryWrapperGenerator.buildQueryCondition ( CwFinanceInvoiceWrapper.INSTANCE.toEntity(cwFinanceInvoiceDTO), CwFinanceInvoice.class );
                queryWrapper.in("fi.id", idByProjectId);
                queryWrapper.eq("fi.del_flag","0");
                queryWrapper.orderByDesc("fi.create_time");
                queryWrapper.eq("fi.invalid_status","0"); // 未作废
                return cwFinanceInvoiceMapper.getByIds(queryWrapper);
            }
        }
        return new ArrayList<>();
    }

    public List<CwFinanceInvoiceDTO> getByContractId(String contractId,CwFinanceInvoiceDTO cwFinanceInvoiceDTO) throws Exception{
        if(StringUtils.isNotBlank(contractId)){
            List<String> idByContractId = cwFinanceInvoiceMapper.getIdByContractId(contractId);
            if (CollectionUtil.isNotEmpty(idByContractId)){
                QueryWrapper<CwFinanceInvoice> queryWrapper = QueryWrapperGenerator.buildQueryCondition ( CwFinanceInvoiceWrapper.INSTANCE.toEntity(cwFinanceInvoiceDTO), CwFinanceInvoice.class );
                queryWrapper.in("fi.id", idByContractId);
                queryWrapper.eq("fi.del_flag","0");
                queryWrapper.eq("fi.status","5"); // 发票申请流程已通过
                queryWrapper.orderByDesc("fi.create_time");
                queryWrapper.eq("fi.invalid_status","0"); // 未作废
                return cwFinanceInvoiceMapper.getByIds(queryWrapper);
            }
        }
        return new ArrayList<>();
    }

    public List<CwFinanceInvoiceDTO> getIdByClientId(String clientId,CwFinanceInvoiceDTO cwFinanceInvoiceDTO) throws Exception{
        if(StringUtils.isNotBlank(clientId)){
            List<String> idByClientId = cwFinanceInvoiceMapper.getIdByClientId(clientId);
            if (CollectionUtil.isNotEmpty(idByClientId)){
                QueryWrapper<CwFinanceInvoice> queryWrapper = QueryWrapperGenerator.buildQueryCondition ( CwFinanceInvoiceWrapper.INSTANCE.toEntity(cwFinanceInvoiceDTO), CwFinanceInvoice.class );
                queryWrapper.in("fi.id", idByClientId);
                queryWrapper.eq("fi.del_flag","0");
                queryWrapper.eq("fi.status","5"); // 发票申请流程已通过
                queryWrapper.orderByDesc("fi.create_time");
                queryWrapper.eq("fi.invalid_status","0"); // 未作废
                return cwFinanceInvoiceMapper.getByIds(queryWrapper);
            }
        }
        return new ArrayList<>();
    }

    /**
     * 对到处数据进行处理
     * @param list
     * @return
     */
    public List<CwFinanceInvoiceDTO> disposeExportList(List<CwFinanceInvoiceDTO> list){
        List<CwFinanceInvoiceDTO> resultList = Lists.newArrayList();
        //对数据进行分组
        Map<String, List<CwFinanceInvoiceDTO>> temporaryListMap = dataMessageDispose(list);


        for (String key : temporaryListMap.keySet()) {
            List<CwFinanceInvoiceDTO> mapList = temporaryListMap.get(key);
            if (mapList.size() <= 1) {
                if (mapList.size() == 1 && (StringUtils.isBlank(mapList.get(0).getBaseAccount()) || "0".equals(mapList.get(0).getBaseAccount()))) {
                    mapList.get(0).setBaseAccount(mapList.get(0).getAccount());
                }
                resultList.addAll(mapList);
            }else{
                Boolean flag = false;

                for (CwFinanceInvoiceDTO invoiceDTO : mapList) {
                    flag = true;
                    //判定：项目开票金额不为0且不为空
                    if (!StringUtils.isBlank(invoiceDTO.getBaseAccount()) && !"0".equals(invoiceDTO.getBaseAccount())) {
                        flag = false;
                        break;
                    }
                }

                if (flag) {//开票金额为0的状态
                    for(int i = 0 ;i<mapList.size();i ++ ){
                        CwFinanceInvoiceDTO invoiceDTO = mapList.get(i);
                        if(i == 0 ){
                            mapList.get(0).setBaseAccount(mapList.get(0).getAccount());
                        }else{
                            invoiceDTO.setAccount("0");
                            invoiceDTO.setAccountDetail("0");
                        }
                    }
                } else {//开票金额不为0的状态
                    int indexFlag = 0;
                    //创建发票集合
                    List<String> invoiceNumber = Lists.newArrayList();
                    BigDecimal allMoneyB = new BigDecimal(0);
                    for (CwFinanceInvoiceDTO invoiceDTO : mapList) {
                        indexFlag ++ ;
                        //开票金额
                        BigDecimal accountB = new BigDecimal(invoiceDTO.getAccount());
                        //发票金额
                        BigDecimal accountDetailB = new BigDecimal(invoiceDTO.getAccountDetail());
                        //项目开票金额
                        BigDecimal baseAccountB = new BigDecimal(invoiceDTO.getBaseAccount());

                        if(allMoneyB.compareTo(accountB) == 0){
                            invoiceDTO.setBaseAccount("0");
                        }else{
                            allMoneyB = allMoneyB.add(baseAccountB);
                        }

                        //将发票号进行汇总并转换成字符串
                        String invoiceNumberStr = String.join(", ", invoiceNumber);
                        //如果 遍历行不是第一行，则需要将总开票费用填写为0 且需要判定当前行的发票号是否已经存在于发票汇总中，若存在，则表示发票金额已经录入，则不需要重复添加，给予默认值0
                        if(indexFlag>1){
                            invoiceDTO.setAccount("0");
                            if(invoiceNumberStr.contains(invoiceDTO.getNumber())){
                                invoiceDTO.setAccountDetail("0");
                            }
                            //invoiceDTO.setNumber("");
                        }
                        //将发票号进行存储
                        invoiceNumber.add(invoiceDTO.getNumber());
                    }
                }
                resultList.addAll(mapList);
            }
        }

        return resultList;
    }

    /**
     * 分组
     * @param list
     * @return
     */
    private Map<String, List<CwFinanceInvoiceDTO>> dataMessageDispose(List<CwFinanceInvoiceDTO> list) {
        Map<String, List<CwFinanceInvoiceDTO>> infoMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(list)) {
            // 分组
            for (CwFinanceInvoiceDTO vo : list) {
                List<CwFinanceInvoiceDTO> tempList = infoMap.get(vo.getNo());
                /*如果取不到数据,那么直接new一个空的ArrayList**/
                if (tempList == null) {
                    tempList = new ArrayList<>();
                    tempList.add(vo);
                    infoMap.put(vo.getNo(), tempList);
                }
                else {
                    /*某个vo之前已经存放过了,则直接追加数据到原来的List里**/
                    tempList.add(vo);
                }
            }
        }
        return infoMap;
    }

    /**
     * 根据项目id查询开票信息
     * @param page
     * @param cwFinanceInvoiceDTO
     * @return
     */
    public IPage<CwFinanceInvoiceDTO> listByProgramId(Page<CwFinanceInvoiceDTO> page, CwFinanceInvoiceDTO cwFinanceInvoiceDTO) {
        QueryWrapper<CwFinanceInvoiceDTO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fib.del_flag",'0');
        queryWrapper.eq("fi.del_flag",'0');
        queryWrapper.eq("fi.status",cwFinanceInvoiceDTO.getStatus());
        queryWrapper.eq("fib.program_id",cwFinanceInvoiceDTO.getProgramId()).or().eq("fib.program_id",cwFinanceInvoiceDTO.getId());
        if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getReconciliationPeopleName())) {
            queryWrapper.eq("fi.reconciliation_people",cwFinanceInvoiceDTO.getReconciliationPeopleName());
        }
        if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getNo())) {
            queryWrapper.like("fi.no",cwFinanceInvoiceDTO.getNo());
        }
        if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getNumber())) {
            queryWrapper.like("fi.number",cwFinanceInvoiceDTO.getNumber());
        }
        // 开票日期
        if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getBillingDateBegin()) || StringUtils.isNotBlank(cwFinanceInvoiceDTO.getBillingDateEnd())) {
            queryWrapper.between("fi.billing_date", cwFinanceInvoiceDTO.getBillingDateBegin(), cwFinanceInvoiceDTO.getBillingDateEnd());
        }

        IPage<CwFinanceInvoiceDTO> list = null;
        list = cwFinanceInvoiceMapper.listByProgramId(page, queryWrapper);
        //根据项目id查询项目下的报告中是否有发票编号信息
        ArrayList<String> strings = new ArrayList<>();
        List<CwProjectReportData> reportData = cwProjectReportMapper.getByProjectId(cwFinanceInvoiceDTO.getProgramId());

        if (CollectionUtils.isNotEmpty(reportData)){
            for (CwProjectReportData reportDatum : reportData) {
                if (StringUtils.isNotBlank(reportDatum.getInvoiceNumber())){
                    strings.add(reportDatum.getInvoiceNumber());
                }
            }
        }

        // 创建一个Set来存储唯一的发票编号，用于检查重复
        Set<String> uniqueInvoiceNumbers = new HashSet<>(strings);

        // 创建一个新的列表来存放需要保留的CwFinanceInvoiceDTO对象
        List<CwFinanceInvoiceDTO> filteredList = new ArrayList<>();

        for (CwFinanceInvoiceDTO record : list.getRecords()) {
            // 如果发票编号不在strings集合中，则添加到filteredList
            if (!uniqueInvoiceNumbers.contains(record.getNo())){
                filteredList.add(record);
            }
        }

        // 将filteredList设置回原来的list.getRecords()
        list.setRecords(filteredList);
        list.setTotal(filteredList.size());
        return list;
    }

    /**
     * 根据发票编号查询是否与预开票项目下的报告完成关联
     * @param no
     * @return
     */
    public boolean getByNo(String no) {
        Integer data = cwFinanceInvoiceMapper.getCountByNo(no);
        if (data != 0){
            return true;
        }
        return false;
    }

    /*
    查询开票时间距今超过1个月的开票数据
     */
    public List<CwFinanceInvoiceDTO> getExceedCwFinance() {

        //查询开票时间为空的，或者是否开票为否的  开票时间距今超过1个月的开票数据
        List<CwFinanceInvoiceDTO> list=cwFinanceInvoiceMapper.getExceedCwFinance();
        //将红字发票及红字发票关联的发票进行剔除
        ArrayList<String> redReveId = new ArrayList<>();
        for (CwFinanceInvoiceDTO cwFinanceInvoiceDTO : list) {
            if (ObjectUtils.isNotEmpty(cwFinanceInvoiceDTO.getRedInvoiceFlag()) && 1 == cwFinanceInvoiceDTO.getRedInvoiceFlag()){
                redReveId.add(cwFinanceInvoiceDTO.getId());
                redReveId.add(cwFinanceInvoiceDTO.getRedInvoiceRelevancyId());
            }
        }
        //将redReveId中存放的id从list中进行去除
        List<CwFinanceInvoiceDTO> filteredList = list.stream()
                .filter(dto -> !redReveId.contains(dto.getId()))
                .collect(Collectors.toList());

        return filteredList;
    }

    private static final Pattern EMAIL_PATTERN = Pattern.compile("^[A-Za-z0-9+_.-]+@(.+)$");


    /**
     * 导入发票数据
     * @param listA
     * @param arrayList
     * @param hashMap
     * @return
     */
    public String importFinance(List<CwFinanceImportDTO> listA, ArrayList<CwFinanceImportDTO> arrayList, HashMap<String, String> hashMap) {
        ArrayList<String> projectNoList = new ArrayList<>();
        ArrayList<String> reportNoList = new ArrayList<>();
        ArrayList<String> clientList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(listA)){
            for (CwFinanceImportDTO cwFinanceImportDTO : listA) {
                // 1. 报告号和项目编号校验
                if (StringUtils.isBlank(cwFinanceImportDTO.getReportNo()) && StringUtils.isBlank(cwFinanceImportDTO.getProjectNo())) {
                    return "报告号和项目名称不能同时为空";
                }
                // 4. 开票内容必填
                if (StringUtils.isBlank(cwFinanceImportDTO.getBillingContent())) {
                    return "开票内容不能为空";
                }
                // 5. 邮箱校验
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getActualDrawerEmailAddress()) &&
                        !EMAIL_PATTERN.matcher(cwFinanceImportDTO.getActualDrawerEmailAddress()).matches()) {
                    return "接收邮箱格式不正确";
                }
                // 6.单位名称校验
                if (StringUtils.isBlank(cwFinanceImportDTO.getBillingWorkplaceReal())){
                    return "单位名称不能为空";
                }
                //发票类型校验
                if (StringUtils.isBlank(cwFinanceImportDTO.getType())){
                    return "发票类型不能为空";
                }
                //开票类型校验
                if (StringUtils.isBlank(cwFinanceImportDTO.getBillingType())){
                    return "开票类型不能为空";
                }
                //银行名称校验
                if ("专票".equals(cwFinanceImportDTO.getType()) && "企业开票".equals(cwFinanceImportDTO.getBillingType()) && StringUtils.isBlank(cwFinanceImportDTO.getOpenBank())){
                    return "发票类型为专票且开票类型为企业开票下的开户银行名称不能为空";
                }

                if (StringUtils.isNotBlank(cwFinanceImportDTO.getProjectNo())){
                    projectNoList.add(cwFinanceImportDTO.getProjectNo());
                }
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getReportNo())){
                    reportNoList.add(cwFinanceImportDTO.getReportNo());
                }
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getBillingWorkplaceReal())){
                    clientList.add(cwFinanceImportDTO.getBillingWorkplaceReal());
                }
            }
        }

        //获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean(IUserApi.class).getByToken(TokenProvider.getCurrentToken());
        //查询全部的项目信息
        List<CwProjectRecordsDTO> projectRecordsList = cwProjectRecordsMapper.selectAllList(userDTO.getId(),projectNoList);
        //查询全部的报告信息
        List<CwProjectReportData> projectReportList = cwProjectReportMapper.getList(userDTO.getId(),reportNoList);
        //查询全部的发票信息
        List<CwFinanceInvoiceDTO> invoiceDTOList = cwFinanceInvoiceMapper.getList(userDTO.getId());
        //查询全部的客户信息
        List<CwWorkClientBaseDTO> cwWorkClientBaseDTOList = cwWorkClientBaseMapper.getList(clientList);

        if (CollectionUtils.isNotEmpty(listA)){
            for (CwFinanceImportDTO cwFinanceImportDTO : listA) {

                // 2. 项目开票金额校验
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getBaseAccount())){
                    double amount = Double.parseDouble(cwFinanceImportDTO.getBaseAccount());
                    if (amount < 0 && StringUtils.isBlank(cwFinanceImportDTO.getRedInvoiceRelevancyNumber())) {
                        return "开票金额为负时，必须填写关联红字发票的发票编号";
                    }
                    if (amount < 0 && StringUtils.isNotBlank(cwFinanceImportDTO.getRedInvoiceRelevancyNumber())) {
                        //将开票编号中的英文转为大写
                        String upperCaseRedInvoice = cwFinanceImportDTO.getRedInvoiceRelevancyNumber().toUpperCase();
                        boolean exists = invoiceDTOList.stream()
                                .anyMatch(invoice -> upperCaseRedInvoice.equals(invoice.getNo()));
                        if (exists) {
                            //根据关联红字发票编号查询发票信息
                            for (CwFinanceInvoiceDTO cwFinanceInvoiceDTO : invoiceDTOList) {
                                if (cwFinanceInvoiceDTO.getNo().equals(upperCaseRedInvoice)){
                                    if (StringUtils.isNotBlank(cwFinanceInvoiceDTO.getAccount())){
                                        double parseDouble = Double.parseDouble(cwFinanceInvoiceDTO.getAccount());
                                        if (parseDouble < 0){
                                            return "关联红字发票编号："+cwFinanceImportDTO.getRedInvoiceRelevancyNumber()+" 的开票金额为负,请重新填写关联红字发票编号";
                                        }
                                    }else {
                                        return "关联红字发票编号："+cwFinanceImportDTO.getRedInvoiceRelevancyNumber()+" 的开票金额为空,请重新填写关联红字发票编号";
                                    }
                                }
                            }
                        } else {
                            return "关联红字发票编号："+cwFinanceImportDTO.getRedInvoiceRelevancyNumber()+" 不是当前登录人所创建,请重新填写";
                        }
                    }
                }else {
                    return "项目开票金额不能为空";
                }

                //发票类型校验
//                if ("专票".equals(cwFinanceImportDTO.getType()) && "企业开票".equals(cwFinanceImportDTO.getBillingType()) && StringUtils.isNotBlank(cwFinanceImportDTO.getBillingWorkplaceReal())){
//                    //根据单位查询客户信息
//                    boolean match = clientBillingList.stream().anyMatch(client -> cwFinanceImportDTO.getBillingWorkplaceReal().equals(client.getCompanyName()));
//                    if (match){
//                        for (CwWorkClientBillingDTO cwWorkClientBilling : clientBillingList) {
//                            if (cwWorkClientBilling.getCompanyName().equals(cwFinanceImportDTO.getBillingWorkplaceReal())){
//                                if (StringUtils.isBlank(cwWorkClientBilling.getTaxpayerIdentificationNo())){
//                                    return "客户名称——"+cwFinanceImportDTO.getBillingWorkplaceReal()+"下的纳税人识别号在系统中不存在，请填写";
//                                }
//                                if (StringUtils.isBlank(cwWorkClientBilling.getAddress())){
//                                    return "客户名称——"+cwFinanceImportDTO.getBillingWorkplaceReal()+"下的地址在系统中不存在，请填写";
//                                }
//                                if (StringUtils.isBlank(cwWorkClientBilling.getPhone())){
//                                    return "客户名称——"+cwFinanceImportDTO.getBillingWorkplaceReal()+"下的电话在系统中不存在，请填写";
//                                }
//                                if (StringUtils.isBlank(cwWorkClientBilling.getAccountHolder())){
//                                    return "客户名称——"+cwFinanceImportDTO.getBillingWorkplaceReal()+"下的开户银行名称在系统中不存在，请填写";
//                                }
//                                if (StringUtils.isBlank(cwWorkClientBilling.getAccount())){
//                                    return "客户名称——"+cwFinanceImportDTO.getBillingWorkplaceReal()+"下的银行账号在系统中不存在，请填写";
//                                }
//                            }
//                        }
//                    }else {
//                        if (StringUtils.isBlank(cwFinanceImportDTO.getTaxpayerIdentificationNo())){
//                            return "客户名称——"+cwFinanceImportDTO.getBillingWorkplaceReal()+"在系统中不存在，纳税人识别号不能为空";
//                        }
//                        if (StringUtils.isBlank(cwFinanceImportDTO.getAddress())){
//                            return "客户名称——"+cwFinanceImportDTO.getBillingWorkplaceReal()+"在系统中不存在，地址不能为空";
//                        }
//                        if (StringUtils.isBlank(cwFinanceImportDTO.getTelPhone())){
//                            return "客户名称——"+cwFinanceImportDTO.getBillingWorkplaceReal()+"在系统中不存在，电话不能为空";
//                        }
//                        if (StringUtils.isBlank(cwFinanceImportDTO.getOpenBank())){
//                            return "客户名称——"+cwFinanceImportDTO.getBillingWorkplaceReal()+"在系统中不存在，开户银行名称不能为空";
//                        }
//                        if (StringUtils.isBlank(cwFinanceImportDTO.getBankAccount())){
//                            return "客户名称——"+cwFinanceImportDTO.getBillingWorkplaceReal()+"在系统中不存在，银行账号不能为空";
//                        }
//                    }
//
//                }

                arrayList.add(cwFinanceImportDTO);
            }
        }

        ArrayList<CwFinanceInvoice> invoiceArrayList = new ArrayList<>();
        ArrayList<CwFinanceInvoiceBase> baseArrayList = new ArrayList<>();

        //发票类型
        String invoiceTypeDatas = SpringUtil.getBean ( IDictApi.class ).getDictValueListMapByDict ("invoice_type");
        Map<String,Object> invoiceTypeValueDTOs = JSON.parseObject(invoiceTypeDatas, new TypeReference<Map<String,Object>>() {});
        //开票类型
        String invoiceBillingTypeDatas = SpringUtil.getBean ( IDictApi.class ).getDictValueListMapByDict ("invoice_billing_type");
        Map<String,Object> invoiceBillingTypeValueDTOs = JSON.parseObject(invoiceBillingTypeDatas, new TypeReference<Map<String,Object>>() {});
        //开票内容
        String invoiceBillingContentDatas = SpringUtil.getBean ( IDictApi.class ).getDictValueListMapByDict ("invoice_billing_content");
        Map<String,Object> invoiceBillingContentValueDTOs = JSON.parseObject(invoiceBillingContentDatas, new TypeReference<Map<String,Object>>() {});

        //根据当前登录人所属部门查询不同的人员信息
        List<UserDTO> allUserInfo = findUserByTenantId(userDTO);
        //区域
        List<AreaDTO> areaDTOList = cwFinanceInvoiceMapper.getAllArea();
        List<AreaDTO> buildTree = buildTree(areaDTOList);

        if (CollectionUtils.isNotEmpty(arrayList)){
            for (CwFinanceImportDTO cwFinanceImportDTO : arrayList) {
                CwFinanceInvoice cwFinanceInvoice = new CwFinanceInvoice();
                String id = UUID.randomUUID().toString().replace("-", "");
                cwFinanceInvoice.setId(id);

                CwFinanceInvoiceBase cwFinanceInvoiceBase = new CwFinanceInvoiceBase();
                String baseId = UUID.randomUUID().toString().replace("-", "");
                cwFinanceInvoiceBase.setId(baseId);
                cwFinanceInvoiceBase.setInvoiceId(id);

                //保存报告或项目信息
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getProjectNo()) && StringUtils.isBlank(cwFinanceImportDTO.getReportNo())){

                    //查询全部的项目信息
                    List<CwProjectRecordsDTO> projectRecordsListByName = cwProjectRecordsMapper.selectProjectListByName(userDTO.getId(),cwFinanceImportDTO.getProjectNo());
                    if (projectRecordsListByName.size()>1) {
                        return "项目名称："+cwFinanceImportDTO.getProjectNo()+" 存在多条，无法进行导入";
                    }

                    boolean exist = projectRecordsListByName.stream().anyMatch(records -> records.getProjectName().equals(cwFinanceImportDTO.getProjectNo()));
                    if (exist){
                        for (CwProjectRecordsDTO cwProjectRecords : projectRecordsListByName) {
                            if (cwProjectRecords.getProjectName().equals(cwFinanceImportDTO.getProjectNo())){
                                cwFinanceInvoiceBase.setProgramId(cwProjectRecords.getId());
                                cwFinanceInvoiceBase.setProgramNo(cwProjectRecords.getProjectNumber());
                                cwFinanceInvoiceBase.setProgramName(cwProjectRecords.getProjectName());
                                cwFinanceInvoiceBase.setType("1");
                                cwFinanceInvoiceBase.setContractId(cwProjectRecords.getContractId());
                                cwFinanceInvoiceBase.setContractName(cwProjectRecords.getContractName());
                                break;
                            }
                        }
                    }else {
                        return "项目名称："+cwFinanceImportDTO.getProjectNo()+" 不是当前登录人所创建或该项目下存在报告,请重新填写";
                    }
                }
                if ((StringUtils.isNotBlank(cwFinanceImportDTO.getReportNo()) && StringUtils.isBlank(cwFinanceImportDTO.getProjectNo())) ||(StringUtils.isNotBlank(cwFinanceImportDTO.getReportNo()) && StringUtils.isNotBlank(cwFinanceImportDTO.getProjectNo()))){
                    boolean exist = projectReportList.stream().anyMatch(report -> report.getReportNo().equals(cwFinanceImportDTO.getReportNo()));
                    if (exist){
                        for (CwProjectReportData reportData : projectReportList) {
                            if (reportData.getReportNo().equals(cwFinanceImportDTO.getReportNo())){
                                cwFinanceInvoiceBase.setProgramId(reportData.getId());
                                cwFinanceInvoiceBase.setProgramNo(reportData.getProjectNumber());
                                cwFinanceInvoiceBase.setProgramName(reportData.getProjectName());
                                cwFinanceInvoiceBase.setType("2");
                                cwFinanceInvoiceBase.setContractName(reportData.getContractName());
                                break;
                            }
                        }
                    }else {
                        return "报告号："+cwFinanceImportDTO.getReportNo()+" 不是当前登录人所创建,请重新填写";
                    }
                }
                //开票金额
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getBaseAccount())){
                    cwFinanceInvoice.setAccount(cwFinanceImportDTO.getBaseAccount());
                    cwFinanceInvoiceBase.setAccount(cwFinanceImportDTO.getBaseAccount());
                }

                //发票类型
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getType())){
                    for (String key : invoiceTypeValueDTOs.keySet()) {
                        if(cwFinanceImportDTO.getType().equals(key)){
                            cwFinanceInvoice.setType(String.valueOf(invoiceTypeValueDTOs.get(key)));
                            break;
                        }
                    }
                }
                //开票类型
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getBillingType())){
                    for (String key : invoiceBillingTypeValueDTOs.keySet()) {
                        if(cwFinanceImportDTO.getBillingType().equals(key)){
                            cwFinanceInvoice.setBillingType(String.valueOf(invoiceBillingTypeValueDTOs.get(key)));
                            break;
                        }
                    }
                }
                //实际开票单位
                if ("企业开票".equals(cwFinanceImportDTO.getBillingType())){
                    for (CwWorkClientBaseDTO cwWorkClientBaseDTO : cwWorkClientBaseDTOList) {
                        if (cwWorkClientBaseDTO.getName().equals(cwFinanceImportDTO.getBillingWorkplaceReal())){
                            cwFinanceInvoice.setBillingWorkplaceRealId(cwWorkClientBaseDTO.getId());
                            cwFinanceInvoice.setBillingWorkplaceReal(cwWorkClientBaseDTO.getName());
                            if (StringUtils.isNotBlank(cwFinanceImportDTO.getTaxpayerIdentificationNo())){
                                cwFinanceInvoice.setTaxpayerIdentificationNo(cwFinanceImportDTO.getTaxpayerIdentificationNo());
                            }else {
                                cwFinanceInvoice.setTaxpayerIdentificationNo(cwWorkClientBaseDTO.getUscCode());
                            }
                            if (StringUtils.isNotBlank(cwFinanceImportDTO.getAddress())){
                                cwFinanceInvoice.setAddress(cwFinanceImportDTO.getAddress());
                            }else {
                                cwFinanceInvoice.setAddress(cwWorkClientBaseDTO.getAddress());
                            }
                            if (StringUtils.isNotBlank(cwFinanceImportDTO.getTelPhone())){
                                cwFinanceInvoice.setTelPhone(cwFinanceImportDTO.getTelPhone());
                            }else {
                                cwFinanceInvoice.setTelPhone(cwWorkClientBaseDTO.getMobile());
                            }

                            List<CwWorkClientBillingDTO> billing = cwWorkClientBaseMapper.getBilling(cwWorkClientBaseDTO.getId());

                            if (StringUtils.isNotBlank(cwFinanceImportDTO.getOpenBank())){
                                if (CollectionUtils.isNotEmpty(billing)){
                                    for (CwWorkClientBillingDTO cwWorkClientBillingDTO : billing) {
                                        if (cwWorkClientBillingDTO.getAccountHolder().equals(cwFinanceImportDTO.getOpenBank())){
                                            cwFinanceInvoice.setOpenBank(cwWorkClientBillingDTO.getAccountHolder());
                                            if (StringUtils.isNotBlank(cwFinanceImportDTO.getBankAccount())){
                                                cwFinanceInvoice.setBankAccount(cwFinanceImportDTO.getBankAccount());
                                            }else {
                                                cwFinanceInvoice.setBankAccount(cwWorkClientBillingDTO.getAccount());
                                            }
                                            if (StringUtils.isBlank(cwFinanceInvoice.getTelPhone())){
                                                cwFinanceInvoice.setTelPhone(cwWorkClientBillingDTO.getPhone());
                                            }

                                            break;
                                        }
                                    }
                                }
                            }else {
                                if (CollectionUtils.isNotEmpty(billing)){
                                    cwFinanceInvoice.setOpenBank(billing.get(0).getAccountHolder());
                                    cwFinanceInvoice.setBankAccount(billing.get(0).getAccount());
                                    cwFinanceInvoice.setTelPhone(billing.get(0).getPhone());
                                }

                            }

                            break;
                        }
                    }
                }
                if ("个人开票".equals(cwFinanceImportDTO.getBillingType())){
                    cwFinanceInvoice.setName(cwFinanceImportDTO.getBillingWorkplaceReal());
                    cwFinanceInvoice.setTaxpayerIdentificationNo(cwFinanceImportDTO.getTaxpayerIdentificationNo());
                    cwFinanceInvoice.setAddress(cwFinanceImportDTO.getAddress());
                    cwFinanceInvoice.setTelPhone(cwFinanceImportDTO.getTelPhone());
                    cwFinanceInvoice.setOpenBank(cwFinanceImportDTO.getOpenBank());
                    cwFinanceInvoice.setBankAccount(cwFinanceImportDTO.getBankAccount());
                }
                //开票内容
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getBillingContent())){
                    for (String key : invoiceBillingContentValueDTOs.keySet()) {
                        if(cwFinanceImportDTO.getBillingContent().equals(key)){
                            cwFinanceInvoice.setBillingContent(String.valueOf(invoiceBillingContentValueDTOs.get(key)));
                            break;
                        }
                    }
                }
                //开票内容要求
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getBillingContentTerms())){
                    cwFinanceInvoice.setBillingContentTerms(cwFinanceImportDTO.getBillingContentTerms());
                }

                //关联红字发票编号
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getRedInvoiceRelevancyNumber())){
                    for (CwFinanceInvoiceDTO cwFinanceInvoiceDTO : invoiceDTOList) {
                        if (cwFinanceInvoiceDTO.getNo().equals(cwFinanceImportDTO.getRedInvoiceRelevancyNumber().toUpperCase())){
                            cwFinanceInvoice.setRedInvoiceFlag(1);
                            cwFinanceInvoice.setRedInvoiceRelevancyNumber(cwFinanceInvoiceDTO.getNo());
                            cwFinanceInvoice.setRedInvoiceRelevancyId(cwFinanceInvoiceDTO.getId());
                            break;
                        }
                    }
                }else {
                    cwFinanceInvoice.setRedInvoiceFlag(0);
                }
                //邮箱
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getActualDrawerEmailAddress())){
                    cwFinanceInvoice.setActualDrawerEmailAddress(cwFinanceImportDTO.getActualDrawerEmailAddress());
                }
                //实际开票人
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getBillingPeopleRealName())){
                    boolean match = allUserInfo.stream().anyMatch(user -> user.getName().equals(cwFinanceImportDTO.getBillingPeopleRealName()));
                    if (match){
                        Optional<String> matchedUser = allUserInfo.stream()
                                .filter(dto -> dto.getName().equals(cwFinanceImportDTO.getBillingPeopleRealName()))
                                .map(UserDTO::getId)
                                .findFirst();
                        cwFinanceInvoice.setBillingPeopleReal(matchedUser.get());
                    }else {
                        return "实际开票人："+cwFinanceImportDTO.getBillingPeopleRealName()+" 名称错误,请重新填写";
                    }
                }else {
                    cwFinanceInvoice.setBillingPeopleReal(userDTO.getId());
                }
                //对账人
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getReconciliationPeopleName())){
                    boolean match = allUserInfo.stream().anyMatch(user -> user.getName().equals(cwFinanceImportDTO.getReconciliationPeopleName()));
                    if (match){
                        Optional<String> matchedUser = allUserInfo.stream()
                                .filter(dto -> dto.getName().equals(cwFinanceImportDTO.getReconciliationPeopleName()))
                                .map(UserDTO::getId)
                                .findFirst();
                        cwFinanceInvoice.setReconciliationPeople(matchedUser.get());
                    }else {
                        return "对账人："+cwFinanceImportDTO.getReconciliationPeopleName()+" 名称错误,请重新填写";
                    }
                }else {
                    cwFinanceInvoice.setReconciliationPeople(userDTO.getId());
                }
                //对账地区
                if (StringUtils.isNotBlank(cwFinanceImportDTO.getReconciliationArea())){
                    String lastLevelCode = findLastLevelCode(areaDTOList, cwFinanceImportDTO.getReconciliationArea());
                    if (StringUtils.isNotBlank(lastLevelCode)){
                        cwFinanceInvoice.setReconciliationArea(lastLevelCode);
                    }else {
                        return "对账地区："+cwFinanceImportDTO.getReconciliationArea()+" 不正确，请重新填写";
                    }

                }
                //收款类型
                cwFinanceInvoice.setReceivablesType("1");
                cwFinanceInvoice.setIsMultiple("0");
                cwFinanceInvoice.setStatus("1");
                cwFinanceInvoice.setCreateById(userDTO.getId());
                cwFinanceInvoice.setCreateTime(new Date());
                cwFinanceInvoice.setUpdateById(userDTO.getId());
                cwFinanceInvoice.setUpdateTime(new Date());
                cwFinanceInvoice.setTenantId(userDTO.getTenantDTO().getId());
                cwFinanceInvoice.setDelFlag(0);
                cwFinanceInvoice.setInvalidStatus("0");
                cwFinanceInvoice.setReceivablesStatus("0");

                invoiceArrayList.add(cwFinanceInvoice);

                cwFinanceInvoiceBase.setCreateById(userDTO.getId());
                cwFinanceInvoiceBase.setCreateTime(new Date());
                cwFinanceInvoiceBase.setUpdateById(userDTO.getId());
                cwFinanceInvoiceBase.setUpdateTime(new Date());
                cwFinanceInvoiceBase.setTenantId(userDTO.getTenantDTO().getId());
                cwFinanceInvoiceBase.setDelFlag(0);
                baseArrayList.add(cwFinanceInvoiceBase);

            }

        }

        //批量保存
        if (CollectionUtils.isNotEmpty(invoiceArrayList) && CollectionUtils.isNotEmpty(baseArrayList) ){
            // 每次最多插入 100 条数据
            int batchSize = 100;
            int totalSize = invoiceArrayList.size();
            int totalSize1 = baseArrayList.size();

            // 按批次处理插入
            for (int i = 0; i < totalSize; i += batchSize) {
                // 计算当前批次的结束位置
                int endIndex = Math.min(i + batchSize, totalSize);
                // 获取当前批次的子列表
                List<CwFinanceInvoice> batchList = invoiceArrayList.subList(i, endIndex);

                // 执行批量插入
                cwFinanceInvoiceMapper.insertBatch(batchList);
            }

            for (int i = 0; i < totalSize1; i += batchSize) {
                // 计算当前批次的结束位置
                int endIndex = Math.min(i + batchSize, totalSize1);
                // 获取当前批次的子列表
                List<CwFinanceInvoiceBase> batchList = baseArrayList.subList(i, endIndex);

                // 执行批量插入
                cwFinanceInvoiceBaseMapper.insertBatch(batchList);
            }


        }

    return "";
    }

    public String findLastLevelCode(List<AreaDTO> areaDTOList, String reconciliationArea) {
        // 按 "-" 拆分层级
        String[] split = reconciliationArea.split("-");


        List<AreaDTO> currentLevelList = areaDTOList;// 当前层级的 AreaDTO 列表
        AreaDTO matchedArea = null; // 记录最后匹配的 AreaDTO

        for (String name : split) {
            // 在当前层级查找匹配的 name
            Optional<AreaDTO> found = currentLevelList.stream()
                    .filter(area -> area.getName().equals(name))
                    .findFirst();

            if (found.isPresent()) {
                matchedArea = found.get(); // 记录匹配的节点
                currentLevelList = matchedArea.getChildren(); // 进入子节点列表
            } else {
                return null; // 如果找不到，直接返回 null
            }
        }
        return matchedArea != null ? matchedArea.getCode() : null;
    }

    public static List<AreaDTO> buildTree(List<AreaDTO> areaList) {
        // 创建一个 Map 来保存 id 到 AreaDTO 的映射
        Map<String, AreaDTO> areaMap = areaList.stream()
                .collect(Collectors.toMap(AreaDTO::getId, area -> area));

        // 用来存储树形结构的根节点
        List<AreaDTO> rootList = new ArrayList<>();

        for (AreaDTO area : areaList) {
            String parentId = area.getParent().getId();
            if (parentId.equals("0") || StringUtils.isBlank(parentId)) {
                // 如果 parentId 为 null 或 0，说明是根节点
                rootList.add(area);
            } else {
                // 否则，把它添加到父节点的 children 列表中
                AreaDTO parentArea = areaMap.get(parentId);
                if (parentArea != null) {
                    parentArea.getChildren().add(area);
                }
            }
        }
        return rootList;
    }

    /**
     * 根据当前登录人的公司查询对应的人员信息
     * @param userDTO
     * @return
     */
    private List<UserDTO> findUserByTenantId(UserDTO userDTO) {

        //查询综合管理公司用户信息
        List<UserDTO> userList1=cwFinanceInvoiceMapper.findZhglgsUserList();
        //获取当前登录人所属公司的人员
        List<UserDTO> dtoList=cwFinanceInvoiceMapper.findDtoList(userDTO.getTenantDTO().getId());

        ArrayList<UserDTO> treeUserDtos = new ArrayList<>();
        treeUserDtos.addAll(userList1);
        treeUserDtos.addAll(dtoList);

        String zsOfficeName = "";
        if (userDTO != null && userDTO.getOfficeDTO() != null && StringUtils.isNotBlank(userDTO.getOfficeDTO().getName())){
            if (userDTO.getOfficeDTO().getName().contains("审计一部")){
                //获取中审公司的张宁部门
                zsOfficeName = "张宁部门";
            }else if (userDTO.getOfficeDTO().getName().contains("审计二部") ){
                //获取中审公司的孙文宝部门
                zsOfficeName = "孙文宝部门";
            }
        }

        //查询中审公司用户信息
        if (null != userDTO && null != userDTO.getOfficeDTO() && StringUtils.isNotBlank(userDTO.getOfficeDTO().getName()) && (userDTO.getOfficeDTO().getName().contains("审计一部") || userDTO.getOfficeDTO().getName().contains("审计二部"))){
            List<UserDTO> zsUserList=cwFinanceInvoiceMapper.findZsUserList(zsOfficeName);
            treeUserDtos.addAll(zsUserList);
        }

        if(null != userDTO && null != userDTO.getOfficeDTO() && StringUtils.isNotBlank(userDTO.getOfficeDTO().getId()) && ("1826176524081065985".equals(userDTO.getOfficeDTO().getId()) || "1826176609011527681".equals(userDTO.getOfficeDTO().getId()))) {
            //查询会计公司用户信息
            List<UserDTO> userList2 = cwFinanceInvoiceMapper.findCwglgsUserList();
            treeUserDtos.addAll(userList2);
        }

        ArrayList<UserDTO> treeUsers = new ArrayList<>();
        //如果当前登录人角色是多公司报销则查询全部公司
        if (CollectionUtil.isNotEmpty(userDTO.getRoleDTOList())){
            for (RoleDTO roleDTO : userDTO.getRoleDTOList()) {
                RoleDTO roleDTOById = SpringUtil.getBean(IRoleApi.class).getRoleDTOById(roleDTO.getId());
                if (null != roleDTOById && (roleDTOById.getEnName().equals("dgsbx")|| roleDTOById.getEnName().equals("zjbry"))){
                    List<UserDTO> users=cwFinanceInvoiceMapper.finduserAllList();
                    treeUsers.addAll(users);
                }
            }
        }
        //管理员则查询全部人员
        if (userDTO.isAdmin()){
            List<UserDTO> users=cwFinanceInvoiceMapper.finduserAllList();
            treeUsers.addAll(users);
        }

        treeUserDtos.addAll(treeUsers);



        //去重
        List<UserDTO> newList = treeUserDtos.stream().filter(new HashSet<>()::add)
                .collect(Collectors.toList());

        return newList;


    }


}
