
package org.sky.scientific.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
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.e.AssetStatusEnum;
import org.sky.scientific.excel.AssetExcel;
import org.sky.scientific.excel.listener.AssetImportListener;
import org.sky.scientific.mapper.*;
import org.sky.scientific.pojo.dto.AssetDTO;
import org.sky.scientific.pojo.dto.CostSummaryDTO;
import org.sky.scientific.pojo.dto.XmAssetCostQueryParam;
import org.sky.scientific.pojo.entity.AssetEntity;
import org.sky.scientific.pojo.entity.XmFixedAsset;
import org.sky.scientific.pojo.entity.XmIntangibleAsset;
import org.sky.scientific.pojo.vo.AssetVO;
import org.sky.scientific.pojo.vo.CostSummaryVO;
import org.sky.scientific.pojo.vo.XmAssetCostSummary;
import org.sky.scientific.service.IAssetService;
import org.sky.scientific.service.IXmDirectCostService;
import org.sky.system.cache.DictCache;
import org.sky.system.pojo.entity.Dict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 资产表 服务实现类
 *
 * @author Kd
 * @since 2025-06-29
 */
@Slf4j
@Service
@AllArgsConstructor
public class AssetServiceImpl extends BaseServiceImpl<AssetMapper, AssetEntity> implements IAssetService {

	private final IXmDirectCostService directCostService;
	private final XmAssetHoursMapper hoursMapper;
	private final XmFixedAssetMapper fixedAssetMapper;
	private final XmIntangibleAssetMapper intangibleAssetMapper;
	private final YsWxzctxfyMapper ysWxzctxfyMapper;
	private final YsZjfyycqdtfyMapper ysZjfyycqdtfyMapper;

	@Override
	public IPage<AssetVO> selectAssetPage(IPage<AssetVO> page, AssetDTO dto) {
		if (Func.isNotBlank(dto.getZclb())) {
			dto.setZclbList(Arrays.asList(dto.getZclb().split(",")));
		}
		return page.setRecords(baseMapper.selectAssetPage(page, dto));
	}

