From 5916cd63ef2b92b314ada5664260bac3d51a922e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=92=B1=E6=B6=9B?= <15850646081@163.com> Date: Fri, 7 Feb 2025 16:58:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=A0=B9=E6=8D=AE=E7=A8=8E?= =?UTF-8?q?=E6=AC=BE=E6=89=80=E5=B1=9E=E6=9C=9F=E8=BF=9B=E8=A1=8C=E7=94=B3?= =?UTF-8?q?=E6=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../param/TaxDeclarationSaveParam.java | 8 + .../datacollection/AddUpSituationManager.java | 2 +- .../impl/TaxDeclarationServiceImpl.java | 164 ++++++++++++------ .../sys/constant/SalarySysConstant.java | 15 +- 4 files changed, 135 insertions(+), 54 deletions(-) diff --git a/src/com/engine/salary/entity/taxdeclaration/param/TaxDeclarationSaveParam.java b/src/com/engine/salary/entity/taxdeclaration/param/TaxDeclarationSaveParam.java index 18b8c28c8..8fffb93cc 100644 --- a/src/com/engine/salary/entity/taxdeclaration/param/TaxDeclarationSaveParam.java +++ b/src/com/engine/salary/entity/taxdeclaration/param/TaxDeclarationSaveParam.java @@ -1,11 +1,13 @@ package com.engine.salary.entity.taxdeclaration.param; +import com.fasterxml.jackson.annotation.JsonFormat; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.time.YearMonth; +import java.util.Date; /** * 生成个税申报表参数 @@ -42,4 +44,10 @@ public class TaxDeclarationSaveParam { private String description; private String salaryMonthStr; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date taxCycle; + + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date salaryDate; } diff --git a/src/com/engine/salary/maintainer/datacollection/AddUpSituationManager.java b/src/com/engine/salary/maintainer/datacollection/AddUpSituationManager.java index c65d02559..8a9ca719a 100644 --- a/src/com/engine/salary/maintainer/datacollection/AddUpSituationManager.java +++ b/src/com/engine/salary/maintainer/datacollection/AddUpSituationManager.java @@ -54,7 +54,7 @@ public class AddUpSituationManager extends Service { // 调用生成申报单接口 YearMonth yearMonth = YearMonth.of(localDate.getYear(), localDate.getMonth()); try { - getTaxDeclarationService().save(TaxDeclarationSaveParam.builder().salaryMonth(yearMonth).taxAgentId(po.getTaxAgentId()).build()); + getTaxDeclarationService().save(TaxDeclarationSaveParam.builder().salaryMonth(yearMonth).salaryDate(po.getSalaryMonth()).taxCycle(po.getTaxCycle()).taxAgentId(po.getTaxAgentId()).build()); } catch (Exception e) { bb.writeLog("错误:" + e); result = false; diff --git a/src/com/engine/salary/service/impl/TaxDeclarationServiceImpl.java b/src/com/engine/salary/service/impl/TaxDeclarationServiceImpl.java index 3327328ec..4388047f9 100644 --- a/src/com/engine/salary/service/impl/TaxDeclarationServiceImpl.java +++ b/src/com/engine/salary/service/impl/TaxDeclarationServiceImpl.java @@ -2,9 +2,9 @@ package com.engine.salary.service.impl; import com.engine.common.util.ServiceUtil; import com.engine.core.impl.Service; +import com.engine.hrmelog.entity.dto.LoggerContext; import com.engine.salary.common.LocalDateRange; import com.engine.salary.config.SalaryElogConfig; -import com.engine.hrmelog.entity.dto.LoggerContext; import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO; import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO; import com.engine.salary.entity.salaryitem.po.SalaryItemPO; @@ -22,6 +22,8 @@ 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.sys.service.SalarySysConfService; +import com.engine.salary.sys.service.impl.SalarySysConfServiceImpl; import com.engine.salary.util.SalaryDateUtil; import com.engine.salary.util.SalaryEntityUtil; import com.engine.salary.util.SalaryI18nUtil; @@ -38,6 +40,8 @@ import java.time.YearMonth; import java.util.*; import java.util.stream.Collectors; +import static com.engine.salary.sys.constant.SalarySysConstant.TAX_DECLARATION_DATE_TYPE; + @Slf4j public class TaxDeclarationServiceImpl extends Service implements TaxDeclarationService { @@ -87,6 +91,13 @@ public class TaxDeclarationServiceImpl extends Service implements TaxDeclaration return ServiceUtil.getService(SalaryAcctEmployeeServiceImpl.class, user); } + private SalarySysConfService getSalarySysConfService(User user) { + return ServiceUtil.getService(SalarySysConfServiceImpl.class, user); + } + + //是否根据税款所属期进行申报 + private final boolean isTaxDeclarationByTaxCycle = "1".equals(getSalarySysConfService(user).getValueByCode(TAX_DECLARATION_DATE_TYPE)); + @Override public List listByTaxCycleAndTaxAgentIds(YearMonth taxCycle, Collection taxAgentIds) { if (Objects.isNull(taxCycle) || CollectionUtils.isEmpty(taxAgentIds)) { @@ -180,51 +191,96 @@ public class TaxDeclarationServiceImpl extends Service implements TaxDeclaration // 查询个税扣缴义务人 List taxAgentPOS = getTaxAgentService(user).listByIds(taxAgentIds); Map taxAgentNameMap = SalaryEntityUtil.convert2Map(taxAgentPOS, TaxAgentPO::getId, TaxAgentPO::getName); + List salaryAcctRecordPOS; + Date taxCycle; + List salaryAcctResultPOS; + Set salaryAcctRecordIds; + //根据税款所属期申报 + if (isTaxDeclarationByTaxCycle) { + taxCycle = saveParam.getTaxCycle(); + if (Objects.isNull(taxCycle)) { + throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "税款所属期参数错误")); + } - // 薪资所属月的日期范围 - LocalDateRange salaryMonthDateRange = SalaryDateUtil.localDate2Range(SalaryDateUtil.localDateToDate(saveParam.getSalaryMonth().atDay(1))); - if (Objects.isNull(salaryMonthDateRange)) { - throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "薪资所属月参数错误")); - } + // 查询税款所属期个税扣缴义务人已经生成过的个税申报表 + List taxDeclarationPOS = listByTaxCycle(TaxDeclarationPO.builder().taxCycle(taxCycle).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}", SalaryDateUtil.getFormatYearMonth(taxCycle))); + } + // 查询薪资所属月的薪资核算记录 + salaryAcctRecordPOS = listByTaxCycle(SalaryAcctRecordPO.builder().taxCycle(taxCycle).build()); + // 无薪资核算记录,不允许生成个税申报表 + if (CollectionUtils.isEmpty(salaryAcctRecordPOS)) { + throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98874, "{0}无申报数据").replace("{0}", SalaryDateUtil.getFormatYearMonth(taxCycle))); + } + // 查询薪资核算结果 + salaryAcctResultPOS = getSalaryAcctResultService(user) + .listBySalaryAcctRecordIdsAndTaxAgentIds(SalaryEntityUtil.properties(salaryAcctRecordPOS, SalaryAcctRecordPO::getId), taxAgentIds); - // 查询薪资所属月个税扣缴义务人已经生成过的个税申报表 - 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}", SalaryDateUtil.getFormatYearMonth(saveParam.getSalaryMonth()))); - } - // 查询薪资所属月的薪资核算记录 - 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}", SalaryDateUtil.getFormatYearMonth(saveParam.getSalaryMonth()))); + } - // 无薪资核算结果,不允许生成个税申报表 - if (CollectionUtils.isEmpty(salaryAcctResultPOS)) { - throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(110093, "{0}无可申报数据") - .replace("{0}", SalaryDateUtil.getFormatYearMonth(saveParam.getSalaryMonth()))); - } + 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}", SalaryDateUtil.getFormatYearMonth(saveParam.getSalaryMonth()))); + } + } else { + //根据薪资所属月申报 + // 薪资所属月的日期范围 + LocalDateRange salaryMonthDateRange = SalaryDateUtil.localDate2Range(SalaryDateUtil.localDateToDate(saveParam.getSalaryMonth().atDay(1))); + if (Objects.isNull(salaryMonthDateRange)) { + throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "薪资所属月参数错误")); + } - 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}", SalaryDateUtil.getFormatYearMonth(saveParam.getSalaryMonth()))); - } - // 如果当前薪资所属月下存在不同的税款所属期,属于异常业务场景,不允许生成个税申报表 - 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}", SalaryDateUtil.getFormatYearMonth(saveParam.getSalaryMonth()))); + // 查询薪资所属月个税扣缴义务人已经生成过的个税申报表 + 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}", SalaryDateUtil.getFormatYearMonth(saveParam.getSalaryMonth()))); + } + // 查询薪资所属月的薪资核算记录 + salaryAcctRecordPOS = listBySalaryMonth(SalaryAcctRecordPO.builder().salaryMonths(salaryMonthDateRange).build()); + // 无薪资核算记录,不允许生成个税申报表 + if (CollectionUtils.isEmpty(salaryAcctRecordPOS)) { + throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98874, "{0}无申报数据").replace("{0}", saveParam.getSalaryMonth().toString())); + } + // 查询薪资核算结果 + salaryAcctResultPOS = getSalaryAcctResultService(user) + .listBySalaryAcctRecordIdsAndTaxAgentIds(SalaryEntityUtil.properties(salaryAcctRecordPOS, SalaryAcctRecordPO::getId), taxAgentIds); + + // 无薪资核算结果,不允许生成个税申报表 + if (CollectionUtils.isEmpty(salaryAcctResultPOS)) { + throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(110093, "{0}无可申报数据") + .replace("{0}", SalaryDateUtil.getFormatYearMonth(saveParam.getSalaryMonth()))); + } + + 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}", SalaryDateUtil.getFormatYearMonth(saveParam.getSalaryMonth()))); + } + // 如果当前薪资所属月下存在不同的税款所属期,属于异常业务场景,不允许生成个税申报表 + 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}", SalaryDateUtil.getFormatYearMonth(saveParam.getSalaryMonth()))); + } } // 查询薪资账套 Set salarySobIds = SalaryEntityUtil.properties(salaryAcctRecordPOS, SalaryAcctRecordPO::getSalarySobId); @@ -273,8 +329,8 @@ public class TaxDeclarationServiceImpl extends Service implements TaxDeclaration loggerContext.setTargetId(declare.getId().toString()); loggerContext.setTargetName(targetName); loggerContext.setOperateType(OperateTypeEnum.ADD.getValue()); - loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel( 0, "生成个税申报表")); - loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel( 0, "生成个税申报表")); + loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "生成个税申报表")); + loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "生成个税申报表")); loggerContext.setNewValues(declare); SalaryElogConfig.taxDeclarationLoggerTemplate.write(loggerContext); }); @@ -315,6 +371,14 @@ public class TaxDeclarationServiceImpl extends Service implements TaxDeclaration return getSalaryAcctRecordMapper().listSome(po); } + public List listByTaxCycle(TaxDeclarationPO build) { + return getTaxDeclarationMapper().listSome(build); + } + + public List listByTaxCycle(SalaryAcctRecordPO po) { + return getSalaryAcctRecordMapper().listSome(po); + } + @Override public boolean checkByAuthority(TaxDeclarationPO taxDeclarationPO, Long employeeId) { // 判断是否开启了分权 @@ -337,7 +401,7 @@ public class TaxDeclarationServiceImpl extends Service implements TaxDeclaration @Override public void withDrawTaxDeclaration(Long taxDeclarationId) { TaxDeclarationPO po = getTaxDeclarationMapper().getById(taxDeclarationId); - if(Objects.isNull(po)){ + if (Objects.isNull(po)) { throw new SalaryRunTimeException("个税申报表不存在"); } // 获取当前个税扣缴义务人下的薪资账套 @@ -350,22 +414,22 @@ public class TaxDeclarationServiceImpl extends Service implements TaxDeclaration // 删除个税申报表 getTaxDeclarationMapper().deleteByIdZj(po.getId()); // 修改薪资核算记录状态为已归档 - if(CollectionUtils.isNotEmpty(salaryAcctRecordIds)){ - getSalaryAcctRecordService(user).updateStatusByIds(salaryAcctRecordIds,SalaryAcctRecordStatusEnum.ARCHIVED); + if (CollectionUtils.isNotEmpty(salaryAcctRecordIds)) { + getSalaryAcctRecordService(user).updateStatusByIds(salaryAcctRecordIds, SalaryAcctRecordStatusEnum.ARCHIVED); } // 查询个税扣缴义务人名称 String bar = "_"; TaxAgentPO taxAgentPO = getTaxAgentService(user).getById(po.getTaxAgentId()); - String targetName = SalaryDateUtil.getFormatYearMonth(po.getSalaryMonth()) + bar + taxAgentPO.getName() + bar + IncomeCategoryEnum.parseByValue(po.getIncomeCategory()).getDefaultLabel(); + String targetName = SalaryDateUtil.getFormatYearMonth(po.getSalaryMonth()) + bar + taxAgentPO.getName() + bar + IncomeCategoryEnum.parseByValue(po.getIncomeCategory()).getDefaultLabel(); // 记录日志 LoggerContext loggerContext = new LoggerContext<>(); loggerContext.setUser(user); loggerContext.setTargetId(taxDeclarationId.toString()); loggerContext.setTargetName(targetName); loggerContext.setOperateType(OperateTypeEnum.DELETE.getValue()); - loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel( 0, "撤回个税申报表")); - loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel( 0, "撤回个税申报表")); + loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "撤回个税申报表")); + loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "撤回个税申报表")); SalaryElogConfig.taxDeclarationLoggerTemplate.write(loggerContext); } } diff --git a/src/com/engine/salary/sys/constant/SalarySysConstant.java b/src/com/engine/salary/sys/constant/SalarySysConstant.java index 7a3c052be..9013c9126 100644 --- a/src/com/engine/salary/sys/constant/SalarySysConstant.java +++ b/src/com/engine/salary/sys/constant/SalarySysConstant.java @@ -79,7 +79,7 @@ public class SalarySysConstant { /** * 个税申报撤回 */ - public static final String WITHDRAW_TAX_DECLARATION ="WITHDRAW_TAX_DECLARATION"; + public static final String WITHDRAW_TAX_DECLARATION = "WITHDRAW_TAX_DECLARATION"; /** * 删除薪资档案 @@ -124,7 +124,7 @@ public class SalarySysConstant { /** * 首次查看后多少分钟不能查看工资单 */ - public static final String SALARY_BILL_BURNING_AFTER_READING_MIN= "SALARY_BILL_BURNING_AFTER_READING_MIN"; + public static final String SALARY_BILL_BURNING_AFTER_READING_MIN = "SALARY_BILL_BURNING_AFTER_READING_MIN"; /** * 核算固定列头数 @@ -215,6 +215,15 @@ public class SalarySysConstant { */ public static final String SHOT_EMP_TIME_TYPE = "SHOT_EMP_TIME_TYPE"; - //是否采集考勤班次数据,0:关闭 1:开启 + /** + * 是否采集考勤班次数据,0:关闭 1:开启 + */ public static final String ATTENDANCE_SERIAL_COLLECTION_BTN = "ATTENDANCE_SERIAL_COLLECTION_BTN"; + + /** + * 报税日期类型,薪资所属月/税款所属期 + * 0:薪资所属月 1:税款所属期 + * 默认薪资所属月 + */ + public static final String TAX_DECLARATION_DATE_TYPE = "TAX_DECLARATION_DATE_TYPE"; }