功能重构开发

This commit is contained in:
2026-01-23 17:15:20 +08:00
parent 9b2b142347
commit 268e5f21fa
19 changed files with 577 additions and 301 deletions

View File

@@ -3,6 +3,7 @@ package com.zg.project.wisdom.controller;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.zg.project.wisdom.domain.dto.BorrowReturnDTO;
import com.zg.project.wisdom.domain.dto.RkBillCreateDTO; import com.zg.project.wisdom.domain.dto.RkBillCreateDTO;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -125,10 +126,10 @@ public class RkBillController extends BaseController
* 还料入库 * 还料入库
*/ */
@PreAuthorize("@ss.hasPermi('wisdom:bill:return:add')") @PreAuthorize("@ss.hasPermi('wisdom:bill:return:add')")
@Log(title = "还料入库", businessType = BusinessType.INSERT) @Log(title = "还料", businessType = BusinessType.UPDATE)
@PostMapping("/return/add") @PostMapping("/borrow/return")
public AjaxResult returnIn(@RequestBody RkBillCreateDTO dto) { public AjaxResult returnBorrow(@RequestBody BorrowReturnDTO dto) {
return toAjax(rkBillService.insertReturnBillAndDetail(dto)); return toAjax(rkBillService.returnBorrow(dto));
} }
} }

View File

@@ -2,6 +2,8 @@ package com.zg.project.wisdom.controller;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.zg.project.wisdom.domain.vo.StockStatisticVO;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -101,4 +103,13 @@ public class RkInfoController extends BaseController
{ {
return toAjax(rkInfoService.deleteRkInfoByIds(ids)); return toAjax(rkInfoService.deleteRkInfoByIds(ids));
} }
/**
* 库存统计(随查询条件动态变化)
*/
@PostMapping("/statistic")
public AjaxResult statistic(@RequestBody RkInfo query) {
return AjaxResult.success(rkInfoService.getStockStatistic(query));
}
} }

View File

@@ -162,4 +162,12 @@ public class RkRecordController extends BaseController
return toAjax(rkRecordService.deletePreOutRecords(ids)); return toAjax(rkRecordService.deletePreOutRecords(ids));
} }
/**
* 出入库统计(同时返回)
*/
@PostMapping("/statistic")
public AjaxResult statistic(@RequestBody RkRecord query) {
return AjaxResult.success(rkRecordService.getRecordStatistic(query));
}
} }

View File

@@ -43,6 +43,10 @@ public class RkRecord extends BaseEntity
@Excel(name = "施工队") @Excel(name = "施工队")
private String teamCode; private String teamCode;
/** 施工队名称(联表) */
@Excel(name = "施工队名称")
private String teamName;
/** 执行状态0预入/预出1已完成 */ /** 执行状态0预入/预出1已完成 */
@Excel(name = "执行状态", readConverterExp = "0=预操作,1=已完成") @Excel(name = "执行状态", readConverterExp = "0=预操作,1=已完成")
private String execStatus; private String execStatus;
@@ -222,7 +226,7 @@ public class RkRecord extends BaseEntity
private Long sid; private Long sid;
/** 是否需要配送(0否,1是,2配送中,3配送完成) */ /** 是否需要配送(0否,1是,2配送中,3配送完成) */
// @Excel(name = "是否需要配送(0否,1是,2配送中,3配送完成)") @Excel(name = "是否需要配送(0否,1是,2配送中,3配送完成)")
private String isDelivery; private String isDelivery;
/** 封样编号1 */ /** 封样编号1 */
@@ -645,6 +649,14 @@ public class RkRecord extends BaseEntity
return teamCode; return teamCode;
} }
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public void setBorrowTime(Date borrowTime) public void setBorrowTime(Date borrowTime)
{ {
this.borrowTime = borrowTime; this.borrowTime = borrowTime;
@@ -850,6 +862,7 @@ public class RkRecord extends BaseEntity
.append("trayCode", getTrayCode()) .append("trayCode", getTrayCode())
.append("entityId", getEntityId()) .append("entityId", getEntityId())
.append("teamCode", getTeamCode()) .append("teamCode", getTeamCode())
.append("teamName", teamName)
.append("borrowTime", getBorrowTime()) .append("borrowTime", getBorrowTime())
.append("returnTime", getReturnTime()) .append("returnTime", getReturnTime())
.append("hasMoved", getHasMoved()) .append("hasMoved", getHasMoved())

View File

@@ -0,0 +1,31 @@
package com.zg.project.wisdom.domain.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@Data
public class BorrowReturnDTO {
/** 原借料出库单据号 */
private String borrowBillNo;
/** 还料单据号(可不传,后端生成) */
private String returnBillNo;
/** 操作人 */
private Long operator;
/** 还料时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date returnTime;
/** 备注 */
private String remark;
/** 明细列表 */
private List<BorrowReturnItemDTO> items;
}

View File

@@ -0,0 +1,40 @@
package com.zg.project.wisdom.domain.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class BorrowReturnItemDTO {
/** 🔑 原借料出库记录 rk_record.id必须 */
private Long recordId;
/** 原 rk_info.id */
private Long rkInfoId;
/** 还料数量 */
private BigDecimal returnQty;
/** 库位 */
private String pcode;
/** 托盘 */
private String trayCode;
/** 实物ID */
private String entityId;
/** 借料时间(前端如果传) */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date borrowTime;
/** 还料时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date returnTime;
/** 备注 */
private String remark;
}

View File

@@ -1,39 +0,0 @@
package com.zg.project.wisdom.domain.vo;// package com.zg.project.wisdom.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class BillGroupVO {
/** 分组主键:统一用入库单号 bill_no若为空会用 bill_no_ck 兜底) */
private String billNo;
/** 出库单号(出库单据时有值,前端可展示/操作) */
private String billNoCk;
/** 单据类型IN / OUT */
private String billType;
/** 单据时间IN 取最早 rk_timeOUT 取最早 ly_time */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date billTime;
// ——主数据常用抬头字段(从首条提取即可)——
private String xj;
private String xmNo;
private String xmMs;
private String rkType; private String rkTypeName;
private String ckType; private String ckTypeName;
private String teamCode; private String teamName;
private String cangkuName;
private String lihuoYName;
private String remark;
// ——聚合指标——
private Integer itemCount; // 明细条数
private BigDecimal sumQty; // 数量合计sum real_qty
private BigDecimal sumAmount; // 金额合计sum ht_dj * real_qty
}

View File

@@ -0,0 +1,13 @@
package com.zg.project.wisdom.domain.vo;
import lombok.Data;
@Data
public class RecordStatisticVO {
/** 入库统计 */
private StockStatisticVO inStatistic;
/** 出库统计 */
private StockStatisticVO outStatistic;
}

View File

@@ -0,0 +1,18 @@
package com.zg.project.wisdom.domain.vo;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class StockStatisticVO {
/** 库存总金额 */
private BigDecimal totalAmount;
/** 使用库位数量 */
private Integer locationCount;
/** 货物总数量 */
private BigDecimal totalQuantity;
}

View File

@@ -4,6 +4,7 @@ import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import com.zg.project.wisdom.domain.RkInfo; import com.zg.project.wisdom.domain.RkInfo;
import com.zg.project.wisdom.domain.vo.StockStatisticVO;
import io.lettuce.core.dynamic.annotation.Param; import io.lettuce.core.dynamic.annotation.Param;
/** /**
@@ -102,4 +103,9 @@ public interface RkInfoMapper
@Param("returnTime") Date returnTime); @Param("returnTime") Date returnTime);
List<RkInfo> selectRkInfoByIds(@Param("rkInfoIds") List<Long> rkInfoIds); List<RkInfo> selectRkInfoByIds(@Param("rkInfoIds") List<Long> rkInfoIds);
/**
* 库存统计(金额 / 库位数 / 数量)
*/
StockStatisticVO selectStockStatisticByCondition(RkInfo query);
} }

