
package org.sky.scientific.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import org.sky.core.excel.util.ExcelUtil;
import org.sky.core.log.exception.ServiceException;
import org.sky.core.mp.base.BaseServiceImpl;
import org.sky.core.mp.support.Condition;
import org.sky.core.mp.support.Query;
import org.sky.core.secure.utils.SecureUtil;
import org.sky.core.tool.utils.*;
import org.sky.scientific.excel.XmCostDetailsExcel;
import org.sky.scientific.mapper.DeductionCostQtMapper;
import org.sky.scientific.mapper.SubjectEnterpriseMapper;
import org.sky.scientific.mapper.XmCostDetailsMapper;
import org.sky.scientific.mapper.XmMapper;
import org.sky.scientific.pojo.dto.XmCostDetailsDTO;
import org.sky.scientific.pojo.entity.DeductionCostQt;
import org.sky.scientific.pojo.entity.SubjectEnterprise;
import org.sky.scientific.pojo.entity.XmCostDetailsEntity;
import org.sky.scientific.pojo.vo.*;
import org.sky.scientific.service.IXmCostDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 研发费用支出明细账 服务实现类
 *
 * @author Kd
 * @since 2025-07-30
 */
@Service
@AllArgsConstructor
public class XmCostDetailsServiceImpl extends BaseServiceImpl<XmCostDetailsMapper, XmCostDetailsEntity> implements IXmCostDetailsService {

	private final XmMapper xmMapper;
	private final SubjectEnterpriseMapper subjectEnterpriseMapper;
	private final DeductionCostQtMapper qtMapper;

