feat: 报销模块相关功能调整

new
chenqp 1 year ago
parent 694242b012
commit 92c6d02b6b

@ -48,7 +48,9 @@ public class ServiceExceptionUtil {
String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMsg()); String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMsg());
return exception0(errorCode.getCode(), messagePattern); return exception0(errorCode.getCode(), messagePattern);
} }
public static ServiceException exception(String message) {
return exception0(500, message);
}
public static ServiceException exception(ErrorCode errorCode, Object... params) { public static ServiceException exception(ErrorCode errorCode, Object... params) {
String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMsg()); String messagePattern = MESSAGES.getOrDefault(errorCode.getCode(), errorCode.getMsg());
return exception0(errorCode.getCode(), messagePattern, params); return exception0(errorCode.getCode(), messagePattern, params);

@ -7,6 +7,8 @@ import javax.validation.constraints.Min;
import javax.validation.constraints.Max; import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collection;
import java.util.List;
@Schema(description="分页参数") @Schema(description="分页参数")
@Data @Data
@ -26,4 +28,5 @@ public class PageParam implements Serializable {
@Max(value = 1000, message = "每页条数最大值为 1000") @Max(value = 1000, message = "每页条数最大值为 1000")
private Integer pageSize = PAGE_SIZE; private Integer pageSize = PAGE_SIZE;
private List<SortingField> sortingFields;
} }

@ -25,7 +25,7 @@ public class MyBatisUtils {
private static final String MYSQL_ESCAPE_CHARACTER = "`"; private static final String MYSQL_ESCAPE_CHARACTER = "`";
public static <T> Page<T> buildPage(PageParam pageParam) { public static <T> Page<T> buildPage(PageParam pageParam) {
return buildPage(pageParam, null); return buildPage(pageParam, pageParam.getSortingFields());
} }
public static <T> Page<T> buildPage(PageParam pageParam, Collection<SortingField> sortingFields) { public static <T> Page<T> buildPage(PageParam pageParam, Collection<SortingField> sortingFields) {

@ -64,7 +64,12 @@ public class ExpenseClaimController {
return expenseClaimService.createExpenseClaim(createReqVO); return expenseClaimService.createExpenseClaim(createReqVO);
} }
@PostMapping("/settle")
@Operation(summary = "结算")
@PreAuthorize("@ss.hasPermission('bs:expense-claim:settle')")
public CommonResult settle(@Valid @RequestBody BillIdReqVO billIdReqVO) {
return expenseClaimService.settle(billIdReqVO);
}
@DeleteMapping("/delete") @DeleteMapping("/delete")
@Operation(summary = "删除报销单") @Operation(summary = "删除报销单")
@Parameter(name = "id", description = "编号", required = true) @Parameter(name = "id", description = "编号", required = true)

@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.bpm.service.expenseclaim;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.bs.controller.admin.expenseclaim.vo.ExpenseClaimCreateReqVO; import cn.iocoder.yudao.module.bs.controller.admin.expenseclaim.vo.*;
import cn.iocoder.yudao.module.bs.controller.admin.expenseclaim.vo.ExpenseClaimExportReqVO;
import cn.iocoder.yudao.module.bs.controller.admin.expenseclaim.vo.ExpenseClaimPageReqVO;
import cn.iocoder.yudao.module.bs.controller.admin.expenseclaim.vo.ExpenseClaimUpdateReqVO;
import cn.iocoder.yudao.module.bs.dal.dataobject.expenseclaim.ExpenseClaimDO; import cn.iocoder.yudao.module.bs.dal.dataobject.expenseclaim.ExpenseClaimDO;
import com.github.yulichang.base.MPJBaseService; import com.github.yulichang.base.MPJBaseService;
@ -75,4 +72,6 @@ public interface ExpenseClaimService extends MPJBaseService<ExpenseClaimDO> {
void setDeptNameField(List<ExpenseClaimDO> toList); void setDeptNameField(List<ExpenseClaimDO> toList);
void processInstanceCallBack(long id, Integer result); void processInstanceCallBack(long id, Integer result);
CommonResult settle(BillIdReqVO billIdReqVO);
} }

@ -20,6 +20,7 @@ import cn.iocoder.yudao.module.bs.dal.mysql.expenseclaim.ExpenseClaimMapper;
import cn.iocoder.yudao.module.bs.enums.BillTypeEnum; import cn.iocoder.yudao.module.bs.enums.BillTypeEnum;
import cn.iocoder.yudao.module.bs.enums.ExpenseApplyStatusEnum; import cn.iocoder.yudao.module.bs.enums.ExpenseApplyStatusEnum;
import cn.iocoder.yudao.module.bs.enums.ExpenseClaimSettleStatusEnum; import cn.iocoder.yudao.module.bs.enums.ExpenseClaimSettleStatusEnum;
import cn.iocoder.yudao.module.bs.service.budget.BudgetService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
@ -63,7 +64,9 @@ public class ExpenseClaimServiceImpl extends MPJBaseServiceImpl<ExpenseClaimMapp
private DeptApi deptApi; private DeptApi deptApi;
@Resource @Resource
private BpmProcessInstanceApi processInstanceApi; private BpmProcessInstanceApi processInstanceApi;
@Resource
@Lazy
private BudgetService budgetService;
@Override @Override
public CommonResult createExpenseClaim(ExpenseClaimCreateReqVO createReqVO) { public CommonResult createExpenseClaim(ExpenseClaimCreateReqVO createReqVO) {
// 插入 // 插入
@ -251,4 +254,13 @@ public class ExpenseClaimServiceImpl extends MPJBaseServiceImpl<ExpenseClaimMapp
} }
} }
@Override
public CommonResult settle(BillIdReqVO billIdReqVO) {
ExpenseClaimDO claimDO = validateExpenseClaimExists(billIdReqVO.getId());
claimDO.setSettleStatus(ExpenseClaimSettleStatusEnum.FINISH.getValue());
updateById(claimDO);
//更新预算使用金额
CommonResult result = budgetService.updateByClaimSettle(claimDO);
return CommonResult.success();
}
} }

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.bs.controller.admin.expenseclaim.vo;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.ImageVo;
import cn.iocoder.yudao.module.bs.enums.BillTypeEnum;
import cn.iocoder.yudao.module.bs.enums.ExpenseApplyStatusEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
import javax.validation.Valid;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
@Schema(description = "管理后台 - 单据ID Request VO")
@Data
@ToString(callSuper = true)
public class BillIdReqVO {
@Schema(description = "id")
@NotNull(message = "id不能为空")
private Long id;
}

