package com.engine.salary.service.impl; import com.engine.common.util.ServiceUtil; import com.engine.core.impl.Service; import com.engine.salary.common.LocalDateRange; import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO; import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO; import com.engine.salary.entity.salaryitem.po.SalaryItemPO; import com.engine.salary.entity.salarysob.po.SalarySobPO; import com.engine.salary.entity.taxagent.po.TaxAgentPO; import com.engine.salary.entity.taxdeclaration.bo.TaxDeclarationBO; import com.engine.salary.entity.taxdeclaration.param.TaxDeclarationListQueryParam; import com.engine.salary.entity.taxdeclaration.param.TaxDeclarationSaveParam; import com.engine.salary.entity.taxdeclaration.po.TaxDeclarationPO; import com.engine.salary.enums.salaryaccounting.SalaryAcctRecordStatusEnum; import com.engine.salary.exception.SalaryRunTimeException; import com.engine.salary.mapper.datacollection.AddUpSituationMapper; import com.engine.salary.mapper.salaryacct.SalaryAcctRecordMapper; import com.engine.salary.mapper.taxdeclaration.TaxDeclarationMapper; import com.engine.salary.service.*; import com.engine.salary.util.SalaryDateUtil; import com.engine.salary.util.SalaryEntityUtil; import com.engine.salary.util.SalaryI18nUtil; import com.engine.salary.util.db.MapperProxyFactory; import com.engine.salary.util.page.PageInfo; import com.engine.salary.util.page.SalaryPageUtil; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; import weaver.hrm.User; import java.time.YearMonth; import java.util.*; import java.util.stream.Collectors; public class TaxDeclarationServiceImpl extends Service implements TaxDeclarationService { private TaxDeclarationMapper getTaxDeclarationMapper() { return MapperProxyFactory.getProxy(TaxDeclarationMapper.class); } private SalaryAcctRecordMapper getSalaryAcctRecordMapper() { return MapperProxyFactory.getProxy(SalaryAcctRecordMapper.class); } private AddUpSituationMapper getAddUpSituationMapper() { return MapperProxyFactory.getProxy(AddUpSituationMapper.class); } private TaxDeclarationDetailService getTaxDeclarationDetailService(User user) { return ServiceUtil.getService(TaxDeclarationDetailServiceImpl.class, user); } private AddUpSituationService getAddUpSituationService(User user) { return ServiceUtil.getService(AddUpSituationServiceImpl.class, user); } private TaxAgentService getTaxAgentService(User user) { return ServiceUtil.getService(TaxAgentServiceImpl.class, user); } private SalarySobService getSalarySobService(User user) { return ServiceUtil.getService(SalarySobServiceImpl.class, user); } private SalaryAcctResultService getSalaryAcctResultService(User user) { return ServiceUtil.getService(SalaryAcctResultServiceImpl.class, user); } private SalaryItemService getSalaryItemService(User user) { return ServiceUtil.getService(SalaryItemServiceImpl.class, user); } private SalaryAcctRecordService getSalaryAcctRecordService(User user) { return ServiceUtil.getService(SalaryAcctRecordServiceImpl.class, user); } private SalaryAcctEmployeeService getSalaryAcctEmployeeService(User user) { return ServiceUtil.getService(SalaryAcctEmployeeServiceImpl.class, user); } @Override public List listByTaxCycleAndTaxAgentIds(YearMonth taxCycle, Collection taxAgentIds) { if (Objects.isNull(taxCycle) || CollectionUtils.isEmpty(taxAgentIds)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "参数错误")); } TaxDeclarationPO po = TaxDeclarationPO.builder().taxCycle(SalaryDateUtil.toDate(taxCycle, 1)).taxAgentIds(taxAgentIds).build(); List taxDeclarationPOS = getTaxDeclarationMapper().listSome(po); return taxDeclarationPOS; } @Override public PageInfo listPageByParam(TaxDeclarationListQueryParam queryParam) { long currentEmployeeId = user.getUID(); // 分页参数 TaxDeclarationPO po = TaxDeclarationPO.builder().build(); LocalDateRange localDateRange = new LocalDateRange(); if (Objects.nonNull(queryParam.getFromSalaryMonth())) { localDateRange.setFromDate(SalaryDateUtil.localDateToDate(queryParam.getFromSalaryMonth().atDay(1))); } if (Objects.nonNull(queryParam.getEndSalaryMonth())) { localDateRange.setEndDate(SalaryDateUtil.localDateToDate(queryParam.getEndSalaryMonth().atEndOfMonth())); } po.setSalaryMonths(localDateRange); // 分权 Boolean openDevolution = getTaxAgentService(user).isNeedAuth(currentEmployeeId); if (openDevolution) { // 查询负责管理的个税扣缴义务人 Collection taxAgentPOS = getTaxAgentService(user).listAllTaxAgents(currentEmployeeId); if (CollectionUtils.isEmpty(taxAgentPOS)) { return new PageInfo<>(new ArrayList<>()); } Set taxAgentIds = SalaryEntityUtil.properties(taxAgentPOS, TaxAgentPO::getId); po.setTaxAgentIds(taxAgentIds); } // 查询个税申报表 SalaryPageUtil.start(queryParam.getCurrent(), queryParam.getPageSize()); List taxDeclarationPOS = getTaxDeclarationMapper().listSome(po); return new PageInfo<>(taxDeclarationPOS, TaxDeclarationPO.class); } //根据id查询taxAgents @Override public List countByTaxDeclarationId(Collection taxAgentIds) { if (CollectionUtils.isEmpty(taxAgentIds)) { return Collections.emptyList(); } return getTaxAgentService(user).listByIds(taxAgentIds); } //根据id获取TaxDeclaration @Override public TaxDeclarationPO getById(Long id) { return getTaxDeclarationMapper().getById(id); } @Override public void save(TaxDeclarationSaveParam saveParam) { long currentEmployeeId = user.getUID(); // 个税扣缴义务人id Set taxAgentIds; Long taxAgentId = saveParam.getTaxAgentId(); if (taxAgentId != null) { taxAgentIds = Collections.singleton(taxAgentId); } else { Boolean openDevolution = getTaxAgentService(user).isOpenDevolution(); if (BooleanUtils.isFalse(openDevolution)) { taxAgentIds = SalaryEntityUtil.properties(getTaxAgentService(user).listAll(), TaxAgentPO::getId); } else { taxAgentIds = SalaryEntityUtil.properties(getTaxAgentService(user).listAllTaxAgentsAsAdmin(currentEmployeeId), TaxAgentPO::getId); } } // 检查是否具有权限 if (CollectionUtils.isEmpty(taxAgentIds)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0, "对不起,您不具备任何个税扣缴义务人的管理权限")); } // 查询个税扣缴义务人 List taxAgentPOS = getTaxAgentService(user).listByIds(taxAgentIds); Map taxAgentNameMap = SalaryEntityUtil.convert2Map(taxAgentPOS, TaxAgentPO::getId, TaxAgentPO::getName); // 薪资所属月的日期范围 LocalDateRange salaryMonthDateRange = SalaryDateUtil.localDate2Range(SalaryDateUtil.localDateToDate(saveParam.getSalaryMonth().atDay(1))); if (Objects.isNull(salaryMonthDateRange)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "薪资所属月参数错误")); } // 查询薪资所属月个税扣缴义务人已经生成过的个税申报表 List taxDeclarationPOS = listBySalaryMonthTax(TaxDeclarationPO.builder().salaryMonths(salaryMonthDateRange).taxAgentIds(taxAgentNameMap.keySet()).build()); // 已经生成过个税申报表,不允许再次生成个税申报表 if (CollectionUtils.isNotEmpty(taxDeclarationPOS)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(107986, "{0}在{1}已经生成过个税申报表,不允许再次生成") .replace("{0}", taxAgentNameMap.get(taxDeclarationPOS.get(0).getTaxAgentId())) .replace("{1}", saveParam.getSalaryMonth().toString())); } // 查询薪资所属月的薪资核算记录 List salaryAcctRecordPOS = listBySalaryMonth(SalaryAcctRecordPO.builder().salaryMonths(salaryMonthDateRange).build()); // 无薪资核算记录,不允许生成个税申报表 if (CollectionUtils.isEmpty(salaryAcctRecordPOS)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98874, "{0}无申报数据").replace("{0}", saveParam.getSalaryMonth().toString())); } // 查询薪资核算结果 List salaryAcctResultPOS = getSalaryAcctResultService(user) .listBySalaryAcctRecordIdsAndTaxAgentIds(SalaryEntityUtil.properties(salaryAcctRecordPOS, SalaryAcctRecordPO::getId), taxAgentIds); // 无薪资核算结果,不允许生成个税申报表 if (CollectionUtils.isEmpty(salaryAcctResultPOS)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(110093, "{0}无可申报数据") .replace("{0}", saveParam.getSalaryMonth().toString())); } Set salaryAcctRecordIds = SalaryEntityUtil.properties(salaryAcctResultPOS, SalaryAcctResultPO::getSalaryAcctRecordId); salaryAcctRecordPOS = salaryAcctRecordPOS.stream().filter(salaryAcctRecordPO -> salaryAcctRecordIds.contains(salaryAcctRecordPO.getId())).collect(Collectors.toList()); // 如果存在未归档的,也不允许生成个税申报表 boolean notArchived = salaryAcctRecordPOS.stream().anyMatch(salaryAcctRecordPO -> Objects.equals(salaryAcctRecordPO.getStatus(), SalaryAcctRecordStatusEnum.NOT_ARCHIVED.getValue())); if (notArchived) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98875, "{0}有未归档数据,请全部归档后再申报") .replace("{0}", saveParam.getSalaryMonth().toString())); } // 如果当前薪资所属月下存在不同的税款所属期,属于异常业务场景,不允许生成个税申报表 Date taxCycle = salaryAcctRecordPOS.get(0).getTaxCycle(); boolean differentTaxCycle = salaryAcctRecordPOS.stream().anyMatch(salaryAcctRecordPO -> salaryAcctRecordPO.getTaxCycle().compareTo(taxCycle) != 0); if (differentTaxCycle) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98876, "{0}存在不同的税款所属期,无法正常生成个税申报表,请调整账套设置,重新核算后再生成个税申报表") .replace("{0}", saveParam.getSalaryMonth().toString())); } // 查询薪资账套 Set salarySobIds = SalaryEntityUtil.properties(salaryAcctRecordPOS, SalaryAcctRecordPO::getSalarySobId); List salarySobPOS = getSalarySobService(user).listByIds(salarySobIds); // 查询所有薪资项目 List salaryItemPOS = getSalaryItemService(user).listAll(); // 处理要保存的数据 TaxDeclarationBO.Result result = TaxDeclarationBO.handle(saveParam, taxCycle, user, salaryItemPOS, salarySobPOS, salaryAcctResultPOS); // 保存个税申报表 if (CollectionUtils.isNotEmpty(result.getNeedInsertTaxDeclarations())) { getTaxDeclarationMapper().batchInsert(result.getNeedInsertTaxDeclarations()); } // 保存个税申报表明细 if (CollectionUtils.isNotEmpty(result.getNeedInsertTaxDeclarationDetails())) { getTaxDeclarationDetailService(user).batchSave(result.getNeedInsertTaxDeclarationDetails()); } // 保存累计情况 if (CollectionUtils.isNotEmpty(result.getNeedInsertAddUpSituations())) { getAddUpSituationService(user).deleteByTaxYearMonthAndTaxAgentIds(SalaryDateUtil.localDate2YearMonth(taxCycle), taxAgentIds); getAddUpSituationService(user).batchSave((List) result.getNeedInsertAddUpSituations()); } // 更新薪资核算记录的状态 getSalaryAcctRecordService(user).updateStatusByIds(salaryAcctRecordIds, SalaryAcctRecordStatusEnum.DECLARED); } @Override public void delete(SalaryAcctRecordPO salaryAcctRecordPO) { SalarySobPO sobPO = getSalarySobService(user).getById(salaryAcctRecordPO.getSalarySobId()); if (sobPO == null || sobPO.getTaxAgentId() == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "账套信息异常")); } // 薪资所属月的日期范围 LocalDateRange taxCycleDateRange = SalaryDateUtil.localDate2Range(salaryAcctRecordPO.getTaxCycle()); if (Objects.isNull(taxCycleDateRange)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "参数错误")); } List taxDeclarationPOS = listByTaxCycleAndTaxAgentIds(SalaryDateUtil.localDate2YearMonth(salaryAcctRecordPO.getTaxCycle()), Collections.singleton(sobPO.getTaxAgentId())); Set taxDeclarationIds = SalaryEntityUtil.properties(taxDeclarationPOS, TaxDeclarationPO::getId); if (CollectionUtils.isNotEmpty(taxDeclarationIds)) { // 删除个税申报表 getTaxDeclarationMapper().deleteByIds(taxDeclarationIds); // 删除个税申报表详情 getTaxDeclarationDetailService(user).deleteByTaxDeclarationIds(taxDeclarationIds); } // 删除往期累计情况 getAddUpSituationService(user).deleteAddUpSituationList(salaryAcctRecordPO.getTaxCycle(), sobPO.getTaxAgentId()); } public List listBySalaryMonthTax(TaxDeclarationPO build) { return getTaxDeclarationMapper().listSome(build); } public List listBySalaryMonth(SalaryAcctRecordPO po) { return getSalaryAcctRecordMapper().listSome(po); } @Override public boolean checkByAuthority(TaxDeclarationPO taxDeclarationPO, Long employeeId) { // 判断是否开启了分权 Boolean openDevolution = getTaxAgentService(user).isOpenDevolution(); // 判断是否是总管理员 Boolean isChief = getTaxAgentService(user).isChief(employeeId); if (openDevolution && !isChief) { // 查询负责管理的个税扣缴义务人 Collection taxAgentPOS = getTaxAgentService(user).listAllTaxAgentsAsAdmin(employeeId); if (CollectionUtils.isEmpty(taxAgentPOS)) { return false; } Set taxAgentIds = SalaryEntityUtil.properties(taxAgentPOS, TaxAgentPO::getId); return taxAgentIds.contains(taxDeclarationPO.getTaxAgentId()); } // 查询个税申报表 return true; } }