package com.engine.salary.service.impl;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.cache.SalaryCacheKey;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.constant.SalaryFormulaFieldConstant;
import com.engine.salary.entity.datacollection.AddUpDeduction;
import com.engine.salary.entity.datacollection.AddUpSituation;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.datacollection.dto.AttendQuoteDataDTO;
import com.engine.salary.entity.datacollection.po.OtherDeductionPO;
import com.engine.salary.entity.salaryacct.bo.*;
import com.engine.salary.entity.salaryacct.po.SalaryAcctEmployeePO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultTempPO;
import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveDataDTO;
import com.engine.salary.entity.salaryformula.ExpressFormula;
import com.engine.salary.entity.salaryformula.po.FormulaVar;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.entity.salarysob.dto.SalarySobCycleDTO;
import com.engine.salary.entity.salarysob.po.SalarySobBackItemPO;
import com.engine.salary.entity.salarysob.po.SalarySobItemPO;
import com.engine.salary.enums.salaryformula.SalaryFormulaReferenceEnum;
import com.engine.salary.formlua.entity.standard.ExcelResult;
import com.engine.salary.service.*;
import com.engine.salary.sys.enums.TaxDeclarationFunctionEnum;
import com.engine.salary.util.SalaryEntityUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.util.StopWatch;
import weaver.general.BaseBean;
import weaver.hrm.User;
import weaver.wechat.util.Utils;
import java.time.Month;
import java.util.*;
import java.util.stream.Collectors;
/**
* 薪资核算-核算
*
Copyright: Copyright (c) 2022
* Company: 泛微软件
*
* @author qiantao
* @version 1.0
**/
@Slf4j
public class SalaryAcctCalculateServiceImpl extends Service implements SalaryAcctCalculateService {
BaseBean bb = new BaseBean();
//公式运行时间超时提醒阈值
private final String formulaRunOvertimeThreshold = bb.getPropValue("hrmSalaryCustom", "formulaRunOvertimeThreshold");
private SalaryAcctResultService getSalaryAcctResultService(User user) {
return ServiceUtil.getService(SalaryAcctResultServiceImpl.class, user);
}
private SalaryEmployeeService getSalaryEmployeeService(User user) {
return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user);
}
private SalaryArchiveService getSalaryArchiveService(User user) {
return ServiceUtil.getService(SalaryArchiveServiceImpl.class, user);
}
private AddUpSituationService getAddUpSituationService(User user) {
return ServiceUtil.getService(AddUpSituationServiceImpl.class, user);
}
private AddUpDeductionService getAddUpDeductionService(User user) {
return ServiceUtil.getService(AddUpDeductionServiceImpl.class, user);
}
private OtherDeductionService getOtherDeductionService(User user) {
return ServiceUtil.getService(OtherDeductionServiceImpl.class, user);
}
private SIAccountService getSIAccountService(User user) {
return ServiceUtil.getService(SIAccountServiceImpl.class, user);
}
private AttendQuoteDataService getAttendQuoteDataService(User user) {
return ServiceUtil.getService(AttendQuoteDataServiceImpl.class, user);
}
private FormulaRunService getFormulaRunService(User user) {
return ServiceUtil.getService(FormulaRunServiceImpl.class, user);
}
private SalaryAcctResultTempService getSalaryAcctResultTempService(User user) {
return ServiceUtil.getService(SalaryAcctResultTempServiceImpl.class, user);
}
private ProgressService getSalaryAcctProgressService(User user) {
return (ProgressService) ServiceUtil.getService(ProgressServiceImpl.class, user);
}
private SalaryAcctEmployeeService getSalaryAcctEmployeeService(User user) {
return ServiceUtil.getService(SalaryAcctEmployeeServiceImpl.class, user);
}
@Override
public void calculate(SalaryAcctCalculateBO salaryAcctCalculateBO, DataCollectionEmployee simpleEmployee, List salarySobBackItems) {
StopWatch sw = new StopWatch("核算耗时明细,id:"+salaryAcctCalculateBO.getSalaryAcctRecordPO().getId()+"");
Date now = new Date();
try {
// 数据库字段加密用
// 1、查询人员信息
sw.start("查询人员信息");
List employeeIds = SalaryEntityUtil.properties(salaryAcctCalculateBO.getSalaryAcctEmployeePOS(), SalaryAcctEmployeePO::getEmployeeId, Collectors.toList());
List simpleEmployees = getSalaryEmployeeService(user).getEmployeeByIdsAll(employeeIds);
SalarySobCycleDTO salarySobCycleDTO = salaryAcctCalculateBO.getSalarySobCycleDTO();
Long taxAgentId = salaryAcctCalculateBO.getSalarySobPO().getTaxAgentId();
sw.stop();
// 2、查询薪资档案的数据
sw.start("查询薪资档案的数据");
List salaryArchiveData = getSalaryArchiveService(user).getSalaryArchiveData(salarySobCycleDTO.getSalaryCycle(), employeeIds, taxAgentId);
sw.stop();
// 3、查询往期累计情况(查询的是上个税款所属期的的累计情况)
sw.start("查询往期累计情况");
List addUpSituationPOS;
if (salarySobCycleDTO.getTaxCycle().getMonth() == Month.JANUARY) {
// 3.1、如果当前税款所属期是本年度第一个税款所属期,就不需要查询往期累计情况
addUpSituationPOS = Collections.emptyList();
} else {
addUpSituationPOS = getAddUpSituationService(user).getAddUpSituationList(salarySobCycleDTO.getTaxCycle().plusMonths(-1), employeeIds);
}
sw.stop();
// 4、查询累计专项附加扣除
sw.start("查询累计专项附加扣除");
List addUpDeductionPOS = getAddUpDeductionService(user).getAddUpDeductionList(salarySobCycleDTO.getTaxCycle(), employeeIds, taxAgentId);
sw.stop();
// 5、查询其他免税扣除
sw.start("查询其他免税扣除");
List otherDeductionPOS = getOtherDeductionService(user).getOtherDeductionList(salarySobCycleDTO.getTaxCycle(), employeeIds, taxAgentId);
sw.stop();
//6、查询社保福利
sw.start("查询社保福利");
List