View File

@@ -5,6 +5,7 @@ import java.util.List;
import com.zg.project.wisdom.domain.RkInfo; import com.zg.project.wisdom.domain.RkInfo;
import com.zg.project.wisdom.domain.RkRecord; import com.zg.project.wisdom.domain.RkRecord;
import com.zg.project.wisdom.domain.vo.StockStatisticVO;
import io.lettuce.core.dynamic.annotation.Param; import io.lettuce.core.dynamic.annotation.Param;
/** /**
@@ -121,4 +122,28 @@ public interface RkRecordMapper
* @return 记录 * @return 记录
*/ */
RkRecord selectRkRecordByRkInfoId(@Param("rkInfoId") Long rkInfoId); RkRecord selectRkRecordByRkInfoId(@Param("rkInfoId") Long rkInfoId);
/**
* 入库统计
*/
StockStatisticVO selectInRecordStatistic(RkRecord query);
/**
* 出库统计
*/
StockStatisticVO selectOutRecordStatistic(RkRecord query);
/**
* 借出入库
*/
int updateBorrowReturnRecordById(@Param("id") Long id,
@Param("isBorrowed") String isBorrowed,
@Param("returnTime") Date returnTime,
@Param("updateBy") String updateBy,
@Param("updateTime") Date updateTime);
/**
* 查询某个单据下仍为预入库状态的记录数量
*/
int countPreInRecordByBillNo(@Param("billNo") String billNo);
} }

View File

@@ -2,6 +2,7 @@ package com.zg.project.wisdom.service;
import java.util.List; import java.util.List;
import com.zg.project.wisdom.domain.RkBill; import com.zg.project.wisdom.domain.RkBill;
import com.zg.project.wisdom.domain.dto.BorrowReturnDTO;
import com.zg.project.wisdom.domain.dto.RkBillCreateDTO; import com.zg.project.wisdom.domain.dto.RkBillCreateDTO;
/** /**
@@ -75,5 +76,5 @@ public interface IRkBillService
/** /**
* 还料入库 * 还料入库
*/ */
int insertReturnBillAndDetail(RkBillCreateDTO dto); int returnBorrow(BorrowReturnDTO dto);
} }

View File

@@ -2,6 +2,7 @@ package com.zg.project.wisdom.service;
import java.util.List; import java.util.List;
import com.zg.project.wisdom.domain.RkInfo; import com.zg.project.wisdom.domain.RkInfo;
import com.zg.project.wisdom.domain.vo.StockStatisticVO;
/** /**
* 库存单据明细Service接口 * 库存单据明细Service接口
@@ -58,4 +59,12 @@ public interface IRkInfoService
* @return 结果 * @return 结果
*/ */
public int deleteRkInfoById(Long id); public int deleteRkInfoById(Long id);
/**
* 查询库存统计信息
*/
StockStatisticVO getStockStatistic(RkInfo query);
} }

View File

@@ -2,6 +2,7 @@ package com.zg.project.wisdom.service;
import java.util.List; import java.util.List;
import com.zg.project.wisdom.domain.RkRecord; import com.zg.project.wisdom.domain.RkRecord;
import com.zg.project.wisdom.domain.vo.RecordStatisticVO;
/** /**
* 出入库记录Service接口 * 出入库记录Service接口
@@ -90,4 +91,7 @@ public interface IRkRecordService
* 删除预出库记录(仅限 exec_status = 0 * 删除预出库记录(仅限 exec_status = 0
*/ */
int deletePreOutRecords(Long[] ids); int deletePreOutRecords(Long[] ids);
RecordStatisticVO getRecordStatistic(RkRecord query);
} }

View File

