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