feat: 完善盘点出入库流程
This commit is contained in:
@@ -20,6 +20,7 @@ import com.ruoyi.in.jobdetail.mapper.MydoJobDetailMapper;
|
||||
import com.ruoyi.in.stockin.mapper.InStockinMapper;
|
||||
import com.ruoyi.out.stockout.mapper.OutStockoutMapper;
|
||||
import com.ruoyi.out.stockoutdetail.mapper.OutStockoutDetailMapper;
|
||||
import com.ruoyi.pd.diff.mapper.PdDifferenceRecordMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.in.job.mapper.MydoJobMapper;
|
||||
@@ -67,6 +68,9 @@ public class MydoJobServiceImpl implements IMydoJobService
|
||||
@Autowired
|
||||
private WcsClient wcsClient;
|
||||
|
||||
@Autowired
|
||||
private PdDifferenceRecordMapper pdDifferenceRecordMapper;
|
||||
|
||||
/**
|
||||
* 查询作业信息
|
||||
*
|
||||
@@ -377,6 +381,9 @@ public class MydoJobServiceImpl implements IMydoJobService
|
||||
if (finishResult.isError()) {
|
||||
return finishResult;
|
||||
}
|
||||
if (isInventoryInboundJob(job)) {
|
||||
pdDifferenceRecordMapper.markInboundDifferencesPendingReviewByJobId(jobId);
|
||||
}
|
||||
return AjaxResult.success();
|
||||
}
|
||||
return AjaxResult.error(Convert.toStr(map.get("v_resultmsg")));
|
||||
@@ -421,6 +428,11 @@ public class MydoJobServiceImpl implements IMydoJobService
|
||||
return job != null && job.getInOrOut() != null && job.getInOrOut() >= 20;
|
||||
}
|
||||
|
||||
private boolean isInventoryInboundJob(MydoJob job)
|
||||
{
|
||||
return job != null && (Long.valueOf(10L).equals(job.getInOrOut()) || Long.valueOf(11L).equals(job.getInOrOut()));
|
||||
}
|
||||
|
||||
/**
|
||||
* WCS 回调取货无货异常。
|
||||
*/
|
||||
|
||||
@@ -43,6 +43,30 @@ public interface PdDifferenceRecordMapper
|
||||
*/
|
||||
public int updatePdDifferenceRecord(PdDifferenceRecord pdDifferenceRecord);
|
||||
|
||||
/**
|
||||
* 审核通过后应用盘点差异到库存明细。
|
||||
*
|
||||
* @param pdDifferenceRecord 盘点差异
|
||||
* @return 结果
|
||||
*/
|
||||
public int applyApprovedDifference(PdDifferenceRecord pdDifferenceRecord);
|
||||
|
||||
/**
|
||||
* 审核通过后刷新库存主表汇总数量。
|
||||
*
|
||||
* @param pdDifferenceRecord 盘点差异
|
||||
* @return 结果
|
||||
*/
|
||||
public int refreshApprovedDifferenceStockSummary(PdDifferenceRecord pdDifferenceRecord);
|
||||
|
||||
/**
|
||||
* 盘点入库完成后,将对应差异从未入库改为待审核。
|
||||
*
|
||||
* @param jobId 盘点入库作业ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int markInboundDifferencesPendingReviewByJobId(String jobId);
|
||||
|
||||
/**
|
||||
* 删除盘点差异
|
||||
*
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.util.List;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import com.ruoyi.pd.diff.mapper.PdDifferenceRecordMapper;
|
||||
import com.ruoyi.pd.diff.domain.PdDifferenceRecord;
|
||||
import com.ruoyi.pd.diff.service.IPdDifferenceRecordService;
|
||||
@@ -97,10 +98,19 @@ public class PdDifferenceRecordServiceImpl implements IPdDifferenceRecordService
|
||||
* 通过差异记录
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int approvePdDifferenceRecord(Long id)
|
||||
{
|
||||
PdDifferenceRecord record = pdDifferenceRecordMapper.selectPdDifferenceRecordById(id);
|
||||
record.setStatus("1");
|
||||
if (record == null || !"1".equals(record.getStatus())) {
|
||||
return 0;
|
||||
}
|
||||
int applyRows = pdDifferenceRecordMapper.applyApprovedDifference(record);
|
||||
if (applyRows <= 0) {
|
||||
throw new RuntimeException("盘点差异未匹配到可更新库存");
|
||||
}
|
||||
pdDifferenceRecordMapper.refreshApprovedDifferenceStockSummary(record);
|
||||
record.setStatus("2");
|
||||
return pdDifferenceRecordMapper.updatePdDifferenceRecord(record);
|
||||
}
|
||||
|
||||
@@ -111,7 +121,10 @@ public class PdDifferenceRecordServiceImpl implements IPdDifferenceRecordService
|
||||
public int rejectPdDifferenceRecord(Long id)
|
||||
{
|
||||
PdDifferenceRecord record = pdDifferenceRecordMapper.selectPdDifferenceRecordById(id);
|
||||
record.setStatus("2");
|
||||
if (record == null || !"1".equals(record.getStatus())) {
|
||||
return 0;
|
||||
}
|
||||
record.setStatus("3");
|
||||
return pdDifferenceRecordMapper.updatePdDifferenceRecord(record);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,26 @@ package com.ruoyi.pd.stockpd.service.impl;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Date;
|
||||
import java.math.BigDecimal;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import com.ruoyi.bas.id.job.service.JobIdService;
|
||||
import com.ruoyi.bas.id.taskno.service.TaskNoService;
|
||||
import com.ruoyi.bas.stock.domain.BasStockDetail;
|
||||
import com.ruoyi.bas.stock.mapper.BasStockDetailMapper;
|
||||
import com.ruoyi.bas.stationpoint.domain.BasStationPoint;
|
||||
import com.ruoyi.bas.stationpoint.service.IBasStationPointService;
|
||||
import com.ruoyi.common.PdStockpdStatusEnum;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.text.Convert;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.in.job.domain.MydoJob;
|
||||
import com.ruoyi.in.job.service.IMydoJobService;
|
||||
import com.ruoyi.in.jobdetail.domain.MydoJobDetail;
|
||||
import com.ruoyi.in.jobdetail.service.IMydoJobDetailService;
|
||||
import com.ruoyi.system.mapper.SysDeptMapper;
|
||||
import com.ruoyi.pd.stockpd.mapper.PdStockpdMapper;
|
||||
import com.ruoyi.pd.stockpd.domain.PdStockpd;
|
||||
@@ -18,6 +30,7 @@ import com.ruoyi.pd.stockpd.domain.PdStockpdSaveDTO;
|
||||
import com.ruoyi.pd.stockpd.service.IPdStockpdService;
|
||||
import com.ruoyi.pd.stockpddetail.mapper.PdStockpdDetailMapper;
|
||||
import com.ruoyi.pd.stockpddetail.domain.PdStockpdDetail;
|
||||
import com.ruoyi.pda.mapper.PdaMapper;
|
||||
|
||||
/**
|
||||
* 盘点单据主信息Service业务层处理
|
||||
@@ -28,6 +41,10 @@ import com.ruoyi.pd.stockpddetail.domain.PdStockpdDetail;
|
||||
@Service
|
||||
public class PdStockpdServiceImpl implements IPdStockpdService
|
||||
{
|
||||
private static final long MATERIAL_INVENTORY_OUT_TYPE = 30L;
|
||||
private static final long LOCATION_INVENTORY_OUT_TYPE = 31L;
|
||||
private static final String INVENTORY_OUT_TASK_NO_TYPE = "22";
|
||||
|
||||
@Autowired
|
||||
private PdStockpdMapper pdStockpdMapper;
|
||||
|
||||
@@ -40,6 +57,24 @@ public class PdStockpdServiceImpl implements IPdStockpdService
|
||||
@Autowired
|
||||
private JobIdService jobIdService;
|
||||
|
||||
@Autowired
|
||||
private TaskNoService taskNoService;
|
||||
|
||||
@Autowired
|
||||
private BasStockDetailMapper basStockDetailMapper;
|
||||
|
||||
@Autowired
|
||||
private IBasStationPointService basStationPointService;
|
||||
|
||||
@Autowired
|
||||
private IMydoJobService mydoJobService;
|
||||
|
||||
@Autowired
|
||||
private IMydoJobDetailService mydoJobDetailService;
|
||||
|
||||
@Autowired
|
||||
private PdaMapper pdaMapper;
|
||||
|
||||
/**
|
||||
* 查询盘点单据主信息
|
||||
*
|
||||
@@ -179,22 +214,73 @@ public class PdStockpdServiceImpl implements IPdStockpdService
|
||||
* 自动分配盘点单据
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public AjaxResult autoAssignPdStockpd(String stockpdId)
|
||||
{
|
||||
StringBuilder str = new StringBuilder();
|
||||
PdStockpd stockpd = pdStockpdMapper.selectPdStockpdByStockpdId(stockpdId);
|
||||
if (stockpd == null) {
|
||||
return AjaxResult.error("盘点单据不存在");
|
||||
}
|
||||
if (!PdStockpdStatusEnum.AUDIT.getCode().equals(stockpd.getStatus())
|
||||
&& !PdStockpdStatusEnum.RUNNING.getCode().equals(stockpd.getStatus())) {
|
||||
return AjaxResult.error("只有已审核或执行中的盘点单据允许生成盘点出库作业");
|
||||
}
|
||||
|
||||
PdStockpdDetail query = new PdStockpdDetail();
|
||||
query.setStockpdId(stockpdId);
|
||||
List<PdStockpdDetail> details = pdStockpdDetailMapper.selectPdStockpdDetailList(query);
|
||||
for (PdStockpdDetail detail : details) {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("v_stockpd_detail_id", detail.getStockpdDetailId());
|
||||
pdStockpdMapper.autoAssignPdStockpdByProc(map);
|
||||
if (Convert.toStr(map.get("v_result")).equals("10")){
|
||||
str.append(detail.getStockpdDetailId()).append(Convert.toStr(map.get("v_result_msg"))).append("|");
|
||||
}else {
|
||||
str.append(detail.getStockpdDetailId()).append(Convert.toStr(map.get("v_result_msg"))).append("|");
|
||||
}
|
||||
if (details == null || details.isEmpty()) {
|
||||
return AjaxResult.error("盘点单据没有明细");
|
||||
}
|
||||
|
||||
BasStationPoint exitPoint = selectDefaultOutboundStationPoint(stockpd.getWarehouseId());
|
||||
StringBuilder str = new StringBuilder("盘点出库作业生成成功:");
|
||||
for (PdStockpdDetail detail : details) {
|
||||
BasStockDetail stockDetail = resolveInventoryStockDetail(stockpd, detail);
|
||||
BigDecimal quantity = resolveInventoryQuantity(detail, stockDetail);
|
||||
if (quantity.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
throw new RuntimeException("盘点明细数量必须大于0:" + detail.getStockpdDetailId());
|
||||
}
|
||||
|
||||
MydoJob job = buildInventoryOutboundJob(stockpd, stockDetail, exitPoint);
|
||||
if (mydoJobService.insertMydoJob(job) <= 0) {
|
||||
throw new RuntimeException("盘点出库作业生成失败:" + detail.getStockpdDetailId());
|
||||
}
|
||||
|
||||
MydoJobDetail jobDetail = buildInventoryOutboundDetail(job, stockpd, detail, stockDetail, quantity);
|
||||
if (mydoJobDetailService.insertMydoJobDetail(jobDetail) <= 0) {
|
||||
throw new RuntimeException("盘点出库作业明细生成失败:" + detail.getStockpdDetailId());
|
||||
}
|
||||
|
||||
HashMap<String, Object> reserveMap = new HashMap<>();
|
||||
reserveMap.put("stockDetailId", stockDetail.getDetailId());
|
||||
reserveMap.put("stockId", stockDetail.getStockId());
|
||||
reserveMap.put("jobDetailId", jobDetail.getJobDetailId());
|
||||
reserveMap.put("quantity", quantity);
|
||||
if (pdaMapper.reserveInventoryStockDetail(reserveMap) <= 0) {
|
||||
throw new RuntimeException("盘点库存已被占用或可用库存不足:" + detail.getStockpdDetailId());
|
||||
}
|
||||
|
||||
HashMap<String, Object> cargoMap = new HashMap<>();
|
||||
cargoMap.put("stockId", stockDetail.getStockId());
|
||||
cargoMap.put("cargoSpaceId", stockDetail.getCargoSpaceId());
|
||||
if (pdaMapper.lockInventoryOutboundCargoSpace(cargoMap) <= 0) {
|
||||
throw new RuntimeException("盘点出库货位锁定失败:" + detail.getStockpdDetailId());
|
||||
}
|
||||
|
||||
AjaxResult pushResult = mydoJobService.pushOutJobToWcs(job.getJobId());
|
||||
if (pushResult == null || pushResult.isError()) {
|
||||
throw new RuntimeException(pushResult == null ? "WCS盘点出库作业下发失败" : Convert.toStr(pushResult.get(AjaxResult.MSG_TAG)));
|
||||
}
|
||||
|
||||
updateAssignedInventoryDetail(detail, stockDetail, quantity);
|
||||
str.append(job.getJobId()).append("|");
|
||||
}
|
||||
PdStockpd update = new PdStockpd();
|
||||
update.setStockpdId(stockpdId);
|
||||
update.setStatus(PdStockpdStatusEnum.RUNNING.getCode());
|
||||
update.setStartDate(new Date());
|
||||
pdStockpdMapper.updatePdStockpd(update);
|
||||
return AjaxResult.success(str);
|
||||
}
|
||||
|
||||
@@ -237,10 +323,143 @@ public class PdStockpdServiceImpl implements IPdStockpdService
|
||||
detail.setAllotNum(0L);
|
||||
detail.setAssignNum(0L);
|
||||
detail.setStockpdId(saveDTO.getStockpdId());
|
||||
if (!StringUtils.hasText(detail.getWarehouseId())) {
|
||||
detail.setWarehouseId(saveDTO.getWarehouseId());
|
||||
}
|
||||
if (!StringUtils.hasText(detail.getWarehouseName())) {
|
||||
detail.setWarehouseName(saveDTO.getWarehouseName());
|
||||
}
|
||||
pdStockpdDetailMapper.insertPdStockpdDetail(detail);
|
||||
}
|
||||
}
|
||||
return saveDTO.getStockpdId();
|
||||
}
|
||||
|
||||
private BasStockDetail resolveInventoryStockDetail(PdStockpd stockpd, PdStockpdDetail detail) {
|
||||
BasStockDetail stockDetail = null;
|
||||
if (StringUtils.hasText(detail.getStockDetailId())) {
|
||||
stockDetail = basStockDetailMapper.selectBasStockDetailByDetailId(detail.getStockDetailId());
|
||||
}
|
||||
if (stockDetail == null) {
|
||||
BasStockDetail query = new BasStockDetail();
|
||||
query.setStockId(detail.getStockId());
|
||||
query.setTrayCode(detail.getTrayCode());
|
||||
query.setWarehouseId(StringUtils.hasText(detail.getWarehouseId()) ? detail.getWarehouseId() : stockpd.getWarehouseId());
|
||||
query.setCargoSpaceId(detail.getCargoSpaceId());
|
||||
query.setProductId(detail.getProductId());
|
||||
List<BasStockDetail> stockDetails = basStockDetailMapper.selectBasStockDetailList(query);
|
||||
if (stockDetails != null && !stockDetails.isEmpty()) {
|
||||
stockDetail = stockDetails.get(0);
|
||||
}
|
||||
}
|
||||
if (stockDetail == null) {
|
||||
throw new RuntimeException("未找到盘点库存明细:" + detail.getStockpdDetailId());
|
||||
}
|
||||
return stockDetail;
|
||||
}
|
||||
|
||||
private BigDecimal resolveInventoryQuantity(PdStockpdDetail detail, BasStockDetail stockDetail) {
|
||||
BigDecimal quantity = detail.getQuantity() == null ? null : BigDecimal.valueOf(detail.getQuantity());
|
||||
if (quantity == null || quantity.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
quantity = stockDetail.getAvailableQuantity();
|
||||
}
|
||||
if (quantity == null || quantity.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
quantity = stockDetail.getQuantity();
|
||||
}
|
||||
BigDecimal availableQuantity = stockDetail.getAvailableQuantity();
|
||||
if (availableQuantity != null && availableQuantity.compareTo(BigDecimal.ZERO) > 0
|
||||
&& quantity.compareTo(availableQuantity) > 0) {
|
||||
throw new RuntimeException("盘点数量不能大于可用库存:" + detail.getStockpdDetailId());
|
||||
}
|
||||
return quantity == null ? BigDecimal.ZERO : quantity;
|
||||
}
|
||||
|
||||
private BasStationPoint selectDefaultOutboundStationPoint(String warehouseId) {
|
||||
BasStationPoint query = new BasStationPoint();
|
||||
query.setWarehouseId(warehouseId);
|
||||
query.setStatus("0");
|
||||
query.setPointStatus("0");
|
||||
List<BasStationPoint> pointList = basStationPointService.selectBasStationPointList(query);
|
||||
if (pointList != null) {
|
||||
for (BasStationPoint point : pointList) {
|
||||
if (point != null && ("2".equals(point.getPointType()) || "3".equals(point.getPointType()))) {
|
||||
return point;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("当前仓库未配置可用出库点位");
|
||||
}
|
||||
|
||||
private MydoJob buildInventoryOutboundJob(PdStockpd stockpd, BasStockDetail stockDetail, BasStationPoint exitPoint) {
|
||||
String jobId = jobIdService.getId("PC");
|
||||
String taskNo = taskNoService.getTaskNo(INVENTORY_OUT_TASK_NO_TYPE);
|
||||
MydoJob job = new MydoJob();
|
||||
job.setJobId(jobId);
|
||||
job.setTaskNo(StringUtils.hasText(taskNo) ? taskNo : jobId);
|
||||
job.setInOrOut(resolveInventoryOutType(stockpd));
|
||||
job.setStatus("1");
|
||||
job.setExecutionPhase("0");
|
||||
job.setTrayCode(stockDetail.getTrayCode());
|
||||
job.setWarehouseId(StringUtils.hasText(stockDetail.getWarehouseId()) ? stockDetail.getWarehouseId() : stockpd.getWarehouseId());
|
||||
job.setWarehouseName(StringUtils.hasText(stockDetail.getWarehouseName()) ? stockDetail.getWarehouseName() : stockpd.getWarehouseName());
|
||||
job.setCargoSpaceId(stockDetail.getCargoSpaceId());
|
||||
job.setCargoSpaceName(stockDetail.getCargoSpaceName());
|
||||
job.setExitId(exitPoint.getPointId());
|
||||
job.setPriority(10L);
|
||||
job.setHeight(BigDecimal.ZERO);
|
||||
job.setWeight(BigDecimal.ZERO);
|
||||
copyLoginUser(job);
|
||||
return job;
|
||||
}
|
||||
|
||||
private Long resolveInventoryOutType(PdStockpd stockpd) {
|
||||
return "2".equals(stockpd.getPdType()) ? LOCATION_INVENTORY_OUT_TYPE : MATERIAL_INVENTORY_OUT_TYPE;
|
||||
}
|
||||
|
||||
private MydoJobDetail buildInventoryOutboundDetail(MydoJob job, PdStockpd stockpd, PdStockpdDetail detail,
|
||||
BasStockDetail stockDetail, BigDecimal quantity) {
|
||||
MydoJobDetail jobDetail = new MydoJobDetail();
|
||||
jobDetail.setJobDetailId(job.getJobId() + "-1");
|
||||
jobDetail.setJobId(job.getJobId());
|
||||
jobDetail.setStockId(stockDetail.getStockId());
|
||||
jobDetail.setLotNo(stockDetail.getLotNo());
|
||||
jobDetail.setInDate(DateUtils.getTime());
|
||||
jobDetail.setInOrOutId(stockpd.getStockpdId());
|
||||
jobDetail.setInOrOutDId(detail.getStockpdDetailId());
|
||||
jobDetail.setProductId(stockDetail.getProductId());
|
||||
jobDetail.setProductName(stockDetail.getProductName());
|
||||
jobDetail.setStockQuantity(stockDetail.getQuantity());
|
||||
jobDetail.setOutQuantity(quantity);
|
||||
jobDetail.setStockinDetailId(stockDetail.getDetailId());
|
||||
return jobDetail;
|
||||
}
|
||||
|
||||
private void updateAssignedInventoryDetail(PdStockpdDetail detail, BasStockDetail stockDetail, BigDecimal quantity) {
|
||||
PdStockpdDetail update = new PdStockpdDetail();
|
||||
update.setStockpdDetailId(detail.getStockpdDetailId());
|
||||
update.setStockId(stockDetail.getStockId());
|
||||
update.setStockDetailId(stockDetail.getDetailId());
|
||||
update.setTrayCode(stockDetail.getTrayCode());
|
||||
update.setCargoSpaceId(stockDetail.getCargoSpaceId());
|
||||
update.setCargoSpaceName(stockDetail.getCargoSpaceName());
|
||||
update.setWarehouseId(stockDetail.getWarehouseId());
|
||||
update.setWarehouseName(stockDetail.getWarehouseName());
|
||||
update.setProductId(stockDetail.getProductId());
|
||||
update.setProductName(stockDetail.getProductName());
|
||||
update.setQuantity(quantity.longValue());
|
||||
update.setAllotNum(quantity.longValue());
|
||||
update.setAssignNum(0L);
|
||||
pdStockpdDetailMapper.updatePdStockpdDetail(update);
|
||||
}
|
||||
|
||||
private void copyLoginUser(MydoJob job) {
|
||||
try {
|
||||
job.setUserId(SecurityUtils.getUserId());
|
||||
job.setDeptId(SecurityUtils.getDeptId());
|
||||
job.setUserName(SecurityUtils.getUsername());
|
||||
} catch (RuntimeException ignored) {
|
||||
// Unit tests and external callbacks may run without a Spring Security context.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,30 @@ public class PdStockpdDetail extends BaseEntity
|
||||
@Excel(name = "托盘码")
|
||||
private String trayCode;
|
||||
|
||||
/** 库存ID */
|
||||
@Excel(name = "库存ID")
|
||||
private String stockId;
|
||||
|
||||
/** 库存明细ID */
|
||||
@Excel(name = "库存明细ID")
|
||||
private String stockDetailId;
|
||||
|
||||
/** 货位ID */
|
||||
@Excel(name = "货位ID")
|
||||
private String cargoSpaceId;
|
||||
|
||||
/** 货位名称 */
|
||||
@Excel(name = "货位名称")
|
||||
private String cargoSpaceName;
|
||||
|
||||
/** 仓库ID */
|
||||
@Excel(name = "仓库ID")
|
||||
private String warehouseId;
|
||||
|
||||
/** 仓库名称 */
|
||||
@Excel(name = "仓库名称")
|
||||
private String warehouseName;
|
||||
|
||||
/** 物料编码 */
|
||||
@Excel(name = "物料编码")
|
||||
private String productId;
|
||||
@@ -86,6 +110,66 @@ public class PdStockpdDetail extends BaseEntity
|
||||
return trayCode;
|
||||
}
|
||||
|
||||
public void setStockId(String stockId)
|
||||
{
|
||||
this.stockId = stockId;
|
||||
}
|
||||
|
||||
public String getStockId()
|
||||
{
|
||||
return stockId;
|
||||
}
|
||||
|
||||
public void setStockDetailId(String stockDetailId)
|
||||
{
|
||||
this.stockDetailId = stockDetailId;
|
||||
}
|
||||
|
||||
public String getStockDetailId()
|
||||
{
|
||||
return stockDetailId;
|
||||
}
|
||||
|
||||
public void setCargoSpaceId(String cargoSpaceId)
|
||||
{
|
||||
this.cargoSpaceId = cargoSpaceId;
|
||||
}
|
||||
|
||||
public String getCargoSpaceId()
|
||||
{
|
||||
return cargoSpaceId;
|
||||
}
|
||||
|
||||
public void setCargoSpaceName(String cargoSpaceName)
|
||||
{
|
||||
this.cargoSpaceName = cargoSpaceName;
|
||||
}
|
||||
|
||||
public String getCargoSpaceName()
|
||||
{
|
||||
return cargoSpaceName;
|
||||
}
|
||||
|
||||
public void setWarehouseId(String warehouseId)
|
||||
{
|
||||
this.warehouseId = warehouseId;
|
||||
}
|
||||
|
||||
public String getWarehouseId()
|
||||
{
|
||||
return warehouseId;
|
||||
}
|
||||
|
||||
public void setWarehouseName(String warehouseName)
|
||||
{
|
||||
this.warehouseName = warehouseName;
|
||||
}
|
||||
|
||||
public String getWarehouseName()
|
||||
{
|
||||
return warehouseName;
|
||||
}
|
||||
|
||||
public void setProductId(String productId)
|
||||
{
|
||||
this.productId = productId;
|
||||
@@ -142,6 +226,12 @@ public class PdStockpdDetail extends BaseEntity
|
||||
.append("stockpdDetailId", getStockpdDetailId())
|
||||
.append("stockpdId", getStockpdId())
|
||||
.append("trayCode", getTrayCode())
|
||||
.append("stockId", getStockId())
|
||||
.append("stockDetailId", getStockDetailId())
|
||||
.append("cargoSpaceId", getCargoSpaceId())
|
||||
.append("cargoSpaceName", getCargoSpaceName())
|
||||
.append("warehouseId", getWarehouseId())
|
||||
.append("warehouseName", getWarehouseName())
|
||||
.append("productId", getProductId())
|
||||
.append("productName", getProductName())
|
||||
.append("quantity", getQuantity())
|
||||
|
||||
@@ -192,6 +192,15 @@ public class PdaController extends BaseController {
|
||||
return AjaxResult.success(pdaService.outboundTaskList(query));
|
||||
}
|
||||
|
||||
/**
|
||||
* PDA 盘点待确认任务列表。
|
||||
*/
|
||||
@GetMapping("/inventoryTaskList")
|
||||
@PreAuthorize("@ss.hasPermi('pd:stockpd:list')")
|
||||
public AjaxResult inventoryTaskList(@RequestParam Map<String, Object> query) {
|
||||
return AjaxResult.success(pdaService.inventoryTaskList(query));
|
||||
}
|
||||
|
||||
/**
|
||||
* PDA 查询当前仓库库内空托按条码头分组的数量。
|
||||
*/
|
||||
@@ -246,6 +255,19 @@ public class PdaController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PDA 扫码查询盘点任务明细。
|
||||
*/
|
||||
@GetMapping("/inventoryDetail")
|
||||
@PreAuthorize("@ss.hasPermi('pd:stockpd:list')")
|
||||
public AjaxResult inventoryDetail(@RequestParam Map<String, Object> query) {
|
||||
try {
|
||||
return AjaxResult.success(pdaService.inventoryDetail(query));
|
||||
} catch (RuntimeException e) {
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PDA 确认出库。
|
||||
*/
|
||||
@@ -261,4 +283,19 @@ public class PdaController extends BaseController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PDA 确认盘点。
|
||||
*/
|
||||
@PostMapping("/inventoryConfirm")
|
||||
@PreAuthorize("@ss.hasPermi('pd:stockpd:edit')")
|
||||
@Log(title = "PDA盘点确认", businessType = BusinessType.UPDATE)
|
||||
public AjaxResult inventoryConfirm(@RequestBody Map<String, Object> data) {
|
||||
try {
|
||||
pdaService.confirmInventory(data);
|
||||
return AjaxResult.success();
|
||||
} catch (RuntimeException e) {
|
||||
return AjaxResult.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -55,16 +55,36 @@ public interface PdaMapper {
|
||||
*/
|
||||
List<HashMap<String, Object>> outboundTaskList(HashMap<String, Object> map);
|
||||
|
||||
/**
|
||||
* PDA 盘点待确认任务列表。
|
||||
*/
|
||||
List<HashMap<String, Object>> inventoryTaskList(HashMap<String, Object> map);
|
||||
|
||||
/**
|
||||
* PDA 扫码查询出库任务明细。
|
||||
*/
|
||||
HashMap<String, Object> selectOutboundDetail(HashMap<String, Object> map);
|
||||
|
||||
/**
|
||||
* PDA 扫码查询盘点出库任务明细。
|
||||
*/
|
||||
HashMap<String, Object> selectInventoryDetail(HashMap<String, Object> map);
|
||||
|
||||
/**
|
||||
* 查询出库托盘上的作业物料明细。
|
||||
*/
|
||||
List<HashMap<String, Object>> selectOutboundTrayMaterials(HashMap<String, Object> map);
|
||||
|
||||
/**
|
||||
* 查询盘点托盘上的作业物料明细。
|
||||
*/
|
||||
List<HashMap<String, Object>> selectInventoryTrayMaterials(HashMap<String, Object> map);
|
||||
|
||||
/**
|
||||
* 查询盘点出库对应的盘点入库作业,防止 PDA 重复确认重复生成回库作业。
|
||||
*/
|
||||
HashMap<String, Object> selectInventoryInboundJobByOutboundJobId(@Param("outboundJobId") String outboundJobId);
|
||||
|
||||
/**
|
||||
* 查询出库确认后托盘上仍有库存的物料。
|
||||
*/
|
||||
@@ -95,8 +115,18 @@ public interface PdaMapper {
|
||||
*/
|
||||
int reserveEmptyTrayStockDetail(HashMap<String, Object> map);
|
||||
|
||||
/**
|
||||
* 预占盘点库存明细,避免重复生成盘点出库作业。
|
||||
*/
|
||||
int reserveInventoryStockDetail(HashMap<String, Object> map);
|
||||
|
||||
/**
|
||||
* 将空托所在货位标记为出库锁定。
|
||||
*/
|
||||
int lockEmptyTrayCargoSpace(HashMap<String, Object> map);
|
||||
|
||||
/**
|
||||
* 将盘点托盘所在货位标记为出库锁定。
|
||||
*/
|
||||
int lockInventoryOutboundCargoSpace(HashMap<String, Object> map);
|
||||
}
|
||||
|
||||
@@ -131,6 +131,14 @@ public interface PdaService {
|
||||
*/
|
||||
List<Map<String, Object>> outboundTaskList(Map<String, Object> query);
|
||||
|
||||
/**
|
||||
* PDA 盘点待确认任务列表。
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @return 盘点任务列表
|
||||
*/
|
||||
List<Map<String, Object>> inventoryTaskList(Map<String, Object> query);
|
||||
|
||||
/**
|
||||
* PDA 扫码查询出库任务明细。
|
||||
*
|
||||
@@ -139,6 +147,14 @@ public interface PdaService {
|
||||
*/
|
||||
Map<String, Object> outboundDetail(Map<String, Object> query);
|
||||
|
||||
/**
|
||||
* PDA 扫码查询盘点任务明细。
|
||||
*
|
||||
* @param query 查询条件,包含任务号和托盘码
|
||||
* @return 盘点任务明细
|
||||
*/
|
||||
Map<String, Object> inventoryDetail(Map<String, Object> query);
|
||||
|
||||
/**
|
||||
* PDA 确认出库。
|
||||
*
|
||||
@@ -146,4 +162,11 @@ public interface PdaService {
|
||||
*/
|
||||
void confirmOutbound(Map<String, Object> data);
|
||||
|
||||
/**
|
||||
* PDA 确认盘点。
|
||||
*
|
||||
* @param data 确认数据
|
||||
*/
|
||||
void confirmInventory(Map<String, Object> data);
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,12 @@ import com.ruoyi.in.stockin.domain.InStockin;
|
||||
import com.ruoyi.in.stockin.mapper.InStockinMapper;
|
||||
import com.ruoyi.in.sotckindetail.domain.InStockinDetail;
|
||||
import com.ruoyi.in.sotckindetail.mapper.InStockinDetailMapper;
|
||||
import com.ruoyi.pd.commit.domain.PdCommitRecord;
|
||||
import com.ruoyi.pd.commit.mapper.PdCommitRecordMapper;
|
||||
import com.ruoyi.pd.diff.domain.PdDifferenceRecord;
|
||||
import com.ruoyi.pd.diff.mapper.PdDifferenceRecordMapper;
|
||||
import com.ruoyi.pd.stockpddetail.domain.PdStockpdDetail;
|
||||
import com.ruoyi.pd.stockpddetail.mapper.PdStockpdDetailMapper;
|
||||
import com.ruoyi.pda.domain.AddInJobRequest;
|
||||
import com.ruoyi.pda.domain.BindTrayRequest;
|
||||
import com.ruoyi.pda.domain.EmptyTrayOutboundRequest;
|
||||
@@ -51,6 +57,8 @@ public class PdaServiceImpl implements PdaService {
|
||||
private static final String EMPTY_TRAY_IN_TASK_NO_TYPE = "6";
|
||||
private static final String EMPTY_TRAY_OUT_TASK_NO_TYPE = "20";
|
||||
private static final BigDecimal ONE_EMPTY_TRAY = BigDecimal.ONE;
|
||||
private static final long MATERIAL_INVENTORY_OUT_TYPE = 30L;
|
||||
private static final long LOCATION_INVENTORY_OUT_TYPE = 31L;
|
||||
|
||||
@Autowired
|
||||
private PdaMapper pdaMapper;
|
||||
@@ -82,6 +90,15 @@ public class PdaServiceImpl implements PdaService {
|
||||
@Autowired
|
||||
private TaskNoService taskNoService;
|
||||
|
||||
@Autowired
|
||||
private PdCommitRecordMapper pdCommitRecordMapper;
|
||||
|
||||
@Autowired
|
||||
private PdDifferenceRecordMapper pdDifferenceRecordMapper;
|
||||
|
||||
@Autowired
|
||||
private PdStockpdDetailMapper pdStockpdDetailMapper;
|
||||
|
||||
// ─────────────────────────────────────────────
|
||||
// 入库待处理任务列表
|
||||
// ─────────────────────────────────────────────
|
||||
@@ -653,6 +670,18 @@ public class PdaServiceImpl implements PdaService {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> inventoryTaskList(Map<String, Object> query) {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
if (query != null) {
|
||||
map.putAll(query);
|
||||
}
|
||||
List<HashMap<String, Object>> rows = pdaMapper.inventoryTaskList(map);
|
||||
List<Map<String, Object>> result = new ArrayList<>();
|
||||
result.addAll(rows);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> outboundDetail(Map<String, Object> query) {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
@@ -670,6 +699,23 @@ public class PdaServiceImpl implements PdaService {
|
||||
return detail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> inventoryDetail(Map<String, Object> query) {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
if (query != null) {
|
||||
map.putAll(query);
|
||||
}
|
||||
HashMap<String, Object> detail = pdaMapper.selectInventoryDetail(map);
|
||||
if (detail == null || detail.isEmpty()) {
|
||||
throw new RuntimeException("未找到对应盘点任务");
|
||||
}
|
||||
HashMap<String, Object> materialQuery = new HashMap<>();
|
||||
materialQuery.put("jobId", detail.get("jobId"));
|
||||
List<HashMap<String, Object>> materials = pdaMapper.selectInventoryTrayMaterials(materialQuery);
|
||||
detail.put("materials", materials == null ? new ArrayList<>() : materials);
|
||||
return detail;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void confirmOutbound(Map<String, Object> data) {
|
||||
@@ -691,6 +737,224 @@ public class PdaServiceImpl implements PdaService {
|
||||
createReturnInboundJobIfNeeded(outboundJob);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void confirmInventory(Map<String, Object> data) {
|
||||
Map<String, Object> detail = inventoryDetail(data);
|
||||
if (!"5".equals(Convert.toStr(detail.get("executionPhase")))) {
|
||||
throw new RuntimeException("盘点出库未到达出口,不能扫码确认");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<HashMap<String, Object>> materials = detail.get("materials") instanceof List<?>
|
||||
? (List<HashMap<String, Object>>) detail.get("materials")
|
||||
: new ArrayList<>();
|
||||
if (materials.isEmpty()) {
|
||||
throw new RuntimeException("盘点作业无物料明细");
|
||||
}
|
||||
|
||||
List<Map<String, Object>> requestMaterials = normalizeInventoryRequestMaterials(data, materials);
|
||||
for (HashMap<String, Object> material : materials) {
|
||||
Map<String, Object> requestMaterial = findInventoryRequestMaterial(requestMaterials, material);
|
||||
BigDecimal oldQuantity = toBigDecimal(firstNotBlank(mapValue(material, "quantity"), mapValue(material, "stockQuantity")));
|
||||
BigDecimal actualQuantity = toBigDecimal(firstNotBlank(
|
||||
mapValue(requestMaterial, "actualQuantity"),
|
||||
mapValue(requestMaterial, "quantity")));
|
||||
if (actualQuantity.compareTo(BigDecimal.ZERO) < 0) {
|
||||
throw new RuntimeException("盘点数量不能小于0");
|
||||
}
|
||||
insertInventoryCommitRecord(detail, material, oldQuantity, actualQuantity);
|
||||
if (oldQuantity.compareTo(actualQuantity) != 0) {
|
||||
insertInventoryDifferenceRecord(detail, material, oldQuantity, actualQuantity);
|
||||
}
|
||||
updateInventoryStockpdDetail(detail, material, oldQuantity, actualQuantity);
|
||||
}
|
||||
|
||||
String jobId = Convert.toStr(detail.get("jobId"));
|
||||
MydoJob outboundJob = mydoJobService.selectMydoJobByJobId(jobId);
|
||||
AjaxResult result = mydoJobService.completeJob(jobId, "2");
|
||||
if (result == null || result.isError()) {
|
||||
throw new RuntimeException(result == null ? "盘点出库确认失败" : Convert.toStr(result.get(AjaxResult.MSG_TAG)));
|
||||
}
|
||||
createInventoryInboundJobIfNeeded(outboundJob, materials);
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> normalizeInventoryRequestMaterials(Map<String, Object> data, List<HashMap<String, Object>> materials) {
|
||||
Object payload = data == null ? null : data.get("materials");
|
||||
List<Map<String, Object>> result = new ArrayList<>();
|
||||
if (payload instanceof List<?> list && !list.isEmpty()) {
|
||||
for (Object item : list) {
|
||||
if (item instanceof Map<?, ?>) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> material = (Map<String, Object>) item;
|
||||
result.add(material);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String, Object> findInventoryRequestMaterial(List<Map<String, Object>> requestMaterials, Map<String, Object> material) {
|
||||
String jobDetailId = mapString(material, "jobDetailId");
|
||||
String stockDetailId = mapString(material, "stockDetailId");
|
||||
String stockpdDetailId = mapString(material, "stockpdDetailId");
|
||||
for (Map<String, Object> requestMaterial : requestMaterials) {
|
||||
if (StringUtils.hasText(jobDetailId) && jobDetailId.equals(mapString(requestMaterial, "jobDetailId"))) {
|
||||
return requestMaterial;
|
||||
}
|
||||
if (StringUtils.hasText(stockDetailId) && stockDetailId.equals(mapString(requestMaterial, "stockDetailId"))) {
|
||||
return requestMaterial;
|
||||
}
|
||||
if (StringUtils.hasText(stockpdDetailId) && stockpdDetailId.equals(mapString(requestMaterial, "stockpdDetailId"))) {
|
||||
return requestMaterial;
|
||||
}
|
||||
}
|
||||
return material;
|
||||
}
|
||||
|
||||
private void insertInventoryCommitRecord(Map<String, Object> detail, Map<String, Object> material,
|
||||
BigDecimal oldQuantity, BigDecimal actualQuantity) {
|
||||
PdCommitRecord record = new PdCommitRecord();
|
||||
record.setWarehouseId(Convert.toStr(detail.get("warehouseId")));
|
||||
record.setTrayCode(Convert.toStr(detail.get("trayCode")));
|
||||
record.setStockId(mapString(material, "stockId"));
|
||||
record.setProductId(mapProductId(material));
|
||||
record.setOldQuantity(oldQuantity.longValue());
|
||||
record.setPdQuantity(actualQuantity.longValue());
|
||||
record.setUserId(SecurityUtils.getUserId());
|
||||
record.setDepeId(SecurityUtils.getDeptId());
|
||||
record.setStockpdDetailId(mapString(material, "stockpdDetailId"));
|
||||
record.setCreateTime(DateUtils.getNowDate());
|
||||
pdCommitRecordMapper.insertPdCommitRecord(record);
|
||||
}
|
||||
|
||||
private void insertInventoryDifferenceRecord(Map<String, Object> detail, Map<String, Object> material,
|
||||
BigDecimal oldQuantity, BigDecimal actualQuantity) {
|
||||
PdDifferenceRecord record = new PdDifferenceRecord();
|
||||
record.setWarehouseId(Convert.toStr(detail.get("warehouseId")));
|
||||
record.setWarehouseName(Convert.toStr(detail.get("warehouseName")));
|
||||
record.setTrayCode(Convert.toStr(detail.get("trayCode")));
|
||||
record.setProductId(mapProductId(material));
|
||||
record.setProductName(mapProductName(material));
|
||||
record.setOldQuantity(oldQuantity.longValue());
|
||||
record.setPdQuantity(actualQuantity.longValue());
|
||||
record.setUserId(SecurityUtils.getUserId());
|
||||
record.setUserName(SecurityUtils.getUsername());
|
||||
record.setDepeId(SecurityUtils.getDeptId());
|
||||
record.setDepeName(null);
|
||||
record.setStockpdDetailId(mapString(material, "stockpdDetailId"));
|
||||
record.setStatus("0");
|
||||
record.setRecordType(resolveDifferenceRecordType(oldQuantity, actualQuantity));
|
||||
record.setCreateTime(DateUtils.getNowDate());
|
||||
pdDifferenceRecordMapper.insertPdDifferenceRecord(record);
|
||||
}
|
||||
|
||||
private String resolveDifferenceRecordType(BigDecimal oldQuantity, BigDecimal actualQuantity) {
|
||||
if (oldQuantity.compareTo(actualQuantity) < 0) {
|
||||
return "1";
|
||||
}
|
||||
if (actualQuantity.compareTo(BigDecimal.ZERO) == 0) {
|
||||
return "3";
|
||||
}
|
||||
return "2";
|
||||
}
|
||||
|
||||
private void updateInventoryStockpdDetail(Map<String, Object> detail, Map<String, Object> material,
|
||||
BigDecimal oldQuantity, BigDecimal actualQuantity) {
|
||||
PdStockpdDetail update = new PdStockpdDetail();
|
||||
update.setStockpdDetailId(mapString(material, "stockpdDetailId"));
|
||||
update.setStockId(mapString(material, "stockId"));
|
||||
update.setStockDetailId(mapString(material, "stockDetailId"));
|
||||
update.setTrayCode(Convert.toStr(detail.get("trayCode")));
|
||||
update.setWarehouseId(Convert.toStr(detail.get("warehouseId")));
|
||||
update.setWarehouseName(Convert.toStr(detail.get("warehouseName")));
|
||||
update.setCargoSpaceId(Convert.toStr(detail.get("locationCode")));
|
||||
update.setCargoSpaceName(Convert.toStr(detail.get("locationName")));
|
||||
update.setProductId(mapProductId(material));
|
||||
update.setProductName(mapProductName(material));
|
||||
update.setQuantity(oldQuantity.longValue());
|
||||
update.setAllotNum(actualQuantity.longValue());
|
||||
update.setAssignNum(actualQuantity.longValue());
|
||||
pdStockpdDetailMapper.updatePdStockpdDetail(update);
|
||||
}
|
||||
|
||||
private void createInventoryInboundJobIfNeeded(MydoJob outboundJob, List<HashMap<String, Object>> materials) {
|
||||
if (outboundJob == null || !StringUtils.hasText(outboundJob.getTrayCode()) || !StringUtils.hasText(outboundJob.getWarehouseId())) {
|
||||
return;
|
||||
}
|
||||
HashMap<String, Object> exists = pdaMapper.selectInventoryInboundJobByOutboundJobId(outboundJob.getJobId());
|
||||
if (exists != null && !exists.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String returnJobId = jobIdService.getId("PR");
|
||||
String returnTaskNo = taskNoService.getTaskNo("2");
|
||||
MydoJob returnJob = new MydoJob();
|
||||
returnJob.setJobId(returnJobId);
|
||||
returnJob.setTaskNo(StringUtils.hasText(returnTaskNo) ? returnTaskNo : returnJobId);
|
||||
returnJob.setInOrOut(resolveInventoryInboundType(outboundJob));
|
||||
returnJob.setStatus("1");
|
||||
returnJob.setExecutionPhase("0");
|
||||
returnJob.setTrayCode(outboundJob.getTrayCode());
|
||||
returnJob.setWarehouseId(outboundJob.getWarehouseId());
|
||||
returnJob.setWarehouseName(outboundJob.getWarehouseName());
|
||||
returnJob.setEntranceId(outboundJob.getExitId());
|
||||
returnJob.setPriority(10L);
|
||||
returnJob.setHeight(BigDecimal.ZERO);
|
||||
returnJob.setWeight(BigDecimal.ZERO);
|
||||
copyLoginUser(returnJob);
|
||||
if (StringUtils.hasText(outboundJob.getExitId())) {
|
||||
BasStationPoint exitPoint = basStationPointService.selectBasStationPointByPointId(outboundJob.getExitId());
|
||||
if (exitPoint != null) {
|
||||
returnJob.setRoadwayId(exitPoint.getRoadwayId());
|
||||
}
|
||||
}
|
||||
if (mydoJobService.insertMydoJob(returnJob) <= 0) {
|
||||
throw new RuntimeException("盘点入库作业生成失败");
|
||||
}
|
||||
|
||||
int index = 1;
|
||||
for (HashMap<String, Object> material : materials) {
|
||||
BigDecimal quantity = toBigDecimal(firstNotBlank(mapValue(material, "quantity"), mapValue(material, "stockQuantity")));
|
||||
if (quantity.compareTo(BigDecimal.ZERO) <= 0) {
|
||||
continue;
|
||||
}
|
||||
MydoJobDetail returnDetail = new MydoJobDetail();
|
||||
returnDetail.setJobDetailId(returnJobId + "-" + index++);
|
||||
returnDetail.setJobId(returnJobId);
|
||||
returnDetail.setStockId(mapString(material, "stockId"));
|
||||
returnDetail.setLotNo(mapString(material, "lotNo"));
|
||||
returnDetail.setInDate(DateUtils.getTime());
|
||||
returnDetail.setInOrOutId(outboundJob.getJobId());
|
||||
returnDetail.setInOrOutDId(mapString(material, "stockpdDetailId"));
|
||||
returnDetail.setProductId(mapProductId(material));
|
||||
returnDetail.setProductName(mapProductName(material));
|
||||
returnDetail.setInQuantity(quantity);
|
||||
returnDetail.setStockQuantity(quantity);
|
||||
returnDetail.setStockinDetailId(mapString(material, "stockDetailId"));
|
||||
mydoJobDetailService.insertMydoJobDetail(returnDetail);
|
||||
}
|
||||
|
||||
ApiResponse<String> wcsResponse = wcsClient.sendPutawayTask(returnJob);
|
||||
if (wcsResponse == null || !wcsResponse.isSuccess()) {
|
||||
String message = wcsResponse == null ? "WCS接口无返回" : wcsResponse.getMessage();
|
||||
throw new RuntimeException("WCS盘点回库作业下发失败:" + message);
|
||||
}
|
||||
markInJobDispatchedToWcs(returnJobId);
|
||||
}
|
||||
|
||||
private Long resolveInventoryInboundType(MydoJob outboundJob) {
|
||||
return outboundJob.getInOrOut() != null && outboundJob.getInOrOut() == LOCATION_INVENTORY_OUT_TYPE ? 11L : 10L;
|
||||
}
|
||||
|
||||
private String mapProductId(Map<String, Object> material) {
|
||||
return Convert.toStr(firstNotBlank(mapValue(material, "productId"), mapValue(material, "materialCode")));
|
||||
}
|
||||
|
||||
private String mapProductName(Map<String, Object> material) {
|
||||
return Convert.toStr(firstNotBlank(mapValue(material, "productName"), mapValue(material, "materialName")));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private BigDecimal applyOutboundMaterialQuantities(Map<String, Object> data, Map<String, Object> detail) {
|
||||
Object materialPayload = data == null ? null : data.get("materials");
|
||||
|
||||
@@ -112,6 +112,88 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="applyApprovedDifference" parameterType="PdDifferenceRecord">
|
||||
update bsd
|
||||
set bsd.quantity = #{pdQuantity},
|
||||
bsd.out_quantity = case
|
||||
when isnull(bsd.out_quantity, 0) > #{pdQuantity} then #{pdQuantity}
|
||||
else isnull(bsd.out_quantity, 0)
|
||||
end,
|
||||
bsd.update_time = sysdatetime()
|
||||
from bas_stock_detail bsd
|
||||
inner join bas_stock bs on bsd.stock_id = bs.stock_id
|
||||
left join pd_stockpd_detail pdd on pdd.stockpd_detail_id = #{stockpdDetailId}
|
||||
left join pd_stockpd_detail_finish pddf on pddf.stockpd_detail_id = #{stockpdDetailId}
|
||||
outer apply (
|
||||
select coalesce(nullif(pdd.stock_detail_id, ''), nullif(pddf.stock_detail_id, '')) as stock_detail_id
|
||||
) src
|
||||
where (
|
||||
src.stock_detail_id is not null
|
||||
and (bsd.stockin_detail_id = src.stock_detail_id or bsd.detail_id = src.stock_detail_id)
|
||||
)
|
||||
or (
|
||||
src.stock_detail_id is null
|
||||
and bs.tray_code = #{trayCode}
|
||||
and bsd.product_id = #{productId}
|
||||
<if test="warehouseId != null and warehouseId != ''">
|
||||
and bs.warehouse_id = #{warehouseId}
|
||||
</if>
|
||||
)
|
||||
</update>
|
||||
|
||||
<update id="refreshApprovedDifferenceStockSummary" parameterType="PdDifferenceRecord">
|
||||
update bs
|
||||
set bs.quantity = isnull(bsa.quantity, 0),
|
||||
bs.out_quantity = isnull(bsa.out_quantity, 0)
|
||||
from bas_stock bs
|
||||
left join (
|
||||
select stock_id,
|
||||
sum(isnull(quantity, 0)) as quantity,
|
||||
sum(isnull(out_quantity, 0)) as out_quantity
|
||||
from bas_stock_detail
|
||||
group by stock_id
|
||||
) bsa on bsa.stock_id = bs.stock_id
|
||||
where bs.stock_id in (
|
||||
select distinct bsd.stock_id
|
||||
from bas_stock_detail bsd
|
||||
inner join bas_stock xbs on bsd.stock_id = xbs.stock_id
|
||||
left join pd_stockpd_detail pdd on pdd.stockpd_detail_id = #{stockpdDetailId}
|
||||
left join pd_stockpd_detail_finish pddf on pddf.stockpd_detail_id = #{stockpdDetailId}
|
||||
outer apply (
|
||||
select coalesce(nullif(pdd.stock_detail_id, ''), nullif(pddf.stock_detail_id, '')) as stock_detail_id
|
||||
) src
|
||||
where (
|
||||
src.stock_detail_id is not null
|
||||
and (bsd.stockin_detail_id = src.stock_detail_id or bsd.detail_id = src.stock_detail_id)
|
||||
)
|
||||
or (
|
||||
src.stock_detail_id is null
|
||||
and xbs.tray_code = #{trayCode}
|
||||
and bsd.product_id = #{productId}
|
||||
<if test="warehouseId != null and warehouseId != ''">
|
||||
and xbs.warehouse_id = #{warehouseId}
|
||||
</if>
|
||||
)
|
||||
)
|
||||
</update>
|
||||
|
||||
<update id="markInboundDifferencesPendingReviewByJobId" parameterType="String">
|
||||
update pd_difference_record
|
||||
set status = '1'
|
||||
where status = '0'
|
||||
and stockpd_detail_id in (
|
||||
select in_or_out_d_id
|
||||
from mydo_job_detail
|
||||
where job_id = #{jobId}
|
||||
and in_or_out_d_id is not null
|
||||
union
|
||||
select in_or_out_d_id
|
||||
from mydo_job_detail_finish
|
||||
where job_id = #{jobId}
|
||||
and in_or_out_d_id is not null
|
||||
)
|
||||
</update>
|
||||
|
||||
<delete id="deletePdDifferenceRecordById" parameterType="Long">
|
||||
delete from pd_difference_record where id = #{id}
|
||||
</delete>
|
||||
@@ -122,4 +204,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
||||
</mapper>
|
||||
|
||||
@@ -8,6 +8,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="stockpdDetailId" column="stockpd_detail_id" />
|
||||
<result property="stockpdId" column="stockpd_id" />
|
||||
<result property="trayCode" column="tray_code" />
|
||||
<result property="stockId" column="stock_id" />
|
||||
<result property="stockDetailId" column="stock_detail_id" />
|
||||
<result property="cargoSpaceId" column="cargo_space_id" />
|
||||
<result property="cargoSpaceName" column="cargo_space_name" />
|
||||
<result property="warehouseId" column="warehouse_id" />
|
||||
<result property="warehouseName" column="warehouse_name" />
|
||||
<result property="productId" column="product_id" />
|
||||
<result property="productName" column="product_name" />
|
||||
<result property="quantity" column="quantity" />
|
||||
@@ -17,12 +23,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectPdStockpdDetailVo">
|
||||
select stockpd_detail_id, stockpd_id, tray_code, product_id, product_name, quantity, allot_num, assign_num, remark from pd_stockpd_detail
|
||||
select stockpd_detail_id, stockpd_id, tray_code, stock_id, stock_detail_id, cargo_space_id, cargo_space_name,
|
||||
warehouse_id, warehouse_name, product_id, product_name, quantity, allot_num, assign_num, remark
|
||||
from pd_stockpd_detail
|
||||
</sql>
|
||||
<sql id="selectPdStockpdDetailFinishVo">
|
||||
select stockpd_detail_id,
|
||||
stockpd_id,
|
||||
tray_code,
|
||||
stock_id,
|
||||
stock_detail_id,
|
||||
cargo_space_id,
|
||||
cargo_space_name,
|
||||
warehouse_id,
|
||||
warehouse_name,
|
||||
product_id,
|
||||
product_name,
|
||||
quantity,
|
||||
@@ -37,6 +51,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<where>
|
||||
<if test="stockpdId != null and stockpdId != ''"> and stockpd_id = #{stockpdId}</if>
|
||||
<if test="trayCode != null and trayCode != ''"> and tray_code = #{trayCode}</if>
|
||||
<if test="stockId != null and stockId != ''"> and stock_id = #{stockId}</if>
|
||||
<if test="stockDetailId != null and stockDetailId != ''"> and stock_detail_id = #{stockDetailId}</if>
|
||||
<if test="cargoSpaceId != null and cargoSpaceId != ''"> and cargo_space_id = #{cargoSpaceId}</if>
|
||||
<if test="warehouseId != null and warehouseId != ''"> and warehouse_id = #{warehouseId}</if>
|
||||
<if test="productId != null and productId != ''"> and product_id = #{productId}</if>
|
||||
<if test="productName != null and productName != ''"> and product_name like concat('%', #{productName}, '%')</if>
|
||||
<if test="quantity != null "> and quantity = #{quantity}</if>
|
||||
@@ -54,6 +72,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<where>
|
||||
<if test="stockpdId != null and stockpdId != ''"> and stockpd_id = #{stockpdId}</if>
|
||||
<if test="trayCode != null and trayCode != ''"> and tray_code = #{trayCode}</if>
|
||||
<if test="stockId != null and stockId != ''"> and stock_id = #{stockId}</if>
|
||||
<if test="stockDetailId != null and stockDetailId != ''"> and stock_detail_id = #{stockDetailId}</if>
|
||||
<if test="cargoSpaceId != null and cargoSpaceId != ''"> and cargo_space_id = #{cargoSpaceId}</if>
|
||||
<if test="warehouseId != null and warehouseId != ''"> and warehouse_id = #{warehouseId}</if>
|
||||
<if test="productId != null and productId != ''"> and product_id = #{productId}</if>
|
||||
<if test="productName != null and productName != ''"> and product_name like concat('%', #{productName}, '%')</if>
|
||||
<if test="quantity != null "> and quantity = #{quantity}</if>
|
||||
@@ -68,6 +90,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="stockpdDetailId != null">stockpd_detail_id,</if>
|
||||
<if test="stockpdId != null and stockpdId != ''">stockpd_id,</if>
|
||||
<if test="trayCode != null">tray_code,</if>
|
||||
<if test="stockId != null">stock_id,</if>
|
||||
<if test="stockDetailId != null">stock_detail_id,</if>
|
||||
<if test="cargoSpaceId != null">cargo_space_id,</if>
|
||||
<if test="cargoSpaceName != null">cargo_space_name,</if>
|
||||
<if test="warehouseId != null">warehouse_id,</if>
|
||||
<if test="warehouseName != null">warehouse_name,</if>
|
||||
<if test="productId != null and productId != ''">product_id,</if>
|
||||
<if test="productName != null">product_name,</if>
|
||||
<if test="quantity != null">quantity,</if>
|
||||
@@ -79,6 +107,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="stockpdDetailId != null">#{stockpdDetailId},</if>
|
||||
<if test="stockpdId != null and stockpdId != ''">#{stockpdId},</if>
|
||||
<if test="trayCode != null">#{trayCode},</if>
|
||||
<if test="stockId != null">#{stockId},</if>
|
||||
<if test="stockDetailId != null">#{stockDetailId},</if>
|
||||
<if test="cargoSpaceId != null">#{cargoSpaceId},</if>
|
||||
<if test="cargoSpaceName != null">#{cargoSpaceName},</if>
|
||||
<if test="warehouseId != null">#{warehouseId},</if>
|
||||
<if test="warehouseName != null">#{warehouseName},</if>
|
||||
<if test="productId != null and productId != ''">#{productId},</if>
|
||||
<if test="productName != null">#{productName},</if>
|
||||
<if test="quantity != null">#{quantity},</if>
|
||||
@@ -93,6 +127,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="stockpdId != null and stockpdId != ''">stockpd_id = #{stockpdId},</if>
|
||||
<if test="trayCode != null">tray_code = #{trayCode},</if>
|
||||
<if test="stockId != null">stock_id = #{stockId},</if>
|
||||
<if test="stockDetailId != null">stock_detail_id = #{stockDetailId},</if>
|
||||
<if test="cargoSpaceId != null">cargo_space_id = #{cargoSpaceId},</if>
|
||||
<if test="cargoSpaceName != null">cargo_space_name = #{cargoSpaceName},</if>
|
||||
<if test="warehouseId != null">warehouse_id = #{warehouseId},</if>
|
||||
<if test="warehouseName != null">warehouse_name = #{warehouseName},</if>
|
||||
<if test="productId != null and productId != ''">product_id = #{productId},</if>
|
||||
<if test="productName != null">product_name = #{productName},</if>
|
||||
<if test="quantity != null">quantity = #{quantity},</if>
|
||||
@@ -113,4 +153,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
#{stockpdDetailId}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|
||||
</mapper>
|
||||
|
||||
@@ -120,12 +120,48 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
from mydo_job j
|
||||
inner join mydo_job_detail jd on j.job_id = jd.job_id
|
||||
where j.in_or_out >= 20
|
||||
and j.in_or_out not in (30, 31)
|
||||
and j.status in ('1', '2', '3')
|
||||
and (#{taskNo} is null or #{taskNo} = '' or j.task_no = #{taskNo})
|
||||
group by j.job_id, j.task_no, j.exit_id, j.create_time, j.status, j.execution_phase
|
||||
order by j.create_time desc
|
||||
</select>
|
||||
|
||||
<select id="inventoryTaskList" parameterType="java.util.Map" resultType="java.util.HashMap">
|
||||
select j.job_id as jobId,
|
||||
j.task_no as taskNo,
|
||||
'inventory' as type,
|
||||
case when j.in_or_out = 31 then '货位盘点' else '物料盘点' end as typeName,
|
||||
'inventory' as typeClass,
|
||||
max(jd.product_id) as materialCode,
|
||||
max(jd.product_name) as materialName,
|
||||
sum(isnull(jd.out_quantity, 0)) as quantity,
|
||||
isnull(j.exit_id, '') as portName,
|
||||
j.tray_code as trayCode,
|
||||
convert(varchar(19), j.create_time, 120) as createTime,
|
||||
j.status as status,
|
||||
j.execution_phase as executionPhase,
|
||||
case
|
||||
when j.execution_phase = '5' then '待扫码盘点'
|
||||
when j.status = '1' then '未下发'
|
||||
when j.status = '2' then '待执行'
|
||||
when j.status = '3' then 'WCS执行中'
|
||||
else '待盘点'
|
||||
end as statusName,
|
||||
case
|
||||
when j.execution_phase = '5' then 'pending'
|
||||
when j.status = '3' then 'processing'
|
||||
else 'pending'
|
||||
end as statusClass
|
||||
from mydo_job j
|
||||
inner join mydo_job_detail jd on j.job_id = jd.job_id
|
||||
where j.in_or_out in (30, 31)
|
||||
and j.status in ('1', '2', '3')
|
||||
and (#{taskNo} is null or #{taskNo} = '' or j.task_no = #{taskNo})
|
||||
group by j.job_id, j.task_no, j.in_or_out, j.exit_id, j.tray_code, j.create_time, j.status, j.execution_phase
|
||||
order by j.create_time desc
|
||||
</select>
|
||||
|
||||
<select id="selectOutboundDetail" parameterType="java.util.Map" resultType="java.util.HashMap">
|
||||
select top 1 j.job_id as jobId,
|
||||
j.task_no as taskNo,
|
||||
@@ -142,6 +178,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
from mydo_job j
|
||||
inner join mydo_job_detail jd on j.job_id = jd.job_id
|
||||
where j.in_or_out >= 20
|
||||
and j.in_or_out not in (30, 31)
|
||||
and j.status in ('1', '2', '3')
|
||||
and (#{taskNo} is null or #{taskNo} = '' or j.task_no = #{taskNo})
|
||||
and (#{barcode} is null or #{barcode} = '' or j.tray_code = #{barcode})
|
||||
@@ -150,6 +187,31 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
order by j.create_time desc
|
||||
</select>
|
||||
|
||||
<select id="selectInventoryDetail" parameterType="java.util.Map" resultType="java.util.HashMap">
|
||||
select top 1 j.job_id as jobId,
|
||||
j.task_no as taskNo,
|
||||
j.tray_code as trayCode,
|
||||
j.cargo_space_id as locationCode,
|
||||
j.cargo_space_name as locationName,
|
||||
j.warehouse_id as warehouseId,
|
||||
j.warehouse_name as warehouseName,
|
||||
j.execution_phase as executionPhase,
|
||||
j.in_or_out as inventoryType,
|
||||
isnull(j.exit_id, '') as portName,
|
||||
sum(isnull(jd.out_quantity, 0)) as quantity,
|
||||
count(1) as materialCount,
|
||||
'' as spec
|
||||
from mydo_job j
|
||||
inner join mydo_job_detail jd on j.job_id = jd.job_id
|
||||
where j.in_or_out in (30, 31)
|
||||
and j.status in ('1', '2', '3')
|
||||
and (#{taskNo} is null or #{taskNo} = '' or j.task_no = #{taskNo})
|
||||
and (#{barcode} is null or #{barcode} = '' or j.tray_code = #{barcode})
|
||||
group by j.job_id, j.task_no, j.tray_code, j.cargo_space_id, j.cargo_space_name,
|
||||
j.warehouse_id, j.warehouse_name, j.execution_phase, j.in_or_out, j.exit_id, j.create_time
|
||||
order by j.create_time desc
|
||||
</select>
|
||||
|
||||
<select id="selectOutboundTrayMaterials" parameterType="java.util.Map" resultType="java.util.HashMap">
|
||||
select jd.job_detail_id as jobDetailId,
|
||||
jd.stock_id as stockId,
|
||||
@@ -165,6 +227,45 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
order by jd.job_detail_id
|
||||
</select>
|
||||
|
||||
<select id="selectInventoryTrayMaterials" parameterType="java.util.Map" resultType="java.util.HashMap">
|
||||
select jd.job_detail_id as jobDetailId,
|
||||
jd.stock_id as stockId,
|
||||
jd.stockin_detail_id as stockDetailId,
|
||||
jd.in_or_out_d_id as stockpdDetailId,
|
||||
jd.product_id as materialCode,
|
||||
jd.product_name as materialName,
|
||||
jd.lot_no as lotNo,
|
||||
jd.stock_quantity as stockQuantity,
|
||||
jd.out_quantity as quantity
|
||||
from mydo_job_detail jd
|
||||
where jd.job_id = #{jobId}
|
||||
order by jd.job_detail_id
|
||||
</select>
|
||||
|
||||
<select id="selectInventoryInboundJobByOutboundJobId" parameterType="String" resultType="java.util.HashMap">
|
||||
select top 1 jobId, taskNo, status
|
||||
from (
|
||||
select j.job_id as jobId,
|
||||
j.task_no as taskNo,
|
||||
j.status as status,
|
||||
j.create_time as createTime
|
||||
from mydo_job j
|
||||
inner join mydo_job_detail jd on j.job_id = jd.job_id
|
||||
where j.in_or_out in (10, 11)
|
||||
and jd.in_or_out_id = #{outboundJobId}
|
||||
union all
|
||||
select jf.job_id as jobId,
|
||||
jf.task_no as taskNo,
|
||||
jf.status as status,
|
||||
jf.create_time as createTime
|
||||
from mydo_job_finish jf
|
||||
inner join mydo_job_detail_finish jdf on jf.job_id = jdf.job_id
|
||||
where jf.in_or_out in (10, 11)
|
||||
and jdf.in_or_out_id = #{outboundJobId}
|
||||
) x
|
||||
order by createTime desc
|
||||
</select>
|
||||
|
||||
<select id="selectResidualTrayMaterials" parameterType="java.util.Map" resultType="java.util.HashMap">
|
||||
select bsd.detail_id as stockDetailId,
|
||||
bsd.stock_id as stockId,
|
||||
@@ -301,6 +402,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
and isnull(quantity, 0) - isnull(out_quantity, 0) >= #{quantity}
|
||||
</update>
|
||||
|
||||
<update id="reserveInventoryStockDetail" parameterType="java.util.Map">
|
||||
update bas_stock_detail
|
||||
set out_quantity = isnull(out_quantity, 0) + #{quantity},
|
||||
job_detail_id = #{jobDetailId},
|
||||
update_time = sysdatetime()
|
||||
where detail_id = #{stockDetailId}
|
||||
and stock_id = #{stockId}
|
||||
and isnull(quantity, 0) - isnull(out_quantity, 0) >= #{quantity}
|
||||
</update>
|
||||
|
||||
<update id="lockEmptyTrayCargoSpace" parameterType="java.util.Map">
|
||||
update bcs
|
||||
set status = '4',
|
||||
@@ -310,4 +421,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
where bs.stock_id = #{stockId}
|
||||
and bs.cargo_space_id = #{cargoSpaceId}
|
||||
</update>
|
||||
|
||||
<update id="lockInventoryOutboundCargoSpace" parameterType="java.util.Map">
|
||||
update bcs
|
||||
set status = '4',
|
||||
tray_code = bs.tray_code
|
||||
from bas_cargo_space bcs
|
||||
inner join bas_stock bs on bcs.cargo_space_id = bs.cargo_space_id
|
||||
where bs.stock_id = #{stockId}
|
||||
and bs.cargo_space_id = #{cargoSpaceId}
|
||||
</update>
|
||||
</mapper>
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.ruoyi.in.jobdetail.mapper.MydoJobDetailMapper;
|
||||
import com.ruoyi.in.stockin.mapper.InStockinMapper;
|
||||
import com.ruoyi.out.stockout.mapper.OutStockoutMapper;
|
||||
import com.ruoyi.out.stockoutdetail.mapper.OutStockoutDetailMapper;
|
||||
import com.ruoyi.pd.diff.mapper.PdDifferenceRecordMapper;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -71,6 +72,9 @@ class MydoJobServiceImplTest {
|
||||
@Mock
|
||||
private WcsClient wcsClient;
|
||||
|
||||
@Mock
|
||||
private PdDifferenceRecordMapper pdDifferenceRecordMapper;
|
||||
|
||||
@InjectMocks
|
||||
private MydoJobServiceImpl service;
|
||||
|
||||
@@ -225,6 +229,26 @@ class MydoJobServiceImplTest {
|
||||
verify(mydoJobMapper, never()).completeJob(any(java.util.HashMap.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void completeInventoryInboundFromWcsMarksDifferencesPendingReviewAfterProcedureSucceeds() {
|
||||
MydoJob job = new MydoJob();
|
||||
job.setJobId("PR001");
|
||||
job.setInOrOut(10L);
|
||||
when(mydoJobMapper.selectMydoJobByJobId("PR001")).thenReturn(job);
|
||||
when(mydoJobMapper.selectStockinIdsByJobId("PR001")).thenReturn(Collections.emptyList());
|
||||
doAnswer(invocation -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
java.util.HashMap<String, Object> map = invocation.getArgument(0);
|
||||
map.put("v_result", "1");
|
||||
return null;
|
||||
}).when(mydoJobMapper).completeJob(any(java.util.HashMap.class));
|
||||
|
||||
AjaxResult result = service.completeInJobFromWcs("PR001");
|
||||
|
||||
assertThat(result.isSuccess()).isTrue();
|
||||
verify(pdDifferenceRecordMapper).markInboundDifferencesPendingReviewByJobId("PR001");
|
||||
}
|
||||
|
||||
@Test
|
||||
void completeOutJobFromWcsRejectsInboundJobType() {
|
||||
MydoJob job = new MydoJob();
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.ruoyi.pd.diff.service.impl;
|
||||
|
||||
import com.ruoyi.pd.diff.domain.PdDifferenceRecord;
|
||||
import com.ruoyi.pd.diff.mapper.PdDifferenceRecordMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class PdDifferenceRecordServiceImplTest {
|
||||
|
||||
@Mock
|
||||
private PdDifferenceRecordMapper pdDifferenceRecordMapper;
|
||||
|
||||
@InjectMocks
|
||||
private PdDifferenceRecordServiceImpl service;
|
||||
|
||||
@Test
|
||||
void approvePendingDifferenceAppliesStockQuantityAndMarksApproved() {
|
||||
PdDifferenceRecord record = new PdDifferenceRecord();
|
||||
record.setId(1L);
|
||||
record.setStatus("1");
|
||||
record.setRecordType("2");
|
||||
record.setStockpdDetailId("PDD001-1");
|
||||
record.setTrayCode("A001");
|
||||
record.setProductId("MAT001");
|
||||
record.setOldQuantity(5L);
|
||||
record.setPdQuantity(4L);
|
||||
when(pdDifferenceRecordMapper.selectPdDifferenceRecordById(1L)).thenReturn(record);
|
||||
when(pdDifferenceRecordMapper.applyApprovedDifference(record)).thenReturn(1);
|
||||
when(pdDifferenceRecordMapper.refreshApprovedDifferenceStockSummary(record)).thenReturn(1);
|
||||
when(pdDifferenceRecordMapper.updatePdDifferenceRecord(record)).thenReturn(1);
|
||||
|
||||
int rows = service.approvePdDifferenceRecord(1L);
|
||||
|
||||
assertThat(rows).isEqualTo(1);
|
||||
verify(pdDifferenceRecordMapper).applyApprovedDifference(record);
|
||||
verify(pdDifferenceRecordMapper).refreshApprovedDifferenceStockSummary(record);
|
||||
ArgumentCaptor<PdDifferenceRecord> updateCaptor = ArgumentCaptor.forClass(PdDifferenceRecord.class);
|
||||
verify(pdDifferenceRecordMapper).updatePdDifferenceRecord(updateCaptor.capture());
|
||||
assertThat(updateCaptor.getValue().getStatus()).isEqualTo("2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectPendingDifferenceLeavesStockUntouchedAndMarksRejected() {
|
||||
PdDifferenceRecord record = new PdDifferenceRecord();
|
||||
record.setId(2L);
|
||||
record.setStatus("1");
|
||||
when(pdDifferenceRecordMapper.selectPdDifferenceRecordById(2L)).thenReturn(record);
|
||||
when(pdDifferenceRecordMapper.updatePdDifferenceRecord(record)).thenReturn(1);
|
||||
|
||||
int rows = service.rejectPdDifferenceRecord(2L);
|
||||
|
||||
assertThat(rows).isEqualTo(1);
|
||||
ArgumentCaptor<PdDifferenceRecord> updateCaptor = ArgumentCaptor.forClass(PdDifferenceRecord.class);
|
||||
verify(pdDifferenceRecordMapper).updatePdDifferenceRecord(updateCaptor.capture());
|
||||
assertThat(updateCaptor.getValue().getStatus()).isEqualTo("3");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package com.ruoyi.pd.stockpd.service.impl;
|
||||
|
||||
import com.ruoyi.bas.id.job.service.JobIdService;
|
||||
import com.ruoyi.bas.id.taskno.service.TaskNoService;
|
||||
import com.ruoyi.bas.stock.domain.BasStockDetail;
|
||||
import com.ruoyi.bas.stock.mapper.BasStockDetailMapper;
|
||||
import com.ruoyi.bas.stationpoint.domain.BasStationPoint;
|
||||
import com.ruoyi.bas.stationpoint.service.IBasStationPointService;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.in.job.domain.MydoJob;
|
||||
import com.ruoyi.in.job.service.IMydoJobService;
|
||||
import com.ruoyi.in.jobdetail.domain.MydoJobDetail;
|
||||
import com.ruoyi.in.jobdetail.service.IMydoJobDetailService;
|
||||
import com.ruoyi.pd.stockpd.domain.PdStockpd;
|
||||
import com.ruoyi.pd.stockpd.mapper.PdStockpdMapper;
|
||||
import com.ruoyi.pd.stockpddetail.domain.PdStockpdDetail;
|
||||
import com.ruoyi.pd.stockpddetail.mapper.PdStockpdDetailMapper;
|
||||
import com.ruoyi.pda.mapper.PdaMapper;
|
||||
import com.ruoyi.system.mapper.SysDeptMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class PdStockpdServiceImplTest {
|
||||
|
||||
@Mock
|
||||
private PdStockpdMapper pdStockpdMapper;
|
||||
|
||||
@Mock
|
||||
private PdStockpdDetailMapper pdStockpdDetailMapper;
|
||||
|
||||
@Mock
|
||||
private SysDeptMapper sysDeptMapper;
|
||||
|
||||
@Mock
|
||||
private JobIdService jobIdService;
|
||||
|
||||
@Mock
|
||||
private TaskNoService taskNoService;
|
||||
|
||||
@Mock
|
||||
private BasStockDetailMapper basStockDetailMapper;
|
||||
|
||||
@Mock
|
||||
private IBasStationPointService basStationPointService;
|
||||
|
||||
@Mock
|
||||
private IMydoJobService mydoJobService;
|
||||
|
||||
@Mock
|
||||
private IMydoJobDetailService mydoJobDetailService;
|
||||
|
||||
@Mock
|
||||
private PdaMapper pdaMapper;
|
||||
|
||||
@InjectMocks
|
||||
private PdStockpdServiceImpl service;
|
||||
|
||||
@Test
|
||||
void autoAssignCreatesInventoryOutboundJobFromStockDetailAndPushesWcs() {
|
||||
PdStockpd stockpd = new PdStockpd();
|
||||
stockpd.setStockpdId("PDD001");
|
||||
stockpd.setPdType("1");
|
||||
stockpd.setStatus("2");
|
||||
stockpd.setWarehouseId("WH01");
|
||||
stockpd.setWarehouseName("一号仓");
|
||||
when(pdStockpdMapper.selectPdStockpdByStockpdId("PDD001")).thenReturn(stockpd);
|
||||
|
||||
PdStockpdDetail detail = new PdStockpdDetail();
|
||||
detail.setStockpdDetailId("PDD001-1");
|
||||
detail.setStockpdId("PDD001");
|
||||
detail.setStockId("KC001");
|
||||
detail.setStockDetailId("SD001");
|
||||
detail.setTrayCode("A001");
|
||||
detail.setProductId("MAT001");
|
||||
detail.setProductName("物料1");
|
||||
detail.setQuantity(5L);
|
||||
when(pdStockpdDetailMapper.selectPdStockpdDetailList(any(PdStockpdDetail.class))).thenReturn(List.of(detail));
|
||||
|
||||
BasStockDetail stockDetail = new BasStockDetail();
|
||||
stockDetail.setDetailId("SD001");
|
||||
stockDetail.setStockId("KC001");
|
||||
stockDetail.setTrayCode("A001");
|
||||
stockDetail.setWarehouseId("WH01");
|
||||
stockDetail.setWarehouseName("一号仓");
|
||||
stockDetail.setCargoSpaceId("CS001");
|
||||
stockDetail.setCargoSpaceName("货位1");
|
||||
stockDetail.setLotNo("LOT1");
|
||||
stockDetail.setProductId("MAT001");
|
||||
stockDetail.setProductName("物料1");
|
||||
stockDetail.setQuantity(new BigDecimal("5"));
|
||||
stockDetail.setAvailableQuantity(new BigDecimal("5"));
|
||||
when(basStockDetailMapper.selectBasStockDetailByDetailId("SD001")).thenReturn(stockDetail);
|
||||
|
||||
BasStationPoint exitPoint = new BasStationPoint();
|
||||
exitPoint.setPointId("OUT01");
|
||||
exitPoint.setWarehouseId("WH01");
|
||||
exitPoint.setRoadwayId("R01");
|
||||
exitPoint.setPointType("2");
|
||||
exitPoint.setStatus("0");
|
||||
when(basStationPointService.selectBasStationPointList(any(BasStationPoint.class))).thenReturn(List.of(exitPoint));
|
||||
when(jobIdService.getId("PC")).thenReturn("PC001");
|
||||
when(taskNoService.getTaskNo("22")).thenReturn("40001");
|
||||
when(mydoJobService.insertMydoJob(any(MydoJob.class))).thenReturn(1);
|
||||
when(mydoJobDetailService.insertMydoJobDetail(any(MydoJobDetail.class))).thenReturn(1);
|
||||
when(pdaMapper.reserveInventoryStockDetail(any(HashMap.class))).thenReturn(1);
|
||||
when(pdaMapper.lockInventoryOutboundCargoSpace(any(HashMap.class))).thenReturn(1);
|
||||
when(mydoJobService.pushOutJobToWcs("PC001")).thenReturn(AjaxResult.success("WCS出库作业下发成功:OK"));
|
||||
when(pdStockpdMapper.updatePdStockpd(any(PdStockpd.class))).thenReturn(1);
|
||||
when(pdStockpdDetailMapper.updatePdStockpdDetail(any(PdStockpdDetail.class))).thenReturn(1);
|
||||
|
||||
AjaxResult result = service.autoAssignPdStockpd("PDD001");
|
||||
|
||||
assertThat(result.isSuccess()).isTrue();
|
||||
ArgumentCaptor<MydoJob> jobCaptor = ArgumentCaptor.forClass(MydoJob.class);
|
||||
verify(mydoJobService).insertMydoJob(jobCaptor.capture());
|
||||
MydoJob job = jobCaptor.getValue();
|
||||
assertThat(job.getJobId()).isEqualTo("PC001");
|
||||
assertThat(job.getTaskNo()).isEqualTo("40001");
|
||||
assertThat(job.getInOrOut()).isEqualTo(30L);
|
||||
assertThat(job.getTrayCode()).isEqualTo("A001");
|
||||
assertThat(job.getWarehouseId()).isEqualTo("WH01");
|
||||
assertThat(job.getCargoSpaceId()).isEqualTo("CS001");
|
||||
assertThat(job.getExitId()).isEqualTo("OUT01");
|
||||
|
||||
ArgumentCaptor<MydoJobDetail> detailCaptor = ArgumentCaptor.forClass(MydoJobDetail.class);
|
||||
verify(mydoJobDetailService).insertMydoJobDetail(detailCaptor.capture());
|
||||
MydoJobDetail jobDetail = detailCaptor.getValue();
|
||||
assertThat(jobDetail.getJobDetailId()).isEqualTo("PC001-1");
|
||||
assertThat(jobDetail.getStockId()).isEqualTo("KC001");
|
||||
assertThat(jobDetail.getStockinDetailId()).isEqualTo("SD001");
|
||||
assertThat(jobDetail.getInOrOutId()).isEqualTo("PDD001");
|
||||
assertThat(jobDetail.getInOrOutDId()).isEqualTo("PDD001-1");
|
||||
assertThat(jobDetail.getOutQuantity()).isEqualByComparingTo("5");
|
||||
|
||||
ArgumentCaptor<HashMap> reserveCaptor = ArgumentCaptor.forClass(HashMap.class);
|
||||
verify(pdaMapper).reserveInventoryStockDetail(reserveCaptor.capture());
|
||||
assertThat(reserveCaptor.getValue())
|
||||
.containsEntry("stockDetailId", "SD001")
|
||||
.containsEntry("stockId", "KC001")
|
||||
.containsEntry("jobDetailId", "PC001-1")
|
||||
.containsEntry("quantity", new BigDecimal("5"));
|
||||
|
||||
verify(mydoJobService).pushOutJobToWcs("PC001");
|
||||
verify(pdStockpdMapper).updatePdStockpd(any(PdStockpd.class));
|
||||
verify(pdStockpdDetailMapper).updatePdStockpdDetail(any(PdStockpdDetail.class));
|
||||
}
|
||||
}
|
||||
@@ -86,10 +86,26 @@ class PdaMapperSqlTest {
|
||||
.contains("j.execution_phase as executionPhase")
|
||||
.contains("when j.execution_phase = '5' then '待扫码确认'")
|
||||
.contains("and j.status in ('1', '2', '3')")
|
||||
.contains("and j.in_or_out not in (30, 31)")
|
||||
.contains("group by j.job_id, j.task_no, j.exit_id, j.create_time, j.status, j.execution_phase");
|
||||
assertThat(detailSql)
|
||||
.contains("j.execution_phase as executionPhase")
|
||||
.contains("and j.status in ('1', '2', '3')");
|
||||
.contains("and j.status in ('1', '2', '3')")
|
||||
.contains("and j.in_or_out not in (30, 31)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void inventoryQueriesUseDedicatedInventoryJobTypes() throws Exception {
|
||||
String xml = Files.readString(resolveMapperXml());
|
||||
String detailSql = section(xml, "<select id=\"selectInventoryDetail\"", "</select>");
|
||||
String materialsSql = section(xml, "<select id=\"selectInventoryTrayMaterials\"", "</select>");
|
||||
|
||||
assertThat(detailSql)
|
||||
.contains("j.in_or_out in (30, 31)")
|
||||
.contains("j.execution_phase as executionPhase");
|
||||
assertThat(materialsSql)
|
||||
.contains("jd.in_or_out_d_id as stockpdDetailId")
|
||||
.contains("jd.stockin_detail_id as stockDetailId");
|
||||
}
|
||||
|
||||
private Path resolveMapperXml() {
|
||||
|
||||
@@ -17,6 +17,9 @@ import com.ruoyi.in.jobdetail.domain.MydoJobDetail;
|
||||
import com.ruoyi.in.jobdetail.service.IMydoJobDetailService;
|
||||
import com.ruoyi.in.stockin.mapper.InStockinMapper;
|
||||
import com.ruoyi.in.sotckindetail.mapper.InStockinDetailMapper;
|
||||
import com.ruoyi.pd.commit.mapper.PdCommitRecordMapper;
|
||||
import com.ruoyi.pd.diff.mapper.PdDifferenceRecordMapper;
|
||||
import com.ruoyi.pd.stockpddetail.mapper.PdStockpdDetailMapper;
|
||||
import com.ruoyi.pda.domain.AddInJobRequest;
|
||||
import com.ruoyi.pda.domain.EmptyTrayOutboundRequest;
|
||||
import com.ruoyi.pda.mapper.PdaMapper;
|
||||
@@ -79,6 +82,15 @@ class PdaServiceImplTest {
|
||||
@Mock
|
||||
private TaskNoService taskNoService;
|
||||
|
||||
@Mock
|
||||
private PdCommitRecordMapper pdCommitRecordMapper;
|
||||
|
||||
@Mock
|
||||
private PdDifferenceRecordMapper pdDifferenceRecordMapper;
|
||||
|
||||
@Mock
|
||||
private PdStockpdDetailMapper pdStockpdDetailMapper;
|
||||
|
||||
@InjectMocks
|
||||
private PdaServiceImpl service;
|
||||
|
||||
@@ -407,6 +419,106 @@ class PdaServiceImplTest {
|
||||
verify(mydoJobService).completeJob("CK002", "2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void confirmInventoryRecordsDifferenceCompletesOutboundAndCreatesReturnInboundWithOriginalQuantity() {
|
||||
HashMap<String, Object> inventoryDetail = new HashMap<>();
|
||||
inventoryDetail.put("jobId", "PC001");
|
||||
inventoryDetail.put("taskNo", "40001");
|
||||
inventoryDetail.put("trayCode", "A001");
|
||||
inventoryDetail.put("warehouseId", "WH01");
|
||||
inventoryDetail.put("warehouseName", "一号仓");
|
||||
inventoryDetail.put("quantity", "5");
|
||||
inventoryDetail.put("executionPhase", "5");
|
||||
when(pdaMapper.selectInventoryDetail(any(HashMap.class))).thenReturn(inventoryDetail);
|
||||
|
||||
HashMap<String, Object> material = new HashMap<>();
|
||||
material.put("jobDetailId", "PC001-1");
|
||||
material.put("stockId", "KC001");
|
||||
material.put("stockDetailId", "SD001");
|
||||
material.put("stockpdDetailId", "PDD001-1");
|
||||
material.put("materialCode", "MAT001");
|
||||
material.put("materialName", "物料1");
|
||||
material.put("lotNo", "LOT1");
|
||||
material.put("stockQuantity", "5");
|
||||
material.put("quantity", "5");
|
||||
when(pdaMapper.selectInventoryTrayMaterials(any(HashMap.class))).thenReturn(List.of(material));
|
||||
when(pdaMapper.selectInventoryInboundJobByOutboundJobId("PC001")).thenReturn(null);
|
||||
|
||||
MydoJob outboundJob = new MydoJob();
|
||||
outboundJob.setJobId("PC001");
|
||||
outboundJob.setTaskNo("40001");
|
||||
outboundJob.setInOrOut(30L);
|
||||
outboundJob.setTrayCode("A001");
|
||||
outboundJob.setWarehouseId("WH01");
|
||||
outboundJob.setWarehouseName("一号仓");
|
||||
outboundJob.setExitId("OUT01");
|
||||
when(mydoJobService.selectMydoJobByJobId("PC001")).thenReturn(outboundJob);
|
||||
when(mydoJobService.completeJob("PC001", "2")).thenReturn(AjaxResult.success());
|
||||
|
||||
BasStationPoint exitPoint = new BasStationPoint();
|
||||
exitPoint.setPointId("OUT01");
|
||||
exitPoint.setRoadwayId("R02");
|
||||
when(basStationPointService.selectBasStationPointByPointId("OUT01")).thenReturn(exitPoint);
|
||||
when(jobIdService.getId("PR")).thenReturn("PR001");
|
||||
when(taskNoService.getTaskNo("2")).thenReturn("30001");
|
||||
when(mydoJobService.insertMydoJob(any(MydoJob.class))).thenReturn(1);
|
||||
when(mydoJobDetailService.insertMydoJobDetail(any(MydoJobDetail.class))).thenReturn(1);
|
||||
when(mydoJobService.updateMydoJob(any(MydoJob.class))).thenReturn(1);
|
||||
when(pdCommitRecordMapper.insertPdCommitRecord(any())).thenReturn(1);
|
||||
when(pdDifferenceRecordMapper.insertPdDifferenceRecord(any())).thenReturn(1);
|
||||
when(pdStockpdDetailMapper.updatePdStockpdDetail(any())).thenReturn(1);
|
||||
when(wcsClient.sendPutawayTask(any(MydoJob.class))).thenReturn(ApiResponse.ok("OK"));
|
||||
|
||||
HashMap<String, Object> requestMaterial = new HashMap<>();
|
||||
requestMaterial.put("jobDetailId", "PC001-1");
|
||||
requestMaterial.put("stockDetailId", "SD001");
|
||||
requestMaterial.put("stockpdDetailId", "PDD001-1");
|
||||
requestMaterial.put("quantity", "4");
|
||||
HashMap<String, Object> data = new HashMap<>();
|
||||
data.put("taskNo", "40001");
|
||||
data.put("barcode", "A001");
|
||||
data.put("materials", List.of(requestMaterial));
|
||||
|
||||
service.confirmInventory(data);
|
||||
|
||||
verify(mydoJobService).completeJob("PC001", "2");
|
||||
|
||||
ArgumentCaptor<com.ruoyi.pd.commit.domain.PdCommitRecord> commitCaptor =
|
||||
ArgumentCaptor.forClass(com.ruoyi.pd.commit.domain.PdCommitRecord.class);
|
||||
verify(pdCommitRecordMapper).insertPdCommitRecord(commitCaptor.capture());
|
||||
assertThat(commitCaptor.getValue().getStockpdDetailId()).isEqualTo("PDD001-1");
|
||||
assertThat(commitCaptor.getValue().getOldQuantity()).isEqualTo(5L);
|
||||
assertThat(commitCaptor.getValue().getPdQuantity()).isEqualTo(4L);
|
||||
|
||||
ArgumentCaptor<com.ruoyi.pd.diff.domain.PdDifferenceRecord> diffCaptor =
|
||||
ArgumentCaptor.forClass(com.ruoyi.pd.diff.domain.PdDifferenceRecord.class);
|
||||
verify(pdDifferenceRecordMapper).insertPdDifferenceRecord(diffCaptor.capture());
|
||||
assertThat(diffCaptor.getValue().getStockpdDetailId()).isEqualTo("PDD001-1");
|
||||
assertThat(diffCaptor.getValue().getStatus()).isEqualTo("0");
|
||||
assertThat(diffCaptor.getValue().getRecordType()).isEqualTo("2");
|
||||
assertThat(diffCaptor.getValue().getOldQuantity()).isEqualTo(5L);
|
||||
assertThat(diffCaptor.getValue().getPdQuantity()).isEqualTo(4L);
|
||||
|
||||
ArgumentCaptor<MydoJob> jobCaptor = ArgumentCaptor.forClass(MydoJob.class);
|
||||
verify(mydoJobService).insertMydoJob(jobCaptor.capture());
|
||||
MydoJob inboundJob = jobCaptor.getValue();
|
||||
assertThat(inboundJob.getJobId()).isEqualTo("PR001");
|
||||
assertThat(inboundJob.getTaskNo()).isEqualTo("30001");
|
||||
assertThat(inboundJob.getInOrOut()).isEqualTo(10L);
|
||||
assertThat(inboundJob.getEntranceId()).isEqualTo("OUT01");
|
||||
assertThat(inboundJob.getRoadwayId()).isEqualTo("R02");
|
||||
verify(wcsClient).sendPutawayTask(inboundJob);
|
||||
|
||||
ArgumentCaptor<MydoJobDetail> inboundDetailCaptor = ArgumentCaptor.forClass(MydoJobDetail.class);
|
||||
verify(mydoJobDetailService).insertMydoJobDetail(inboundDetailCaptor.capture());
|
||||
MydoJobDetail inboundDetail = inboundDetailCaptor.getValue();
|
||||
assertThat(inboundDetail.getJobId()).isEqualTo("PR001");
|
||||
assertThat(inboundDetail.getInOrOutId()).isEqualTo("PC001");
|
||||
assertThat(inboundDetail.getInOrOutDId()).isEqualTo("PDD001-1");
|
||||
assertThat(inboundDetail.getStockinDetailId()).isEqualTo("SD001");
|
||||
assertThat(inboundDetail.getInQuantity()).isEqualByComparingTo("5");
|
||||
}
|
||||
|
||||
private void stubInboundStationAndRoadway() {
|
||||
BasStationPoint point = new BasStationPoint();
|
||||
point.setPointId("IN01");
|
||||
|
||||
Reference in New Issue
Block a user