@@ -4,6 +4,7 @@ import java.math.BigDecimal;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import com.zg.common.exception.ServiceException; import com.zg.common.exception.ServiceException;
import com.zg.common.utils.DateUtils; import com.zg.common.utils.DateUtils;
@@ -14,6 +15,8 @@ import com.zg.project.information.mapper.PcdeDetailMapper;
import com.zg.project.wisdom.domain.GysJh; import com.zg.project.wisdom.domain.GysJh;
import com.zg.project.wisdom.domain.RkInfo; import com.zg.project.wisdom.domain.RkInfo;
import com.zg.project.wisdom.domain.RkRecord; import com.zg.project.wisdom.domain.RkRecord;
import com.zg.project.wisdom.domain.dto.BorrowReturnDTO;
import com.zg.project.wisdom.domain.dto.BorrowReturnItemDTO;
import com.zg.project.wisdom.domain.dto.RkBillCreateDTO; import com.zg.project.wisdom.domain.dto.RkBillCreateDTO;
import com.zg.project.wisdom.mapper.GysJhMapper; import com.zg.project.wisdom.mapper.GysJhMapper;
import com.zg.project.wisdom.mapper.RkInfoMapper; import com.zg.project.wisdom.mapper.RkInfoMapper;
@@ -101,7 +104,12 @@ public class RkBillServiceImpl implements IRkBillService
Date now = DateUtils.getNowDate(); Date now = DateUtils.getNowDate();
String userId = String.valueOf(SecurityUtils.getUserId()); String userId = String.valueOf(SecurityUtils.getUserId());
/* ================== 1. 主单 rk_bill ================== */ List<RkInfo> rkInfoList = dto.getRkInfoList();
/* ================== 0⃣ 入库前:供应计划【批量】校验 ================== */
checkGysJhQtyBeforeInStockBatch(rkInfoList);
/* ================== 1⃣ 主单 rk_bill ================== */
RkBill bill = new RkBill(); RkBill bill = new RkBill();
if (dto.getRkBill() != null) { if (dto.getRkBill() != null) {
BeanUtils.copyProperties(dto.getRkBill(), bill); BeanUtils.copyProperties(dto.getRkBill(), bill);
@@ -109,41 +117,33 @@ public class RkBillServiceImpl implements IRkBillService
bill.setBillNo(billNo); bill.setBillNo(billNo);
bill.setBizType("0"); // 入库 bill.setBizType("0"); // 入库
bill.setExecStatus(bill.getExecStatus());
bill.setOperationTime(dto.getRkBill().getOperationTime()); bill.setOperationTime(dto.getRkBill().getOperationTime());
bill.setCreateTime(now); bill.setCreateTime(now);
bill.setCreateBy(userId); bill.setCreateBy(userId);
bill.setIsDelete("0"); bill.setIsDelete("0");
// operator默认当前登录人
if (bill.getOperator() == null) { if (bill.getOperator() == null) {
bill.setOperator(Integer.valueOf(userId)); bill.setOperator(Integer.valueOf(userId));
} }
// execStatus默认已完成预入库 / 直接入库统一处理)
if (StringUtils.isBlank(bill.getExecStatus())) {
bill.setExecStatus("1");
}
rkBillMapper.insertRkBill(bill); rkBillMapper.insertRkBill(bill);
/* ================== 2. 明细 + 事件 + 供应计划 ================== */ /* ================== 2️⃣ 明细 & 事件 ================== */
for (RkInfo info : dto.getRkInfoList()) { for (RkInfo info : rkInfoList) {
/* ====== ★ 0. 入库前:供应计划数量校验(核心新增) ====== */ info.setExecStatus(bill.getExecStatus());
checkGysJhQtyBeforeInStock(info);
/* ====== ① 根据 pcode 查询 pcde_detail获取 encoded_id ====== */ // 库位编码
if (StringUtils.isNotBlank(info.getPcode())) { if (StringUtils.isNotBlank(info.getPcode())) {
PcdeDetail pcde = pcdeDetailMapper.selectByPcode(info.getPcode()); PcdeDetail pcde = pcdeDetailMapper.selectByPcode(info.getPcode());
if (pcde == null) { if (pcde == null) {
throw new RuntimeException("库位不存在:" + info.getPcode()); throw new RuntimeException("库位不存在:" + info.getPcode());
} }
info.setPcodeId(pcde.getEncodedId()); info.setPcodeId(pcde.getEncodedId());
} }
/* ---------- rk_info ---------- */ // rk_info
info.setBillNo(billNo); info.setBillNo(billNo);
info.setBizType(bill.getBizType()); info.setBizType(bill.getBizType());
info.setOperationType(bill.getOperationType()); info.setOperationType(bill.getOperationType());
@@ -155,45 +155,56 @@ public class RkBillServiceImpl implements IRkBillService
info.setIsChuku("0"); info.setIsChuku("0");
info.setHasMoved("0"); info.setHasMoved("0");
info.setIsBorrowed("0"); info.setIsBorrowed("0");
info.setExecStatus(bill.getExecStatus()); info.setIsDelete("0");
info.setCreateTime(now); info.setCreateTime(now);
info.setCreateBy(userId); info.setCreateBy(userId);
info.setIsDelete("0");
rkInfoMapper.insertRkInfo(info); rkInfoMapper.insertRkInfo(info);
/* ---------- rk_record ---------- */ // rk_record
RkRecord record = buildInRkRecord(bill, info, now); RkRecord record = buildInRkRecord(bill, info, now);
record.setExecStatus(bill.getExecStatus()); record.setExecStatus(bill.getExecStatus());
record.setPcodeId(info.getPcodeId()); record.setPcodeId(info.getPcodeId());
rkRecordMapper.insertRkRecord(record); rkRecordMapper.insertRkRecord(record);
/* ---------- 供应计划 ---------- */
handleGysJhAfterInStock(info);
} }
/* ================== 3⃣ 入库后:供应计划【批量】更新 ================== */
handleGysJhAfterInStockBatch(rkInfoList);
return 1; return 1;
} }
/** /**
* 入库前校验:入库数量不能超过供应计划数量 * 入库前校验按供应计划ID聚合
* 规则:已入库数量 + 本次单据入库合计 ≤ 计划数量
*/ */
private void checkGysJhQtyBeforeInStock(RkInfo info) { private void checkGysJhQtyBeforeInStockBatch(List<RkInfo> rkInfoList) {
if (info.getGysJhId() == null || info.getRealQty() == null) { Map<Long, BigDecimal> qtyMap = rkInfoList.stream()
return; .filter(i -> i.getGysJhId() != null && i.getRealQty() != null)
} .collect(Collectors.groupingBy(
RkInfo::getGysJhId,
Collectors.mapping(
RkInfo::getRealQty,
Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)
)
));
GysJh gysJh = gysJhMapper.selectGysJhById(info.getGysJhId()); for (Map.Entry<Long, BigDecimal> entry : qtyMap.entrySet()) {
Long gysJhId = entry.getKey();
BigDecimal currentInQty = entry.getValue();
GysJh gysJh = gysJhMapper.selectGysJhById(gysJhId);
if (gysJh == null) { if (gysJh == null) {
throw new RuntimeException("供应计划不存在ID" + info.getGysJhId()); throw new RuntimeException("供应计划不存在ID" + gysJhId);
} }
BigDecimal planQty = gysJh.getJhQty(); BigDecimal planQty = gysJh.getJhQty();
if (planQty == null) { if (planQty == null) {
return; continue;
} }
BigDecimal alreadyInQty = gysJh.getRealQty(); BigDecimal alreadyInQty = gysJh.getRealQty();
@@ -201,58 +212,18 @@ public class RkBillServiceImpl implements IRkBillService
alreadyInQty = BigDecimal.ZERO; alreadyInQty = BigDecimal.ZERO;
} }
BigDecimal afterQty = alreadyInQty.add(info.getRealQty()); BigDecimal afterQty = alreadyInQty.add(currentInQty);
if (afterQty.compareTo(planQty) > 0) { if (afterQty.compareTo(planQty) > 0) {
throw new RuntimeException( throw new RuntimeException(
"入库数量超出供应计划数量,物料号:" + info.getWlNo() "入库数量超出供应计划数量,物料号:" + gysJh.getWlNo()
+ ",计划数量:" + planQty + ",计划数量:" + planQty
+ ",已入库:" + alreadyInQty + ",已入库:" + alreadyInQty
+ ",本次入库:" + info.getRealQty() + ",本次入库:" + currentInQty
); );
} }
} }
private void handleGysJhAfterInStock(RkInfo info) {
// 1. 未关联供应计划或无实际入库数量,直接跳过
if (info.getGysJhId() == null || info.getRealQty() == null) {
return;
} }
// 2. 累加 实际入库数量real_qty = real_qty + 本次入库数量)
gysJhMapper.increaseRealQtyById(
info.getRealQty(),
info.getGysJhId()
);
// 3. 查询最新供应计划数据
GysJh gysJh = gysJhMapper.selectGysJhById(info.getGysJhId());
if (gysJh == null) {
throw new RuntimeException("供应计划不存在ID" + info.getGysJhId());
}
BigDecimal planQty = gysJh.getJhQty(); // 计划交货数量
BigDecimal realQty = gysJh.getRealQty(); // 实际入库数量
if (realQty == null) {
realQty = BigDecimal.ZERO;
}
// 4. 状态判定
String status;
if (realQty.compareTo(BigDecimal.ZERO) == 0) {
status = "0"; // 未到货
} else if (planQty != null && realQty.compareTo(planQty) >= 0) {
status = "1"; // 已入库
} else {
status = "2"; // 部分入库
}
// 5. 更新供应计划状态
gysJhMapper.updateStatusById(gysJh.getId(), status);
}
private RkRecord buildInRkRecord(RkBill bill, RkInfo info, Date now) { private RkRecord buildInRkRecord(RkBill bill, RkInfo info, Date now) {
RkRecord record = new RkRecord(); RkRecord record = new RkRecord();
@@ -286,6 +257,55 @@ public class RkBillServiceImpl implements IRkBillService
return record; return record;
} }
/**
* 入库完成后按供应计划ID汇总本次入库数量统一更新 real_qty 与 status
*/
private void handleGysJhAfterInStockBatch(List<RkInfo> rkInfoList) {
// 1⃣ 按 gysJhId 分组并汇总 realQty
Map<Long, BigDecimal> qtyMap = rkInfoList.stream()
.filter(i -> i.getGysJhId() != null && i.getRealQty() != null)
.collect(Collectors.groupingBy(
RkInfo::getGysJhId,
Collectors.mapping(
RkInfo::getRealQty,
Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)
)
));
// 2⃣ 逐个供应计划更新
for (Map.Entry<Long, BigDecimal> entry : qtyMap.entrySet()) {
Long gysJhId = entry.getKey();
BigDecimal totalInQty = entry.getValue();
// 累加入库数量
gysJhMapper.increaseRealQtyById(totalInQty, gysJhId);
// 查询最新状态
GysJh gysJh = gysJhMapper.selectGysJhById(gysJhId);
if (gysJh == null) {
throw new RuntimeException("供应计划不存在ID" + gysJhId);
}
BigDecimal planQty = gysJh.getJhQty();
BigDecimal realQty = gysJh.getRealQty();
if (realQty == null) {
realQty = BigDecimal.ZERO;
}
String status;
if (realQty.compareTo(BigDecimal.ZERO) == 0) {
status = "0"; // 未到货
} else if (planQty != null && realQty.compareTo(planQty) >= 0) {
status = "1"; // 已入库
} else {
status = "2"; // 部分入库
}
gysJhMapper.updateStatusById(gysJhId, status);
}
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@@ -293,95 +313,97 @@ public class RkBillServiceImpl implements IRkBillService
if (dto == null || dto.getRkBill() == null if (dto == null || dto.getRkBill() == null
|| StringUtils.isBlank(dto.getRkBill().getBillNo())) { || StringUtils.isBlank(dto.getRkBill().getBillNo())) {
throw new RuntimeException("单据号不能为空"); throw new ServiceException("单据号不能为空");
} }
if (dto.getRkInfoList() == null || dto.getRkInfoList().isEmpty()) { if (dto.getRkInfoList() == null || dto.getRkInfoList().isEmpty()) {
throw new RuntimeException("入库明细不能为空"); throw new ServiceException("入库明细不能为空");
} }
String billNo = dto.getRkBill().getBillNo(); String billNo = dto.getRkBill().getBillNo();
Date now = DateUtils.getNowDate(); Date now = DateUtils.getNowDate();
// ================== 1. 查主单 ================== /* ================== 1️⃣主单 ================== */
RkBill bill = rkBillMapper.selectByBillNo(billNo); RkBill bill = rkBillMapper.selectByBillNo(billNo);
if (bill == null) { if (bill == null) {
throw new RuntimeException("单据不存在:" + billNo); throw new ServiceException("单据不存在:" + billNo);
} }
// ================== 2. execStatus 规则 ================== /* ================== 2️⃣ 执行状态规则 ================== */
String execStatus = dto.getRkBill().getExecStatus(); String execStatus = dto.getRkBill().getExecStatus();
if (StringUtils.isBlank(execStatus)) { if (StringUtils.isBlank(execStatus)) {
execStatus = bill.getExecStatus(); execStatus = bill.getExecStatus();
} }
// ================== 3. 追加明细 ================== // 🚩 标记:本次是否包含预入库
for (RkInfo info : dto.getRkInfoList()) { boolean hasPreIn = false;
// ===== ① 根据 pcode 查询 pcde_detail → encoded_id关键新增 ===== List<RkInfo> rkInfoList = dto.getRkInfoList();
/* ================== 3⃣ 追加前:供应计划【批量】校验 ================== */
checkGysJhQtyBeforeInStockBatch(rkInfoList);
/* ================== 4⃣ 插入明细 & 事件 ================== */
for (RkInfo info : rkInfoList) {
/* ===== 4.1 库位校验 ===== */
if (StringUtils.isNotBlank(info.getPcode())) { if (StringUtils.isNotBlank(info.getPcode())) {
PcdeDetail pcde = pcdeDetailMapper.selectByPcode(info.getPcode()); PcdeDetail pcde = pcdeDetailMapper.selectByPcode(info.getPcode());
if (pcde == null) { if (pcde == null) {
throw new RuntimeException("库位不存在:" + info.getPcode()); throw new ServiceException("库位不存在:" + info.getPcode());
} }
info.setPcodeId(pcde.getEncodedId()); info.setPcodeId(pcde.getEncodedId());
} }
// ---------- 基础关联 ---------- /* ===== 4.2 继承主单字段 ===== */
info.setBillNo(bill.getBillNo()); info.setBillNo(bill.getBillNo());
// ---------- 类型信息(来源于主单,不信前端) ----------
info.setOperationType(bill.getOperationType()); info.setOperationType(bill.getOperationType());
info.setBizType(bill.getBizType()); info.setBizType(bill.getBizType());
info.setWlType(bill.getWlType()); info.setWlType(bill.getWlType());
// ---------- 仓库 ----------
info.setCangku(bill.getCangku()); info.setCangku(bill.getCangku());
// ---------- 操作信息 ---------- info.setOperationTime(now);
info.setOperationTime(info.getOperationTime()); info.setOperator(bill.getOperator());
info.setOperator(info.getOperator());
// ---------- 执行状态 ----------
info.setExecStatus(execStatus); info.setExecStatus(execStatus);
// ---------- 库存状态 ---------- if ("0".equals(execStatus)) {
hasPreIn = true;
}
info.setIsChuku("0"); info.setIsChuku("0");
info.setHasMoved("0"); info.setHasMoved("0");
info.setIsBorrowed("0"); info.setIsBorrowed("0");
// ---------- 备注 ---------- /* ===== 4.3 备注兜底 ===== */
String finalRemark = info.getRemark(); String finalRemark = StringUtils.isNotBlank(info.getRemark())
if (StringUtils.isBlank(finalRemark)) { ? info.getRemark()
finalRemark = bill.getRemark(); : bill.getRemark();
}
info.setRemark(finalRemark); info.setRemark(finalRemark);
// ---------- 审计字段 ---------- /* ===== 4.4 审计字段 ===== */
info.setCreateTime(now); info.setCreateTime(now);
info.setCreateBy(bill.getCreateBy()); info.setCreateBy(bill.getCreateBy());
info.setIsDelete("0"); info.setIsDelete("0");
// ---------- 插入 rk_info ---------- /* ===== 4.5 插入 rk_info ===== */
rkInfoMapper.insertRkInfo(info); rkInfoMapper.insertRkInfo(info);
// ---------- rk_record ---------- /* ===== 4.6 插入 rk_record ===== */
RkRecord record = buildInRkRecord(bill, info, now); RkRecord record = buildInRkRecord(bill, info, now);
record.setExecStatus(execStatus); record.setExecStatus(execStatus);
record.setRkInfoId(info.getId()); record.setRkInfoId(info.getId());
// ⭐ encoded_id 同步
record.setPcodeId(info.getPcodeId()); record.setPcodeId(info.getPcodeId());
// ⭐ 备注同步
record.setRemark(finalRemark); record.setRemark(finalRemark);
rkRecordMapper.insertRkRecord(record); rkRecordMapper.insertRkRecord(record);
}
// ---------- 供应计划 ---------- /* ================== 5⃣ 追加后:供应计划【批量】更新 ================== */
handleGysJhAfterInStock(info); handleGysJhAfterInStockBatch(rkInfoList);
/* ================== 6⃣ 同步回退主单状态 ================== */
if (hasPreIn && !"0".equals(bill.getExecStatus())) {
rkBillMapper.updateExecStatusByBillNo(billNo, "0");
} }
return 1; return 1;
@@ -575,8 +597,8 @@ public class RkBillServiceImpl implements IRkBillService
record.setOperationType(bill.getOperationType()); record.setOperationType(bill.getOperationType());
record.setOperationTime(bill.getOperationTime()); record.setOperationTime(bill.getOperationTime());
record.setOperator(bill.getOperator()); record.setOperator(bill.getOperator());
record.setCangku(dbInfo.getCangku()); record.setCangku(bill.getCangku());
record.setTeamCode(dbInfo.getTeamCode()); record.setTeamCode(bill.getTeamCode());
// ===== ★ 关键:备注来自【出库明细 outInfo】===== // ===== ★ 关键:备注来自【出库明细 outInfo】=====
record.setRemark(outInfo.getRemark()); record.setRemark(outInfo.getRemark());
@@ -611,136 +633,64 @@ public class RkBillServiceImpl implements IRkBillService
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public int insertReturnBillAndDetail(RkBillCreateDTO dto) { public int returnBorrow(BorrowReturnDTO dto) {
if (dto == null || dto.getRkInfoList() == null || dto.getRkInfoList().isEmpty()) { if (dto == null || dto.getItems() == null || dto.getItems().isEmpty()) {
throw new RuntimeException("还料明细不能为空"); throw new RuntimeException("还料明细不能为空");
} }
String billNo = BillNoUtil.generateTodayBillNo("HL", null);
Date now = DateUtils.getNowDate(); Date now = DateUtils.getNowDate();
String userId = String.valueOf(SecurityUtils.getUserId()); String userId = String.valueOf(SecurityUtils.getUserId());
/* ================== 1. 主单 rk_bill ================== */ for (BorrowReturnItemDTO item : dto.getItems()) {
RkBill bill = new RkBill();
if (dto.getRkBill() != null) { /* ================== 1. 参数校验 ================== */
BeanUtils.copyProperties(dto.getRkBill(), bill); if (item.getRecordId() == null) {
throw new RuntimeException("借料记录ID(recordId)不能为空");
}
if (item.getReturnTime() == null) {
throw new RuntimeException("归还时间不能为空");
} }
bill.setBillNo(billNo); /* ================== 2. 查询借料 record主驱动 ================== */
bill.setBizType("3"); // 3 = 还料入库 RkRecord record = rkRecordMapper.selectRkRecordById(item.getRecordId());
bill.setOperationTime(now); if (record == null) {
bill.setCreateTime(now); throw new RuntimeException("借料记录不存在recordId=" + item.getRecordId());
bill.setCreateBy(userId);
bill.setIsDelete("0");
if (bill.getOperator() == null) {
bill.setOperator(Integer.valueOf(userId));
} }
// 还料入库默认已完成 // 必须是借料出库记录
if (StringUtils.isBlank(bill.getExecStatus())) { if (!"2".equals(record.getBizType())) {
bill.setExecStatus("1"); throw new RuntimeException("该记录不是借料出库记录,禁止还料");
} }
rkBillMapper.insertRkBill(bill); // 防止重复还料
if ("2".equals(record.getIsBorrowed())) {
/* ================== 2. 明细 + 事件 ================== */ throw new RuntimeException("该借料记录已归还,禁止重复操作");
for (RkInfo info : dto.getRkInfoList()) {
// ===== ① 基础校验 =====
if (info.getRealQty() == null || info.getRealQty().compareTo(BigDecimal.ZERO) <= 0) {
throw new RuntimeException("还料数量必须大于 0");
} }
// 必须关联原借料出库库存 Long rkInfoId = record.getRkInfoId();
if (info.getRdid() == null) { if (rkInfoId == null) {
throw new RuntimeException("还料必须指定原借料库存ID(rdid)"); throw new RuntimeException("借料记录未关联库存(rkInfoId)");
} }
RkInfo borrowInfo = rkInfoMapper.selectRkInfoById(info.getRdid()); /* ================== 3. 更新 rk_info库存闭环 ================== */
if (borrowInfo == null) {
throw new RuntimeException("原借料库存不存在ID" + info.getRdid());
}
/* ---------- rk_info新增库存 ---------- */
info.setId(null);
info.setBillNo(billNo);
info.setBizType("3"); // 还料入库
info.setOperationType(bill.getOperationType());
info.setOperationTime(bill.getOperationTime());
info.setOperator(bill.getOperator());
// 关键:库存是“新增”,不是回补原库存
info.setIsChuku("0");
info.setIsBorrowed("0");
info.setHasMoved("0");
info.setExecStatus(bill.getExecStatus());
// 仓库 / 物料 / 项目信息,默认继承原借料库存
info.setCangku(borrowInfo.getCangku());
info.setWlType(borrowInfo.getWlType());
info.setXmNo(borrowInfo.getXmNo());
info.setXmMs(borrowInfo.getXmMs());
info.setWlNo(borrowInfo.getWlNo());
info.setWlMs(borrowInfo.getWlMs());
info.setGysNo(borrowInfo.getGysNo());
info.setGysMc(borrowInfo.getGysMc());
info.setDw(borrowInfo.getDw());
info.setCreateTime(now);
info.setCreateBy(userId);
info.setIsDelete("0");
rkInfoMapper.insertRkInfo(info);
/* ---------- rk_record还料入库事件 ---------- */
RkRecord record = buildReturnRkRecord(bill, info, now);
rkRecordMapper.insertRkRecord(record);
/* ---------- 原借料记录标记“已归还” ---------- */
rkInfoMapper.updateBorrowReturn( rkInfoMapper.updateBorrowReturn(
borrowInfo.getId(), rkInfoId,
"2", // is_borrowed = 2 已归还 "2", // is_borrowed = 已归还
item.getReturnTime()
);
/* ================== 4. 更新 rk_record状态闭环按主键 ================== */
rkRecordMapper.updateBorrowReturnRecordById(
record.getId(),
"2", // is_borrowed = 已归还
item.getReturnTime(),
userId,
now now
); );
} }
return 1; return dto.getItems().size();
}
private RkRecord buildReturnRkRecord(RkBill bill, RkInfo info, Date now) {
RkRecord record = new RkRecord();
// ① 明细快照
BeanUtils.copyProperties(info, record);
record.setId(null);
// ② 主单上下文
record.setBillNo(bill.getBillNo());
record.setBizType("3"); // 还料入库
record.setOperationType(bill.getOperationType());
record.setOperationTime(bill.getOperationTime());
record.setOperator(bill.getOperator());
record.setCangku(info.getCangku());
record.setTeamCode(info.getTeamCode());
// ③ 状态
record.setIsChuku("0");
record.setIsBorrowed("2"); // 已归还
record.setHasMoved("0");
record.setExecStatus(bill.getExecStatus());
record.setIsDelete("0");
// ④ 审计
record.setCreateTime(now);
record.setCreateBy(bill.getCreateBy());
// ⑤ 关联
record.setRkInfoId(info.getId());
record.setRdid(info.getRdid()); // 指向原借料库存
return record;
} }
} }

