9 changed files with 1029 additions and 24 deletions
-
155src/main/java/com/gaotao/modules/crossAreaTransfer/controller/CrossAreaTransferController.java
-
71src/main/java/com/gaotao/modules/crossAreaTransfer/dao/CrossAreaTransferMapper.java
-
101src/main/java/com/gaotao/modules/crossAreaTransfer/entity/CrossAreaTransferEntity.java
-
31src/main/java/com/gaotao/modules/crossAreaTransfer/service/CrossAreaTransferService.java
-
304src/main/java/com/gaotao/modules/crossAreaTransfer/service/impl/CrossAreaTransferServiceImpl.java
-
179src/main/java/com/gaotao/modules/labelSplitMerge/service/impl/LabelSplitMergeServiceImpl.java
-
108src/main/java/com/gaotao/modules/propertyChange/service/impl/PropertyChangeServiceImpl.java
-
7src/main/java/com/gaotao/modules/trans/service/impl/TransHeaderServiceImpl.java
-
97src/main/resources/mapper/crossAreaTransfer/CrossAreaTransferMapper.xml
@ -0,0 +1,155 @@ |
|||||
|
package com.gaotao.modules.crossAreaTransfer.controller; |
||||
|
|
||||
|
import com.gaotao.common.utils.R; |
||||
|
import com.gaotao.modules.crossAreaTransfer.service.CrossAreaTransferService; |
||||
|
import io.swagger.annotations.Api; |
||||
|
import io.swagger.annotations.ApiOperation; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.web.bind.annotation.*; |
||||
|
|
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* 跨区调拨控制器 |
||||
|
* |
||||
|
* @author system |
||||
|
* @date 2025-01-01 |
||||
|
*/ |
||||
|
@Api(tags = "跨区调拨管理") |
||||
|
@RestController |
||||
|
@RequestMapping("/cross-area-transfer") |
||||
|
public class CrossAreaTransferController { |
||||
|
|
||||
|
private static final Logger logger = LoggerFactory.getLogger(CrossAreaTransferController.class); |
||||
|
|
||||
|
@Autowired |
||||
|
private CrossAreaTransferService crossAreaTransferService; |
||||
|
|
||||
|
/** |
||||
|
* 获取跨区调拨信息 |
||||
|
* |
||||
|
* @param params 查询参数 |
||||
|
* @return 调拨信息 |
||||
|
*/ |
||||
|
@ApiOperation("获取跨区调拨信息") |
||||
|
@PostMapping("/getTransferInfo") |
||||
|
public R getTransferInfo(@RequestBody Map<String, Object> params) { |
||||
|
logger.info("获取跨区调拨信息接口调用,参数: {}", params); |
||||
|
|
||||
|
try { |
||||
|
// 参数校验 |
||||
|
String scanCode = (String) params.get("scanCode"); |
||||
|
String transferMode = (String) params.get("transferMode"); |
||||
|
String site = (String) params.get("site"); |
||||
|
String warehouseId = (String) params.get("warehouseId"); |
||||
|
|
||||
|
if (scanCode == null || scanCode.trim().isEmpty()) { |
||||
|
return R.error("扫描码不能为空"); |
||||
|
} |
||||
|
|
||||
|
if (transferMode == null || transferMode.trim().isEmpty()) { |
||||
|
return R.error("调拨模式不能为空"); |
||||
|
} |
||||
|
|
||||
|
if (!"label".equals(transferMode) && !"location".equals(transferMode)) { |
||||
|
return R.error("调拨模式参数错误"); |
||||
|
} |
||||
|
|
||||
|
if (site == null || site.trim().isEmpty()) { |
||||
|
return R.error("站点不能为空"); |
||||
|
} |
||||
|
|
||||
|
if (warehouseId == null || warehouseId.trim().isEmpty()) { |
||||
|
return R.error("仓库ID不能为空"); |
||||
|
} |
||||
|
|
||||
|
Map<String, Object> result = crossAreaTransferService.getTransferInfo(params); |
||||
|
|
||||
|
if ((Integer) result.get("code") == 0) { |
||||
|
return R.ok().put("data", result.get("data")); |
||||
|
} else { |
||||
|
return R.error((String) result.get("msg")); |
||||
|
} |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
logger.error("获取跨区调拨信息失败", e); |
||||
|
return R.error("获取调拨信息失败: " + e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 保存跨区调拨 |
||||
|
* |
||||
|
* @param params 调拨参数 |
||||
|
* - scanCode: 扫描码 |
||||
|
* - transferMode: 调拨模式 |
||||
|
* - sourceLocation: 源库位 |
||||
|
* - targetLocation: 目标库位 |
||||
|
* - site: 站点 |
||||
|
* - warehouseId: 仓库ID |
||||
|
* - operator: 操作员 |
||||
|
* @return 操作结果 |
||||
|
*/ |
||||
|
@ApiOperation("保存跨区调拨") |
||||
|
@PostMapping("/saveTransfer") |
||||
|
public R saveTransfer(@RequestBody Map<String, Object> params) { |
||||
|
logger.info("保存跨区调拨接口调用,参数: {}", params); |
||||
|
|
||||
|
try { |
||||
|
// 参数校验 |
||||
|
String scanCode = (String) params.get("scanCode"); |
||||
|
String transferMode = (String) params.get("transferMode"); |
||||
|
String sourceLocation = (String) params.get("sourceLocation"); |
||||
|
String targetLocation = (String) params.get("targetLocation"); |
||||
|
String site = (String) params.get("site"); |
||||
|
String warehouseId = (String) params.get("warehouseId"); |
||||
|
String operator = (String) params.get("operator"); |
||||
|
|
||||
|
if (scanCode == null || scanCode.trim().isEmpty()) { |
||||
|
return R.error("扫描码不能为空"); |
||||
|
} |
||||
|
|
||||
|
if (transferMode == null || transferMode.trim().isEmpty()) { |
||||
|
return R.error("调拨模式不能为空"); |
||||
|
} |
||||
|
|
||||
|
if (!"label".equals(transferMode) && !"location".equals(transferMode)) { |
||||
|
return R.error("调拨模式参数错误"); |
||||
|
} |
||||
|
|
||||
|
if (sourceLocation == null || sourceLocation.trim().isEmpty()) { |
||||
|
return R.error("源库位不能为空"); |
||||
|
} |
||||
|
|
||||
|
if (targetLocation == null || targetLocation.trim().isEmpty()) { |
||||
|
return R.error("目标库位不能为空"); |
||||
|
} |
||||
|
|
||||
|
if (site == null || site.trim().isEmpty()) { |
||||
|
return R.error("站点不能为空"); |
||||
|
} |
||||
|
|
||||
|
if (warehouseId == null || warehouseId.trim().isEmpty()) { |
||||
|
return R.error("仓库ID不能为空"); |
||||
|
} |
||||
|
|
||||
|
if (operator == null || operator.trim().isEmpty()) { |
||||
|
return R.error("操作员不能为空"); |
||||
|
} |
||||
|
|
||||
|
boolean success = crossAreaTransferService.saveTransfer(params); |
||||
|
|
||||
|
if (success) { |
||||
|
return R.ok("跨区调拨成功"); |
||||
|
} else { |
||||
|
return R.error("跨区调拨失败"); |
||||
|
} |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
logger.error("保存跨区调拨失败", e); |
||||
|
return R.error("保存调拨失败: " + e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,71 @@ |
|||||
|
package com.gaotao.modules.crossAreaTransfer.dao; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
|
import com.gaotao.modules.crossAreaTransfer.entity.CrossAreaTransferEntity; |
||||
|
import org.apache.ibatis.annotations.Mapper; |
||||
|
import org.apache.ibatis.annotations.Param; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* 跨区调拨Mapper |
||||
|
* |
||||
|
* @author system |
||||
|
* @date 2025-01-01 |
||||
|
*/ |
||||
|
@Mapper |
||||
|
public interface CrossAreaTransferMapper extends BaseMapper<CrossAreaTransferEntity> { |
||||
|
|
||||
|
/** |
||||
|
* 根据标签条码获取库存信息 |
||||
|
* |
||||
|
* @param labelCode 标签条码 |
||||
|
* @param site 站点 |
||||
|
* @param warehouseId 仓库ID |
||||
|
* @return 库存信息 |
||||
|
*/ |
||||
|
Map<String, Object> getStockInfoByLabelCode(@Param("labelCode") String labelCode, |
||||
|
@Param("site") String site, |
||||
|
@Param("warehouseId") String warehouseId); |
||||
|
|
||||
|
/** |
||||
|
* 根据库位获取标签列表 |
||||
|
* |
||||
|
* @param locationId 库位ID |
||||
|
* @param site 站点 |
||||
|
* @param warehouseId 仓库ID |
||||
|
* @return 标签列表 |
||||
|
*/ |
||||
|
List<Map<String, Object>> getLabelsByLocation(@Param("locationId") String locationId, |
||||
|
@Param("site") String site, |
||||
|
@Param("warehouseId") String warehouseId); |
||||
|
|
||||
|
/** |
||||
|
* 根据库位获取库存信息列表 |
||||
|
* |
||||
|
* @param locationId 库位ID |
||||
|
* @param site 站点 |
||||
|
* @param warehouseId 仓库ID |
||||
|
* @return 库存信息列表 |
||||
|
*/ |
||||
|
List<Map<String, Object>> getStockInfoByLocation(@Param("locationId") String locationId, |
||||
|
@Param("site") String site, |
||||
|
@Param("warehouseId") String warehouseId); |
||||
|
|
||||
|
/** |
||||
|
* 更新库存表的库位和仓库信息(按标签调拨) |
||||
|
* |
||||
|
* @param params 更新参数 |
||||
|
* @return 更新行数 |
||||
|
*/ |
||||
|
int updateStockLocationAndWarehouse(Map<String, Object> params); |
||||
|
|
||||
|
/** |
||||
|
* 批量更新库存表的库位和仓库信息(按库位调拨) |
||||
|
* |
||||
|
* @param params 更新参数 |
||||
|
* @return 更新行数 |
||||
|
*/ |
||||
|
int batchUpdateStockLocationAndWarehouse(Map<String, Object> params); |
||||
|
} |
||||
@ -0,0 +1,101 @@ |
|||||
|
package com.gaotao.modules.crossAreaTransfer.entity; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.annotation.TableId; |
||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
/** |
||||
|
* 跨区调拨实体类 |
||||
|
* |
||||
|
* @author system |
||||
|
* @date 2025-01-01 |
||||
|
*/ |
||||
|
@Data |
||||
|
@TableName("cross_area_transfer") |
||||
|
public class CrossAreaTransferEntity implements Serializable { |
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** |
||||
|
* 主键ID |
||||
|
*/ |
||||
|
@TableId |
||||
|
private Long id; |
||||
|
|
||||
|
/** |
||||
|
* 站点 |
||||
|
*/ |
||||
|
private String site; |
||||
|
|
||||
|
/** |
||||
|
* 事业部 |
||||
|
*/ |
||||
|
private String buNo; |
||||
|
|
||||
|
/** |
||||
|
* 仓库ID |
||||
|
*/ |
||||
|
private String warehouseId; |
||||
|
|
||||
|
/** |
||||
|
* 标签条码 |
||||
|
*/ |
||||
|
private String labelCode; |
||||
|
|
||||
|
/** |
||||
|
* 物料编码 |
||||
|
*/ |
||||
|
private String partNo; |
||||
|
|
||||
|
/** |
||||
|
* 批次号 |
||||
|
*/ |
||||
|
private String batchNo; |
||||
|
|
||||
|
/** |
||||
|
* 调拨模式:label-按标签调拨,location-按库位调拨 |
||||
|
*/ |
||||
|
private String transferMode; |
||||
|
|
||||
|
/** |
||||
|
* 源库位 |
||||
|
*/ |
||||
|
private String sourceLocation; |
||||
|
|
||||
|
/** |
||||
|
* 目标库位 |
||||
|
*/ |
||||
|
private String targetLocation; |
||||
|
|
||||
|
/** |
||||
|
* 数量 |
||||
|
*/ |
||||
|
private Float quantity; |
||||
|
|
||||
|
/** |
||||
|
* 操作员 |
||||
|
*/ |
||||
|
private String operator; |
||||
|
|
||||
|
/** |
||||
|
* 创建时间 |
||||
|
*/ |
||||
|
private Date createTime; |
||||
|
|
||||
|
/** |
||||
|
* 事务单号 |
||||
|
*/ |
||||
|
private String transNo; |
||||
|
|
||||
|
/** |
||||
|
* 状态:0-待处理,1-已完成,2-已取消 |
||||
|
*/ |
||||
|
private Integer status; |
||||
|
|
||||
|
/** |
||||
|
* 备注 |
||||
|
*/ |
||||
|
private String remark; |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
package com.gaotao.modules.crossAreaTransfer.service; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.extension.service.IService; |
||||
|
import com.gaotao.modules.crossAreaTransfer.entity.CrossAreaTransferEntity; |
||||
|
|
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* 跨区调拨服务接口 |
||||
|
* |
||||
|
* @author system |
||||
|
* @date 2025-01-01 |
||||
|
*/ |
||||
|
public interface CrossAreaTransferService extends IService<CrossAreaTransferEntity> { |
||||
|
|
||||
|
/** |
||||
|
* 获取跨区调拨信息 |
||||
|
* |
||||
|
* @param params 查询参数 |
||||
|
* @return 调拨信息 |
||||
|
*/ |
||||
|
Map<String, Object> getTransferInfo(Map<String, Object> params); |
||||
|
|
||||
|
/** |
||||
|
* 保存跨区调拨 |
||||
|
* |
||||
|
* @param params 调拨参数 |
||||
|
* @return 是否成功 |
||||
|
*/ |
||||
|
boolean saveTransfer(Map<String, Object> params); |
||||
|
} |
||||
@ -0,0 +1,304 @@ |
|||||
|
package com.gaotao.modules.crossAreaTransfer.service.impl; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
||||
|
import com.gaotao.modules.crossAreaTransfer.dao.CrossAreaTransferMapper; |
||||
|
import com.gaotao.modules.crossAreaTransfer.entity.CrossAreaTransferEntity; |
||||
|
import com.gaotao.modules.crossAreaTransfer.service.CrossAreaTransferService; |
||||
|
import com.gaotao.modules.inboundNotification.dao.InboundNotificationHeadMapper; |
||||
|
import com.gaotao.modules.trans.entity.TransDetail; |
||||
|
import com.gaotao.modules.trans.entity.TransDetailDto; |
||||
|
import com.gaotao.modules.trans.entity.TransHeader; |
||||
|
import com.gaotao.modules.trans.service.TransDetailService; |
||||
|
import com.gaotao.modules.trans.service.TransHeaderService; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
import org.springframework.transaction.annotation.Transactional; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.util.ArrayList; |
||||
|
import java.util.Date; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* 跨区调拨服务实现类 |
||||
|
* |
||||
|
* @author system |
||||
|
* @date 2025-01-01 |
||||
|
*/ |
||||
|
@Service |
||||
|
public class CrossAreaTransferServiceImpl extends ServiceImpl<CrossAreaTransferMapper, CrossAreaTransferEntity> implements CrossAreaTransferService { |
||||
|
|
||||
|
private static final Logger logger = LoggerFactory.getLogger(CrossAreaTransferServiceImpl.class); |
||||
|
|
||||
|
@Autowired |
||||
|
private CrossAreaTransferMapper crossAreaTransferMapper; |
||||
|
|
||||
|
@Autowired |
||||
|
private TransHeaderService transHeaderService; |
||||
|
|
||||
|
@Autowired |
||||
|
private TransDetailService transDetailService; |
||||
|
|
||||
|
@Autowired |
||||
|
private InboundNotificationHeadMapper headMapper; |
||||
|
|
||||
|
@Override |
||||
|
public Map<String, Object> getTransferInfo(Map<String, Object> params) { |
||||
|
logger.info("获取跨区调拨信息,参数: {}", params); |
||||
|
|
||||
|
String scanCode = (String) params.get("scanCode"); |
||||
|
String transferMode = (String) params.get("transferMode"); |
||||
|
String site = (String) params.get("site"); |
||||
|
String warehouseId = (String) params.get("warehouseId"); |
||||
|
|
||||
|
Map<String, Object> result = new HashMap<>(); |
||||
|
|
||||
|
try { |
||||
|
if ("label".equals(transferMode)) { |
||||
|
// 按标签调拨:获取标签信息 |
||||
|
Map<String, Object> stockInfo = crossAreaTransferMapper.getStockInfoByLabelCode(scanCode, site, warehouseId); |
||||
|
|
||||
|
if (stockInfo == null) { |
||||
|
logger.warn("未找到标签库存信息,标签条码: {}", scanCode); |
||||
|
result.put("code", 1); |
||||
|
result.put("msg", "未找到该标签的库存信息"); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
// 格式化返回数据 |
||||
|
Map<String, Object> labelInfo = new HashMap<>(); |
||||
|
labelInfo.put("labelCode", stockInfo.get("label_code")); |
||||
|
labelInfo.put("quantity", stockInfo.get("quantity")); |
||||
|
labelInfo.put("warehouseName", stockInfo.get("warehouse_name")); |
||||
|
labelInfo.put("locationId", stockInfo.get("location_id")); |
||||
|
labelInfo.put("status", stockInfo.get("status")); |
||||
|
labelInfo.put("productionDate", stockInfo.get("production_date")); |
||||
|
labelInfo.put("expiryDate", stockInfo.get("expiry_date")); |
||||
|
labelInfo.put("orderRef1", stockInfo.get("order_ref1")); |
||||
|
labelInfo.put("orderRef2", stockInfo.get("order_ref2")); |
||||
|
labelInfo.put("batchNo", stockInfo.get("batch_no")); |
||||
|
labelInfo.put("buNo", stockInfo.get("buNo")); |
||||
|
result.put("code", 0); |
||||
|
result.put("data", labelInfo); |
||||
|
|
||||
|
} else if ("location".equals(transferMode)) { |
||||
|
// 按库位调拨:获取库位下的所有标签 |
||||
|
List<Map<String, Object>> labels = crossAreaTransferMapper.getLabelsByLocation(scanCode, site, warehouseId); |
||||
|
|
||||
|
if (labels == null || labels.isEmpty()) { |
||||
|
logger.warn("该库位下未找到标签,库位: {}", scanCode); |
||||
|
result.put("code", 1); |
||||
|
result.put("msg", "该库位下未找到标签"); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
result.put("code", 0); |
||||
|
result.put("data", labels); |
||||
|
} |
||||
|
|
||||
|
logger.info("获取跨区调拨信息成功,模式: {}, 扫描码: {}", transferMode, scanCode); |
||||
|
return result; |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
logger.error("获取跨区调拨信息失败", e); |
||||
|
result.put("code", 1); |
||||
|
result.put("msg", "查询失败: " + e.getMessage()); |
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
@Transactional(rollbackFor = Exception.class) |
||||
|
public boolean saveTransfer(Map<String, Object> params) { |
||||
|
logger.info("开始保存跨区调拨,参数: {}", params); |
||||
|
|
||||
|
try { |
||||
|
String scanCode = (String) params.get("scanCode"); |
||||
|
String transferMode = (String) params.get("transferMode"); |
||||
|
String sourceLocation = (String) params.get("sourceLocation"); |
||||
|
String targetLocation = (String) params.get("targetLocation"); |
||||
|
String site = (String) params.get("site"); |
||||
|
String buNo = (String) params.get("buNo"); |
||||
|
String warehouseId = (String) params.get("warehouseId"); |
||||
|
String operator = (String) params.get("operator"); |
||||
|
// 1. 验证库位是否存在且可用 |
||||
|
Map<String, Object> locationInfo = headMapper.validateLocation(targetLocation, site); |
||||
|
if (locationInfo == null || locationInfo.isEmpty()) { |
||||
|
throw new RuntimeException("该库位不存在,请检查"); |
||||
|
} |
||||
|
|
||||
|
String locationStatus = (String) locationInfo.get("status"); |
||||
|
if (!"Y".equals(locationStatus)) { |
||||
|
throw new RuntimeException("该库位已停用,请检查"); |
||||
|
} |
||||
|
|
||||
|
// 2. 根据源库位查询库存信息 |
||||
|
List<Map<String, Object>> stockInfoList = new ArrayList<>(); |
||||
|
if ("label".equals(transferMode)) { |
||||
|
// 按标签调拨:查询单个标签的库存信息 |
||||
|
Map<String, Object> stockInfo = crossAreaTransferMapper.getStockInfoByLabelCode(scanCode, site, warehouseId); |
||||
|
if (stockInfo != null) { |
||||
|
stockInfoList.add(stockInfo); |
||||
|
} |
||||
|
} else { |
||||
|
// 按库位调拨:查询库位下所有标签的库存信息 |
||||
|
stockInfoList = crossAreaTransferMapper.getStockInfoByLocation(sourceLocation, site, warehouseId); |
||||
|
} |
||||
|
|
||||
|
if (stockInfoList.isEmpty()) { |
||||
|
logger.error("未找到库存信息,源库位: {}", sourceLocation); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
// 根据库位获取实际的仓库ID |
||||
|
String actualWarehouseId = (String) locationInfo.get("warehouseId"); |
||||
|
if (actualWarehouseId != null && !actualWarehouseId.trim().isEmpty()) { |
||||
|
warehouseId = actualWarehouseId; |
||||
|
logger.info("根据库位号 {} 获取到仓库ID: {}", targetLocation, warehouseId); |
||||
|
} |
||||
|
|
||||
|
// 3. 更新库存表 - 根据源库位更新到目标库位和仓库 |
||||
|
Map<String, Object> updateParams = new HashMap<>(); |
||||
|
updateParams.put("site", site); |
||||
|
updateParams.put("sourceLocation", sourceLocation); |
||||
|
updateParams.put("targetLocation", targetLocation); |
||||
|
updateParams.put("targetWarehouseId", warehouseId); // 目标仓库ID |
||||
|
updateParams.put("operator", operator); |
||||
|
updateParams.put("updateTime", new Date()); |
||||
|
|
||||
|
int updateCount = 0; |
||||
|
if ("label".equals(transferMode)) { |
||||
|
// 按标签调拨:更新单个标签的库位和仓库 |
||||
|
updateParams.put("labelCode", scanCode); |
||||
|
updateCount = crossAreaTransferMapper.updateStockLocationAndWarehouse(updateParams); |
||||
|
} else { |
||||
|
// 按库位调拨:更新整个库位下所有标签的库位和仓库 |
||||
|
updateCount = crossAreaTransferMapper.batchUpdateStockLocationAndWarehouse(updateParams); |
||||
|
} |
||||
|
|
||||
|
if (updateCount == 0) { |
||||
|
logger.error("更新库存失败,未找到匹配的库存记录"); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
// 5. 生成标签变动事务记录 |
||||
|
generateTransferTransaction(site, warehouseId, scanCode, transferMode, buNo, stockInfoList); |
||||
|
|
||||
|
logger.info("跨区调拨保存成功,模式: {}, 扫描码: {}, 目标库位: {}", transferMode, scanCode, targetLocation); |
||||
|
return true; |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
logger.error("保存跨区调拨失败", e); |
||||
|
throw new RuntimeException("保存跨区调拨失败: " + e.getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 生成跨区调拨事务记录 |
||||
|
*/ |
||||
|
private void generateTransferTransaction(String site, String warehouseId, String scanCode, String transferMode, String buNo, List<Map<String, Object>> stockInfoList) { |
||||
|
logger.info("开始生成跨区调拨事务记录,扫描码: {}", scanCode); |
||||
|
|
||||
|
try { |
||||
|
// 构建TransDetailDto对象 |
||||
|
TransDetailDto transDetailDto = new TransDetailDto(); |
||||
|
transDetailDto.setSite(site); |
||||
|
transDetailDto.setRemark("跨区调拨 - " + transferMode); |
||||
|
transDetailDto.setOrderref1(scanCode); // 扫描码(标签或库位) |
||||
|
transDetailDto.setOrderref2(transferMode); // 调拨模式 |
||||
|
transDetailDto.setOrderref3(warehouseId); // 仓库ID |
||||
|
|
||||
|
// 使用TransHeaderService的genTrans方法生成事务头 |
||||
|
// CAT = Cross Area Transfer 跨区调拨 |
||||
|
TransHeader transHeader = transHeaderService.genTrans(transDetailDto, "CAT", warehouseId, buNo); |
||||
|
|
||||
|
if (transHeader == null) { |
||||
|
throw new RuntimeException("生成跨区调拨事务头记录失败"); |
||||
|
} |
||||
|
|
||||
|
logger.info("跨区调拨事务头记录生成成功,事务单号: {}", transHeader.getTransno()); |
||||
|
|
||||
|
// 生成事务明细记录 |
||||
|
generateTransactionDetails(transHeader.getTransno(), stockInfoList, site); |
||||
|
|
||||
|
logger.info("跨区调拨事务记录生成完成,事务单号: {}, 扫描码: {}, 明细记录数: {}", |
||||
|
transHeader.getTransno(), scanCode, stockInfoList.size()); |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
logger.error("生成跨区调拨事务记录失败", e); |
||||
|
// 不抛出异常,避免影响主流程 |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 生成事务明细记录 |
||||
|
*/ |
||||
|
private void generateTransactionDetails(String transNo, List<Map<String, Object>> stockInfoList, String site) { |
||||
|
logger.info("开始生成跨区调拨事务明细记录,事务单号: {}, 明细数量: {}", transNo, stockInfoList.size()); |
||||
|
|
||||
|
List<TransDetail> transDetailList = new ArrayList<>(); |
||||
|
double itemNo = 1.0; // 行号从1开始 |
||||
|
|
||||
|
for (Map<String, Object> stockInfo : stockInfoList) { |
||||
|
String labelCode = (String) stockInfo.get("label_code"); |
||||
|
String partNo = (String) stockInfo.get("part_no"); |
||||
|
String batchNo = (String) stockInfo.get("batch_no"); |
||||
|
Object quantityObj = stockInfo.get("quantity"); |
||||
|
|
||||
|
// 转换数量 |
||||
|
BigDecimal quantity = convertToDecimal(quantityObj); |
||||
|
|
||||
|
// 构建事务明细记录 |
||||
|
TransDetail transDetail = new TransDetail(); |
||||
|
transDetail.setSite(site); |
||||
|
transDetail.setTransno(transNo); |
||||
|
transDetail.setItemno(itemNo); |
||||
|
transDetail.setPartno(partNo); |
||||
|
transDetail.setTransqty(quantity); |
||||
|
transDetail.setBatchno(batchNo); |
||||
|
transDetail.setDirection("-"); // 调拨方向 |
||||
|
transDetail.setOrderref1(labelCode); // 标签条码 |
||||
|
transDetail.setOrderref2(partNo); // 物料编码 |
||||
|
transDetail.setOrderref3(batchNo); // 批次号 |
||||
|
transDetail.setRemark("跨区调拨 - 标签: " + labelCode); |
||||
|
|
||||
|
transDetailList.add(transDetail); |
||||
|
itemNo += 1.0; // 行号递增 |
||||
|
} |
||||
|
|
||||
|
// 批量保存事务明细记录 |
||||
|
if (!transDetailList.isEmpty()) { |
||||
|
boolean success = transDetailService.saveBatch(transDetailList); |
||||
|
if (!success) { |
||||
|
throw new RuntimeException("跨区调拨事务明细记录保存失败"); |
||||
|
} |
||||
|
logger.info("跨区调拨事务明细记录生成成功,共生成 {} 条明细记录", transDetailList.size()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 转换数量为BigDecimal |
||||
|
*/ |
||||
|
private BigDecimal convertToDecimal(Object quantityObj) { |
||||
|
if (quantityObj == null) { |
||||
|
return BigDecimal.ZERO; |
||||
|
} |
||||
|
|
||||
|
if (quantityObj instanceof BigDecimal) { |
||||
|
return (BigDecimal) quantityObj; |
||||
|
} else if (quantityObj instanceof Number) { |
||||
|
return new BigDecimal(quantityObj.toString()); |
||||
|
} else { |
||||
|
try { |
||||
|
return new BigDecimal(quantityObj.toString()); |
||||
|
} catch (NumberFormatException e) { |
||||
|
logger.warn("数量转换失败,使用默认值0,原值: {}", quantityObj); |
||||
|
return BigDecimal.ZERO; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,97 @@ |
|||||
|
<?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.crossAreaTransfer.dao.CrossAreaTransferMapper"> |
||||
|
|
||||
|
<!-- 根据标签条码获取库存信息 --> |
||||
|
<select id="getStockInfoByLabelCode" resultType="map"> |
||||
|
SELECT |
||||
|
s.roll_no as label_code, |
||||
|
s.part_no, |
||||
|
s.batch_no, |
||||
|
s.bu_no as buNo, |
||||
|
s.qty_on_hand as quantity, |
||||
|
s.location_id, |
||||
|
s.manufacture_date as production_date, |
||||
|
s.expired_date as expiry_date, |
||||
|
s.orderref1 as order_ref1, |
||||
|
s.orderref2 as order_ref2, |
||||
|
s.status, |
||||
|
w.WareHouseName as warehouse_name |
||||
|
FROM inventory_stock s |
||||
|
LEFT JOIN warehouse w ON s.warehouse_id = w.WareHouseID AND s.site = w.site |
||||
|
WHERE s.roll_no = #{labelCode} |
||||
|
AND s.site = #{site} |
||||
|
AND s.warehouse_id = #{warehouseId} |
||||
|
AND s.status = '在库' |
||||
|
AND s.qty_on_hand > 0 |
||||
|
</select> |
||||
|
|
||||
|
<!-- 根据库位获取标签列表 --> |
||||
|
<select id="getLabelsByLocation" resultType="map"> |
||||
|
SELECT |
||||
|
s.roll_no AS labelCode, |
||||
|
s.part_no AS partNo, |
||||
|
s.bu_no as buNo, |
||||
|
s.qty_on_hand AS quantity, |
||||
|
p.UMID as unit |
||||
|
FROM inventory_stock s |
||||
|
LEFT JOIN Part p ON s.part_no = p.PartNo AND s.site = p.site and s.bu_no = p.bu_no |
||||
|
WHERE s.location_id = #{locationId} |
||||
|
AND s.site = #{site} |
||||
|
AND s.warehouse_id = #{warehouseId} |
||||
|
AND s.status = '在库' |
||||
|
AND s.qty_on_hand > 0 |
||||
|
ORDER BY s.roll_no |
||||
|
</select> |
||||
|
|
||||
|
<!-- 根据库位获取库存信息列表 --> |
||||
|
<select id="getStockInfoByLocation" resultType="map"> |
||||
|
SELECT |
||||
|
s.roll_no as label_code, |
||||
|
s.part_no, |
||||
|
s.batch_no, |
||||
|
s.qty_on_hand as quantity, |
||||
|
s.location_id, |
||||
|
s.manufacture_date as production_date, |
||||
|
s.expired_date as expiry_date, |
||||
|
s.orderref1 as order_ref1, |
||||
|
s.orderref2 as order_ref2, |
||||
|
s.status, |
||||
|
w.WareHouseName as warehouse_name |
||||
|
FROM inventory_stock s |
||||
|
LEFT JOIN warehouse w ON s.warehouse_id = w.WareHouseID AND s.site = w.site |
||||
|
WHERE s.location_id = #{locationId} |
||||
|
AND s.site = #{site} |
||||
|
AND s.warehouse_id = #{warehouseId} |
||||
|
AND s.status = '在库' |
||||
|
AND s.qty_on_hand > 0 |
||||
|
ORDER BY s.roll_no |
||||
|
</select> |
||||
|
|
||||
|
<!-- 更新库存表的库位和仓库信息(按标签调拨) --> |
||||
|
<update id="updateStockLocationAndWarehouse"> |
||||
|
UPDATE inventory_stock |
||||
|
SET location_id = #{targetLocation}, |
||||
|
warehouse_id = #{targetWarehouseId}, |
||||
|
latest_in_date = #{updateTime} |
||||
|
WHERE roll_no = #{labelCode} |
||||
|
AND location_id = #{sourceLocation} |
||||
|
AND site = #{site} |
||||
|
AND status = '在库' |
||||
|
AND qty_on_hand > 0 |
||||
|
</update> |
||||
|
|
||||
|
<!-- 批量更新库存表的库位和仓库信息(按库位调拨) --> |
||||
|
<update id="batchUpdateStockLocationAndWarehouse"> |
||||
|
UPDATE inventory_stock |
||||
|
SET location_id = #{targetLocation}, |
||||
|
warehouse_id = #{targetWarehouseId}, |
||||
|
latest_in_date = #{updateTime} |
||||
|
WHERE location_id = #{sourceLocation} |
||||
|
AND site = #{site} |
||||
|
AND status = '在库' |
||||
|
AND qty_on_hand > 0 |
||||
|
</update> |
||||
|
|
||||
|
</mapper> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue