Merge branch 'wms_dev' into dev

This commit is contained in:
王奎兴
2026-02-12 10:10:49 +08:00
39 changed files with 1136 additions and 207 deletions
@@ -218,6 +218,12 @@ public interface SystemServiceFeign {
@GetMapping("/associationWarehouseApi/getWarehouseInfo/{correlationId}")
public AjaxResult getWarehouseInfo(@PathVariable("correlationId") Long correlationId);
/**
* 直接从数据库获取指定用户设置的仓库(不使用缓存)
*/
@GetMapping("/associationWarehouseApi/getWarehouseInfoFromDb/{correlationId}")
public AjaxResult getWarehouseInfoFromDb(@PathVariable("correlationId") Long correlationId);
/**
* 根据warehouseId获取对仓库信息
*/
@@ -6,6 +6,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.List;
/**
@@ -66,6 +67,10 @@ public class MaterialBarCodeFeign extends BaseVOEntity{
@Excel(name = "名称")
private String name;
@ApiModelProperty("数量")
@Excel(name = "数量")
private BigDecimal number;
@ApiModelProperty("备注")
@Excel(name = "备注")
private String remark;
@@ -169,6 +169,11 @@ public class RemoteSystemFeignFallbackFactory implements FallbackFactory<SystemS
return AjaxResult.error("获取用户当前设置的仓库失败");
}
@Override
public AjaxResult getWarehouseInfoFromDb(Long correlationId) {
return AjaxResult.error("从数据库获取用户当前设置的仓库失败");
}
@Override
public AjaxResult getWarehouseInfoByWarehouseId(@PathVariable("warehouseId") Long warehouseId) {
return AjaxResult.error("根据仓库ID获取仓库信息失败");
@@ -1,5 +1,6 @@
package com.mhd.basic.application.service.Lease;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@@ -188,56 +189,98 @@ public class LeaseApplicationService {
/**
* 货主租赁明细
* 定时任务:每天凌晨1点执行,计算前一天的货主租赁明细
*/
@Scheduled(cron = "0 0 1 * * ?")
public void shipperLeaseDetails() {
log.info("开始执行货主租赁明细定时任务");
// 计算前一天的日期,将时间设置为当天的0点0分0秒,只保留日期部分
final Date yesterday = DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), -1));
LeaseDO leaseDO = new LeaseDO();
leaseDO.setTime(new Date());
//查询租赁
leaseDO.setTime(yesterday);
//查询有效期内的租赁
List<LeasePO> leasePOS = queryList(leaseDO);
// List<LeasePO> leasePOS = leaseDomainService.queryList(leaseDO);
List<LeasePO> entireUnit = leasePOS.stream()
.filter(lease -> lease.getLeaseType().equals("整租"))
.collect(Collectors.toList());
List<LeasePO> casualRental = leasePOS.stream()
.filter(lease -> lease.getLeaseType().equals("散租"))
.collect(Collectors.toList());
List<ShipperLeaseDetails> shipperLeaseDetailsList = new ArrayList<>(); //建表后保存
for (LeasePO en : entireUnit) {//整租
List<ShipperLeaseDetails> shipperLeaseDetailsList = new ArrayList<>(); //需要保存或更新的数据
List<ShipperLeaseDetails> shipperLeaseDetailsToUpdate = new ArrayList<>(); //需要更新的数据
// 查询已存在的货主租赁明细数据(用于判断是新增还是更新)
ShipperLeaseDetailsDO queryDO = new ShipperLeaseDetailsDO();
queryDO.setBusinessDate(yesterday);
List<ShipperLeaseDetailsPO> existingList = shipperLeaseDetailsService.queryList(queryDO);
// 构建已存在数据的Map,key为:业务日期+货主ID+仓库ID+租赁类型
Map<String, ShipperLeaseDetailsPO> existingMap = existingList.stream()
.collect(Collectors.toMap(
item -> buildKey(yesterday, item.getShipperId(), item.getWarehouseId(), item.getLeaseType()),
item -> item,
(existing, replacement) -> existing // 如果有重复key,保留第一个
));
// 处理整租
for (LeasePO en : entireUnit) {
String key = buildKey(yesterday, en.getShipperId(), en.getWarehouseId(), en.getLeaseType());
ShipperLeaseDetails shipperLeaseDetails = new ShipperLeaseDetails();
BeanUtils.copyProperties(en, shipperLeaseDetails);
shipperLeaseDetails.setBusinessDate(new Date());
shipperLeaseDetailsList.add(shipperLeaseDetails);
shipperLeaseDetails.setBusinessDate(yesterday);
// 如果已存在,则更新;否则新增
if (existingMap.containsKey(key)) {
ShipperLeaseDetailsPO existing = existingMap.get(key);
shipperLeaseDetails.setId(existing.getId());
shipperLeaseDetailsToUpdate.add(shipperLeaseDetails);
} else {
shipperLeaseDetailsList.add(shipperLeaseDetails);
}
}
//当前货主当前仓库,库存查询页面所有面积加起来就是散租面积
for (LeasePO ca : casualRental) {//散租
// 处理散租:从租赁管理页面维护的面积,效期内的散租客户面积之和
for (LeasePO ca : casualRental) {
String key = buildKey(yesterday, ca.getShipperId(), ca.getWarehouseId(), ca.getLeaseType());
ShipperLeaseDetails shipperLeaseDetails = new ShipperLeaseDetails();
BeanUtils.copyProperties(ca, shipperLeaseDetails);
shipperLeaseDetails.setBusinessDate(new Date());
//物料库存
MaterialInventoryDTO materialInventoryDTO = new MaterialInventoryDTO();
materialInventoryDTO.setShipperId(ca.getShipperId());
materialInventoryDTO.setWarehouseId(ca.getWarehouseId());
AjaxResult ajaxResult = wmsServiceFeign.materialInventoryApiListAll(materialInventoryDTO);
BigDecimal area = BigDecimal.ZERO;
if(String.valueOf(ajaxResult.get("code")).equals("200")) {
JSONArray data = JSONObject.parseArray(JSON.toJSONString(ajaxResult.get("data")));
for (Object datum : data) {
JSONObject json = (JSONObject) datum;
BigDecimal area1 = json.getBigDecimal("area");
if (area1 == null) {
area1 = BigDecimal.ZERO;
}
area = area.add(area1);
}
shipperLeaseDetails.setBusinessDate(yesterday);
// 散租面积直接使用租赁管理页面维护的面积
shipperLeaseDetails.setLeaseArea(ca.getLeaseArea());
log.info("货主:{},仓库:{},散租面积:{}(来自租赁管理)", ca.getCargoOwnerName(), ca.getWarehouseName(), ca.getLeaseArea());
// 如果已存在,则更新;否则新增
if (existingMap.containsKey(key)) {
ShipperLeaseDetailsPO existing = existingMap.get(key);
shipperLeaseDetails.setId(existing.getId());
shipperLeaseDetailsToUpdate.add(shipperLeaseDetails);
} else {
shipperLeaseDetailsList.add(shipperLeaseDetails);
}
shipperLeaseDetails.setLeaseArea(area);
shipperLeaseDetailsList.add(shipperLeaseDetails);
}
// 保存货主租赁明细(新建表)
// 批量新增货主租赁明细
if (shipperLeaseDetailsList.size() > 0) {
shipperLeaseDetailsService.saveBatch(shipperLeaseDetailsList);
log.info("新增货主租赁明细{}条", shipperLeaseDetailsList.size());
}
// 批量更新货主租赁明细
if (shipperLeaseDetailsToUpdate.size() > 0) {
shipperLeaseDetailsService.updateBatchById(shipperLeaseDetailsToUpdate);
log.info("更新货主租赁明细{}条", shipperLeaseDetailsToUpdate.size());
}
log.info("货主租赁明细定时任务执行完成,业务日期:{}", DateUtil.formatDate(yesterday));
}
/**
* 构建唯一key:业务日期+货主ID+仓库ID+租赁类型
*/
private String buildKey(Date businessDate, Long shipperId, Long warehouseId, String leaseType) {
String dateStr = DateUtil.formatDate(businessDate);
return dateStr + "_" + shipperId + "_" + warehouseId + "_" + leaseType;
}
/**
@@ -247,9 +290,11 @@ public class LeaseApplicationService {
* businessDateEnd 业务结束时间
*/
public List<WarehouseOccupancyRate> warehouseOccupancyRate(ShipperLeaseDetailsDO shipperLeaseDetailsDO) {
//仓库id 和 开始结束时间作为查询条件 查数据库 出来当前仓库所有的
//仓库id 和 开始结束时间作为查询条件 查数据库 出来当前仓库所有的
List<ShipperLeaseDetailsPO> shipperLeaseDetailsList = shipperLeaseDetailsService.queryList(shipperLeaseDetailsDO);
ShipperLeaseDetailsPO shipperLeaseDetailsPO = shipperLeaseDetailsList.get(0);
if (shipperLeaseDetailsList == null || shipperLeaseDetailsList.isEmpty()) {
return new ArrayList<>();
}
//按业务日期分组,并按日期排序
TreeMap<Date, List<ShipperLeaseDetailsPO>> groupedByDate = shipperLeaseDetailsList.stream().collect(
Collectors.groupingBy(
@@ -117,4 +117,15 @@ public class AssociationWarehouseApplicationService {
public AssociationWarehouseCacheDO getWarehouseInfo(Long correlationId) {
return associationWarehouseDomainService.getWarehouseInfo(correlationId);
}
/**
* @description 直接从数据库查询关联仓库列表根据关联id(不使用缓存)
* @author ZhouGY
* @date 2024/6/11 15:34
* @param correlationId
* @return AssociationWarehouseCacheDO
*/
public AssociationWarehouseCacheDO getWarehouseInfoFromDb(Long correlationId) {
return associationWarehouseDomainService.getWarehouseInfoFromDb(correlationId);
}
}
@@ -146,4 +146,37 @@ public class AssociationWarehouseDomainService {
return associationWarehouseCacheDO;
}
/**
* @description 直接从数据库查询关联仓库列表根据关联id(不使用缓存)
* @author ZhouGY
* @date 2024/6/11 15:34
* @param correlationId
* @return AssociationWarehouseCacheDO
*/
public AssociationWarehouseCacheDO getWarehouseInfoFromDb(Long correlationId) {
LoginUser loginUser = SecurityUtils.getLoginUser();
// 直接从数据库查询,不使用缓存
AssociationWarehouse associationWarehouse = associationWarehouseService.getOne(new QueryWrapper<AssociationWarehouse>().lambda()
.eq(AssociationWarehouse::getCorrelationId, loginUser.getUserid())
.eq(AssociationWarehouse::getIsDefault, 2)
.eq(AssociationWarehouse::getDelFlag, 1));
AssociationWarehouseCacheDO associationWarehouseCacheDO = null;
if (ObjectUtil.isNotNull(associationWarehouse)){
associationWarehouseCacheDO = new AssociationWarehouseCacheDO();
BeanUtils.copyProperties(associationWarehouse, associationWarehouseCacheDO);
}else {
//首次 没有查到默认取第一条数据
List<AssociationWarehouse> associationWarehouseList = associationWarehouseService.list(new QueryWrapper<AssociationWarehouse>().lambda()
.eq(AssociationWarehouse::getCorrelationId, loginUser.getUserid())
.orderByAsc(AssociationWarehouse::getAssociationWarehouseId));
if (CollectionUtils.isEmpty(associationWarehouseList)){
return null; // 返回null,不抛异常,允许查询所有仓库
}
AssociationWarehouse associationWarehouseAsc = associationWarehouseList.get(0);
associationWarehouseCacheDO = new AssociationWarehouseCacheDO();
BeanUtils.copyProperties(associationWarehouseAsc, associationWarehouseCacheDO);
}
return associationWarehouseCacheDO;
}
}
@@ -308,7 +308,7 @@ public class StorageLocationDomainService {
updateWrapper.in("storage_location_group_id", storageLocationGroupIds);
updateWrapper.set("update_by", loginUser.getUserid());
updateWrapper.set("update_by_name", loginUser.getUsername());
updateWrapper.set("update_by", new Date());
updateWrapper.set("update_time", new Date());
updateWrapper.setSql("storage_location_count = storage_location_count - 1");
storageLocationGroupService.update(updateWrapper);
}
@@ -134,4 +134,14 @@ public class AssociationWarehouseApi extends BaseController{
return AjaxResult.success(associationWarehouseCacheDO);
}
/**
* 直接从数据库获取指定用户设置的仓库(不使用缓存)
*/
@ApiOperation("直接从数据库获取指定用户设置的仓库(不使用缓存)")
@GetMapping("/getWarehouseInfoFromDb/{correlationId}")
public AjaxResult getWarehouseInfoFromDb(@PathVariable("correlationId") Long correlationId) {
AssociationWarehouseCacheDO associationWarehouseCacheDO = associationWarehouseApplicationService.getWarehouseInfoFromDb(correlationId);
return AjaxResult.success(associationWarehouseCacheDO);
}
}
@@ -10,6 +10,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="organizationId" column="organization_id" />
<result property="organizationName" column="organization_name" />
<result property="topOrganizationId" column="top_organization_id" />
<result property="warehouseId" column="warehouse_id" />
<result property="warehouseName" column="warehouse_name" />
<result property="shipperId" column="shipper_id" />
<result property="cargoOwnerName" column="cargo_owner_name" />
<result property="leaseType" column="lease_type" />
<result property="leaseArea" column="lease_area" />
@@ -2022,6 +2022,10 @@ public class UserApplicationService {
*/
@Transactional(rollbackFor = Exception.class)
public int deleteByIds(List<Long> ids) {
// 检查ids是否为空
if (ids == null || ids.isEmpty()) {
throw new ServiceException("删除的用户ID列表不能为空");
}
//获取登录人信息
LoginUser loginUser = SecurityUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
@@ -2042,8 +2046,10 @@ public class UserApplicationService {
userDomainService.updateUser(userDO);
}
}
//同步删除网货的员工信息
wlhyDomainService.deleteBatchPlatformUser(ids);
//同步删除网货的员工信息(只有当ids不为空时才调用)
if (!ids.isEmpty()) {
wlhyDomainService.deleteBatchPlatformUser(ids);
}
return ids.size();
}
@@ -609,6 +609,10 @@ public class UserWlhyDomainService {
* @return boolean
*/
public boolean deleteBatchPlatformUser(List<Long> szwlUserIds){
// 检查ids是否为空
if (szwlUserIds == null || szwlUserIds.isEmpty()) {
return true; // 如果列表为空,直接返回成功,避免SQL语法错误
}
//检查是否开启网货
boolean flag = checkSwitch();
if(!flag){
@@ -366,6 +366,10 @@ public class UserAPI extends BaseController {
@Log(title = "用户中台管理-删除", description ="批量删除用户",businessType = BusinessType.DELETE)
@DeleteMapping("/removeByIds/{ids}")
public AjaxResult removeByIds(@PathVariable List<Long> ids) {
// 检查ids是否为空
if (ids == null || ids.isEmpty()) {
return error("删除的用户ID列表不能为空");
}
return toAjax(userApplicationService.deleteByIds(ids));
}
@@ -56,8 +56,14 @@ public class MaterialInventoryApplicationService {
if (topOrganizationId != null && topOrganizationId != 1){
materialInventoryDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
}
AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid());
materialInventoryDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId());
// 前端有传warehouseId则优先使用传参未传时才使用用户关联仓库作为默认值
if (materialInventoryDO.getWarehouseId() == null) {
AssociationWarehouseCacheDO associationWarehouseCacheDO =
SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid());
if (associationWarehouseCacheDO != null) {
materialInventoryDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId());
}
}
}
return materialInventoryDomainService.queryList(materialInventoryDO);
}
@@ -337,8 +343,14 @@ public class MaterialInventoryApplicationService {
if (topOrganizationId != null && topOrganizationId != 1){
materialInventoryDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
}
AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid());
materialInventoryDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId());
// 前端有传warehouseId则优先使用传参未传时才使用用户关联仓库作为默认值
if (materialInventoryDO.getWarehouseId() == null) {
AssociationWarehouseCacheDO associationWarehouseCacheDO =
SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid());
if (associationWarehouseCacheDO != null) {
materialInventoryDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId());
}
}
}
List<MaterialInventoryPO> materialInventoryPOS = materialInventoryDomainService.queryList(materialInventoryDO);
if (CollectionUtils.isNotEmpty(materialInventoryPOS)){
@@ -66,8 +66,8 @@ public class PickingOrderApplicationService {
if (topOrganizationId != null && topOrganizationId != 1){
pickingOrderDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
}
AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid());
pickingOrderDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId());
//AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid());
//pickingOrderDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId());
}
List<PickingOrderPO> pickingOrderPOList = pickingOrderDomainService.queryList(pickingOrderDO);
@@ -583,4 +583,4 @@ public class PickingOrderApplicationService {
returnPickingOrderDO.setMaterialDetailList(returnPickingMaterialDetailDOList);
return returnPickingOrderDO;
}
}
}
@@ -73,22 +73,13 @@ public class StockInOrderApplicationService {
if (topOrganizationId != null && topOrganizationId != 1){
stockInOrderDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
}
try {
AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid());
// 前端有传warehouseId则优先使用传参未传时才使用"用户关联仓库"作为默认值
if (stockInOrderDO.getWarehouseId() == null) {
AssociationWarehouseCacheDO associationWarehouseCacheDO =
SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid());
if (associationWarehouseCacheDO != null) {
if (associationWarehouseCacheDO.getWarehouseId() != null) {
stockInOrderDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId());
}
if (StringUtils.isNotBlank(associationWarehouseCacheDO.getWarehouseCode())) {
stockInOrderDO.setWarehouseCode(associationWarehouseCacheDO.getWarehouseCode());
}
if (StringUtils.isNotBlank(associationWarehouseCacheDO.getWarehouseName())) {
stockInOrderDO.setWarehouseName(associationWarehouseCacheDO.getWarehouseName());
}
stockInOrderDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId());
}
} catch (Exception e) {
// 如果获取仓库信息失败记录日志但不影响查询允许查询所有仓库
log.warn("获取用户关联仓库信息失败,将查询所有仓库数据,用户ID:{},错误:{}", loginUser.getUserid(), e.getMessage());
}
}
return stockInOrderDomainService.queryList(stockInOrderDO);
@@ -139,10 +130,46 @@ public class StockInOrderApplicationService {
/**
* 批量删除入库单
* 只有已创建状态status = 1的入库单可以删除
*/
public boolean delete(Long[] inOrderIds) {
if (inOrderIds == null || inOrderIds.length == 0) {
throw new ServiceException("删除的入库单ID不能为空");
}
// 查询入库单信息检查状态
for (Long inOrderId : inOrderIds) {
StockInOrderPO stockInOrderPO = stockInOrderDomainService.getInfo(inOrderId);
if (stockInOrderPO == null) {
throw new ServiceException("入库单不存在,入库单ID" + inOrderId);
}
// 只有已创建状态status = 1的入库单可以删除
if (stockInOrderPO.getStatus() == null || !stockInOrderPO.getStatus().equals(1)) {
throw new ServiceException("只有已创建状态的入库单可以删除,入库单号:" + stockInOrderPO.getInOrderNumber() + ",当前状态:" + getStatusName(stockInOrderPO.getStatus()));
}
}
return stockInOrderDomainService.delete(inOrderIds);
}
/**
* 获取入库状态名称
*/
private String getStatusName(Integer status) {
if (status == null) {
return "未知";
}
switch (status) {
case 1: return "已创建";
case 2: return "已审核";
case 3: return "收货中";
case 4: return "上架中";
case 5: return "已入库";
case 6: return "已取消";
case 7: return "已关闭";
default: return "未知";
}
}
/**
* 获取入库单详细信息
@@ -195,7 +222,7 @@ public class StockInOrderApplicationService {
* - 第13行明细表列名
* - 第14行开始明细数据
*/
public Boolean importData(MultipartFile file) {
public Boolean importData(MultipartFile file, Long warehouseId, String warehouseCode, String warehouseName) {
if (file == null || file.isEmpty()) {
throw new ServiceException("导入文件不能为空");
}
@@ -1046,13 +1073,16 @@ public class StockInOrderApplicationService {
List<StockInOrderImportRowDTO> groupRows = entry.getValue();
StockInOrderImportRowDTO h = groupRows.get(0);
// 获取仓库ID使用登录人当前关联仓库
Long warehouseId;
AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid());
if (associationWarehouseCacheDO == null || associationWarehouseCacheDO.getWarehouseId() == null) {
throw new ServiceException("导入失败:未配置用户关联仓库,请先配置仓库");
// 使用传入的仓库信息与出库单导入保持一致
if (warehouseId == null) {
throw new ServiceException("导入失败:仓库ID不能为空");
}
if (StringUtils.isBlank(warehouseCode)) {
throw new ServiceException("导入失败:仓库编码不能为空");
}
if (StringUtils.isBlank(warehouseName)) {
throw new ServiceException("导入失败:仓库名称不能为空");
}
warehouseId = associationWarehouseCacheDO.getWarehouseId();
// 客户名称应该从表头获取优先使用表头如果表头为空则使用明细行
String customerName = StringUtils.isNotBlank(headerInfo.getShipperName()) ? headerInfo.getShipperName() : h.getShipperName();
@@ -1074,10 +1104,10 @@ public class StockInOrderApplicationService {
// 设置创建时间为当前时间
order.setCreateTime(new Date());
// 必填/基础字段
// 必填/基础字段使用传入的仓库信息与出库单导入保持一致
order.setWarehouseId(warehouseId);
// 设置仓库完整信息warehouseCode warehouseName
setWarehouseInfo(order);
order.setWarehouseCode(warehouseCode);
order.setWarehouseName(warehouseName);
// 货主信息优先使用表头如果表头为空则使用明细行
String shipperName = StringUtils.isNotBlank(headerInfo.getShipperName()) ? headerInfo.getShipperName() : h.getShipperName();
String shipperCode = StringUtils.isNotBlank(headerInfo.getShipperCode()) ? headerInfo.getShipperCode() : h.getShipperCode();
@@ -1202,124 +1232,45 @@ public class StockInOrderApplicationService {
}
}
// 根据明细表中的字段查询物料基础信息优先料号 > 商品SKU码 > 商品名称
// 注意查询时必须加上货主ID条件确保查询到的是该货主绑定的物料
// 导入文件中必须填写料号根据料号获取商品信息必须是货主下有的才可以匹配
// 如果没有填写提示用户请在导入文件中填写正确的料号
if (StringUtils.isBlank(r.getMaterialCode())) {
String errorMsg = String.format("导入失败:请在导入文件中填写正确的料号",
r.getMaterialName());
log.error(errorMsg);
throw new ServiceException(errorMsg);
}
// 根据料号查询物料基础信息必须是货主下有的才可以匹配
Long materialBaseInfoId = null;
LoginUser currentLoginUser = SecurityUtils.getLoginUser();
Long topOrganizationId = currentLoginUser != null && currentLoginUser.getUserPo() != null
? currentLoginUser.getUserPo().getTopOrganizationId() : null;
// 优先使用料号查询
if (StringUtils.isNotBlank(r.getMaterialCode())) {
MaterialBaseInfoDO queryDO = new MaterialBaseInfoDO();
queryDO.setMaterialCode(r.getMaterialCode());
if (topOrganizationId != null) {
queryDO.setTopOrganizationId(topOrganizationId);
}
// 加上货主ID条件确保查询到的是该货主绑定的物料
if (shipperId != null) {
queryDO.setShipperId(shipperId);
}
log.info("尝试通过料号查询物料基础信息,料号: [{}], topOrganizationId: {}, shipperId: {}",
r.getMaterialCode(), topOrganizationId, shipperId);
List<MaterialBaseInfoPO> materialList = materialBaseInfoService.queryList(queryDO);
log.info("料号查询结果,查询到 {} 条记录", materialList != null ? materialList.size() : 0);
if (materialList != null && !materialList.isEmpty()) {
materialBaseInfoId = materialList.get(0).getMaterialBaseInfoId();
log.info("通过料号查询到物料基础信息,料号: {}, 物料ID: {}, 货主ID: {}",
r.getMaterialCode(), materialBaseInfoId, shipperId);
} else {
// 如果提供了料号但查询不到直接报错不允许导入
String errorMsg = String.format("导入失败:该货主下不存在该料号(委托编号NO=%s,货主名称=%s,料号=%s)。请确保该料号已在物料管理中创建,且属于该货主",
h.getConsignmentNo(), order.getShipperName(), r.getMaterialCode());
log.error(errorMsg);
throw new ServiceException(errorMsg);
}
// 使用料号查询必须加上货主ID条件确保查询到的是该货主绑定的物料
MaterialBaseInfoDO queryDO = new MaterialBaseInfoDO();
queryDO.setMaterialCode(r.getMaterialCode());
if (topOrganizationId != null) {
queryDO.setTopOrganizationId(topOrganizationId);
}
// 加上货主ID条件确保查询到的是该货主绑定的物料
if (shipperId != null) {
queryDO.setShipperId(shipperId);
}
log.info("尝试通过料号查询物料基础信息,料号: [{}], topOrganizationId: {}, shipperId: {}",
r.getMaterialCode(), topOrganizationId, shipperId);
List<MaterialBaseInfoPO> materialList = materialBaseInfoService.queryList(queryDO);
log.info("料号查询结果,查询到 {} 条记录", materialList != null ? materialList.size() : 0);
if (materialList != null && !materialList.isEmpty()) {
materialBaseInfoId = materialList.get(0).getMaterialBaseInfoId();
log.info("通过料号查询到物料基础信息,料号: {}, 物料ID: {}, 货主ID: {}",
r.getMaterialCode(), materialBaseInfoId, shipperId);
} else {
log.warn("料号为空,跳过料号查询,将尝试使用SKU码或商品名称查询");
}
// 只有在料号为空的情况下才使用商品SKU码查询
if (materialBaseInfoId == null && StringUtils.isNotBlank(r.getSkuCode())) {
MaterialBaseInfoDO queryDO = new MaterialBaseInfoDO();
queryDO.setBarCode(r.getSkuCode());
if (topOrganizationId != null) {
queryDO.setTopOrganizationId(topOrganizationId);
}
// 加上货主ID条件确保查询到的是该货主绑定的物料
if (shipperId != null) {
queryDO.setShipperId(shipperId);
}
log.info("尝试通过商品SKU码查询物料基础信息,SKU码: [{}], topOrganizationId: {}, shipperId: {}",
r.getSkuCode(), topOrganizationId, shipperId);
List<MaterialBaseInfoPO> materialList = materialBaseInfoService.queryList(queryDO);
log.info("SKU码查询结果,查询到 {} 条记录", materialList != null ? materialList.size() : 0);
if (materialList != null && !materialList.isEmpty()) {
materialBaseInfoId = materialList.get(0).getMaterialBaseInfoId();
log.info("通过商品SKU码查询到物料基础信息,SKU码: {}, 物料ID: {}, 货主ID: {}",
r.getSkuCode(), materialBaseInfoId, shipperId);
} else {
log.warn("通过SKU码未查询到物料基础信息,SKU码: [{}], 货主ID: [{}]", r.getSkuCode(), shipperId);
}
} else if (materialBaseInfoId == null) {
log.warn("SKU码为空,跳过SKU码查询");
}
// 如果料号和SKU码都查询不到使用商品名称查询
if (materialBaseInfoId == null && StringUtils.isNotBlank(r.getMaterialName())) {
MaterialBaseInfoDO queryDO = new MaterialBaseInfoDO();
queryDO.setMaterialName(r.getMaterialName());
if (topOrganizationId != null) {
queryDO.setTopOrganizationId(topOrganizationId);
}
// 加上货主ID条件确保查询到的是该货主绑定的物料
if (shipperId != null) {
queryDO.setShipperId(shipperId);
}
log.info("尝试通过商品名称查询物料基础信息,商品名称: [{}], topOrganizationId: {}, shipperId: {}",
r.getMaterialName(), topOrganizationId, shipperId);
List<MaterialBaseInfoPO> materialList = materialBaseInfoService.queryList(queryDO);
log.info("商品名称查询结果,查询到 {} 条记录", materialList != null ? materialList.size() : 0);
if (materialList != null && !materialList.isEmpty()) {
materialBaseInfoId = materialList.get(0).getMaterialBaseInfoId();
log.info("通过商品名称查询到物料基础信息,商品名称: {}, 物料ID: {}, 货主ID: {}",
r.getMaterialName(), materialBaseInfoId, shipperId);
} else {
log.warn("通过商品名称未查询到物料基础信息,商品名称: [{}], 货主ID: [{}]", r.getMaterialName(), shipperId);
}
} else if (materialBaseInfoId == null) {
log.warn("商品名称为空,跳过商品名称查询");
}
// 如果都查询不到物料基础信息阻止导入并抛出异常
if (materialBaseInfoId == null) {
// 检查是否至少有一个查询条件
boolean hasQueryCondition = StringUtils.isNotBlank(r.getMaterialCode())
|| StringUtils.isNotBlank(r.getSkuCode())
|| StringUtils.isNotBlank(r.getMaterialName());
// 构建错误信息说明物料在物料管理中不存在
StringBuilder errorMsg = new StringBuilder();
errorMsg.append("导入失败:物料在物料管理中不存在(委托编号NO=").append(h.getConsignmentNo());
errorMsg.append(",货主名称=").append(order.getShipperName());
if (StringUtils.isNotBlank(r.getMaterialCode())) {
errorMsg.append(",料号=").append(r.getMaterialCode());
}
if (StringUtils.isNotBlank(r.getSkuCode())) {
errorMsg.append("SKU码=").append(r.getSkuCode());
}
if (StringUtils.isNotBlank(r.getMaterialName())) {
errorMsg.append(",商品名称=").append(r.getMaterialName());
}
errorMsg.append("");
if (!hasQueryCondition) {
errorMsg.append("。明细行缺少物料标识信息(料号、SKU码或商品名称至少需要填写一个)");
} else {
errorMsg.append("。请确保该物料已在物料管理中创建,且料号、SKU码或商品名称与货主信息匹配");
}
log.error(errorMsg.toString());
throw new ServiceException(errorMsg.toString());
// 如果提供了料号查询不到或不属于该货主直接报错不允许导入
String errorMsg = String.format("导入失败:该货主下不存在该料号(货主名称=%s,料号=%s)。请确保该料号已在物料管理中创建,且属于该货主",
order.getShipperName(), r.getMaterialCode());
log.error(errorMsg);
throw new ServiceException(errorMsg);
}
// 数量已在前面检查过这里直接使用
@@ -99,15 +99,10 @@ public class StockReceiptOrderApplicationService {
try {
AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid());
if (associationWarehouseCacheDO != null) {
if (associationWarehouseCacheDO.getWarehouseId() != null) {
// 如果前端没有传仓库ID则使用关联仓库ID前端传了则以前端为准
if (stockReceiptOrderDO.getWarehouseId() == null && associationWarehouseCacheDO.getWarehouseId() != null) {
stockReceiptOrderDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId());
}
if (StringUtils.isNotBlank(associationWarehouseCacheDO.getWarehouseCode())) {
stockReceiptOrderDO.setWarehouseCode(associationWarehouseCacheDO.getWarehouseCode());
}
if (StringUtils.isNotBlank(associationWarehouseCacheDO.getWarehouseName())) {
stockReceiptOrderDO.setWarehouseName(associationWarehouseCacheDO.getWarehouseName());
}
}
} catch (Exception e) {
// 如果获取仓库信息失败记录日志但不影响查询允许查询所有仓库
@@ -19,9 +19,13 @@ import com.mhd.system.api.domain.StorageLocationFeignPO;
import com.mhd.system.api.domain.cache.AssociationWarehouseCacheDO;
import com.mhd.system.api.domain.cache.SystemServiceCacheUtil;
import com.mhd.system.api.model.LoginUser;
import com.mhd.wms.domain.materialBarCode.repository.facade.IMaterialBarCodeService;
import com.mhd.wms.domain.materialBarCode.repository.po.MaterialBarCodePO;
import com.mhd.wms.domain.materialBaseInfo.entity.MaterialBaseInfo;
import com.mhd.wms.domain.materialBaseInfo.repository.facade.IMaterialBaseInfoService;
import com.mhd.wms.domain.materialBaseInfo.repository.mapper.MaterialBaseInfoMapper;
import com.mhd.wms.domain.materialBaseInfo.repository.po.MaterialBaseInfoPO;
import com.mhd.system.api.domain.PackDetailFeignPO;
import com.mhd.wms.domain.materialGoodsRule.repository.facade.IMaterialGoodsRuleService;
import com.mhd.wms.domain.materialGoodsRule.repository.po.BatchDetailPO;
import com.mhd.wms.domain.materialGoodsRule.repository.po.BatchPO;
@@ -80,6 +84,10 @@ public class StockShelfOrderApplicationService {
private MaterialInventoryMapper materialInventoryMapper;
@Autowired
private IMaterialGoodsRuleService materialGoodsRuleService;
@Autowired
private IMaterialBaseInfoService materialBaseInfoService;
@Autowired
private IMaterialBarCodeService materialBarCodeService;
@@ -97,15 +105,10 @@ public class StockShelfOrderApplicationService {
try {
AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid());
if (associationWarehouseCacheDO != null) {
if (associationWarehouseCacheDO.getWarehouseId() != null) {
// 如果前端没有传仓库ID则使用关联仓库ID前端传了则以前端为准
if (stockShelfOrderDO.getWarehouseId() == null && associationWarehouseCacheDO.getWarehouseId() != null) {
stockShelfOrderDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId());
}
if (StringUtils.isNotBlank(associationWarehouseCacheDO.getWarehouseCode())) {
stockShelfOrderDO.setWarehouseCode(associationWarehouseCacheDO.getWarehouseCode());
}
if (StringUtils.isNotBlank(associationWarehouseCacheDO.getWarehouseName())) {
stockShelfOrderDO.setWarehouseName(associationWarehouseCacheDO.getWarehouseName());
}
}
} catch (Exception e) {
// 如果获取仓库信息失败记录日志但不影响查询允许查询所有仓库
@@ -179,6 +182,66 @@ public class StockShelfOrderApplicationService {
// 3. 为每个物料明细设置更多属性从缓存中获取递归处理所有层级
setMaterialMoreDetailListRecursively(shelfMaterialDetailPOList, batchDetailMap);
// 4. 批量查询物料基础信息和物料条码信息填充明细行的物料单位包装和条码
// 4.1 批量查询物料基础信息
Map<Long, MaterialBaseInfoPO> materialBaseInfoMap = new HashMap<>();
for (Long materialBaseInfoId : materialBaseInfoIdSet) {
try {
MaterialBaseInfoPO materialBaseInfoPO = materialBaseInfoService.getInfo(materialBaseInfoId);
if (materialBaseInfoPO != null) {
materialBaseInfoMap.put(materialBaseInfoId, materialBaseInfoPO);
}
} catch (Exception e) {
log.warn("获取物料基础信息失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage());
}
}
// 4.2 批量查询物料条码信息单位代码为EA的条码
Map<Long, MaterialBarCodePO> materialBarCodeMap = new HashMap<>();
for (Long materialBaseInfoId : materialBaseInfoIdSet) {
try {
List<MaterialBarCodePO> materialBarCodePOList = materialBarCodeService.getInfoByMaterialBaseInfoIds(materialBaseInfoId);
if (materialBarCodePOList != null && !materialBarCodePOList.isEmpty()) {
// 查找单位代码为EA的条码
MaterialBarCodePO eaBarCode = materialBarCodePOList.stream()
.filter(barCode -> "EA".equals(barCode.getUnitCode()))
.findFirst()
.orElse(null);
if (eaBarCode != null) {
materialBarCodeMap.put(materialBaseInfoId, eaBarCode);
}
}
} catch (Exception e) {
log.warn("获取物料条码信息失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage());
}
}
// 4.3 批量查询包装规格信息单位代码为EA的单位名称
Map<Long, PackDetailFeignPO> packDetailMap = new HashMap<>();
for (Long materialBaseInfoId : materialBaseInfoIdSet) {
MaterialBaseInfoPO materialBaseInfoPO = materialBaseInfoMap.get(materialBaseInfoId);
if (materialBaseInfoPO != null && materialBaseInfoPO.getPackId() != null) {
try {
AjaxResult packDetailResult = systemServiceFeign.getInfoByPackIdAndUnitCode(materialBaseInfoPO.getPackId(), "EA");
if (packDetailResult != null && "200".equals(String.valueOf(packDetailResult.get("code")))
&& packDetailResult.get("data") != null) {
PackDetailFeignPO packDetailFeignPO = JSON.parseObject(
JSONObject.toJSONString(packDetailResult.get("data")),
PackDetailFeignPO.class);
if (packDetailFeignPO != null) {
packDetailMap.put(materialBaseInfoId, packDetailFeignPO);
}
}
} catch (Exception e) {
log.warn("获取包装规格EA单位信息失败,物料基础信息ID:{},包装ID:{},错误:{}",
materialBaseInfoId, materialBaseInfoPO.getPackId(), e.getMessage());
}
}
}
// 4.4 为每个明细行填充物料单位包装和条码信息
fillMaterialDetailInfoRecursively(shelfMaterialDetailPOList, materialBaseInfoMap, materialBarCodeMap, packDetailMap);
stockShelfOrderPO.setMaterialDetailList(shelfMaterialDetailPOList);
log.info("返回上架单信息,shelfOrderId={}, materialDetailList大小={}",
stockShelfOrderPO.getShelfOrderId(),
@@ -645,6 +708,58 @@ public class StockShelfOrderApplicationService {
});
}
/**
* 递归填充明细行的物料单位包装和条码信息
* @param shelfMaterialDetailPOList 上架单明细列表
* @param materialBaseInfoMap 物料基础信息Mapkey: materialBaseInfoId, value: MaterialBaseInfoPO
* @param materialBarCodeMap 物料条码Mapkey: materialBaseInfoId, value: MaterialBarCodePO单位代码为EA
* @param packDetailMap 包装规格明细Mapkey: materialBaseInfoId, value: PackDetailFeignPO单位代码为EA
*/
private void fillMaterialDetailInfoRecursively(List<ShelfMaterialDetailPO> shelfMaterialDetailPOList,
Map<Long, MaterialBaseInfoPO> materialBaseInfoMap,
Map<Long, MaterialBarCodePO> materialBarCodeMap,
Map<Long, PackDetailFeignPO> packDetailMap) {
if (CollectionUtils.isEmpty(shelfMaterialDetailPOList)) {
return;
}
shelfMaterialDetailPOList.forEach(shelfMaterialDetailPO -> {
Long materialBaseInfoId = shelfMaterialDetailPO.getMaterialBaseInfoId();
if (materialBaseInfoId != null) {
// 填充包装名称从物料基础信息中获取
MaterialBaseInfoPO materialBaseInfoPO = materialBaseInfoMap.get(materialBaseInfoId);
if (materialBaseInfoPO != null) {
// 包装显示物料绑定的包装规格名称
if (StringUtils.isNotBlank(materialBaseInfoPO.getPackName())) {
shelfMaterialDetailPO.setPackName(materialBaseInfoPO.getPackName());
}
}
// 填充物料单位名称从包装规格明细中获取单位代码为EA的单位名称
PackDetailFeignPO packDetailFeignPO = packDetailMap.get(materialBaseInfoId);
if (packDetailFeignPO != null && StringUtils.isNotBlank(packDetailFeignPO.getName())) {
// 物料单位EA显示物料绑定的包装规格维护的单位代码为EA的单位名称
shelfMaterialDetailPO.setUnitName(packDetailFeignPO.getName());
shelfMaterialDetailPO.setUnitCode("EA");
}
// 填充条码从物料条码信息中获取单位代码为EA的条码
MaterialBarCodePO materialBarCodePO = materialBarCodeMap.get(materialBaseInfoId);
if (materialBarCodePO != null && StringUtils.isNotBlank(materialBarCodePO.getBarCode())) {
// 条码取物料条码信息中单位代码为EA的条码
shelfMaterialDetailPO.setBarCode(materialBarCodePO.getBarCode());
}
}
// 递归处理子明细
if (!CollectionUtils.isEmpty(shelfMaterialDetailPO.getChildren())) {
fillMaterialDetailInfoRecursively(shelfMaterialDetailPO.getChildren(),
materialBaseInfoMap, materialBarCodeMap, packDetailMap);
}
});
}
/**
* 根据批次标签batchLabels映射到字段名
* @param batchLabel 批次标签
@@ -196,20 +196,31 @@ public class HandoverTaskOrderDomainService {
MaterialInventory materialInventoryPO = materialInventoryMapper.selectById(materialInventoryId);
if (materialInventoryPO != null) {
//更新库存数量
//库存数量
BigDecimal oldInventoryQuantity = materialInventoryPO.getInventoryQuantity();
oldInventoryQuantity = oldInventoryQuantity != null ? oldInventoryQuantity : BigDecimal.ZERO;
//冻结数量
BigDecimal oldFreezeQuantity = materialInventoryPO.getFreezeQuantity();
oldFreezeQuantity = oldFreezeQuantity != null ? oldFreezeQuantity : BigDecimal.ZERO;
//分配后库存数量
BigDecimal newInventoryQuantity = oldInventoryQuantity.subtract(checkQuantity);
//分配后冻结数量
BigDecimal newFreezeQuantity = oldFreezeQuantity.subtract(checkQuantity);
BigDecimal oldArea = materialInventoryPO.getArea();
BigDecimal oldVolume = materialInventoryPO.getVolume();
BigDecimal oldGrossWeight = materialInventoryPO.getGrossWeight();
BigDecimal oldNetWeight = materialInventoryPO.getNetWeight();
// 初始化旧数据避免空指针
oldArea = oldArea != null ? oldArea : BigDecimal.ZERO;
oldVolume = oldVolume != null ? oldVolume : BigDecimal.ZERO;
oldGrossWeight = oldGrossWeight != null ? oldGrossWeight : BigDecimal.ZERO;
oldNetWeight = oldNetWeight != null ? oldNetWeight : BigDecimal.ZERO;
BigDecimal newArea = oldArea.subtract(checkArea);
BigDecimal newVolume = oldVolume.subtract(checkVolume);
BigDecimal newGrossWeight = oldGrossWeight.subtract(checkGrossWeight);
@@ -6,6 +6,8 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* 物料条码信息对象 material_bar_code
@@ -66,6 +68,10 @@ public class MaterialBarCodePO extends BaseVOEntity {
@Excel(name = "名称")
private String name;
@ApiModelProperty("数量")
@Excel(name = "数量")
private BigDecimal number;
@ApiModelProperty("备注")
@Excel(name = "备注")
private String remark;
@@ -5,6 +5,7 @@ import com.mhd.common.core.web.domain.BaseVOEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@@ -66,6 +67,10 @@ public class MaterialBarCodeDO extends BaseVOEntity {
@Excel(name = "名称")
private String name;
@ApiModelProperty("数量")
@Excel(name = "数量")
private BigDecimal number;
@ApiModelProperty("备注")
@Excel(name = "备注")
private String remark;
@@ -116,9 +116,80 @@ public class MaterialBaseInfoDomainService {
//获取库存预警
List<MaterialInventoryWarningPO> materialInventoryWarningPOList = materialInventoryWarningService.getInfoByMaterialBaseInfoIds(materialBaseInfoId);
materialBaseInfoPO.setMaterialInventoryWarningList(materialInventoryWarningPOList);
//获取条码信息
// 条码信息
// 1优先读取已维护的物料条码表 material_bar_code
// 2如果没有维护条码则根据当前物料绑定的包装规格packId
// 按包装明细的单位EA/IP/CS/PL/OT 生成一份默认的条码信息列表
// 其中条码字段留空前端可编辑
List<MaterialBarCodePO> materialBarCodePOList = materialBarCodeService.getInfoByMaterialBaseInfoIds(materialBaseInfoId);
if ((materialBarCodePOList == null || materialBarCodePOList.isEmpty()) && materialBaseInfoPO.getPackId() != null) {
try {
materialBarCodePOList = new ArrayList<>();
// 常见单位代码只生成在包装规格中实际存在的单位
String[] unitCodes = {"EA", "IP", "CS", "PL", "OT"};
for (String unitCode : unitCodes) {
AjaxResult packDetailResult = systemServiceFeign.getInfoByPackIdAndUnitCode(materialBaseInfoPO.getPackId(), unitCode);
if (!"200".equals(String.valueOf(packDetailResult.get("code")))
|| packDetailResult.get("data") == null) {
continue;
}
PackDetailFeignPO packDetailFeignPO = JSON.parseObject(
JSONObject.toJSONString(packDetailResult.get("data")),
PackDetailFeignPO.class);
// 如果包装明细没有维护名称或数量则不生成对应的条码行
if (packDetailFeignPO == null
|| packDetailFeignPO.getName() == null
|| packDetailFeignPO.getNumber() == null) {
continue;
}
MaterialBarCodePO barCodePO = new MaterialBarCodePO();
// 物料组织信息
barCodePO.setMaterialBaseInfoId(materialBaseInfoId);
barCodePO.setPackId(materialBaseInfoPO.getPackId());
barCodePO.setPackCode(materialBaseInfoPO.getPackCode());
barCodePO.setPackName(materialBaseInfoPO.getPackName());
// 绑定包装明细单位代码名称数量来自包装规格明细
barCodePO.setPackDetailId(packDetailFeignPO.getPackDetailId());
barCodePO.setUnitCode(packDetailFeignPO.getUnitCode());
barCodePO.setName(packDetailFeignPO.getName());
barCodePO.setNumber(packDetailFeignPO.getNumber());
// 条码本身留空前端允许编辑
barCodePO.setBarCode(null);
materialBarCodePOList.add(barCodePO);
}
} catch (Exception e) {
log.warn("根据包装规格生成条码信息失败,物料ID:{},包装ID:{},错误:{}",
materialBaseInfoId, materialBaseInfoPO.getPackId(), e.getMessage());
}
}
materialBaseInfoPO.setMaterialBarCodeList(materialBarCodePOList);
// 从包装规格获取默认显示的包装单位取第一条包装详情的单位名称前端只读展示
if (materialBaseInfoPO.getPackId() != null) {
try {
String[] unitCodes = {"EA", "IP", "CS", "PL", "OT"};
for (String unitCode : unitCodes) {
AjaxResult packDetailResult = systemServiceFeign.getInfoByPackIdAndUnitCode(materialBaseInfoPO.getPackId(), unitCode);
if (!"200".equals(String.valueOf(packDetailResult.get("code")))
|| packDetailResult.get("data") == null) {
continue;
}
PackDetailFeignPO packDetailFeignPO = JSON.parseObject(
JSONObject.toJSONString(packDetailResult.get("data")),
PackDetailFeignPO.class);
if (packDetailFeignPO != null && packDetailFeignPO.getName() != null) {
materialBaseInfoPO.setUnitName(packDetailFeignPO.getName());
materialBaseInfoPO.setUnitCode(packDetailFeignPO.getUnitCode());
break;
}
}
} catch (Exception e) {
log.warn("获取包装规格单位名称失败,物料ID:{},包装ID:{},错误:{}",
materialBaseInfoId, materialBaseInfoPO.getPackId(), e.getMessage());
}
}
return materialBaseInfoPO;
}
@@ -415,6 +415,11 @@ public class OutMaterialDetailImpl extends ServiceImpl<OutMaterialDetailMapper,
public synchronized void xgkc(List<OutMaterialDetail> outMaterialDetailList,String outOrderNumber,LoginUser loginUser) {
StockOutOrder stockOutOrder = stockOutOrderMapper.selectOne(new QueryWrapper<StockOutOrder>().lambda().eq(StockOutOrder::getOutOrderNumber, outOrderNumber));
for (OutMaterialDetail outMaterialDetail : outMaterialDetailList) {
BigDecimal alreadyAllocationQuantity = outMaterialDetail.getAlreadyAllocationQuantity();
// 如果已经分配数量大于0则跳过本次循环该明细已分配过不再重复处理
if (alreadyAllocationQuantity != null && alreadyAllocationQuantity.compareTo(BigDecimal.ZERO) > 0) {
continue;
}
Long materialInventoryId = outMaterialDetail.getMaterialInventoryId();
BigDecimal allocationQuantity = outMaterialDetail.getAllocationQuantity();
if (ObjectUtils.isEmpty(allocationQuantity)) {
@@ -84,6 +84,10 @@ public class PickingMaterialDetail extends BaseVOEntity {
@Excel(name = "拣货数量")
private BigDecimal pickingQuantity;
@ApiModelProperty("已拣货数量")
@Excel(name = "已拣货数量")
private BigDecimal alreadyPickingQuantity;
@ApiModelProperty("包装规格id")
@Excel(name = "包装规格id")
private Long packId;
@@ -148,7 +148,7 @@ public class PickingMaterialDetailImpl extends ServiceImpl<PickingMaterialDetail
pickingMaterialDetail.setUnitCode(pickingMaterialDetailDO.getUnitCode());
pickingMaterialDetail.setUnitName(pickingMaterialDetailDO.getUnitName());
BigDecimal actualQuantity = pickingMaterialDetailDO.getActualQuantity();
pickingMaterialDetail.setPickingQuantity(pickingMaterialDetailDb.getPickingQuantity().add(actualQuantity));
pickingMaterialDetail.setPickingQuantity(actualQuantity);
pickingMaterialDetailList.add(pickingMaterialDetail);
//判断是否开启了序列号管理
@@ -87,6 +87,10 @@ public class PickingMaterialDetailPO extends BaseVOEntity {
@Excel(name = "拣货数量")
private BigDecimal pickingQuantity;
@ApiModelProperty("已拣货数量")
@Excel(name = "已拣货数量")
private BigDecimal alreadyPickingQuantity;
@ApiModelProperty("包装规格id")
@Excel(name = "包装规格id")
private Long packId;
@@ -82,6 +82,10 @@ public class PickingMaterialDetailDO extends BaseVOEntity {
@Excel(name = "拣货数量")
private BigDecimal pickingQuantity;
@ApiModelProperty("已拣货数量")
@Excel(name = "已拣货数量")
private BigDecimal alreadyPickingQuantity;
@ApiModelProperty("包装规格id")
@Excel(name = "包装规格id")
private Long packId;
@@ -342,7 +342,8 @@ public class PickingOrderDomainService {
PickingOrder pickingOrder = new PickingOrder();
pickingOrder.setPickingOrderId(pickingOrderPODb.getPickingOrderId());
pickingOrder.setStatus(2);
pickingOrder.setPickingQuantity(pickingOrderPODb.getPickingQuantity().add(pickingOrderPO.getPickingQuantity()));
pickingOrder.setPickingQuantity(pickingOrderPO.getPickingQuantity());
//pickingOrder.setPickingQuantity(pickingOrderPODb.getPickingQuantity().add(pickingOrderPO.getPickingQuantity()));
pickingOrder.setPickingMaterialQuantity(pickingOrderPODb.getPickingMaterialQuantity() + pickingOrderPO.getPickingMaterialQuantity());
pickingOrder.setUpdateBy(loginUser.getUserid());
pickingOrder.setUpdateByName(loginUser.getUsername());
@@ -372,7 +373,7 @@ public class PickingOrderDomainService {
.eq(PickingOrder::getOrderNumber, pickingOrderPODb.getOrderNumber()));
BigDecimal pickingQuantity = pickingOrderList.stream().map(PickingOrder::getPickingQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
if (1 == pickingOrderPODb.getType()){
int status = 6;
int status = 7;
//不需要复核的单子 标记出库单完成
StockOutOrder stockOutOrderDb = stockOutOrderService.getOne(new QueryWrapper<StockOutOrder>().lambda()
.eq(StockOutOrder::getOutOrderNumber, pickingOrderPODb.getOrderNumber()));
@@ -149,10 +149,31 @@ public class StockInOrderPO extends BaseVOEntity {
@Excel(name = "物料种数")
private Integer materialQuantity;
@ApiModelProperty("计划数量")
@Excel(name = "计划数量")
@ApiModelProperty("计划数量(原字段)")
@Excel(name = "计划数量(原字段)")
private BigDecimal quantity;
/**
* 计划入库数量取入库单明细中的入库数量汇总
*/
@ApiModelProperty("计划入库数量")
@Excel(name = "计划入库数量")
private BigDecimal planInQuantity;
/**
* 收货数量入库单对应的收货单实际收货数量汇总
*/
@ApiModelProperty("收货数量")
@Excel(name = "收货数量")
private BigDecimal receiptQuantity;
/**
* 上架数量入库单对应的上架单实际上架数量汇总
*/
@ApiModelProperty("上架数量")
@Excel(name = "上架数量")
private BigDecimal shelvesQuantity;
@ApiModelProperty("净重 单位:千克")
@Excel(name = "净重 单位:千克")
private BigDecimal weightLimit;
@@ -26,7 +26,12 @@ import com.mhd.wms.domain.materialWarehouseControl.repository.facade.IMaterialWa
import com.mhd.wms.domain.materialWarehouseControl.repository.po.MaterialWarehouseControlPO;
import com.mhd.wms.domain.qualityInspection.repository.facade.IQualityInspectionService;
import com.mhd.wms.domain.qualityInspection.repository.todo.QualityInspectionDO;
import com.mhd.wms.domain.receiptMaterialDetail.repository.facade.IReceiptMaterialDetailService;
import com.mhd.wms.domain.receiptMaterialDetail.repository.po.ReceiptMaterialDetailPO;
import com.mhd.wms.domain.receiptMaterialDetail.repository.todo.ReceiptMaterialDetailDO;
import com.mhd.wms.domain.shelfMaterialDetail.repository.facade.IShelfMaterialDetailService;
import com.mhd.wms.domain.shelfMaterialDetail.repository.po.ShelfMaterialDetailPO;
import com.mhd.wms.domain.shelfMaterialDetail.repository.todo.ShelfMaterialDetailDO;
import com.mhd.wms.domain.stockInOrder.entity.StockInOrder;
import com.mhd.wms.domain.stockInOrder.repository.facade.IStockInOrderService;
import com.mhd.wms.domain.stockInOrder.repository.po.StockInOrderPO;
@@ -34,6 +39,9 @@ import com.mhd.wms.domain.stockInOrder.repository.todo.StockInOrderDO;
import com.mhd.wms.domain.stockReceiptOrder.repository.po.StockReceiptOrderPO;
import com.mhd.wms.domain.stockReceiptOrder.repository.todo.StockReceiptOrderDO;
import com.mhd.wms.domain.stockReceiptOrder.service.StockReceiptOrderDomainService;
import com.mhd.wms.domain.stockShelfOrder.repository.po.StockShelfOrderPO;
import com.mhd.wms.domain.stockShelfOrder.repository.todo.StockShelfOrderDO;
import com.mhd.wms.domain.stockShelfOrder.service.StockShelfOrderDomainService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -62,6 +70,8 @@ public class StockInOrderDomainService {
@Autowired
private StockReceiptOrderDomainService stockReceiptOrderDomainService;
@Autowired
private StockShelfOrderDomainService stockShelfOrderDomainService;
@Autowired
private IQualityInspectionService qualityInspectionService;
@Autowired
private IMaterialBaseInfoService materialBaseInfoService;
@@ -71,6 +81,10 @@ public class StockInOrderDomainService {
private IMaterialWarehouseControlService materialWarehouseControlService;
@Autowired
private SystemServiceFeign systemServiceFeign;
@Autowired
private IReceiptMaterialDetailService receiptMaterialDetailService;
@Autowired
private IShelfMaterialDetailService shelfMaterialDetailService;
/**
* 分页查询入库单列表
@@ -180,10 +194,161 @@ public class StockInOrderDomainService {
inMaterialDetailDO.setInOrderNumber(stockInOrderPO.getInOrderNumber());
inMaterialDetailDO.setLevel(1);
List<InMaterialDetailPO> inMaterialDetailPOList = materialDetailService.queryList(inMaterialDetailDO);
// 先通过入库单号查询收货单列表
StockReceiptOrderDO stockReceiptOrderDO = new StockReceiptOrderDO();
stockReceiptOrderDO.setInOrderNumber(stockInOrderPO.getInOrderNumber());
List<StockReceiptOrderPO> stockReceiptOrderPOList = stockReceiptOrderDomainService.queryList(stockReceiptOrderDO);
// 先通过入库单号查询上架单列表
StockShelfOrderDO stockShelfOrderDO = new StockShelfOrderDO();
stockShelfOrderDO.setInOrderNumber(stockInOrderPO.getInOrderNumber());
List<StockShelfOrderPO> stockShelfOrderPOList = stockShelfOrderDomainService.queryList(stockShelfOrderDO);
// 查询收货单明细用于填充收货数量和更新毛重净重面积体积
List<ReceiptMaterialDetailPO> receiptMaterialDetailPOList = new ArrayList<>();
if (!CollectionUtils.isEmpty(stockReceiptOrderPOList)) {
List<String> receiptOrderNumberList = stockReceiptOrderPOList.stream()
.map(StockReceiptOrderPO::getReceiptOrderNumber)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toList());
if (!CollectionUtils.isEmpty(receiptOrderNumberList)) {
ReceiptMaterialDetailDO receiptMaterialDetailDO = new ReceiptMaterialDetailDO();
receiptMaterialDetailDO.setReceiptOrderNumberList(receiptOrderNumberList);
receiptMaterialDetailPOList = receiptMaterialDetailService.queryList(receiptMaterialDetailDO);
}
}
// 查询上架单明细用于填充上架数量
List<ShelfMaterialDetailPO> shelfMaterialDetailPOList = new ArrayList<>();
if (!CollectionUtils.isEmpty(stockShelfOrderPOList)) {
for (StockShelfOrderPO stockShelfOrderPO : stockShelfOrderPOList) {
if (StringUtils.isNotBlank(stockShelfOrderPO.getShelfOrderNumber())) {
ShelfMaterialDetailDO shelfMaterialDetailDO = new ShelfMaterialDetailDO();
shelfMaterialDetailDO.setShelfOrderNumber(stockShelfOrderPO.getShelfOrderNumber());
List<ShelfMaterialDetailPO> shelfDetails = shelfMaterialDetailService.queryList(shelfMaterialDetailDO);
if (!CollectionUtils.isEmpty(shelfDetails)) {
shelfMaterialDetailPOList.addAll(shelfDetails);
}
}
}
}
// materialDetailId 分组汇总收货数量和上架数量以及更新毛重净重面积体积
if (!CollectionUtils.isEmpty(inMaterialDetailPOList)) {
// materialDetailId 分组汇总收货数量实际收货数量毛重净重面积体积
// 收货数量入库单对应的收货单实际收货数量汇总
Map<Long, ReceiptMaterialDetailPO> receiptDetailMap = new HashMap<>();
if (!CollectionUtils.isEmpty(receiptMaterialDetailPOList)) {
// 递归处理所有层级的收货单明细包括子明细
for (ReceiptMaterialDetailPO receiptDetail : receiptMaterialDetailPOList) {
processReceiptDetail(receiptDetail, receiptDetailMap);
}
}
// materialDetailId 分组汇总上架数量实际上架数量
// 上架数量入库单对应的上架单实际上架数量汇总
Map<Long, BigDecimal> shelfQuantityMap = new HashMap<>();
if (!CollectionUtils.isEmpty(shelfMaterialDetailPOList)) {
for (ShelfMaterialDetailPO shelfDetail : shelfMaterialDetailPOList) {
if (shelfDetail.getMaterialDetailId() != null && shelfDetail.getShelvesQuantity() != null) {
Long materialDetailId = shelfDetail.getMaterialDetailId();
BigDecimal shelvesQuantity = shelfQuantityMap.getOrDefault(materialDetailId, BigDecimal.ZERO);
shelfQuantityMap.put(materialDetailId, shelvesQuantity.add(shelfDetail.getShelvesQuantity()));
}
}
}
// 填充入库单明细的收货数量上架数量以及更新毛重净重面积体积
for (InMaterialDetailPO inMaterialDetail : inMaterialDetailPOList) {
Long materialDetailId = inMaterialDetail.getMaterialDetailId();
if (materialDetailId != null) {
// 填充收货数量入库单对应的收货单实际收货数量
ReceiptMaterialDetailPO receiptDetail = receiptDetailMap.get(materialDetailId);
if (receiptDetail != null) {
// 更新收货数量
if (receiptDetail.getReceiptQuantity() != null) {
inMaterialDetail.setReceiptQuantity(receiptDetail.getReceiptQuantity());
}
// 更新毛重净重面积体积根据收货时所填的明细行数据更新到入库单明细中
// 将收货单明细中填写的数据汇总后更新到入库单明细
if (receiptDetail.getTotalGrossWeight() != null) {
inMaterialDetail.setTotalGrossWeight(receiptDetail.getTotalGrossWeight());
}
if (receiptDetail.getTotalNetWeight() != null) {
inMaterialDetail.setTotalNetWeight(receiptDetail.getTotalNetWeight());
}
if (receiptDetail.getTotalArea() != null) {
inMaterialDetail.setTotalArea(receiptDetail.getTotalArea());
}
if (receiptDetail.getTotalVolume() != null) {
inMaterialDetail.setTotalVolume(receiptDetail.getTotalVolume());
}
}
// 填充上架数量入库单对应的上架单实际上架数量
BigDecimal shelvesQuantity = shelfQuantityMap.get(materialDetailId);
if (shelvesQuantity != null) {
inMaterialDetail.setShelvesQuantity(shelvesQuantity);
}
}
}
}
stockInOrderPO.setMaterialDetailList(inMaterialDetailPOList);
return stockInOrderPO;
}
/**
* 递归处理收货单明细汇总毛重净重面积体积
* @param receiptDetail 收货单明细
* @param receiptDetailMap 收货单明细汇总Map
*/
private void processReceiptDetail(ReceiptMaterialDetailPO receiptDetail, Map<Long, ReceiptMaterialDetailPO> receiptDetailMap) {
if (receiptDetail == null || receiptDetail.getMaterialDetailId() == null) {
return;
}
Long materialDetailId = receiptDetail.getMaterialDetailId();
ReceiptMaterialDetailPO existing = receiptDetailMap.get(materialDetailId);
if (existing == null) {
// 如果不存在直接放入Map
receiptDetailMap.put(materialDetailId, receiptDetail);
} else {
// 如果已存在汇总收货数量毛重净重面积体积
// 汇总收货数量实际收货数量
BigDecimal receiptQuantity = existing.getReceiptQuantity() != null ? existing.getReceiptQuantity() : BigDecimal.ZERO;
BigDecimal newReceiptQuantity = receiptDetail.getReceiptQuantity() != null ? receiptDetail.getReceiptQuantity() : BigDecimal.ZERO;
existing.setReceiptQuantity(receiptQuantity.add(newReceiptQuantity));
// 汇总毛重净重面积体积根据收货时填写的数据
// 累加所有收货单明细的毛重净重面积体积
BigDecimal existingGrossWeight = existing.getTotalGrossWeight() != null ? existing.getTotalGrossWeight() : BigDecimal.ZERO;
BigDecimal newGrossWeight = receiptDetail.getTotalGrossWeight() != null ? receiptDetail.getTotalGrossWeight() : BigDecimal.ZERO;
existing.setTotalGrossWeight(existingGrossWeight.add(newGrossWeight));
BigDecimal existingNetWeight = existing.getTotalNetWeight() != null ? existing.getTotalNetWeight() : BigDecimal.ZERO;
BigDecimal newNetWeight = receiptDetail.getTotalNetWeight() != null ? receiptDetail.getTotalNetWeight() : BigDecimal.ZERO;
existing.setTotalNetWeight(existingNetWeight.add(newNetWeight));
BigDecimal existingArea = existing.getTotalArea() != null ? existing.getTotalArea() : BigDecimal.ZERO;
BigDecimal newArea = receiptDetail.getTotalArea() != null ? receiptDetail.getTotalArea() : BigDecimal.ZERO;
existing.setTotalArea(existingArea.add(newArea));
BigDecimal existingVolume = existing.getTotalVolume() != null ? existing.getTotalVolume() : BigDecimal.ZERO;
BigDecimal newVolume = receiptDetail.getTotalVolume() != null ? receiptDetail.getTotalVolume() : BigDecimal.ZERO;
existing.setTotalVolume(existingVolume.add(newVolume));
}
// 递归处理子明细
if (!CollectionUtils.isEmpty(receiptDetail.getChildren())) {
for (ReceiptMaterialDetailPO child : receiptDetail.getChildren()) {
processReceiptDetail(child, receiptDetailMap);
}
}
}
/**
* @description 审核入库单
@@ -11,6 +11,7 @@ import com.mhd.common.core.constant.SnowFlakeConstants;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.utils.IgnoreNullUtil;
import com.mhd.common.core.utils.OrderSequence;
import com.mhd.common.core.utils.StringUtils;
import com.mhd.common.core.utils.bean.BeanUtils;
import com.mhd.common.core.utils.uuid.IdGenerator;
import com.mhd.common.core.web.domain.AjaxResult;
@@ -23,6 +24,7 @@ import com.mhd.wms.domain.containerUsageRecord.repository.facade.IContainerUsage
import com.mhd.wms.domain.containerUsageRecord.repository.todo.ContainerUsageRecordDO;
import com.mhd.wms.domain.deliveTask.repository.facade.IDeliveTaskService;
import com.mhd.wms.domain.deliveTask.repository.todo.DeliveTaskDO;
import com.mhd.wms.domain.inMaterialDetail.entity.InMaterialDetail;
import com.mhd.wms.domain.inMaterialDetail.repository.facade.IInMaterialDetailService;
import com.mhd.wms.domain.inMaterialDetail.repository.po.InMaterialDetailPO;
import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.facade.IInMaterialDetailSerialNumberService;
@@ -330,7 +332,10 @@ public class StockReceiptOrderDomainService {
public Boolean taskDistribution(StockReceiptOrderDO stockReceiptOrderDO) {
LoginUser loginUser = SecurityUtils.getLoginUser();
StockReceiptOrderDO stockReceiptOrderDOQuery = new StockReceiptOrderDO();
stockReceiptOrderDOQuery.setReceiptOrderIds(stockReceiptOrderDO.getReceiptOrderIds());
List<Long> receiptOrderIds = stockReceiptOrderDO.getReceiptOrderIds();
if (receiptOrderIds == null || receiptOrderIds.size() == 0) {
throw new ServiceException("未选择收货单,或收货单不存在");
}
stockReceiptOrderDOQuery.setTaskDistribution(2);
List<StockReceiptOrderPO> stockReceiptOrderPOList = stockReceiptOrderService.queryList(stockReceiptOrderDOQuery);
if (CollectionUtils.isEmpty(stockReceiptOrderPOList)) {
@@ -387,6 +392,8 @@ public class StockReceiptOrderDomainService {
genInventoryStandingReport(stockReceiptOrderPO, stockReceiptOrderDO);
//修改物料明细信息
receiptMaterialDetailService.batchReceiptUpdate(stockReceiptOrderDO);
//同步更新入库单明细的收货数量总毛重总净重总面积总体积
syncUpdateInMaterialDetailFromReceipt(stockReceiptOrderDO, stockReceiptOrderPO);
//生成 收货作业单
genStockReceiptTaskOrderByReceivingGoods(stockReceiptOrderPO,stockReceiptOrderDO);
//收货后上架前 生成质检
@@ -399,6 +406,197 @@ public class StockReceiptOrderDomainService {
}
/**
* 同步更新入库单明细的收货数量总毛重总净重总面积总体积
* 根据收货单明细中填写的数据按materialDetailId分组汇总后更新到入库单明细
* @param stockReceiptOrderDO 收货单DO
* @param stockReceiptOrderPO 收货单PO可选如果为null则从DO中获取
*/
private void syncUpdateInMaterialDetailFromReceipt(StockReceiptOrderDO stockReceiptOrderDO, StockReceiptOrderPO stockReceiptOrderPO) {
if (stockReceiptOrderDO == null || StringUtils.isBlank(stockReceiptOrderDO.getReceiptOrderNumber())) {
return;
}
// 获取入库单号
String inOrderNumber = stockReceiptOrderDO.getInOrderNumber();
if (StringUtils.isBlank(inOrderNumber) && stockReceiptOrderPO != null) {
inOrderNumber = stockReceiptOrderPO.getInOrderNumber();
}
if (StringUtils.isBlank(inOrderNumber) && stockReceiptOrderDO.getReceiptOrderId() != null) {
// 如果收货单DO中没有入库单号从收货单PO中获取
StockReceiptOrderPO receiptOrderPO = stockReceiptOrderService.getInfo(stockReceiptOrderDO.getReceiptOrderId());
if (receiptOrderPO != null) {
inOrderNumber = receiptOrderPO.getInOrderNumber();
}
}
if (StringUtils.isBlank(inOrderNumber)) {
log.warn("收货单【{}】没有关联的入库单号,无法同步更新入库单明细", stockReceiptOrderDO.getReceiptOrderNumber());
return;
}
log.info("开始同步更新入库单【{}】的明细,收货单号:{}", inOrderNumber, stockReceiptOrderDO.getReceiptOrderNumber());
// 查询该入库单对应的所有收货单
StockReceiptOrderDO queryReceiptOrderDO = new StockReceiptOrderDO();
queryReceiptOrderDO.setInOrderNumber(inOrderNumber);
List<StockReceiptOrderPO> receiptOrderPOList = stockReceiptOrderService.queryList(queryReceiptOrderDO);
if (CollectionUtils.isEmpty(receiptOrderPOList)) {
return;
}
// 获取所有收货单号
List<String> receiptOrderNumberList = receiptOrderPOList.stream()
.map(StockReceiptOrderPO::getReceiptOrderNumber)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(receiptOrderNumberList)) {
return;
}
// 从数据库查询该入库单对应的所有收货单明细包括已更新的数据
ReceiptMaterialDetailDO receiptMaterialDetailDO = new ReceiptMaterialDetailDO();
receiptMaterialDetailDO.setReceiptOrderNumberList(receiptOrderNumberList);
List<ReceiptMaterialDetailPO> receiptMaterialDetailPOList = receiptMaterialDetailService.queryList(receiptMaterialDetailDO);
if (CollectionUtils.isEmpty(receiptMaterialDetailPOList)) {
return;
}
// 按unique_id入库单明细的唯一标识分组汇总收货数量总毛重总净重总面积总体积
// 注意收货单明细的material_detail_id和入库单明细的material_detail_id是不同的
// 需要通过in_unique_id收货单明细关联到unique_id入库单明细
Map<Long, Map<String, BigDecimal>> uniqueIdSummaryMap = new HashMap<>();
// 递归处理所有层级的收货单明细
for (ReceiptMaterialDetailPO receiptDetail : receiptMaterialDetailPOList) {
processReceiptDetailPOForSync(receiptDetail, uniqueIdSummaryMap);
}
// 批量更新入库单明细
if (!uniqueIdSummaryMap.isEmpty()) {
LoginUser loginUser = SecurityUtils.getLoginUser();
Date updateTime = new Date();
log.info("开始同步更新入库单【{}】的明细,共{}个明细需要更新", inOrderNumber, uniqueIdSummaryMap.size());
for (Map.Entry<Long, Map<String, BigDecimal>> entry : uniqueIdSummaryMap.entrySet()) {
Long uniqueId = entry.getKey(); // 这是入库单明细的unique_id
Map<String, BigDecimal> summary = entry.getValue();
UpdateWrapper<InMaterialDetail> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("unique_id", uniqueId);
updateWrapper.eq("in_order_number", inOrderNumber);
updateWrapper.eq("del_flag", 1);
boolean hasUpdate = false;
// 更新收货数量
if (summary.containsKey("receiptQuantity") && summary.get("receiptQuantity") != null) {
updateWrapper.set("receipt_quantity", summary.get("receiptQuantity"));
hasUpdate = true;
}
// 更新总毛重
if (summary.containsKey("totalGrossWeight") && summary.get("totalGrossWeight") != null) {
updateWrapper.set("total_gross_weight", summary.get("totalGrossWeight"));
hasUpdate = true;
}
// 更新总净重
if (summary.containsKey("totalNetWeight") && summary.get("totalNetWeight") != null) {
updateWrapper.set("total_net_weight", summary.get("totalNetWeight"));
hasUpdate = true;
}
// 更新总面积
if (summary.containsKey("totalArea") && summary.get("totalArea") != null) {
updateWrapper.set("total_area", summary.get("totalArea"));
hasUpdate = true;
}
// 更新总体积
if (summary.containsKey("totalVolume") && summary.get("totalVolume") != null) {
updateWrapper.set("total_volume", summary.get("totalVolume"));
hasUpdate = true;
}
if (hasUpdate) {
updateWrapper.set("update_by", loginUser.getUserid());
updateWrapper.set("update_by_name", loginUser.getUsername());
updateWrapper.set("update_time", updateTime);
boolean updateResult = iInMaterialDetailService.update(updateWrapper);
if (updateResult) {
log.info("成功更新入库单明细,uniqueId: {}, 收货数量: {}, 总毛重: {}, 总净重: {}, 总面积: {}, 总体积: {}",
uniqueId,
summary.get("receiptQuantity"),
summary.get("totalGrossWeight"),
summary.get("totalNetWeight"),
summary.get("totalArea"),
summary.get("totalVolume"));
} else {
log.warn("更新入库单明细失败,uniqueId: {}, inOrderNumber: {}", uniqueId, inOrderNumber);
}
} else {
log.debug("入库单明细无需更新,uniqueId: {}", uniqueId);
}
}
log.info("完成同步更新入库单【{}】的明细", inOrderNumber);
} else {
log.warn("入库单【{}】没有需要更新的明细数据", inOrderNumber);
}
}
/**
* 递归处理收货单明细汇总收货数量总毛重总净重总面积总体积
* @param receiptDetail 收货单明细PO
* @param uniqueIdSummaryMap 汇总Mapkey为入库单明细的unique_id即收货单明细的in_unique_idvalue为字段汇总Map
*/
private void processReceiptDetailPOForSync(ReceiptMaterialDetailPO receiptDetail,
Map<Long, Map<String, BigDecimal>> uniqueIdSummaryMap) {
if (receiptDetail == null || receiptDetail.getInUniqueId() == null) {
return;
}
// 使用in_unique_id作为key因为这是关联到入库单明细的unique_id
Long uniqueId = receiptDetail.getInUniqueId();
Map<String, BigDecimal> summary = uniqueIdSummaryMap.computeIfAbsent(uniqueId, k -> new HashMap<>());
// 汇总收货数量
BigDecimal receiptQuantity = summary.getOrDefault("receiptQuantity", BigDecimal.ZERO);
BigDecimal newReceiptQuantity = receiptDetail.getReceiptQuantity() != null ? receiptDetail.getReceiptQuantity() : BigDecimal.ZERO;
summary.put("receiptQuantity", receiptQuantity.add(newReceiptQuantity));
// 汇总总毛重
BigDecimal totalGrossWeight = summary.getOrDefault("totalGrossWeight", BigDecimal.ZERO);
BigDecimal newGrossWeight = receiptDetail.getTotalGrossWeight() != null ? receiptDetail.getTotalGrossWeight() : BigDecimal.ZERO;
summary.put("totalGrossWeight", totalGrossWeight.add(newGrossWeight));
// 汇总总净重
BigDecimal totalNetWeight = summary.getOrDefault("totalNetWeight", BigDecimal.ZERO);
BigDecimal newNetWeight = receiptDetail.getTotalNetWeight() != null ? receiptDetail.getTotalNetWeight() : BigDecimal.ZERO;
summary.put("totalNetWeight", totalNetWeight.add(newNetWeight));
// 汇总总面积
BigDecimal totalArea = summary.getOrDefault("totalArea", BigDecimal.ZERO);
BigDecimal newArea = receiptDetail.getTotalArea() != null ? receiptDetail.getTotalArea() : BigDecimal.ZERO;
summary.put("totalArea", totalArea.add(newArea));
// 汇总总体积
BigDecimal totalVolume = summary.getOrDefault("totalVolume", BigDecimal.ZERO);
BigDecimal newVolume = receiptDetail.getTotalVolume() != null ? receiptDetail.getTotalVolume() : BigDecimal.ZERO;
summary.put("totalVolume", totalVolume.add(newVolume));
// 递归处理子明细
if (!CollectionUtils.isEmpty(receiptDetail.getChildren())) {
for (ReceiptMaterialDetailPO child : receiptDetail.getChildren()) {
processReceiptDetailPOForSync(child, uniqueIdSummaryMap);
}
}
}
/**
* @param stockReceiptOrderDO
* @return StockReceiptOrder
@@ -471,6 +669,19 @@ public class StockReceiptOrderDomainService {
//根据收货数量生成上架
genStockShelfOrder(stockReceiptOrderPO);
//生成上架单后更新入库单状态为4上架中
if (StringUtils.isNotBlank(stockReceiptOrderPO.getInOrderNumber())) {
StockInOrder stockInOrder = new StockInOrder();
stockInOrder.setInOrderNumber(stockReceiptOrderPO.getInOrderNumber());
stockInOrder.setStatus(4); // 4-上架中
stockInOrder.setUpdateBy(loginUser.getUserid());
stockInOrder.setUpdateByName(loginUser.getUsername());
stockInOrder.setUpdateTime(new Date());
stockInOrderService.update(stockInOrder,
new QueryWrapper<StockInOrder>().lambda()
.eq(StockInOrder::getInOrderNumber, stockReceiptOrderPO.getInOrderNumber()));
}
//收货完成后自动生成上架任务
try {
//查询刚生成的上架单
@@ -22,6 +22,8 @@ import com.mhd.wms.domain.containerUsageRecord.repository.facade.IContainerUsage
import com.mhd.wms.domain.containerUsageRecord.repository.todo.ContainerUsageRecordDO;
import com.mhd.wms.domain.deliveTask.repository.facade.IDeliveTaskService;
import com.mhd.wms.domain.deliveTask.repository.todo.DeliveTaskDO;
import com.mhd.wms.domain.inMaterialDetail.entity.InMaterialDetail;
import com.mhd.wms.domain.inMaterialDetail.repository.facade.IInMaterialDetailService;
import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.facade.IInMaterialDetailSerialNumberService;
import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.po.InMaterialDetailSerialNumberPO;
import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.todo.InMaterialDetailSerialNumberDO;
@@ -93,6 +95,8 @@ public class StockShelfOrderDomainService {
@Autowired
private IMaterialBaseInfoService materialBaseInfoService;
@Autowired
private IInMaterialDetailService inMaterialDetailService;
@Autowired
private IInMaterialDetailSerialNumberService inMaterialDetailSerialNumberService;
@Autowired
private IStockInTaskOrderService stockInTaskOrderService;
@@ -299,6 +303,8 @@ public class StockShelfOrderDomainService {
genContainerUsageRecord(stockShelfOrderDO);
//修改物料明细信息
shelfMaterialDetailService.batchShelfUpdate(stockShelfOrderDO);
//同步更新入库单明细的上架数量/上架状态
syncShelvesQuantityToInMaterialDetail(stockShelfOrderDO);
//生成 上架作业单
genStockShelfTaskOrderByUpShelf(stockShelfOrderDO);
//修改入库单状态: 1-已创建 2-已审核 3-收货中 4-上架中 5-已入库
@@ -309,6 +315,90 @@ public class StockShelfOrderDomainService {
return updateStockShelfOrder(stockShelfOrderDO, stockShelfOrderPO);
}
/**
* @description 上架数量同步更新到入库单明细中累计值
* @author Auto
* @date 2026/2/11
*/
private void syncShelvesQuantityToInMaterialDetail(StockShelfOrderDO stockShelfOrderDO) {
List<ShelfMaterialDetailDO> detailDOList = stockShelfOrderDO.getMaterialDetailList();
if (CollectionUtils.isEmpty(detailDOList)) {
return;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
// 收集所有需要同步的入库单明细 uniqueIdinUniqueId
Set<Long> inUniqueIdSet = new HashSet<>();
for (ShelfMaterialDetailDO d : detailDOList) {
// 只处理一级明细子级是拆分库位的记录不作为入库单明细的累计口径
if (d.getLevel() != null && d.getLevel() == 2) {
continue;
}
if (d.getInUniqueId() != null) {
inUniqueIdSet.add(d.getInUniqueId());
}
}
if (inUniqueIdSet.isEmpty()) {
return;
}
// 从数据库查询所有相关的上架明细 inUniqueId 汇总本次上架数量shelvesQuantity
// 这样可以确保即使一个入库单明细对应多个上架明细多次上架也能正确同步
Map<Long, BigDecimal> shelvesQuantityMap = new HashMap<>();
Map<Long, Integer> shelvesStatusMap = new HashMap<>();
for (Long inUniqueId : inUniqueIdSet) {
ShelfMaterialDetailDO queryDO = new ShelfMaterialDetailDO();
queryDO.setInUniqueId(inUniqueId);
queryDO.setLevel(1); // 只查询一级明细
List<ShelfMaterialDetailPO> shelfDetailPOList = shelfMaterialDetailService.queryList(queryDO);
if (!CollectionUtils.isEmpty(shelfDetailPOList)) {
BigDecimal totalShelvesQty = BigDecimal.ZERO;
Integer maxShelvesStatus = null;
for (ShelfMaterialDetailPO po : shelfDetailPOList) {
// 汇总本次上架数量shelvesQuantity
BigDecimal shelvesQty = po.getShelvesQuantity();
if (shelvesQty != null && shelvesQty.compareTo(BigDecimal.ZERO) > 0) {
totalShelvesQty = totalShelvesQty.add(shelvesQty);
}
// 取最大的上架状态3-已上架 > 2-上架中 > 1-待上架
Integer status = po.getShelvesStatus();
if (status != null) {
if (maxShelvesStatus == null || status > maxShelvesStatus) {
maxShelvesStatus = status;
}
}
}
shelvesQuantityMap.put(inUniqueId, totalShelvesQty);
if (maxShelvesStatus != null) {
shelvesStatusMap.put(inUniqueId, maxShelvesStatus);
}
}
}
// 更新入库单明细的上架数量和上架状态
Date now = new Date();
for (Long inUniqueId : inUniqueIdSet) {
BigDecimal shelvesQty = shelvesQuantityMap.getOrDefault(inUniqueId, BigDecimal.ZERO);
Integer shelvesStatus = shelvesStatusMap.get(inUniqueId);
// 仅更新与上架相关字段
inMaterialDetailService.update(null, new UpdateWrapper<InMaterialDetail>().lambda()
.set(InMaterialDetail::getShelvesQuantity, shelvesQty)
.set(shelvesStatus != null, InMaterialDetail::getShelvesStatus, shelvesStatus)
.set(InMaterialDetail::getUpdateBy, loginUser.getUserid())
.set(InMaterialDetail::getUpdateByName, loginUser.getUsername())
.set(InMaterialDetail::getUpdateTime, now)
.eq(InMaterialDetail::getUniqueId, inUniqueId)
.eq(StringUtils.isNotBlank(stockShelfOrderDO.getInOrderNumber()), InMaterialDetail::getInOrderNumber, stockShelfOrderDO.getInOrderNumber())
);
}
}
/**
* @description 设置上架单上架需要更新的数据数据
* @author ZhouGY
@@ -541,10 +631,14 @@ public class StockShelfOrderDomainService {
BigDecimal shelvesQuantity = shelfMaterialDetail.getShelvesQuantity();
shelvesQuantity = shelvesQuantity != null ? shelvesQuantity : BigDecimal.ZERO;
MaterialInventoryPO materialInventoryPO = materialInventoryPOS.get(0);
BigDecimal newInventoryQuantity = materialInventoryPO.getInventoryQuantity().add(shelvesQuantity);
BigDecimal oldInventoryQuantity = materialInventoryPO.getInventoryQuantity();
BigDecimal newAllocationQuantity = materialInventoryPO.getAllocationQuantity().add(shelvesQuantity);
oldInventoryQuantity = oldInventoryQuantity != null ? oldInventoryQuantity : BigDecimal.ZERO;
BigDecimal newInventoryQuantity = oldInventoryQuantity.add(shelvesQuantity);
BigDecimal oldAllocationQuantity = materialInventoryPO.getAllocationQuantity();
oldAllocationQuantity = oldAllocationQuantity != null ? oldAllocationQuantity : BigDecimal.ZERO;
BigDecimal newAllocationQuantity = oldAllocationQuantity.add(shelvesQuantity);
BigDecimal oldArea = materialInventoryPO.getArea();
oldArea = oldArea != null ? oldArea : BigDecimal.ZERO;
@@ -5,6 +5,7 @@ import com.mhd.common.core.web.domain.BaseVOEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
/**
@@ -65,6 +66,10 @@ public class MaterialBarCodeDTO extends BaseVOEntity {
@Excel(name = "名称")
private String name;
@ApiModelProperty("数量")
@Excel(name = "数量")
private BigDecimal number;
@ApiModelProperty("备注")
@Excel(name = "备注")
private String remark;
@@ -313,4 +313,20 @@ public class ShelfMaterialDetailDTO extends BaseVOEntity {
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "ExtAttr4", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date extAttr4;
@ApiModelProperty("总净重(KG)")
@Excel(name = "总净重(KG)")
private BigDecimal totalNetWeight;
@ApiModelProperty("总毛重(KG)")
@Excel(name = "总毛重(KG)")
private BigDecimal totalGrossWeight;
@ApiModelProperty("总体积(CBM)")
@Excel(name = "总体积(CBM)")
private BigDecimal totalVolume;
@ApiModelProperty("总面积(SQM)")
@Excel(name = "总面积(SQM)")
private BigDecimal totalArea;
}
@@ -1,8 +1,14 @@
package com.mhd.wms.interfaces.facadeApi.materialInventory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.mhd.common.core.domain.po.UserPo;
import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.utils.StringUtils;
import com.mhd.common.core.web.controller.BaseController;
import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.core.web.page.TableDataInfo;
import com.mhd.system.api.UserServiceFeign;
import com.mhd.wms.application.service.materialInventory.MaterialInventoryApplicationService;
import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO;
import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryQueryListPO;
@@ -12,6 +18,7 @@ import com.mhd.wms.interfaces.assember.materialInventory.MaterialInventoryAssemb
import com.mhd.wms.interfaces.dto.materialInventory.MaterialInventoryDTO;
import com.mhd.wms.interfaces.dto.materialInventory.MaterialInventoryQueryListDTO;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@@ -26,6 +33,7 @@ import java.util.List;
*/
@RestController
@RequestMapping("/materialInventoryApi")
@Slf4j
public class MaterialInventoryApi extends BaseController {
@Autowired
private MaterialInventoryApplicationService materialInventoryApplicationService;
@@ -33,19 +41,77 @@ public class MaterialInventoryApi extends BaseController {
@Resource
private MaterialInventoryAssembler materialInventoryAssembler;
@Autowired
private UserServiceFeign userServiceFeign;
/**
* 分页查询物料库存列表
*/
@ApiOperation("查询物料库存列表")
@GetMapping("/list")
public TableDataInfo list(MaterialInventoryDTO materialInventoryDTO)
public TableDataInfo list(MaterialInventoryDTO materialInventoryDTO,
@RequestParam(value = "customerName", required = false) String customerName)
{
// 出库分配前端传的是客户名称 customerName这里通过名称查询货主ID使用精确匹配不模糊匹配
String shipperName = null; // 保存查询到的货主名称
if (StringUtils.isNotBlank(customerName) && materialInventoryDTO.getShipperId() == null) {
try {
AjaxResult ajaxResult = userServiceFeign.getInfoByName(customerName);
if ("200".equals(String.valueOf(ajaxResult.get("code"))) && ajaxResult.get("data") != null) {
UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class);
if (userPo != null && userPo.getUserId() != null) {
materialInventoryDTO.setShipperId(userPo.getUserId());
// 获取货主名称优先使用企业名称如果没有则使用用户名称
shipperName = StringUtils.isNotBlank(userPo.getShipperEnterpriseName())
? userPo.getShipperEnterpriseName()
: userPo.getUserName();
log.info("根据客户名称查询到货主信息,客户名称:{},货主ID:{},货主名称:{}",
customerName, userPo.getUserId(), shipperName);
}
}
} catch (Exception e) {
log.warn("根据客户名称查询货主ID失败,客户名称:{},错误:{}", customerName, e.getMessage());
}
}
//转换实体
MaterialInventoryDO materialInventoryDO = materialInventoryAssembler.toDO(materialInventoryDTO);
startPage();
// 使用带批次属性的查询方法批次属性值从库存表中获取
List<MaterialInventoryPO> list = materialInventoryApplicationService.queryListWithBatchAttributes(materialInventoryDO);
return getDataTable(list);
TableDataInfo tableDataInfo = getDataTable(list);
// 如果查询结果为空抛出异常提示用户该物料在库存中不存在
if (tableDataInfo.getTotal() == 0) {
StringBuilder errorMsg = new StringBuilder("该物料在库存中不存在");
// 如果有物料信息添加到提示中
if (StringUtils.isNotBlank(materialInventoryDTO.getMaterialName())) {
errorMsg.append(",物料名称:").append(materialInventoryDTO.getMaterialName());
} else if (StringUtils.isNotBlank(materialInventoryDTO.getMaterialCode())) {
errorMsg.append(",物料编码:").append(materialInventoryDTO.getMaterialCode());
} else if (StringUtils.isNotBlank(materialInventoryDTO.getBarCode())) {
errorMsg.append(",物料条码:").append(materialInventoryDTO.getBarCode());
}
// 如果有货主信息添加到提示中优先显示查询到的货主名称否则显示客户名称
if (StringUtils.isNotBlank(shipperName)) {
errorMsg.append(",货主:").append(shipperName);
} else if (StringUtils.isNotBlank(customerName)) {
errorMsg.append(",货主:").append(customerName);
}
// 如果有批次参考号添加到提示中
if (StringUtils.isNotBlank(materialInventoryDTO.getBatchRefNo())) {
errorMsg.append("Batch Ref NO's").append(materialInventoryDTO.getBatchRefNo());
}
// 如果有单据参考号添加到提示中
if (StringUtils.isNotBlank(materialInventoryDTO.getSheetRefNo())) {
errorMsg.append("Sheet Ref NO's").append(materialInventoryDTO.getSheetRefNo());
}
// 如果有箱号/卡板号添加到提示中
if (StringUtils.isNotBlank(materialInventoryDTO.getBoxPalletNo())) {
errorMsg.append(",箱号/卡板号:").append(materialInventoryDTO.getBoxPalletNo());
}
throw new ServiceException(errorMsg.toString());
}
return tableDataInfo;
}
@ApiOperation("查询物料库存列表不分页")
@@ -88,9 +88,13 @@ public class StockInOrderApi extends BaseController {
*/
@ApiOperation("导入入库单")
@PostMapping(value = "/importData")
public AjaxResult importData(MultipartFile file)
public AjaxResult importData(
@RequestParam("file") MultipartFile file,
@RequestParam("warehouseId") Long warehouseId,
@RequestParam("warehouseCode") String warehouseCode,
@RequestParam("warehouseName") String warehouseName)
{
return AjaxResult.success(stockInOrderApplicationService.importData(file));
return AjaxResult.success(stockInOrderApplicationService.importData(file, warehouseId, warehouseCode, warehouseName));
}
/**
@@ -141,5 +141,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<where>
<include refid="selectHandoverTaskOrderPo1"/>
</where>
order by a.create_time desc
</select>
</mapper>
@@ -99,11 +99,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and shipper_name like concat('%', #{shipperName}, '%')
</if>
<if test="materialCode != null and materialCode != ''">
and material_code = #{materialCode}
and material_code like concat('%', #{materialCode}, '%')
</if>
<if test="materialName != null and materialName != ''">
and material_name like concat('%', #{materialName}, '%')
</if>
<if test="unitName != null and unitName != ''">
and unit_name like concat('%', #{unitName}, '%')
</if>
<if test="barCode != null and barCode != ''">
and bar_code like concat('%',#{barCode},'%')
</if>
@@ -67,7 +67,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<sql id="selectShelfMaterialDetailPo">
select material_detail_id, organization_id, organization_name, top_organization_id, unique_id, shelf_order_number, material_base_info_id, material_code, material_name, bar_code, quantity, already_shelves_quantity, shelves_quantity, shelves_status, pack_id, pack_code, pack_name, pack_detail_id, unit_code, unit_name, unit_number, material_warehouse_control_id, serial_number_manage, quality_inspection_manage, quality_inspection_stage, quality_inspection_rule, quality_inspection_ratio, quality_inspection_term, quality_inspection_results, allow_overcharge, overcharge_ratio, batch_number, material_status_code, material_status_name, distribute_rule_id, distribute_rule_code, distribute_rule_name, container_id, container_code, container_type, container_type_name, warehouse_id, warehouse_code, warehouse_name, storage_section_id, storage_code, storage_name, storage_location_id, storage_location_code, storage_location_name, level, parent_unique_id, in_unique_id, receipt_unique_id, allow_modify, remark, batch_ref_no, sheet_ref_no, box_pallet_no, ext_attr_1, ext_attr_2, production_date, expiry_date, inventory_date, ext_attr_3, ext_attr_4, create_time, create_by, create_by_name, update_time, update_by, update_by_name, del_flag,total_net_weight,total_gross_weight,total_volume,total_area from shelf_material_detail
select material_detail_id, organization_id, organization_name, top_organization_id, unique_id, shelf_order_number, material_base_info_id, material_code, material_name, bar_code, quantity, already_shelves_quantity, shelves_quantity, shelves_status, pack_id, pack_code, pack_name,
CASE
WHEN pack_detail_id IS NULL OR TRIM(pack_detail_id) = '' THEN NULL
ELSE CAST(pack_detail_id AS BIGINT)
END as pack_detail_id, unit_code, unit_name, unit_number, material_warehouse_control_id, serial_number_manage, quality_inspection_manage, quality_inspection_stage, quality_inspection_rule, quality_inspection_ratio, quality_inspection_term, quality_inspection_results, allow_overcharge, overcharge_ratio, batch_number, material_status_code, material_status_name, distribute_rule_id, distribute_rule_code, distribute_rule_name, container_id, container_code, container_type, container_type_name, warehouse_id, warehouse_code, warehouse_name, storage_section_id, storage_code, storage_name, storage_location_id, storage_location_code, storage_location_name, level, parent_unique_id, in_unique_id, receipt_unique_id, allow_modify, remark, batch_ref_no, sheet_ref_no, box_pallet_no, ext_attr_1, ext_attr_2, production_date, expiry_date, inventory_date, ext_attr_3, ext_attr_4, create_time, create_by, create_by_name, update_time, update_by, update_by_name, del_flag,total_net_weight,total_gross_weight,total_volume,total_area from shelf_material_detail
</sql>
<sql id="selectShelfMaterialDetailPo1">
@@ -33,6 +33,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="directWarehouse" column="direct_warehouse" />
<result property="annexUrl" column="annex_url" />
<result property="quantity" column="quantity" />
<result property="planInQuantity" column="plan_in_quantity" />
<result property="receiptQuantity" column="receipt_quantity" />
<result property="shelvesQuantity" column="shelves_quantity" />
<result property="cancelOrder" column="cancel_order" />
<result property="cancelRemark" column="cancel_remark" />
<result property="cancelBy" column="cancel_by" />
@@ -84,7 +87,27 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
a.in_order_id, a.organization_id, a.organization_name, a.top_organization_id, a.notice_number, a.in_order_number, a.status,
a.audit_status, a.audit_remark, a.audit_by, a.audit_by_name, a.audit_time, a.warehouse_id, a.warehouse_code, a.warehouse_name, a.shipper_id, a.shipper_code,
a.shipper_name, a.order_type_code, a.order_type_name, a.supplier_id, a.supplier_code, a.supplier_name, a.expect_time, a.supply_chain_number,
a.priority_level_code, a.priority_level_name, a.direct_warehouse, a.annex_url, a.material_quantity, a.quantity, a.weight_limit, a.volume_limit, a.cancel_order, a.cancel_remark, a.cancel_by,
a.priority_level_code, a.priority_level_name, a.direct_warehouse, a.annex_url, a.material_quantity, a.quantity,
-- 计划入库数量:入库明细表 in_material_detail 的 quantity 汇总
(select ifnull(sum(imd.quantity), 0)
from in_material_detail imd
where imd.in_order_number = a.in_order_number
and imd.del_flag = 1
and (imd.level is null or imd.level = 1)
) as plan_in_quantity,
-- 收货数量:收货单表 stock_receipt_order 的 receipt_quantity 汇总
(select ifnull(sum(sro.receipt_quantity), 0)
from stock_receipt_order sro
where sro.in_order_number = a.in_order_number
and sro.del_flag = 1
) as receipt_quantity,
-- 上架数量:上架单表 stock_shelf_order 的 shelves_quantity 汇总
(select ifnull(sum(sso.shelves_quantity), 0)
from stock_shelf_order sso
where sso.in_order_number = a.in_order_number
and sso.del_flag = 1
) as shelves_quantity,
a.weight_limit, a.volume_limit, a.cancel_order, a.cancel_remark, a.cancel_by,
a.cancel_by_name, a.cancel_time, a.close_order, a.close_remark, a.close_by, a.close_by_name, a.close_time, a.remark, a.create_time, a.create_by,
a.create_by_name, a.update_time, a.update_by, a.update_by_name, a.del_flag, over_stock_id, over_stock_status, over_stock_type,
a."TO", a.CONTACT_PERSON, a.VEHICLE_INFO, a.CONSIGNMENT_NO, a.TEL, a.DRIVER_SIGNATURE, a.FAX, a.DECLARATION_AREA, a.MANUFACTURER,