Browse Source
feat(check): 新增盘点模式管理及自动盘盈盘亏处理功能
feat(check): 新增盘点模式管理及自动盘盈盘亏处理功能
- 添加盘点模式开关接口,支持获取和更新系统盘点模式状态 - 实现自动盘盈盘亏处理服务,支持批量处理盘点差异结果 - 创建盘点调整相关实体类,包括调整项、标签明细、请求参数和结果实体 - 集成事务处理机制,自动生成盘亏(PK)和盘盈(PY)事务单据 - 提供盘盈盘亏事务记录查询接口,支持查看处理明细和子明细 - 完善库存更新逻辑,处理完成后自动更新标签数量和库存状态master
12 changed files with 1605 additions and 0 deletions
-
131src/main/java/com/gaotao/common/utils/CountModeChecker.java
-
84src/main/java/com/gaotao/modules/check/controller/PhysicalInventoryController.java
-
102src/main/java/com/gaotao/modules/check/entity/CountAdjustmentItem.java
-
119src/main/java/com/gaotao/modules/check/entity/CountAdjustmentLabelItem.java
-
39src/main/java/com/gaotao/modules/check/entity/CountAdjustmentRequest.java
-
75src/main/java/com/gaotao/modules/check/entity/CountAdjustmentResult.java
-
116src/main/java/com/gaotao/modules/check/entity/CountAdjustmentTransData.java
-
85src/main/java/com/gaotao/modules/check/entity/CountAdjustmentTransSubData.java
-
116src/main/java/com/gaotao/modules/check/mapper/CountAdjustmentMapper.java
-
84src/main/java/com/gaotao/modules/check/service/CountAdjustmentService.java
-
502src/main/java/com/gaotao/modules/check/service/impl/CountAdjustmentServiceImpl.java
-
152src/main/resources/mapper/check/CountAdjustmentMapper.xml
@ -0,0 +1,131 @@ |
|||
package com.gaotao.common.utils; |
|||
|
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.jdbc.core.JdbcTemplate; |
|||
import org.springframework.stereotype.Component; |
|||
import org.springframework.util.StringUtils; |
|||
|
|||
/** |
|||
* 盘点模式检查工具类 - rqrq |
|||
* |
|||
* <p>用于快速判断当前是否处于盘点模式,如果是盘点模式则抛出异常阻止其他业务操作</p> |
|||
* |
|||
* <p><b>使用方式:</b></p> |
|||
* <pre> |
|||
* // 1. 注入工具类 |
|||
* @Autowired |
|||
* private CountModeChecker countModeChecker; |
|||
* |
|||
* // 2. 在业务方法开头调用检查 |
|||
* public void yourBusinessMethod(String site) { |
|||
* countModeChecker.checkNotInCountMode(site); // 如果是盘点模式会抛出异常 |
|||
* // ... 业务逻辑 |
|||
* } |
|||
* |
|||
* // 3. 也可以只获取状态不抛异常 |
|||
* if (countModeChecker.isInCountMode(site)) { |
|||
* // 处理盘点模式的情况 |
|||
* } |
|||
* </pre> |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/12/23 |
|||
*/ |
|||
@Component |
|||
public class CountModeChecker { |
|||
|
|||
@Autowired |
|||
private JdbcTemplate jdbcTemplate; |
|||
|
|||
/** |
|||
* 检查当前是否在盘点模式,如果是则抛出异常 - rqrq |
|||
* |
|||
* <p>业务方法开头调用此方法,可以快速阻止盘点模式下的其他操作</p> |
|||
* |
|||
* @param site 工厂编码 |
|||
* @throws RuntimeException 如果当前处于盘点模式 |
|||
* @author rqrq |
|||
*/ |
|||
public void checkNotInCountMode(String site) { |
|||
if (isInCountMode(site)) { |
|||
throw new RuntimeException("当前处于盘点模式,无法进行此操作,请先关闭盘点模式"); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 检查当前是否在盘点模式,如果是则抛出自定义异常信息 - rqrq |
|||
* |
|||
* @param site 工厂编码 |
|||
* @param customMessage 自定义错误信息 |
|||
* @throws RuntimeException 如果当前处于盘点模式 |
|||
* @author rqrq |
|||
*/ |
|||
public void checkNotInCountMode(String site, String customMessage) { |
|||
if (isInCountMode(site)) { |
|||
throw new RuntimeException(customMessage); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 判断当前是否处于盘点模式 - rqrq |
|||
* |
|||
* @param site 工厂编码 |
|||
* @return true=盘点模式 false=非盘点模式 |
|||
* @author rqrq |
|||
*/ |
|||
public boolean isInCountMode(String site) { |
|||
if (!StringUtils.hasText(site)) { |
|||
return false; |
|||
} |
|||
|
|||
String countModeValue = getCountModeValue(site); |
|||
return "Y".equals(countModeValue); |
|||
} |
|||
|
|||
/** |
|||
* 获取盘点模式参数值 - rqrq |
|||
* |
|||
* @param site 工厂编码 |
|||
* @return Y=盘点模式 N=非盘点模式 null=未配置 |
|||
* @author rqrq |
|||
*/ |
|||
public String getCountModeValue(String site) { |
|||
try { |
|||
String sql = "SELECT parameter_value FROM wms_sys_parameter WHERE site = ? AND parameter_key = 'IF_COUNT'"; |
|||
return jdbcTemplate.queryForObject(sql, String.class, site); |
|||
} catch (Exception e) { |
|||
// 查询失败或无数据时返回N(默认非盘点模式) |
|||
return "N"; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 检查当前必须在盘点模式,如果不是则抛出异常 - rqrq |
|||
* |
|||
* <p>盘点相关业务方法开头调用此方法,确保只有盘点模式下才能执行</p> |
|||
* |
|||
* @param site 工厂编码 |
|||
* @throws RuntimeException 如果当前不在盘点模式 |
|||
* @author rqrq |
|||
*/ |
|||
public void checkMustInCountMode(String site) { |
|||
if (!isInCountMode(site)) { |
|||
throw new RuntimeException("当前不在盘点模式,无法进行此操作,请先开启盘点模式"); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 检查当前必须在盘点模式,如果不是则抛出自定义异常信息 - rqrq |
|||
* |
|||
* @param site 工厂编码 |
|||
* @param customMessage 自定义错误信息 |
|||
* @throws RuntimeException 如果当前不在盘点模式 |
|||
* @author rqrq |
|||
*/ |
|||
public void checkMustInCountMode(String site, String customMessage) { |
|||
if (!isInCountMode(site)) { |
|||
throw new RuntimeException(customMessage); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,102 @@ |
|||
package com.gaotao.modules.check.entity; |
|||
|
|||
import lombok.Data; |
|||
import org.apache.ibatis.type.Alias; |
|||
|
|||
import java.math.BigDecimal; |
|||
import java.util.Date; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 盘点调整明细项实体类 - 按ERP维度汇总后的盘盈盘亏数据 - rqrq |
|||
* |
|||
* <p><b>用途:</b>用于盘盈盘亏处理时按维度汇总的库存数据</p> |
|||
* |
|||
* <p><b>汇总维度:</b></p> |
|||
* <ul> |
|||
* <li>site - 工厂编码</li> |
|||
* <li>warehouseId - 仓库ID</li> |
|||
* <li>locationId - 库位ID</li> |
|||
* <li>partNo - 物料号</li> |
|||
* <li>batchNo - 批号</li> |
|||
* <li>wdr - WDR</li> |
|||
* <li>expiredDate - 过期日期</li> |
|||
* <li>engChgLevel - 工程变更级别</li> |
|||
* </ul> |
|||
* |
|||
* <p><b>业务逻辑:</b></p> |
|||
* <pre> |
|||
* // 根据diffQty判断盘盈盘亏 |
|||
* if (diffQty > 0) { |
|||
* // 盘盈:库存增加 |
|||
* } else if (diffQty < 0) { |
|||
* // 盘亏:库存减少 |
|||
* } |
|||
* </pre> |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/12/23 |
|||
*/ |
|||
@Data |
|||
@Alias("CountAdjustmentItem") |
|||
public class CountAdjustmentItem { |
|||
|
|||
// ==================== 维度字段 ==================== |
|||
|
|||
/** |
|||
* 工厂编码 |
|||
*/ |
|||
private String site; |
|||
|
|||
/** |
|||
* 仓库ID |
|||
*/ |
|||
private String warehouseId; |
|||
|
|||
/** |
|||
* 库位ID |
|||
*/ |
|||
private String locationId; |
|||
|
|||
/** |
|||
* 物料号 |
|||
*/ |
|||
private String partNo; |
|||
|
|||
/** |
|||
* 批号 |
|||
*/ |
|||
private String batchNo; |
|||
|
|||
/** |
|||
* WDR(物料追溯号) |
|||
*/ |
|||
private String wdr; |
|||
|
|||
/** |
|||
* 过期日期 |
|||
*/ |
|||
private Date expiredDate; |
|||
|
|||
/** |
|||
* 工程变更级别 |
|||
*/ |
|||
private String engChgLevel; |
|||
|
|||
// ==================== 数量字段 ==================== |
|||
|
|||
/** |
|||
* 汇总后的差异数量 |
|||
* <p>正数=盘盈,负数=盘亏</p> |
|||
*/ |
|||
private BigDecimal diffQty; |
|||
|
|||
// ==================== 关联明细 ==================== |
|||
|
|||
/** |
|||
* 该维度下的所有标签明细列表 |
|||
* <p>用于生成trans_detail_sub</p> |
|||
*/ |
|||
private List<CountAdjustmentLabelItem> labelItems; |
|||
} |
|||
|
|||
@ -0,0 +1,119 @@ |
|||
package com.gaotao.modules.check.entity; |
|||
|
|||
import lombok.Data; |
|||
import org.apache.ibatis.type.Alias; |
|||
|
|||
import java.math.BigDecimal; |
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* 盘点调整标签明细实体类 - 标签级别的盘盈盘亏数据 - rqrq |
|||
* |
|||
* <p><b>用途:</b>用于盘盈盘亏处理时记录每个标签的调整信息</p> |
|||
* |
|||
* <p><b>数据来源:</b></p> |
|||
* <ul> |
|||
* <li>count_result表:盘点结果信息</li> |
|||
* <li>handling_unit表:标签详细信息</li> |
|||
* </ul> |
|||
* |
|||
* <p><b>业务逻辑:</b></p> |
|||
* <pre> |
|||
* // 1. 用于生成trans_detail_sub记录 |
|||
* // 2. 用于更新handling_unit.qty |
|||
* if (newQty <= 0) { |
|||
* // 设置in_stock_flag = 'N' |
|||
* } |
|||
* </pre> |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/12/23 |
|||
*/ |
|||
@Data |
|||
@Alias("CountAdjustmentLabelItem") |
|||
public class CountAdjustmentLabelItem { |
|||
|
|||
// ==================== 盘点结果字段 ==================== |
|||
|
|||
/** |
|||
* 盘点结果ID |
|||
*/ |
|||
private Long countResultId; |
|||
|
|||
/** |
|||
* 盘点单号 |
|||
*/ |
|||
private String countNo; |
|||
|
|||
/** |
|||
* 盘点结果类型 |
|||
* <p>QTY_DIFF=数量差异,MISSING=缺失</p> |
|||
*/ |
|||
private String countResult; |
|||
|
|||
/** |
|||
* 差异数量 |
|||
* <p>正数=盘盈,负数=盘亏</p> |
|||
*/ |
|||
private BigDecimal diffQty; |
|||
|
|||
// ==================== 标签基本信息 ==================== |
|||
|
|||
/** |
|||
* 工厂编码 |
|||
*/ |
|||
private String site; |
|||
|
|||
/** |
|||
* 标签号(handling_unit.unit_id) |
|||
*/ |
|||
private String unitId; |
|||
|
|||
/** |
|||
* 栈板号 |
|||
*/ |
|||
private String palletId; |
|||
|
|||
// ==================== 库存维度字段 ==================== |
|||
|
|||
/** |
|||
* 物料号 |
|||
*/ |
|||
private String partNo; |
|||
|
|||
/** |
|||
* 标签当前数量 |
|||
*/ |
|||
private BigDecimal qty; |
|||
|
|||
/** |
|||
* 批号 |
|||
*/ |
|||
private String batchNo; |
|||
|
|||
/** |
|||
* 库位ID |
|||
*/ |
|||
private String locationId; |
|||
|
|||
/** |
|||
* 仓库ID |
|||
*/ |
|||
private String warehouseId; |
|||
|
|||
/** |
|||
* WDR(物料追溯号) |
|||
*/ |
|||
private String wdr; |
|||
|
|||
/** |
|||
* 过期日期 |
|||
*/ |
|||
private Date expiredDate; |
|||
|
|||
/** |
|||
* 工程变更级别 |
|||
*/ |
|||
private String engChgLevel; |
|||
} |
|||
|
|||
@ -0,0 +1,39 @@ |
|||
package com.gaotao.modules.check.entity; |
|||
|
|||
import lombok.Data; |
|||
import org.apache.ibatis.type.Alias; |
|||
|
|||
/** |
|||
* 盘点调整请求参数实体类 - rqrq |
|||
* |
|||
* <p><b>用途:</b>用于自动处理盈亏功能的请求参数传递</p> |
|||
* |
|||
* <p><b>使用场景:</b></p> |
|||
* <ul> |
|||
* <li>Controller接收前端请求参数</li> |
|||
* <li>Service层方法入参</li> |
|||
* </ul> |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/12/23 |
|||
*/ |
|||
@Data |
|||
@Alias("CountAdjustmentRequest") |
|||
public class CountAdjustmentRequest { |
|||
|
|||
/** |
|||
* 工厂编码(必填) |
|||
*/ |
|||
private String site; |
|||
|
|||
/** |
|||
* 盘点单号(必填) |
|||
*/ |
|||
private String countNo; |
|||
|
|||
/** |
|||
* 操作用户名(必填) |
|||
*/ |
|||
private String username; |
|||
} |
|||
|
|||
@ -0,0 +1,75 @@ |
|||
package com.gaotao.modules.check.entity; |
|||
|
|||
import lombok.Data; |
|||
import org.apache.ibatis.type.Alias; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 盘点调整处理结果实体类 - rqrq |
|||
* |
|||
* <p><b>用途:</b>用于返回自动处理盈亏的执行结果</p> |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/12/23 |
|||
*/ |
|||
@Data |
|||
@Alias("CountAdjustmentResult") |
|||
public class CountAdjustmentResult { |
|||
|
|||
/** |
|||
* 处理是否成功 |
|||
*/ |
|||
private boolean success; |
|||
|
|||
/** |
|||
* 结果消息 |
|||
*/ |
|||
private String message; |
|||
|
|||
/** |
|||
* 生成的盘亏单据号列表 |
|||
*/ |
|||
private List<String> lossTransNoList; |
|||
|
|||
/** |
|||
* 生成的盘盈单据号列表 |
|||
*/ |
|||
private List<String> profitTransNoList; |
|||
|
|||
/** |
|||
* 处理的盘亏记录数 |
|||
*/ |
|||
private int lossCount; |
|||
|
|||
/** |
|||
* 处理的盘盈记录数 |
|||
*/ |
|||
private int profitCount; |
|||
|
|||
/** |
|||
* 处理的标签数 |
|||
*/ |
|||
private int labelCount; |
|||
|
|||
/** |
|||
* 创建成功结果 - rqrq |
|||
*/ |
|||
public static CountAdjustmentResult success(String message) { |
|||
CountAdjustmentResult result = new CountAdjustmentResult(); |
|||
result.setSuccess(true); |
|||
result.setMessage(message); |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 创建失败结果 - rqrq |
|||
*/ |
|||
public static CountAdjustmentResult fail(String message) { |
|||
CountAdjustmentResult result = new CountAdjustmentResult(); |
|||
result.setSuccess(false); |
|||
result.setMessage(message); |
|||
return result; |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,116 @@ |
|||
package com.gaotao.modules.check.entity; |
|||
|
|||
import lombok.Data; |
|||
import org.apache.ibatis.type.Alias; |
|||
|
|||
import java.math.BigDecimal; |
|||
import java.util.Date; |
|||
|
|||
/** |
|||
* 盘盈盘亏事务明细实体类 - 用于查询展示 - rqrq |
|||
* |
|||
* <p><b>用途:</b>用于前端盘盈盘亏记录页签左侧列表展示</p> |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/12/23 |
|||
*/ |
|||
@Data |
|||
@Alias("CountAdjustmentTransData") |
|||
public class CountAdjustmentTransData { |
|||
|
|||
// ==================== trans_header字段 ==================== |
|||
|
|||
/** |
|||
* 工厂编码 |
|||
*/ |
|||
private String site; |
|||
|
|||
/** |
|||
* 事务号 |
|||
*/ |
|||
private String transNo; |
|||
|
|||
/** |
|||
* 事务日期 |
|||
*/ |
|||
private Date transDate; |
|||
|
|||
/** |
|||
* 事务类型 |
|||
* <p>PK=盘亏,PY=盘盈</p> |
|||
*/ |
|||
private String transTypeDb; |
|||
|
|||
/** |
|||
* 事务类型描述 |
|||
*/ |
|||
private String transTypeDesc; |
|||
|
|||
/** |
|||
* 仓库ID |
|||
*/ |
|||
private String warehouseId; |
|||
|
|||
/** |
|||
* 关联盘点单号(存储在order_ref1) |
|||
*/ |
|||
private String orderRef1; |
|||
|
|||
/** |
|||
* 备注 |
|||
*/ |
|||
private String remark; |
|||
|
|||
/** |
|||
* 操作用户 |
|||
*/ |
|||
private String userName; |
|||
|
|||
// ==================== trans_detail字段 ==================== |
|||
|
|||
/** |
|||
* 行号 |
|||
*/ |
|||
private Double itemNo; |
|||
|
|||
/** |
|||
* 物料号 |
|||
*/ |
|||
private String partNo; |
|||
|
|||
/** |
|||
* 事务数量 |
|||
*/ |
|||
private BigDecimal transQty; |
|||
|
|||
/** |
|||
* 批号 |
|||
*/ |
|||
private String batchNo; |
|||
|
|||
/** |
|||
* 库位ID |
|||
*/ |
|||
private String locationId; |
|||
|
|||
/** |
|||
* 方向(IN=入库,OUT=出库) |
|||
*/ |
|||
private String direction; |
|||
|
|||
/** |
|||
* 方向描述 |
|||
*/ |
|||
private String directionDesc; |
|||
|
|||
/** |
|||
* WDR号 |
|||
*/ |
|||
private String wdrNo; |
|||
|
|||
/** |
|||
* 工程变更级别 |
|||
*/ |
|||
private String engChgLevel; |
|||
} |
|||
|
|||
@ -0,0 +1,85 @@ |
|||
package com.gaotao.modules.check.entity; |
|||
|
|||
import lombok.Data; |
|||
import org.apache.ibatis.type.Alias; |
|||
|
|||
import java.math.BigDecimal; |
|||
|
|||
/** |
|||
* 盘盈盘亏事务子明细实体类 - 用于查询展示 - rqrq |
|||
* |
|||
* <p><b>用途:</b>用于前端盘盈盘亏记录页签右侧列表展示</p> |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/12/23 |
|||
*/ |
|||
@Data |
|||
@Alias("CountAdjustmentTransSubData") |
|||
public class CountAdjustmentTransSubData { |
|||
|
|||
/** |
|||
* 工厂编码 |
|||
*/ |
|||
private String site; |
|||
|
|||
/** |
|||
* 事务号 |
|||
*/ |
|||
private String transNo; |
|||
|
|||
/** |
|||
* 行号 |
|||
*/ |
|||
private Double itemNo; |
|||
|
|||
/** |
|||
* 子行号 |
|||
*/ |
|||
private String subNo; |
|||
|
|||
/** |
|||
* 子数量 |
|||
*/ |
|||
private Double subQty; |
|||
|
|||
/** |
|||
* 方向(IN=入库,OUT=出库) |
|||
*/ |
|||
private String direction; |
|||
|
|||
/** |
|||
* 方向描述 |
|||
*/ |
|||
private String directionDesc; |
|||
|
|||
/** |
|||
* 标签号 |
|||
*/ |
|||
private String handlingUnitId; |
|||
|
|||
/** |
|||
* 物料号 |
|||
*/ |
|||
private String partNo; |
|||
|
|||
/** |
|||
* 批号 |
|||
*/ |
|||
private String batchNo; |
|||
|
|||
/** |
|||
* 库位ID |
|||
*/ |
|||
private String locationId; |
|||
|
|||
/** |
|||
* 工程变更级别 |
|||
*/ |
|||
private String engChgLevel; |
|||
|
|||
/** |
|||
* 栈板号(存储在order_ref1) |
|||
*/ |
|||
private String palletId; |
|||
} |
|||
|
|||
@ -0,0 +1,116 @@ |
|||
package com.gaotao.modules.check.mapper; |
|||
|
|||
import com.gaotao.modules.check.entity.CountAdjustmentLabelItem; |
|||
import com.gaotao.modules.trans.entity.TransDetail; |
|||
import com.gaotao.modules.trans.entity.TransDetailSub; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
import org.apache.ibatis.annotations.Param; |
|||
|
|||
|
|||
import com.gaotao.modules.check.entity.CountAdjustmentTransData; |
|||
import com.gaotao.modules.check.entity.CountAdjustmentTransSubData; |
|||
import java.math.BigDecimal; |
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 盘点调整Mapper接口 - rqrq |
|||
* |
|||
* <p><b>功能:</b>提供盘盈盘亏处理相关的数据库操作</p> |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/12/23 |
|||
*/ |
|||
@Mapper |
|||
public interface CountAdjustmentMapper { |
|||
|
|||
/** |
|||
* 统计需要系统处理的异常结果数量 - rqrq |
|||
* |
|||
* @param site 工厂编码 |
|||
* @param countNo 盘点单号 |
|||
* @return int 记录数 |
|||
* @author rqrq |
|||
*/ |
|||
int countSystemHandleRecords(@Param("site") String site, @Param("countNo") String countNo); |
|||
|
|||
/** |
|||
* 查询待系统处理的标签明细(排除SURPLUS类型)- rqrq |
|||
* |
|||
* <p>关联handling_unit获取标签详细信息</p> |
|||
* |
|||
* @param site 工厂编码 |
|||
* @param countNo 盘点单号 |
|||
* @return List<CountAdjustmentLabelItem> 标签明细列表 |
|||
* @author rqrq |
|||
*/ |
|||
List<CountAdjustmentLabelItem> querySystemHandleLabels(@Param("site") String site, @Param("countNo") String countNo); |
|||
|
|||
/** |
|||
* 插入事务明细 - rqrq |
|||
* |
|||
* @param detail 事务明细 |
|||
* @return int 影响行数 |
|||
* @author rqrq |
|||
*/ |
|||
int insertTransDetail(TransDetail detail); |
|||
|
|||
/** |
|||
* 插入事务子明细 - rqrq |
|||
* |
|||
* @param sub 事务子明细 |
|||
* @return int 影响行数 |
|||
* @author rqrq |
|||
*/ |
|||
int insertTransDetailSub(TransDetailSub sub); |
|||
|
|||
/** |
|||
* 更新标签数量 - rqrq |
|||
* |
|||
* @param site 工厂编码 |
|||
* @param unitId 标签号 |
|||
* @param qty 新数量 |
|||
* @param inStockFlag 在库标记 |
|||
* @param username 操作用户 |
|||
* @return int 影响行数 |
|||
* @author rqrq |
|||
*/ |
|||
int updateHandlingUnitQty(@Param("site") String site, |
|||
@Param("unitId") String unitId, |
|||
@Param("qty") BigDecimal qty, |
|||
@Param("inStockFlag") String inStockFlag, |
|||
@Param("username") String username); |
|||
|
|||
/** |
|||
* 更新盘点结果处理标记 - rqrq |
|||
* |
|||
* @param countResultId 盘点结果ID |
|||
* @param username 操作用户 |
|||
* @return int 影响行数 |
|||
* @author rqrq |
|||
*/ |
|||
int updateCountResultHandleFlag(@Param("countResultId") Long countResultId, |
|||
@Param("username") String username); |
|||
|
|||
// ==================== 盘盈盘亏记录查询 ==================== - rqrq |
|||
|
|||
/** |
|||
* 查询盘盈盘亏事务头和明细 - rqrq |
|||
* |
|||
* @param site 工厂编码 |
|||
* @param countNo 盘点单号(存储在order_ref1中) |
|||
* @return List<CountAdjustmentTransData> 事务列表 |
|||
* @author rqrq |
|||
*/ |
|||
List<CountAdjustmentTransData> queryAdjustmentTransList(@Param("site") String site, @Param("countNo") String countNo); |
|||
|
|||
/** |
|||
* 查询事务子明细 - rqrq |
|||
* |
|||
* @param site 工厂编码 |
|||
* @param transNo 事务号 |
|||
* @return List<CountAdjustmentTransSubData> 子明细列表 |
|||
* @author rqrq |
|||
*/ |
|||
List<CountAdjustmentTransSubData> queryAdjustmentTransSubList(@Param("site") String site, @Param("transNo") String transNo); |
|||
} |
|||
|
|||
@ -0,0 +1,84 @@ |
|||
package com.gaotao.modules.check.service; |
|||
|
|||
import com.gaotao.modules.check.entity.CountAdjustmentRequest; |
|||
import com.gaotao.modules.check.entity.CountAdjustmentResult; |
|||
import com.gaotao.modules.check.entity.CountAdjustmentTransData; |
|||
import com.gaotao.modules.check.entity.CountAdjustmentTransSubData; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 盘点调整服务接口 - 用于自动处理盘盈盘亏 - rqrq |
|||
* |
|||
* <p><b>功能说明:</b></p> |
|||
* <ul> |
|||
* <li>自动处理系统处理方式的盘点异常结果</li> |
|||
* <li>生成盘亏(PK)和盘盈(PY)事务单据</li> |
|||
* <li>更新库存和标签数量</li> |
|||
* </ul> |
|||
* |
|||
* <p><b>处理范围:</b></p> |
|||
* <ul> |
|||
* <li>QTY_DIFF(数量差异):差异数量正数=盘盈,负数=盘亏</li> |
|||
* <li>MISSING(标签缺失):差异数量为负数=盘亏</li> |
|||
* <li>SURPLUS(多出标签):不处理,需手工处理</li> |
|||
* </ul> |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/12/23 |
|||
*/ |
|||
public interface CountAdjustmentService { |
|||
|
|||
/** |
|||
* 检查是否有需要系统处理的异常结果 - rqrq |
|||
* |
|||
* @param request 请求参数(包含site和countNo) |
|||
* @return int 需要处理的记录数,0表示无需处理 |
|||
* @author rqrq |
|||
*/ |
|||
int checkSystemHandleCount(CountAdjustmentRequest request); |
|||
|
|||
/** |
|||
* 执行自动盘盈盘亏处理 - rqrq |
|||
* |
|||
* <p><b>处理流程:</b></p> |
|||
* <ol> |
|||
* <li>查询所有待系统处理的盘点结果(handle_type='SYSTEM' AND handle_flag='N')</li> |
|||
* <li>排除SURPLUS类型(多出标签不处理)</li> |
|||
* <li>关联handling_unit获取标签详细信息</li> |
|||
* <li>按ERP维度汇总差异数量</li> |
|||
* <li>分离盘盈和盘亏数据</li> |
|||
* <li>按仓库分组处理盘亏:生成PK单据、更新库存</li> |
|||
* <li>按仓库分组处理盘盈:生成PY单据、更新库存</li> |
|||
* <li>逐个标签更新handling_unit.qty</li> |
|||
* <li>更新盘点结果handle_flag='Y'</li> |
|||
* </ol> |
|||
* |
|||
* @param request 请求参数(包含site、countNo、username) |
|||
* @return CountAdjustmentResult 处理结果 |
|||
* @author rqrq |
|||
*/ |
|||
CountAdjustmentResult executeSystemAdjustment(CountAdjustmentRequest request); |
|||
|
|||
// ==================== 盘盈盘亏记录查询 ==================== - rqrq |
|||
|
|||
/** |
|||
* 查询盘盈盘亏事务记录 - rqrq |
|||
* |
|||
* @param request 请求参数(包含site和countNo) |
|||
* @return List<CountAdjustmentTransData> 事务列表 |
|||
* @author rqrq |
|||
*/ |
|||
List<CountAdjustmentTransData> queryAdjustmentTransList(CountAdjustmentRequest request); |
|||
|
|||
/** |
|||
* 查询盘盈盘亏事务子明细 - rqrq |
|||
* |
|||
* @param site 工厂编码 |
|||
* @param transNo 事务号 |
|||
* @return List<CountAdjustmentTransSubData> 子明细列表 |
|||
* @author rqrq |
|||
*/ |
|||
List<CountAdjustmentTransSubData> queryAdjustmentTransSubList(String site, String transNo); |
|||
} |
|||
|
|||
@ -0,0 +1,502 @@ |
|||
package com.gaotao.modules.check.service.impl; |
|||
|
|||
import com.gaotao.modules.check.entity.*; |
|||
import com.gaotao.modules.check.mapper.CountAdjustmentMapper; |
|||
import com.gaotao.modules.check.service.CountAdjustmentService; |
|||
import com.gaotao.modules.trans.entity.TransHeader; |
|||
import com.gaotao.modules.trans.entity.TransDetail; |
|||
import com.gaotao.modules.trans.entity.TransDetailSub; |
|||
import com.gaotao.modules.trans.entity.TransNoControl; |
|||
import com.gaotao.modules.trans.service.TransNoControlService; |
|||
import com.gaotao.modules.trans.service.TransHeaderService; |
|||
import com.gaotao.modules.warehouse.service.InventoryStockService; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
import org.springframework.util.StringUtils; |
|||
|
|||
import java.math.BigDecimal; |
|||
import java.util.*; |
|||
import java.util.stream.Collectors; |
|||
|
|||
/** |
|||
* 盘点调整服务实现类 - 自动处理盘盈盘亏 - rqrq |
|||
* |
|||
* <p><b>处理流程:</b></p> |
|||
* <ol> |
|||
* <li>查询待系统处理的盘点结果(handle_type='SYSTEM' AND handle_flag='N')</li> |
|||
* <li>排除SURPLUS类型(多出标签需手工处理)</li> |
|||
* <li>关联handling_unit获取标签详细信息</li> |
|||
* <li>按ERP维度汇总差异数量</li> |
|||
* <li>分离盘盈(diffQty>0)和盘亏(diffQty<0)数据</li> |
|||
* <li>处理盘亏:生成PK单据、减少库存</li> |
|||
* <li>处理盘盈:生成PY单据、增加库存</li> |
|||
* <li>逐个标签更新handling_unit.qty</li> |
|||
* <li>更新盘点结果handle_flag='Y'</li> |
|||
* </ol> |
|||
* |
|||
* @author rqrq |
|||
* @date 2025/12/23 |
|||
*/ |
|||
@Slf4j |
|||
@Service |
|||
public class CountAdjustmentServiceImpl implements CountAdjustmentService { |
|||
|
|||
@Autowired |
|||
private CountAdjustmentMapper countAdjustmentMapper; |
|||
|
|||
@Autowired |
|||
private TransNoControlService transNoService; |
|||
|
|||
@Autowired |
|||
private TransHeaderService transHeaderService; |
|||
|
|||
@Autowired |
|||
private InventoryStockService inventoryStockService; |
|||
|
|||
/** |
|||
* 检查是否有需要系统处理的异常结果 - rqrq |
|||
*/ |
|||
@Override |
|||
public int checkSystemHandleCount(CountAdjustmentRequest request) { |
|||
log.info("开始检查系统处理异常数量 - rqrq,site={}, countNo={}", request.getSite(), request.getCountNo()); |
|||
|
|||
// 参数校验 - rqrq |
|||
if (!StringUtils.hasText(request.getSite())) { |
|||
throw new RuntimeException("站点不能为空"); |
|||
} |
|||
if (!StringUtils.hasText(request.getCountNo())) { |
|||
throw new RuntimeException("盘点单号不能为空"); |
|||
} |
|||
|
|||
int count = countAdjustmentMapper.countSystemHandleRecords(request.getSite(), request.getCountNo()); |
|||
log.info("检查系统处理异常数量完成,共{}条记录 - rqrq", count); |
|||
return count; |
|||
} |
|||
|
|||
/** |
|||
* 执行自动盘盈盘亏处理 - rqrq |
|||
*/ |
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public CountAdjustmentResult executeSystemAdjustment(CountAdjustmentRequest request) { |
|||
log.info("开始执行自动盘盈盘亏处理 - rqrq,site={}, countNo={}, username={}", |
|||
request.getSite(), request.getCountNo(), request.getUsername()); |
|||
|
|||
// 1. 参数校验 - rqrq |
|||
validateRequest(request); |
|||
|
|||
// 2. 查询待系统处理的盘点结果(排除SURPLUS类型)- rqrq |
|||
List<CountAdjustmentLabelItem> labelItems = countAdjustmentMapper.querySystemHandleLabels( |
|||
request.getSite(), request.getCountNo()); |
|||
|
|||
if (labelItems == null || labelItems.isEmpty()) { |
|||
log.info("没有需要系统处理的异常结果 - rqrq"); |
|||
return CountAdjustmentResult.fail("无异常结果需要系统处理"); |
|||
} |
|||
log.info("查询到待处理标签明细:{}条 - rqrq", labelItems.size()); |
|||
|
|||
// 3. 按ERP维度汇总差异数量 - rqrq |
|||
List<CountAdjustmentItem> summaryItems = summarizeByErpDimension(labelItems); |
|||
log.info("按ERP维度汇总后:{}条记录 - rqrq", summaryItems.size()); |
|||
|
|||
// 4. 分离盘盈和盘亏数据 - rqrq |
|||
List<CountAdjustmentItem> lossItems = summaryItems.stream() |
|||
.filter(item -> item.getDiffQty().compareTo(BigDecimal.ZERO) < 0) |
|||
.collect(Collectors.toList()); |
|||
List<CountAdjustmentItem> profitItems = summaryItems.stream() |
|||
.filter(item -> item.getDiffQty().compareTo(BigDecimal.ZERO) > 0) |
|||
.collect(Collectors.toList()); |
|||
|
|||
log.info("盘亏记录:{}条,盘盈记录:{}条 - rqrq", lossItems.size(), profitItems.size()); |
|||
|
|||
// 5. 创建结果对象 - rqrq |
|||
CountAdjustmentResult result = new CountAdjustmentResult(); |
|||
result.setSuccess(true); |
|||
result.setLossTransNoList(new ArrayList<>()); |
|||
result.setProfitTransNoList(new ArrayList<>()); |
|||
result.setLossCount(lossItems.size()); |
|||
result.setProfitCount(profitItems.size()); |
|||
result.setLabelCount(labelItems.size()); |
|||
|
|||
// 6. 处理盘亏(按仓库分组)- rqrq |
|||
if (!lossItems.isEmpty()) { |
|||
processLossItems(lossItems, request, result); |
|||
} |
|||
|
|||
// 7. 处理盘盈(按仓库分组)- rqrq |
|||
if (!profitItems.isEmpty()) { |
|||
processProfitItems(profitItems, request, result); |
|||
} |
|||
|
|||
// 8. 逐个标签更新handling_unit.qty - rqrq |
|||
updateHandlingUnitQty(labelItems, request.getUsername()); |
|||
|
|||
// 9. 更新盘点结果handle_flag='Y' - rqrq |
|||
updateCountResultHandleFlag(labelItems, request.getUsername()); |
|||
|
|||
result.setMessage("处理完成,盘亏" + result.getLossCount() + "条,盘盈" + result.getProfitCount() + "条"); |
|||
log.info("自动盘盈盘亏处理完成 - rqrq,{}", result.getMessage()); |
|||
return result; |
|||
} |
|||
|
|||
/** |
|||
* 参数校验 - rqrq |
|||
*/ |
|||
private void validateRequest(CountAdjustmentRequest request) { |
|||
if (!StringUtils.hasText(request.getSite())) { |
|||
throw new RuntimeException("站点不能为空"); |
|||
} |
|||
if (!StringUtils.hasText(request.getCountNo())) { |
|||
throw new RuntimeException("盘点单号不能为空"); |
|||
} |
|||
if (!StringUtils.hasText(request.getUsername())) { |
|||
throw new RuntimeException("操作用户不能为空"); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 按ERP维度汇总差异数量 - rqrq |
|||
* |
|||
* <p>汇总维度:site + warehouseId + locationId + partNo + batchNo + wdr + expiredDate + engChgLevel</p> |
|||
*/ |
|||
private List<CountAdjustmentItem> summarizeByErpDimension(List<CountAdjustmentLabelItem> labelItems) { |
|||
// 使用Map按维度汇总 - rqrq |
|||
Map<String, CountAdjustmentItem> summaryMap = new HashMap<>(); |
|||
|
|||
for (CountAdjustmentLabelItem label : labelItems) { |
|||
// 构建维度Key - rqrq |
|||
String key = buildDimensionKey(label); |
|||
|
|||
CountAdjustmentItem item = summaryMap.get(key); |
|||
if (item == null) { |
|||
item = new CountAdjustmentItem(); |
|||
item.setSite(label.getSite()); |
|||
item.setWarehouseId(label.getWarehouseId()); |
|||
item.setLocationId(label.getLocationId()); |
|||
item.setPartNo(label.getPartNo()); |
|||
item.setBatchNo(label.getBatchNo()); |
|||
item.setWdr(label.getWdr()); |
|||
item.setExpiredDate(label.getExpiredDate()); |
|||
item.setEngChgLevel(label.getEngChgLevel()); |
|||
item.setDiffQty(BigDecimal.ZERO); |
|||
item.setLabelItems(new ArrayList<>()); |
|||
summaryMap.put(key, item); |
|||
} |
|||
|
|||
// 累加差异数量 - rqrq |
|||
item.setDiffQty(item.getDiffQty().add(label.getDiffQty())); |
|||
item.getLabelItems().add(label); |
|||
} |
|||
|
|||
return new ArrayList<>(summaryMap.values()); |
|||
} |
|||
|
|||
/** |
|||
* 构建维度Key - rqrq |
|||
*/ |
|||
private String buildDimensionKey(CountAdjustmentLabelItem label) { |
|||
return String.join("||", |
|||
nullToEmpty(label.getSite()), |
|||
nullToEmpty(label.getWarehouseId()), |
|||
nullToEmpty(label.getLocationId()), |
|||
nullToEmpty(label.getPartNo()), |
|||
nullToEmpty(label.getBatchNo()), |
|||
nullToEmpty(label.getWdr()), |
|||
label.getExpiredDate() != null ? label.getExpiredDate().toString() : "", |
|||
nullToEmpty(label.getEngChgLevel()) |
|||
); |
|||
} |
|||
|
|||
private String nullToEmpty(String str) { |
|||
return str != null ? str : ""; |
|||
} |
|||
|
|||
/** |
|||
* 处理盘亏(按仓库分组)- rqrq |
|||
* |
|||
* <p><b>处理流程:</b></p> |
|||
* <ol> |
|||
* <li>按site+warehouseId分组</li> |
|||
* <li>每组生成一个盘亏单据(PK)</li> |
|||
* <li>创建trans_header(order_ref1=盘点单号)</li> |
|||
* <li>创建trans_detail(按维度)</li> |
|||
* <li>创建trans_detail_sub(按标签)</li> |
|||
* <li>减少库存</li> |
|||
* </ol> |
|||
*/ |
|||
private void processLossItems(List<CountAdjustmentItem> lossItems, |
|||
CountAdjustmentRequest request, |
|||
CountAdjustmentResult result) { |
|||
log.info("开始处理盘亏,共{}条记录 - rqrq", lossItems.size()); |
|||
|
|||
// 按site+warehouseId分组 - rqrq |
|||
Map<String, List<CountAdjustmentItem>> groupedItems = lossItems.stream() |
|||
.collect(Collectors.groupingBy(item -> item.getSite() + "||" + item.getWarehouseId())); |
|||
|
|||
for (Map.Entry<String, List<CountAdjustmentItem>> entry : groupedItems.entrySet()) { |
|||
String[] keys = entry.getKey().split("\\|\\|"); |
|||
String site = keys[0]; |
|||
String warehouseId = keys.length > 1 ? keys[1] : ""; |
|||
List<CountAdjustmentItem> items = entry.getValue(); |
|||
|
|||
// 生成盘亏单据号 - rqrq |
|||
TransNoControl transData = transNoService.getTransNo(site, "PK", 10); |
|||
String transNo = transData.getNewTransNo(); |
|||
log.info("生成盘亏单据号:{} - rqrq", transNo); |
|||
|
|||
// 创建trans_header - rqrq |
|||
TransHeader header = createTransHeader(site, transNo, warehouseId, "PK", |
|||
request.getCountNo(), request.getUsername()); |
|||
transHeaderService.save(header); |
|||
|
|||
// 创建trans_detail和trans_detail_sub - rqrq |
|||
int itemNo = 1; |
|||
for (CountAdjustmentItem item : items) { |
|||
// 创建trans_detail - rqrq |
|||
TransDetail detail = createTransDetail(transNo, itemNo, item, "OUT"); |
|||
countAdjustmentMapper.insertTransDetail(detail); |
|||
|
|||
// 创建trans_detail_sub(按标签)- rqrq |
|||
int subNo = 1; |
|||
for (CountAdjustmentLabelItem label : item.getLabelItems()) { |
|||
TransDetailSub sub = createTransDetailSub(transNo, itemNo, subNo, label, "OUT"); |
|||
countAdjustmentMapper.insertTransDetailSub(sub); |
|||
subNo++; |
|||
} |
|||
|
|||
// 减少库存 - rqrq |
|||
inventoryStockService.reduceStockWithLock( |
|||
item.getSite(), |
|||
item.getWarehouseId(), |
|||
item.getPartNo(), |
|||
item.getBatchNo(), |
|||
item.getLocationId(), |
|||
item.getDiffQty().abs(), |
|||
item.getWdr(), |
|||
item.getEngChgLevel() |
|||
); |
|||
|
|||
itemNo++; |
|||
} |
|||
|
|||
result.getLossTransNoList().add(transNo); |
|||
} |
|||
|
|||
log.info("盘亏处理完成,生成{}个单据 - rqrq", result.getLossTransNoList().size()); |
|||
} |
|||
|
|||
/** |
|||
* 处理盘盈(按仓库分组)- rqrq |
|||
*/ |
|||
private void processProfitItems(List<CountAdjustmentItem> profitItems, |
|||
CountAdjustmentRequest request, |
|||
CountAdjustmentResult result) { |
|||
log.info("开始处理盘盈,共{}条记录 - rqrq", profitItems.size()); |
|||
|
|||
// 按site+warehouseId分组 - rqrq |
|||
Map<String, List<CountAdjustmentItem>> groupedItems = profitItems.stream() |
|||
.collect(Collectors.groupingBy(item -> item.getSite() + "||" + item.getWarehouseId())); |
|||
|
|||
for (Map.Entry<String, List<CountAdjustmentItem>> entry : groupedItems.entrySet()) { |
|||
String[] keys = entry.getKey().split("\\|\\|"); |
|||
String site = keys[0]; |
|||
String warehouseId = keys.length > 1 ? keys[1] : ""; |
|||
List<CountAdjustmentItem> items = entry.getValue(); |
|||
|
|||
// 生成盘盈单据号 - rqrq |
|||
TransNoControl transData = transNoService.getTransNo(site, "PY", 10); |
|||
String transNo = transData.getNewTransNo(); |
|||
log.info("生成盘盈单据号:{} - rqrq", transNo); |
|||
|
|||
// 创建trans_header - rqrq |
|||
TransHeader header = createTransHeader(site, transNo, warehouseId, "PY", |
|||
request.getCountNo(), request.getUsername()); |
|||
transHeaderService.save(header); |
|||
|
|||
// 创建trans_detail和trans_detail_sub - rqrq |
|||
int itemNo = 1; |
|||
for (CountAdjustmentItem item : items) { |
|||
// 创建trans_detail - rqrq |
|||
TransDetail detail = createTransDetail(transNo, itemNo, item, "IN"); |
|||
countAdjustmentMapper.insertTransDetail(detail); |
|||
|
|||
// 创建trans_detail_sub(按标签)- rqrq |
|||
int subNo = 1; |
|||
for (CountAdjustmentLabelItem label : item.getLabelItems()) { |
|||
TransDetailSub sub = createTransDetailSub(transNo, itemNo, subNo, label, "IN"); |
|||
countAdjustmentMapper.insertTransDetailSub(sub); |
|||
subNo++; |
|||
} |
|||
|
|||
// 增加库存 - rqrq |
|||
inventoryStockService.updateStockWithLock( |
|||
item.getSite(), |
|||
item.getWarehouseId(), |
|||
item.getPartNo(), |
|||
item.getBatchNo(), |
|||
item.getLocationId(), |
|||
item.getWdr(), |
|||
item.getDiffQty(), |
|||
"N", |
|||
item.getEngChgLevel() |
|||
); |
|||
|
|||
itemNo++; |
|||
} |
|||
|
|||
result.getProfitTransNoList().add(transNo); |
|||
} |
|||
|
|||
log.info("盘盈处理完成,生成{}个单据 - rqrq", result.getProfitTransNoList().size()); |
|||
} |
|||
|
|||
/** |
|||
* 创建事务头 - rqrq |
|||
*/ |
|||
private TransHeader createTransHeader(String site, String transNo, String warehouseId, |
|||
String transType, String countNo, String username) { |
|||
TransHeader header = new TransHeader(); |
|||
header.setSite(site); |
|||
header.setTransNo(transNo); |
|||
header.setTransDate(new Date()); |
|||
header.setTransTypeDb(transType); |
|||
header.setWarehouseId(warehouseId); |
|||
header.setUserId(username); |
|||
header.setUserName(username); |
|||
header.setOrderRef1(countNo); // 关联盘点单号 - rqrq |
|||
header.setRemark(transType.equals("PK") ? "盘亏处理" : "盘盈处理"); |
|||
header.setStatus("COMPLETED"); |
|||
header.setStatusDb("COMPLETED"); |
|||
header.setEnterDate(new Date()); |
|||
header.setIfsFlag("N"); |
|||
return header; |
|||
} |
|||
|
|||
/** |
|||
* 创建事务明细 - rqrq |
|||
*/ |
|||
private TransDetail createTransDetail(String transNo, int itemNo, |
|||
CountAdjustmentItem item, String direction) { |
|||
TransDetail detail = new TransDetail(); |
|||
detail.setSite(item.getSite()); |
|||
detail.setTransNo(transNo); |
|||
detail.setItemNo((double) itemNo); |
|||
detail.setPartNo(item.getPartNo()); |
|||
detail.setTransQty(item.getDiffQty().abs()); |
|||
detail.setBatchNo(item.getBatchNo()); |
|||
detail.setLocationId(item.getLocationId()); |
|||
detail.setDirection(direction); |
|||
detail.setWdrNo(item.getWdr()); |
|||
detail.setEngChgLevel(item.getEngChgLevel()); |
|||
return detail; |
|||
} |
|||
|
|||
/** |
|||
* 创建事务子明细 - rqrq |
|||
*/ |
|||
private TransDetailSub createTransDetailSub(String transNo, int itemNo, int subNo, |
|||
CountAdjustmentLabelItem label, String direction) { |
|||
TransDetailSub sub = new TransDetailSub(); |
|||
sub.setSite(label.getSite()); |
|||
sub.setTransNo(transNo); |
|||
sub.setItemNo((double) itemNo); |
|||
sub.setSubNo(String.valueOf(subNo)); |
|||
sub.setSubQty(label.getDiffQty().abs().doubleValue()); |
|||
sub.setDirection(direction); |
|||
sub.setHandlingUnitId(label.getUnitId()); |
|||
sub.setPartNo(label.getPartNo()); |
|||
sub.setBatchNo(label.getBatchNo()); |
|||
sub.setLocationId(label.getLocationId()); |
|||
sub.setEngChgLevel(label.getEngChgLevel()); |
|||
sub.setOrderRef1(label.getPalletId()); // 记录栈板号 - rqrq |
|||
return sub; |
|||
} |
|||
|
|||
/** |
|||
* 更新标签数量 - rqrq |
|||
* |
|||
* <p>如果更新后qty<=0,设置in_stock_flag='N'</p> |
|||
*/ |
|||
private void updateHandlingUnitQty(List<CountAdjustmentLabelItem> labelItems, String username) { |
|||
log.info("开始更新标签数量,共{}个标签 - rqrq", labelItems.size()); |
|||
|
|||
for (CountAdjustmentLabelItem label : labelItems) { |
|||
// 计算新数量 - rqrq |
|||
BigDecimal newQty = label.getQty().add(label.getDiffQty()); |
|||
String inStockFlag = newQty.compareTo(BigDecimal.ZERO) > 0 ? "Y" : "N"; |
|||
|
|||
// 如果新数量小于0,设为0 - rqrq |
|||
if (newQty.compareTo(BigDecimal.ZERO) < 0) { |
|||
newQty = BigDecimal.ZERO; |
|||
} |
|||
|
|||
// 更新handling_unit - rqrq |
|||
countAdjustmentMapper.updateHandlingUnitQty( |
|||
label.getSite(), |
|||
label.getUnitId(), |
|||
newQty, |
|||
inStockFlag, |
|||
username |
|||
); |
|||
} |
|||
|
|||
log.info("标签数量更新完成 - rqrq"); |
|||
} |
|||
|
|||
/** |
|||
* 更新盘点结果处理标记 - rqrq |
|||
*/ |
|||
private void updateCountResultHandleFlag(List<CountAdjustmentLabelItem> labelItems, String username) { |
|||
log.info("开始更新盘点结果处理标记 - rqrq"); |
|||
|
|||
for (CountAdjustmentLabelItem label : labelItems) { |
|||
countAdjustmentMapper.updateCountResultHandleFlag(label.getCountResultId(), username); |
|||
} |
|||
|
|||
log.info("盘点结果处理标记更新完成 - rqrq"); |
|||
} |
|||
|
|||
// ==================== 盘盈盘亏记录查询 ==================== - rqrq |
|||
|
|||
/** |
|||
* 查询盘盈盘亏事务记录 - rqrq |
|||
*/ |
|||
@Override |
|||
public List<CountAdjustmentTransData> queryAdjustmentTransList(CountAdjustmentRequest request) { |
|||
log.info("开始查询盘盈盘亏事务记录 - rqrq,site={}, countNo={}", request.getSite(), request.getCountNo()); |
|||
|
|||
if (!StringUtils.hasText(request.getSite())) { |
|||
throw new RuntimeException("站点不能为空"); |
|||
} |
|||
if (!StringUtils.hasText(request.getCountNo())) { |
|||
throw new RuntimeException("盘点单号不能为空"); |
|||
} |
|||
|
|||
List<CountAdjustmentTransData> list = countAdjustmentMapper.queryAdjustmentTransList( |
|||
request.getSite(), request.getCountNo()); |
|||
log.info("查询盘盈盘亏事务记录完成,共{}条记录 - rqrq", list != null ? list.size() : 0); |
|||
return list; |
|||
} |
|||
|
|||
/** |
|||
* 查询盘盈盘亏事务子明细 - rqrq |
|||
*/ |
|||
@Override |
|||
public List<CountAdjustmentTransSubData> queryAdjustmentTransSubList(String site, String transNo) { |
|||
log.info("开始查询盘盈盘亏事务子明细 - rqrq,site={}, transNo={}", site, transNo); |
|||
|
|||
if (!StringUtils.hasText(site)) { |
|||
throw new RuntimeException("站点不能为空"); |
|||
} |
|||
if (!StringUtils.hasText(transNo)) { |
|||
throw new RuntimeException("事务号不能为空"); |
|||
} |
|||
|
|||
List<CountAdjustmentTransSubData> list = countAdjustmentMapper.queryAdjustmentTransSubList(site, transNo); |
|||
log.info("查询盘盈盘亏事务子明细完成,共{}条记录 - rqrq", list != null ? list.size() : 0); |
|||
return list; |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,152 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
|||
<mapper namespace="com.gaotao.modules.check.mapper.CountAdjustmentMapper"> |
|||
|
|||
<!-- rqrq - 统计需要系统处理的异常结果数量 --> |
|||
<select id="countSystemHandleRecords" resultType="int"> |
|||
SELECT COUNT(1) |
|||
FROM count_result |
|||
WHERE site = #{site} |
|||
AND count_no = #{countNo} |
|||
AND handle_flag = 'N' |
|||
AND handle_type = 'SYSTEM' |
|||
AND count_result != 'SURPLUS' |
|||
AND count_result != 'OK' |
|||
</select> |
|||
|
|||
<!-- rqrq - 查询待系统处理的标签明细(排除SURPLUS类型)--> |
|||
<select id="querySystemHandleLabels" resultType="CountAdjustmentLabelItem"> |
|||
SELECT |
|||
r.id AS countResultId, |
|||
r.count_no AS countNo, |
|||
r.count_result AS countResult, |
|||
r.diff_qty AS diffQty, |
|||
r.site AS site, |
|||
r.unit_id AS unitId, |
|||
r.pallet_id AS palletId, |
|||
h.part_no AS partNo, |
|||
h.qty AS qty, |
|||
h.batch_no AS batchNo, |
|||
h.location_id AS locationId, |
|||
h.warehouse_id AS warehouseId, |
|||
h.wdr AS wdr, |
|||
h.expired_date AS expiredDate, |
|||
h.eng_chg_level AS engChgLevel |
|||
FROM count_result r |
|||
LEFT JOIN handling_unit h ON r.site = h.site AND r.unit_id = h.unit_id |
|||
WHERE r.site = #{site} |
|||
AND r.count_no = #{countNo} |
|||
AND r.handle_flag = 'N' |
|||
AND r.handle_type = 'SYSTEM' |
|||
AND r.count_result != 'SURPLUS' |
|||
AND r.count_result != 'OK' |
|||
ORDER BY r.id |
|||
</select> |
|||
|
|||
<!-- rqrq - 插入事务明细 --> |
|||
<insert id="insertTransDetail"> |
|||
INSERT INTO trans_detail ( |
|||
site, trans_no, item_no, part_no, trans_qty, |
|||
batch_no, location_id, direction, wdr_no, eng_chg_level |
|||
) VALUES ( |
|||
#{site}, #{transNo}, #{itemNo}, #{partNo}, #{transQty}, |
|||
#{batchNo}, #{locationId}, #{direction}, #{wdrNo}, #{engChgLevel} |
|||
) |
|||
</insert> |
|||
|
|||
<!-- rqrq - 插入事务子明细 --> |
|||
<insert id="insertTransDetailSub"> |
|||
INSERT INTO trans_detail_sub ( |
|||
site, trans_no, item_no, sub_no, sub_qty, direction, |
|||
handling_unit_id, part_no, batch_no, location_id, eng_chg_level, order_ref1 |
|||
) VALUES ( |
|||
#{site}, #{transNo}, #{itemNo}, #{subNo}, #{subQty}, #{direction}, |
|||
#{handlingUnitId}, #{partNo}, #{batchNo}, #{locationId}, #{engChgLevel}, #{orderRef1} |
|||
) |
|||
</insert> |
|||
|
|||
<!-- rqrq - 更新标签数量 --> |
|||
<update id="updateHandlingUnitQty"> |
|||
UPDATE handling_unit |
|||
SET qty = #{qty}, |
|||
in_stock_flag = #{inStockFlag}, |
|||
modified_by = #{username}, |
|||
modified_date = GETDATE() |
|||
WHERE site = #{site} |
|||
AND unit_id = #{unitId} |
|||
</update> |
|||
|
|||
<!-- rqrq - 更新盘点结果处理标记 --> |
|||
<update id="updateCountResultHandleFlag"> |
|||
UPDATE count_result |
|||
SET handle_flag = 'Y', |
|||
handle_time = GETDATE(), |
|||
handle_by = #{username} |
|||
WHERE id = #{countResultId} |
|||
</update> |
|||
|
|||
<!-- rqrq - 查询盘盈盘亏事务头和明细 --> |
|||
<select id="queryAdjustmentTransList" resultType="CountAdjustmentTransData"> |
|||
SELECT |
|||
h.site, |
|||
h.trans_no AS transNo, |
|||
h.trans_date AS transDate, |
|||
h.trans_type_db AS transTypeDb, |
|||
CASE h.trans_type_db |
|||
WHEN 'PK' THEN '盘亏' |
|||
WHEN 'PY' THEN '盘盈' |
|||
ELSE h.trans_type_db |
|||
END AS transTypeDesc, |
|||
h.warehouse_id AS warehouseId, |
|||
h.order_ref1 AS orderRef1, |
|||
h.remark, |
|||
h.user_name AS userName, |
|||
d.item_no AS itemNo, |
|||
d.part_no AS partNo, |
|||
d.trans_qty AS transQty, |
|||
d.batch_no AS batchNo, |
|||
d.location_id AS locationId, |
|||
d.direction, |
|||
CASE d.direction |
|||
WHEN 'IN' THEN '入库' |
|||
WHEN 'OUT' THEN '出库' |
|||
ELSE d.direction |
|||
END AS directionDesc, |
|||
d.wdr_no AS wdrNo, |
|||
d.eng_chg_level AS engChgLevel |
|||
FROM trans_header h |
|||
INNER JOIN trans_detail d ON h.site = d.site AND h.trans_no = d.trans_no |
|||
WHERE h.site = #{site} |
|||
AND h.order_ref1 = #{countNo} |
|||
AND h.trans_type_db IN ('PK', 'PY') |
|||
ORDER BY h.trans_no, d.item_no |
|||
</select> |
|||
|
|||
<!-- rqrq - 查询事务子明细 --> |
|||
<select id="queryAdjustmentTransSubList" resultType="CountAdjustmentTransSubData"> |
|||
SELECT |
|||
site, |
|||
trans_no AS transNo, |
|||
item_no AS itemNo, |
|||
sub_no AS subNo, |
|||
sub_qty AS subQty, |
|||
direction, |
|||
CASE direction |
|||
WHEN 'IN' THEN '入库' |
|||
WHEN 'OUT' THEN '出库' |
|||
ELSE direction |
|||
END AS directionDesc, |
|||
handling_unit_id AS handlingUnitId, |
|||
part_no AS partNo, |
|||
batch_no AS batchNo, |
|||
location_id AS locationId, |
|||
eng_chg_level AS engChgLevel, |
|||
order_ref1 AS palletId |
|||
FROM trans_detail_sub |
|||
WHERE site = #{site} |
|||
AND trans_no = #{transNo} |
|||
ORDER BY item_no, sub_no |
|||
</select> |
|||
|
|||
</mapper> |
|||
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue