/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the yifu4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.yifu.cloud.plus.v1.yifu.salary.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.ekp.vo.EkpSocialPushInfoVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.EmpIdCardAndDeptVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.EmpStatusVo;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TSettleDomainSelectVo;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.DateUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprArchivesProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprInsurancesProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprSocialProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.EkpDaprUtils;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.HttpDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.ekp.util.EkpSalaryUtil;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpPushFundParam;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpPushSocialParam;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpSalaryParam;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpSalaryParamVo;
import com.yifu.cloud.plus.v1.yifu.salary.entity.*;
import com.yifu.cloud.plus.v1.yifu.salary.mapper.TSalaryStandardMapper;
import com.yifu.cloud.plus.v1.yifu.salary.service.*;
import com.yifu.cloud.plus.v1.yifu.salary.util.DoJointSalaryAsyncTask;
import com.yifu.cloud.plus.v1.yifu.salary.util.SalaryConstants;
import com.yifu.cloud.plus.v1.yifu.salary.vo.*;
import com.yifu.cloud.plus.v1.yifu.social.entity.TSendEkpError;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 标准薪酬工资表
 *
 * @author hgw
 * @date 2022-08-05 11:40:14
 */
@Log4j2
@Service
@AllArgsConstructor
@EnableConfigurationProperties({DaprArchivesProperties.class, DaprSocialProperties.class, DaprInsurancesProperties.class})
public class TSalaryStandardServiceImpl extends ServiceImpl<TSalaryStandardMapper, TSalaryStandard> implements TSalaryStandardService {

	private final TApprovalRecordService approvalRecordService;
	private final TSalaryAccountService salaryAccountService;
	private final TSalaryAccountItemService salaryAccountItemService;
	private final MSalaryEstimateService mSalaryEstimateService;
	private final DaprSocialProperties socialProperties;
	private final DaprArchivesProperties archivesProperties;

	private final EkpSalaryUtil ekpSalaryUtil;
	private final TApprovalRecordService auditLogService;
	private final TSalaryStandardIssueResService issueResService;
	@Lazy
	private final DoJointSalaryAsyncTask doSalaryAsync;

	private final EkpDaprUtils ekpDaprUtil;

	private final DaprInsurancesProperties insurancesProperties;

	private final TInsuranceUnpurchasePersonService tInsuranceUnpurchasePersonService;

	private final TInsuranceUnpurchasePersonSalaryService tInsuranceUnpurchasePersonSalaryService;


	/**
	 * 标准薪酬工资表简单分页查询
	 *
	 * @param tSalaryStandard 标准薪酬工资表
	 * @return
	 */
	@Override
	public IPage<TSalaryStandard> getTSalaryStandardPageApply(Page<TSalaryStandard> page, TSalaryStandardSearchVo tSalaryStandard) {
		return baseMapper.getTSalaryStandardPageApply(page, tSalaryStandard);
	}

	/**
	 * 标准薪酬工资表简单分页查询
	 *
	 * @param tSalaryStandard 标准薪酬工资表
	 * @return
	 */
	@Override
	public IPage<TSalaryStandard> getTSalaryStandardPage(Page<TSalaryStandard> page, TSalaryStandardSearchVo tSalaryStandard) {
		return baseMapper.getTSalaryStandardPage(page, tSalaryStandard);
	}

	@Override
	public IPage<TSalaryStandardUnprojectVo> getUnDeptSalaryList(Page<TSalaryStandardUnprojectVo> page, String deptNo) {
		List<TSalaryStandardUnprojectVo> voList = baseMapper.getSalaryEmpUnprojectList(deptNo);
		String salaryId;
		if (null != voList && !voList.isEmpty()) {
			salaryId = voList.get(0).getSalaryId();
		} else {
			return null;
		}
		//找到不在项人员的身份证信息
		R<TSalaryStandardSelectViewVo> sdr = HttpDaprUtil.invokeMethodPost(archivesProperties.getAppUrl(), archivesProperties.getAppId()
				, "/temployeeproject/inner/getUnProjectEmpList", voList, TSalaryStandardSelectViewVo.class, SecurityConstants.FROM_IN);
		// 结算主体
		TSalaryStandardSelectViewVo viewVo;
		if (sdr != null && sdr.getData() != null) {
			viewVo = sdr.getData();
		} else {
			return null;
		}
		List<TSalaryStandardUnprojectVo> unEmpList = viewVo.getSalaryList();
		if (null != unEmpList && !unEmpList.isEmpty()) {
			List<String> idCardList = unEmpList.stream().map(TSalaryStandardUnprojectVo::getEmpIdcard).collect(Collectors.toList());
			return baseMapper.getSalaryStandardUnprojectList(page,salaryId, idCardList);
		}
		return null;
	}

	/**
	 * 标准薪酬工资表批量导出
	 *
	 * @return
	 */
	@Override
	public void listExport(HttpServletResponse response, TSalaryStandardSearchVo searchVo) {
		String fileName = "项目薪酬查询批量导出" + DateUtil.getThisTime() + CommonConstants.XLSX;
		//获取要导出的列表
		List<TSalaryStandardExportVo> list = new ArrayList<>();
		long count = noPageCountDiy(searchVo);
		ServletOutputStream out = null;
		try {
			out = response.getOutputStream();
			response.setContentType(CommonConstants.MULTIPART_FORM_DATA);
			response.setCharacterEncoding("utf-8");
			response.setHeader(CommonConstants.CONTENT_DISPOSITION, CommonConstants.ATTACHMENT_FILENAME + URLEncoder.encode(fileName, "UTF-8"));
			// 这里 需要指定写用哪个class去写，然后写到第一个sheet，然后文件流会自动关闭
			ExcelWriter excelWriter = EasyExcelFactory.write(out, TSalaryStandardExportVo.class).build();
			int index = 0;
			WriteSheet writeSheet;
			if (count > CommonConstants.ZERO_INT) {
				for (int i = 0; i <= count; i += CommonConstants.EXCEL_EXPORT_LIMIT_3) {
					// 获取实际记录
					searchVo.setLimitStart(i);
					searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT_3);
					list = noPageDiy(searchVo);
					if (Common.isNotNull(list)) {
						writeSheet = EasyExcelFactory.writerSheet("项目薪酬表" + index).build();
						excelWriter.write(list, writeSheet);
						index++;
						list.clear();
					}
				}
			} else {
				writeSheet = EasyExcelFactory.writerSheet("项目薪酬表" + index).build();
				excelWriter.write(list, writeSheet);
			}
			if (Common.isNotNull(list)) {
				list.clear();
			}
			out.flush();
			excelWriter.finish();
		} catch (Exception e) {
			log.error("执行异常", e);
		} finally {
			try {
				if (null != out) {
					out.close();
				}
			} catch (IOException e) {
				log.error("执行异常", e);
			}
		}
	}

	@Override
	public List<TSalaryStandardExportVo> noPageDiy(TSalaryStandardSearchVo searchVo) {
		return baseMapper.getSalaryStandardExport(searchVo, Common.getList(searchVo.getIds()));
	}

	private int noPageCountDiy(TSalaryStandardSearchVo searchVo) {
		return baseMapper.getSalaryStandardExportCount(searchVo, Common.getList(searchVo.getIds()));
	}

	@Override
	public IPage<TSalaryStandard> getTSalaryStandardAuditPage(Page<TSalaryStandard> page, TSalaryStandardSearchVo tSalaryStandard) {
		return baseMapper.getTSalaryStandardAuditPage(page, tSalaryStandard);
	}

	@Override
	public R<String> salaryStandardAudit(String auditFlag, String auditRemark, String id) {
		YifuUser user = SecurityUtils.getUser();
		TSalaryStandard tSalaryStandard = baseMapper.selectById(id);
		if (Common.isNotNull(tSalaryStandard)) {
			//新增流程进展明细
			TApprovalRecord tApprovalRecord = new TApprovalRecord();

			if (CommonConstants.ZERO_STRING.equals(auditFlag)) {

				tSalaryStandard.setStatus(CommonConstants.TWO_INT);
				tApprovalRecord.setApprovalResult(CommonConstants.ZERO_STRING);
				tApprovalRecord.setNodeId("审核通过");

				R<TSettleDomainSelectVo> sdr = HttpDaprUtil.invokeMethodPost(archivesProperties.getAppUrl(), archivesProperties.getAppId()
						, "/tsettledomain/inner/getSettleDomainVoById", tSalaryStandard.getDeptId()
						, TSettleDomainSelectVo.class, SecurityConstants.FROM_IN);
				// 结算主体
				TSettleDomainSelectVo dept;
				if (sdr != null && sdr.getData() != null) {
					dept = sdr.getData();
				} else {
					return R.failed("获取项目信息失败，请联管理员！");
				}
				List<TSalaryAccount> salaryAccountList = salaryAccountService.getListByIncome(id);
				if (salaryAccountList != null && !salaryAccountList.isEmpty()) {
					// 将审核状态变为中间态
					tSalaryStandard.setStatus(CommonConstants.dingleDigitIntArray[11]);
					tSalaryStandard.setIncomeStartTime(new Date());
					baseMapper.updateById(tSalaryStandard);
					// 异步-收入相关
					doSalaryAsync.doIncomeDetail(dept, salaryAccountList, id, tSalaryStandard);
				}
			} else {
				tSalaryStandard.setStatus(CommonConstants.FIVE_INT);
				tApprovalRecord.setApprovalResult(CommonConstants.ONE_STRING);
				tApprovalRecord.setNodeId("审核不通过");
			}
			if (Common.isNotNull(auditRemark)) {
				tSalaryStandard.setAuditRemark(auditRemark);
				tApprovalRecord.setApprovalOpinion(auditRemark);
			}
			tSalaryStandard.setAuditUser(user.getId());
			tSalaryStandard.setAuditTime(DateUtil.getCurrentDateTime());
			baseMapper.updateById(tSalaryStandard);

			tApprovalRecord.setSalaryId(tSalaryStandard.getId());
			tApprovalRecord.setApprovalMan(user.getId());
			tApprovalRecord.setApprovalManName(user.getNickname());
			tApprovalRecord.setApprovalTime(DateUtil.getCurrentDateTime());
			approvalRecordService.save(tApprovalRecord);
		}
		return R.ok();

	}

	@Override
	public R<String> doIncome(TSalaryStandard tSalaryStandard) {
		if (Common.isNotNull(tSalaryStandard)) {
			R<TSettleDomainSelectVo> sdr = HttpDaprUtil.invokeMethodPost(archivesProperties.getAppUrl(), archivesProperties.getAppId()
					, "/tsettledomain/inner/getSettleDomainVoById", tSalaryStandard.getDeptId()
					, TSettleDomainSelectVo.class, SecurityConstants.FROM_IN);
			// 结算主体
			TSettleDomainSelectVo dept;
			if (sdr != null && sdr.getData() != null) {
				dept = sdr.getData();
			} else {
				return R.failed("获取项目信息失败，请联管理员！");
			}
			List<TSalaryAccount> salaryAccountList = salaryAccountService.getListByIncome(tSalaryStandard.getId());
			if (salaryAccountList != null && !salaryAccountList.isEmpty()) {
				// 异步-收入相关
				doSalaryAsync.doIncomeDetail(dept, salaryAccountList, tSalaryStandard.getId(), tSalaryStandard);
			}
		}
		return R.ok();
	}

	/**
	 * @Description: 删除
	 * @Author: hgw
	 * @Date: 2022/9/2 17:16
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	@Override
	public R<String> deleteSalaryById(String id) {
		if (id != null) {
			TSalaryStandard sf = this.getById(id);
			if (sf != null && Common.isNotNull(sf.getId())) {
				if (sf.getStatus() != null && !SalaryConstants.AUDIT_STATUS[0].equals(sf.getStatus())
						&& !SalaryConstants.AUDIT_STATUS[5].equals(sf.getStatus())
						&& !SalaryConstants.AUDIT_STATUS[6].equals(sf.getStatus())
						&& !SalaryConstants.AUDIT_STATUS[7].equals(sf.getStatus())) {
					return R.failed("状态为：【" + SalaryConstants.AUDIT_STATUS_STRING[sf.getStatus()] + "】，不可删除");
				}
			} else {
				return R.failed("删除失败：未找到工资表！");
			}
			YifuUser user = SecurityUtils.getUser();
			if (null == user || null == user.getId()) {
				return R.failed("删除工资表失败-获取登录人信息为空");
			}
			//查询结算单：T_SETTLEMENTH_FORM
			if (sf.getType() == null || sf.getType() != CommonConstants.ONE_INT) {
				//4：删除报账
				TSalaryAccount querySalaryAccountEntity = new TSalaryAccount();
				querySalaryAccountEntity.setSalaryFormId(id);
				QueryWrapper<TSalaryAccount> querySalaryAccountWrapper = new QueryWrapper<>();
				querySalaryAccountWrapper.setEntity(querySalaryAccountEntity);
				List<TSalaryAccount> salaryAccountList = salaryAccountService.list(querySalaryAccountWrapper);
				if (salaryAccountList != null && salaryAccountList.size() > CommonConstants.ZERO_INT) {
					for (TSalaryAccount entity : salaryAccountList) {
						entity.setDeleteFlag(SalaryConstants.DELETED);
					}
					salaryAccountService.updateBatchById(salaryAccountList);
					//5：更新预估库结算标识为0
					MSalaryEstimate salaryEstimate = new MSalaryEstimate();
					salaryEstimate.setSalaryId(id);
					salaryEstimate.setIsSocial(SalaryConstants.IS_SOCIAL_ZERO);
					salaryEstimate.setType(CommonConstants.ZERO_INT);
					QueryWrapper<MSalaryEstimate> salaryEstimateQueryWrapper = new QueryWrapper<>();
					salaryEstimateQueryWrapper.setEntity(salaryEstimate);
					//缴费库社保
					List<MSalaryEstimate> socialList = mSalaryEstimateService.list(salaryEstimateQueryWrapper);
					salaryEstimate.setIsSocial(SalaryConstants.IS_FUND_ONE);
					salaryEstimateQueryWrapper.setEntity(salaryEstimate);
					//缴费库公积金
					List<MSalaryEstimate> fundList = mSalaryEstimateService.list(salaryEstimateQueryWrapper);

					salaryEstimate.setType(CommonConstants.ONE_INT);
					salaryEstimateQueryWrapper.setEntity(salaryEstimate);
					//缴费库公积金
					List<MSalaryEstimate> forecastFundList = mSalaryEstimateService.list(salaryEstimateQueryWrapper);

					salaryEstimate.setIsSocial(SalaryConstants.IS_SOCIAL_ZERO);
					salaryEstimateQueryWrapper.setEntity(salaryEstimate);
					//缴费库公积金
					List<MSalaryEstimate> forecastSocialList = mSalaryEstimateService.list(salaryEstimateQueryWrapper);

					List<String> stringList;
					if (socialList != null && !socialList.isEmpty()) {
						stringList = new ArrayList<>();
						for (MSalaryEstimate s : socialList) {
							stringList.add(s.getEstimateId());
						}
						//更新社保状态为-待结算
						HttpDaprUtil.invokeMethodPost(socialProperties.getAppUrl(), socialProperties.getAppId()
								, "/tpaymentinfo/inner/updatePaymentSocialStatusToNoSettle", stringList, Integer.class, SecurityConstants.FROM_IN);
					}
					if (fundList != null && !fundList.isEmpty()) {
						stringList = new ArrayList<>();
						for (MSalaryEstimate s : fundList) {
							stringList.add(s.getEstimateId());
						}
						//更新公积金状态为-待结算
						HttpDaprUtil.invokeMethodPost(socialProperties.getAppUrl(), socialProperties.getAppId()
								, "/tpaymentinfo/inner/updatePaymentFundStatusToNoSettle", stringList, Integer.class, SecurityConstants.FROM_IN);
					}
					if (forecastSocialList != null && !forecastSocialList.isEmpty()) {
						stringList = new ArrayList<>();
						for (MSalaryEstimate s : forecastSocialList) {
							stringList.add(s.getEstimateId());
						}
						//更新社保状态为-待结算
						HttpDaprUtil.invokeMethodPost(socialProperties.getAppUrl(), socialProperties.getAppId()
								, "/tforecastlibrary/inner/updateForecastSocialStatusToNoSettle", stringList, Integer.class, SecurityConstants.FROM_IN);
					}
					if (forecastFundList != null && !forecastFundList.isEmpty()) {
						stringList = new ArrayList<>();
						for (MSalaryEstimate s : forecastFundList) {
							stringList.add(s.getEstimateId());
						}
						//更新公积金状态为-待结算
						HttpDaprUtil.invokeMethodPost(socialProperties.getAppUrl(), socialProperties.getAppId()
								, "/tforecastlibrary/inner/updateForecastFundStatusToNoSettle", stringList, Integer.class, SecurityConstants.FROM_IN);
					}

				}
			}
			// 删除不购买商险的关联项
			if (Common.isNotNull(sf.getIsCheckRisk()) && sf.getIsCheckRisk() == CommonConstants.ONE_INT) {
				tInsuranceUnpurchasePersonSalaryService.deletePersonSalaryBySalaryId(id);
				sf.setIsCheckRisk(CommonConstants.ZERO_INT);
			}
			//6：删除工资表
			sf.setDeleteUser(user.getNickname());
			sf.setDeleteDate(new Date());
			sf.setDeleteFlag(SalaryConstants.DELETED);
			this.updateById(sf);
			return R.ok("级联删除工资表成功");
		}
		return R.failed("id 不可为空");
	}

	/**
	 * @Description: 推送
	 * @Author: hgw
	 * @Date: 2022/9/2 17:16
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	@Override
	public R<String> doSend(String id) {
		TSalaryStandard s = this.getById(id);
		if (s == null) {
			return R.failed("未找到工资表");
		} else if (s.getStatus() == SalaryConstants.STATUS[2] || s.getStatus() == SalaryConstants.STATUS[10]) {
			// 2022-9-15 10:50:57需求变更：代扣的要组装预估明细给EKP，EKP自己找差额、变更实缴结算状态。
			//报账表
			List<EkpSalaryParamVo> ekpList = salaryAccountService.getEkpSalaryParamList(id);
			YifuUser user = SecurityUtils.getUser();
			if (user != null) {
				if (ekpList != null && !ekpList.isEmpty()) {
					boolean sendStatus = true;
					String sendBack;
					List<TSalaryAccount> accountList = new ArrayList<>();
					TSalaryAccount account;
					Date sendTime = new Date();
					String nowMonth = DateUtil.addMonth(0);
					EkpSalaryParam salaryParam;
					EmpIdCardAndDeptVo empIdCardAndDeptVo;
					List<EmpIdCardAndDeptVo> voList = new ArrayList<>();

					//社保推送集合
					List<EkpPushSocialParam> socialPushList = new ArrayList<>();
					//公积金推送集合
					List<EkpPushFundParam> fundPushList = new ArrayList<>();
					//薪资推送集合
					List<EkpSalaryParam> salaryPushList = new ArrayList<>();

					for (EkpSalaryParamVo sendParam : ekpList) {
						salaryParam = new EkpSalaryParam();
						BeanUtils.copyProperties(sendParam, salaryParam);
						// 转化报账表的参数
						account = new TSalaryAccount();
						account.setId(sendParam.getFd_3b10af838eab5c());

						// 社保
						if ((Common.isNotNull(sendParam.getFd_3bcd41d857b764())
								&& !CommonConstants.ZERO_STRING.equals(sendParam.getFd_3bcd41d857b764()))
								|| (Common.isNotNull(sendParam.getFd_3b16ce48a9735c())
								&& !CommonConstants.ZERO_STRING.equals(sendParam.getFd_3b16ce48a9735c()))) {
							doSendForecastSocialToEkp(sendParam, s, socialPushList);
						}
						// 公积金
						if ((Common.isNotNull(sendParam.getFd_3bcd41d77e4812())
								&& !CommonConstants.ZERO_STRING.equals(sendParam.getFd_3bcd41d77e4812()))
								|| (Common.isNotNull(sendParam.getFd_3b16ce4b7fc42a())
								&& !CommonConstants.ZERO_STRING.equals(sendParam.getFd_3b16ce4b7fc42a()))) {
							doSendForecastFundToEkp(sendParam, s, fundPushList);
						}
						salaryPushList.add(salaryParam);
						account.setSendTime(sendTime);
						account.setSendUser(user.getId());
						account.setSendUserName(user.getNickname());
						account.setSendStatus(CommonConstants.ONE_STRING);
						account.setSendMonth(nowMonth);
						empIdCardAndDeptVo = new EmpIdCardAndDeptVo();
						empIdCardAndDeptVo.setIdCard(sendParam.getFd_3adfedfb8f76d4());
						empIdCardAndDeptVo.setDeptNo(sendParam.getFd_3adfedf98ccba2());
						empIdCardAndDeptVo.setStatus(CommonConstants.ONE_STRING);
						voList.add(empIdCardAndDeptVo);
						accountList.add(account);
					}
					//社保预估明细数据推送
					if (!socialPushList.isEmpty()) {
						R<EkpSocialPushInfoVo> info = ekpDaprUtil.pushSocialInfoToEkp(socialPushList);
						if (Common.isEmpty(info) || Common.isEmpty(info.getData())) {
							TSendEkpError error = new TSendEkpError();
							error.setCreateTime(new Date());
							error.setCreateDay(DateUtil.getThisDay());
							error.setType(CommonConstants.ZERO_STRING);
							error.setCreateUserName(s.getCreateName());
							error.setLinkId(socialPushList.get(0).getFd_3b0afbe1f94a08());
							error.setTitle("薪资社保预估批量生成失败");
							error.setNums(CommonConstants.ONE_INT);
							HttpDaprUtil.invokeMethodPost(socialProperties.getAppUrl(), socialProperties.getAppId()
									, "/tsendekperror/inner/saveError", error, Boolean.class, SecurityConstants.FROM_IN);
						}
					}
					//公积金明细数据推送
					if (!fundPushList.isEmpty()) {
						R<EkpSocialPushInfoVo> info = ekpDaprUtil.pushFundInfoToEkp(fundPushList);
						if (Common.isEmpty(info) || Common.isEmpty(info.getData())) {
							TSendEkpError error = new TSendEkpError();
							error.setCreateTime(new Date());
							error.setCreateDay(DateUtil.getThisDay());
							error.setType(CommonConstants.ZERO_STRING);
							error.setCreateUserName(s.getCreateName());
							error.setLinkId(fundPushList.get(0).getFd_3b0afbaf10df2c());
							error.setTitle("薪资公积金批量生成失败");
							error.setNums(CommonConstants.ONE_INT);
							HttpDaprUtil.invokeMethodPost(socialProperties.getAppUrl(), socialProperties.getAppId()
									, "/tsendekperror/inner/saveError", error, Boolean.class, SecurityConstants.FROM_IN);
						}
					}
					//工资报账明细推送
					if (!salaryPushList.isEmpty()) {
						R<Boolean> info = ekpDaprUtil.pushSalaryInfoToEkp(salaryPushList);
						if (Common.isEmpty(info) || Common.isEmpty(info.getData())) {
							sendStatus = false;
							TSendEkpError error = new TSendEkpError();
							error.setCreateTime(new Date());
							error.setCreateDay(DateUtil.getThisDay());
							error.setType(CommonConstants.ONE_STRING);
							error.setCreateUserName(s.getCreateName());
							error.setLinkId(salaryPushList.get(0).getFd_3b10af838eab5c());
							error.setTitle("批量生成工资明细失败");
							error.setNums(CommonConstants.ONE_INT);
							HttpDaprUtil.invokeMethodPost(socialProperties.getAppUrl(), socialProperties.getAppId()
									, "/tsendekperror/inner/saveError", error, Boolean.class, SecurityConstants.FROM_IN);
						} else {
							salaryAccountService.updateBatchById(accountList);
							// 改变档案状态
							EmpStatusVo empStatusVo = new EmpStatusVo();
							empStatusVo.setEmpInfo(voList);
							HttpDaprUtil.invokeMethodPost(archivesProperties.getAppUrl(), archivesProperties.getAppId()
									, "/temployeeproject/inner/updateEmployeeSalaryStatus"
									, JSON.toJSONString(empStatusVo), Boolean.class, SecurityConstants.FROM_IN);
						}
					}

					if (sendStatus) {
						HashMap<String, Object> sendMap = this.setSendEkpStandardParam(s);
						// 推送主表信息
						String loginName = user.getUsername();
						sendBack = ekpSalaryUtil.sendStandardToEKP(loginName, JSON.toJSONString(sendMap));
						if (Common.isEmpty(sendBack) || sendBack.length() != 32) {
							sendBack = ekpSalaryUtil.sendStandardToEKP(loginName, JSON.toJSONString(sendMap));
						}
						s.setSendTime(new Date());
						s.setSendMonth(nowMonth);
						if (Common.isNotNull(sendBack) && sendBack.length() == 32) {
							s.setStatus(SalaryConstants.STATUS[3]);
						} else {
							s.setStatus(SalaryConstants.STATUS[10]);
							TSendEkpError error = new TSendEkpError();
							error.setCreateTime(new Date());
							error.setCreateDay(DateUtil.getThisDay());
							error.setType(CommonConstants.SIX_STRING);
							error.setCreateUserName(s.getCreateName());
							error.setLinkId(s.getId());
							error.setTitle(sendBack);
							error.setNums(CommonConstants.ONE_INT);
							HttpDaprUtil.invokeMethodPost(socialProperties.getAppUrl(), socialProperties.getAppId()
									, "/tsendekperror/inner/saveError", error, Boolean.class, SecurityConstants.FROM_IN);
						}
						this.updateById(s);
						// 添加流程进展明细
						this.saveRecordLog(s, user, CommonConstants.ZERO_STRING, "发送数字化平台-成功");
						return R.ok("发送成功！");
					} else {
						s.setStatus(SalaryConstants.STATUS[10]);
						this.updateById(s);
						// 添加流程进展明细
						this.saveRecordLog(s, user, CommonConstants.ONE_STRING, "发送数字化平台-失败");
						return R.ok("发送失败！");
					}
				} else {
					return R.ok("无数据可发送！");
				}
			} else {
				return R.failed("请登录！");
			}
		} else {
			return R.failed("请刷新后检查薪资表状态！");
		}
	}

	@Override
	public String testSendEkpList(String id) {
		TSalaryStandard s = this.getById(id);
		HashMap<String, Object> sendMap = this.setSendEkpStandardParam(s);
		YifuUser user = SecurityUtils.getUser();
		// 推送主表信息
		String loginName = user.getUsername();
		return ekpSalaryUtil.sendStandardToEKP(loginName, JSON.toJSONString(sendMap));
	}

	/**
	 * @param s
	 * @Description: 组建发送EKP的主表信息
	 * @Author: hgw
	 * @Date: 2023/1/12 15:07
	 * @return: java.util.HashMap<java.lang.String, java.lang.Object>
	 **/
	private HashMap<String, Object> setSendEkpStandardParam(TSalaryStandard s) {
		HashMap<String, Object> sendMap = new HashMap<>();
		//表单类型 fd_3cfb06799adc3a  表单类型0：薪资；1：绩效；2：其他；3：劳务费；4：稿酬  fxj 20240523
		if (CommonConstants.ZERO_STRING.equals(s.getFormType())) {
			sendMap.put("fd_3cfb06799adc3a", "薪资");
		}
		if (CommonConstants.ONE_STRING.equals(s.getFormType())) {
			sendMap.put("fd_3cfb06799adc3a", "绩效");
		}
		if (CommonConstants.TWO_STRING.equals(s.getFormType())) {
			sendMap.put("fd_3cfb06799adc3a", "其他");
		}
		if (CommonConstants.THREE_STRING.equals(s.getFormType())) {
			sendMap.put("fd_3cfb06799adc3a", "劳务费");
		}
		if (CommonConstants.FOUR_STRING.equals(s.getFormType())) {
			sendMap.put("fd_3cfb06799adc3a", "稿酬");
		}
		//表格类型 fd_3cfb067af80082 表格类型 0 薪资原表 1 系统模板  fxj 20240523
		sendMap.put("fd_3cfb067af80082", CommonConstants.ZERO_STRING.equals(s.getExcelType()) ? "薪资原表" : "系统模板");

		sendMap.put("fd_3b3bf2c3b1a6cc", s.getDeptName());
		sendMap.put("fd_3b3bf2c426cfc8", s.getDeptNo());
		sendMap.put("fd_3b3bf2c4975776", s.getApplyNo() == null ? "" : s.getApplyNo());
		sendMap.put("fd_3b3bf2c58d2b46", s.getId());
		sendMap.put("fd_3b3cbe1d05f0d6", "");
		sendMap.put("fd_3b3d3ec95b68fc", String.valueOf(s.getSettlementAmount()));
		sendMap.put("fd_3b3d3ec85bfeb0", s.getSalaryMonth().substring(0, 4)
				+ CommonConstants.CENTER_SPLIT_LINE_STRING + s.getSalaryMonth().substring(4, 6));
		sendMap.put("fd_3b73e18ad34090", "否");
		sendMap.put("fd_3c3fd0da14ed9a", s.getCreateName());

		if (Common.isNotNull(s.getIssueStatus()) && s.getIssueStatus() == 1) {
			sendMap.put("fd_3b73e18ad34090", "是");
			List<TSalaryStandardIssueRes> resList = issueResService.list(
					Wrappers.<TSalaryStandardIssueRes>query().lambda().eq(
							TSalaryStandardIssueRes::getSalaryId, s.getId()));
			if (resList != null && !resList.isEmpty()) {
				// 代发户银行账户
				List<String> fd3b71f207c0cfd0 = new ArrayList<>();
				// 代发户银行账户
				List<String> fd3b71f20883301a = new ArrayList<>();
				// 代发户支行
				List<String> fd3b71f20933e0d2 = new ArrayList<>();
				// 代发户开户行总行
				List<String> fd3b745c35ff27a8 = new ArrayList<>();
				// 代发金额
				List<String> fd3b73a736cc9cc8 = new ArrayList<>();
				for (TSalaryStandardIssueRes res : resList) {
					fd3b71f207c0cfd0.add(res.getOrgName());
					fd3b71f20883301a.add(res.getBankNo());
					if (Common.isNotNull(res.getBankSubName())) {
						fd3b71f20933e0d2.add(res.getBankSubName());
					} else {
						fd3b71f20933e0d2.add("");
					}
					fd3b745c35ff27a8.add(res.getBankName());
					if (Common.isNotNull(res.getMoney())) {
						fd3b73a736cc9cc8.add(String.valueOf(res.getMoney()));
					} else {
						fd3b73a736cc9cc8.add("");
					}
				}
				sendMap.put("fd_3b71f1f4fd40ac.fd_3b71f207c0cfd0", fd3b71f207c0cfd0);
				sendMap.put("fd_3b71f1f4fd40ac.fd_3b71f20883301a", fd3b71f20883301a);
				sendMap.put("fd_3b71f1f4fd40ac.fd_3b71f20933e0d2", fd3b71f20933e0d2);
				sendMap.put("fd_3b71f1f4fd40ac.fd_3b745c35ff27a8", fd3b745c35ff27a8);
				sendMap.put("fd_3b71f1f4fd40ac.fd_3b73a736cc9cc8", fd3b73a736cc9cc8);
			}
		}
		return sendMap;
	}

	/**
	 * @Description: 添加流程进展明细
	 * @Author: hgw
	 * @Date: 2022/9/6 16:02
	 * @return: void
	 **/
	@Override
	public void saveRecordLog(TSalaryStandard tSalaryStandard, YifuUser user, String status, String nodeId) {
		TApprovalRecord tApprovalRecord = new TApprovalRecord();
		tApprovalRecord.setApprovalResult(status);
		tApprovalRecord.setApprovalOpinion(tSalaryStandard.getRemark());
		tApprovalRecord.setSalaryId(tSalaryStandard.getId());
		tApprovalRecord.setNodeId(nodeId);
		tApprovalRecord.setApprovalMan(user.getId());
		tApprovalRecord.setApprovalManName(user.getNickname());
		tApprovalRecord.setApprovalTime(DateUtil.getCurrentDateTime());
		auditLogService.save(tApprovalRecord);
	}

	private void doSendForecastSocialToEkp(EkpSalaryParamVo account, TSalaryStandard s,
										   List<EkpPushSocialParam> socialPushList) {
		EkpPushSocialParam socialParam = new EkpPushSocialParam();
		//订单类型
		socialParam.setFd_3add9dd7833db8("预估");
		//是否有预估
		socialParam.setFd_3add9de0be85e4(CommonConstants.IS_TRUE);
		//与工资合并结算
		socialParam.setFd_3add9e1a670144(CommonConstants.IS_FALSE);
		//项目编码
		socialParam.setFd_3adfe8c70d3fd4(account.getFd_3adfedf98ccba2());
		//项目名称
		socialParam.setFd_3adfe8c8468e54(account.getFd_3adfedf9d2bf1c());
		//项目编码-原  fxj 20240527 add
		socialParam.setFd_3cfe2da7e35daa(account.getFd_3adfedf98ccba2());
		//项目名称-原  fxj 20240527 add
		socialParam.setFd_3cfe2db5015d6e(account.getFd_3adfedf9d2bf1c());
		//单号
		socialParam.setFd_3adfe95c169c48(CommonConstants.EMPTY_STRING);
		//客户编码
		socialParam.setFd_3adfe8c73cb5a4(account.getFd_3adfedfacd65d6());
		//客户名称
		socialParam.setFd_3adfe8c81a0e42(account.getFd_3adfedfb174068());
		//社保户
		socialParam.setFd_3aeafa25916e82(CommonConstants.EMPTY_STRING);
		//员工姓名
		socialParam.setFd_3adfe8c79989d4(account.getFd_3adfedfb5a68a2());
		//员工身份证
		socialParam.setFd_3adfe8c7e4cf7a(account.getFd_3adfedfb8f76d4());
		// 缴纳月份
		socialParam.setFd_3adfe8cf632700(account.getDeduSocialMonth());
		// 生成月份
		socialParam.setFd_3adfe8cb96c41e(null != account.getDeduSocialMonth() ? account.getDeduSocialMonth().replace("-", "") : null);
		// 预估单位合计
		socialParam.setFd_3adfeb4e8064a8(account.getFd_3bcd41d857b764());
		// 预估个人合计
		socialParam.setFd_3adfeb52a4d2e2(account.getFd_3b16ce48a9735c());
		//应收
		socialParam.setFd_3adfeb7b624f06(account.getSocialSum());
		//预估合计
		socialParam.setFd_3af9ed7e813b86(account.getSocialSum());
		//单位养老金额
		socialParam.setFd_3af9ec80a9de7a(CommonConstants.EMPTY_STRING);
		//单位医疗金额
		socialParam.setFd_3af9eba5899c90(CommonConstants.EMPTY_STRING);
		//单位工伤金额
		socialParam.setFd_3af9eba684f592(CommonConstants.EMPTY_STRING);
		//单位失业金额
		socialParam.setFd_3af9eba5f6e19e(CommonConstants.EMPTY_STRING);
		//单位生育金额
		socialParam.setFd_3af9eba71c0138(CommonConstants.EMPTY_STRING);
		//单位大病金额
		socialParam.setFd_3af9eba863c0ee(CommonConstants.EMPTY_STRING);
		//个人养老金额
		socialParam.setFd_3af9ebbd791662(CommonConstants.EMPTY_STRING);
		//个人医疗金额
		socialParam.setFd_3af9ebbdd9797e(CommonConstants.EMPTY_STRING);
		//预估个人大病救助
		socialParam.setFd_3af9ebbf3e8be2(CommonConstants.EMPTY_STRING);
		//预估个人失业
		socialParam.setFd_3af9ebbe29ce1c(CommonConstants.EMPTY_STRING);
		//结算状态
		socialParam.setFd_3add9ea428879a(CommonConstants.SALARY_UNFLAG);
		//结算月份
		socialParam.setFd_3adfe8cff746bc(CommonConstants.EMPTY_STRING);
		//单位差异
		socialParam.setFd_3adfeb53c70f72(CommonConstants.EMPTY_STRING);
		//个人差异
		socialParam.setFd_3adfeb5413fb44(CommonConstants.EMPTY_STRING);
		//收款状态
		socialParam.setFd_3add9eaeed2560(CommonConstants.EMPTY_STRING);
		//结算单号
		socialParam.setFd_3adfeb830523b6(CommonConstants.EMPTY_STRING);
		//收款单号
		socialParam.setFd_3adfeb8489e6c2(CommonConstants.EMPTY_STRING);
		//应支出
		socialParam.setFd_3adfeb7bd97464(CommonConstants.EMPTY_STRING);
		//支出结算状态
		socialParam.setFd_3add9edfbc6f7e(CommonConstants.EMPTY_STRING);
		//付款状态
		socialParam.setFd_3add9eed23894a(CommonConstants.EMPTY_STRING);
		//支出缴纳单号
		socialParam.setFd_3adfeb83a704c8(CommonConstants.EMPTY_STRING);
		//实缴单位生育
		socialParam.setFd_3af9ee3afb34c2(CommonConstants.EMPTY_STRING);
		//付款单号
		socialParam.setFd_3adfeb84175f28(CommonConstants.EMPTY_STRING);
		//实缴个人合计
		socialParam.setFd_3af9ee3cb6d4fa(CommonConstants.EMPTY_STRING);
		//实缴单位合计
		socialParam.setFd_3af9ee3c0bf286(CommonConstants.EMPTY_STRING);
		//实缴个人补缴利息
		socialParam.setFd_3af9ee3d634946(CommonConstants.EMPTY_STRING);
		//实缴单位医疗
		socialParam.setFd_3af9ee39dea6a8(CommonConstants.EMPTY_STRING);
		//预估个人补缴利息
		socialParam.setFd_3af9ebbecc4aa8(CommonConstants.EMPTY_STRING);
		//预估单位补缴利息
		socialParam.setFd_3af9eba7c3da5e(CommonConstants.EMPTY_STRING);
		//实缴单位养老
		socialParam.setFd_3af9ee3938170a(CommonConstants.EMPTY_STRING);
		//实缴个人失业
		socialParam.setFd_3af9ee3db44d96(CommonConstants.EMPTY_STRING);
		//实缴单位补缴利息
		socialParam.setFd_3af9ee3b5ddae8(CommonConstants.EMPTY_STRING);
		//实缴单位大病救助
		socialParam.setFd_3af9ee3ba76f54(CommonConstants.EMPTY_STRING);
		//实缴单位工伤
		socialParam.setFd_3af9ee3aa9c84a(CommonConstants.EMPTY_STRING);
		//实缴合计
		socialParam.setFd_3af9ee3c6bfc74(CommonConstants.EMPTY_STRING);
		//实缴个人医疗
		socialParam.setFd_3af9ee3e066d48(CommonConstants.EMPTY_STRING);
		//实缴单位失业
		socialParam.setFd_3af9ee3a46b7e6(CommonConstants.EMPTY_STRING);
		//实缴个人养老
		socialParam.setFd_3af9ee3e513962(CommonConstants.EMPTY_STRING);
		//实缴个人大病救助
		socialParam.setFd_3af9ee3d0ba3b6(CommonConstants.EMPTY_STRING);
		//我司到款单位
		socialParam.setFd_3b01953871b8be(s.getInvoiceTitle());
		//社保id
		socialParam.setFd_3b0afbe1f94a08(account.getFd_3b10af838eab5c());
		// 是否为BPO业务
		socialParam.setFd_3b178dfcf9e3e6(s.getBpoFlag());
		// 薪酬申请编号
		socialParam.setFd_3b3cab77923f44(s.getApplyNo() == null ? "" : s.getApplyNo());
		//预估
		socialParam.setYgFlag(CommonConstants.ONE_STRING);
		//创建人姓名
		socialParam.setFd_3b438e33f37378(account.getFd_3c3e5ff65115a2());
		socialPushList.add(socialParam);
	}

	private void doSendForecastFundToEkp(EkpSalaryParamVo account, TSalaryStandard s, List<EkpPushFundParam> fundPushList) {
		EkpPushFundParam socialParam = new EkpPushFundParam();
		//订单类型
		socialParam.setFd_3add9dd7833db8("预估");
		//是否有预估
		socialParam.setFd_3add9de0be85e4(CommonConstants.IS_TRUE);
		//与工资合并结算
		socialParam.setFd_3add9e1a670144(CommonConstants.IS_FALSE);
		//项目编码
		socialParam.setFd_3adfe8c70d3fd4(account.getFd_3adfedf98ccba2());
		//项目名称
		socialParam.setFd_3adfe8c8468e54(account.getFd_3adfedf9d2bf1c());
		//项目编码-原  fxj 20240527 add
		socialParam.setFd_3cfe2da7e35daa(account.getFd_3adfedf98ccba2());
		//项目名称-原  fxj 20240527 add
		socialParam.setFd_3cfe2db5015d6e(account.getFd_3adfedf9d2bf1c());
		//单号
		socialParam.setFd_3adfe95c169c48(CommonConstants.EMPTY_STRING);
		//客户编码
		socialParam.setFd_3adfe8c73cb5a4(account.getFd_3adfedfacd65d6());
		//客户名称
		socialParam.setFd_3adfe8c81a0e42(account.getFd_3adfedfb174068());
		//公积金账户
		socialParam.setFd_3aeafa8cc144bc(CommonConstants.EMPTY_STRING);
		//员工姓名
		socialParam.setFd_3adfe8c79989d4(account.getFd_3adfedfb5a68a2());
		//员工身份证
		socialParam.setFd_3adfe8c7e4cf7a(account.getFd_3adfedfb8f76d4());
		// 预估单位代缴
		socialParam.setFd_3adfeb4e8064a8(account.getFd_3bcd41d77e4812());
		// 预估个人代缴
		socialParam.setFd_3adfeb52a4d2e2(account.getFd_3b16ce4b7fc42a());
		//应收
		socialParam.setFd_3adfeb7b624f06(account.getFundSum());
		// 缴纳月份
		socialParam.setFd_3adfe8cf632700(account.getDeduProvidentMonth());
		// 生成月份
		socialParam.setFd_3adfe8cb96c41e(null != account.getDeduProvidentMonth() ? account.getDeduProvidentMonth().replace("-", "") : null);
		//结算状态
		socialParam.setFd_3add9ea428879a(CommonConstants.SALARY_UNFLAG);
		//单位代缴
		socialParam.setFd_3adfeb52fbe966(CommonConstants.EMPTY_STRING);
		//个人代缴
		socialParam.setFd_3adfeb5366dd82(CommonConstants.EMPTY_STRING);
		//结算月份
		socialParam.setFd_3adfe8cff746bc(CommonConstants.EMPTY_STRING);
		//单位差异
		socialParam.setFd_3adfeb53c70f72(CommonConstants.EMPTY_STRING);
		//个人差异
		socialParam.setFd_3adfeb5413fb44(CommonConstants.EMPTY_STRING);
		//收款状态
		socialParam.setFd_3add9eaeed2560(CommonConstants.EMPTY_STRING);
		//结算单号
		socialParam.setFd_3adfeb830523b6(CommonConstants.EMPTY_STRING);
		//收款单号
		socialParam.setFd_3adfeb8489e6c2(CommonConstants.EMPTY_STRING);
		//应支出
		socialParam.setFd_3adfeb7bd97464(CommonConstants.EMPTY_STRING);
		//支出结算状态
		socialParam.setFd_3add9edfbc6f7e(CommonConstants.EMPTY_STRING);
		//付款状态
		socialParam.setFd_3add9eed23894a(CommonConstants.EMPTY_STRING);
		//支出缴纳单号
		socialParam.setFd_3adfeb83a704c8(CommonConstants.EMPTY_STRING);
		//付款单号
		socialParam.setFd_3adfeb84175f28(CommonConstants.EMPTY_STRING);
		//我司到款单位
		socialParam.setFd_3b019a2e9bfdd6(s.getInvoiceTitle());
		// 公积金id
		socialParam.setFd_3b0afbaf10df2c(account.getFd_3b10af838eab5c());
		// 是否为BPO业务
		socialParam.setFd_3b178ea361cabe(s.getBpoFlag());
		// 薪酬申请编号
		socialParam.setFd_3b3cabde83d1d0(s.getApplyNo() == null ? "" : s.getApplyNo());
		//创建人姓名
		socialParam.setFd_3b43922217c6f8(account.getFd_3c3e5ff65115a2());
		fundPushList.add(socialParam);
	}

	/**
	 * @param applyNo
	 * @Description: 从EKP退回薪资表
	 * @Author: hgw
	 * @Date: 2022/11/4 17:26
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.Boolean>
	 **/
	public R<String> backSalaryByApplyNo(String applyNo) {
		if (Common.isNotNull(applyNo)) {
			List<TSalaryStandard> salaryList = this.list(Wrappers.<TSalaryStandard>query().lambda()
					.eq(TSalaryStandard::getApplyNo, applyNo)
					.eq(TSalaryStandard::getDeleteFlag, CommonConstants.ZERO_INT));
			if (salaryList != null && !salaryList.isEmpty()) {
				TSalaryStandard ss = salaryList.get(0);
				if (ss.getStatus() != SalaryConstants.STATUS[6]) {
					YifuUser user = SecurityUtils.getUser();
					// 异步-收入相关
					doSalaryAsync.doBackSalary(applyNo, ss, user);
					return R.ok();
				} else {
					return R.failed("工资表已退回，请不要重复操作");
				}
			}
		}
		return R.failed("未找到工资表");
	}

	/**
	 * @param id
	 * @Description: 重新生成收入
	 * @Author: hgw
	 * @Date: 2022/11/29 17:58
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	@Override
	public R<String> salaryDoIncome(String id) {
		TSalaryStandard tSalaryStandard = this.getById(id);
		if (tSalaryStandard != null
				&& (tSalaryStandard.getStatus() == CommonConstants.dingleDigitIntArray[11]
				|| tSalaryStandard.getStatus() == CommonConstants.dingleDigitIntArray[12])
				&& tSalaryStandard.getIncomeStartTime() != null) {
			if (tSalaryStandard.getStatus() == CommonConstants.dingleDigitIntArray[11]) {
				long start = tSalaryStandard.getIncomeStartTime().getTime() + 1800000;
				long end = new Date().getTime();
				if (start > end) {
					return R.failed("上次生成时间：" + DateUtil.formatDatePatten(tSalaryStandard.getIncomeStartTime(), DateUtil.DATETIME_PATTERN_SECOND) + "，请稍等30分钟");
				}
			}
			R<TSettleDomainSelectVo> sdr = HttpDaprUtil.invokeMethodPost(archivesProperties.getAppUrl(), archivesProperties.getAppId()
					, "/tsettledomain/inner/getSettleDomainVoById", tSalaryStandard.getDeptId()
					, TSettleDomainSelectVo.class, SecurityConstants.FROM_IN);
			// 结算主体
			TSettleDomainSelectVo dept;
			if (sdr != null && sdr.getData() != null) {
				dept = sdr.getData();
			} else {
				return R.failed("获取项目信息失败，请联管理员！");
			}
			List<TSalaryAccount> salaryAccountList = salaryAccountService.getListByIncome(id);
			if (salaryAccountList != null && !salaryAccountList.isEmpty()) {
				// 将重置生成推送时间
				tSalaryStandard.setStatus(CommonConstants.dingleDigitIntArray[11]);
				tSalaryStandard.setIncomeStartTime(new Date());
				tSalaryStandard.setIncomeEndTime(null);
				this.updateById(tSalaryStandard);
				// 异步-收入相关
				doSalaryAsync.doIncomeDetail(dept, salaryAccountList, id, tSalaryStandard);
				return R.ok(null, "生成收入并推送中，请耐心等待！");
			}
			return R.failed("未获取到报账明细，请重试");
		} else {
			return R.failed("请耐心等待！");
		}
	}

	/**
	 * @param voList
	 * @Description: 差额单--EKP调用接口
	 * @Author: hgw
	 * @Date: 2023/1/31 17:29
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	public R<String> saveSalaryDiff(List<AccountByEkpDiffVo> voList) {
		if (voList != null && !voList.isEmpty()) {
			List<String> accIdList = new ArrayList<>();
			for (AccountByEkpDiffVo vo : voList) {
				if (Common.isEmpty(vo.getAccountId()) || Common.isEmpty(vo.getRelaySalary())
						|| Common.isEmpty(vo.getActualSalary()) || Common.isEmpty(vo.getSalaryTax())) {
					return R.failed("参数不可为空");
				}
				accIdList.add(vo.getAccountId());
			}
			List<TSalaryAccount> accountList = salaryAccountService.getListByIdList(accIdList);
			if (accountList != null && !accountList.isEmpty()) {
				Map<String, TSalaryAccount> accountMap = new HashMap<>();
				for (TSalaryAccount account : accountList) {
					accountMap.put(account.getId(), account);
				}
				List<TSalaryAccount> newAccountList = new ArrayList<>();
				TSalaryAccount oldAccount;
				TSalaryAccount newAccount;
				BigDecimal allRelaySalary = BigDecimal.ZERO;

				for (AccountByEkpDiffVo idVo : voList) {
					oldAccount = accountMap.get(idVo.getAccountId());
					if (oldAccount == null) {
						return R.failed("未找到id为：【" + idVo.getAccountId() + "】的表");
					} else {
						newAccount = new TSalaryAccount();
						BeanUtil.copyProperties(oldAccount, newAccount);
						this.deleteAccountBaseInfo(newAccount);
						newAccount.setRelaySalary(idVo.getRelaySalary());
						newAccount.setActualSalary(idVo.getActualSalary());
						newAccount.setSalaryTax(idVo.getSalaryTax());
						newAccount.setIsDiff(CommonConstants.ONE_STRING);
						newAccountList.add(newAccount);
						allRelaySalary = allRelaySalary.add(idVo.getRelaySalary());
					}
				}
				TSalaryStandard oldSalary = this.getById(accountList.get(CommonConstants.ZERO_INT).getSalaryFormId());
				if (oldSalary == null) {
					return R.failed("未找到工资表!");
				}
				TSalaryStandard newSalary = new TSalaryStandard();
				BeanUtil.copyProperties(oldSalary, newSalary);
				newSalary.setId(null);
				newSalary.setSettlementAmount(allRelaySalary);
				newSalary.setIsDiff(CommonConstants.ONE_STRING);
				this.save(newSalary);
				int i = 1;
				TSalaryAccountItem relayItem;
				TSalaryAccountItem actualItem;
				TSalaryAccountItem taxItem;
				for (TSalaryAccount account : newAccountList) {
					account.setSalaryFormId(newSalary.getId());
					account.setRowIndex(i);
					salaryAccountService.save(account);
					// 应发
					relayItem = new TSalaryAccountItem();
					relayItem.setSalaryAccountId(account.getId());
					relayItem.setJavaFiedName(SalaryConstants.RELAY_SALARY_JAVA);
					relayItem.setCnName(SalaryConstants.RELAY_SALARY);
					relayItem.setSalaryMoney(account.getRelaySalary());
					relayItem.setIsTax(CommonConstants.ZERO_INT);
					salaryAccountItemService.save(relayItem);

					// 实发
					actualItem = new TSalaryAccountItem();
					actualItem.setSalaryAccountId(account.getId());
					actualItem.setJavaFiedName(SalaryConstants.ACTUAL_SALARY_SUM_JAVA);
					actualItem.setCnName(SalaryConstants.ACTUAL_SALARY_SUM);
					actualItem.setSalaryMoney(account.getActualSalary());
					actualItem.setIsTax(CommonConstants.ZERO_INT);
					salaryAccountItemService.save(actualItem);

					// 个税
					taxItem = new TSalaryAccountItem();
					taxItem.setSalaryAccountId(account.getId());
					taxItem.setJavaFiedName(SalaryConstants.SALARY_TAX_JAVA);
					taxItem.setCnName(SalaryConstants.SALARY_TAX);
					taxItem.setSalaryMoney(account.getSalaryTax());
					taxItem.setIsTax(CommonConstants.ZERO_INT);
					salaryAccountItemService.save(taxItem);
					i++;
				}
				return R.ok();
			}
		}
		return R.failed("未找到工资表！");
	}

	/**
	 * @param newAccount
	 * @Description: 复制原报账信息后，清空无关列
	 * @Author: hgw
	 * @Date: 2023/2/3 11:28
	 * @return: void
	 **/
	private void deleteAccountBaseInfo(TSalaryAccount newAccount) {
		newAccount.setId(null);
		newAccount.setRelaySalaryUnit(null);
		newAccount.setSalaryTaxUnit(null);
		newAccount.setUnitSocial(null);
		newAccount.setPersonSocial(null);
		newAccount.setUnitFund(null);
		newAccount.setPersonFund(null);
		newAccount.setSumChildEduMoney(null);
		newAccount.setSumContinuingEducationMoney(null);
		newAccount.setSumHousingLoanMoney(null);
		newAccount.setSumHousingRentMoney(null);
		newAccount.setSumSupportElderlyMoney(null);
		newAccount.setSumBabyMoney(null);
		newAccount.setSumPrivatePension(null);
		newAccount.setAnnualBonusTax(null);
	}

	/**
	 * @param deptId      项目id
	 * @param settleMonth 结算月
	 * @param nowYear     当前结算年
	 * @Description: 获取薪资条数
	 * @Author: hgw
	 * @Date: 2023/6/25 18:04
	 * @return: int
	 **/
	@Override
	public int getNum(String deptId, String setId, String settleMonth, String nowYear) {
		return baseMapper.getNum(deptId, setId, settleMonth, nowYear);
	}

	/**
	 * @param s    薪资主表
	 * @param user 登录人
	 * @Description: 判断薪资是否购买商险
	 * @Author: hgw
	 * @Date: 2025/1/14 14:21
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.util.List < com.yifu.cloud.plus.v1.yifu.salary.vo.SalaryRiskVo>>
	 **/
	@Override
	public R<List<SalaryRiskVo>> judgeRisk(TSalaryStandard s, YifuUser user) {

		// 1 判断项目信息：是否含风险、含商险服务项
		R<TSettleDomainSelectVo> sdr = HttpDaprUtil.invokeMethodPost(archivesProperties.getAppUrl(), archivesProperties.getAppId()
				, "/tsettledomain/inner/getSettleDomainVoById", s.getDeptId()
				, TSettleDomainSelectVo.class, SecurityConstants.FROM_IN);
		// 结算主体
		TSettleDomainSelectVo dept;
		if (sdr != null && sdr.getData() != null) {
			dept = sdr.getData();
			// 含风险 且 服务项目有商险，才下一步：
			if (CommonConstants.IS_TRUE.equals(dept.getHasContainRisks()) && Common.isNotNull(dept.getServerItem()) && dept.getServerItem().contains("商险")) {
				// 2 判断商险
				List<TSalaryAccount> accountList = salaryAccountService.getIdCardListBySalaryId(s.getId());
				if (accountList != null && !accountList.isEmpty()) {
					// 获取未购买商险列表
					R<SalaryRiskListVo> riskListVoR = HttpDaprUtil.invokeMethodPost(insurancesProperties.getAppUrl(), insurancesProperties.getAppId()
							, "/insuranceDetail/inner/getRiskByIdCard", accountList
							, SalaryRiskListVo.class, SecurityConstants.FROM_IN);
					if (riskListVoR == null || riskListVoR.getCode() == CommonConstants.FAIL) {
						return R.failed("商险服务返回为空，请稍后重试，多次失败请联系管理员");
					} else {
						SalaryRiskListVo vo = riskListVoR.getData();
						// 未购买商险列表
						List<SalaryRiskVo> noRisklist = vo.getList();
						if (noRisklist != null && !noRisklist.isEmpty()) {
							List<String> idCardList = new ArrayList<>();
							for (SalaryRiskVo a : noRisklist) {
								idCardList.add(a.getEmpIdCard());
							}
							// 3 判断不购买申请明细
							List<TInsuranceUnpurchasePerson> buyList = tInsuranceUnpurchasePersonService.getBuyList(s.getDeptNo(), idCardList);
							Map<String, TInsuranceUnpurchasePerson> buyMap = new HashMap<>();
							TInsuranceUnpurchasePerson buyPerson;
							for (TInsuranceUnpurchasePerson buys : buyList) {
								buyPerson = buyMap.get(buys.getEmpIdcardNo());
								// 优先使用 人员已离职 的数据
								if (buyPerson == null || Common.isEmpty(buyPerson.getReasonType())
										|| !CommonConstants.TWO_STRING.equals(buyPerson.getReasonType())) {
									buyMap.put(buys.getEmpIdcardNo(), buys);
								}
							}

							boolean isTrue;
							List<SalaryRiskVo> returnList = new ArrayList<>();
							List<TInsuranceUnpurchasePersonSalary> savePerSonSalaryList = new ArrayList<>();
							List<String> updatePerSonList = new ArrayList<>();
							for (SalaryRiskVo a : noRisklist) {
								isTrue = false;
								buyPerson = buyMap.get(a.getEmpIdCard());
								if (buyPerson != null) {
									if (buyPerson.getReasonType() != null) {
										if (CommonConstants.TWO_STRING.equals(buyPerson.getReasonType())) {
											isTrue = true;
											setUpdateRiskInfo(s, buyPerson, savePerSonSalaryList, updatePerSonList);
										} else if (CommonConstants.ONE_STRING.equals(buyPerson.getReasonType())) {
											if (CommonConstants.ZERO_STRING.equals(buyPerson.getSocialStatus())) {
												isTrue = true;
												setUpdateRiskInfo(s, buyPerson, savePerSonSalaryList, updatePerSonList);
											} else {
												a.setMsg("“不购买申请”原因为“社保已购买”，但社保不在保");
											}
										}
									} else {
										a.setMsg("未购买商险列表 有“不购买申请”但“不购买原因”为空");
									}
								} else {
									a.setMsg("无在途/在保的“商险”且无“不购买申请”");
								}
								if (!isTrue) {
									returnList.add(a);
								}
							}
							// 无错误信息返回
							if (returnList.isEmpty()) {
								if (!savePerSonSalaryList.isEmpty()) {
									tInsuranceUnpurchasePersonSalaryService.saveBatch(savePerSonSalaryList);
									if (!updatePerSonList.isEmpty()) {
										tInsuranceUnpurchasePersonSalaryService.updatePersonSalaryNumByParentIds(updatePerSonList);
									}
								}
								return getTrueR(s, "校验【商险不购买】通过");
							} else {
								return new R<>(CommonConstants.TWO_INT, "校验【商险不购买】不通过！", returnList);
							}
						} else {
							return getTrueR(s, "均已购买【商险】");
						}
					}
				} else {
					return getTrueR(s, "没有报账明细，无需拦截");
				}
			} else {
				return getTrueR(s, "项目不含风险或无商险");
			}
		} else {
			return R.failed("获取项目信息失败，请联管理员！");
		}
	}

	/**
	 * @Description: 校验通过的返回
	 * @Author: hgw
	 * @Date: 2025/1/16 11:16
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.util.List < com.yifu.cloud.plus.v1.yifu.salary.vo.SalaryRiskVo>>
	 **/
	private R<List<SalaryRiskVo>> getTrueR(TSalaryStandard s, String msg) {
		s.setIsCheckRisk(CommonConstants.ONE_INT);
		s.setCheckRiskRemark(msg);
		this.updateById(s);
		return R.ok(null, msg);
	}

	/**
	 * @Description: 设置增加 不购买商险的相关信息
	 * @Author: hgw
	 * @Date: 2025/1/15 12:50
	 * @return: void
	 **/
	private void setUpdateRiskInfo(TSalaryStandard s, TInsuranceUnpurchasePerson buyPerson
			, List<TInsuranceUnpurchasePersonSalary> savePerSonSalaryList
			, List<String> updatePerSonList) {
		updatePerSonList.add(buyPerson.getId());

		TInsuranceUnpurchasePersonSalary updatePerSonSalary = new TInsuranceUnpurchasePersonSalary();
		updatePerSonSalary.setSalaryId(s.getId());
		updatePerSonSalary.setApplyNo(s.getApplyNo());
		updatePerSonSalary.setParentId(buyPerson.getId());
		updatePerSonSalary.setSalaryMonth(s.getSalaryMonth());
		savePerSonSalaryList.add(updatePerSonSalary);
	}

}
