逻辑优化

This commit is contained in:
2025-11-12 08:52:38 +08:00
parent e26f30781c
commit 7743d052b2
5 changed files with 138 additions and 4 deletions

View File

@@ -284,4 +284,17 @@ public class RkInfoController extends BaseController
return toAjax(rkInfoService.updateBillInfo(rkInfo));
}
/**
* 相同入库单据号追加入库
* @param dto
* @return
*/
@PostMapping("/append")
@PreAuthorize("@ss.hasPermi('wisdom:stock:add')")
@Log(title = "追加入库", businessType = BusinessType.INSERT)
public AjaxResult append(@RequestBody PcRkInfoBatchDTO dto) {
rkInfoService.appendToExistingBill(dto);
return AjaxResult.success("追加入库成功");
}
}

View File

@@ -11,6 +11,9 @@ import java.util.List;
@Data
public class PcRkInfoBatchDTO {
/** 要追加到的入库单据号(必填) */
private String billNo;
/** 审核人用户ID */
private String approverId;

View File

@@ -239,4 +239,5 @@ public interface RkInfoMapper
Long selectPcde(RkInfo query);
int updateBillInfo(RkInfo query);
}

View File

@@ -173,4 +173,10 @@ public interface IRkInfoService
Long selectPcde(RkInfo query);
public int updateBillInfo(RkInfo rkInfo);
/**
* 追加入库
* @param dto
*/
void appendToExistingBill(PcRkInfoBatchDTO dto);
}

View File

