package cn.ezhizao.project.business.upgrade.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;

import cn.ezhizao.common.exception.ServiceException;
import cn.ezhizao.common.utils.bean.BeanUtils;
import cn.ezhizao.common.utils.uuid.SnowflakeIdWorker;
import cn.ezhizao.project.business.channel.domain.BizChannel;
import cn.ezhizao.project.business.channel.service.IBizChannelService;
import cn.ezhizao.project.business.company.domain.BizCompany;
import cn.ezhizao.project.business.company.service.IBizCompanyService;
import cn.ezhizao.project.business.order.domain.BizArchiveInput;
import cn.ezhizao.project.business.order.domain.BizArchiveInputDetail;
import cn.ezhizao.project.business.order.domain.OrderExcelImportLoopGroupModel;
import cn.ezhizao.project.business.order.domain.OrderExcelImportLoopModel;
import cn.ezhizao.project.business.order.domain.vo.InputVo;
import cn.ezhizao.project.business.order.service.IBizArchiveInputDetailService;
import cn.ezhizao.project.business.order.service.IBizArchiveInputService;
import cn.ezhizao.project.business.settings.domain.BizSource;
import cn.ezhizao.project.business.settings.service.IBizSourceService;
import cn.ezhizao.project.business.upgrade.domain.*;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrder;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrderDetail;
import cn.ezhizao.project.business.workOrder.service.IBizWorkOrderDetailService;
import cn.ezhizao.project.business.workOrder.service.IBizWorkOrderService;
import cn.ezhizao.project.system.domain.SysUser;
import cn.ezhizao.project.system.service.ISysUserService;
import cn.ezhizao.project.business.upgrade.service.IBizArchiveInputDetailUpdateService;
import cn.ezhizao.project.business.upgrade.service.IBizWorkOrderDetailUpdateService;
import cn.ezhizao.project.business.upgrade.service.IBizWorkOrderUpdateService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import cn.ezhizao.project.business.upgrade.mapper.BizArchiveInputTempMapper;
import cn.ezhizao.project.business.upgrade.service.IBizArchiveInputTempService;

/**
 * 档案入库Service业务层处理
 *
 * @author ruoyi
 * @date 2024-10-12
 */
@Service
public class BizArchiveInputTempServiceImpl extends ServiceImpl<BizArchiveInputTempMapper, BizArchiveInputUpdate> implements IBizArchiveInputTempService {
    @Resource
    private IBizArchiveInputDetailService bizArchiveInputDetailService;
    @Resource
    private IBizArchiveInputService bizArchiveInputService;
    @Resource
    private IBizArchiveInputDetailUpdateService bizArchiveInputDetailUpdateService;
    @Resource
    private BizArchiveInputTempMapper bizArchiveInputTempMapper;
    @Resource
    private IBizCompanyService companyService;
    @Resource
    private IBizSourceService bizSourceService;
    @Resource
    SnowflakeIdWorker snowflakeIdWorker;
    @Resource
    private ISysUserService userService;
    @Resource
    private IBizChannelService channelService;
    @Resource
    private IBizWorkOrderService workOrderService;
    @Resource
    private IBizWorkOrderUpdateService workOrderUpdateService;
    @Resource
    private IBizWorkOrderDetailService workOrderDetailService;
    @Resource
    private IBizWorkOrderDetailUpdateService workOrderDetailUpdateService;
    StringBuilder successMsg = new StringBuilder();
    StringBuilder failureMsg = new StringBuilder();
    int successNum = 0;
    int failureNum = 0;

    /**
     * 查询档案入库列表
     *
     * @param bizArchiveInputUpdate 档案入库
     * @return 档案入库
     */
    @Override
    public List<BizArchiveInputUpdate> getList(BizArchiveInputUpdate bizArchiveInputUpdate) {
        return bizArchiveInputTempMapper.getList(bizArchiveInputUpdate);
    }

    /**
     * 物理删除
     *
     * @param bizArchiveInputUpdate
     * @return 删除结果
     */
    @Override
    public int physicalDelete(BizArchiveInputUpdate bizArchiveInputUpdate) {
        return bizArchiveInputTempMapper.physicalDelete(bizArchiveInputUpdate);
    }

    /**
     * 创建合同
     */
    private List<BizArchiveInputUpdate> createImportArchiveInput(List<OrderExcelImportLoopModel> orderList,
                                                                 long tenantId) {

        List<String> contractNo = orderList.stream().map(m -> m.getContractNo()).collect(Collectors.toList());
        //合同号不能重复
        Map<String, Long> nameCountMap = contractNo.stream()
                .collect(Collectors.groupingBy(name -> name, Collectors.counting()));

        //最后需要保存的合同表list
        List<BizArchiveInputUpdate> archiveInputs = new ArrayList<>();
        //最后需要保存的合同详情表list
        List<BizArchiveInputDetailUpdate> inputDetailList = new ArrayList<>();
        successNum = 0;
        failureNum = 0;

        successMsg = new StringBuilder();
        failureMsg = new StringBuilder();
        List<String> contNOs = this.query().eq("service_type", 1).eq("tenant_id", tenantId).list().stream().map(m -> m.getContractNo()).collect(Collectors.toList());
        BizSource sourceCondition = new BizSource();
        sourceCondition.setTenantId(tenantId);
        List<BizSource> sources = bizSourceService.getList(sourceCondition);
        List<BizCompany> companies = companyService.query().eq("tenant_id", tenantId).list();

        for (OrderExcelImportLoopModel loopModel : orderList) {

            BizCompany company = companies.stream().filter(v -> v.getName().equals(loopModel.getCompanyName())).findFirst().orElse(null);
            if (company == null) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、客户 ").append(loopModel.getCompanyName()).append(" 不存在");
                continue;
            }

            BizArchiveInputUpdate archiveInput = new BizArchiveInputUpdate();
            //创建合同和合同明细
            if (loopModel.getDiscountAmount() == null) {
                loopModel.setDiscountAmount(BigDecimal.ZERO);
            }
            archiveInput.setCompanyId(company.getId());
            archiveInput.setArchiveCode(String.valueOf(snowflakeIdWorker.nextId()));
            archiveInput.setAmount(loopModel.getAmount());
            archiveInput.setDiscountAmount(loopModel.getDiscountAmount());
            archiveInput.setTrueAmount(loopModel.getTrueAmount());
            archiveInput.setFormDate(loopModel.getFormDate());
            archiveInput.setContractNo(loopModel.getContractNo());
            SysUser user = userService.selectUserByUserNameAndTenantId(loopModel.getSignerName(), String.valueOf(tenantId));
//            if (user == null) {
//                failureNum++;
//                failureMsg.append("<br/>").append(failureNum).append("、员工 ").append(item.getSignerName()).append(" 不存在");
//                continue;
//            }
            // 判断下订单总价单价是否和录入相符
            // 假设 amount - discountAmount != trueAmount 跳过该订单
            if (loopModel.getAmount() == null) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(failureNum).append("服务金额不能为空");
                continue;
            }
            if (loopModel.getTrueAmount() == null) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(failureNum).append("实收金额不能为空");
                continue;
            }
            if (loopModel.getAmount().subtract(loopModel.getDiscountAmount() == null ? BigDecimal.ZERO : loopModel.getDiscountAmount()).compareTo(loopModel.getTrueAmount()) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(" 实际付款金额出错");
                continue;
            }
            if (loopModel.getTrueAmount().compareTo(BigDecimal.ZERO) < 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(" 实际付款金额小于0");
                continue;
            }
            // 假设子表金额不等于订单总金额
            BigDecimal keepAccount = loopModel.getKeepAccountAmount() == null ? BigDecimal.ZERO : loopModel.getKeepAccountAmount();
            BigDecimal security = loopModel.getSocialSecurityAmount() == null ? BigDecimal.ZERO : loopModel.getSocialSecurityAmount();
            BigDecimal housingFund = loopModel.getHousingFundAmount() == null ? BigDecimal.ZERO : loopModel.getHousingFundAmount();
            BigDecimal returnTax = loopModel.getReturnTaxAmount() == null ? BigDecimal.ZERO : loopModel.getReturnTaxAmount();
            //优惠
            BigDecimal keepFreeAccount = loopModel.getKeepAccountFreeAmount() == null ? BigDecimal.ZERO : loopModel.getKeepAccountFreeAmount();
            BigDecimal securityFree = loopModel.getSocialSecurityFreeAmount() == null ? BigDecimal.ZERO : loopModel.getSocialSecurityFreeAmount();
            BigDecimal housingFundFree = loopModel.getHousingFundFreeAmount() == null ? BigDecimal.ZERO : loopModel.getHousingFundFreeAmount();
            BigDecimal returnTaxFree = loopModel.getReturnTaxFreeAmount() == null ? BigDecimal.ZERO : loopModel.getReturnTaxFreeAmount();