	@Override
	public IPage<XmCostDetailsEntity> selectXmCostDetailsPage(IPage<XmCostDetailsEntity> page, XmCostDetailsDTO dto) {
		if (Func.isBlank(dto.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		List<XmCostDetailsEntity> list = null;
		if (dto.getYearAndMonth().length() == 6) {
			list = baseMapper.selectPageByYearAndMonth(page, dto);
		} else if (dto.getYearAndMonth().length() == 4) {
			list = baseMapper.selectPageByYear(page, dto);
		} else {
			throw new ServiceException("参数yearAndMonth格式错误，yyyyMM或yyyy");
		}
		return page.setRecords(list);
	}

	@Override
	public boolean submit(XmCostDetailsEntity xmCostDetails) {
		boolean result = false;
		//日期，必须为当月日期
		judgeDate(xmCostDetails.getRecordDate(), xmCostDetails.getYearAndMonth());
		if (Func.isEmpty(xmCostDetails.getId())) {
			//新增
			result = this.save(xmCostDetails);
		} else {
			//修改
			result = this.updateById(xmCostDetails);
		}
		return result;
	}

	@Override
	public boolean physicalDeleteByIds(List<Long> ids) {
		return baseMapper.physicalDeleteByIds(ids) > 0;
	}

	@Override
	public boolean importXmCostDetails(MultipartFile file, String yearAndMonth) {
		if (StringUtil.isBlank(yearAndMonth)) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		List<XmCostDetailsExcel> data = ExcelUtil.read(file, 0, 2, XmCostDetailsExcel.class);
		if (CollectionUtil.isEmpty(data)) {
			throw new ServiceException("未能从模板中读取数据，请检查模板格式是否正确");
		}
		List<XmCostDetailsEntity> insertList = new ArrayList<>();

		for (XmCostDetailsExcel excel : data) {
			XmCostDetailsEntity entity = Objects.requireNonNull(BeanUtil.copyProperties(excel, XmCostDetailsEntity.class));

			//日期，必须时当月日期
			judgeDate(excel.getRecordDate(), yearAndMonth);

			if (Func.isBlank(excel.getXmmc())) {
				throw new ServiceException("序号[" + excel.getSerialNumber() + "]的研发项目名称不能为空");
			}
			if (Func.isBlank(excel.getESubjectCode())) {
				throw new ServiceException("序号[" + excel.getSerialNumber() + "]的企业科目代码不能为空");
			}
			if (Func.isBlank(excel.getESubjectName())) {
				throw new ServiceException("序号[" + excel.getSerialNumber() + "]的企业科目名称不能为空");
			}
//			if(excel.getSubjectName().contains("\\") && excel.getSubjectName().split("\\\\").length != 4){
//				throw new ServiceException("序号["+excel.getSerialNumber()+"]的科目名称应该为四级科目");
//			}
			//根据项目名称或编号查询xmId
			Long xmId = xmMapper.getXmIdByXmmcOrXmbh(yearAndMonth, excel.getXmmc(), null);
			if (xmId == null) {
				throw new ServiceException("研发项目[" + excel.getXmmc() + "]不存在，请检查模板数据");
			}
			entity.setXmId(xmId);

			//根据企业科目代码查询id

//			Subject dbSubject = subjectMapper.selectOne(Wrappers.<Subject>lambdaQuery().eq(Subject::getCode, excel.getSubjectCode()));
			SubjectEnterprise dbSubject = subjectEnterpriseMapper.selectOne(Wrappers.<SubjectEnterprise>lambdaQuery().eq(SubjectEnterprise::getCode, excel.getESubjectCode()));
			if (Func.isNull(dbSubject)) {
				throw new ServiceException("序号[" + excel.getSerialNumber() + "]的企业科目代码不存在");
			}
			entity.setESubjectId(dbSubject.getId());
			entity.setESubjectCode(dbSubject.getCode());
			entity.setESubjectName(dbSubject.getCode());
			entity.setYearAndMonth(yearAndMonth);
			insertList.add(entity);

			if (insertList.size() % 20 == 0) {
				if (this.saveBatch(insertList)) {
					insertList.clear();
				}
			}
		}

		if (Func.isNotEmpty(insertList)) {
			this.saveBatch(insertList);
		}
		return true;
	}

	@Override
	public void exportXmCostDetails(HttpServletResponse response, XmCostDetailsDTO dto) {

	}

	@Override
	public List<FinanceCostDetailVO> financeCostDetail(XmCostDetailsDTO dto) {
		if (Func.isBlank(dto.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		dto.setTenantId(SecureUtil.getTenantId());
		List<FinanceCostDetailVO> list = baseMapper.financeCostDetail(dto);
		for (FinanceCostDetailVO tmp : list) {
			List<FinanceCostItemVO> vos = tmp.getCostList();
			for (FinanceCostItemVO vo : vos) {
				if (Arrays.asList("53010101", "53010201").contains(vo.getL3Code())) {
					//人员人工费用
					vo.setRyrg(vo.getAmount().doubleValue());
				} else if (Arrays.asList("53010102", "53010202").contains(vo.getL3Code())) {
					//直接投入费用
					vo.setZjtr(vo.getAmount().doubleValue());
				} else if (Arrays.asList("53010103", "53010203").contains(vo.getL3Code())) {
					//折旧费用与长期待摊费用
					vo.setZjfyycqdtfy(vo.getAmount().doubleValue());
				} else if (Arrays.asList("53010104", "53010204").contains(vo.getL3Code())) {
					//无形资产摊销费用
					vo.setWxzctx(vo.getAmount().doubleValue());
				} else if (Arrays.asList("53010105", "53010205").contains(vo.getL3Code())) {
					//设计费用
					vo.setSjf(vo.getAmount().doubleValue());
				} else if (Arrays.asList("53010106", "53010206").contains(vo.getL3Code())) {
					//装备调试费用与试验费用
					vo.setZbtsfyysyfy(vo.getAmount().doubleValue());
				} else if (Arrays.asList("53010107", "53010207").contains(vo.getL3Code())) {
					//委托外部研究开发费用
					vo.setWwyf(vo.getAmount().doubleValue());
				} else if (Arrays.asList("53010108", "53010208").contains(vo.getL3Code())) {
					//其他费用
					vo.setQtfy(vo.getAmount().doubleValue());
				} else {
					throw new ServiceException("费用归集出错啦");
				}
			}
		}
		return list;
	}

	@Override
	public IPage<FinanceCostSummary> financeCostSummary(IPage<FinanceCostSummary> page, XmCostDetailsDTO dto) {
		if (Func.isBlank(dto.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		dto.setTenantId(SecureUtil.getTenantId());


		Query query = new Query();
		query.setCurrent((int) page.getCurrent());
		query.setSize((int) page.getSize());
		IPage<JSONObject> p1 = Condition.getPage(query);
		List<JSONObject> tmpList = baseMapper.costSummary(p1, dto);
		page.setTotal(p1.getTotal()).setCurrent(p1.getCurrent()).setSize(p1.getSize());

		List<FinanceCostSummary> summaryList = JSON.parseArray(JSON.toJSONString(tmpList), FinanceCostSummary.class);
		for (FinanceCostSummary summary : summaryList) {

			List<CostItemVO> itemVOS = baseMapper.selectCostItemByCondition(dto.getYearAndMonth(), summary.getXmId());
			for (CostItemVO item : itemVOS) {
				if (Arrays.asList("53010101", "53010201").contains(item.getL3Code())) {
					//人员人工费用
					summary.setRyrgTotal(summary.getRyrgTotal() + item.getAmount().doubleValue());
				} else if (Arrays.asList("53010102", "53010202").contains(item.getL3Code())) {
					//直接投入费用
					summary.setZjtrTotal(summary.getZjtrTotal() + item.getAmount().doubleValue());
				} else if (Arrays.asList("53010103", "53010203").contains(item.getL3Code())) {
					//折旧费用与长期待摊费用
					summary.setZjfyycqdtfyTotal(summary.getZjfyycqdtfyTotal() + item.getAmount().doubleValue());
				} else if (Arrays.asList("53010104", "53010204").contains(item.getL3Code())) {
					//无形资产摊销费用
					summary.setWxzctxTotal(summary.getWxzctxTotal() + item.getAmount().doubleValue());
				} else if (Arrays.asList("53010105", "53010205").contains(item.getL3Code())) {
					//设计费用
					summary.setSjfTotal(summary.getSjfTotal() + item.getAmount().doubleValue());
				} else if (Arrays.asList("53010106", "53010206").contains(item.getL3Code())) {
					//装备调试费用与试验费用
					summary.setZbtsfyysyfyTotal(summary.getZbtsfyysyfyTotal() + item.getAmount().doubleValue());
				} else if (Arrays.asList("53010107", "53010207").contains(item.getL3Code())) {
					//委托外部研究开发费用
					summary.setWwyfTotal(summary.getWwyfTotal() + item.getAmount().doubleValue());
				} else if (Arrays.asList("53010108", "53010208").contains(item.getL3Code())) {
					//其他费用
					summary.setQtfyTotal(summary.getQtfyTotal() + item.getAmount().doubleValue());
				}
			}
		}
		return page.setRecords(summaryList);
	}

	@Override
	public List<HighTechCostDetailVO> highTechCostDetail(XmCostDetailsDTO dto) {
		if (Func.isBlank(dto.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		dto.setTenantId(SecureUtil.getTenantId());
		List<HighTechCostDetailVO> list = baseMapper.highTechCostDetail(dto);
		for (HighTechCostDetailVO tmp : list) {
			List<HighTechCostItemVO> vos = tmp.getCostList();
			for (HighTechCostItemVO vo : vos) {
				if (vo.getRdSubjectEnable() == 0) {
					//四级科目 不是高新研发费用科目，费用不归集
					continue;
				}
				if (Arrays.asList("53010101", "53010201").contains(vo.getL3Code())) {
					//人员人工费用
					vo.setRyrg(vo.getAmount().doubleValue());
				} else if (Arrays.asList("53010102", "53010202").contains(vo.getL3Code())) {
					//直接投入费用
					vo.setZjtr(vo.getAmount().doubleValue());
				} else if (Arrays.asList("53010103", "53010203").contains(vo.getL3Code())) {
					//折旧费用与长期待摊费用
					vo.setZjfyycqdtfy(vo.getAmount().doubleValue());
				} else if (Arrays.asList("53010104", "53010204").contains(vo.getL3Code())) {
					//无形资产摊销费用
					vo.setWxzctx(vo.getAmount().doubleValue());
				} else if (Arrays.asList("53010105", "53010205").contains(vo.getL3Code())) {
					//设计费用
					vo.setSjf(vo.getAmount().doubleValue());
				} else if (Arrays.asList("53010106", "53010206").contains(vo.getL3Code())) {
					//装备调试费用与试验费用
					vo.setZbtsfyysyfy(vo.getAmount().doubleValue());
				} else if (Arrays.asList("53010107", "53010207").contains(vo.getL3Code())) {
					//委托外部研究开发费用
					vo.setWwyf(vo.getAmount().doubleValue());
				} else if (Arrays.asList("53010108", "53010208").contains(vo.getL3Code())) {
					//其他费用
					vo.setQtfy(vo.getAmount().doubleValue());
				} else {
					throw new ServiceException("费用归集出错啦");
				}
			}
		}
		return list;
	}

	@Override
	public IPage<HighTechCostSummary> highTechCostSummary(IPage<HighTechCostSummary> page, XmCostDetailsDTO dto) {
		if (Func.isBlank(dto.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		dto.setTenantId(SecureUtil.getTenantId());

		Query query = new Query();
		query.setCurrent((int) page.getCurrent());
		query.setSize((int) page.getSize());
		IPage<JSONObject> p1 = Condition.getPage(query);

		List<JSONObject> tmpList = baseMapper.costSummary(p1, dto);

		page.setTotal(p1.getTotal()).setCurrent(p1.getCurrent()).setSize(p1.getSize());

		List<HighTechCostSummary> summaryList = JSON.parseArray(JSON.toJSONString(tmpList), HighTechCostSummary.class);
		for (HighTechCostSummary summary : summaryList) {

			List<CostItemVO> itemVOS = baseMapper.selectCostItemByCondition(dto.getYearAndMonth(), summary.getXmId());

			for (CostItemVO item : itemVOS) {
				if (item.getRdSubjectEnable() == 0) {
					//四级科目不是高新研发费用科目，费用不归集
					continue;
				}
				if (Arrays.asList("53010101", "53010201").contains(item.getL3Code())) {
					//1、人员人工费用
					summary.setRyrgTotal(summary.getRyrgTotal() + item.getAmount().doubleValue());
				} else if (Arrays.asList("53010102", "53010202").contains(item.getL3Code())) {
					//2、直接投入费用
					summary.setZjtrTotal(summary.getZjtrTotal() + item.getAmount().doubleValue());
				} else if (Arrays.asList("53010103", "53010203").contains(item.getL3Code())) {
					//3、折旧费用与长期待摊费用
					summary.setZjfyycqdtfyTotal(summary.getZjfyycqdtfyTotal() + item.getAmount().doubleValue());
				} else if (Arrays.asList("53010104", "53010204").contains(item.getL3Code())) {
					//4、无形资产摊销费用
					summary.setWxzctxTotal(summary.getWxzctxTotal() + item.getAmount().doubleValue());
				} else if (Arrays.asList("53010105", "53010205").contains(item.getL3Code())) {
					//5、设计费用
					summary.setSjfTotal(summary.getSjfTotal() + item.getAmount().doubleValue());
				} else if (Arrays.asList("53010106", "53010206").contains(item.getL3Code())) {
					//6、装备调试费用与试验费用
					summary.setZbtsfyysyfyTotal(summary.getZbtsfyysyfyTotal() + item.getAmount().doubleValue());
				} else if (Arrays.asList("53010107", "53010207").contains(item.getL3Code())) {
					//委托外部研究开发费用
					summary.setWwyfTotal(summary.getWwyfTotal() + item.getAmount().doubleValue());
				} else if (Arrays.asList("53010108", "53010208").contains(item.getL3Code())) {
					//7-1、其他费用
					summary.setQtfyTotal(summary.getQtfyTotal() + item.getAmount().doubleValue());
				}
				// 7-2、其他费用限额，1-6合计相加/0.8*0.2
				double total = summary.getRyrgTotal() + summary.getZjtrTotal() + summary.getZjfyycqdtfyTotal() + summary.getSjfTotal() + summary.getWxzctxTotal() + summary.getZbtsfyysyfyTotal();
				summary.setQtfyLimit(total / 0.8 * 0.2);
				//7-3、调整后其他费用，7-1和7-2，谁小取谁
				summary.setQtfyAdjust(Math.min(summary.getQtfyTotal(), summary.getQtfyLimit()));

			}
		}
		return page.setRecords(summaryList);
	}

	@Override
	public List<DeductionCostDetailVO> deductionCostDetail(XmCostDetailsDTO dto) {
		if (Func.isBlank(dto.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		if (dto.getType() == null) {
			throw new ServiceException("参数type不能为空");
		}
		if (!Arrays.asList(1, 2).contains(dto.getType())) {
			throw new ServiceException("参数type的值只能是1：费用化，2：资本化");
		}
		dto.setTenantId(SecureUtil.getTenantId());
		List<DeductionCostDetailVO> list = baseMapper.deductionCostDetail(dto);
		for (DeductionCostDetailVO tmp : list) {
			tmp.setWcqk(DateUtil.now().before(tmp.getXmjssj()) ? "进行中" : "已完成");
			List<DeductionCostItemVO> vos = tmp.getCostList();
			for (DeductionCostItemVO vo : vos) {
				if (vo.getAdSubjectEnable() == 0) {
					//四级科目 不是加计扣除研发费用科目，费用不归集
					continue;
				}
				if (dto.getType() == 1) {
					//费用化
					if (Func.equals(vo.getL3Code(), "53010101")) {
						//人员人工费用
						vo.setRyrgfy(vo.getAmount().doubleValue());
					} else if (Func.equals(vo.getL3Code(), "53010102")) {
						//直接投入费用
						vo.setZjtrfy(vo.getAmount().doubleValue());
					} else if (Func.equals(vo.getL3Code(), "53010103")) {
						//折旧费用
						vo.setZjfy(vo.getAmount().doubleValue());
					} else if (Func.equals(vo.getL3Code(), "53010104")) {
						//无形资产摊销
						vo.setWxzctx(vo.getAmount().doubleValue());
					} else if (Arrays.asList("5301010501", "5301010502", "5301010602", "5301010603").contains(vo.getL4Code())) {
						//新产品设计费等
						//三级科目中的“设计费用”-新产品设计费，新工艺规程制定费；和"装备调试费用与试验费用"-新药研制的临床试验费,勘探开发的现场试验费；归集到新产品设计费等
						vo.setXcpsjfd(vo.getAmount().doubleValue());
					} else if (Func.equals(vo.getL3Code(), "53010108")) {
						//其他相关费用
						vo.setQtxgfy(vo.getAmount().doubleValue());
					} else if (Func.equals(vo.getL4Code(), "5301010701")) {
						//委托境内机构或个人进行研发活动所发生的费用
						vo.setWtjnjgfy(vo.getAmount().doubleValue());
					} else if (Func.equals(vo.getL4Code(), "5301010702")) {
						//委托境外机构进行研发活动所发生的费用
						vo.setWtjwjgfy(vo.getAmount().doubleValue());
					} else {
						throw new ServiceException("费用归集出错啦");
					}
				} else if (dto.getType() == 2) {
					//资本化
					if (Func.equals(vo.getL3Code(), "53010201")) {
						//人员人工费用
						vo.setRyrgfy(vo.getAmount().doubleValue());
					} else if (Func.equals(vo.getL3Code(), "53010202")) {
						//直接投入费用
						vo.setZjtrfy(vo.getAmount().doubleValue());
					} else if (Func.equals(vo.getL3Code(), "53010203")) {
						//折旧费用
						vo.setZjfy(vo.getAmount().doubleValue());
					} else if (Func.equals(vo.getL3Code(), "53010204")) {
						//无形资产摊销
						vo.setWxzctx(vo.getAmount().doubleValue());
					} else if (Arrays.asList("5301020501", "5301020502", "5301020602", "5301020603").contains(vo.getL4Code())) {
						//新产品设计费等
						//三级科目中的“设计费用”-新产品设计费，新工艺规程制定费；和"装备调试费用与试验费用"-新药研制的临床试验费,勘探开发的现场试验费；归集到新产品设计费等
						vo.setXcpsjfd(vo.getAmount().doubleValue());
					} else if (Func.equals(vo.getL3Code(), "53010208")) {
						//其他相关费用
						vo.setQtxgfy(vo.getAmount().doubleValue());
					} else if (Func.equals(vo.getL4Code(), "5301020701")) {
						//委托境内机构或个人进行研发活动所发生的费用
						vo.setWtjnjgfy(vo.getAmount().doubleValue());
					} else if (Func.equals(vo.getL4Code(), "5301020702")) {
						//委托境外机构进行研发活动所发生的费用
						vo.setWtjwjgfy(vo.getAmount().doubleValue());
					} else {
						throw new ServiceException("费用归集出错啦");
					}
				}
			}
		}
		return list;
	}

	@Override
	public DeductionCostSummary deductionCostSummary(XmCostDetailsDTO dto) {
		if (Func.isBlank(dto.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		dto.setTenantId(SecureUtil.getTenantId());
		List<DeductionCostDetailVO> list = baseMapper.deductionCostDetail(dto);
		DeductionCostSummary summary = new DeductionCostSummary();


		DeductionCostQt qt = qtMapper.selectOne(Wrappers.<DeductionCostQt>lambdaQuery().eq(DeductionCostQt::getYearAndMonth, dto.getYearAndMonth()));

		if (Func.notNull(qt)) {

			summary.setRyrgfy_qt(qt.getRyrgfyQt());
			summary.setZjtrfy_qt(qt.getZjtrfyQt());
			summary.setZjfy_qt(qt.getZjfyQt());
			summary.setWxzctx_qt(qt.getWxzctxQt());
			summary.setXcpsjfd_qt(qt.getXcpsjfdQt());
			summary.setQtxgfyhj_qt(qt.getQtxgfyhjQt());
			summary.setWtjnjgfy_qt(qt.getWtjnjgfyQt());
			summary.setWtjwjgfy_qt(qt.getWtjwjgfyQt());

			//先将“其中：其他事项”加入到 对应的费用化金额小计
			summary.setRyrgfy_fyh(summary.getRyrgfy_fyh().add(summary.getRyrgfy_qt()));
			summary.setZjtrfy_fyh(summary.getZjtrfy_fyh().add(summary.getZjtrfy_qt()));
			summary.setZjfy_fyh(summary.getZjfy_fyh().add(summary.getZjfy_qt()));
			summary.setWxzctx_fyh(summary.getWxzctx_fyh().add(summary.getWxzctx_qt()));
			summary.setXcpsjfd_fyh(summary.getXcpsjfd_fyh().add(summary.getXcpsjfd_qt()));
			summary.setQtxgfyhj_fyh(summary.getQtxgfyhj_fyh().add(summary.getQtxgfyhj_qt()));
			summary.setWtjnjgfy_fyh(summary.getWtjnjgfy_fyh().add(summary.getWtjnjgfy_qt()));
			summary.setWtjwjgfy_fyh(summary.getWtjwjgfy_fyh().add(summary.getWtjwjgfy_qt()));

			//其中：其他事项-前五项 小计
			summary.setTotal_qt(qt.getRyrgfyQt().add(qt.getZjtrfyQt()).add(qt.getZjfyQt()).add(qt.getWxzctxQt()).add(qt.getXcpsjfdQt()));

			summary.setTotal_fyh(summary.getTotal_fyh().add(summary.getTotal_qt()));
		}


		List<DeductionCostSummaryItem> summaryList = new ArrayList<>();
		for (DeductionCostDetailVO cost : list) {

			String wcqk = DateUtil.now().before(cost.getXmjssj()) ? "进行中" : "已完成";

			DeductionCostSummaryItem fyhSummary = new DeductionCostSummaryItem(cost.getXmId(), cost.getXmbh(), cost.getXmmc(), wcqk, 1);
			DeductionCostSummaryItem zbhSummary = new DeductionCostSummaryItem(cost.getXmId(), cost.getXmbh(), cost.getXmmc(), wcqk, 2);
			summaryList.add(fyhSummary);
			summaryList.add(zbhSummary);


			for (DeductionCostItemVO vo : cost.getCostList()) {
				if (vo.getAdSubjectEnable() == 0) {
					//四级科目 不是加计扣除研发费用科目，费用不归集
					continue;
				}
				if (Func.equals(vo.getL3Code(), "53010101")) {
					//1、人员人工费用-费用化
					fyhSummary.setRyrgTotal(fyhSummary.getRyrgTotal().add(vo.getAmount()));
				} else if (Func.equals(vo.getL3Code(), "53010201")) {
					//人员人工费用-资本化
					zbhSummary.setRyrgTotal(zbhSummary.getRyrgTotal().add(vo.getAmount()));
				} else if (Func.equals(vo.getL3Code(), "53010102")) {
					//2、直接投入费用费用-费用化
					fyhSummary.setZjtrTotal(fyhSummary.getZjtrTotal().add(vo.getAmount()));
				} else if (Func.equals(vo.getL3Code(), "53010202")) {
					//直接投入费用-资本化
					zbhSummary.setZjtrTotal(zbhSummary.getZjtrTotal().add(vo.getAmount()));
				} else if (Func.equals(vo.getL3Code(), "53010103")) {
					//3、折旧费用-费用化
					fyhSummary.setZjfyTotal(fyhSummary.getZjfyTotal().add(vo.getAmount()));
				} else if (Func.equals(vo.getL3Code(), "53010203")) {
					//3、折旧费用-资本化
					zbhSummary.setZjfyTotal(zbhSummary.getZjfyTotal().add(vo.getAmount()));
				} else if (Func.equals(vo.getL3Code(), "53010104")) {
					//4、无形资产摊销-费用化
					fyhSummary.setWxzctxTotal(fyhSummary.getWxzctxTotal().add(vo.getAmount()));
				} else if (Func.equals(vo.getL3Code(), "53010204")) {
					//4、无形资产摊销-资本化
					zbhSummary.setWxzctxTotal(zbhSummary.getWxzctxTotal().add(vo.getAmount()));
				} else if (Arrays.asList("5301010501", "5301010502", "5301010602", "5301010603").contains(vo.getL4Code())) {
					//5、新产品设计费等-费用化
					//三级科目中的“设计费用”-新产品设计费，新工艺规程制定费；和"装备调试费用与试验费用"-新药研制的临床试验费,勘探开发的现场试验费；归集到新产品设计费等
					fyhSummary.setXcpsjfd(fyhSummary.getXcpsjfd().add(vo.getAmount()));
				} else if (Arrays.asList("5301020501", "5301020502", "5301020602", "5301020603").contains(vo.getL4Code())) {
					//5、新产品设计费等-资本化
					//三级科目中的“设计费用”-新产品设计费，新工艺规程制定费；和"装备调试费用与试验费用"-新药研制的临床试验费,勘探开发的现场试验费；归集到新产品设计费等
					zbhSummary.setXcpsjfd(zbhSummary.getXcpsjfd().add(vo.getAmount()));
				} else if (Func.equals(vo.getL3Code(), "53010108")) {
					//7.1、其他相关费用-费用化
					fyhSummary.setQtxgfyTotal(fyhSummary.getQtxgfyTotal().add(vo.getAmount()));
				} else if (Func.equals(vo.getL3Code(), "53010208")) {
					//7.1、其他相关费用-资本化
					zbhSummary.setQtxgfyTotal(zbhSummary.getQtxgfyTotal().add(vo.getAmount()));
				} else if (Func.equals(vo.getL4Code(), "5301010701")) {
					//8.1、委托境内机构或个人进行研发活动所发生的费用-费用化
					fyhSummary.setWtjnfy(fyhSummary.getWtjnfy().add(vo.getAmount()));
				} else if (Func.equals(vo.getL4Code(), "5301020701")) {
					//8.1、委托境内机构或个人进行研发活动所发生的费用-资本化
					zbhSummary.setWtjnfy(zbhSummary.getWtjnfy().add(vo.getAmount()));
				} else if (Func.equals(vo.getL4Code(), "5301010702")) {
					//8.3、委托境外机构进行研发活动所发生的费用-费用化
					fyhSummary.setWtjwfy(fyhSummary.getWtjwfy().add(vo.getAmount()));
				} else if (Func.equals(vo.getL4Code(), "5301020702")) {
					//8.3、委托境外机构进行研发活动所发生的费用-资本化
					zbhSummary.setWtjwfy(zbhSummary.getWtjwfy().add(vo.getAmount()));
				} else {
					throw new ServiceException("费用归集出错啦");
				}
			}



			//前五项小计=1、人员人工费用+2、直接投入费用+3、折旧费用+4、无形资产摊销+5、新产品设计费等
			fyhSummary.setTotal(fyhSummary.getRyrgTotal().add(fyhSummary.getZjtrTotal()).add(fyhSummary.getZjfyTotal()).add(fyhSummary.getWxzctxTotal()).add(fyhSummary.getXcpsjfd()));
			zbhSummary.setTotal(zbhSummary.getRyrgTotal().add(zbhSummary.getZjtrTotal()).add(zbhSummary.getZjfyTotal()).add(zbhSummary.getWxzctxTotal()).add(zbhSummary.getXcpsjfd()));

			zbhSummary.setWtjnfyAdjust(zbhSummary.getWtjnfyAdjust().multiply(new BigDecimal("0.8")));
			fyhSummary.setWtjnfyAdjust(fyhSummary.getWtjnfyAdjust().multiply(new BigDecimal("0.8")));


			//资本化金额小计----------------begin
			//资本化金额小计-人员人工费用
			summary.setRyrgfy_zbh(summary.getRyrgfy_zbh().add(zbhSummary.getRyrgTotal()));
			//费用化金额小计-人员人工费用
			summary.setRyrgfy_fyh(summary.getRyrgfy_fyh().add(fyhSummary.getRyrgTotal()));
			//金额合计-人员人工费用
			summary.setRyrgfy_hjje(summary.getRyrgfy_hjje().add(summary.getRyrgfy_zbh()).add(summary.getRyrgfy_fyh()));

			//资本化金额小计-直接投入费用
			summary.setZjtrfy_zbh(summary.getZjtrfy_zbh().add(zbhSummary.getZjtrTotal()));
			//费用化金额小计-直接投入费用
			summary.setZjtrfy_fyh(summary.getZjtrfy_fyh().add(fyhSummary.getZjtrTotal()));
			//金额合计-直接投入费用
			summary.setZjtrfy_hjje(summary.getZjtrfy_hjje().add(summary.getZjtrfy_zbh()).add(summary.getZjtrfy_fyh()));

			//资本化金额小计-折旧费用
			summary.setZjfy_zbh(summary.getZjfy_zbh().add(zbhSummary.getZjfyTotal()));
			//费用化金额小计-折旧费用
			summary.setZjfy_fyh(summary.getZjfy_fyh().add(fyhSummary.getZjfyTotal()));
			//金额合计-折旧费用
			summary.setZjfy_hjje(summary.getZjfy_hjje().add(summary.getZjfy_zbh()).add(summary.getZjfy_fyh()));

			//资本化金额小计-无形资产摊销
			summary.setWxzctx_zbh(summary.getWxzctx_zbh().add(zbhSummary.getWxzctxTotal()));
			//费用化金额小计-无形资产摊销
			summary.setWxzctx_fyh(summary.getWxzctx_fyh().add(fyhSummary.getWxzctxTotal()));
			//金额合计-无形资产摊销
			summary.setWxzctx_hjje(summary.getWxzctx_hjje().add(summary.getWxzctx_zbh()).add(summary.getWxzctx_fyh()));

			//资本化金额小计-新产品设计费等
			summary.setXcpsjfd_zbh(summary.getXcpsjfd_zbh().add(zbhSummary.getXcpsjfd()));
			//费用化金额小计-新产品设计费等
			summary.setXcpsjfd_fyh(summary.getXcpsjfd_fyh().add(fyhSummary.getXcpsjfd()));
			//金额合计-新产品设计费等
			summary.setXcpsjfd_hjje(summary.getXcpsjfd_hjje().add(summary.getXcpsjfd_zbh()).add(summary.getXcpsjfd_fyh()));


			//资本化金额小计-前五项小计
			summary.setTotal_zbh(summary.getTotal_zbh().add(zbhSummary.getTotal()));
			//费用化金额小计-前五项小计
			summary.setTotal_fyh(summary.getTotal_fyh().add(fyhSummary.getTotal()));
			//金额合计-前五项 小计
			summary.setTotal_hjje(summary.getTotal_hjje().add(summary.getTotal_zbh()).add(summary.getTotal_fyh()));

			//资本化金额小计-其他相关费用合计
			summary.setQtxgfyhj_zbh(summary.getQtxgfyhj_zbh().add(zbhSummary.getQtxgfyTotal()));
			//费用化金额小计-其他相关费用合计
			summary.setQtxgfyhj_fyh(summary.getQtxgfyhj_fyh().add(fyhSummary.getQtxgfyTotal()));
			//金额合计-其他相关费用合计
			summary.setQtxgfyhj_hjje(summary.getQtxgfyhj_hjje().add(summary.getQtxgfyhj_zbh()).add(summary.getQtxgfyhj_fyh()));

			//资本化金额小计-委托境内机构或个人进行研发活动所发生的费用
			summary.setWtjnjgfy_zbh(summary.getWtjnjgfy_zbh().add(zbhSummary.getWtjnfy()));
			//费用化金额小计-委托境内机构或个人进行研发活动所发生的费用
			summary.setWtjnjgfy_fyh(summary.getWtjnjgfy_fyh().add(fyhSummary.getWtjnfy()));
			//金额合计-委托境内机构或个人进行研发活动所发生的费用
			summary.setWtjnjgfy_hjje(summary.getWtjnjgfy_hjje().add(summary.getWtjnjgfy_zbh()).add(summary.getWtjnjgfy_fyh()));


			//资本化金额小计-允许加计扣除的委托境内机构或个人进行研发活动所发生的费用
			summary.setWtjnjgfy_zbh(summary.getWtjnjgfy_zbh().add(zbhSummary.getWtjnfyAdjust()));
			//费用化金额小计-允许加计扣除的委托境内机构或个人进行研发活动所发生的费用
			summary.setWtjnjgfy_fyh(summary.getWtjnjgfy_fyh().add(fyhSummary.getWtjnfyAdjust()));
			//金额合计-允许加计扣除的委托境内机构或个人进行研发活动所发生的费用
			summary.setWtjnjgfy_hjje(summary.getWtjnjgfy_hjje().add(summary.getWtjnjgfy_zbh()).add(summary.getWtjnjgfy_fyh()));


			//资本化金额小计-委托境外机构进行研发活动所发生的费用
			summary.setWtjwjgfy_zbh(summary.getWtjwjgfy_zbh().add(zbhSummary.getWtjwfy()));
			//费用化金额小计-委托境外机构进行研发活动所发生的费用
			summary.setWtjwjgfy_fyh(summary.getWtjwjgfy_fyh().add(fyhSummary.getWtjwfy()));
			//金额合计-委托境外机构进行研发活动所发生的费用
			summary.setWtjwjgfy_hjje(summary.getWtjwjgfy_hjje().add(summary.getWtjwjgfy_zbh()).add(summary.getWtjwjgfy_fyh()));


			//允许加计扣除金额合计=前五项 小计 + 经限额调整后的其他相关费用 + 允许加计扣除的委托境内机构或个人进行研发活动所发生的费用 + 经限额调整后的委托境外机构进行研发活动所发生的费用
			fyhSummary.setYxjjkcjehj(fyhSummary.getYxjjkcjehj().add(fyhSummary.getTotal()));
			zbhSummary.setYxjjkcjehj(zbhSummary.getYxjjkcjehj().add(zbhSummary.getTotal()));


		}

		summary.setTotal_hjje(summary.getTotal_zbh().add(summary.getTotal_fyh()));

		//=IF(K20*0.1/0.9<L20,K20*0.1/0.9,L20)
		BigDecimal divide = summary.getTotal_hjje().multiply(new BigDecimal("0.1")).divide(new BigDecimal("0.9"), 2, RoundingMode.HALF_UP);
		summary.setQtxgfyhj_adjust_hjje(divide.compareTo(summary.getQtxgfyhj_hjje()) < 0 ? divide : summary.getQtxgfyhj_hjje());


		//金额合计-经限额调整后的委托境外机构进行研发活动所发生的费用
		//(K20+M20+O20)*2/3
		BigDecimal d1 = summary.getTotal_hjje().add(summary.getQtxgfyhj_hjje()).add(summary.getWtjnjgfy_hjje()).multiply(new BigDecimal("2")).divide(new BigDecimal("3"), 2, RoundingMode.HALF_UP);
		//P20*0.8
		BigDecimal d2 = summary.getWtjwjgfy_hjje().multiply(new BigDecimal("0.8"));
		summary.setWtjwjgfy_adjust_hjje(d1.compareTo(d2) < 0 ? d1 : d2);

		for (DeductionCostSummaryItem item : summaryList) {

			//=$Q$20/$P$20*P8 经限额调整后的委托境外机构进行研发活动所发生的费用
			if (BigDecimal.ZERO.compareTo(summary.getWtjwjgfy_hjje()) != 0) {
				item.setWtjwfyAdjust(summary.getWtjwjgfy_adjust_hjje().multiply(item.getWtjwfy()).divide(summary.getWtjwjgfy_hjje(), 2, RoundingMode.HALF_UP));
			}

			//=M20/L20*L9
			if (BigDecimal.ZERO.compareTo(summary.getQtxgfyhj_hjje()) != 0) {
				item.setQtxgfyAdjustTotal(summary.getQtxgfyhj_adjust_hjje().multiply(item.getQtxgfyTotal()).divide(summary.getQtxgfyhj_hjje(), 2, RoundingMode.HALF_UP));
			}

			//允许加计扣除金额合计 = 前五项 小计 + 经限额调整后的其他相关费用 + 允许加计扣除的委托境内机构或个人进行研发活动所发生的费用 + 经限额调整后的委托境外机构进行研发活动所发生的费用
			item.setYxjjkcjehj(item.getRyrgTotal().add(item.getQtxgfyAdjustTotal()).add(item.getWtjnfyAdjust()).add(item.getWtjwfyAdjust()));

			if (item.getType() == 1) {
				summary.setQtxgfyhj_adjust_fyh(summary.getQtxgfyhj_adjust_fyh().add(item.getQtxgfyAdjustTotal()));
				summary.setWtjwjgfy_adjust_fyh(summary.getWtjwjgfy_adjust_fyh().add(item.getWtjwfyAdjust()));

				summary.setYxjjkcjehj_fyh(summary.getYxjjkcjehj_fyh().add(item.getYxjjkcjehj()));

			} else if (item.getType() == 2) {
				summary.setQtxgfyhj_adjust_zbh(summary.getQtxgfyhj_adjust_zbh().add(item.getQtxgfyAdjustTotal()));
				summary.setWtjwjgfy_adjust_zbh(summary.getWtjwjgfy_adjust_zbh().add(item.getWtjwfyAdjust()));

				summary.setYxjjkcjehj_zbh(summary.getYxjjkcjehj_zbh().add(item.getYxjjkcjehj()));
			}

		}

		summary.setYxjjkcjehj_hjje(summary.getYxjjkcjehj_hjje().add(summary.getYxjjkcjehj_fyh()).add(summary.getYxjjkcjehj_zbh()));


		summary.setItemList(summaryList);
		return summary;
	}

	@Override
	public boolean updateDeductionQt(DeductionCostQt dto) {
		if (Func.isBlank(dto.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		LambdaQueryWrapper<DeductionCostQt> eq = Wrappers.<DeductionCostQt>lambdaQuery()
			.eq(DeductionCostQt::getYearAndMonth, dto.getYearAndMonth())
			.eq(DeductionCostQt::getTenantId, SecureUtil.getTenantId());
		DeductionCostQt dbQt = qtMapper.selectOne(eq);
		if (Func.isNull(dbQt)) {
			return qtMapper.insert(dto) == 1;
		} else {
			dto.setId(dbQt.getId());
			return qtMapper.updateById(dto) == 1;
		}
	}

	public static void judgeDate(Date date, String yearAndMonth) {
		//日期，必须时当月日期
		if (date != null) {
			String format = DateUtil.format(date, DateUtil.PATTERN_YYYYMM);
			boolean equals = StringUtil.equals(format, yearAndMonth);
			if (!equals) {
				throw new ServiceException("日期" + format + "必须是" + yearAndMonth + "月的一天");
			}
		}
	}

}