@@ -23,7 +23,6 @@ import com.zg.project.system.service.ISysConfigService;
import com.zg.project.wisdom.domain.AuditSignature;
import com.zg.project.wisdom.domain.GysJh;
import com.zg.project.wisdom.domain.dto.*;
import com.zg.project.wisdom.domain.vo.PcodeQtyVO;
import com.zg.project.wisdom.mapper.AuditSignatureMapper;
import com.zg.project.wisdom.mapper.GysJhMapper;
import com.zg.project.wisdom.utils.BillNoUtil;
@@ -36,6 +35,8 @@ import com.zg.project.wisdom.domain.RkInfo;
import com.zg.project.wisdom.service.IRkInfoService;
import org.springframework.transaction.annotation.Transactional;
import static com.zg.common.utils.SecurityUtils.getUsername;
/**
* 库存单据主Service业务层处理
*
@@ -259,7 +260,7 @@ public class RkInfoServiceImpl implements IRkInfoService
RkInfo update = new RkInfo();
update.setId(id);
update.setIsChuku("4"); // 4 = 已撤销
update.setUpdateBy(SecurityUtils.getUsername());
update.setUpdateBy(getUsername());
update.setUpdateTime(DateUtils.getNowDate());
return rkInfoMapper.updateRkInfo(update);
@@ -927,7 +928,7 @@ public class RkInfoServiceImpl implements IRkInfoService
update.setId(originalId);
update.setIsBorrowed("2");
update.setReturnTime(DateUtils.getNowDate());
update.setUpdateBy(SecurityUtils.getUsername());
update.setUpdateBy(getUsername());
update.setUpdateTime(DateUtils.getNowDate());
rkInfoMapper.updateById(update);
@@ -940,7 +941,7 @@ public class RkInfoServiceImpl implements IRkInfoService
RkInfo update = new RkInfo();
update.setId(id);
update.setIsChuku("5");
update.setUpdateBy(SecurityUtils.getUsername());
update.setUpdateBy(getUsername());
update.setUpdateTime(DateUtils.getNowDate());
// 执行更新
@@ -1019,8 +1020,118 @@ public class RkInfoServiceImpl implements IRkInfoService
return rkInfoMapper.updateBillInfo(query);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void appendToExistingBill(PcRkInfoBatchDTO dto) {
// ========== 参数校验 ==========
if (StringUtils.isEmpty(dto.getBillNo())) {
throw new ServiceException("入库单号 billNo 不能为空");
}
if (dto.getRkList() == null || dto.getRkList().isEmpty()) {
throw new ServiceException("追加明细不能为空");
}
// ========== 1. 校验原单据是否存在 ==========
List<RkInfo> exists = rkInfoMapper.selectRkInfoListByBillNo(dto.getBillNo());
if (exists == null || exists.isEmpty()) {
throw new ServiceException("目标入库单不存在:" + dto.getBillNo());
}
Date now = DateUtils.getNowDate();
String user = getUsername();
// ========== 2. 组装并插入追加的入库明细(无审批:直接入库) ==========
List<RkInfo> toSave = new ArrayList<>(dto.getRkList().size());
Date rkTime = dto.getRkTime() != null ? dto.getRkTime() : now;
for (PcRkInfoItemDTO item : dto.getRkList()) {
RkInfo e = new RkInfo();
BeanUtils.copyProperties(item, e); // 拷贝 DTO 相同字段
// 公共字段
e.setBillNo(dto.getBillNo());
e.setRkType(dto.getRkType());
e.setWlType(dto.getWlType());
e.setCangku(dto.getCangku());
e.setLihuoY(dto.getLihuoY());
e.setRkTime(rkTime);
// 入库状态(未启用审批)
e.setIsChuku("0"); // 已入库
e.setStatus("1"); // 正常
e.setIsDelete("0");
e.setCreateBy(user);
e.setCreateTime(now);
e.setUpdateBy(user);
e.setUpdateTime(now);
toSave.add(e);
}
rkInfoMapper.batchInsertRkInfo(toSave);
// ========== 3. 更新供应计划(关键改动):只在“部分入库”时扣减 ==========
for (PcRkInfoItemDTO item : dto.getRkList()) {
Long jhId = item.getGysJhId();
BigDecimal realQty = item.getRealQty();
if (jhId == null || realQty == null) continue;
// 查当前计划行
GysJh plan = gysJhMapper.selectGysJhById(jhId);
if (plan == null) continue;
// 已经标记为全部入库的行,直接跳过(既不扣减也不改)
if ("1".equals(plan.getStatus())) {
continue;
}
// 计划剩余(表里 jh_qty 列)
BigDecimal remain = plan.getJhQty() == null
? BigDecimal.ZERO
: BigDecimal.valueOf(plan.getJhQty());
// ① 全额入库realQty >= remain -> 直接置 1不做扣减
if (remain.compareTo(BigDecimal.ZERO) <= 0 || realQty.compareTo(remain) >= 0) {
gysJhMapper.updateStatusById(jhId, "1"); // 全部入库
// 不调用 decreaseJhQtyById避免出现负数
continue;
}
// ② 部分入库realQty < remain -> 先扣减,再把该行置 2
gysJhMapper.decreaseJhQtyById(jhId, realQty); // jh_qty = jh_qty - realQty
gysJhMapper.updateStatusById(jhId, "2"); // 部分入库
}
// ========== 4. 按 sapNo 再做一轮收尾(把 <=0 的行批量收敛到 1其余置 2==========
// 说明:上面已经对每个行做了状态落地;此处是“兜底收敛”,确保同一 sapNo 下的行一致
Set<String> sapNos = dto.getRkList().stream()
.map(PcRkInfoItemDTO::getSapNo)
.filter(StringUtils::isNotEmpty)
.collect(Collectors.toSet());
for (String sapNo : sapNos) {
// 仅返回 status != '1' 的行(未完全入库的)
List<GysJh> rows = gysJhMapper.getBySapNo(sapNo);
if (rows == null || rows.isEmpty()) continue;
List<Long> toAll = new ArrayList<>();
List<Long> toPartial = new ArrayList<>();
for (GysJh r : rows) {
long remain = r.getJhQty() == null ? 0L : r.getJhQty();
if (remain <= 0L) {
toAll.add(r.getId()); // 已经无剩余 -> 置 1
} else {
toPartial.add(r.getId()); // 仍有剩余 -> 置 2
}
}
for (Long id : toAll) {
gysJhMapper.updateStatusById(id, "1"); // 全部入库
}
if (!toPartial.isEmpty()) {
gysJhMapper.batchUpdateStatusByIds(new HashSet<>(toPartial)); // 部分入库
}
}
}
}