	@Override
	public boolean saveAsset(AssetEntity asset) {
		if (StringUtil.isBlank(asset.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		LambdaQueryWrapper<AssetEntity> qw = Wrappers.<AssetEntity>lambdaQuery().eq(AssetEntity::getZcbm, asset.getZcbm()).eq(AssetEntity::getYearAndMonth, asset.getYearAndMonth());
		if (this.baseMapper.selectCount(qw) > 0) {
			throw new ServiceException("资产【" + asset.getZcbm() + "】已存在");
		}

		validateAsset(asset);

		asset.setStatus((asset.getSysm() - asset.getYsysm() <= 0) ? AssetStatusEnum.已足额折旧.getCode() : AssetStatusEnum.正常.getCode());
		return this.save(asset);
	}


	@SneakyThrows
	@Override
	@Transactional
	public void importAsset(MultipartFile file, String yearAndMonth) {
		AssetImportListener listener = new AssetImportListener();
		EasyExcel.read(new BufferedInputStream(file.getInputStream()))
			.registerReadListener(listener)
			.sheet(0)
			.headRowNumber(2) // 重要：设置表头行数(0-based)
			.doRead();
		List<Object> data = listener.getDataList();

		List<AssetEntity> dbAssetList = baseMapper.selectList(Wrappers.<AssetEntity>lambdaQuery().eq(AssetEntity::getYearAndMonth, yearAndMonth));
		List<String> idenfifierList = new ArrayList<>(dbAssetList.stream().map(AssetEntity::getZcbm).toList());

		for (Object excel : data) {
			AssetExcel excel1 = (AssetExcel) excel;
			AssetEntity asset = Objects.requireNonNull(BeanUtil.copyProperties(excel, AssetDTO.class));
 			if (idenfifierList.contains(asset.getZcbm())) {
				throw new ServiceException("资产【" + asset.getZcbm() + "】已存在，导入失败！");
			}
			idenfifierList.add(asset.getZcbm());
			asset.setYearAndMonth(yearAndMonth);

			validateAsset(asset);

			Optional<AssetStatusEnum> optional = Arrays.stream(AssetStatusEnum.values()).filter(temp -> temp.getName().equalsIgnoreCase(excel1.getStatusName())).findFirst();
			if (optional.isEmpty()) {
				throw new ServiceException("状态错误，请重新选择");
			}
			asset.setStatus(optional.get().getCode());

			this.save(asset);
		}
	}

	private void validateAsset(AssetEntity asset) {
		List<String> zclbList = DictCache.getList("zclb").stream().map(Dict::getDictValue).toList();
		List<String> ytList = DictCache.getList("zcyt").stream().map(Dict::getDictValue).toList();
		if (Func.isNotEmpty(zclbList) && !zclbList.contains(asset.getZclb())) {
			throw new ServiceException("资产类别错误，请重新选择");
		}
		if (Func.isNotEmpty(ytList) && !ytList.contains(asset.getYt())) {
			throw new ServiceException("用途错误，请重新选择");
		}
		if (!isFixedAsset(asset.getZclb())) {
			asset.setGl("/");
		}
		asset.setYsysm(getYsysm(asset.getYearAndMonth(), asset.getKssj(), asset.getZclb()));
		if (Func.notNull(asset.getJcz())) {
			asset.setJcz(Math.min(asset.getJcz(), 1.0));
		}
		Date selectDate = DateUtil.parse(asset.getYearAndMonth(), DateUtil.PATTERN_YYYYMM);

		if ((selectDate.compareTo(asset.getKssj()) < 0 && !cn.hutool.core.date.DateUtil.isSameMonth(selectDate, asset.getKssj()))) {
			throw new ServiceException("开始时间可以添加当前或是前面的时间，不能添加未来的时间");
		}
	}

	@Transactional
	@Override
	public boolean fetchLastMonthData(AssetDTO zc) {
		AtomicInteger count = new AtomicInteger(0);
		//查询上个月的数据
		//得到上个月的年月
		String lastDate = DateUtil.format(DateUtil.minusMonths(DateUtil.parse(zc.getYearAndMonth(), DateUtil.PATTERN_YYYYMM), 1), DateUtil.PATTERN_YYYYMM);
		LambdaQueryWrapper<AssetEntity> queryWrapper = Wrappers.<AssetEntity>lambdaQuery().eq(AssetEntity::getYearAndMonth, lastDate);
		List<AssetEntity> lastMonthDataList = this.baseMapper.selectList(queryWrapper);
		if (CollectionUtil.isEmpty(lastMonthDataList)) {
			throw new ServiceException("上个月资产数据为空");
		}
		//与本月数据对比，去重后保存至数据库
		for (AssetEntity temp : lastMonthDataList) {
			LambdaQueryWrapper<AssetEntity> qw = Wrappers.<AssetEntity>lambdaQuery().eq(AssetEntity::getZcbm, temp.getZcbm()).eq(AssetEntity::getYearAndMonth, zc.getYearAndMonth());
			if (this.baseMapper.selectCount(qw) > 0) {
 				continue;
			}

			if (Arrays.asList(AssetStatusEnum.停用.getCode(), AssetStatusEnum.已足额折旧.getCode()).contains(temp.getStatus())) {
				continue;
			}
			temp.setYearAndMonth(zc.getYearAndMonth());
			if (Func.equals(temp.getStatus(), AssetStatusEnum.正常.getCode())) {
				temp.setYsysm(getYsysm(temp.getYearAndMonth(), temp.getKssj(), temp.getZclb()));
				//使用寿命-已使用月份数=0时，即已足额折旧
				if (temp.getSysm() - temp.getYsysm() <= 0) {
					temp.setStatus(AssetStatusEnum.已足额折旧.getCode());
				}
			}
			temp.setId(null);
			if (this.save(temp)) {
				count.incrementAndGet();
			}
		}
		if (count.get() == 0) {
			throw new ServiceException("上个月无资产数据可读取");
		}
		return true;
	}

	@Override
	public List<AssetEntity> selectAssetList() {
		return baseMapper.selectAssetList();
	}

	@Override
	@Transactional
	public boolean physicalDeleteByIds(List<Long> ids, String yearAndMonth) {
		//删除说明
		//①　删除：如果此资产，在研发项目中，已使用情况下，不可以删除。系统提示：资产已被使用，无法删除！
		//②　如果此资产，无任何研发项目使用，可以在资产清单管理中，将此资产进行删除。
		//③　如果此资产，曾经被研发项目使用（可能研发项目后续不再使用此资产），这一类情况也不可以进行删除。
//		List<Long> list = baseMapper.checkAssetUsage(ids, yearAndMonth, SecureUtil.getTenantId());
//		if (Func.isNotEmpty(list)) {
//			throw new ServiceException("资产已被使用，无法删除！");
//		}

		for (Long assetId : ids) {
			AssetEntity dbAsset = baseMapper.selectById(assetId);
			canDeleteAsset(dbAsset, yearAndMonth);
			baseMapper.deleteAssesByZcbmAfterMonth(dbAsset.getZcbm(), yearAndMonth);
		}
		return true;
	}

	private void canDeleteAsset(AssetEntity asset, String yearAndMonth) {
		if (hoursMapper.countByZcbmAfterMonth(asset.getZcbm(), yearAndMonth) > 0) {
			throw new ServiceException("无法删除，每月仪器设备工时打卡中引用了【" + asset.getZcbm() + "】");
		}
		if (fixedAssetMapper.selectCount(Wrappers.<XmFixedAsset>lambdaQuery().eq(XmFixedAsset::getZcbm, asset.getZcbm()).ge(XmFixedAsset::getYearAndMonth, yearAndMonth)) > 0) {
			throw new ServiceException("无法删除，每月仪器设备明细/每月在用建筑物明细中引用了【" + asset.getZcbm() + "】");
		}
		if (intangibleAssetMapper.selectCount(Wrappers.<XmIntangibleAsset>lambdaQuery().eq(XmIntangibleAsset::getZcbm, asset.getZcbm()).ge(XmIntangibleAsset::getYearAndMonth, yearAndMonth)) > 0) {
			throw new ServiceException("无法删除，每月无形资产明细中引用了【" + asset.getZcbm() + "】");
		}
		if (ysWxzctxfyMapper.countByZcbmAfterMonth(asset.getZcbm(), yearAndMonth) > 0) {
			throw new ServiceException("无法删除，研发项目预算-无形资产摊销费用中引用了【" + asset.getZcbm() + "】");
		}
		if (ysZjfyycqdtfyMapper.countByZcbmAfterMonth(asset.getZcbm(), yearAndMonth) > 0) {
			throw new ServiceException("无法删除，研发项目预算-折旧费用与长期待摊费用中引用了【" + asset.getZcbm() + "】");
		}
	}

	@SneakyThrows
	@Override
	public void exportAsset(HttpServletResponse response, AssetDTO dto) {

		Query query = new Query().setCurrent(1).setSize(Integer.MAX_VALUE);
		List<AssetVO> list = this.selectAssetPage(Condition.getPage(query), dto).getRecords();

		AtomicInteger i = new AtomicInteger(1);
		list.forEach(temp -> {
			temp.setXh(i.getAndIncrement() + "");
			temp.setKssjStr(Func.notNull(temp.getKssj()) ? DateUtil.format(temp.getKssj(), DateUtil.PATTERN_DATE) : "");
			Arrays.stream(AssetStatusEnum.values()).anyMatch(assetStatusEnum -> assetStatusEnum.getCode() == temp.getStatus());
			AssetStatusEnum assetStatusEnum = Arrays.stream(AssetStatusEnum.values()).filter(o -> o.getCode() == temp.getStatus()).findFirst().orElse(AssetStatusEnum.正常);
			temp.setStatusStr(assetStatusEnum.getName());
		});

		InputStream templateFileName = this.getClass().getClassLoader().getResourceAsStream("export-template/基础资源管理/企业科研资产清单.xls");
		response.setContentType("application/vnd.ms-excel");
		response.setCharacterEncoding("utf-8");
		response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("企业科研资产清单.xls", Charsets.UTF_8));
		ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
			.withTemplate((templateFileName))
			.excelType(ExcelTypeEnum.XLS)
			.build();

		WriteSheet writeSheet = EasyExcel.writerSheet().build();
		//设置list集合数据
		FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
		excelWriter.fill(list, fillConfig, writeSheet);
		excelWriter.finish();
		if (templateFileName != null) {
			templateFileName.close();
		}
	}

	@Override
	public List<CostSummaryVO> costSummary(CostSummaryDTO dto) {
		if (Func.isBlank(dto.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}

		String startYearMonth = dto.getYearAndMonth().substring(0, 4) + "01";
		dto.setStartYearMonth(startYearMonth);
		dto.setMonthCount(Integer.parseInt(dto.getYearAndMonth().substring(4)));
		dto.setTenantId(SecureUtil.getTenantId());
		List<CostSummaryVO> list = baseMapper.costSummary(dto);
		for (CostSummaryVO vo : list) {
			vo.setWwfyAdjust(vo.getWwfy().multiply(new BigDecimal("0.8")).setScale(2, RoundingMode.HALF_UP));
			vo.setTotal(vo.getRyrgfy().add(vo.getZjtrfy()).add(vo.getZjfyycqdtfy()).add(vo.getSjfy()).add(vo.getWxzctxfy()).add(vo.getZbtsfyysyfy()).add(vo.getQtfy()).add(vo.getWwfyAdjust()).setScale(2, RoundingMode.HALF_UP));

		}
		return list;
	}

	@SneakyThrows
	@Override
	public void exportCostSummary(HttpServletResponse response, CostSummaryDTO dto) {
		List<CostSummaryVO> list = this.costSummary(dto);
		AtomicInteger index = new AtomicInteger(1);
		list.forEach(temp -> {
			temp.setXh(index.getAndIncrement() + "");
		});

		InputStream templateFileName = this.getClass().getClassLoader().getResourceAsStream("export-template/研发费用管理/研发费用汇总表P0040.xls");
		response.setContentType("application/vnd.ms-excel");
		response.setCharacterEncoding("utf-8");
		response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("研发费用汇总表.xls", Charsets.UTF_8));
		ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
			.withTemplate((templateFileName))
			.excelType(ExcelTypeEnum.XLS)
			.build();

		WriteSheet writeSheet = EasyExcel.writerSheet().build();
		FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
		//设置list集合数据
		excelWriter.fill(list, fillConfig, writeSheet);
		Map<String, Object> map = new HashMap<>();
		map.put("ryrgfySum", list.stream().map(CostSummaryVO::getRyrgfy).reduce(BigDecimal.ZERO, BigDecimal::add));
		map.put("zjtrfySum", list.stream().map(CostSummaryVO::getZjtrfy).reduce(BigDecimal.ZERO, BigDecimal::add));
		map.put("zjfyycqdtfySum", list.stream().map(CostSummaryVO::getZjfyycqdtfy).reduce(BigDecimal.ZERO, BigDecimal::add));
		map.put("sjfySum", list.stream().map(CostSummaryVO::getSjfy).reduce(BigDecimal.ZERO, BigDecimal::add));
		map.put("wxzctxfySum", list.stream().map(CostSummaryVO::getWxzctxfy).reduce(BigDecimal.ZERO, BigDecimal::add));
		map.put("zbtsfyysyfySum", list.stream().map(CostSummaryVO::getZbtsfyysyfy).reduce(BigDecimal.ZERO, BigDecimal::add));
		map.put("qtfySum", list.stream().map(CostSummaryVO::getQtfy).reduce(BigDecimal.ZERO, BigDecimal::add));
		map.put("wwfySum", list.stream().map(CostSummaryVO::getWwfy).reduce(BigDecimal.ZERO, BigDecimal::add));
		map.put("wwfyAdjustSum", list.stream().map(CostSummaryVO::getWwfyAdjust).reduce(BigDecimal.ZERO, BigDecimal::add));
		map.put("totalSum", list.stream().map(CostSummaryVO::getTotal).reduce(BigDecimal.ZERO, BigDecimal::add));
		map.put("year", dto.getYearAndMonth().substring(0, 4));
		map.put("month", dto.getYearAndMonth().substring(4));
		excelWriter.fill(map, writeSheet);
		excelWriter.finish();
		if (templateFileName != null) {
			templateFileName.close();
		}
	}

	@Override
	@Transactional
	public boolean updateAsset(AssetEntity asset) {
		if (Func.isNull(asset.getId())) {
			throw new ServiceException("参数id不能为空");
		}
		LambdaQueryWrapper<AssetEntity> qw = Wrappers.<AssetEntity>lambdaQuery().eq(AssetEntity::getZcbm, asset.getZcbm()).eq(AssetEntity::getYearAndMonth, asset.getYearAndMonth());
		AssetEntity dbAsset = this.getOne(qw);
		if (Func.isNull(dbAsset)) {
			throw new ServiceException("资产不存在");
		}
		if (Func.equals(dbAsset.getZcbm(), asset.getZcbm()) && !Func.equals(dbAsset.getId(), asset.getId())) {
			throw new ServiceException("资产【" + asset.getZcbm() + "】已存在");
		}

		if (!isFixedAsset(asset.getZclb())) {
			asset.setGl("/");
		}
		return this.updateOtherMonthAsset(asset);
	}

	private Integer getYsysm(String yearAndMonth, Date kssj, String zclb) {
		Date month = DateUtil.parse(yearAndMonth, DateUtil.PATTERN_YYYYMM);
		long ysysm = 0;
		if (month.compareTo(kssj) >= 0 || (cn.hutool.core.date.DateUtil.isSameMonth(month, kssj) && new Date().compareTo(kssj) >= 0)) {
			//2025年01月-2024年5月 = 8个月
			ysysm = cn.hutool.core.date.DateUtil.betweenMonth(month, kssj, true);
			if (!Func.equals("仪器设备", zclb)) {
				ysysm++;
			}
		}
		return (int) ysysm;
	}

	public boolean updateOtherMonthAsset(AssetEntity asset) {
		LambdaQueryWrapper<AssetEntity> queryWrapper = Wrappers.<AssetEntity>lambdaQuery()
			.eq(AssetEntity::getZcbm, asset.getZcbm()).ge(AssetEntity::getYearAndMonth, asset.getYearAndMonth());
		List<AssetEntity> list = baseMapper.selectList(queryWrapper);
		for (AssetEntity entity : list) {

			AssetEntity updateEntity = new AssetEntity();
			cn.hutool.core.bean.BeanUtil.copyProperties(asset, updateEntity);
			updateEntity.setId(null);
			updateEntity.setYearAndMonth(null);
			updateEntity.setTenantId(null);
			updateEntity.setZgs(null);

			if (Func.equals(entity.getStatus(), AssetStatusEnum.正常.getCode()) || Func.equals(entity.getStatus(), AssetStatusEnum.停用.getCode())) {

				updateEntity.setYsysm(getYsysm(entity.getYearAndMonth(), asset.getKssj(), entity.getZclb()));
				//使用寿命-已使用月份数=0时，即已足额折旧
				if (updateEntity.getSysm() - updateEntity.getYsysm() <= 0) {
					updateEntity.setStatus(AssetStatusEnum.已足额折旧.getCode());
					updateEntity.setYsysm(Math.min(asset.getSysm(), updateEntity.getYsysm()));
				}
			}

			LambdaUpdateWrapper<AssetEntity> updateWrapper = Wrappers.<AssetEntity>lambdaUpdate().eq(AssetEntity::getZcbm, entity.getZcbm()).eq(AssetEntity::getYearAndMonth, entity.getYearAndMonth());
			baseMapper.update(updateEntity, updateWrapper);
		}
		return true;
	}

	@Override
	public boolean updateStatus(AssetEntity asset) {
		if (asset.getId() == null) {
			throw new ServiceException("参数assetId不能为空");
		}
		if (Func.isNull(asset.getStatus())) {
			throw new ServiceException("参数status不能为空");
		}
		AssetEntity dbAsset = baseMapper.selectById(asset.getId());
		if (Func.isNull(dbAsset)) {
			throw new ServiceException("资产不存在");
		}

		if (asset.getStatus() == AssetStatusEnum.改造.getCode() && !isFixedAsset(dbAsset.getZclb())) {
			throw new ServiceException("只有固定资产才能改造");
		}
//		String name = AssetStatusEnum.改造.name();
//		①　正常状态：表示正常使用中；正常折旧，已使用寿命/月数累加。可进行“改造”、“停用”、“资产处置”。
//		②　停用状态：表示停止使用状态；虽然停用，但是正常折旧，已使用寿命/月数继续累加。停用后，可点击“恢复”恢复为正常状态。可进行“改造”、“资产处置”。
//		③　改造状态：表示改造中，改造期已使用寿命/月数/折旧为“全部暂停”状态。改造完成，需点击“恢复按钮”，恢复时需对资产内容进行修改完成。恢复为正常状态。
//		④　已足额折扣状态：按照使用寿命，全部折旧完毕；不可以进行操作；后续不再提折旧。不再使用，不再显示。
//		⑤　资产处理状态：表示资产已被转让、报废、捐赠或其他处理等；不可以进行操作；后续不属于企业 ，不再计提折旧，不能再使用。
//		⑥　/：表示无操作
//		⑦　注意，资产总表涉及资产明细统计，需进行相应的处理
		if (Func.equals(dbAsset.getStatus(), AssetStatusEnum.已足额折旧.getCode())) {
			throw new ServiceException("该资产已足额折旧");
		}
		if (Func.equals(dbAsset.getStatus(), AssetStatusEnum.资产处置.getCode())) {
			throw new ServiceException("该资产已处置");
		}
//		if (Func.equals(AssetStatusEnum.正常.getCode(), dbAsset.getStatus())) {
//			//①　正常状态：表示正常使用中；正常折旧，已使用寿命/月数累加。可进行“改造”、“停用”、“资产处置”。
//			if (!Arrays.asList(AssetStatusEnum.改造.getCode(), AssetStatusEnum.停用.getCode(), AssetStatusEnum.资产处置.getCode()).contains(asset.getStatus())) {
//				throw new ServiceException("状态为正常的资产，可进行改造、停用、资产处置操作");
//			}
//		} else if (Func.equals(AssetStatusEnum.停用.getCode(), dbAsset.getStatus())) {
//			//②　停用状态：表示停止使用状态；虽然停用，但是正常折旧，已使用寿命/月数继续累加。停用后，可点击“恢复”恢复为正常状态。可进行“改造”、“资产处置”。
//			if (!Arrays.asList(AssetStatusEnum.改造.getCode(), AssetStatusEnum.资产处置.getCode(), AssetStatusEnum.正常.getCode()).contains(asset.getStatus())) {
//				throw new ServiceException("状态为停用的资产，可进行改造、恢复、资产处置操作");
//			}
//		} else if (Func.equals(AssetStatusEnum.改造.getCode(), dbAsset.getStatus())) {
//			//改造状态：表示改造中，改造期已使用寿命/月数/折旧为“全部暂停”状态。改造完成，需点击“恢复按钮”，恢复时需对资产内容进行修改完成。恢复为正常状态。
//			if (!List.of(AssetStatusEnum.正常.getCode()).contains(asset.getStatus())) {
//				throw new ServiceException("状态为改造的资产，可进行恢复操作");
//			}
//		}

//		return baseMapper.updateStatus(asset.getId(), asset.getStatus()) == 1;
		return updateOtherMonthAsset(asset);
	}

	@Override
	public boolean recover(AssetEntity asset) {

		if (Func.isNull(asset.getId())) {
			throw new ServiceException("参数id不能为空");
		}
		asset.setStatus(AssetStatusEnum.正常.getCode());
		return updateOtherMonthAsset(asset);
	}

	@Override
	public IPage<XmAssetCostSummary> zjCqdtWxzctxFyHzb(IPage<XmAssetCostSummary> page, XmAssetCostQueryParam dto) {
		if (Func.isBlank(dto.getYearAndMonth())) {
			throw new ServiceException("参数yearAndMonth不能为空");
		}
		List<XmAssetCostSummary> list = null;
		dto.setTenantId(SecureUtil.getTenantId());
		if (dto.getYearAndMonth().length() == 6) {
			list = baseMapper.zjCqdtWxzctxFyHzbByYearAndMonth(page, dto);
		} else if (dto.getYearAndMonth().length() == 4) {
			list = baseMapper.zjCqdtWxzctxFyHzbByYear(page, dto);
		} else {
			throw new ServiceException("参数yearAndMonth格式错误，yyyyMM或yyyy");
		}

		for (XmAssetCostSummary vo : list) {
			vo.setTotal(vo.getYqsbzjfy().add(vo.getFwzjfy()).add(vo.getCqdtfy()).add(vo.getWxzcdtfy()));
		}
		return page.setRecords(list);
	}

	@SneakyThrows
	@Override
	public void exportZjCqdtWxzctxFyHzb(HttpServletResponse response, XmAssetCostQueryParam dto) {
		List<XmAssetCostSummary> list = zjCqdtWxzctxFyHzb(Condition.getPage(new Query().setCurrent(1).setSize(Integer.MAX_VALUE)), dto).getRecords();
		AtomicInteger index = new AtomicInteger(1);

		list.forEach(temp -> {
			temp.setXh(index.getAndIncrement() + "");
		});
		InputStream templateFileName = this.getClass().getClassLoader().getResourceAsStream("export-template/研发费用管理/折旧费用长期待摊费用无形资产摊销费用/研发费用管理-折旧费用、长期待摊费用、无形资产摊销费用汇总表.xls");
		response.setContentType("application/vnd.ms-excel");
		response.setCharacterEncoding("utf-8");
		response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("研发费用管理-折旧费用、长期待摊费用、无形资产摊销费用汇总表.xls", Charsets.UTF_8));
		ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
			.withTemplate((templateFileName))
			.excelType(ExcelTypeEnum.XLS)
			.build();

		WriteSheet writeSheet = EasyExcel.writerSheet().build();
		FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
		//设置list集合数据
		excelWriter.fill(list, fillConfig, writeSheet);
		Map<String, Object> map = new HashMap<>();

		String yearAndMonth = dto.getYearAndMonth();
		map.put("yearAndMonth", yearAndMonth.length() == 6 ? yearAndMonth.substring(0, 4) + "年" + yearAndMonth.substring(4) + "月" : yearAndMonth + "年");
		map.put("yqsbzjfySum", list.stream().map(XmAssetCostSummary::getYqsbzjfy).reduce(BigDecimal.ZERO, BigDecimal::add));
		map.put("fwzjfySum", list.stream().map(XmAssetCostSummary::getFwzjfy).reduce(BigDecimal.ZERO, BigDecimal::add));
		map.put("cqdtfySum", list.stream().map(XmAssetCostSummary::getCqdtfy).reduce(BigDecimal.ZERO, BigDecimal::add));
		map.put("wxzcdtfySum", list.stream().map(XmAssetCostSummary::getWxzcdtfy).reduce(BigDecimal.ZERO, BigDecimal::add));
		map.put("totalSum", list.stream().map(XmAssetCostSummary::getTotal).reduce(BigDecimal.ZERO, BigDecimal::add));
		excelWriter.fill(map, writeSheet);
		excelWriter.finish();
		if (templateFileName != null) {
			templateFileName.close();
		}
	}

	public static boolean isFixedAsset(String zclb) {
		return List.of("仪器设备", "房屋建筑物").contains(zclb);
	}
}