View File

@@ -2,6 +2,7 @@ package com.zg.project.wisdom.service.impl;
import java.util.List; import java.util.List;
import com.zg.common.utils.DateUtils; import com.zg.common.utils.DateUtils;
import com.zg.project.wisdom.domain.vo.StockStatisticVO;
import com.zg.project.wisdom.mapper.RkRecordMapper; import com.zg.project.wisdom.mapper.RkRecordMapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -105,4 +106,10 @@ public class RkInfoServiceImpl implements IRkInfoService
{ {
return rkInfoMapper.deleteRkInfoById(id); return rkInfoMapper.deleteRkInfoById(id);
} }
@Override
public StockStatisticVO getStockStatistic(RkInfo query) {
return rkInfoMapper.selectStockStatisticByCondition(query);
}
} }

View File

@@ -9,6 +9,7 @@ import com.zg.common.utils.DateUtils;
import com.zg.common.utils.StringUtils; import com.zg.common.utils.StringUtils;
import com.zg.project.wisdom.domain.GysJh; import com.zg.project.wisdom.domain.GysJh;
import com.zg.project.wisdom.domain.RkInfo; import com.zg.project.wisdom.domain.RkInfo;
import com.zg.project.wisdom.domain.vo.RecordStatisticVO;
import com.zg.project.wisdom.mapper.GysJhMapper; import com.zg.project.wisdom.mapper.GysJhMapper;
import com.zg.project.wisdom.mapper.RkBillMapper; import com.zg.project.wisdom.mapper.RkBillMapper;
import com.zg.project.wisdom.mapper.RkInfoMapper; import com.zg.project.wisdom.mapper.RkInfoMapper;
@@ -206,6 +207,8 @@ public class RkRecordServiceImpl implements IRkRecordService
info.setGysMc(rkRecord.getGysMc()); info.setGysMc(rkRecord.getGysMc());
info.setDw(rkRecord.getDw()); info.setDw(rkRecord.getDw());
info.setHtDj(rkRecord.getHtDj()); info.setHtDj(rkRecord.getHtDj());
info.setCangku(rkRecord.getCangku());
info.setPcode(rkRecord.getPcode());
info.setIsChuku("0"); info.setIsChuku("0");
} }
@@ -240,6 +243,8 @@ public class RkRecordServiceImpl implements IRkRecordService
info.setGysMc(rkRecord.getGysMc()); info.setGysMc(rkRecord.getGysMc());
info.setDw(rkRecord.getDw()); info.setDw(rkRecord.getDw());
info.setHtDj(rkRecord.getHtDj()); info.setHtDj(rkRecord.getHtDj());
info.setCangku(rkRecord.getCangku());
info.setPcode(rkRecord.getPcode());
} }
/* ====================== 4. 更新库存表 ====================== */ /* ====================== 4. 更新库存表 ====================== */
@@ -431,14 +436,12 @@ public class RkRecordServiceImpl implements IRkRecordService
} }
/* ================== 1. 查询 rk_record ================== */ /* ================== 1. 查询 rk_record ================== */
List<RkRecord> recordList = List<RkRecord> recordList = rkRecordMapper.selectRkRecordByIds(recordIds);
rkRecordMapper.selectRkRecordByIds(recordIds);
if (recordList == null || recordList.isEmpty()) { if (recordList == null || recordList.isEmpty()) {
throw new ServiceException("入库记录不存在"); throw new ServiceException("入库记录不存在");
} }
/* ================== 2. 处理「预入库」记录 ================== */ /* ================== 2. 处理「预入库」记录 ================== */
List<RkRecord> preRecordList = recordList.stream() List<RkRecord> preRecordList = recordList.stream()
.filter(r -> "0".equals(r.getExecStatus())) // 预入库 .filter(r -> "0".equals(r.getExecStatus())) // 预入库
.collect(Collectors.toList()); .collect(Collectors.toList());
@@ -447,16 +450,13 @@ public class RkRecordServiceImpl implements IRkRecordService
throw new ServiceException("所选入库记录均已完成,无需重复入库"); throw new ServiceException("所选入库记录均已完成,无需重复入库");
} }
/* ================== 3. 校验:一键入库数量 ≤ 计划交货数量 ================== */ /* ================== 3. 校验:完成入库数量 ≤ 计划交货数量 ================== */
// 按供应计划ID聚合「本次完成入库数量」
Map<Long, BigDecimal> finishQtyMap = new HashMap<>(); Map<Long, BigDecimal> finishQtyMap = new HashMap<>();
for (RkRecord record : preRecordList) { for (RkRecord record : preRecordList) {
if (record.getGysJhId() == null || record.getRealQty() == null) { if (record.getGysJhId() == null || record.getRealQty() == null) {
continue; continue;
} }
finishQtyMap.merge( finishQtyMap.merge(
record.getGysJhId(), record.getGysJhId(),
record.getRealQty(), record.getRealQty(),
@@ -464,7 +464,6 @@ public class RkRecordServiceImpl implements IRkRecordService
); );
} }
// 只和「计划交货数量」做校验
for (Map.Entry<Long, BigDecimal> entry : finishQtyMap.entrySet()) { for (Map.Entry<Long, BigDecimal> entry : finishQtyMap.entrySet()) {
Long gysJhId = entry.getKey(); Long gysJhId = entry.getKey();
@@ -494,7 +493,7 @@ public class RkRecordServiceImpl implements IRkRecordService
rkRecordMapper.updateExecStatusByIds(preRecordIds, "1"); rkRecordMapper.updateExecStatusByIds(preRecordIds, "1");
// ② rk_info.exec_status = 1 // ② rk_info.exec_status = 1(只推进本次涉及的库存)
List<Long> rkInfoIds = preRecordList.stream() List<Long> rkInfoIds = preRecordList.stream()
.map(RkRecord::getRkInfoId) .map(RkRecord::getRkInfoId)
.filter(Objects::nonNull) .filter(Objects::nonNull)
@@ -505,27 +504,33 @@ public class RkRecordServiceImpl implements IRkRecordService
rkInfoMapper.updateExecStatusByIds(rkInfoIds, "1"); rkInfoMapper.updateExecStatusByIds(rkInfoIds, "1");
} }
// ③ rk_bill.exec_status = 1 // ③ rk_bill.exec_status = 1(✅ 只有当 bill 下所有 record 均完成)
List<String> billNos = preRecordList.stream() Set<String> billNoSet = preRecordList.stream()
.map(RkRecord::getBillNo) .map(RkRecord::getBillNo)
.filter(StringUtils::isNotBlank) .filter(StringUtils::isNotBlank)
.distinct() .collect(Collectors.toSet());
.collect(Collectors.toList());
for (String billNo : billNos) { for (String billNo : billNoSet) {
// 查询该 bill 下是否仍存在 预入库 record
int unFinishedCount = rkRecordMapper.countPreInRecordByBillNo(billNo);
// 只有当不存在任何预入库 record 时,才推进 bill 状态
if (unFinishedCount == 0) {
rkBillMapper.updateExecStatusByBillNo(billNo, "1"); rkBillMapper.updateExecStatusByBillNo(billNo, "1");
} }
}
/* ================== 5. 同步修正供应计划(以完成结果为准) ================== */ /* ================== 5. 同步修正供应计划 ================== */
for (Map.Entry<Long, BigDecimal> entry : finishQtyMap.entrySet()) { for (Map.Entry<Long, BigDecimal> entry : finishQtyMap.entrySet()) {
Long gysJhId = entry.getKey(); Long gysJhId = entry.getKey();
BigDecimal finishQty = entry.getValue(); BigDecimal finishQty = entry.getValue();
// ① 直接修正 real_qty以一键入库结果为准 // ① 修正实收数量
gysJhMapper.updateRealQtyById(gysJhId, finishQty); gysJhMapper.updateRealQtyById(gysJhId, finishQty);
// ② 重新判定状态 // ② 修正状态
GysJh gysJh = gysJhMapper.selectGysJhById(gysJhId); GysJh gysJh = gysJhMapper.selectGysJhById(gysJhId);
if (gysJh == null) { if (gysJh == null) {
continue; continue;
@@ -546,6 +551,7 @@ public class RkRecordServiceImpl implements IRkRecordService
return preRecordIds.size(); return preRecordIds.size();
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public int rollbackOut(List<Long> recordIds) { public int rollbackOut(List<Long> recordIds) {
@@ -752,6 +758,12 @@ public class RkRecordServiceImpl implements IRkRecordService
return deleteCount; return deleteCount;
} }
@Override
public RecordStatisticVO getRecordStatistic(RkRecord query) {
RecordStatisticVO vo = new RecordStatisticVO();
vo.setInStatistic(rkRecordMapper.selectInRecordStatistic(query));
vo.setOutStatistic(rkRecordMapper.selectOutRecordStatistic(query));
return vo;
}
} }

View File

@@ -189,6 +189,65 @@
</foreach> </foreach>
</select> </select>
<select id="selectStockStatisticByCondition"
parameterType="com.zg.project.wisdom.domain.RkInfo"
resultType="com.zg.project.wisdom.domain.vo.StockStatisticVO">
SELECT
IFNULL(SUM(ri.real_qty * ri.ht_dj), 0) AS total_amount,
COUNT(DISTINCT ri.pcode) AS location_count,
IFNULL(SUM(ri.real_qty), 0) AS total_quantity
FROM rk_info ri
<where>
ri.exec_status = 1
AND ri.is_chuku = 0
AND ri.is_delete = 0
<if test="operationType != null and operationType != ''">
AND ri.operation_type LIKE CONCAT('%', #{operationType}, '%')
</if>
<if test="sapNo != null and sapNo != ''">
AND ri.sap_no LIKE CONCAT('%', #{sapNo}, '%')
</if>
<if test="xmNo != null and xmNo != ''">
AND ri.xm_no LIKE CONCAT('%', #{xmNo}, '%')
</if>
<if test="xmMs != null and xmMs != ''">
AND ri.xm_ms LIKE CONCAT('%', #{xmMs}, '%')
</if>
<if test="wlNo != null and wlNo != ''">
AND ri.wl_no LIKE CONCAT('%', #{wlNo}, '%')
</if>
<if test="wlMs != null and wlMs != ''">
AND ri.wl_ms LIKE CONCAT('%', #{wlMs}, '%')
</if>
<if test="gysMc != null and gysMc != ''">
AND ri.gys_mc LIKE CONCAT('%', #{gysMc}, '%')
</if>
<if test="pcode != null and pcode != ''">
AND ri.pcode LIKE CONCAT('%', #{pcode}, '%')
</if>
<if test="bizType != null and bizType != ''">
AND ri.biz_type LIKE CONCAT('%', #{bizType}, '%')
</if>
<if test="wlType != null and wlType != ''">
AND ri.wl_type LIKE CONCAT('%', #{wlType}, '%')
</if>
<if test="cangku != null and cangku != ''">
AND ri.cangku LIKE CONCAT('%', #{cangku}, '%')
</if>
<if test="billNo != null and billNo != ''">
AND ri.bill_no LIKE CONCAT('%', #{billNo}, '%')
</if>
<if test="startDate != null">
AND ri.operation_time &gt;= #{startDate}
</if>
<if test="endDate != null">
AND ri.operation_time &lt;= #{endDate}
</if>
</where>
</select>
<!-- ========================= 删除 ========================= --> <!-- ========================= 删除 ========================= -->
<delete id="deleteRkInfoById" parameterType="Long"> <delete id="deleteRkInfoById" parameterType="Long">
DELETE FROM rk_info WHERE id = #{id} DELETE FROM rk_info WHERE id = #{id}
@@ -327,6 +386,7 @@
return_time = #{returnTime}, return_time = #{returnTime},
update_time = NOW() update_time = NOW()
WHERE id = #{id} WHERE id = #{id}
AND is_delete = '0'
</update> </update>

View File

@@ -61,6 +61,7 @@
<result property="trayCode" column="tray_code"/> <result property="trayCode" column="tray_code"/>
<result property="entityId" column="entity_id"/> <result property="entityId" column="entity_id"/>
<result property="teamCode" column="team_code"/> <result property="teamCode" column="team_code"/>
<result property="teamName" column="team_name"/>
<result property="borrowTime" column="borrow_time"/> <result property="borrowTime" column="borrow_time"/>
<result property="returnTime" column="return_time"/> <result property="returnTime" column="return_time"/>
@@ -101,7 +102,8 @@
/* 仓库信息:小仓/大仓 */ /* 仓库信息:小仓/大仓 */
wh.warehouse_name, wh.warehouse_name,
wh.parent_warehouse_code, wh.parent_warehouse_code,
wh.parent_warehouse_name wh.parent_warehouse_name,
ct.team_name AS team_name
FROM rk_record rr FROM rk_record rr
LEFT JOIN sys_user su LEFT JOIN sys_user su
ON rr.operator = su.user_id ON rr.operator = su.user_id
@@ -113,6 +115,9 @@
ON rr.operation_type = sot.type_code ON rr.operation_type = sot.type_code
LEFT JOIN warehouse_info wh LEFT JOIN warehouse_info wh
ON rr.cangku = wh.warehouse_code ON rr.cangku = wh.warehouse_code
LEFT JOIN construction_team ct
ON rr.team_code = ct.team_code
AND ct.is_delete = '0'
</sql> </sql>
<!-- ===================== 查询列表 ===================== --> <!-- ===================== 查询列表 ===================== -->
@@ -193,7 +198,10 @@
<if test="wlMs != null and wlMs != ''"> <if test="wlMs != null and wlMs != ''">
AND rr.wl_ms LIKE concat('%', #{wlMs}, '%') AND rr.wl_ms LIKE concat('%', #{wlMs}, '%')
</if> </if>
<!-- 是否借料 -->
<if test="isBorrowed != null and isBorrowed != ''">
AND rr.is_borrowed = #{isBorrowed}
</if>
<!-- 默认不查删除 --> <!-- 默认不查删除 -->
<if test="isDelete == null"> <if test="isDelete == null">
AND (rr.is_delete = '0' OR rr.is_delete = 0 OR rr.is_delete IS NULL) AND (rr.is_delete = '0' OR rr.is_delete = 0 OR rr.is_delete IS NULL)
@@ -528,4 +536,102 @@
</foreach> </foreach>
</delete> </delete>
<!-- 入库统计 -->
<select id="selectInRecordStatistic"
parameterType="com.zg.project.wisdom.domain.RkRecord"
resultType="com.zg.project.wisdom.domain.vo.StockStatisticVO">
SELECT
IFNULL(SUM(rr.real_qty * rr.ht_dj), 0) AS total_amount,
COUNT(DISTINCT rr.pcode) AS location_count,
IFNULL(SUM(rr.real_qty), 0) AS total_quantity
FROM rk_record rr
<where>
rr.is_delete = 0
AND rr.exec_status = 1
AND rr.biz_type = 0 <!-- 入库 -->
<if test="operationType != null and operationType != ''">
AND rr.operation_type LIKE CONCAT('%', #{operationType}, '%')
</if>
<if test="xmNo != null and xmNo != ''">
AND rr.xm_no LIKE CONCAT('%', #{xmNo}, '%')
</if>
<if test="wlNo != null and wlNo != ''">
AND rr.wl_no LIKE CONCAT('%', #{wlNo}, '%')
</if>
<if test="pcode != null and pcode != ''">
AND rr.pcode LIKE CONCAT('%', #{pcode}, '%')
</if>
<if test="cangku != null and cangku != ''">
AND rr.cangku LIKE CONCAT('%', #{cangku}, '%')
</if>
<if test="startDate != null">
AND rr.operation_time &gt;= #{startDate}
</if>
<if test="endDate != null">
AND rr.operation_time &lt;= #{endDate}
</if>
</where>
</select>
<!-- 出库统计 -->
<select id="selectOutRecordStatistic"
parameterType="com.zg.project.wisdom.domain.RkRecord"
resultType="com.zg.project.wisdom.domain.vo.StockStatisticVO">
SELECT
IFNULL(SUM(rr.real_qty * rr.ht_dj), 0) AS total_amount,
COUNT(DISTINCT rr.pcode) AS location_count,
IFNULL(SUM(rr.real_qty), 0) AS total_quantity
FROM rk_record rr
<where>
rr.is_delete = 0
AND rr.exec_status = 1
AND rr.biz_type = 1 <!-- 出库 -->
<if test="operationType != null and operationType != ''">
AND rr.operation_type LIKE CONCAT('%', #{operationType}, '%')
</if>
<if test="xmNo != null and xmNo != ''">
AND rr.xm_no LIKE CONCAT('%', #{xmNo}, '%')
</if>
<if test="wlNo != null and wlNo != ''">
AND rr.wl_no LIKE CONCAT('%', #{wlNo}, '%')
</if>
<if test="pcode != null and pcode != ''">
AND rr.pcode LIKE CONCAT('%', #{pcode}, '%')
</if>
<if test="cangku != null and cangku != ''">
AND rr.cangku LIKE CONCAT('%', #{cangku}, '%')
</if>
<if test="startDate != null">
AND rr.operation_time &gt;= #{startDate}
</if>
<if test="endDate != null">
AND rr.operation_time &lt;= #{endDate}
</if>
</where>
</select>
<select id="countPreInRecordByBillNo" resultType="int">
SELECT COUNT(1)
FROM rk_record
WHERE bill_no = #{billNo}
AND exec_status = '0'
AND is_delete = '0'
</select>
<update id="updateBorrowReturnRecordById">
UPDATE rk_record
SET
is_borrowed = #{isBorrowed},
return_time = #{returnTime},
update_by = #{updateBy},
update_time = #{updateTime}
WHERE id = #{id}
AND is_delete = '0'
</update>
</mapper> </mapper>