@ -4,6 +4,9 @@ import cn.iocoder.yudao.framework.common.pojo.ImageVo;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
@ -17,20 +20,22 @@ import java.util.Set;
public class FeeManageBaseVO { public class FeeManageBaseVO {
@Schema(description = "部门ID", example = "29962") @Schema(description = "部门ID", example = "29962")
@NotBlank(message = "部门不能为空")
private Long deptId; private Long deptId;
@Schema(description = "角色", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "角色", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "角色不能为空") @NotEmpty(message = "角色不能为空")
private Set<Long> roleIds; private Set<Long> roleIds;
@Schema(description = "费用类型", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "费用类型", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "费用类型不能为空") @NotNull(message = "费用类型不能为空")
private String feeType; private String feeType;
@Schema(description = "限定金额", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "限定金额", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "限定金额不能为空") @NotNull(message = "限定金额不能为空")
@Min(value = 0, message = "限定金额需要大于等于 0")
private BigDecimal amount; private BigDecimal amount;
@Schema(description = "出差区域", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "出差区域", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "出差区域不能为空") @NotEmpty(message = "出差区域不能为空")
private List<String> area; private List<String> area;
@Schema(description = "备注", example = "你说的对") @Schema(description = "备注", example = "你说的对")

@ -1,11 +1,13 @@
package cn.iocoder.yudao.module.bs.service.budget; package cn.iocoder.yudao.module.bs.service.budget;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetCreateReqVO; import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetCreateReqVO;
import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetExportReqVO; import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetExportReqVO;
import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetPageReqVO; import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetPageReqVO;
import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetUpdateReqVO; import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetUpdateReqVO;
import cn.iocoder.yudao.module.bs.dal.dataobject.budget.BudgetDO; import cn.iocoder.yudao.module.bs.dal.dataobject.budget.BudgetDO;
import cn.iocoder.yudao.module.bs.dal.dataobject.expenseclaim.ExpenseClaimDO;
import com.github.yulichang.base.MPJBaseService; import com.github.yulichang.base.MPJBaseService;
import javax.validation.Valid; import javax.validation.Valid;
@ -73,4 +75,5 @@ public interface BudgetService extends MPJBaseService<BudgetDO> {
*/ */
List<BudgetDO> getBudgetList(BudgetExportReqVO exportReqVO); List<BudgetDO> getBudgetList(BudgetExportReqVO exportReqVO);
CommonResult updateByClaimSettle(ExpenseClaimDO claimDO);
} }

@ -1,14 +1,22 @@
package cn.iocoder.yudao.module.bs.service.budget; package cn.iocoder.yudao.module.bs.service.budget;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetCreateReqVO; import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetCreateReqVO;
import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetExportReqVO; import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetExportReqVO;
import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetPageReqVO; import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetPageReqVO;
import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetUpdateReqVO; import cn.iocoder.yudao.module.bs.controller.admin.budget.vo.BudgetUpdateReqVO;
import cn.iocoder.yudao.module.bs.convert.budget.BudgetConvert; import cn.iocoder.yudao.module.bs.convert.budget.BudgetConvert;
import cn.iocoder.yudao.module.bs.dal.dataobject.budget.BudgetDO; import cn.iocoder.yudao.module.bs.dal.dataobject.budget.BudgetDO;
import cn.iocoder.yudao.module.bs.dal.dataobject.expenseclaim.ExpenseClaimDO;
import cn.iocoder.yudao.module.bs.dal.mysql.budget.BudgetMapper; import cn.iocoder.yudao.module.bs.dal.mysql.budget.BudgetMapper;
import com.github.yulichang.base.MPJBaseServiceImpl; import com.github.yulichang.base.MPJBaseServiceImpl;
import org.apache.commons.io.filefilter.FalseFileFilter;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -36,6 +44,7 @@ public class BudgetServiceImpl extends MPJBaseServiceImpl<BudgetMapper, BudgetDO
public Long createBudget(BudgetCreateReqVO createReqVO) { public Long createBudget(BudgetCreateReqVO createReqVO) {
// 插入 // 插入
BudgetDO budget = BudgetConvert.INSTANCE.convert(createReqVO); BudgetDO budget = BudgetConvert.INSTANCE.convert(createReqVO);
setBaseField(budget); setBaseField(budget);
budgetMapper.insert(budget); budgetMapper.insert(budget);
// 返回 // 返回
@ -53,6 +62,15 @@ public class BudgetServiceImpl extends MPJBaseServiceImpl<BudgetMapper, BudgetDO
} }
private void setBaseField(BudgetDO budget) { private void setBaseField(BudgetDO budget) {
boolean isAdd = budget.getId() == null ? true : false;
BudgetDO budgetDO = getBudgetDO(budget.getDeptId(), DateUtil.beginOfYear(DateUtil.date()));
if (isAdd && budgetDO != null) {
throw exception(new ErrorCode(500, "保存失败,当前部门该年度预算数据已存在"));
}
if (!isAdd && !budgetDO.getId().equals(budget.getId())) {
throw exception(new ErrorCode(500, "保存失败,当前部门该年度预算数据已存在"));
}
budget.setBudgetYear(DateUtil.beginOfYear(DateUtil.date(budget.getBudgetYear())).toLocalDateTime());
budget.setOccupyAmount(BigDecimal.ZERO); budget.setOccupyAmount(BigDecimal.ZERO);
budget.setUsedAmount(BigDecimal.ZERO); budget.setUsedAmount(BigDecimal.ZERO);
budget.setRemainAmount(BigDecimal.ZERO); budget.setRemainAmount(BigDecimal.ZERO);
@ -92,4 +110,23 @@ public class BudgetServiceImpl extends MPJBaseServiceImpl<BudgetMapper, BudgetDO
return budgetMapper.selectList(exportReqVO); return budgetMapper.selectList(exportReqVO);
} }
@Override
public CommonResult updateByClaimSettle(ExpenseClaimDO claimDO) {
BudgetDO budgetDO = getBudgetDO(claimDO.getCostDeptId(), DateUtil.beginOfYear(DateUtil.date(claimDO.getCreateTime())));
if (budgetDO != null) {
budgetDO.setUsedAmount(budgetDO.getUsedAmount().add(claimDO.getAmount()));
budgetDO.setRemainAmount(NumberUtil.max(BigDecimal.ZERO, budgetDO.getAmount().subtract(budgetDO.getUsedAmount())));
updateById(budgetDO);
}
return CommonResult.success();
}
private BudgetDO getBudgetDO(Long deptId, DateTime dateTime) {
LambdaQueryWrapperX<BudgetDO> query = new LambdaQueryWrapperX<>();
//根据部门和年度查找预算
query.eq(BudgetDO::getDeptId, deptId);
query.apply("budget_year = {0}", dateTime);
BudgetDO budgetDO = getOne(query);
return budgetDO;
}
} }

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.bs.service.feemanage; package cn.iocoder.yudao.module.bs.service.feemanage;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.bs.controller.admin.feemanage.vo.FeeManageCreateReqVO; import cn.iocoder.yudao.module.bs.controller.admin.feemanage.vo.FeeManageCreateReqVO;
import cn.iocoder.yudao.module.bs.controller.admin.feemanage.vo.FeeManageExportReqVO; import cn.iocoder.yudao.module.bs.controller.admin.feemanage.vo.FeeManageExportReqVO;
import cn.iocoder.yudao.module.bs.controller.admin.feemanage.vo.FeeManagePageReqVO; import cn.iocoder.yudao.module.bs.controller.admin.feemanage.vo.FeeManagePageReqVO;
@ -35,17 +36,38 @@ public class FeeManageServiceImpl extends MPJBaseServiceImpl<FeeManageMapper, Fe
public Long createFeeManage(FeeManageCreateReqVO createReqVO) { public Long createFeeManage(FeeManageCreateReqVO createReqVO) {
// 插入 // 插入
FeeManageDO feeManage = FeeManageConvert.INSTANCE.convert(createReqVO); FeeManageDO feeManage = FeeManageConvert.INSTANCE.convert(createReqVO);
checkExisit(feeManage);
feeManageMapper.insert(feeManage); feeManageMapper.insert(feeManage);
// 返回 // 返回
return feeManage.getId(); return feeManage.getId();
} }
private void checkExisit(FeeManageDO feeManage) {
for (Long roleId : feeManage.getRoleIds()) {
for (String area : feeManage.getArea()) {
LambdaQueryWrapperX<FeeManageDO> query = new LambdaQueryWrapperX<>();
query.eq(FeeManageDO::getDeptId, feeManage.getDeptId());
query.eq(FeeManageDO::getFeeType, feeManage.getFeeType());
query.apply("FIND_IN_SET({0}, role_ids) > 0",roleId);
query.apply("FIND_IN_SET({0}, area) > 0",area);
if (feeManage.getId() != null) {
query.ne(FeeManageDO::getId, feeManage.getId());
}
FeeManageDO feeManageDO = getOne(query);
if (feeManageDO != null) {
throw exception("保存失败,已存在相同费用类型、角色、区域、部门的费控配置");
}
}
}
}
@Override @Override
public void updateFeeManage(FeeManageUpdateReqVO updateReqVO) { public void updateFeeManage(FeeManageUpdateReqVO updateReqVO) {
// 校验存在 // 校验存在
validateFeeManageExists(updateReqVO.getId()); validateFeeManageExists(updateReqVO.getId());
// 更新 // 更新
FeeManageDO updateObj = FeeManageConvert.INSTANCE.convert(updateReqVO); FeeManageDO updateObj = FeeManageConvert.INSTANCE.convert(updateReqVO);
checkExisit(updateObj);
feeManageMapper.updateById(updateObj); feeManageMapper.updateById(updateObj);
} }

Loading…
Cancel
Save