commit
This commit is contained in:
+36
-23
@@ -11,41 +11,41 @@ import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分工会季度额度分配服务。
|
||||
* 分工会分配项目额度分配服务。
|
||||
*
|
||||
* <p>该服务统一处理季度额度的分配、批量分配和重置回滚,
|
||||
* 保证季度记录与年度预算表金额始终同步。</p>
|
||||
* <p>该服务统一处理会费、评优奖励等分配项目的额度分配、批量分配和重置回滚,
|
||||
* 保证分配项目记录与年度预算表金额始终同步。</p>
|
||||
*
|
||||
* @author zhf
|
||||
*/
|
||||
public interface OutlayManageUnionAllocateService extends BaseService<OutLayAllocateUnion> {
|
||||
|
||||
/**
|
||||
* 修改单个分工会的季度分配金额。
|
||||
* 修改单个分工会的分配项目金额。
|
||||
*
|
||||
* @param id outlay_allocate_union 表主键,用于定位当前编辑的季度分配记录
|
||||
* @param allocateMoney 本次要设置的季度分配金额,传入的是最终金额,不是增量金额
|
||||
* @param id outlay_allocate_union 表主键,用于定位当前编辑的分配项目记录
|
||||
* @param allocateMoney 本次要设置的分配项目金额,传入的是最终金额,不是增量金额
|
||||
* @return Result 成功时返回 success;失败时返回错误信息,前端据此提示用户
|
||||
*/
|
||||
Result doEdit(String id, BigDecimal allocateMoney);
|
||||
|
||||
/**
|
||||
* 批量设置某一季度所有分工会的分配金额。
|
||||
* 批量设置某一分配项目所有分工会的分配金额。
|
||||
*
|
||||
* @param allocateMoney 本次批量设置的季度分配金额,所有命中的分工会都会写入该金额
|
||||
* @param quarterly 要操作的季度,例如 1/2/3/4
|
||||
* @param year 要操作的年份,用于筛选对应季度的有效分配记录
|
||||
* @param allocateMoney 本次批量设置的分配项目金额,所有命中的分工会都会写入该金额
|
||||
* @param quarterly 要操作的分配项目编码,复用 OUTLAY_QUARTERLY 字典
|
||||
* @param year 要操作的年份,用于筛选对应分配项目的有效记录
|
||||
* @return Result 成功时返回 success;失败时返回错误信息
|
||||
*/
|
||||
Result doBatchAllocate(BigDecimal allocateMoney, Integer quarterly, Integer year);
|
||||
|
||||
/**
|
||||
* 判断某年某季度是否已经做过额度分配。
|
||||
* 判断某年某分配项目是否已经做过额度分配。
|
||||
*
|
||||
* <p>只要当前季度记录中存在分配额度大于 0 的有效记录,
|
||||
* 就认为该季度已经分配过额度,前端据此决定是否提示再次分配。</p>
|
||||
* <p>只要当前分配项目记录中存在分配额度大于 0 的有效记录,
|
||||
* 就认为该分配项目已经分配过额度,前端据此决定是否提示再次分配。</p>
|
||||
*
|
||||
* @param quarterly 要检查的季度,例如 1/2/3/4
|
||||
* @param quarterly 要检查的分配项目编码,取值由 OUTLAY_QUARTERLY 字典维护
|
||||
* @param year 要检查的年份
|
||||
* @return true 已分配过;false 未分配
|
||||
*/
|
||||
@@ -60,15 +60,28 @@ public interface OutlayManageUnionAllocateService extends BaseService<OutLayAllo
|
||||
List<OutlayUnionAllocateImportVo> readImportExcel(TempFile file);
|
||||
|
||||
/**
|
||||
* 根据导入数据按分工会逐条分配季度额度。
|
||||
* 根据导入数据按分工会逐条分配项目额度。
|
||||
*
|
||||
* @param importList 导入预览数据
|
||||
* @param quarterly 当前季度
|
||||
* @param quarterly 当前分配项目编码
|
||||
* @param year 当前年度
|
||||
* @return 导入分配结果
|
||||
*/
|
||||
Result doImportAllocate(List<OutlayUnionAllocateImportVo> importList, Integer quarterly, Integer year);
|
||||
|
||||
/**
|
||||
* 给指定分工会新增评优奖励分配记录。
|
||||
*
|
||||
* <p>评优奖励属于 OUTLAY_QUARTERLY 字典中的独立分配项目,只针对单个分工会新增;
|
||||
* 新增后同步累加年度预算表总额度,分工会经费分配详情会按分配项目展示该记录。</p>
|
||||
*
|
||||
* @param year 当前预算年度
|
||||
* @param unionId 要新增评优奖励的分工会 ID
|
||||
* @param allocateMoney 本次新增的评优奖励金额
|
||||
* @return Result 成功时返回 success;失败时返回校验原因
|
||||
*/
|
||||
Result doAddAwardAllocate(Integer year, String unionId, BigDecimal allocateMoney);
|
||||
|
||||
/**
|
||||
* 导出分工会额度导入模板。
|
||||
*
|
||||
@@ -77,24 +90,24 @@ public interface OutlayManageUnionAllocateService extends BaseService<OutLayAllo
|
||||
Workbook exportImportTemplate();
|
||||
|
||||
/**
|
||||
* 重置指定年度季度的分配记录。
|
||||
* 重置指定年度分配项目的分配记录。
|
||||
*
|
||||
* <p>页面支持切换年度和季度,所以重置动作必须严格使用前端当前选择值,
|
||||
* 不能再按系统当前自然季度处理,否则会出现页面筛选季度和实际重置季度不一致的问题。</p>
|
||||
* <p>页面支持切换年度和分配项目,所以重置动作必须严格使用前端当前选择值,
|
||||
* 不能再按系统当前默认项目处理,否则会出现页面筛选项目和实际重置项目不一致的问题。</p>
|
||||
*
|
||||
* @param quarterly 要重置的季度,例如 1/2/3/4
|
||||
* @param quarterly 要重置的分配项目编码
|
||||
* @param year 要重置的年份
|
||||
* @return Result 成功时返回 success;失败时返回错误信息
|
||||
*/
|
||||
Result deleteAllocateRecord(Integer quarterly, Integer year);
|
||||
|
||||
/**
|
||||
* 按指定年度季度生成分工会预算记录。
|
||||
* 按指定年度分配项目生成分工会预算记录。
|
||||
*
|
||||
* <p>生成前会先校验该年度季度是否已存在有效记录;
|
||||
* <p>生成前会先校验该年度分配项目是否已存在有效记录;
|
||||
* 若已存在,则直接提示前端需要先重置后再重新生成。</p>
|
||||
*
|
||||
* @param quarterly 要生成的季度,例如 1/2/3/4
|
||||
* @param quarterly 要生成的分配项目编码
|
||||
* @param year 要生成的年份
|
||||
* @return Result 成功时返回 success;失败时返回错误信息
|
||||
*/
|
||||
|
||||
+134
-37
@@ -33,13 +33,15 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 分工会季度额度分配实现。
|
||||
* 分工会分配项目额度分配实现。
|
||||
*
|
||||
* @author zhf
|
||||
*/
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLayAllocateUnion> implements OutlayManageUnionAllocateService {
|
||||
|
||||
private static final int AWARD_PROJECT_CODE = 4;
|
||||
|
||||
public OutlayManageUnionAllocateServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
@@ -50,9 +52,9 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
if (Lang.isEmpty(allocateUnion)) {
|
||||
return Result.error("分配记录不存在!");
|
||||
}
|
||||
int currentQuarter = getCurrentQuarter();
|
||||
if (allocateUnion.getQuarterly() < currentQuarter) {
|
||||
return Result.error("当前是第【" + currentQuarter + "季度】无法修改【第" + allocateUnion.getQuarterly() + "季度】的额度!");
|
||||
int currentProject = getCurrentFeeProject();
|
||||
if (allocateUnion.getQuarterly() < currentProject) {
|
||||
return Result.error("当前仅允许修改当前会费项目额度!");
|
||||
}
|
||||
applyAllocateMoney(allocateUnion, allocateMoney);
|
||||
return Result.success();
|
||||
@@ -60,7 +62,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
|
||||
@Override
|
||||
public Result doBatchAllocate(BigDecimal allocateMoney, Integer quarterly, Integer year) {
|
||||
Result validateResult = validateCurrentQuarterOperation(quarterly);
|
||||
Result validateResult = validateCurrentPeriodOperation(quarterly);
|
||||
if (validateResult != null) {
|
||||
return validateResult;
|
||||
}
|
||||
@@ -69,7 +71,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
.and(OutLayAllocateUnion::getYear, "=", year)
|
||||
.and(OutLayAllocateUnion::getDelFlag, "=", false));
|
||||
if (allocateUnionList == null || allocateUnionList.isEmpty()) {
|
||||
return Result.error("当前季度没有分配记录!");
|
||||
return Result.error("当前分配项目没有分配记录!");
|
||||
}
|
||||
for (OutLayAllocateUnion allocateUnion : allocateUnionList) {
|
||||
applyAllocateMoney(allocateUnion, allocateMoney);
|
||||
@@ -143,7 +145,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
|
||||
@Override
|
||||
public Result doImportAllocate(List<OutlayUnionAllocateImportVo> importList, Integer quarterly, Integer year) {
|
||||
Result validateResult = validateCurrentQuarterOperation(quarterly);
|
||||
Result validateResult = validateCurrentPeriodOperation(quarterly);
|
||||
if (validateResult != null) {
|
||||
return validateResult;
|
||||
}
|
||||
@@ -155,7 +157,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
.and(OutLayAllocateUnion::getYear, "=", year)
|
||||
.and(OutLayAllocateUnion::getDelFlag, "=", false));
|
||||
if (allocateUnionList == null || allocateUnionList.isEmpty()) {
|
||||
return Result.error("当前季度没有分配记录!");
|
||||
return Result.error("当前分配项目没有分配记录!");
|
||||
}
|
||||
List<Sys_union> unionList = dao().query(Sys_union.class, Cnd.NEW());
|
||||
Map<String, Sys_union> unionMap = new HashMap<>();
|
||||
@@ -190,7 +192,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
continue;
|
||||
}
|
||||
if (!allocateUnionMap.containsKey(union.getId())) {
|
||||
errorList.add("第" + item.getRowNum() + "行:当前季度未生成该分工会分配记录");
|
||||
errorList.add("第" + item.getRowNum() + "行:当前分配项目未生成该分工会分配记录");
|
||||
}
|
||||
}
|
||||
if (!errorList.isEmpty()) {
|
||||
@@ -199,20 +201,62 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
for (OutlayUnionAllocateImportVo item : importList) {
|
||||
Sys_union union = unionMap.get(item.getUnionCode());
|
||||
OutLayAllocateUnion allocateUnion = allocateUnionMap.get(union.getId());
|
||||
// 导入分配与手工分配保持同一套金额同步规则,确保季度表和年度预算表数据一致。
|
||||
// 导入分配与手工分配保持同一套金额同步规则,确保分配项目记录和年度预算表数据一致。
|
||||
applyAllocateMoney(allocateUnion, item.getAllocateMoney());
|
||||
}
|
||||
return Result.success("导入分配成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result doAddAwardAllocate(Integer year, String unionId, BigDecimal allocateMoney) {
|
||||
if (year == null || StrUtil.isBlank(unionId) || allocateMoney == null) {
|
||||
return Result.error("参数错误!");
|
||||
}
|
||||
if (allocateMoney.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
return Result.error("评优奖励金额必须大于0!");
|
||||
}
|
||||
Sys_union union = dao().fetch(Sys_union.class, unionId);
|
||||
if (Lang.isEmpty(union)) {
|
||||
return Result.error("分工会不存在!");
|
||||
}
|
||||
int count = dao().count(OutLayAllocateUnion.class,
|
||||
Cnd.where(OutLayAllocateUnion::getYear, "=", year)
|
||||
.and(OutLayAllocateUnion::getUnionId, "=", unionId)
|
||||
.and(OutLayAllocateUnion::getQuarterly, "=", AWARD_PROJECT_CODE)
|
||||
.and(OutLayAllocateUnion::getDelFlag, "=", false));
|
||||
if (count > 0) {
|
||||
return Result.error("该分工会本年度已存在评优奖励记录,请直接编辑已有记录!");
|
||||
}
|
||||
|
||||
OutLayAllocateUnion allocateUnion = new OutLayAllocateUnion();
|
||||
allocateUnion.setYear(year);
|
||||
allocateUnion.setUnionId(unionId);
|
||||
allocateUnion.setQuarterly(AWARD_PROJECT_CODE);
|
||||
allocateUnion.setAllocateHeadMoney(getCurrentYearSurplusMoney(year, unionId));
|
||||
allocateUnion.setAllocateMoney(BigDecimal.ZERO);
|
||||
insert(allocateUnion);
|
||||
// 新增评优奖励后复用统一金额同步规则,确保分配项目记录和年度预算表 totalQuota 同步。
|
||||
applyAllocateMoney(allocateUnion, allocateMoney);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Workbook exportImportTemplate() {
|
||||
List<ExcelExportEntity> entityList = new ArrayList<>();
|
||||
entityList.add(new ExcelExportEntity("工会名称", "unionName", 20));
|
||||
entityList.add(new ExcelExportEntity("工会编码", "unionCode", 20));
|
||||
entityList.add(new ExcelExportEntity("分配额度", "allocateMoney", 20));
|
||||
List<Sys_union> unionList = dao().query(Sys_union.class, Cnd.NEW().asc("unionCode"));
|
||||
List<OutlayUnionAllocateImportVo> templateList = new ArrayList<>();
|
||||
for (Sys_union union : unionList) {
|
||||
OutlayUnionAllocateImportVo item = new OutlayUnionAllocateImportVo();
|
||||
item.setUnionName(union.getName());
|
||||
item.setUnionCode(union.getUnionCode());
|
||||
templateList.add(item);
|
||||
}
|
||||
ExportParams exportParams = new ExportParams();
|
||||
exportParams.setType(ExcelType.XSSF);
|
||||
return ExcelExportUtil.exportExcel(exportParams, entityList, new ArrayList<>());
|
||||
return ExcelExportUtil.exportExcel(exportParams, entityList, templateList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -220,7 +264,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
if (quarterly == null || year == null) {
|
||||
return Result.error("参数错误!");
|
||||
}
|
||||
Result validateResult = validateCurrentQuarterOperation(quarterly);
|
||||
Result validateResult = validateCurrentPeriodOperation(quarterly);
|
||||
if (validateResult != null) {
|
||||
return validateResult;
|
||||
}
|
||||
@@ -229,7 +273,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
.and(OutLayAllocateUnion::getYear, "=", year)
|
||||
.and(OutLayAllocateUnion::getDelFlag, "=", false));
|
||||
if (allocateUnionList == null || allocateUnionList.isEmpty()) {
|
||||
return Result.error("当前季度还未分配,无法重置!");
|
||||
return Result.error("当前分配项目还未分配,无法重置!");
|
||||
}
|
||||
|
||||
for (OutLayAllocateUnion allocateUnion : allocateUnionList) {
|
||||
@@ -248,7 +292,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
if (quarterly == null || year == null) {
|
||||
return Result.error("参数错误!");
|
||||
}
|
||||
Result validateResult = validateCurrentQuarterOperation(quarterly);
|
||||
Result validateResult = validateCurrentPeriodOperation(quarterly);
|
||||
if (validateResult != null) {
|
||||
return validateResult;
|
||||
}
|
||||
@@ -257,10 +301,10 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
.and(OutLayAllocateUnion::getYear, "=", year)
|
||||
.and(OutLayAllocateUnion::getDelFlag, "=", false));
|
||||
if (count > 0) {
|
||||
return Result.error("当前季度已分配,如需重新分配请点击重置分配记录!");
|
||||
return Result.error("当前分配项目已分配,如需重新分配请点击重置分配记录!");
|
||||
}
|
||||
|
||||
// 第一季度需要承接上一年度剩余额度,其余季度承接当年预算额度,确保生成记录时的分配前额度准确。
|
||||
// 第一个会费项目需要承接上一年度剩余额度,其余项目承接当年预算额度,确保生成记录时的分配前额度准确。
|
||||
Integer sourceYear = quarterly == 1 ? year - 1 : year;
|
||||
List<OutlayManageUnion> outlayManageUnionList = dao().query(OutlayManageUnion.class,
|
||||
Cnd.where(OutlayManageUnion::getYear, "=", sourceYear));
|
||||
@@ -270,10 +314,10 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
}
|
||||
|
||||
/**
|
||||
* 按“先回退旧额度,再写入新额度”的方式同步季度记录和年度预算表。
|
||||
* 按“先回退旧额度,再写入新额度”的方式同步分配项目记录和年度预算表。
|
||||
*
|
||||
* @param allocateUnion 当前季度分配记录,包含分工会、年份、旧分配额度等上下文
|
||||
* @param newAllocateMoney 本次最终要保存的季度分配金额
|
||||
* @param allocateUnion 当前分配项目记录,包含分工会、年份、旧分配额度等上下文
|
||||
* @param newAllocateMoney 本次最终要保存的分配项目金额
|
||||
*/
|
||||
private void applyAllocateMoney(OutLayAllocateUnion allocateUnion, BigDecimal newAllocateMoney) {
|
||||
BigDecimal oldAllocateMoney = defaultValue(allocateUnion.getAllocateMoney());
|
||||
@@ -285,10 +329,14 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
manageUnion = buildManageUnion(allocateUnion, newAllocateMoney);
|
||||
insert(manageUnion);
|
||||
} else {
|
||||
// 当前 totalQuota 里已经包含了旧季度额度,因此要先减旧值,再加新值,避免重复累加。
|
||||
// 当前 totalQuota 里已经包含了旧项目额度,因此要先减旧值,再加新值,避免重复累加。
|
||||
BigDecimal newTotalQuota = defaultValue(manageUnion.getTotalQuota())
|
||||
.subtract(oldAllocateMoney)
|
||||
.add(newAllocateMoney);
|
||||
BigDecimal lastYearSurplusMoney = getFirstProjectMissingHeadMoney(allocateUnion, manageUnion);
|
||||
if (lastYearSurplusMoney.compareTo(BigDecimal.ZERO) != 0) {
|
||||
newTotalQuota = newTotalQuota.add(lastYearSurplusMoney);
|
||||
}
|
||||
dao().update(OutlayManageUnion.class, Chain.make("totalQuota", newTotalQuota),
|
||||
Cnd.where(OutlayManageUnion::getId, "=", manageUnion.getId()));
|
||||
}
|
||||
@@ -298,9 +346,9 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
}
|
||||
|
||||
/**
|
||||
* 回滚当前季度已分配到年度预算表中的金额。
|
||||
* 回滚当前分配项目已分配到年度预算表中的金额。
|
||||
*
|
||||
* @param allocateUnion 当前季度分配记录,allocateMoney 表示本次需要从年度额度中扣回的金额
|
||||
* @param allocateUnion 当前分配项目记录,allocateMoney 表示本次需要从年度额度中扣回的金额
|
||||
*/
|
||||
private void rollbackAllocateMoney(OutLayAllocateUnion allocateUnion) {
|
||||
OutlayManageUnion manageUnion = dao().fetch(OutlayManageUnion.class,
|
||||
@@ -315,11 +363,43 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
Cnd.where(OutlayManageUnion::getId, "=", manageUnion.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 第一段会费分配记录的 allocateHeadMoney 保存上一年度剩余额度。
|
||||
* 如果当前年度预算表已提前生成,导入/一键分配时 totalQuota 可能只包含各分配项目金额,
|
||||
* 此时需要补入这笔期初结余;已补入过的年度预算再次导入时不重复累加。
|
||||
*
|
||||
* @param allocateUnion 当前分配项目记录
|
||||
* @param manageUnion 当前年度分工会预算记录
|
||||
* @return BigDecimal 本次需要补入的上一年度剩余额度;无需补入时返回 0
|
||||
*/
|
||||
private BigDecimal getFirstProjectMissingHeadMoney(OutLayAllocateUnion allocateUnion, OutlayManageUnion manageUnion) {
|
||||
if (allocateUnion == null || manageUnion == null || !Integer.valueOf(1).equals(allocateUnion.getQuarterly())) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
BigDecimal headMoney = defaultValue(allocateUnion.getAllocateHeadMoney());
|
||||
if (headMoney.compareTo(BigDecimal.ZERO) == 0) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
List<OutLayAllocateUnion> allocateUnionList = dao().query(OutLayAllocateUnion.class,
|
||||
Cnd.where(OutLayAllocateUnion::getUnionId, "=", allocateUnion.getUnionId())
|
||||
.and(OutLayAllocateUnion::getYear, "=", allocateUnion.getYear())
|
||||
.and(OutLayAllocateUnion::getDelFlag, "=", false));
|
||||
BigDecimal allocatedTotalMoney = allocateUnionList.stream()
|
||||
.map(OutLayAllocateUnion::getAllocateMoney)
|
||||
.map(this::defaultValue)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
BigDecimal nonAllocateMoney = defaultValue(manageUnion.getTotalQuota()).subtract(allocatedTotalMoney);
|
||||
if (nonAllocateMoney.compareTo(BigDecimal.ZERO) == 0) {
|
||||
return headMoney;
|
||||
}
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前年份预算表不存在时,按“分配前额度 + 本次分配额度”创建年度预算记录。
|
||||
*
|
||||
* @param allocateUnion 当前季度分配记录,allocateHeadMoney 表示生成记录时的剩余额度快照
|
||||
* @param allocateMoney 本次要设置的季度分配额度
|
||||
* @param allocateUnion 当前分配项目记录,allocateHeadMoney 表示生成记录时的剩余额度快照
|
||||
* @param allocateMoney 本次要设置的分配项目额度
|
||||
* @return OutlayManageUnion 新建的年度预算实体
|
||||
*/
|
||||
private OutlayManageUnion buildManageUnion(OutLayAllocateUnion allocateUnion, BigDecimal allocateMoney) {
|
||||
@@ -347,38 +427,55 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算当前自然季度。
|
||||
* 计算当前年度指定分工会的可用余额,作为新增评优奖励前的额度快照。
|
||||
*
|
||||
* @return int 当前季度,取值范围 1-4
|
||||
* @param year 当前预算年度
|
||||
* @param unionId 分工会 ID
|
||||
* @return BigDecimal 当前年度总额度减已使用额度;没有年度预算记录时返回 0
|
||||
*/
|
||||
private int getCurrentQuarter() {
|
||||
return DateUtil.month(DateUtil.date()) / 3 + 1;
|
||||
private BigDecimal getCurrentYearSurplusMoney(Integer year, String unionId) {
|
||||
OutlayManageUnion manageUnion = dao().fetch(OutlayManageUnion.class,
|
||||
Cnd.where(OutlayManageUnion::getYear, "=", year)
|
||||
.and(OutlayManageUnion::getUnionId, "=", unionId));
|
||||
if (Lang.isEmpty(manageUnion)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return defaultValue(manageUnion.getTotalQuota()).subtract(defaultValue(manageUnion.getUsedQuota()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 预算季度记录相关操作只能针对当前自然季度执行。
|
||||
* 计算当前会费项目。
|
||||
*
|
||||
* @param quarterly 前端传入的目标季度
|
||||
* @return int 当前会费项目,1 表示 1-4月会费,2 表示 5-8月会费,3 表示 9-12月会费
|
||||
*/
|
||||
private int getCurrentFeeProject() {
|
||||
return DateUtil.month(DateUtil.date()) / 4 + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预算分配项目记录相关操作只能针对当前会费项目执行。
|
||||
*
|
||||
* @param quarterly 前端传入的目标分配项目编码,取值由 OUTLAY_QUARTERLY 字典维护
|
||||
* @return Result 不允许操作时返回错误结果;允许操作时返回 null
|
||||
*/
|
||||
private Result validateCurrentQuarterOperation(Integer quarterly) {
|
||||
private Result validateCurrentPeriodOperation(Integer quarterly) {
|
||||
if (quarterly == null) {
|
||||
return Result.error("参数错误!");
|
||||
}
|
||||
int currentQuarter = getCurrentQuarter();
|
||||
if (!quarterly.equals(currentQuarter)) {
|
||||
return Result.error("当前仅允许操作第" + currentQuarter + "季度数据,请切换后再操作!");
|
||||
int currentProject = getCurrentFeeProject();
|
||||
if (!quarterly.equals(currentProject)) {
|
||||
return Result.error("当前仅允许操作当前会费项目数据,请切换后再操作!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按目标年度季度初始化要生成的分工会分配记录。
|
||||
* 按目标年度分配项目初始化要生成的分工会分配记录。
|
||||
*
|
||||
* @param outlayManageUnionList 用于计算“分配前额度”的年度预算数据
|
||||
* @param quarterly 目标季度
|
||||
* @param quarterly 目标分配项目编码
|
||||
* @param year 目标年度
|
||||
* @return List<OutLayAllocateUnion> 待插入的季度分配记录
|
||||
* @return List<OutLayAllocateUnion> 待插入的分配项目记录
|
||||
*/
|
||||
private List<OutLayAllocateUnion> buildAllocateUnionList(List<OutlayManageUnion> outlayManageUnionList, Integer quarterly, Integer year) {
|
||||
List<Sys_union> unionList = dao().query(Sys_union.class, Cnd.NEW());
|
||||
|
||||
+32
-9
@@ -38,13 +38,13 @@ import java.util.List;
|
||||
/**
|
||||
* @author zhf
|
||||
* @date 2026/2/3 11:12
|
||||
* @description 分工会经费分配
|
||||
* @description 分工会经费分配项目管理
|
||||
*/
|
||||
@IocBean
|
||||
@At("/platform/outlay/outlayManage/unionAllocate")
|
||||
@Ok("json:full")
|
||||
@Slf4j
|
||||
@Api(tags = "分工会经费分配")
|
||||
@Api(tags = "分工会经费分配项目管理")
|
||||
public class OutlayManageUnionAllocateController {
|
||||
|
||||
@Inject
|
||||
@@ -100,11 +100,13 @@ public class OutlayManageUnionAllocateController {
|
||||
@At
|
||||
@ApiOperation("一键批量分配所有工会额度")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SLog(tag = "分工会预算-季度预算分配", msg = "一键批量分配所有工会额度")
|
||||
@SLog(tag = "分工会预算-分配项目预算分配", msg = "一键批量分配所有工会额度")
|
||||
@SaCheckPermission("outlay.outlayManage.union.allocate")
|
||||
public Result doBatchAllocate(@Param("allocateMoney") BigDecimal allocateMoney,
|
||||
@Param("quarterly") Integer quarterly,
|
||||
@Param("year") Integer year) {
|
||||
// 参数说明:allocateMoney 为本次写入的分配额度;quarterly 承载 OUTLAY_QUARTERLY 字典编码,对应会费、评优奖励等分配项目;year 为预算年度。
|
||||
// 返回 Result,成功时前端刷新列表,失败时 msg 字段用于页面提示。
|
||||
if (allocateMoney == null || quarterly == null || year == null) {
|
||||
return Result.error("参数错误!");
|
||||
}
|
||||
@@ -112,7 +114,7 @@ public class OutlayManageUnionAllocateController {
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("校验当前季度是否已分配额度")
|
||||
@ApiOperation("校验当前分配项目是否已分配额度")
|
||||
@SaCheckPermission("outlay.outlayManage.union.allocate")
|
||||
public Result hasAllocated(@Param("quarterly") Integer quarterly,
|
||||
@Param("year") Integer year) {
|
||||
@@ -139,11 +141,13 @@ public class OutlayManageUnionAllocateController {
|
||||
@At
|
||||
@ApiOperation("导入分配分工会额度")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SLog(tag = "分工会预算-季度预算分配", msg = "导入分配分工会额度")
|
||||
@SLog(tag = "分工会预算-分配项目预算分配", msg = "导入分配分工会额度")
|
||||
@SaCheckPermission("outlay.outlayManage.union.allocate")
|
||||
public Result doImportAllocate(String data,
|
||||
@Param("quarterly") Integer quarterly,
|
||||
@Param("year") Integer year) {
|
||||
// 参数说明:data 为导入预览行 JSON;quarterly 为分配项目字典编码;year 为预算年度。
|
||||
// 返回 Result,成功表示导入额度已同步到分配项目记录和年度预算表,失败时 msg 字段返回具体校验原因。
|
||||
if (StrUtil.isBlank(data) || quarterly == null || year == null) {
|
||||
return Result.error("参数错误!");
|
||||
}
|
||||
@@ -151,6 +155,22 @@ public class OutlayManageUnionAllocateController {
|
||||
return outlayManageUnionAllocateService.doImportAllocate(importList, quarterly, year);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("新增单个分工会评优奖励")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SLog(tag = "分工会预算-分配项目预算分配", msg = "新增单个分工会评优奖励")
|
||||
@SaCheckPermission("outlay.outlayManage.union.allocate")
|
||||
public Result doAddAwardAllocate(@Param("year") Integer year,
|
||||
@Param("unionId") String unionId,
|
||||
@Param("allocateMoney") BigDecimal allocateMoney) {
|
||||
// 参数说明:year 为预算年度;unionId 为分工会 ID;allocateMoney 为本次新增的评优奖励金额。
|
||||
// 返回 Result,成功后前端刷新分配列表;失败时 msg 字段返回参数或重复新增等校验原因。
|
||||
if (year == null || StrUtil.isBlank(unionId) || allocateMoney == null) {
|
||||
return Result.error("参数错误!");
|
||||
}
|
||||
return outlayManageUnionAllocateService.doAddAwardAllocate(year, unionId, allocateMoney);
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@ApiOperation("下载导入分配模板")
|
||||
@@ -166,12 +186,13 @@ public class OutlayManageUnionAllocateController {
|
||||
|
||||
|
||||
@At
|
||||
@ApiOperation("重置预算季度记录")
|
||||
@ApiOperation("重置预算分配记录")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SLog(tag = "分工会预算-季度预算分配", msg = "重置预算季度记录")
|
||||
@SLog(tag = "分工会预算-分配项目预算分配", msg = "重置预算分配记录")
|
||||
@SaCheckPermission("outlay.outlayManage.union.allocate")
|
||||
public Result deleteAllocateRecord(@Param("quarterly") Integer quarterly,
|
||||
@Param("year") Integer year) {
|
||||
// 参数说明:quarterly 为当前要重置的分配项目编码,year 为预算年度;返回 Result 用于提示重置是否成功。
|
||||
if (quarterly == null || year == null) {
|
||||
return Result.error("参数错误!");
|
||||
}
|
||||
@@ -179,11 +200,13 @@ public class OutlayManageUnionAllocateController {
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("预算季度记录生成")
|
||||
@SLog(tag = "分工会预算-季度预算分配", msg = "生成了预算分配记录")
|
||||
@ApiOperation("预算分配记录生成")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SLog(tag = "分工会预算-分配项目预算分配", msg = "生成了预算分配记录")
|
||||
@SaCheckPermission("outlay.outlayManage.union.allocate")
|
||||
public Result doAllocateRecord(@Param("quarterly") Integer quarterly,
|
||||
@Param("year") Integer year) {
|
||||
// 参数说明:quarterly 为本次生成记录的分配项目编码,year 为预算年度;返回 Result 用于前端提示生成结果。
|
||||
if (quarterly == null || year == null) {
|
||||
return Result.error("参数错误!");
|
||||
}
|
||||
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
package com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.controller;
|
||||
|
||||
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.vo.OutlayUnionIncomeExpenseVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Strings;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 二级分工会经费收支使用情况表。
|
||||
*/
|
||||
@IocBean
|
||||
@At("/platform/outlay/outlayManage/unionIncomeExpense")
|
||||
@Ok("json:full")
|
||||
@Slf4j
|
||||
@Api(tags = "二级分工会经费收支使用情况表")
|
||||
public class OutlayManageUnionIncomeExpenseController {
|
||||
|
||||
@Inject
|
||||
private BaseService baseService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/dayofficework/outlay/outlayManage/union/incomeExpense/index.html")
|
||||
@SaCheckPermission("outlay.outlayManage.union.incomeExpense")
|
||||
public void index() {
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("分页查询")
|
||||
@SaCheckPermission("outlay.outlayManage.union.incomeExpense")
|
||||
public Result pageData(PageForm pageForm, Integer year, String unionId) {
|
||||
Sql sql = buildIncomeExpenseSql(year, unionId);
|
||||
Pagination pagination = baseService.listPageVO(pageForm, sql, OutlayUnionIncomeExpenseVO.class);
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@ApiOperation("导出")
|
||||
@SaCheckPermission("outlay.outlayManage.union.incomeExpense")
|
||||
public void doExport(Integer year, String unionId, HttpServletResponse response) {
|
||||
Integer queryYear = getQueryYear(year);
|
||||
Sql sql = buildIncomeExpenseSql(queryYear, unionId);
|
||||
List<OutlayUnionIncomeExpenseVO> list = baseService.listVO(sql, OutlayUnionIncomeExpenseVO.class);
|
||||
|
||||
ArrayList<ExcelExportEntity> entities = new ArrayList<>();
|
||||
entities.add(new ExcelExportEntity("单位", "unionName", 25));
|
||||
entities.add(new ExcelExportEntity("年初数", "beginMoney", 20));
|
||||
entities.add(new ExcelExportEntity("1-4月会费", "feeJanApr", 20));
|
||||
entities.add(new ExcelExportEntity("5-8月会费", "feeMayAug", 20));
|
||||
entities.add(new ExcelExportEntity("9-12月会费", "feeSepDec", 20));
|
||||
entities.add(new ExcelExportEntity("评优奖励", "awardMoney", 20));
|
||||
entities.add(new ExcelExportEntity("1-12月支出", "usedMoney", 20));
|
||||
entities.add(new ExcelExportEntity("经费余额", "remainMoney", 20));
|
||||
|
||||
ExportParams exportParams = new ExportParams();
|
||||
exportParams.setType(ExcelType.XSSF);
|
||||
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, list);
|
||||
CommonDownloadUtil.download(queryYear + "年二级分工会经费收支使用情况表.xlsx", workbook, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计参数说明:
|
||||
* year 为统计年度,未传时默认当前年份;unionId 为二级分工会主键,管理员可为空查询全部。
|
||||
* 返回 VO 中 beginMoney 是年初数,feeJanApr/feeMayAug/feeSepDec 是三个会费收入段,
|
||||
* awardMoney 是评优奖励,usedMoney 是年度支出,remainMoney 是当前经费余额。
|
||||
*/
|
||||
private Sql buildIncomeExpenseSql(Integer year, String unionId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
mu.year AS year,
|
||||
mu.unionId AS unionId,
|
||||
COALESCE(mu.unionName, su.name) AS unionName,
|
||||
COALESCE(mu.unionCode, su.unionCode) AS unionCode,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 1 THEN au.allocateHeadMoney ELSE 0 END), 0) AS beginMoney,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 1 THEN au.allocateMoney ELSE 0 END), 0) AS feeJanApr,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 2 THEN au.allocateMoney ELSE 0 END), 0) AS feeMayAug,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 3 THEN au.allocateMoney ELSE 0 END), 0) AS feeSepDec,
|
||||
COALESCE(SUM(CASE WHEN au.quarterly = 4 THEN au.allocateMoney ELSE 0 END), 0) AS awardMoney,
|
||||
COALESCE(mu.usedQuota, 0) AS usedMoney,
|
||||
COALESCE(mu.totalQuota, 0) - COALESCE(mu.usedQuota, 0) AS remainMoney
|
||||
FROM outlay_manage_union mu
|
||||
LEFT JOIN sys_union su ON su.id = mu.unionId
|
||||
LEFT JOIN outlay_allocate_union au ON au.year = mu.year
|
||||
AND au.unionId = mu.unionId
|
||||
AND au.delFlag = 0
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and("mu.delFlag", "=", false);
|
||||
cnd.and("mu.year", "=", getQueryYear(year));
|
||||
cnd.and("mu.totalQuota", "IS NOT", null);
|
||||
cnd.andEX("mu.unionId", "=", unionId);
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
cnd.and("mu.unionId", "=", SecurityUtil.getUnionId());
|
||||
}
|
||||
cnd.groupBy("mu.year");
|
||||
cnd.groupBy("mu.unionId");
|
||||
cnd.groupBy("mu.unionName");
|
||||
cnd.groupBy("mu.unionCode");
|
||||
cnd.groupBy("su.name");
|
||||
cnd.groupBy("su.unionCode");
|
||||
cnd.groupBy("mu.usedQuota");
|
||||
cnd.groupBy("mu.totalQuota");
|
||||
cnd.asc("mu.unionCode");
|
||||
sql.setCondition(cnd);
|
||||
return sql;
|
||||
}
|
||||
|
||||
private Integer getQueryYear(Integer year) {
|
||||
if (year != null) {
|
||||
return year;
|
||||
}
|
||||
return DateUtil.thisYear();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -116,7 +116,7 @@ public class OutlayManageUnionUseDetailController {
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("查询分工会今年每个季度的分配情况")
|
||||
@ApiOperation("查询分工会今年每个分配项目的分配情况")
|
||||
@SaCheckPermission("outlay.outlayManage.union.useDetail")
|
||||
public Result queryQuarterlyList(Integer year, String unionId){
|
||||
Sql sql = Sqls.create("""
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ public class OutLayAllocateUnion extends BaseModel implements Serializable {
|
||||
private String unionId;
|
||||
|
||||
@Column
|
||||
@Comment("季度")
|
||||
@Comment("分配项目")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private Integer quarterly;
|
||||
|
||||
|
||||
+4
-6
@@ -6,22 +6,20 @@ import lombok.Data;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 分工会季度额度导入行数据。
|
||||
* 分工会分配项目额度导入行数据。
|
||||
*/
|
||||
@Data
|
||||
public class OutlayUnionAllocateImportVo {
|
||||
|
||||
@Excel(name = "工会名称")
|
||||
private String unionName;
|
||||
|
||||
@Excel(name = "工会编码")
|
||||
private String unionCode;
|
||||
|
||||
@Excel(name = "分配额度")
|
||||
private BigDecimal allocateMoney;
|
||||
|
||||
/**
|
||||
* 预览时展示匹配到的工会名称。
|
||||
*/
|
||||
private String unionName;
|
||||
|
||||
/**
|
||||
* 预览时展示当前行错误信息。
|
||||
*/
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 二级分工会经费收支使用情况表数据。
|
||||
*/
|
||||
@Data
|
||||
public class OutlayUnionIncomeExpenseVO {
|
||||
|
||||
private Integer year;
|
||||
|
||||
private String unionId;
|
||||
|
||||
private String unionName;
|
||||
|
||||
private String unionCode;
|
||||
|
||||
private BigDecimal beginMoney;
|
||||
|
||||
private BigDecimal feeJanApr;
|
||||
|
||||
private BigDecimal feeMayAug;
|
||||
|
||||
private BigDecimal feeSepDec;
|
||||
|
||||
private BigDecimal awardMoney;
|
||||
|
||||
private BigDecimal usedMoney;
|
||||
|
||||
private BigDecimal remainMoney;
|
||||
}
|
||||
+36
-22
@@ -111,8 +111,6 @@ public class UnionReimburseCollectController {
|
||||
cnd.and(seg);
|
||||
}
|
||||
|
||||
cnd.and("info.stateId", "in", List.of(3, 2));
|
||||
|
||||
applyListSort(cnd, pageForm);
|
||||
sql.setCondition(cnd);
|
||||
Pagination<NutMap> pagination = unionReimburseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
@@ -185,29 +183,26 @@ public class UnionReimburseCollectController {
|
||||
@Ok("void")
|
||||
@SaCheckPermission(value = {"unionReimburse.collect", "h5.unionReimburse.collect"}, mode = SaMode.OR)
|
||||
@ApiOperation("导出报销汇总表")
|
||||
public void onExport(@Param(value = "year") Integer year,
|
||||
public void onExport(PageForm pageForm,
|
||||
@Param(value = "year") Integer year,
|
||||
@Param(value = "unionId") String unionId,
|
||||
@Param(value = "unitId") String unitId,
|
||||
@Param(value = "reimburseProject") String reimburseProject,
|
||||
@Param(value = "userName") String userName,
|
||||
@Param(value = "searchKeyword") String searchKeyword,
|
||||
HttpServletResponse response) {
|
||||
//查询审核通过的数据
|
||||
// 导出复用收集列表筛选口径,保证下载结果与页面当前查询条件一致。
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
t1.*,
|
||||
ins.state instanceState
|
||||
info.*
|
||||
FROM
|
||||
union_reimburse t1
|
||||
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = t1.id
|
||||
union_reimburse info
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = buildCondition(year, unionId, unitId, reimburseProject, userName, "t1.");
|
||||
// 只查询流程实例状态为20的数据(已完成状态)
|
||||
cnd.and("ins.state", "=", 20);
|
||||
Cnd cnd = buildCondition(year, unionId, unitId, reimburseProject, searchKeyword, "info.");
|
||||
if (!isAdmin()) {
|
||||
cnd.andEX("t1.unionId", "=", SecurityUtil.getUnionId());
|
||||
cnd.andEX("info.unionId", "=", SecurityUtil.getUnionId());
|
||||
}
|
||||
cnd.desc("t1.createTime");
|
||||
applyListSort(cnd, pageForm);
|
||||
|
||||
sql.setCondition(cnd);
|
||||
List<UnionReimburseCollectExcelVO> list = unionReimburseService.listVO(sql,UnionReimburseCollectExcelVO.class);
|
||||
@@ -242,11 +237,13 @@ public class UnionReimburseCollectController {
|
||||
item.setCreateTime(DateUtil.format(DateUtil.parse(item.getCreateTime()), "yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
|
||||
// 拼接备注字段(仿照系统代码逻辑,使用activityName和condolenceName字段)
|
||||
item.setStateName(formatStateName(item.getStateId()));
|
||||
|
||||
// 备注字段与页面表格保持一致:慰问显示被慰问人,其他项目显示活动名称。
|
||||
if (cn.hutool.core.util.StrUtil.isNotBlank(item.getActivityName())) {
|
||||
item.setRemark("活动名称:" + item.getActivityName());
|
||||
} else if (cn.hutool.core.util.StrUtil.isNotBlank(item.getCondolenceName())) {
|
||||
item.setRemark("慰问对象:" + item.getCondolenceName());
|
||||
} else if (cn.hutool.core.util.StrUtil.isNotBlank(item.getCondolenceUserName())) {
|
||||
item.setRemark("被慰问人:" + item.getCondolenceUserName());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -263,12 +260,12 @@ public class UnionReimburseCollectController {
|
||||
* @param unionId 工会ID
|
||||
* @param unitId 单位ID
|
||||
* @param reimburseProject 报销项目
|
||||
* @param userName 经办人姓名
|
||||
* @param searchKeyword 经办人姓名或工号
|
||||
* @param prefix 表前缀
|
||||
* @return 查询条件
|
||||
*/
|
||||
private Cnd buildCondition(Integer year, String unionId, String unitId,
|
||||
String reimburseProject, String userName, String prefix) {
|
||||
String reimburseProject, String searchKeyword, String prefix) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
|
||||
// 年度查询条件
|
||||
@@ -281,9 +278,12 @@ public class UnionReimburseCollectController {
|
||||
// 报销项目查询条件
|
||||
cnd.andEX(prefix + "reimburseProject", "=", reimburseProject);
|
||||
|
||||
// 经办人姓名查询条件
|
||||
if (StrUtil.isNotBlank(userName)) {
|
||||
cnd.and(prefix + "userName", "like", "%" + userName + "%");
|
||||
// 经办人姓名或工号查询条件
|
||||
if (StrUtil.isNotBlank(searchKeyword)) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
seg.orLike(prefix + "userName", searchKeyword);
|
||||
seg.orLike(prefix + "loginName", searchKeyword);
|
||||
cnd.and(seg);
|
||||
}
|
||||
|
||||
return cnd;
|
||||
@@ -318,4 +318,18 @@ public class UnionReimburseCollectController {
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private String formatStateName(Integer stateId) {
|
||||
if (stateId == null) {
|
||||
return "";
|
||||
}
|
||||
return switch (stateId) {
|
||||
case 1 -> "待提交";
|
||||
case 2 -> "待审核确认";
|
||||
case 3 -> "报销成功";
|
||||
case 4 -> "拒绝";
|
||||
case 5 -> "退回";
|
||||
default -> String.valueOf(stateId);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -175,6 +175,11 @@ public class UnionReimburse extends BaseModel {
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String bankOfDeposit;
|
||||
|
||||
@Column
|
||||
@Comment("支付明细")
|
||||
@ColDefine(type = ColType.MYSQL_JSON)
|
||||
private List<JSONObject> paymentDetails;
|
||||
|
||||
/**
|
||||
* 慰问
|
||||
*/
|
||||
|
||||
+20
-8
@@ -369,13 +369,15 @@ public class UnionReimburseServiceImpl extends BaseServiceImpl<UnionReimburse> i
|
||||
if (Integer.valueOf(3).equals(dbRecord.getStateId())) {
|
||||
return Result.success();
|
||||
}
|
||||
Result validateResult = validateFundSourceBeforeSubmit(dbRecord);
|
||||
if (validateResult != null) {
|
||||
return validateResult;
|
||||
}
|
||||
Result deductResult = deductBudgetAndSaveUseDetail(dbRecord);
|
||||
if (deductResult != null && deductResult.getCode() != 0) {
|
||||
return deductResult;
|
||||
if (!skipBudgetDeduct(dbRecord)) {
|
||||
Result validateResult = validateFundSourceBeforeSubmit(dbRecord);
|
||||
if (validateResult != null) {
|
||||
return validateResult;
|
||||
}
|
||||
Result deductResult = deductBudgetAndSaveUseDetail(dbRecord);
|
||||
if (deductResult != null && deductResult.getCode() != 0) {
|
||||
return deductResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
dbRecord.setReviewTime(new Date());
|
||||
@@ -422,7 +424,7 @@ public class UnionReimburseServiceImpl extends BaseServiceImpl<UnionReimburse> i
|
||||
if (dbRecord == null) {
|
||||
return Result.error("未找到对应的报销记录");
|
||||
}
|
||||
if (Integer.valueOf(3).equals(dbRecord.getStateId())) {
|
||||
if (Integer.valueOf(3).equals(dbRecord.getStateId()) && !skipBudgetDeduct(dbRecord)) {
|
||||
OutlayUseDetail oldDetail = dao().fetch(OutlayUseDetail.class, Cnd.where("outlayReimburseId", "=", dbRecord.getId()));
|
||||
BigDecimal oldMoney = oldDetail != null && oldDetail.getAdjustMoney() != null
|
||||
? oldDetail.getAdjustMoney()
|
||||
@@ -652,6 +654,16 @@ public class UnionReimburseServiceImpl extends BaseServiceImpl<UnionReimburse> i
|
||||
return Result.error("不支持的经费来源");
|
||||
}
|
||||
|
||||
/**
|
||||
* 慰问和专项活动费用不占用经费预算,审核通过及后续调整实际金额时都不写预算台账。
|
||||
*/
|
||||
private boolean skipBudgetDeduct(UnionReimburse unionReimburse) {
|
||||
return unionReimburse != null && Set.of(
|
||||
"UNION_REIMBURSE_PROJECT_1",
|
||||
"UNION_REIMBURSE_PROJECT_4"
|
||||
).contains(unionReimburse.getReimburseProject());
|
||||
}
|
||||
|
||||
/**
|
||||
* 已通过报销单修改实际金额时,用差额同步预算主表和使用明细,避免重复全量扣减。
|
||||
*/
|
||||
|
||||
+10
-3
@@ -22,23 +22,30 @@ public class UnionReimburseCollectExcelVO implements Serializable {
|
||||
@Excel(name = "所属单位", width = 20)
|
||||
private String unitName;
|
||||
|
||||
@Excel(name = "申请时间", width = 30)
|
||||
private String createTime;
|
||||
|
||||
@Excel(name = "报销项目", width = 20)
|
||||
private String reimburseProject;
|
||||
|
||||
@Excel(name = "备注", width = 20)
|
||||
private String remark;
|
||||
|
||||
@Excel(name = "金额", width = 20)
|
||||
@Excel(name = "申请状态", width = 20)
|
||||
private String stateName;
|
||||
|
||||
private Double money;
|
||||
|
||||
@Excel(name = "申请时间", width = 30)
|
||||
private String createTime;
|
||||
private Integer stateId;
|
||||
|
||||
private String reimburseFundSource;
|
||||
|
||||
//活动名称
|
||||
private String activityName;
|
||||
|
||||
//被慰问人姓名
|
||||
private String condolenceUserName;
|
||||
|
||||
//被慰问人
|
||||
private String condolenceName;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user