//            if (item.getAmount().compareTo(keepAccount.add(security).add(housingFund).add(returnTax)) != 0) {
            //update 6/12 实收金额 和各项金额比较 ，各项金额填写时应该为 单价*月-优惠金额
            if (loopModel.getTrueAmount().compareTo(keepAccount.add(security).add(housingFund).add(returnTax)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(" 实收金额不等于实际任务金额的和。");
                continue;
            }

            if (loopModel.getDiscountAmount().compareTo(keepFreeAccount.add(securityFree).add(housingFundFree).add(returnTaxFree)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append("优惠金额不等于任务优惠金额的和。");
                continue;
            }
            BigDecimal keepAccountPrice = loopModel.getKeepAccountPrice() == null ? BigDecimal.ZERO : loopModel.getKeepAccountPrice();
            BigDecimal securityPrice = loopModel.getSocialSecurityPrice() == null ? BigDecimal.ZERO : loopModel.getSocialSecurityPrice();
            BigDecimal housingFundPrice = loopModel.getHousingFundPrice() == null ? BigDecimal.ZERO : loopModel.getHousingFundPrice();
            BigDecimal returnTaxPrice = loopModel.getReturnTaxPrice() == null ? BigDecimal.ZERO : loopModel.getReturnTaxPrice();
            BigDecimal keepAccountMonth = loopModel.getKeepAccountMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getKeepAccountMonth());
            BigDecimal securityMonth = loopModel.getSocialSecurityMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getSocialSecurityMonth());
            BigDecimal housingFundMonth = loopModel.getHousingFundMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getHousingFundMonth());
            BigDecimal returnTaxMonth = loopModel.getReturnTaxMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getReturnTaxMonth());
            if (loopModel.getKeepAccountStartMonth() != null && loopModel.getKeepAccountEndMonth() != null) {
                Calendar startCalendar = Calendar.getInstance();
                startCalendar.setTime(loopModel.getKeepAccountStartMonth());
                Calendar endCalendar = Calendar.getInstance();
                endCalendar.setTime(loopModel.getKeepAccountEndMonth());
                // 计算年份和月份的差异
                int yearDiff = endCalendar.get(Calendar.YEAR) - startCalendar.get(Calendar.YEAR);
                int monthDiff = endCalendar.get(Calendar.MONTH) - startCalendar.get(Calendar.MONTH);
                // 总的月份差异
                int totalMonthsBetween = yearDiff * 12 + monthDiff + 1;
                BigDecimal keeFreeMonth = loopModel.getKeepAccountFreeMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getKeepAccountFreeMonth());
                if (totalMonthsBetween != keepAccountMonth.add(keeFreeMonth).intValue()) {
                    failureNum++;
                    failureMsg.append("<br/>").append(failureNum).append(company.getName() + "的代理记账服务的服务月数+赠送月数跟结束月-开始月的时间不等，请检查数据");
                    continue;
                }

            }
            if (loopModel.getSocialSecurityStartMonth() != null && loopModel.getSocialSecurityEndMonth() != null) {
                Calendar startCalendar2 = Calendar.getInstance();
                startCalendar2.setTime(loopModel.getSocialSecurityStartMonth());
                Calendar endCalendar2 = Calendar.getInstance();
                endCalendar2.setTime(loopModel.getSocialSecurityEndMonth());
                // 计算年份和月份的差异
                int yearDiff2 = endCalendar2.get(Calendar.YEAR) - startCalendar2.get(Calendar.YEAR);
                int monthDiff2 = endCalendar2.get(Calendar.MONTH) - startCalendar2.get(Calendar.MONTH);
                // 总的月份差异
                int totalMonthsBetween2 = yearDiff2 * 12 + monthDiff2 + 1;
                BigDecimal socialSecurityMonth = loopModel.getSocialSecurityFreeMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getSocialSecurityFreeMonth());
                if (totalMonthsBetween2 != securityMonth.add(socialSecurityMonth).intValue()) {
                    failureNum++;

                    failureMsg.append("<br/>").append(failureNum).append(company.getName() + "的社保代缴服务的服务月数+赠送月数跟结束月-开始月的时间不等，请检查数据");
                    continue;
                }
            }


            if (loopModel.getHousingFundStartMonth() != null && loopModel.getHousingFundEndMonth() != null) {
                Calendar startCalendar3 = Calendar.getInstance();
                startCalendar3.setTime(loopModel.getHousingFundStartMonth());
                Calendar endCalendar3 = Calendar.getInstance();
                endCalendar3.setTime(loopModel.getHousingFundEndMonth());
                // 计算年份和月份的差异
                int yearDiff3 = endCalendar3.get(Calendar.YEAR) - startCalendar3.get(Calendar.YEAR);
                int monthDiff3 = endCalendar3.get(Calendar.MONTH) - startCalendar3.get(Calendar.MONTH);
                // 总的月份差异
                int totalMonthsBetween3 = yearDiff3 * 12 + monthDiff3 + 1;
                BigDecimal housingFundMonths = loopModel.getHousingFundFreeMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getHousingFundFreeMonth());
                if (totalMonthsBetween3 != housingFundMonth.add(housingFundMonths).intValue()) {
                    failureNum++;
                    failureMsg.append("<br/>").append(failureNum).append(company.getName() + "的公积金服务的服务月数+赠送月数跟结束月-开始月的时间不等，请检查数据");
                    continue;
                }
            }

            if (loopModel.getReturnTaxStartMonth() != null && loopModel.getReturnTaxEndMonth() != null) {
                Calendar startCalendar4 = Calendar.getInstance();
                startCalendar4.setTime(loopModel.getReturnTaxStartMonth());
                Calendar endCalendar4 = Calendar.getInstance();
                endCalendar4.setTime(loopModel.getReturnTaxEndMonth());
                // 计算年份和月份的差异
                int yearDiff4 = endCalendar4.get(Calendar.YEAR) - startCalendar4.get(Calendar.YEAR);
                int monthDiff4 = endCalendar4.get(Calendar.MONTH) - startCalendar4.get(Calendar.MONTH);
                // 总的月份差异
                int totalMonthsBetween4 = yearDiff4 * 12 + monthDiff4 + 1;
                BigDecimal returnTaxFreeMonth = loopModel.getReturnTaxFreeMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getReturnTaxFreeMonth());
                if (totalMonthsBetween4 != returnTaxMonth.add(returnTaxFreeMonth).intValue()) {
                    failureNum++;
                    failureMsg.append("<br/>").append(failureNum).append(company.getName() + "的返税申报服务的服务月数+赠送月数跟结束月-开始月的时间不等，请检查数据");
                    continue;
                }
            }

            if (nameCountMap.get(loopModel.getContractNo()) > 1L) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("导入的合同编号 ").append(loopModel.getContractNo()).append("不能重复");
                continue;
            }
            if (contNOs.contains(loopModel.getContractNo())) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("合同编号 ").append(loopModel.getContractNo()).append("已存在不能重复导入");
                continue;
            }
            //update 6/12 加单条优惠才为当月总金额
            if (keepAccount.add(keepFreeAccount).compareTo(keepAccountPrice.multiply(keepAccountMonth)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(" 记账总金额计算值与记账单价不符。");
                continue;
            }
            if (security.add(securityFree).compareTo(securityPrice.multiply(securityMonth)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(" 社保总金额计算值与社保单价不符。");
                continue;
            }
            if (housingFund.add(housingFundFree).compareTo(housingFundPrice.multiply(housingFundMonth)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(" 公积金总金额计算值与公积金单价不符。");
                continue;
            }
            if (returnTax.add(returnTaxFree).compareTo(returnTaxMonth.multiply(returnTaxPrice)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(" 返税总金额计算值与返税单价不符。");
                continue;
            }
            archiveInput.setSignerId(user != null ? user.getUserId() : null);
            archiveInput.setContractType("新签".equals(loopModel.getOrderType()) ? 0 : "续签".equals(loopModel.getOrderType()) ? 1 : 3);
            archiveInput.setServiceType(1);
            archiveInput.setTenantId(tenantId);
            archiveInput.setId(snowflakeIdWorker.nextId());
            archiveInput.setStatus(1);
            archiveInput.setVerifyStatus(1);
            archiveInput.setRemark(loopModel.getRemark());
            String sourceName = loopModel.getSourceName();
            String sourceCategory = loopModel.getSourceCategoryName();
            BizSource source = sources.stream().filter(v -> v.getTitle().equals(sourceCategory)).findFirst().orElse(null);
            if (source != null) {
                archiveInput.setSourceCategoryId(source.getId());
                switch (source.getReferrerDataSource()) {
                    case "company":
                        QueryWrapper<BizCompany> companyWrapper = new QueryWrapper<>();
                        companyWrapper.eq("name", sourceName);
                        BizCompany sourceCompany = companyService.getOne(companyWrapper);
                        archiveInput.setSourceId(sourceCompany.getId());
                        break;
                    case "employee":
                        SysUser sourceUser = userService.selectUserByUserName(sourceName);
                        archiveInput.setSourceId(sourceUser != null ? sourceUser.getId() : null);
                        break;
                    case "channel":
                        QueryWrapper<BizChannel> channelWrapper = new QueryWrapper<>();
                        channelWrapper.eq("name", sourceName);
                        BizChannel sourceChannel = channelService.getOne(channelWrapper);
                        archiveInput.setSourceId(sourceChannel.getId());
                        break;
                    default:
                        break;
                }
            }
            archiveInputs.add(archiveInput);

            if ("是".equals(loopModel.getKeepAccount())) {
                BizArchiveInputDetailUpdate detail = new BizArchiveInputDetailUpdate();
                detail.setTaskTypeId(1L);
                detail.setAmount(loopModel.getKeepAccountAmount());
                //update 6/12
                detail.setDiscountAmount(loopModel.getKeepAccountFreeAmount());
                detail.setPrice(loopModel.getKeepAccountPrice());
                detail.setServiceNum(loopModel.getKeepAccountMonth());
                detail.setFreeNum(loopModel.getKeepAccountFreeMonth());
                detail.setContractId(archiveInput.getId());
                detail.setCompanyId(archiveInput.getCompanyId());
                detail.setStartMonth(loopModel.getKeepAccountStartMonth());
                detail.setEndMonth(loopModel.getKeepAccountEndMonth());
                detail.setId(snowflakeIdWorker.nextId());
                detail.setTenantId(tenantId);
                inputDetailList.add(detail);
            }
            if ("是".equals(loopModel.getSocialSecurity())) {
                BizArchiveInputDetailUpdate detail = new BizArchiveInputDetailUpdate();
                detail.setTaskTypeId(2L);
                detail.setAmount(loopModel.getSocialSecurityAmount());
                detail.setDiscountAmount(loopModel.getSocialSecurityFreeAmount());
                detail.setPrice(loopModel.getSocialSecurityPrice());
                detail.setServiceNum(loopModel.getSocialSecurityMonth());
                detail.setFreeNum(loopModel.getSocialSecurityFreeMonth());
                detail.setContractId(archiveInput.getId());
                detail.setCompanyId(archiveInput.getCompanyId());
                detail.setStartMonth(loopModel.getSocialSecurityStartMonth());
                detail.setEndMonth(loopModel.getSocialSecurityEndMonth());
                detail.setId(snowflakeIdWorker.nextId());
                detail.setTenantId(tenantId);
                inputDetailList.add(detail);
            }
            if ("是".equals(loopModel.getHousingFund())) {
                BizArchiveInputDetailUpdate detail = new BizArchiveInputDetailUpdate();
                detail.setTaskTypeId(3L);
                detail.setAmount(loopModel.getHousingFundAmount());
                detail.setPrice(loopModel.getHousingFundPrice());
                detail.setDiscountAmount(loopModel.getHousingFundFreeAmount());
                detail.setServiceNum(loopModel.getHousingFundMonth());
                detail.setFreeNum(loopModel.getHousingFundFreeMonth());
                detail.setContractId(archiveInput.getId());
                detail.setCompanyId(archiveInput.getCompanyId());
                detail.setStartMonth(loopModel.getHousingFundStartMonth());
                detail.setEndMonth(loopModel.getHousingFundEndMonth());
                detail.setId(snowflakeIdWorker.nextId());
                detail.setTenantId(tenantId);
                inputDetailList.add(detail);
            }
            if ("是".equals(loopModel.getReturnTax())) {
                BizArchiveInputDetailUpdate detail = new BizArchiveInputDetailUpdate();
                detail.setTaskTypeId(4L);
                detail.setAmount(loopModel.getReturnTaxAmount());
                detail.setDiscountAmount(loopModel.getReturnTaxFreeAmount());
                detail.setPrice(loopModel.getReturnTaxPrice());
                detail.setServiceNum(loopModel.getReturnTaxMonth());
                detail.setFreeNum(loopModel.getReturnTaxFreeMonth());
                detail.setContractId(archiveInput.getId());
                detail.setCompanyId(archiveInput.getCompanyId());
                detail.setStartMonth(loopModel.getReturnTaxStartMonth());
                detail.setEndMonth(loopModel.getReturnTaxEndMonth());
                detail.setId(snowflakeIdWorker.nextId());
                detail.setTenantId(tenantId);
                inputDetailList.add(detail);
            }

            archiveInput.setDetails(inputDetailList);

            successNum++;
            successMsg.append("<br/>").append(successNum).append("、订单 ").append(archiveInput.getContractNo()).append(" 导入成功");
        }

        super.saveBatch(archiveInputs);
        bizArchiveInputDetailUpdateService.saveBatch(inputDetailList);

        archiveInputs.stream().forEach(archiveInput -> {
            archiveInput.setDetails(inputDetailList.stream()
                    .filter(detail -> Objects.equals(detail.getContractId(), archiveInput.getId())).collect(Collectors.toList()));
        });
        return archiveInputs;
    }

    @Override
    public String importLoop(List<OrderExcelImportLoopModel> orderList, Long userId, long tenantId) {


        List<BizArchiveInputUpdate> archiveInputList = this.createImportArchiveInput(orderList, tenantId);
        if(archiveInputList.isEmpty()){
            return failureMsg.toString();
        }
        archiveInputList = this.resetOldContract(tenantId, archiveInputList);
        importarchiveinput(tenantId, archiveInputList);
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            return failureMsg.toString();
//            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    private List<BizArchiveInputUpdate> resetOldContract(long tenantId, List<BizArchiveInputUpdate> archiveInputList) {

        List<BizArchiveInputUpdate> resultList = new ArrayList<>(archiveInputList);

        // 重新导入的合同
        Set<Long> reloopContractIdList = new HashSet<>();
        for (BizArchiveInputUpdate inputUpdate : archiveInputList) {
            Long companyId = inputUpdate.getCompanyId();
            List<BizArchiveInputDetailUpdate> inputDetailList = bizArchiveInputDetailUpdateService
                    .lambdaQuery()
                    .eq(BizArchiveInputDetailUpdate::getContractId, inputUpdate.getId())
                    .list();
            List<Long> taskidList = inputDetailList.stream()
                    .map(BizArchiveInputDetailUpdate::getTaskTypeId)
                    .collect(Collectors.toList());

            List<BizArchiveInputDetailUpdate> bizArchiveInputDetailUpdateList= bizArchiveInputDetailUpdateService.lambdaQuery()
                    .eq(BizArchiveInputDetailUpdate::getCompanyId, companyId)
                    .in(BizArchiveInputDetailUpdate::getTaskTypeId, taskidList)
                    .list();
            List<Long> contractIds = bizArchiveInputDetailUpdateList.stream()
                    .map(BizArchiveInputDetailUpdate::getContractId).collect(Collectors.toList());
            reloopContractIdList.addAll(contractIds);
        }

        if (!reloopContractIdList.isEmpty()) {
            //删除工单详细表
            List<BizWorkOrderDetailUpdate> workOrderUpdateList = workOrderDetailUpdateService.lambdaQuery()
                    .in(BizWorkOrderDetailUpdate::getContractId, reloopContractIdList).list();
            if(!workOrderUpdateList.isEmpty()){
                workOrderDetailUpdateService.physicalDelete(workOrderUpdateList);
            }
            //删除工单表
            List<Long> workOrderId = workOrderUpdateList.stream().map(BizWorkOrderDetailUpdate::getWorkOrderId).collect(Collectors.toList());
            if(!workOrderId.isEmpty()){
                workOrderUpdateService.physicalDelete(workOrderId);
            }
            resultList = bizArchiveInputTempMapper.selectBatchIds(reloopContractIdList);
//                    .in(BizArchiveInputUpdate::getId, reloopContractIdList).list();
            //resultList.addAll(reloopContractList);
        }
        return resultList;
    }

    private void importarchiveinput(long tenantId, List<BizArchiveInputUpdate> archiveInputList) {

        List<Long> contractId = archiveInputList.stream().map(BizArchiveInputUpdate::getId).collect(Collectors.toList());
        List<BizArchiveInputDetailUpdate> allInputDetailList = bizArchiveInputDetailUpdateService
                .lambdaQuery()
                .in(BizArchiveInputDetailUpdate::getContractId, contractId)
                .list();
        List<BizArchiveInputDetailUpdate> InputDetailList = allInputDetailList.stream().sorted(Comparator.comparing(BizArchiveInputDetailUpdate::getStartMonth)).collect(Collectors.toList());

        //分组数据
        List<OrderExcelImportLoopGroupModel> groupList = new ArrayList<>();

        for (BizArchiveInputDetailUpdate bizArchiveInputDetailUpdate : InputDetailList) {
            Long companyId = bizArchiveInputDetailUpdate.getCompanyId();
            int index = -1;
            for (int i = 0; i < groupList.size(); i++) {
                //分组 如果
                if (groupList.get(i).getCompanyId().equals(companyId)
                        && groupList.get(i).getTaskTypeId().equals(bizArchiveInputDetailUpdate.getTaskTypeId())
                        && groupList.get(i).isIncludeModel(bizArchiveInputDetailUpdate)) {
                    index = i;
                    break;
                }
            }
            if (index >= 0) {
                groupList.get(index).addModel(bizArchiveInputDetailUpdate);
            } else {
                OrderExcelImportLoopGroupModel groupModel = new OrderExcelImportLoopGroupModel();
                groupModel.setCompanyId(companyId);
                groupModel.setTaskTypeId(bizArchiveInputDetailUpdate.getTaskTypeId());
                groupModel.addModel(bizArchiveInputDetailUpdate);
                groupList.add(groupModel);
            }
        }

        // 同类型分组
        Map<String, List<OrderExcelImportLoopGroupModel>> groupMap = new HashMap<>();
        for (OrderExcelImportLoopGroupModel groupModel : groupList) {
            String key = groupModel.getCompanyId() + "-" + groupModel.getTaskTypeId();
            List<OrderExcelImportLoopGroupModel> subGroupList = groupMap.get(key);
            if (subGroupList == null) {
                subGroupList = new ArrayList<>();
            }
            subGroupList.add(groupModel);
            groupMap.put(key, subGroupList);
        }

        //最后需要保存的工单表list
        List<BizWorkOrderUpdate> workOrderUpdates = new ArrayList<>();
        List<BizWorkOrderDetailUpdate> workOrderDetailUpdates = new ArrayList<>();

        for (List<OrderExcelImportLoopGroupModel> subGroupList : groupMap.values()) {
            // 处理
            for (int i = 0; i < subGroupList.size(); i++) {

                OrderExcelImportLoopGroupModel groupModel = subGroupList.get(i);

                // 如果没查到， 新建
                BizWorkOrder workOrder = null;
                BizWorkOrderUpdate workOrderUpdate = null;
                // 最后一条
                if (i == subGroupList.size() - 1) {
                    List<BizWorkOrder> workOrders = workOrderService.query()
                            .eq("company_id", groupModel.getCompanyId())
                            .eq("task_type_id", groupModel.getTaskTypeId())
                            .eq("is_stop",0)
                            .list(); // 根据company_id + task_type_id + start_month包含在group_start...end
                    if (!workOrders.isEmpty()) {
                        workOrder = workOrders.get(0);
                    }
                }

                if (null != workOrder) {
                    workOrderUpdate = new BizWorkOrderUpdate();
                    BeanUtils.copyProperties(workOrder, workOrderUpdate);
                    workOrderUpdate.setSourceWorkOrderId(workOrder.getId());
                    workOrderUpdate.setIsNew(0);
                } else {
                    workOrderUpdate = new BizWorkOrderUpdate();
                    workOrderUpdate.setTenantId(tenantId);
                    workOrderUpdate.setCompanyId(groupModel.getCompanyId());
                    workOrderUpdate.setTaskTypeId(groupModel.getTaskTypeId());
                    workOrderUpdate.setId(snowflakeIdWorker.nextId());
                    workOrderUpdate.setIsNew(1);
                    workOrderUpdate.setIsStop(0);
                }

                workOrderUpdate.setStartMonth(groupModel.getStartMonth());
                workOrderUpdate.setEndMonth(groupModel.getEndMonth());
                workOrderUpdate.setMonthNum(groupModel.getMonthNum());

                workOrderUpdate.setContractId(groupModel.getModelList().get(0).getContractId());
                workOrderUpdate.setContractDetailId(groupModel.getModelList().get(0).getId());


                workOrderUpdates.add(workOrderUpdate);

                List<BizWorkOrderDetail> existWorkOrderDetailList = new ArrayList<>();
                if (workOrderUpdate.getSourceWorkOrderId() != null) {
                    // 从数据库查找工单明细
                    existWorkOrderDetailList = workOrderDetailService.query()
                            .eq("work_order_id", workOrderUpdate.getId())
                            .list();
                }

                for (int i2 = 0; i2 < groupModel.getModelList().size(); i2++) {

                    BizArchiveInputDetailUpdate inputDetail = groupModel.getModelList().get(i2);

                    // 工单明细
                    BizWorkOrderDetailUpdate workOrderDetailUpdate = new BizWorkOrderDetailUpdate();

                    if (!existWorkOrderDetailList.isEmpty()) {
                        BizWorkOrderDetail workOrderDetail = existWorkOrderDetailList.get(0);
                        BeanUtils.copyProperties(workOrderDetail, workOrderDetailUpdate);
                        workOrderDetailUpdate.setSourceWorkOrderDetailId(workOrderDetail.getId());
                        existWorkOrderDetailList.remove(0);
                    } else {
                        workOrderDetailUpdate = new BizWorkOrderDetailUpdate();
                        workOrderDetailUpdate.setId(snowflakeIdWorker.nextId());
                        workOrderDetailUpdate.setTenantId(tenantId);
                        workOrderDetailUpdate.setCompanyId(groupModel.getCompanyId());
                        workOrderDetailUpdate.setTaskTypeId(groupModel.getTaskTypeId());
                    }

                    workOrderDetailUpdate.setWorkOrderId(workOrderUpdate.getId());
                    workOrderDetailUpdate.setContractDetailId(inputDetail.getId());
                    workOrderDetailUpdate.setContractId(inputDetail.getContractId());
                    workOrderDetailUpdate.setFreeNum(inputDetail.getFreeNum());
                    workOrderDetailUpdate.setServiceNum(inputDetail.getServiceNum());
                    workOrderDetailUpdates.add(workOrderDetailUpdate);
                }

            }



        }
        // 同公司， 同类型 =》 分组
        // 查工单： 0条， 1条
        // 0条 =》 有多少条合同 -》 生成工单
        // 1- 把工单绑定到 start_month 最大的， 有多少条合同 -》 生成工单

        workOrderUpdateService.saveBatch(workOrderUpdates);
        workOrderDetailUpdateService.saveBatch(workOrderDetailUpdates);
    }

    @Override
    public List<BizArchiveInputUpdate> getListByInput(InputVo bizArchiveInput) {
        return bizArchiveInputTempMapper.getListByInput(bizArchiveInput);
    }

    public boolean deleteArchiveInput(Long tenantId, Long inputId) {
        // 找到跟要删除的合同 -> 相同的 company_id和task_type -> 合同明细 -> 合同列表
        // 4个表全部真删除
        // 移除当前删除
        // 如果删除完 isNotEmpty
        Long companyId = 0L;
        BizArchiveInputUpdate inputUpdate = this.query().eq("id", inputId).one();
        companyId = inputUpdate.getCompanyId();
        List<BizArchiveInputDetailUpdate> inputDetailList = bizArchiveInputDetailUpdateService
                .lambdaQuery()
                .eq(BizArchiveInputDetailUpdate::getContractId, inputUpdate.getId())
                .list();


        List<Long> taskidList = inputDetailList.stream()
                .map(BizArchiveInputDetailUpdate::getTaskTypeId)
                .collect(Collectors.toList());

        List<BizArchiveInputDetailUpdate> bizArchiveInputDetailUpdateList= bizArchiveInputDetailUpdateService.lambdaQuery()
                .eq(BizArchiveInputDetailUpdate::getCompanyId, companyId)
                .in(BizArchiveInputDetailUpdate::getTaskTypeId, taskidList)
                .list();
        List<Long> contractIds = bizArchiveInputDetailUpdateList.stream()
                .map(BizArchiveInputDetailUpdate::getContractId).collect(Collectors.toList());

        List<BizArchiveInputUpdate> inputUpdates = this.query()
                .in("id", contractIds)
                .ne("id", inputId)
                .list();
        for(BizArchiveInputUpdate archiveInputUpdate : inputUpdates){
            archiveInputUpdate.setDetails(bizArchiveInputDetailUpdateList.stream()
                    .filter(l->l.getContractId().equals(archiveInputUpdate.getId())).collect(Collectors.toList()));
        }
        //删除合同详细表
        BizArchiveInputDetailUpdate delDetail = new BizArchiveInputDetailUpdate();
        delDetail.setContractId(inputUpdate.getId());
        bizArchiveInputDetailUpdateService.physicalDelete(delDetail);
        //删除合同表
        bizArchiveInputTempMapper.physicalDelete(inputUpdate);
        //删除工单详细表
        List<BizWorkOrderDetailUpdate> workOrderUpdateList = workOrderDetailUpdateService.lambdaQuery()
                .in(BizWorkOrderDetailUpdate::getContractId, contractIds).list();
        workOrderDetailUpdateService.physicalDelete(workOrderUpdateList);
        //删除工单表
        List<Long> workOrderId = workOrderUpdateList.stream().map(BizWorkOrderDetailUpdate::getWorkOrderId).collect(Collectors.toList());
        workOrderUpdateService.physicalDelete(workOrderId);

        //调用保存工单逻辑,删除合同后,原先连续的工单关联的合同id会缺失(并且会把工单和工单详情从表里真删掉),所以在删除之后需要从新调用保存工单逻辑
        if(!inputUpdates.isEmpty()){
            importarchiveinput(tenantId, inputUpdates);
        }
        return true;
    }

    @Override
    public void inputUpgrade(Long tenantId) {
        //在插入要升级的数据时需要删除原表同账套下的合同和详情
        BizArchiveInput del = new BizArchiveInput();
        del.setTenantId(tenantId);
        bizArchiveInputService.physicalDelete(del);
        //这个是详情
        BizArchiveInputDetail del2 = new BizArchiveInputDetail();
        del2.setTenantId(tenantId);
        bizArchiveInputDetailService.physicalDelete(del2);
        //这个是查询升级表的数据并用原表实体接受
        BizArchiveInputUpdate query = new BizArchiveInputUpdate();
        query.setTenantId(tenantId);
        List<BizArchiveInput> bizArchiveInputList = bizArchiveInputTempMapper.selectByUpgradeId(query);
        //因为合同确定没有存在在系统里的所以批量插入
        bizArchiveInputService.saveBatch(bizArchiveInputList);
        BizArchiveInputDetailUpdate query2 = new BizArchiveInputDetailUpdate();
        query2.setTenantId(tenantId);
        List<BizArchiveInputDetail> bizArchiveInputDetailList = bizArchiveInputDetailUpdateService.selectByUpgradeId(query2);
        bizArchiveInputDetailService.saveBatch(bizArchiveInputDetailList);
    }

    @Override
    public Map<String,List<importCheckModel>> checkInput(List<OrderExcelImportLoopModel> orderList,Long tenantId) {
        importCheckModel checkmodel = null;
        //结束月小于当前时间
        List<importCheckModel> endMonthList = new ArrayList<>();
        //开始时间大于当前时间
        List<importCheckModel> startMonthList = new ArrayList<>();

        List<importCheckModel> checkModelList = new ArrayList<>();
        for(OrderExcelImportLoopModel loopModel : orderList){
            String companyName = loopModel.getCompanyName();

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Long taskId = 0L;

            if ("是".equals(loopModel.getKeepAccount())) {
                checkmodel = new importCheckModel();
                checkmodel.setCompanyName(companyName);
                checkmodel.setContractNo(loopModel.getContractNo());
                checkmodel.setTaskType("代理记账");
                checkmodel.setStartMonth(loopModel.getKeepAccountStartMonth());
                checkmodel.setEndMonth(loopModel.getKeepAccountEndMonth());
                checkModelList.add(checkmodel);
            }
            if ("是".equals(loopModel.getSocialSecurity())) {
                checkmodel = new importCheckModel();
                checkmodel.setCompanyName(companyName);
                checkmodel.setContractNo(loopModel.getContractNo());
                checkmodel.setTaskType("社保");
                checkmodel.setStartMonth(loopModel.getSocialSecurityStartMonth());
                checkmodel.setEndMonth(loopModel.getSocialSecurityEndMonth());
                checkModelList.add(checkmodel);
            }
            if ("是".equals(loopModel.getHousingFund())) {
                checkmodel = new importCheckModel();
                checkmodel.setCompanyName(companyName);
                checkmodel.setContractNo(loopModel.getContractNo());
                checkmodel.setTaskType("公积金");
                checkmodel.setStartMonth(loopModel.getHousingFundStartMonth());
                checkmodel.setEndMonth(loopModel.getHousingFundEndMonth());
                checkModelList.add(checkmodel);
            }
            if ("是".equals(loopModel.getReturnTax())) {
                checkmodel = new importCheckModel();
                checkmodel.setCompanyName(companyName);
                checkmodel.setContractNo(loopModel.getContractNo());
                checkmodel.setTaskType("返税");
                checkmodel.setStartMonth(loopModel.getReturnTaxStartMonth());
                checkmodel.setEndMonth(loopModel.getReturnTaxEndMonth());
                checkModelList.add(checkmodel);
            }
        }

        // 同类型分组
        Map<String, List<importCheckModel>> groupMap = new HashMap<>();
        for (importCheckModel groupModel : checkModelList) {
            String key = groupModel.getCompanyName() + "-" + groupModel.getTaskType();
            List<importCheckModel> subGroupList = groupMap.get(key);
            if (subGroupList == null) {
                subGroupList = new ArrayList<>();
            }
            subGroupList.add(groupModel);
            groupMap.put(key, subGroupList);
        }
        for(List<importCheckModel> model:groupMap.values()){
            List<importCheckModel> startList =
                    model.stream()
                            .sorted(Comparator.comparing(importCheckModel::getStartMonth))
                            .collect(Collectors.toList());
            List<importCheckModel> endList =
                    model.stream()
                            .sorted(Comparator.comparing(importCheckModel::getEndMonth))
                            .collect(Collectors.toList());

            if(endList.get(endList.size()-1).getEndMonth().compareTo(new Date()) < 0){
                endMonthList.add(endList.get(endList.size()-1));
            }
            if(startList.get(0).getStartMonth().compareTo(new Date()) > 0){
            startMonthList.add(startList.get(0));
            }
        }
        Map<String,List<importCheckModel>> map = new HashMap<>();
        map.put("startMonth",startMonthList);
        map.put("endMonth",endMonthList);
        return map;
    }
    public Map<String,String> checkexcel(List<OrderExcelImportLoopModel> orderList,Long tenantId){
        successNum = 0;
        failureNum = 0;
        successMsg = new StringBuilder();
        failureMsg = new StringBuilder();
        List<String> contractNo = orderList.stream().map(m -> m.getContractNo()).collect(Collectors.toList());
        //合同号不能重复
        Map<String, Long> nameCountMap = contractNo.stream()
                .collect(Collectors.groupingBy(name -> name, Collectors.counting()));
        List<BizCompany> companies = companyService.query().eq("tenant_id", tenantId).list();
        List<String> contNOs = this.query().eq("service_type", 1).eq("tenant_id", tenantId).list().stream().map(m -> m.getContractNo()).collect(Collectors.toList());
        List<importCheckModel> checkModelList = new ArrayList<>();
        for(OrderExcelImportLoopModel loopModel : orderList) {
            if (loopModel.getDiscountAmount() == null) {
                loopModel.setDiscountAmount(BigDecimal.ZERO);
            }
            BizCompany company = companies.stream().filter(v -> v.getName().equals(loopModel.getCompanyName())).findFirst().orElse(null);
            if (company == null) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、客户 ").append(loopModel.getCompanyName()).append(" 不存在");
                continue;
            }
            SysUser user = userService.selectUserByUserNameAndTenantId(loopModel.getSignerName(), String.valueOf(tenantId));
//            if (user == null) {
//                failureNum++;
//                failureMsg.append("<br/>").append(failureNum).append("、员工 ").append(item.getSignerName()).append(" 不存在");
//                continue;
//            }
            // 判断下订单总价单价是否和录入相符
            // 假设 amount - discountAmount != trueAmount 跳过该订单
            if (loopModel.getAmount() == null) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(failureNum).append("服务金额不能为空");
                continue;
            }
            if (loopModel.getTrueAmount() == null) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(failureNum).append("实收金额不能为空");
                continue;
            }
            if (loopModel.getAmount().subtract(loopModel.getDiscountAmount() == null ? BigDecimal.ZERO : loopModel.getDiscountAmount()).compareTo(loopModel.getTrueAmount()) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(" 实际付款金额出错");
                continue;
            }
            if (loopModel.getTrueAmount().compareTo(BigDecimal.ZERO) < 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(" 实际付款金额小于0");
                continue;
            }
            // 假设子表金额不等于订单总金额
            BigDecimal keepAccount = loopModel.getKeepAccountAmount() == null ? BigDecimal.ZERO : loopModel.getKeepAccountAmount();
            BigDecimal security = loopModel.getSocialSecurityAmount() == null ? BigDecimal.ZERO : loopModel.getSocialSecurityAmount();
            BigDecimal housingFund = loopModel.getHousingFundAmount() == null ? BigDecimal.ZERO : loopModel.getHousingFundAmount();
            BigDecimal returnTax = loopModel.getReturnTaxAmount() == null ? BigDecimal.ZERO : loopModel.getReturnTaxAmount();
            //优惠
            BigDecimal keepFreeAccount = loopModel.getKeepAccountFreeAmount() == null ? BigDecimal.ZERO : loopModel.getKeepAccountFreeAmount();
            BigDecimal securityFree = loopModel.getSocialSecurityFreeAmount() == null ? BigDecimal.ZERO : loopModel.getSocialSecurityFreeAmount();
            BigDecimal housingFundFree = loopModel.getHousingFundFreeAmount() == null ? BigDecimal.ZERO : loopModel.getHousingFundFreeAmount();
            BigDecimal returnTaxFree = loopModel.getReturnTaxFreeAmount() == null ? BigDecimal.ZERO : loopModel.getReturnTaxFreeAmount();
//            if (item.getAmount().compareTo(keepAccount.add(security).add(housingFund).add(returnTax)) != 0) {
            //update 6/12 实收金额 和各项金额比较 ，各项金额填写时应该为 单价*月-优惠金额
            if (loopModel.getTrueAmount().compareTo(keepAccount.add(security).add(housingFund).add(returnTax)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(" 实收金额不等于实际任务金额的和。");
                continue;
            }

            if (loopModel.getDiscountAmount().compareTo(keepFreeAccount.add(securityFree).add(housingFundFree).add(returnTaxFree)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append("优惠金额不等于任务优惠金额的和。");
                continue;
            }
            BigDecimal keepAccountPrice = loopModel.getKeepAccountPrice() == null ? BigDecimal.ZERO : loopModel.getKeepAccountPrice();
            BigDecimal securityPrice = loopModel.getSocialSecurityPrice() == null ? BigDecimal.ZERO : loopModel.getSocialSecurityPrice();
            BigDecimal housingFundPrice = loopModel.getHousingFundPrice() == null ? BigDecimal.ZERO : loopModel.getHousingFundPrice();
            BigDecimal returnTaxPrice = loopModel.getReturnTaxPrice() == null ? BigDecimal.ZERO : loopModel.getReturnTaxPrice();
            BigDecimal keepAccountMonth = loopModel.getKeepAccountMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getKeepAccountMonth());
            BigDecimal securityMonth = loopModel.getSocialSecurityMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getSocialSecurityMonth());
            BigDecimal housingFundMonth = loopModel.getHousingFundMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getHousingFundMonth());
            BigDecimal returnTaxMonth = loopModel.getReturnTaxMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getReturnTaxMonth());
            if (loopModel.getKeepAccountStartMonth() != null && loopModel.getKeepAccountEndMonth() != null) {
                Calendar startCalendar = Calendar.getInstance();
                startCalendar.setTime(loopModel.getKeepAccountStartMonth());
                Calendar endCalendar = Calendar.getInstance();
                endCalendar.setTime(loopModel.getKeepAccountEndMonth());
                // 计算年份和月份的差异
                int yearDiff = endCalendar.get(Calendar.YEAR) - startCalendar.get(Calendar.YEAR);
                int monthDiff = endCalendar.get(Calendar.MONTH) - startCalendar.get(Calendar.MONTH);
                // 总的月份差异
                int totalMonthsBetween = yearDiff * 12 + monthDiff + 1;
                BigDecimal keeFreeMonth = loopModel.getKeepAccountFreeMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getKeepAccountFreeMonth());
                if (totalMonthsBetween != keepAccountMonth.add(keeFreeMonth).intValue()) {
                    failureNum++;
                    failureMsg.append("<br/>").append(failureNum).append(company.getName() + "的代理记账服务的服务月数+赠送月数跟结束月-开始月的时间不等，请检查数据");
                    continue;
                }

            }
            if (loopModel.getSocialSecurityStartMonth() != null && loopModel.getSocialSecurityEndMonth() != null) {
                Calendar startCalendar2 = Calendar.getInstance();
                startCalendar2.setTime(loopModel.getSocialSecurityStartMonth());
                Calendar endCalendar2 = Calendar.getInstance();
                endCalendar2.setTime(loopModel.getSocialSecurityEndMonth());
                // 计算年份和月份的差异
                int yearDiff2 = endCalendar2.get(Calendar.YEAR) - startCalendar2.get(Calendar.YEAR);
                int monthDiff2 = endCalendar2.get(Calendar.MONTH) - startCalendar2.get(Calendar.MONTH);
                // 总的月份差异
                int totalMonthsBetween2 = yearDiff2 * 12 + monthDiff2 + 1;
                BigDecimal socialSecurityMonth = loopModel.getSocialSecurityFreeMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getSocialSecurityFreeMonth());
                if (totalMonthsBetween2 != securityMonth.add(socialSecurityMonth).intValue()) {
                    failureNum++;

                    failureMsg.append("<br/>").append(failureNum).append(company.getName() + "的社保代缴服务的服务月数+赠送月数跟结束月-开始月的时间不等，请检查数据");
                    continue;
                }
            }


            if (loopModel.getHousingFundStartMonth() != null && loopModel.getHousingFundEndMonth() != null) {
                Calendar startCalendar3 = Calendar.getInstance();
                startCalendar3.setTime(loopModel.getHousingFundStartMonth());
                Calendar endCalendar3 = Calendar.getInstance();
                endCalendar3.setTime(loopModel.getHousingFundEndMonth());
                // 计算年份和月份的差异
                int yearDiff3 = endCalendar3.get(Calendar.YEAR) - startCalendar3.get(Calendar.YEAR);
                int monthDiff3 = endCalendar3.get(Calendar.MONTH) - startCalendar3.get(Calendar.MONTH);
                // 总的月份差异
                int totalMonthsBetween3 = yearDiff3 * 12 + monthDiff3 + 1;
                BigDecimal housingFundMonths = loopModel.getHousingFundFreeMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getHousingFundFreeMonth());
                if (totalMonthsBetween3 != housingFundMonth.add(housingFundMonths).intValue()) {
                    failureNum++;
                    failureMsg.append("<br/>").append(failureNum).append(company.getName() + "的公积金服务的服务月数+赠送月数跟结束月-开始月的时间不等，请检查数据");
                    continue;
                }
            }

            if (loopModel.getReturnTaxStartMonth() != null && loopModel.getReturnTaxEndMonth() != null) {
                Calendar startCalendar4 = Calendar.getInstance();
                startCalendar4.setTime(loopModel.getReturnTaxStartMonth());
                Calendar endCalendar4 = Calendar.getInstance();
                endCalendar4.setTime(loopModel.getReturnTaxEndMonth());
                // 计算年份和月份的差异
                int yearDiff4 = endCalendar4.get(Calendar.YEAR) - startCalendar4.get(Calendar.YEAR);
                int monthDiff4 = endCalendar4.get(Calendar.MONTH) - startCalendar4.get(Calendar.MONTH);
                // 总的月份差异
                int totalMonthsBetween4 = yearDiff4 * 12 + monthDiff4 + 1;
                BigDecimal returnTaxFreeMonth = loopModel.getReturnTaxFreeMonth() == null ? BigDecimal.ZERO : BigDecimal.valueOf(loopModel.getReturnTaxFreeMonth());
                if (totalMonthsBetween4 != returnTaxMonth.add(returnTaxFreeMonth).intValue()) {
                    failureNum++;
                    failureMsg.append("<br/>").append(failureNum).append(company.getName() + "的返税申报服务的服务月数+赠送月数跟结束月-开始月的时间不等，请检查数据");
                    continue;
                }
            }

            if (nameCountMap.get(loopModel.getContractNo()) > 1L) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("导入的合同编号 ").append(loopModel.getContractNo()).append("不能重复");
                continue;
            }
            if (contNOs.contains(loopModel.getContractNo())) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("合同编号 ").append(loopModel.getContractNo()).append("已存在不能重复导入");
                continue;
            }
            //update 6/12 加单条优惠才为当月总金额
            if (keepAccount.add(keepFreeAccount).compareTo(keepAccountPrice.multiply(keepAccountMonth)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(" 记账总金额计算值与记账单价不符。");
                continue;
            }
            if (security.add(securityFree).compareTo(securityPrice.multiply(securityMonth)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(" 社保总金额计算值与社保单价不符。");
                continue;
            }
            if (housingFund.add(housingFundFree).compareTo(housingFundPrice.multiply(housingFundMonth)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(" 公积金总金额计算值与公积金单价不符。");
                continue;
            }
            if (returnTax.add(returnTaxFree).compareTo(returnTaxMonth.multiply(returnTaxPrice)) != 0) {
                failureNum++;
                failureMsg.append("<br/>").append(failureNum).append("、订单 ").append(loopModel.getContractNo()).append(" 返税总金额计算值与返税单价不符。");
                continue;
            }
        }
        Map<String,String> map = new HashMap<>();
        map.put("failureNum",String.valueOf(failureNum));
        map.put("failureMsg",failureMsg.toString());
        return map;
    }

}
