材料站结算

This commit is contained in:
mashuai 2025-10-09 15:36:22 +08:00
parent b123d9c2b7
commit d93c4a38f9
6 changed files with 264 additions and 89 deletions

View File

@ -12,18 +12,14 @@ import com.bonus.material.clz.domain.vo.MaterialSltAgreementInfo;
import com.bonus.material.clz.domain.vo.sltAgreementInfo.MaterialSltInfoVo;
import com.bonus.material.clz.service.ClzSltAgreementInfoService;
import com.bonus.material.common.domain.dto.SelectDto;
import com.bonus.material.settlement.domain.SltAgreementApply;
import com.bonus.material.settlement.domain.SltAgreementInfo;
import com.bonus.material.settlement.domain.vo.SltInfoVo;
import com.bonus.material.task.domain.TmTask;
import com.bonus.material.task.mapper.TmTaskMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@Api(tags = "材料站结算申请接口")
@ -75,8 +71,8 @@ public class ClzSltAgreementInfoController extends BaseController {
}
@ApiOperation(value = "根据结算单号查询已提交的结算信息")
@PostMapping("/getSettledInfo")
public AjaxResult getSettledDetailsByApplyCode(@RequestBody MaterialSltAgreementInfo requestDto) {
@GetMapping("/getSettledInfo")
public AjaxResult getSettledDetailsByApplyCode(MaterialSltAgreementInfo requestDto) {
if (requestDto == null) {
throw new ServiceException("请求参数不能为空!");
}
@ -90,6 +86,19 @@ public class ClzSltAgreementInfoController extends BaseController {
return AjaxResult.success(resultList);
}
/**
* 进行结算审批
*/
@ApiOperation(value = "进行结算审批")
@PostMapping("/costExamine")
public AjaxResult costExamine(@RequestBody SltAgreementApply apply) {
try {
return clzSltAgreementInfoService.costExamine(apply);
} catch (Exception e) {
return error("系统错误, " + e.getMessage());
}
}
/**
* 提交结算清单

View File

@ -114,8 +114,12 @@ public class MaterialSltInfoVo {
private Long id; //申请id
@ApiModelProperty(value = "费用合计")
String cost;
@ApiModelProperty(value = "申请单号")
private String code;
@ApiModelProperty(value = "申请时间")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date applyTime;

View File

@ -4,6 +4,7 @@ import com.bonus.common.biz.domain.ProjectTreeNode;
import com.bonus.material.clz.domain.vo.MaterialSltAgreementInfo;
import com.bonus.material.clz.domain.vo.sltAgreementInfo.MaterialSltInfoVo;
import com.bonus.material.common.domain.vo.AgreementVo;
import com.bonus.material.settlement.domain.SltAgreementApply;
import com.bonus.material.settlement.domain.SltAgreementInfo;
import com.bonus.material.settlement.domain.SltAgreementReduce;
import org.apache.ibatis.annotations.Param;
@ -16,6 +17,30 @@ import java.util.List;
*/
public interface ClzSltAgreementInfoMapper {
/**
* 进行结算审批
*
* @param sltAgreementApply 进行结算审批
* @return 结果
*/
int costExame(SltAgreementApply sltAgreementApply);
/**
* 根据结算单号查找协议ids
* @param applyCode 结算单号
* @return 协议集合
*/
List<Long> getSltAgreementIdsBySltApplyCode(String applyCode);
/**
* 更新协议结算状态
*/
int updateClzSltInfoByIds(@Param("agreementIds") List<Long> agreementIds);
/**
* 更新协议明细表状态
*/
int updateClzSltDetailsByIds(@Param("agreementIds") List<Long> agreementIds);
/**
* 查询结算审批列表

View File

@ -6,8 +6,8 @@ import com.bonus.material.clz.domain.ClzSltApplyDTO;
import com.bonus.material.clz.domain.vo.MaterialSltAgreementInfo;
import com.bonus.material.clz.domain.vo.sltAgreementInfo.MaterialSltInfoVo;
import com.bonus.material.common.domain.dto.SelectDto;
import com.bonus.material.settlement.domain.SltAgreementApply;
import com.bonus.material.settlement.domain.SltAgreementInfo;
import com.bonus.material.settlement.domain.vo.SltInfoVo;
import java.util.List;
@ -17,6 +17,11 @@ import java.util.List;
*/
public interface ClzSltAgreementInfoService {
/**
* 进行结算审批
*/
AjaxResult costExamine(SltAgreementApply sltAgreementApply);
/**
* 根据条件获取协议结算列表
*/

View File

@ -1,8 +1,7 @@
package com.bonus.material.clz.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.IdUtil;
import com.bonus.common.biz.constant.GlobalConstants;
import com.bonus.common.biz.domain.ProjectTreeBuild;
import com.bonus.common.biz.domain.ProjectTreeNode;
@ -18,10 +17,10 @@ import com.bonus.material.clz.mapper.ClzSltAgreementInfoMapper;
import com.bonus.material.clz.service.ClzSltAgreementInfoService;
import com.bonus.material.common.domain.dto.SelectDto;
import com.bonus.material.common.domain.vo.AgreementVo;
import com.bonus.material.settlement.domain.SltAgreementApply;
import com.bonus.material.settlement.domain.SltAgreementInfo;
import com.bonus.material.settlement.domain.SltAgreementReduce;
import com.bonus.material.settlement.domain.SltAgreementRelation;
import com.bonus.material.settlement.domain.vo.SltInfoVo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
@ -40,9 +39,65 @@ import java.util.stream.Collectors;
@Service
public class ClzSltAgreementInfoServiceImpl implements ClzSltAgreementInfoService {
// 结算审核通过
private static final String REVIEW_PASS = "2";
// 结算审核驳回
private static final String REVIEW_REJECT = "3";
@Resource
private ClzSltAgreementInfoMapper clzSltAgreementInfoMapper;
/**
* 进行结算审批
*
* @param sltAgreementApply
*/
@Override
public AjaxResult costExamine(SltAgreementApply sltAgreementApply) {
if (Objects.isNull(sltAgreementApply) || Objects.isNull(sltAgreementApply.getStatus())) {
return AjaxResult.error("结算信息为空,请刷新后重试!");
}
try {
sltAgreementApply.setAuditor(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
sltAgreementApply.setAuditTime(DateUtils.getNowDate());
sltAgreementApply.setUpdateTime(DateUtils.getNowDate());
if (sltAgreementApply.getCode() == null) {
return AjaxResult.error("缺少结算单号!");
}
List<Long> idsBySltApplyCode = clzSltAgreementInfoMapper.getSltAgreementIdsBySltApplyCode(sltAgreementApply.getCode());
if (Objects.equals(REVIEW_REJECT, sltAgreementApply.getStatus())) {
// 驳回更新slt_apply协议审批状态
int updateNum = clzSltAgreementInfoMapper.costExame(sltAgreementApply);
// 删除结算详情,后续删除
//clzSltAgreementInfoMapper.costDeleteDetail(sltAgreementApply);
if (updateNum != GlobalConstants.INT_1) {
return AjaxResult.error("结算审批失败");
} else {
return AjaxResult.success("驳回成功!");
}
} else if (Objects.equals(REVIEW_PASS, sltAgreementApply.getStatus())) {
// 通过更新slt_apply协议审批状态
int examNum = clzSltAgreementInfoMapper.costExame(sltAgreementApply);
if (examNum == GlobalConstants.INT_0) {
return AjaxResult.error("结算审批失败");
} else {
// 更新结算协议表及相关信息
clzSltAgreementInfoMapper.updateClzSltInfoByIds(idsBySltApplyCode);
clzSltAgreementInfoMapper.updateClzSltDetailsByIds(idsBySltApplyCode);
return AjaxResult.success();
}
} else {
return AjaxResult.error("审批错误,状态码错误");
}
} catch (Exception e) {
return AjaxResult.error();
}
}
/**
* 根据条件获取协议结算列表
* @param bean 查询条件
@ -147,53 +202,88 @@ public class ClzSltAgreementInfoServiceImpl implements ClzSltAgreementInfoServic
// 查询各项费用列表
List<MaterialSltAgreementInfo> sltedList = clzSltAgreementInfoMapper.getSltedList(info);
// 按照协议进行分组
if (CollectionUtils.isEmpty(sltedList)) {
throw new ServiceException("未查询到已结算信息!");
}
// 定义遍历集合
Map<Long, List<MaterialSltAgreementInfo>> materialSltInfoResultMap = sltedList.stream().collect(Collectors.groupingBy(MaterialSltAgreementInfo::getAgreementId));
// 定义返回对象
List<MaterialSltInfoVo> resultVoList = new ArrayList<>();
sltedList.forEach((item) -> {
MaterialSltInfoVo sltInfoVo = new MaterialSltInfoVo();
BigDecimal leaseCost = BigDecimal.ZERO, repairCost = BigDecimal.ZERO, scrapCost = BigDecimal.ZERO;
BigDecimal loseCost = BigDecimal.ZERO, reducCost = BigDecimal.ZERO;
//租赁费用列表
List<MaterialSltAgreementInfo> leaseList = sltedList.stream().filter(slt -> slt.getSltType() == 1).collect(Collectors.toList());
//维修费用列表
List<MaterialSltAgreementInfo> repairList = sltedList.stream().filter(slt -> slt.getSltType() == 3).collect(Collectors.toList());
//报废费用列表
List<MaterialSltAgreementInfo> scrapList = sltedList.stream().filter(slt -> slt.getSltType() == 4).collect(Collectors.toList());
//丢失费用列表
List<MaterialSltAgreementInfo> loseList = sltedList.stream().filter(slt -> slt.getSltType() == 2).collect(Collectors.toList());
sltInfoVo.setLeaseList(leaseList);
sltInfoVo.setRepairList(repairList);
sltInfoVo.setScrapList(scrapList);
sltInfoVo.setLoseList(loseList);
sltInfoVo.setReductionList(Collections.emptyList());
for (MaterialSltAgreementInfo lease : leaseList) {
if(lease.getCosts()!=null){
leaseCost = leaseCost.add(lease.getCosts());
}
}
for (MaterialSltAgreementInfo lose : loseList) {
if(lose.getCosts()!=null){
loseCost = loseCost.add(lose.getCosts());
}
for (List<MaterialSltAgreementInfo> key : materialSltInfoResultMap.values()) {
if (CollectionUtils.isEmpty(key)) {
throw new ServiceException("已结算信息异常,请联系管理员!");
}
sltInfoVo.setLeaseCost(leaseCost);
sltInfoVo.setRepairCost(repairCost);
sltInfoVo.setScrapCost(scrapCost);
sltInfoVo.setLoseCost(loseCost);
sltInfoVo.setReductionCost(reducCost);
List<SltAgreementRelation> relations = getRelations(leaseList, repairList, scrapList, loseList, info);
sltInfoVo.setRelations(relations);
key.forEach((item) -> {
MaterialSltInfoVo sltInfoVo = new MaterialSltInfoVo();
BigDecimal leaseCost = BigDecimal.ZERO, repairCost = BigDecimal.ZERO, scrapCost = BigDecimal.ZERO;
BigDecimal loseCost = BigDecimal.ZERO, reducCost = BigDecimal.ZERO;
resultVoList.add(sltInfoVo);
//租赁费用列表
List<MaterialSltAgreementInfo> leaseList = key.stream().filter(slt -> slt.getSltType() == 1).collect(Collectors.toList());
//维修费用列表
List<MaterialSltAgreementInfo> repairList = key.stream().filter(slt -> slt.getSltType() == 3).collect(Collectors.toList());
//报废费用列表
List<MaterialSltAgreementInfo> scrapList = key.stream().filter(slt -> slt.getSltType() == 4).collect(Collectors.toList());
//丢失费用列表
List<MaterialSltAgreementInfo> loseList = key.stream().filter(slt -> slt.getSltType() == 2).collect(Collectors.toList());
// 给外层的单位名称/工程名称赋值
extractInnerNameToOuter(resultVoList, sltInfoVo);
});
return resultVoList;
sltInfoVo.setLeaseList(leaseList);
sltInfoVo.setRepairList(repairList);
sltInfoVo.setScrapList(scrapList);
sltInfoVo.setLoseList(loseList);
sltInfoVo.setReductionList(Collections.emptyList());
for (MaterialSltAgreementInfo lease : leaseList) {
if (lease.getCosts() != null) {
leaseCost = leaseCost.add(lease.getCosts());
}
}
for (MaterialSltAgreementInfo lose : loseList) {
if (lose.getCosts() != null) {
loseCost = loseCost.add(lose.getCosts());
}
}
sltInfoVo.setLeaseCost(leaseCost);
sltInfoVo.setRepairCost(repairCost);
sltInfoVo.setScrapCost(scrapCost);
sltInfoVo.setLoseCost(loseCost);
sltInfoVo.setReductionCost(reducCost);
List<SltAgreementRelation> relations = getRelations(leaseList, repairList, scrapList, loseList, info);
sltInfoVo.setRelations(relations);
resultVoList.add(sltInfoVo);
// 给外层的单位名称/工程名称赋值
extractInnerNameToOuter(resultVoList, sltInfoVo);
});
}
// 返回之前对集合做去重处理根据外层的单位名称去重,保留每个单位名称的第一个
Set<String> seen = new HashSet<>();
List<MaterialSltInfoVo> dedup = new ArrayList<>(resultVoList.size());
for (MaterialSltInfoVo it : resultVoList) {
if (it == null) continue;
String key = normalize(it.getUnitName());
// 若不希望把 null 当作一个有效键可加if (key == null) continue;
if (seen.add(key)) {
dedup.add(it); // 第一次见到该单位名 -> 保留
}
}
return dedup;
}
private static String normalize(String s) {
if (s == null) return null; // 若希望丢弃 null可直接返回 null 不参与去重键
return s.trim(); // 需要忽略大小写可用s.trim().toLowerCase(Locale.ROOT)
}
/**
@ -411,8 +501,10 @@ public class ClzSltAgreementInfoServiceImpl implements ClzSltAgreementInfoServic
public int submitCosts(MaterialSltInfoVo sltInfoVo) {
try {
if (sltInfoVo.getAgreementIds() != null && sltInfoVo.getAgreementIds().length > 0) {
// 生成uuid使其成为一个批次
String fastUUID = IdUtil.fastUUID();
for (Long agreementId : sltInfoVo.getAgreementIds()) {
Long id = null;
Long id;
sltInfoVo.setAgreementId(agreementId);
// 计算总成本
BigDecimal totalCost = BigDecimal.ZERO;
@ -449,6 +541,8 @@ public class ClzSltAgreementInfoServiceImpl implements ClzSltAgreementInfoServic
sltInfoVo.setUpdateTime(DateUtils.getNowDate());
sltInfoVo.setCreateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
} else {
// 生成统一批次号
sltInfoVo.setCode(fastUUID);
sltInfoVo.setCreateTime(DateUtils.getNowDate());
sltInfoVo.setCreateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
//新增
@ -461,6 +555,7 @@ public class ClzSltAgreementInfoServiceImpl implements ClzSltAgreementInfoServic
sltInfoVo.setUpdateTime(DateUtils.getNowDate());
}
// 插入结算明细表 -- 租赁
if (!sltInfoVo.getLeaseList().isEmpty()) {
List<MaterialSltAgreementInfo> filteredLeaseList = sltInfoVo.getLeaseList().stream()
.filter(lease -> lease.getAgreementId().equals(sltInfoVo.getAgreementId()))
@ -469,6 +564,7 @@ public class ClzSltAgreementInfoServiceImpl implements ClzSltAgreementInfoServic
clzSltAgreementInfoMapper.insertSltAgreementDetailLease(filteredLeaseList, id);
}
}
// 插入结算明细表 -- 丢失
if (!sltInfoVo.getLoseList().isEmpty()) {
List<MaterialSltAgreementInfo> filteredLoseList = sltInfoVo.getLoseList().stream()
.filter(lease -> lease.getAgreementId().equals(sltInfoVo.getAgreementId()))

View File

@ -7,7 +7,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
insert into clz_slt_agreement_apply
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="agreementId != null">agreement_id,</if>
<if test="agreementCode != null">code,</if>
<if test="code != null">`code`,</if>
<if test="createBy != null">creator,</if>
<if test="createTime != null">create_time,</if>
status,
@ -15,7 +15,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="agreementId != null">#{agreementId},</if>
<if test="agreementCode != null">#{agreementCode},</if>
<if test="code != null">#{code,jdbcType=VARCHAR},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
1,
@ -52,42 +52,42 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="getSltAgreementInfo4Project" resultType="com.bonus.material.clz.domain.vo.MaterialSltAgreementInfo">
SELECT
bai.agreement_id as agreementId, bai.agreement_code as agreementCode,
bui.unit_id as unitId,bui.unit_name as unitName, bp.pro_id as projectId , bp.pro_name as projectName,
saa.remark,bai.protocol,saa.cost as costs,
case when (saa.id is null or saa.status = '0') then '0' when saa.status = '1' then '1'
when saa.status = '2' then '2' when saa.status = '3' then '3' end as sltStatus
bai.agreement_id as agreementId, bai.agreement_code as agreementCode,
bui.unit_id as unitId,bui.unit_name as unitName, bp.pro_id as projectId , bp.pro_name as projectName,
saa.remark,bai.protocol,saa.cost as costs,
case when (saa.id is null or saa.status = '0') then '0' when saa.status = '1' then '1'
when saa.status = '2' then '2' when saa.status = '3' then '3' end as sltStatus
FROM
clz_slt_agreement_info sai
LEFT JOIN clz_bm_agreement_info bai ON bai.agreement_id = sai.agreement_id
LEFT JOIN bm_project bp ON bp.pro_id = bai.project_id
LEFT JOIN bm_unit bui ON bui.unit_id = bai.unit_id
LEFT JOIN clz_slt_agreement_apply saa on saa.agreement_id = bai.agreement_id
clz_slt_agreement_info sai
LEFT JOIN clz_bm_agreement_info bai ON bai.agreement_id = sai.agreement_id
LEFT JOIN bm_project bp ON bp.pro_id = bai.project_id
LEFT JOIN bm_unit bui ON bui.unit_id = bai.unit_id
LEFT JOIN clz_slt_agreement_apply saa on saa.agreement_id = bai.agreement_id
where
bai.status = '1'
<if test="unitIds != null">
and bui.unit_id in
<foreach item="item" index="index" collection="unitIds" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="projectId != null and projectId != ''">
and bp.pro_id = #{projectId}
</if>
<choose>
<when test="sltStatus == '0'.toString()">
and saa.id is null
</when>
<when test="sltStatus == '1'.toString()">
and saa.status = '1'
</when>
<when test="sltStatus == '2'.toString()">
and saa.status = '2'
</when>
<when test="sltStatus == '3'.toString()">
and saa.status = '3'
</when>
</choose>
bai.status = '1'
<if test="unitIds != null">
and bui.unit_id in
<foreach item="item" index="index" collection="unitIds" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="projectId != null and projectId != ''">
and bp.pro_id = #{projectId}
</if>
<choose>
<when test="sltStatus == '0'.toString()">
and saa.id is null
</when>
<when test="sltStatus == '1'.toString()">
and saa.status = '1'
</when>
<when test="sltStatus == '2'.toString()">
and saa.status = '2'
</when>
<when test="sltStatus == '3'.toString()">
and saa.status = '3'
</when>
</choose>
GROUP BY sai.agreement_id
ORDER BY sai.create_time desc
</select>
@ -293,4 +293,40 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where
saa.`code` = #{sltApplyCode}
</select>
<select id="costExame" resultType="int">
update clz_slt_agreement_apply
<set>
<if test="status != null and status!=''">status = #{status},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="auditTime != null">audit_time = #{auditTime},</if>
<if test="auditor != null and auditor!=''">auditor = #{auditor},</if>
<if test="remark != null and remark!=''">remark = #{remark}</if>
</set>
where `code` = #{code,jdbcType=VARCHAR}
</select>
<select id="getSltAgreementIdsBySltApplyCode" resultType="java.lang.Long">
select agreement_id
from clz_slt_agreement_apply
where `code` = #{sltApplyCode}
</select>
<update id="updateClzSltInfoByIds">
update clz_bm_agreement_info
set is_slt = 1, update_time = now(), slt_time = now()
where agreement_id in
<foreach item="item" index="index" collection="agreementIds" open="(" separator="," close=")">
#{item}
</foreach>
</update>
<update id="updateClzSltDetailsByIds">
update clz_slt_agreement_info
set end_time = now(), update_time = now()
where id in
<foreach item="item" index="index" collection="ids" open="(" separator="," close=")">
#{item}
</foreach>
</update>
</mapper>