diff --git a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/SystemServiceFeign.java b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/SystemServiceFeign.java index 581e8c257..bfd94ccba 100644 --- a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/SystemServiceFeign.java +++ b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/SystemServiceFeign.java @@ -275,6 +275,12 @@ public interface SystemServiceFeign { @GetMapping("/associationWarehouseApi/setWarehouseInfo") public AjaxResult setWarehouseInfo(@RequestBody AssociationWarehouseFeign associationWarehouseFeign); + /** + * 查询仓库关联的用户ID集合 + */ + @GetMapping("/associationWarehouseApi/queryListCorrelationId") + public AjaxResult queryListCorrelationId(@RequestParam(value = "warehouseId", required = false) Long warehouseId); + /** * 根据code编码查询费用科目 diff --git a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/UserServiceFeign.java b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/UserServiceFeign.java index 977accfd1..506727a20 100644 --- a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/UserServiceFeign.java +++ b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/UserServiceFeign.java @@ -109,6 +109,13 @@ public interface UserServiceFeign { @GetMapping("/userApi/getInfo/{userId}") public AjaxResult getInfo(@PathVariable("userId") Long userId); + /** + * 根据用户ID查询用户详细信息 + */ + @ApiOperation("根据用户ID查询用户详细信息") + @GetMapping("/userApi/getInfoByName/{userName}") + public AjaxResult getInfoByName(@PathVariable("userName") String userName); + /** * 查询车辆绑定的承运人列表 @@ -184,4 +191,4 @@ public interface UserServiceFeign { @ApiOperation("根据用户ID查询货主信息") @GetMapping("/userShipperApi/getShipperByUserId/{userId}") public AjaxResult getShipperByUserId(@PathVariable("userId") Long userId); -} +} \ No newline at end of file diff --git a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WmsServiceFeign.java b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WmsServiceFeign.java index 00c8815b8..6551d451e 100644 --- a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WmsServiceFeign.java +++ b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WmsServiceFeign.java @@ -3,12 +3,15 @@ package com.mhd.system.api; import com.mhd.common.core.constant.ServiceNameConstants; import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.system.api.domain.MaterialBaseInfoFeign; +import com.mhd.system.api.domain.MaterialInventoryDTO; import com.mhd.system.api.domain.NoticeOrderDTO; import com.mhd.system.api.factory.RemoteTicketFeignFallbackFactory; import com.mhd.system.api.feign.FeignAutoConfiguration; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.*; +import java.util.Map; + /** * @author ZhouGY * @title WmsServiceFeign @@ -57,4 +60,9 @@ public interface WmsServiceFeign { @PostMapping("/noticeOrderApi/insert") public AjaxResult stockOutOrInInsert(@RequestBody NoticeOrderDTO noticeOrderDTO); + /** + * 查询物料库存列表不分页 + */ + @GetMapping("/materialInventoryApi/listAll") + public AjaxResult materialInventoryApiListAll(MaterialInventoryDTO materialInventoryDTO); } diff --git a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/BatchDetailFeignPO.java b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/BatchDetailFeignPO.java index e0645a815..d2d867393 100644 --- a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/BatchDetailFeignPO.java +++ b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/BatchDetailFeignPO.java @@ -44,6 +44,10 @@ public class BatchDetailFeignPO extends BaseVOEntity{ @Excel(name = "批次标签") private String batchLabels; + @ApiModelProperty("字段名称") + @Excel(name = "字段名称") + private String fieldName; + @ApiModelProperty("输入控制: 1-必填 2-可选") @Excel(name = "输入控制: 1-必填 2-可选") private String inputControl; @@ -56,6 +60,10 @@ public class BatchDetailFeignPO extends BaseVOEntity{ @Excel(name = "属性选项") private String attributeOption; + @ApiModelProperty("是否显示: 0-不显示 1-显示") + @Excel(name = "是否显示: 0-不显示 1-显示") + private Integer isDisplay; + @ApiModelProperty("备注") @Excel(name = "备注") private String remark; diff --git a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/MaterialBaseInfoFeign.java b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/MaterialBaseInfoFeign.java index 711ffd15f..6e8c58bf0 100644 --- a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/MaterialBaseInfoFeign.java +++ b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/MaterialBaseInfoFeign.java @@ -181,5 +181,35 @@ public class MaterialBaseInfoFeign extends BaseVOEntity{ @ApiModelProperty("是否公用: 1-是 2-否") @Excel(name = "是否公用: 1-是 2-否") private Integer common; + + @ApiModelProperty("SKU码") + private String skuCode; + + @ApiModelProperty("单价") + private BigDecimal unitPrice; + + @ApiModelProperty("原产国") + private String originCountry; + + @ApiModelProperty("HS码") + private String hsCode; + + @ApiModelProperty("申报单位") + private String declarationUnit; + + @ApiModelProperty("法定单位") + private String statutoryUnit; + + @ApiModelProperty("法定第二单位") + private String statutorySecondUnit; + /** + * 规格型号 + */ + @ApiModelProperty("规格型号") + @Excel(name = "规格型号") + private String specificationModel; + + @ApiModelProperty("币制") + private String currency; } diff --git a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/MaterialInventoryDTO.java b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/MaterialInventoryDTO.java new file mode 100644 index 000000000..a59612918 --- /dev/null +++ b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/MaterialInventoryDTO.java @@ -0,0 +1,149 @@ +package com.mhd.system.api.domain; + +import com.mhd.common.core.annotation.Excel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +/** + * 物料库存对象 material_inventory + * + * @author gen + * @date 2024-05-29 + */ + +@Data +public class MaterialInventoryDTO { + private static final long serialVersionUID = 1L; + + @ApiModelProperty("物料库存id") + private Long materialInventoryId; + + @ApiModelProperty("组织表ID") + @Excel(name = "组织表ID") + private Long organizationId; + + @ApiModelProperty("组织名称") + @Excel(name = "组织名称") + private String organizationName; + + @ApiModelProperty("一级组织表ID") + @Excel(name = "一级组织表ID") + private Long topOrganizationId; + + @ApiModelProperty("物料基础信息id") + @Excel(name = "物料基础信息id") + private Long materialBaseInfoId; + + @ApiModelProperty("上架单物料明细id") + @Excel(name = "上架单物料明细id") + private Long materialDetailId; + + @ApiModelProperty("仓库id") + @Excel(name = "仓库id") + private Long warehouseId; + + @ApiModelProperty("仓库编码") + @Excel(name = "仓库编码") + private String warehouseCode; + + @ApiModelProperty("仓库名称") + @Excel(name = "仓库名称") + private String warehouseName; + + @ApiModelProperty("库区id") + @Excel(name = "库区id") + private Long storageSectionId; + + @ApiModelProperty("库区编码") + @Excel(name = "库区编码") + private String storageCode; + + @ApiModelProperty("库区名称") + @Excel(name = "库区名称") + private String storageName; + + @ApiModelProperty("库位id") + @Excel(name = "库位id") + private Long storageLocationId; + + @ApiModelProperty("库位编码") + @Excel(name = "库位编码") + private String storageLocationCode; + + @ApiModelProperty("库位名称") + @Excel(name = "库位名称") + private String storageLocationName; + + @ApiModelProperty("批次号") + @Excel(name = "批次号") + private String batchNumber; + + @ApiModelProperty("物料状态编码") + @Excel(name = "物料状态编码") + private String materialStatusCode; + + @ApiModelProperty("物料状态名称") + @Excel(name = "物料状态名称") + private String materialStatusName; + + @ApiModelProperty("容器id") + @Excel(name = "容器id") + private Long containerId; + + @ApiModelProperty("容器编码") + @Excel(name = "容器编码") + private String containerCode; + + @ApiModelProperty("容器类型 数据字典") + @Excel(name = "容器类型 数据字典") + private String containerType; + + @ApiModelProperty("容器类型名称 数据字典") + @Excel(name = "容器类型名称 数据字典") + private String containerTypeName; + + @ApiModelProperty("库存数量") + @Excel(name = "库存数量") + private BigDecimal inventoryQuantity; + + @ApiModelProperty("可用数量") + @Excel(name = "可用数量") + private BigDecimal allocationQuantity; + + @ApiModelProperty("冻结数量") + @Excel(name = "冻结数量") + private BigDecimal freezeQuantity; + + @ApiModelProperty("备注") + @Excel(name = "备注") + private String remark; + + + @ApiModelProperty(name = "组织ID集合") + private List organizationIdList; + + @ApiModelProperty(name = "权限菜单ID") + private Long permissionMenuId; + + @ApiModelProperty("盘点是否可用:0-禁用 1-可用") + @Excel(name = "盘点是否可用:0-禁用 1-可用") + private Integer isAble; + + @ApiModelProperty("货主信息") + @Excel(name = "货主信息") + private String shipperInfo; + + @ApiModelProperty("物料信息") + @Excel(name = "物料信息") + private String materialInfo; + + @ApiModelProperty("物料/库位信息") + @Excel(name = "物料/库位信息") + private String storageInfo; + + @ApiModelProperty("货主id") + private Long shipperId; +} diff --git a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/factory/RemoteSystemFeignFallbackFactory.java b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/factory/RemoteSystemFeignFallbackFactory.java index f9e020923..4b199c215 100644 --- a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/factory/RemoteSystemFeignFallbackFactory.java +++ b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/factory/RemoteSystemFeignFallbackFactory.java @@ -219,6 +219,11 @@ public class RemoteSystemFeignFallbackFactory implements FallbackFactory queryList(LeaseDO leaseDO) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser != null && loginUser.getUserPo() != null){ + Long loginUserOrganizationId = loginUser.getUserPo().getOrganizationId(); + Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); + + // 数据权限:根据organizationId来设置查询权限 + // organizationId等于2827时查询全部,其他仅查询各自组织的信息 + if (loginUserOrganizationId != null && loginUserOrganizationId.equals(2827L)) { + // 南光组织(organizationId=2827):可以查询所有组织的数据 + // 如果前端传递了 organizationId,使用前端传递的值进行过滤 + // 如果前端没有传递 organizationId,清空组织过滤条件,查询所有组织的数据 + if (leaseDO.getOrganizationId() == null) { + leaseDO.setOrganizationId(null); + leaseDO.setTopOrganizationId(null); + } + } else { + // 其他组织:设置organizationId,只查询当前组织的数据 + if (topOrganizationId != null && topOrganizationId != 1){ + leaseDO.setTopOrganizationId(topOrganizationId); + } + // 如果前端传递了organizationId,验证是否与当前登录用户的组织ID一致 + if (leaseDO.getOrganizationId() != null && !leaseDO.getOrganizationId().equals(loginUserOrganizationId)) { + // 前端传递了其他组织的organizationId,强制使用当前登录用户的组织ID,防止越权查询 + leaseDO.setOrganizationId(loginUserOrganizationId); + } + } + } + return leaseDomainService.queryList(leaseDO); + } + + + /** + * 新增租赁管理 + */ + public Boolean insert(LeaseDO leaseDO) { + // 设置当前登录用户的组织信息 + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser != null && loginUser.getUserPo() != null) { + leaseDO.setOrganizationId(loginUser.getUserPo().getOrganizationId()); + leaseDO.setOrganizationName(loginUser.getUserPo().getOrganizationName()); + leaseDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); + } + List timeOverlapSimple = isTimeOverlapSimple(leaseDO.getCargoOwnerName(), leaseDO.getStartDate(), leaseDO.getEndDate(), null); + if (ObjectUtil.isNotEmpty(timeOverlapSimple)) { + throw new ServiceException("同一货主租赁信息时间不能重叠"); + } + setWarehouseInfo(leaseDO); + return leaseDomainService.insert(leaseDO); + } + + @Autowired + private SystemServiceFeign systemServiceFeign; + + private void setWarehouseInfo(LeaseDO leaseDO) { + AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(leaseDO.getWarehouseId()); + if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ + throw new ServiceException("获取仓库信息失败"); + } + WarehouseFeignPO warehouseFeignPO = com.alibaba.fastjson.JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), WarehouseFeignPO.class); + leaseDO.setWarehouseName(warehouseFeignPO.getWarehouseName()); + } + + private List isTimeOverlapSimple(String cargoOwnerName, Date startDate, Date endDate, Long excludeId) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(Lease::getCargoOwnerName, cargoOwnerName) + .eq(Lease::getDelFlag, 1) // 只查询正常状态 + .le(Lease::getStartDate, endDate) + .ge(Lease::getEndDate, startDate); + if (excludeId != null) { + wrapper.ne(Lease::getId, excludeId); + } + return leaseService.list(wrapper); + } + + /** + * 修改租赁管理 + */ + public Boolean update(LeaseDO leaseDO) { + List timeOverlapSimple = isTimeOverlapSimple(leaseDO.getCargoOwnerName(), leaseDO.getStartDate(), leaseDO.getEndDate(), leaseDO.getId()); + if (ObjectUtil.isNotEmpty(timeOverlapSimple)) { + throw new ServiceException("同一货主租赁信息时间不能重叠"); + } + return leaseDomainService.update(leaseDO); + } + + /** + * 批量删除租赁管理 + */ + public boolean delete(Long[] leaseIds) { + return leaseDomainService.delete(leaseIds); + } + + /** + * 获取租赁管理详细信息 + */ + public LeasePO getInfo(Long leaseId) + { + return leaseDomainService.getInfo(leaseId); + } + + /** + * @description 批量作废租赁 + * @author ZhouGY + * @date 2024/5/13 9:46 + * @param leaseIds + * @return Boolean + */ + public Boolean nullifyByIds(List leaseIds){ + return leaseDomainService.nullifyByIds(leaseIds); + } + + + /** + * 货主租赁明细 + */ + @Scheduled(cron = "0 0 1 * * ?") + public void shipperLeaseDetails() { + LeaseDO leaseDO = new LeaseDO(); + leaseDO.setTime(new Date()); + //查询租赁 + List leasePOS = queryList(leaseDO); +// List leasePOS = leaseDomainService.queryList(leaseDO); + List entireUnit = leasePOS.stream() + .filter(lease -> lease.getLeaseType().equals("整租")) + .collect(Collectors.toList()); + List casualRental = leasePOS.stream() + .filter(lease -> lease.getLeaseType().equals("散租")) + .collect(Collectors.toList()); + List shipperLeaseDetailsList = new ArrayList<>(); //建表后保存 + for (LeasePO en : entireUnit) {//整租 + ShipperLeaseDetails shipperLeaseDetails = new ShipperLeaseDetails(); + BeanUtils.copyProperties(en, shipperLeaseDetails); + shipperLeaseDetails.setBusinessDate(new Date()); + shipperLeaseDetailsList.add(shipperLeaseDetails); + } + //当前货主当前仓库,库存查询页面所有面积加起来就是散租面积 + for (LeasePO ca : casualRental) {//散租 + 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.setLeaseArea(area); + shipperLeaseDetailsList.add(shipperLeaseDetails); + } + // 保存货主租赁明细(新建表) + if (shipperLeaseDetailsList.size() > 0) { + shipperLeaseDetailsService.saveBatch(shipperLeaseDetailsList); + } + } + + /** + * 计算仓库出租率 + * warehouseId 仓库id + * businessDateStart 业务开始时间 + * businessDateEnd 业务结束时间 + */ + public List warehouseOccupancyRate(ShipperLeaseDetailsDO shipperLeaseDetailsDO) { + //仓库id 和 开始结束时间作为查询条件 查数据库 差出来当前仓库所有的 + List shipperLeaseDetailsList = shipperLeaseDetailsService.queryList(shipperLeaseDetailsDO); + ShipperLeaseDetailsPO shipperLeaseDetailsPO = shipperLeaseDetailsList.get(0); + //按业务日期分组,并按日期排序 + TreeMap> groupedByDate = shipperLeaseDetailsList.stream().collect( + Collectors.groupingBy( + ShipperLeaseDetailsPO::getBusinessDate, + TreeMap::new, + Collectors.toList() + ) + ); + //获取总面积 + BigDecimal totalArea = BigDecimal.ZERO; + StorageSectionDO storageSectionDO = new StorageSectionDO(); + storageSectionDO.setWarehouseId(shipperLeaseDetailsDO.getWarehouseId()); + storageSectionDO.setOpeningUp(1); + List storageSectionPOS = storageSectionApplicationService.queryList(storageSectionDO); + for (StorageSectionPO storageSectionPO : storageSectionPOS) { + totalArea = totalArea.add(storageSectionPO.getStorageRegion()); + } + + List warehouseOccupancyRatesList = new ArrayList<>(); + //组装仓库返回数据 + BigDecimal finalTotalArea = totalArea; + groupedByDate.forEach((date, shipperLeaseDetails) -> { + WarehouseOccupancyRate warehouseOccupancyRate = new WarehouseOccupancyRate(); + warehouseOccupancyRate.setBusinessDate(date); + BigDecimal entireLeaseArea = BigDecimal.ZERO; + BigDecimal fractionalLeaseArea = BigDecimal.ZERO; + //计算整租和散租 + for (ShipperLeaseDetailsPO shipperLeaseDetail : shipperLeaseDetails) { + if (shipperLeaseDetail.getLeaseType().equals("整租")){ + entireLeaseArea = entireLeaseArea.add(shipperLeaseDetail.getLeaseArea()); + }else { + fractionalLeaseArea = fractionalLeaseArea.add(shipperLeaseDetail.getLeaseArea()); + } + warehouseOccupancyRate.setWarehouseName(shipperLeaseDetail.getWarehouseName()); + warehouseOccupancyRate.setBusinessDate(date); + warehouseOccupancyRate.setWarehouseId(shipperLeaseDetail.getWarehouseId()); + } + warehouseOccupancyRate.setEntireLeaseArea(entireLeaseArea); + warehouseOccupancyRate.setFractionalLeaseArea(fractionalLeaseArea); + warehouseOccupancyRate.setTotalArea(finalTotalArea); + BigDecimal dailyRentalRate = entireLeaseArea.add(fractionalLeaseArea).divide(finalTotalArea, 2, BigDecimal.ROUND_HALF_UP); + warehouseOccupancyRate.setDailyRentalRate(dailyRentalRate); + warehouseOccupancyRatesList.add(warehouseOccupancyRate); + }); + return warehouseOccupancyRatesList; + } + +// /** +// * @description 设置数据字典键值 +// * @author ZhouGY +// * @date 2024/4/7 14:33 +// * @param containerDO +// */ +// private void setDataDict(LeaseDO leaseDO){ +// //翻译租赁类型 +// List storageTypeDictDataList = dictTypeService.selectDictDataByType(DictCode.CONTAINER_TYPE.getCode()); +// if (null == storageTypeDictDataList) { +// throw new ServiceException("租赁类型数据字典不存在 请联系管理员"); +// } +// SysDictData storageTypeDictData = storageTypeDictDataList.stream().filter(info -> ObjectUtil.equal(info.getDictValue(), containerDO.getContainerType())).findAny().orElse(null); +// if (null == storageTypeDictData) { +// throw new ServiceException("租赁类型【" + leaseDO.getContainerType() + "】数据字典不存在 请联系管理员"); +// } +// leaseDO.setContainerTypeName(storageTypeDictData.getDictLabel()); +// } +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/batch/BatchApplicationService.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/batch/BatchApplicationService.java index 23b5559b0..433041bed 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/batch/BatchApplicationService.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/batch/BatchApplicationService.java @@ -1,15 +1,22 @@ package com.mhd.basic.application.service.batch; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.mhd.basic.domain.batch.repository.po.BatchPO; import com.mhd.basic.domain.batch.repository.todo.BatchDO; import com.mhd.basic.domain.batch.service.BatchDomainService; +import com.mhd.basic.domain.batchDetail.entity.BatchDetail; +import com.mhd.basic.domain.batchDetail.repository.facade.IBatchDetailService; +import com.mhd.basic.domain.batchDetail.repository.po.BatchDetailPO; import com.mhd.basic.domain.pack.repository.todo.PackDO; import com.mhd.common.core.domain.po.UserPo; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.model.LoginUser; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; + +import java.util.ArrayList; import java.util.List; /** * 批次管理ApplicationService @@ -22,6 +29,8 @@ import java.util.List; public class BatchApplicationService { @Autowired private BatchDomainService batchDomainService; + @Autowired + private IBatchDetailService batchDetailService; /** @@ -36,7 +45,21 @@ public class BatchApplicationService { batchDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); } } - return batchDomainService.queryList(batchDO); + List batchPOS = batchDomainService.queryList(batchDO); + for (BatchPO batchPO : batchPOS) { + List batchDetailList = batchDetailService.list(new LambdaQueryWrapper() + .eq(BatchDetail::getBatchId, batchPO.getBatchId()) + .eq(BatchDetail::getDelFlag, "1")); + List batchDetailPOS = new ArrayList<>(); + // 逐个对象拷贝 + for (BatchDetail detail : batchDetailList) { + BatchDetailPO detailPO = new BatchDetailPO(); + BeanUtils.copyProperties(detail, detailPO); + batchDetailPOS.add(detailPO); + } + batchPO.setBatchDetailList(batchDetailPOS); + } + return batchPOS; } diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/batchDetail/BatchDetailApplicationService.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/batchDetail/BatchDetailApplicationService.java index a1a16a3e4..9ca5b92f5 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/batchDetail/BatchDetailApplicationService.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/batchDetail/BatchDetailApplicationService.java @@ -45,6 +45,10 @@ public class BatchDetailApplicationService { batchDetailDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); } } + // 如果未指定isDisplay,默认只查询显示的数据(isDisplay=1) + if (batchDetailDO.getIsDisplay() == null) { + batchDetailDO.setIsDisplay(1); + } return batchDetailDomainService.queryList(batchDetailDO); } diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/container/ContainerApplicationService.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/container/ContainerApplicationService.java index ca2a60370..f5c8a2160 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/container/ContainerApplicationService.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/container/ContainerApplicationService.java @@ -79,8 +79,6 @@ public class ContainerApplicationService { containerDO.setOrganizationName(loginUser.getUserPo().getOrganizationName()); containerDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); } - //翻译库区类型 - setDataDict(containerDO); return containerDomainService.insert(containerDO); } @@ -117,22 +115,4 @@ public class ContainerApplicationService { return containerDomainService.nullifyByIds(containerIds); } - /** - * @description 设置数据字典键值 - * @author ZhouGY - * @date 2024/4/7 14:33 - * @param containerDO - */ - private void setDataDict(ContainerDO containerDO){ - //翻译容器类型 - List storageTypeDictDataList = dictTypeService.selectDictDataByType(DictCode.CONTAINER_TYPE.getCode()); - if (null == storageTypeDictDataList) { - throw new ServiceException("容器类型数据字典不存在 请联系管理员"); - } - SysDictData storageTypeDictData = storageTypeDictDataList.stream().filter(info -> ObjectUtil.equal(info.getDictValue(), containerDO.getContainerType())).findAny().orElse(null); - if (null == storageTypeDictData) { - throw new ServiceException("容器类型【" + containerDO.getContainerType() + "】数据字典不存在 请联系管理员"); - } - containerDO.setContainerTypeName(storageTypeDictData.getDictLabel()); - } } diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/materialBaseInfo/MaterialBaseInfoApplicationService.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/materialBaseInfo/MaterialBaseInfoApplicationService.java index a85a4c75b..8a253446d 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/materialBaseInfo/MaterialBaseInfoApplicationService.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/materialBaseInfo/MaterialBaseInfoApplicationService.java @@ -120,7 +120,11 @@ public class MaterialBaseInfoApplicationService { throw new ServiceException("获取货主信息失败"); } UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); - materialBaseInfoDO.setShipperName(userPo.getUserName()); + // 如果原始shipperName不为空,保留原始值(导入或手动输入时应该保留完整名称) + // 只有在原始shipperName为空时,才使用查询到的userName + if (materialBaseInfoDO.getShipperName() == null || materialBaseInfoDO.getShipperName().trim().isEmpty()) { + materialBaseInfoDO.setShipperName(userPo.getUserName()); + } } public List getMaterialStockList(String shipperName, String materialName, diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/shipperLeaseDetails/ShipperLeaseDetailsApplicationService.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/shipperLeaseDetails/ShipperLeaseDetailsApplicationService.java new file mode 100644 index 000000000..2cfbe02e1 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/shipperLeaseDetails/ShipperLeaseDetailsApplicationService.java @@ -0,0 +1,160 @@ +package com.mhd.basic.application.service.shipperLeaseDetails; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.mhd.basic.application.service.storageSection.StorageSectionApplicationService; +import com.mhd.basic.domain.lease.entity.Lease; +import com.mhd.basic.domain.lease.repository.facade.ILeaseService; +import com.mhd.basic.domain.lease.repository.po.LeasePO; +import com.mhd.basic.domain.lease.repository.todo.LeaseDO; +import com.mhd.basic.domain.lease.service.LeaseDomainService; +import com.mhd.basic.domain.shipperLeaseDetails.entity.ShipperLeaseDetails; +import com.mhd.basic.domain.shipperLeaseDetails.entity.WarehouseOccupancyRate; +import com.mhd.basic.domain.shipperLeaseDetails.repository.facade.IShipperLeaseDetailsService; +import com.mhd.basic.domain.shipperLeaseDetails.repository.po.ShipperLeaseDetailsPO; +import com.mhd.basic.domain.shipperLeaseDetails.repository.todo.ShipperLeaseDetailsDO; +import com.mhd.basic.domain.shipperLeaseDetails.service.ShipperLeaseDetailsDomainService; +import com.mhd.basic.domain.storageSection.repository.po.StorageSectionPO; +import com.mhd.basic.domain.storageSection.repository.todo.StorageSectionDO; +import com.mhd.basic.interfaces.dto.lease.LeaseDTO; +import com.mhd.common.core.exception.ServiceException; +import com.mhd.common.core.web.domain.AjaxResult; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.WmsServiceFeign; +import com.mhd.system.api.domain.MaterialInventoryDTO; +import com.mhd.system.api.model.LoginUser; +import com.mhd.system.service.ISysDictTypeService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.TreeMap; +import java.util.stream.Collectors; + +/** + * 货主租赁明细ApplicationService + * + * @author gen + * @date 2024-05-07 + */ +@Service +@Slf4j +public class ShipperLeaseDetailsApplicationService { + + @Autowired + private ShipperLeaseDetailsDomainService shipperLeaseDetailsDomainService; + + @Autowired + private ISysDictTypeService dictTypeService; + + /** + * 分页查询货主租赁明细列表 + */ + + public List queryList(ShipperLeaseDetailsDO shipperLeaseDetailsDO) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser != null && loginUser.getUserPo() != null){ + Long loginUserOrganizationId = loginUser.getUserPo().getOrganizationId(); + Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); + + // 数据权限:根据organizationId来设置查询权限 + // organizationId等于2827时查询全部,其他仅查询各自组织的信息 + if (loginUserOrganizationId != null && loginUserOrganizationId.equals(2827L)) { + // 南光组织(organizationId=2827):可以查询所有组织的数据 + // 如果前端传递了 organizationId,使用前端传递的值进行过滤 + // 如果前端没有传递 organizationId,清空组织过滤条件,查询所有组织的数据 + if (shipperLeaseDetailsDO.getOrganizationId() == null) { + shipperLeaseDetailsDO.setOrganizationId(null); + shipperLeaseDetailsDO.setTopOrganizationId(null); + } + } else { + // 其他组织:设置organizationId,只查询当前组织的数据 + if (topOrganizationId != null && topOrganizationId != 1){ + shipperLeaseDetailsDO.setTopOrganizationId(topOrganizationId); + } + // 如果前端传递了organizationId,验证是否与当前登录用户的组织ID一致 + if (shipperLeaseDetailsDO.getOrganizationId() != null && !shipperLeaseDetailsDO.getOrganizationId().equals(loginUserOrganizationId)) { + // 前端传递了其他组织的organizationId,强制使用当前登录用户的组织ID,防止越权查询 + shipperLeaseDetailsDO.setOrganizationId(loginUserOrganizationId); + } + } + } + return shipperLeaseDetailsDomainService.queryList(shipperLeaseDetailsDO); + } + + + /** + * 新增货主租赁明细 + */ + public Boolean insert(ShipperLeaseDetailsDO shipperLeaseDetailsDO) { + // 设置当前登录用户的组织信息 + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser != null && loginUser.getUserPo() != null) { + shipperLeaseDetailsDO.setOrganizationId(loginUser.getUserPo().getOrganizationId()); + shipperLeaseDetailsDO.setOrganizationName(loginUser.getUserPo().getOrganizationName()); + shipperLeaseDetailsDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); + } + return shipperLeaseDetailsDomainService.insert(shipperLeaseDetailsDO); + } + + + /** + * 修改货主租赁明细 + */ + public Boolean update(ShipperLeaseDetailsDO shipperLeaseDetailsDO) { + return shipperLeaseDetailsDomainService.update(shipperLeaseDetailsDO); + } + + /** + * 批量删除货主租赁明细 + */ + public boolean delete(Long[] shipperLeaseDetailsIds) { + return shipperLeaseDetailsDomainService.delete(shipperLeaseDetailsIds); + } + + /** + * 获取货主租赁明细详细信息 + */ + public ShipperLeaseDetailsPO getInfo(Long shipperLeaseDetailsId) + { + return shipperLeaseDetailsDomainService.getInfo(shipperLeaseDetailsId); + } + + /** + * @description 批量作废租赁 + * @author ZhouGY + * @date 2024/5/13 9:46 + * @return Boolean + */ + public Boolean nullifyByIds(List shipperLeaseDetailsIds){ + return shipperLeaseDetailsDomainService.nullifyByIds(shipperLeaseDetailsIds); + } + + +// /** +// * @description 设置数据字典键值 +// * @author ZhouGY +// * @date 2024/4/7 14:33 +// * @param containerDO +// */ +// private void setDataDict(LeaseDO leaseDO){ +// //翻译租赁类型 +// List storageTypeDictDataList = dictTypeService.selectDictDataByType(DictCode.CONTAINER_TYPE.getCode()); +// if (null == storageTypeDictDataList) { +// throw new ServiceException("租赁类型数据字典不存在 请联系管理员"); +// } +// SysDictData storageTypeDictData = storageTypeDictDataList.stream().filter(info -> ObjectUtil.equal(info.getDictValue(), containerDO.getContainerType())).findAny().orElse(null); +// if (null == storageTypeDictData) { +// throw new ServiceException("租赁类型【" + leaseDO.getContainerType() + "】数据字典不存在 请联系管理员"); +// } +// leaseDO.setContainerTypeName(storageTypeDictData.getDictLabel()); +// } +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/storageLocation/StorageLocationApplicationService.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/storageLocation/StorageLocationApplicationService.java index c14ade53b..2d69d28eb 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/storageLocation/StorageLocationApplicationService.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/storageLocation/StorageLocationApplicationService.java @@ -49,8 +49,30 @@ public class StorageLocationApplicationService { if (topOrganizationId != null && topOrganizationId != 1){ storageLocationDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); } - AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); - storageLocationDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId()); + // 只有当前端没有明确传仓库条件时,才使用用户关联仓库缓存进行过滤; + // 避免出现“单据仓库=常温仓,但库位列表仍显示保税仓”的错配问题。 + boolean hasWarehouseFilter = storageLocationDO.getWarehouseId() != null + || (storageLocationDO.getWarehouseCode() != null && !storageLocationDO.getWarehouseCode().trim().isEmpty()) + || (storageLocationDO.getWarehouseName() != null && !storageLocationDO.getWarehouseName().trim().isEmpty()); + if (!hasWarehouseFilter) { + try { + AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); + if (associationWarehouseCacheDO != null) { + if (associationWarehouseCacheDO.getWarehouseId() != null) { + storageLocationDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId()); + } + if (associationWarehouseCacheDO.getWarehouseCode() != null && !associationWarehouseCacheDO.getWarehouseCode().trim().isEmpty()) { + storageLocationDO.setWarehouseCode(associationWarehouseCacheDO.getWarehouseCode()); + } + if (associationWarehouseCacheDO.getWarehouseName() != null && !associationWarehouseCacheDO.getWarehouseName().trim().isEmpty()) { + storageLocationDO.setWarehouseName(associationWarehouseCacheDO.getWarehouseName()); + } + } + } catch (Exception e) { + // 获取失败不影响查询(允许查询所有仓库,或由前端传参控制) + log.warn("获取用户关联仓库信息失败,将按前端条件查询库位数据,用户ID:{},错误:{}", loginUser.getUserid(), e.getMessage()); + } + } } return storageLocationDomainService.queryList(storageLocationDO); } diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/warehouse/WarehouseApplicationService.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/warehouse/WarehouseApplicationService.java index a3649948d..7765d64bb 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/warehouse/WarehouseApplicationService.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/application/service/warehouse/WarehouseApplicationService.java @@ -43,9 +43,9 @@ public class WarehouseApplicationService { public List queryList(WarehouseDO warehouseDO) { LoginUser loginUser = SecurityUtils.getLoginUser(); if (loginUser != null){ - Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); - if (topOrganizationId != null && topOrganizationId != 1){ - warehouseDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); + Long organizationId = loginUser.getUserPo().getOrganizationId(); + if (organizationId != null && organizationId != 1){ + warehouseDO.setOrganizationId(loginUser.getUserPo().getOrganizationId()); } } return warehouseDomainService.queryList(warehouseDO); diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/entity/BatchDetail.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/entity/BatchDetail.java index 536aa4de4..7e0a26afd 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/entity/BatchDetail.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/entity/BatchDetail.java @@ -46,6 +46,10 @@ public class BatchDetail extends BaseVOEntity{ @Excel(name = "批次标签") private String batchLabels; + @ApiModelProperty("字段名称") + @Excel(name = "字段名称") + private String fieldName; + @ApiModelProperty("输入控制: 1-必填 2-可选") @Excel(name = "输入控制: 1-必填 2-可选") private String inputControl; @@ -58,6 +62,10 @@ public class BatchDetail extends BaseVOEntity{ @Excel(name = "属性选项") private String attributeOption; + @ApiModelProperty("是否显示: 0-不显示 1-显示") + @Excel(name = "是否显示: 0-不显示 1-显示") + private Integer isDisplay; + @ApiModelProperty("备注") @Excel(name = "备注") private String remark; diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/repository/persistence/BatchDetailImpl.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/repository/persistence/BatchDetailImpl.java index ec531a1a8..675a2b10f 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/repository/persistence/BatchDetailImpl.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/repository/persistence/BatchDetailImpl.java @@ -62,24 +62,40 @@ public class BatchDetailImpl extends ServiceImpl LoginUser loginUser = SecurityUtils.getLoginUser(); UserPo userPo = loginUser.getUserPo(); List batchDetailDOList = batchDO.getBatchDetailList(); - //验证提交的数据是否存在重复 + // 验证本次提交的数据是否存在重复(同一批次内不允许重复标签) long count = batchDetailDOList.stream().map(BatchDetailDO::getBatchLabels).distinct().count(); if (batchDetailDOList.size() != count){ throw new ServiceException("批次标签不允许重复,请检查提交的数据"); } + + // 查询当前批次原有的标签明细 List batchDetailDbList = batchDetailMapper.selectList(new QueryWrapper().lambda() .eq(BatchDetail::getBatchId, batchDO.getBatchId())); + + // 如果数据库里已经有明细,并且这次前端传过来的所有明细都没有明细ID, + // 说明前端没有带回原来的主键,这种情况我们视为“完全替换”: + // 先物理删除当前批次下所有旧的明细,再按本次数据重新插入,避免命中数据库唯一索引冲突。 + boolean allNewWithoutId = CollectionUtil.isNotEmpty(batchDetailDOList) + && batchDetailDOList.stream().allMatch(detail -> detail.getBatchDetailId() == null); + if (CollectionUtil.isNotEmpty(batchDetailDbList) && allNewWithoutId) { + batchDetailMapper.delete(new QueryWrapper().lambda() + .eq(BatchDetail::getBatchId, batchDO.getBatchId())); + batchDetailDbList = new ArrayList<>(); + } List batchDetailListSave = new ArrayList<>(); + List batchDetailListSave2 = new ArrayList<>(); List batchDetailListUpdates = new ArrayList<>(); if (CollectionUtil.isNotEmpty(batchDetailDbList)){ - Map batchDetailMap = batchDetailDbList.stream().collect(Collectors.toMap(BatchDetail::getBatchLabels, Function.identity())); + Map batchDetailMap = batchDetailDbList.stream().collect(Collectors.toMap(BatchDetail::getBatchDetailId, Function.identity())); for (BatchDetailDO batchDetailDO : batchDetailDOList){ - BatchDetail batchDetailDb = batchDetailMap.get(batchDetailDO.getBatchLabels()); + BatchDetail batchDetailDb = batchDetailMap.get(batchDetailDO.getBatchDetailId()); if (batchDetailDb != null){ batchDetailDb.setBatchLabels(batchDetailDO.getBatchLabels()); + batchDetailDb.setFieldName(batchDetailDO.getFieldName()); batchDetailDb.setInputControl(batchDetailDO.getInputControl()); batchDetailDb.setAttributeFormat(batchDetailDO.getAttributeFormat()); batchDetailDb.setAttributeOption(batchDetailDO.getAttributeOption()); + batchDetailDb.setIsDisplay(batchDetailDO.getIsDisplay()); batchDetailDb.setRemark(batchDetailDO.getRemark()); batchDetailDb.setDelFlag(1); batchDetailListUpdates.add(batchDetailDb); @@ -96,6 +112,20 @@ public class BatchDetailImpl extends ServiceImpl batchDetailListSave.add(batchDetail); } } + }else { + //是空没有详情 新增 + for (BatchDetailDO batchDetailDO : batchDetailDOList) { + BatchDetail batchDetail = new BatchDetail(); + BeanUtils.copyProperties(batchDetailDO, batchDetail); + batchDetail.setBatchId(batchDO.getBatchId()); + batchDetail.setOrganizationId(batchDO.getOrganizationId()); + batchDetail.setOrganizationName(batchDO.getOrganizationName()); + batchDetail.setTopOrganizationId(batchDO.getTopOrganizationId()); + batchDetail.setCreateBy(userPo.getUserId()); + batchDetail.setCreateByName(userPo.getUserName()); + batchDetail.setCreateTime(new Date()); + batchDetailListSave2.add(batchDetail); + } } //删除 之前存在 现在没有的 List batchDetailIds = batchDetailDbList.stream().map(BatchDetail::getBatchDetailId).collect(Collectors.toList()); @@ -113,6 +143,8 @@ public class BatchDetailImpl extends ServiceImpl //新增 if (CollectionUtil.isNotEmpty(batchDetailListSave)){ saveBatch(batchDetailListSave); + }else if (CollectionUtil.isNotEmpty(batchDetailListSave2)){ + saveBatch(batchDetailListSave2); } //修改 if (CollectionUtil.isNotEmpty(batchDetailListUpdates)){ diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/repository/po/BatchDetailPO.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/repository/po/BatchDetailPO.java index 51ad85366..6d66a4cd6 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/repository/po/BatchDetailPO.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/repository/po/BatchDetailPO.java @@ -45,6 +45,10 @@ public class BatchDetailPO extends BaseVOEntity{ @Excel(name = "批次标签") private String batchLabels; + @ApiModelProperty("字段名称") + @Excel(name = "字段名称") + private String fieldName; + @ApiModelProperty("输入控制: 1-必填 2-可选") @Excel(name = "输入控制: 1-必填 2-可选") private String inputControl; @@ -57,6 +61,10 @@ public class BatchDetailPO extends BaseVOEntity{ @Excel(name = "属性选项") private String attributeOption; + @ApiModelProperty("是否显示: 0-不显示 1-显示") + @Excel(name = "是否显示: 0-不显示 1-显示") + private Integer isDisplay; + @ApiModelProperty("备注") @Excel(name = "备注") private String remark; diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/repository/todo/BatchDetailDO.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/repository/todo/BatchDetailDO.java index 6d4e9ab0c..95cc7033b 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/repository/todo/BatchDetailDO.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/batchDetail/repository/todo/BatchDetailDO.java @@ -1,5 +1,7 @@ package com.mhd.basic.domain.batchDetail.repository.todo; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; import com.mhd.common.core.annotation.Excel; import lombok.Data; import java.util.Date; @@ -23,6 +25,7 @@ public class BatchDetailDO extends BaseVOEntity{ private static final long serialVersionUID = 1L; @ApiModelProperty("批次管理详情id") + @TableId(type = IdType.AUTO) private Long batchDetailId; @ApiModelProperty("组织表ID") @@ -45,6 +48,14 @@ public class BatchDetailDO extends BaseVOEntity{ @Excel(name = "批次标签") private String batchLabels; + @ApiModelProperty("字段名称") + @Excel(name = "字段名称") + private String fieldName; + + @ApiModelProperty("是否显示: 0-不显示 1-显示") + @Excel(name = "是否显示: 0-不显示 1-显示") + private Integer isDisplay; + @ApiModelProperty("输入控制: 1-必填 2-可选") @Excel(name = "输入控制: 1-必填 2-可选") private String inputControl; @@ -57,6 +68,8 @@ public class BatchDetailDO extends BaseVOEntity{ @Excel(name = "属性选项") private String attributeOption; + + @ApiModelProperty("备注") @Excel(name = "备注") private String remark; diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/entity/Lease.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/entity/Lease.java new file mode 100644 index 000000000..a942af918 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/entity/Lease.java @@ -0,0 +1,64 @@ +package com.mhd.basic.domain.lease.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.mhd.common.core.annotation.Excel; +import com.mhd.common.core.web.domain.BaseVOEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 租赁管理对象 container + * + */ + +@Data +public class Lease extends BaseVOEntity{ + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableId(type = IdType.AUTO) + private Long id; + + @ApiModelProperty("组织表ID") + @Excel(name = "组织表ID") + private Long organizationId; + + @ApiModelProperty("组织名称") + @Excel(name = "组织名称") + private String organizationName; + + @ApiModelProperty("一级组织表ID") + @Excel(name = "一级组织表ID") + private Long topOrganizationId; + + @ApiModelProperty("仓库ID") + private Long warehouseId; + + @ApiModelProperty("仓库名字") + private String warehouseName; + + @ApiModelProperty("货主id") + private Long shipperId; + + @ApiModelProperty("货主名称") + private String cargoOwnerName; + + @ApiModelProperty(value = "租赁方式(整租/散租)") + private String leaseType; + + @ApiModelProperty("租赁面积(m²)") + private BigDecimal leaseArea; + + @ApiModelProperty("开始日期") + private Date startDate; + + @ApiModelProperty("结束日期") + private Date endDate; + + @ApiModelProperty("备注") + private String remark; +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/facade/ILeaseService.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/facade/ILeaseService.java new file mode 100644 index 000000000..a7de83151 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/facade/ILeaseService.java @@ -0,0 +1,43 @@ +package com.mhd.basic.domain.lease.repository.facade; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.mhd.basic.domain.lease.entity.Lease; +import com.mhd.basic.domain.lease.repository.po.LeasePO; +import com.mhd.basic.domain.lease.repository.todo.LeaseDO; + +import java.util.List; + +/** + * 租赁管理Service接口 + * + * @author gen + * @date 2024-05-07 + */ +public interface ILeaseService extends IService +{ + /** + * 分页查询租赁管理列表 + */ + public List queryList(LeaseDO leaseDO); + + /** + * 新增租赁管理 + */ + public Boolean insert(LeaseDO leaseDO); + + /** + * 修改租赁管理 + */ + public Boolean update(LeaseDO leaseDO); + + /** + * 批量删除租赁管理 + */ + public Boolean delete(Long[] leaseIds); + + + /** + * 查询租赁管理 + */ + public LeasePO getInfo(Long leaseId); +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/mapper/LeaseMapper.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/mapper/LeaseMapper.java new file mode 100644 index 000000000..2d38584a2 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/mapper/LeaseMapper.java @@ -0,0 +1,21 @@ +package com.mhd.basic.domain.lease.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.mhd.basic.domain.lease.entity.Lease; +import com.mhd.basic.domain.lease.repository.po.LeasePO; +import com.mhd.basic.domain.lease.repository.todo.LeaseDO; + +import java.util.List; + +/** + * 租赁管理Mapper接口 + * + */ +public interface LeaseMapper extends BaseMapper +{ + /** + * 查询租赁管理列表 + */ + public List queryList(LeaseDO leaseDO); + +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/persistence/LeaseImpl.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/persistence/LeaseImpl.java new file mode 100644 index 000000000..208ba54a7 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/persistence/LeaseImpl.java @@ -0,0 +1,114 @@ +package com.mhd.basic.domain.lease.repository.persistence; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.mhd.basic.domain.lease.entity.Lease; +import com.mhd.basic.domain.lease.repository.facade.ILeaseService; +import com.mhd.basic.domain.lease.repository.mapper.LeaseMapper; +import com.mhd.basic.domain.lease.repository.po.LeasePO; +import com.mhd.basic.domain.lease.repository.todo.LeaseDO; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.model.LoginUser; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 容器管理Service业务层处理 + * + * @author gen + * @date 2024-05-07 + */ +@Service +public class LeaseImpl extends ServiceImpl implements ILeaseService { + @Autowired + private LeaseMapper leaseMapper; + + /** + * 查询容器管理列表 + */ + @Override + public List queryList(LeaseDO leaseDO) + { + return leaseMapper.queryList(leaseDO); + } + + /** + * 新增容器管理 + */ + @Override + public Boolean insert(LeaseDO leaseDO) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + Lease lease = new Lease(); + BeanUtils.copyProperties(leaseDO,lease); + return this.save(lease); + } + + /** + * 修改容器管理 + */ + @Override + public Boolean update(LeaseDO leaseDO) { + Lease lease = new Lease(); + BeanUtils.copyProperties(leaseDO,lease); + return this.updateById(lease); + } + + /** + * 批量删除容器管理 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean delete(Long[] leaseIds ) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + List list = new ArrayList<>(); + for (Long id : leaseIds) { + Lease lease = new Lease(); + lease.setId(id); + lease.setDelFlag(2); + lease.setUpdateBy(loginUser.getUserid()); + lease.setUpdateByName(loginUser.getUsername()); + lease.setUpdateTime(new Date()); + list.add(lease); + } + return this.updateBatchById(list); + } + + /** + * 修改容器管理 + */ + @Override + public LeasePO getInfo(Long leaseId) { + Lease lease = this.getById(leaseId); + LeasePO leasePO = new LeasePO(); + BeanUtils.copyProperties(lease,leasePO); + return leasePO; + } + +// /** +// * @description 校验唯一 +// * @author ZhouGY +// * @date 2024/5/9 21:10 +// * @param containerDO +// */ +// private void verifyUniqueness(ContainerDO containerDO){ +// LoginUser loginUser = SecurityUtils.getLoginUser(); +// Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); +// if (topOrganizationId == null || topOrganizationId == 0 ){ +// throw new ServiceException("获取当前登陆人组织失败!"); +// } +// int count = leaseMapper.selectCount(new QueryWrapper().lambda() +// .eq(Container::getTopOrganizationId, topOrganizationId) +// .eq(Container::getContainerCode,containerDO.getContainerCode()) +// .eq(Container::getOrganizationId, containerDO.getOrganizationId()) +// .ne(containerDO.getContainerId() != null, Container::getContainerId, containerDO.getContainerId() ) +// .eq(Container::getDelFlag,1)); +// if (count > 0){ +// throw new ServiceException("容器编码【" + containerDO.getContainerCode() + "】已存在"); +// } +// } +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/po/LeasePO.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/po/LeasePO.java new file mode 100644 index 000000000..b934f01ad --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/po/LeasePO.java @@ -0,0 +1,67 @@ +package com.mhd.basic.domain.lease.repository.po; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.mhd.common.core.annotation.Excel; +import com.mhd.common.core.web.domain.BaseVOEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 租赁管理对象 container + * + */ + +@Data +public class LeasePO extends BaseVOEntity{ + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("组织表ID") + @Excel(name = "组织表ID") + private Long organizationId; + + @ApiModelProperty("组织名称") + @Excel(name = "组织名称") + private String organizationName; + + @ApiModelProperty("一级组织表ID") + @Excel(name = "一级组织表ID") + private Long topOrganizationId; + + @ApiModelProperty("仓库ID") + private Long warehouseId; + + @ApiModelProperty("仓库名字") + private String warehouseName; + + @ApiModelProperty("货主id") + private Long shipperId; + + @ApiModelProperty("货主名称") + private String cargoOwnerName; + + @ApiModelProperty(value = "租赁方式(整租/散租)") + private String leaseType; + + @ApiModelProperty("租赁面积(m²)") + private BigDecimal leaseArea; + + @ApiModelProperty("开始日期") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + private Date startDate; + + @ApiModelProperty("结束日期") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + private Date endDate; + + @ApiModelProperty("备注") + private String remark; +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/todo/LeaseDO.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/todo/LeaseDO.java new file mode 100644 index 000000000..41a2a2e5d --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/repository/todo/LeaseDO.java @@ -0,0 +1,82 @@ +package com.mhd.basic.domain.lease.repository.todo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.mhd.common.core.annotation.Excel; +import com.mhd.common.core.web.domain.BaseVOEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 租赁管理对象 container + * + */ + +@Data +public class LeaseDO extends BaseVOEntity{ + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("组织表ID") + @Excel(name = "组织表ID") + private Long organizationId; + + @ApiModelProperty("组织名称") + @Excel(name = "组织名称") + private String organizationName; + + @ApiModelProperty("一级组织表ID") + @Excel(name = "一级组织表ID") + private Long topOrganizationId; + + @ApiModelProperty("仓库ID") + private Long warehouseId; + + @ApiModelProperty("仓库名字") + private String warehouseName; + + @ApiModelProperty("货主id") + private Long shipperId; + + @ApiModelProperty("货主名称") + private String cargoOwnerName; + + @ApiModelProperty(value = "租赁方式(整租/散租)") + private String leaseType; + + @ApiModelProperty("租赁面积(m²)") + private BigDecimal leaseArea; + + @ApiModelProperty("开始日期") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date startDate; + + @ApiModelProperty("结束日期") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date endDate; + + @ApiModelProperty("备注") + private String remark; + + @ApiModelProperty("当前时间") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date time; + + @ApiModelProperty(name = "创建时间查询条件开始日期") + private String createTimeStart; + + @ApiModelProperty(name = "创建时间查询条件结束日期") + private String createTimeEnd; + + @ApiModelProperty(name = "修改时间查询条件开始日期") + private String updateTimeStart; + + @ApiModelProperty(name = "修改时间查询条件结束日期") + private String updateTimeEnd; +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/service/LeaseDomainService.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/service/LeaseDomainService.java new file mode 100644 index 000000000..20c5cff06 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/lease/service/LeaseDomainService.java @@ -0,0 +1,87 @@ +package com.mhd.basic.domain.lease.service; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.mhd.basic.domain.container.entity.Container; +import com.mhd.basic.domain.container.repository.facade.IContainerService; +import com.mhd.basic.domain.container.repository.po.ContainerPO; +import com.mhd.basic.domain.container.repository.todo.ContainerDO; +import com.mhd.basic.domain.lease.entity.Lease; +import com.mhd.basic.domain.lease.repository.facade.ILeaseService; +import com.mhd.basic.domain.lease.repository.po.LeasePO; +import com.mhd.basic.domain.lease.repository.todo.LeaseDO; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.model.LoginUser; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; + +/** + * 租赁管理 + * + */ +@Service +@Slf4j +public class LeaseDomainService { + + @Autowired + private ILeaseService leaseService; + + + /** + * 分页查询租赁管理列表 + */ + public List queryList(LeaseDO leaseDO) { + return leaseService.queryList(leaseDO); + } + + + /** + * 新增租赁管理 + */ + public Boolean insert(LeaseDO leaseDO) { + + return leaseService.insert(leaseDO); + } + + /** + * 修改租赁管理 + */ + public Boolean update(LeaseDO leaseDO) { + return leaseService.update(leaseDO); + } + + /** + * 批量删除租赁管理 + */ + public Boolean delete(Long[] leaseIds) { + return leaseService.delete(leaseIds); + } + + /** + * 获取租赁管理详细信息 + */ + public LeasePO getInfo(Long leaseId) + { + return leaseService.getInfo(leaseId); + } + + + /** + * @description 批量作废租赁 + * @author ZhouGY + * @date 2024/5/13 9:46 + * @param leaseIds + * @return Boolean + */ + public Boolean nullifyByIds(List leaseIds) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + return leaseService.update(new UpdateWrapper().lambda() + .set(Lease::getUpdateBy, loginUser.getUserid()) + .set(Lease::getUpdateTime, new Date()) + .in(Lease::getId, leaseIds) + .eq(Lease::getDelFlag, 1)); + } +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/materialBaseInfo/entity/MaterialBaseInfo.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/materialBaseInfo/entity/MaterialBaseInfo.java index 9215e874f..01955b43f 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/materialBaseInfo/entity/MaterialBaseInfo.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/materialBaseInfo/entity/MaterialBaseInfo.java @@ -158,6 +158,7 @@ public class MaterialBaseInfo extends BaseVOEntity{ @ApiModelProperty("单位数量") @Excel(name = "单位数量") + @TableField(exist = false) private BigDecimal unitNumber; @ApiModelProperty("是否公用: 1-是 2-否") @@ -184,4 +185,204 @@ public class MaterialBaseInfo extends BaseVOEntity{ @ApiModelProperty("整机编码") @Excel(name = "整机编号") private String machineCode; -} + + /** + * 商品名称 + */ + @ApiModelProperty("商品名称") + @Excel(name = "商品名称") + @TableField(exist = false) + private String commodityName; + /** + * 商品编码 + */ + @ApiModelProperty("商品编码") + @Excel(name = "商品编码") + @TableField(exist = false) + private String commodityNo; + /** + * 料号 + */ + @ApiModelProperty("料号") + @Excel(name = "料号") + @TableField(exist = false) + private String materialNo; + /** + * 规格型号 + */ + @ApiModelProperty("规格型号") + @Excel(name = "规格型号") + @TableField(exist = false) + private String specificationModel; + /** + * Invoice No + */ + @ApiModelProperty("Invoice No") + @Excel(name = "Invoice No") + @TableField(exist = false) + private String invoiceNo; + /** + * 升 + */ + @ApiModelProperty("升") + @Excel(name = "升") + @TableField(exist = false) + private String liter; + + /** + * 尺寸 + */ + @ApiModelProperty("尺寸") + @Excel(name = "尺寸") + @TableField(exist = false) + private String size; + + /** + * 申报单位 + */ + @ApiModelProperty("申报单位") + @Excel(name = "申报单位") + @TableField(exist = false) + private String declareUnit; + + /** + * Batch Ref NO's + */ + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + @TableField(exist = false) + private String batchRefNo; + + /** + * Sheet Ref NO's + */ + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + @TableField(exist = false) + private String sheetRefNo; + + /** + * 原产国 + */ + @ApiModelProperty("原产国") + @Excel(name = "原产国") + @TableField(exist = false) + private String countryOfOrigin; + + /** + * 箱号/卡板号 + */ + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + @TableField(exist = false) + private String casePalletNo; + + /** + * 币制 + */ + @ApiModelProperty("币制") + @Excel(name = "币制") + private String currency; + + /** + * 申报数量 + */ + @ApiModelProperty("申报数量") + @Excel(name = "申报数量") + @TableField(exist = false) + private Double declareQuantity; + + /** + * 箱数 + */ + @ApiModelProperty("箱数") + @Excel(name = "箱数") + @TableField(exist = false) + private Double caseCount; + + /** + * 件数 + */ + @ApiModelProperty("件数") + @Excel(name = "件数") + @TableField(exist = false) + private Double pieceCount; + + /** + * 出库数量 + */ + @ApiModelProperty("出库数量") + @Excel(name = "出库数量") + @TableField(exist = false) + private Double outboundQuantity; + + /** + * 总净重(KG) + */ + @ApiModelProperty("总净重(KG)") + @Excel(name = "总净重(KG)") + @TableField(exist = false) + private Double totalNetWeight; + + /** + * 总毛重(KG) + */ + @ApiModelProperty("总毛重(KG)") + @Excel(name = "总毛重(KG)") + @TableField(exist = false) + private Double totalGrossWeight; + + /** + * 总体积(CBM) + */ + @ApiModelProperty("总体积(CBM)") + @Excel(name = "总体积(CBM)") + @TableField(exist = false) + private Double totalVolume; + + /** + * 总面积(SQM) + */ + @ApiModelProperty("总面积(SQM)") + @Excel(name = "总面积(SQM)") + @TableField(exist = false) + private Double totalArea; + /** + * 总价 + */ + @ApiModelProperty("总价") + @Excel(name = "总价") + @TableField(exist = false) + private Double totalAmount; + + /** + * 单位 + */ + @ApiModelProperty("单位") + @Excel(name = "单位") + @TableField(exist = false) + private String unit; + + + @ApiModelProperty("SKU码") + private String skuCode; + + @ApiModelProperty("单价") + private BigDecimal unitPrice; + + + @ApiModelProperty("原产国") + private String originCountry; + + @ApiModelProperty("HS码") + private String hsCode; + + @ApiModelProperty("申报单位") + private String declarationUnit; + + @ApiModelProperty("法定单位") + private String statutoryUnit; + + @ApiModelProperty("法定第二单位") + private String statutorySecondUnit; +} \ No newline at end of file diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/materialBaseInfo/repository/po/MaterialBaseInfoPO.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/materialBaseInfo/repository/po/MaterialBaseInfoPO.java index 1b9bae270..a93bec1f0 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/materialBaseInfo/repository/po/MaterialBaseInfoPO.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/materialBaseInfo/repository/po/MaterialBaseInfoPO.java @@ -5,6 +5,7 @@ import com.mhd.basic.domain.batch.repository.po.BatchPO; import com.mhd.common.core.annotation.Excel; import com.mhd.common.core.handler.ListTypeHandler; import com.mhd.common.core.web.domain.BaseVOEntity; +import com.mhd.system.api.domain.*; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -182,4 +183,197 @@ public class MaterialBaseInfoPO extends BaseVOEntity{ @Excel(name = "整机编号") private String machineCode; -} + + /** + * 商品名称 + */ + @ApiModelProperty("商品名称") + @Excel(name = "商品名称") + private String commodityName; + /** + * 商品编码 + */ + @ApiModelProperty("商品编码") + @Excel(name = "商品编码") + private String commodityNo; + /** + * 料号 + */ + @ApiModelProperty("料号") + @Excel(name = "料号") + private String materialNo; + /** + * 规格型号 + */ + @ApiModelProperty("规格型号") + @Excel(name = "规格型号") + private String specificationModel; + /** + * Invoice No + */ + @ApiModelProperty("Invoice No") + @Excel(name = "Invoice No") + private String invoiceNo; + /** + * 升 + */ + @ApiModelProperty("升") + @Excel(name = "升") + private String liter; + + /** + * 尺寸 + */ + @ApiModelProperty("尺寸") + @Excel(name = "尺寸") + private String size; + + /** + * 申报单位 + */ + @ApiModelProperty("申报单位") + @Excel(name = "申报单位") + private String declareUnit; + + /** + * Batch Ref NO’s + */ + @ApiModelProperty("Batch Ref NO’s") + @Excel(name = "Batch Ref NO’s") + private String batchRefNo; + + /** + * Sheet Ref NO’s + */ + @ApiModelProperty("Sheet Ref NO’s") + @Excel(name = "Sheet Ref NO’s") + private String sheetRefNo; + + /** + * 原产国 + */ + @ApiModelProperty("原产国") + @Excel(name = "原产国") + private String countryOfOrigin; + + /** + * 箱号/卡板号 + */ + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String casePalletNo; + + /** + * 币制 + */ + @ApiModelProperty("币制") + @Excel(name = "币制") + private String currency; + + /** + * 申报数量 + */ + @ApiModelProperty("申报数量") + @Excel(name = "申报数量") + private Double declareQuantity; + + /** + * 箱数 + */ + @ApiModelProperty("箱数") + @Excel(name = "箱数") + private Double caseCount; + + /** + * 件数 + */ + @ApiModelProperty("件数") + @Excel(name = "件数") + private Double pieceCount; + + /** + * 出库数量 + */ + @ApiModelProperty("出库数量") + @Excel(name = "出库数量") + private Double outboundQuantity; + + /** + * 总净重(KG) + */ + @ApiModelProperty("总净重(KG)") + @Excel(name = "总净重(KG)") + private Double totalNetWeight; + + /** + * 总毛重(KG) + */ + @ApiModelProperty("总毛重(KG)") + @Excel(name = "总毛重(KG)") + private Double totalGrossWeight; + + /** + * 总体积(CBM) + */ + @ApiModelProperty("总体积(CBM)") + @Excel(name = "总体积(CBM)") + private Double totalVolume; + + /** + * 总面积(SQM) + */ + @ApiModelProperty("总面积(SQM)") + @Excel(name = "总面积(SQM)") + private Double totalArea; + /** + * 总价 + */ + @ApiModelProperty("总价") + @Excel(name = "总价") + private Double totalAmount; + + /** + * 单位 + */ + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unit; + + + @ApiModelProperty("SKU码") + private String skuCode; + + @ApiModelProperty("单价") + private BigDecimal unitPrice; + + @ApiModelProperty("原产国") + private String originCountry; + + @ApiModelProperty("HS码") + private String hsCode; + + @ApiModelProperty("申报单位") + private String declarationUnit; + + @ApiModelProperty("法定单位") + private String statutoryUnit; + + @ApiModelProperty("法定第二单位") + private String statutorySecondUnit; + + @ApiModelProperty("商品规则") + private MaterialGoodsRuleFeign materialGoodsRule; + + @ApiModelProperty("公共信息") + private MaterialCommonFeign materialCommon; + + @ApiModelProperty("仓库控制信息") + private MaterialWarehouseControlFeign materialWarehouseControl; + + @ApiModelProperty("库存预警信息") + private List materialInventoryWarningList; + + @ApiModelProperty("条码信息") + private List materialBarCodeList; + +} \ No newline at end of file diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/materialBaseInfo/repository/todo/MaterialBaseInfoDO.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/materialBaseInfo/repository/todo/MaterialBaseInfoDO.java index b688b22fa..aeb53ba58 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/materialBaseInfo/repository/todo/MaterialBaseInfoDO.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/materialBaseInfo/repository/todo/MaterialBaseInfoDO.java @@ -203,4 +203,182 @@ public class MaterialBaseInfoDO extends BaseVOEntity{ @ApiModelProperty("整机编码") @Excel(name = "整机编号") private String machineCode; -} + + + /** + * 商品名称 + */ + @ApiModelProperty("商品名称") + @Excel(name = "商品名称") + private String commodityName; + /** + * 商品编码 + */ + @ApiModelProperty("商品编码") + @Excel(name = "商品编码") + private String commodityNo; + /** + * 料号 + */ + @ApiModelProperty("料号") + @Excel(name = "料号") + private String materialNo; + /** + * 规格型号 + */ + @ApiModelProperty("规格型号") + @Excel(name = "规格型号") + private String specificationModel; + /** + * Invoice No + */ + @ApiModelProperty("Invoice No") + @Excel(name = "Invoice No") + private String invoiceNo; + /** + * 升 + */ + @ApiModelProperty("升") + @Excel(name = "升") + private String liter; + + /** + * 尺寸 + */ + @ApiModelProperty("尺寸") + @Excel(name = "尺寸") + private String size; + + /** + * 申报单位 + */ + @ApiModelProperty("申报单位") + @Excel(name = "申报单位") + private String declareUnit; + + /** + * Batch Ref NO’s + */ + @ApiModelProperty("Batch Ref NO’s") + @Excel(name = "Batch Ref NO’s") + private String batchRefNo; + + /** + * Sheet Ref NO’s + */ + @ApiModelProperty("Sheet Ref NO’s") + @Excel(name = "Sheet Ref NO’s") + private String sheetRefNo; + + /** + * 原产国 + */ + @ApiModelProperty("原产国") + @Excel(name = "原产国") + private String countryOfOrigin; + + /** + * 箱号/卡板号 + */ + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String casePalletNo; + + /** + * 币制 + */ + @ApiModelProperty("币制") + @Excel(name = "币制") + private String currency; + + /** + * 申报数量 + */ + @ApiModelProperty("申报数量") + @Excel(name = "申报数量") + private Double declareQuantity; + + /** + * 箱数 + */ + @ApiModelProperty("箱数") + @Excel(name = "箱数") + private Double caseCount; + + /** + * 件数 + */ + @ApiModelProperty("件数") + @Excel(name = "件数") + private Double pieceCount; + + /** + * 出库数量 + */ + @ApiModelProperty("出库数量") + @Excel(name = "出库数量") + private Double outboundQuantity; + + /** + * 总净重(KG) + */ + @ApiModelProperty("总净重(KG)") + @Excel(name = "总净重(KG)") + private Double totalNetWeight; + + /** + * 总毛重(KG) + */ + @ApiModelProperty("总毛重(KG)") + @Excel(name = "总毛重(KG)") + private Double totalGrossWeight; + + /** + * 总体积(CBM) + */ + @ApiModelProperty("总体积(CBM)") + @Excel(name = "总体积(CBM)") + private Double totalVolume; + + /** + * 总面积(SQM) + */ + @ApiModelProperty("总面积(SQM)") + @Excel(name = "总面积(SQM)") + private Double totalArea; + /** + * 总价 + */ + @ApiModelProperty("总价") + @Excel(name = "总价") + private Double totalAmount; + + /** + * 单位 + */ + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unit; + + + @ApiModelProperty("SKU码") + private String skuCode; + + @ApiModelProperty("单价") + private BigDecimal unitPrice; + + @ApiModelProperty("原产国") + private String originCountry; + + @ApiModelProperty("HS码") + private String hsCode; + + @ApiModelProperty("申报单位") + private String declarationUnit; + + @ApiModelProperty("法定单位") + private String statutoryUnit; + + @ApiModelProperty("法定第二单位") + private String statutorySecondUnit; +} \ No newline at end of file diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/pack/repository/po/PackPO.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/pack/repository/po/PackPO.java index 066989566..049b1e7bf 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/pack/repository/po/PackPO.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/pack/repository/po/PackPO.java @@ -68,6 +68,10 @@ public class PackPO extends BaseVOEntity{ @Excel(name = "是否作废: 1-否 2-是") private Integer nullify; + @ApiModelProperty("包装单位(取第一条包装详情的单位名称)") + @Excel(name = "包装单位") + private String unitName; + @ApiModelProperty("包装明细") private List packDetailList; diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/entity/ShipperLeaseDetails.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/entity/ShipperLeaseDetails.java new file mode 100644 index 000000000..5a041d453 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/entity/ShipperLeaseDetails.java @@ -0,0 +1,65 @@ +package com.mhd.basic.domain.shipperLeaseDetails.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.mhd.common.core.annotation.Excel; +import com.mhd.common.core.web.domain.BaseVOEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 货主租赁明细 + * + */ + +@Data +public class ShipperLeaseDetails extends BaseVOEntity{ + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableId(type = IdType.AUTO) + private Long id; + + @ApiModelProperty("组织表ID") + @Excel(name = "组织表ID") + private Long organizationId; + + @ApiModelProperty("组织名称") + @Excel(name = "组织名称") + private String organizationName; + + @ApiModelProperty("一级组织表ID") + @Excel(name = "一级组织表ID") + private Long topOrganizationId; + + @ApiModelProperty("仓库ID") + private Long warehouseId; + + @ApiModelProperty("仓库名字") + private String warehouseName; + + @ApiModelProperty("货主id") + private Long shipperId; + + @ApiModelProperty("货主名称") + private String cargoOwnerName; + + @ApiModelProperty(value = "租赁方式(整租/散租)") + private String leaseType; + + @ApiModelProperty("租赁面积(m²)") + private BigDecimal leaseArea; + + @ApiModelProperty("业务日期") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + private Date businessDate; + + + +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/entity/WarehouseOccupancyRate.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/entity/WarehouseOccupancyRate.java new file mode 100644 index 000000000..31c008c60 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/entity/WarehouseOccupancyRate.java @@ -0,0 +1,58 @@ +package com.mhd.basic.domain.shipperLeaseDetails.entity; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.mhd.common.core.annotation.Excel; +import com.mhd.common.core.web.domain.BaseVOEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 仓库出租率返回类 没有表 + * + */ + +@Data +public class WarehouseOccupancyRate extends BaseVOEntity{ + private static final long serialVersionUID = 1L; + + + @ApiModelProperty("组织表ID") + @Excel(name = "组织表ID") + private Long organizationId; + + @ApiModelProperty("组织名称") + @Excel(name = "组织名称") + private String organizationName; + + @ApiModelProperty("一级组织表ID") + @Excel(name = "一级组织表ID") + private Long topOrganizationId; + + @ApiModelProperty("仓库ID") + private Long warehouseId; + + @ApiModelProperty("仓库名字") + private String warehouseName; + + @ApiModelProperty("业务日期") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + private Date businessDate; + + @ApiModelProperty("整租面积(m²)") + private BigDecimal entireLeaseArea; + + @ApiModelProperty("散租面积(m²)") + private BigDecimal fractionalLeaseArea; + + @ApiModelProperty("总面积(m²)") + private BigDecimal totalArea; + + @ApiModelProperty("日租率(%)") + private BigDecimal dailyRentalRate; + +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/facade/IShipperLeaseDetailsService.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/facade/IShipperLeaseDetailsService.java new file mode 100644 index 000000000..d086cd185 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/facade/IShipperLeaseDetailsService.java @@ -0,0 +1,43 @@ +package com.mhd.basic.domain.shipperLeaseDetails.repository.facade; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.mhd.basic.domain.shipperLeaseDetails.entity.ShipperLeaseDetails; +import com.mhd.basic.domain.shipperLeaseDetails.repository.po.ShipperLeaseDetailsPO; +import com.mhd.basic.domain.shipperLeaseDetails.repository.todo.ShipperLeaseDetailsDO; + +import java.util.List; + +/** + * 货主租赁明细Service接口 + * + * @author gen + * @date 2024-05-07 + */ +public interface IShipperLeaseDetailsService extends IService +{ + /** + * 分页查询货主租赁明细列表 + */ + public List queryList(ShipperLeaseDetailsDO shipperLeaseDetailsDO); + + /** + * 新增货主租赁明细 + */ + public Boolean insert(ShipperLeaseDetailsDO shipperLeaseDetailsDO); + + /** + * 修改货主租赁明细 + */ + public Boolean update(ShipperLeaseDetailsDO shipperLeaseDetailsDO); + + /** + * 批量删除货主租赁明细 + */ + public Boolean delete(Long[] leaseIds); + + + /** + * 查询货主租赁明细 + */ + public ShipperLeaseDetailsPO getInfo(Long leaseId); +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/mapper/ShipperLeaseDetailsMapper.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/mapper/ShipperLeaseDetailsMapper.java new file mode 100644 index 000000000..09758148e --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/mapper/ShipperLeaseDetailsMapper.java @@ -0,0 +1,21 @@ +package com.mhd.basic.domain.shipperLeaseDetails.repository.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.mhd.basic.domain.shipperLeaseDetails.entity.ShipperLeaseDetails; +import com.mhd.basic.domain.shipperLeaseDetails.repository.po.ShipperLeaseDetailsPO; +import com.mhd.basic.domain.shipperLeaseDetails.repository.todo.ShipperLeaseDetailsDO; + +import java.util.List; + +/** + * 货主租赁明细Mapper接口 + * + */ +public interface ShipperLeaseDetailsMapper extends BaseMapper +{ + /** + * 查询货主租赁明细列表 + */ + public List queryList(ShipperLeaseDetailsDO shipperLeaseDetailsDO); + +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/persistence/ShipperLeaseDetailsImpl.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/persistence/ShipperLeaseDetailsImpl.java new file mode 100644 index 000000000..955922e4a --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/persistence/ShipperLeaseDetailsImpl.java @@ -0,0 +1,114 @@ +package com.mhd.basic.domain.shipperLeaseDetails.repository.persistence; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.mhd.basic.domain.shipperLeaseDetails.entity.ShipperLeaseDetails; +import com.mhd.basic.domain.shipperLeaseDetails.repository.facade.IShipperLeaseDetailsService; +import com.mhd.basic.domain.shipperLeaseDetails.repository.mapper.ShipperLeaseDetailsMapper; +import com.mhd.basic.domain.shipperLeaseDetails.repository.po.ShipperLeaseDetailsPO; +import com.mhd.basic.domain.shipperLeaseDetails.repository.todo.ShipperLeaseDetailsDO; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.model.LoginUser; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 货主租赁明细Service业务层处理 + * + * @author gen + * @date 2024-05-07 + */ +@Service +public class ShipperLeaseDetailsImpl extends ServiceImpl implements IShipperLeaseDetailsService { + @Autowired + private ShipperLeaseDetailsMapper shipperLeaseDetailsMapper; + + /** + * 查询货主租赁明细列表 + */ + @Override + public List queryList(ShipperLeaseDetailsDO shipperLeaseDetailsDO) + { + return shipperLeaseDetailsMapper.queryList(shipperLeaseDetailsDO); + } + + /** + * 新增货主租赁明细 + */ + @Override + public Boolean insert(ShipperLeaseDetailsDO shipperLeaseDetailsDO) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + ShipperLeaseDetails shipperLeaseDetails = new ShipperLeaseDetails(); + BeanUtils.copyProperties(shipperLeaseDetailsDO,shipperLeaseDetails); + return this.save(shipperLeaseDetails); + } + + /** + * 修改货主租赁明细 + */ + @Override + public Boolean update(ShipperLeaseDetailsDO shipperLeaseDetailsDO) { + ShipperLeaseDetails shipperLeaseDetails = new ShipperLeaseDetails(); + BeanUtils.copyProperties(shipperLeaseDetailsDO,shipperLeaseDetails); + return this.updateById(shipperLeaseDetails); + } + + /** + * 批量删除货主租赁明细 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean delete(Long[] leaseIds ) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + List list = new ArrayList<>(); + for (Long id : leaseIds) { + ShipperLeaseDetails shipperLeaseDetails = new ShipperLeaseDetails(); + shipperLeaseDetails.setId(id); + shipperLeaseDetails.setDelFlag(2); + shipperLeaseDetails.setUpdateBy(loginUser.getUserid()); + shipperLeaseDetails.setUpdateByName(loginUser.getUsername()); + shipperLeaseDetails.setUpdateTime(new Date()); + list.add(shipperLeaseDetails); + } + return this.updateBatchById(list); + } + + /** + * 修改货主租赁明细 + */ + @Override + public ShipperLeaseDetailsPO getInfo(Long ShipperLeaseDetailsId) { + ShipperLeaseDetails shipperLeaseDetails = this.getById(ShipperLeaseDetailsId); + ShipperLeaseDetailsPO shipperLeaseDetailsPO = new ShipperLeaseDetailsPO(); + BeanUtils.copyProperties(shipperLeaseDetails,shipperLeaseDetailsPO); + return shipperLeaseDetailsPO; + } + +// /** +// * @description 校验唯一 +// * @author ZhouGY +// * @date 2024/5/9 21:10 +// * @param containerDO +// */ +// private void verifyUniqueness(ContainerDO containerDO){ +// LoginUser loginUser = SecurityUtils.getLoginUser(); +// Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); +// if (topOrganizationId == null || topOrganizationId == 0 ){ +// throw new ServiceException("获取当前登陆人组织失败!"); +// } +// int count = leaseMapper.selectCount(new QueryWrapper().lambda() +// .eq(Container::getTopOrganizationId, topOrganizationId) +// .eq(Container::getContainerCode,containerDO.getContainerCode()) +// .eq(Container::getOrganizationId, containerDO.getOrganizationId()) +// .ne(containerDO.getContainerId() != null, Container::getContainerId, containerDO.getContainerId() ) +// .eq(Container::getDelFlag,1)); +// if (count > 0){ +// throw new ServiceException("容器编码【" + containerDO.getContainerCode() + "】已存在"); +// } +// } +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/po/ShipperLeaseDetailsPO.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/po/ShipperLeaseDetailsPO.java new file mode 100644 index 000000000..5d945a943 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/po/ShipperLeaseDetailsPO.java @@ -0,0 +1,65 @@ +package com.mhd.basic.domain.shipperLeaseDetails.repository.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.mhd.common.core.annotation.Excel; +import com.mhd.common.core.web.domain.BaseVOEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 货主租赁明细 + * + */ + +@Data +public class ShipperLeaseDetailsPO extends BaseVOEntity{ + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableId(type = IdType.AUTO) + private Long id; + + @ApiModelProperty("组织表ID") + @Excel(name = "组织表ID") + private Long organizationId; + + @ApiModelProperty("组织名称") + @Excel(name = "组织名称") + private String organizationName; + + @ApiModelProperty("一级组织表ID") + @Excel(name = "一级组织表ID") + private Long topOrganizationId; + + @ApiModelProperty("仓库ID") + private Long warehouseId; + + @ApiModelProperty("仓库名字") + private String warehouseName; + + @ApiModelProperty("货主id") + private Long shipperId; + + @ApiModelProperty("货主名称") + private String cargoOwnerName; + + @ApiModelProperty(value = "租赁方式(整租/散租)") + private String leaseType; + + @ApiModelProperty("租赁面积(m²)") + private BigDecimal leaseArea; + + @ApiModelProperty("业务日期") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + private Date businessDate; + + + +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/todo/ShipperLeaseDetailsDO.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/todo/ShipperLeaseDetailsDO.java new file mode 100644 index 000000000..9e8d08373 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/repository/todo/ShipperLeaseDetailsDO.java @@ -0,0 +1,73 @@ +package com.mhd.basic.domain.shipperLeaseDetails.repository.todo; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.mhd.common.core.annotation.Excel; +import com.mhd.common.core.web.domain.BaseVOEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 货主租赁明细 + * + */ + +@Data +public class ShipperLeaseDetailsDO extends BaseVOEntity{ + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableId(type = IdType.AUTO) + private Long id; + + @ApiModelProperty("组织表ID") + @Excel(name = "组织表ID") + private Long organizationId; + + @ApiModelProperty("组织名称") + @Excel(name = "组织名称") + private String organizationName; + + @ApiModelProperty("一级组织表ID") + @Excel(name = "一级组织表ID") + private Long topOrganizationId; + + @ApiModelProperty("仓库ID") + private Long warehouseId; + + @ApiModelProperty("仓库名字") + private String warehouseName; + + @ApiModelProperty("货主id") + private Long shipperId; + + @ApiModelProperty("货主名称") + private String cargoOwnerName; + + @ApiModelProperty(value = "租赁方式(整租/散租)") + private String leaseType; + + @ApiModelProperty("租赁面积(m²)") + private BigDecimal leaseArea; + + @ApiModelProperty("业务日期") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + private Date businessDate; + + @ApiModelProperty("业务日期开始时间") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + private Date businessDateStart; + + @ApiModelProperty("业务日期结束时间") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + private Date businessDateEnd; + +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/service/ShipperLeaseDetailsDomainService.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/service/ShipperLeaseDetailsDomainService.java new file mode 100644 index 000000000..ac63d9e88 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/domain/shipperLeaseDetails/service/ShipperLeaseDetailsDomainService.java @@ -0,0 +1,87 @@ +package com.mhd.basic.domain.shipperLeaseDetails.service; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.mhd.basic.domain.lease.entity.Lease; +import com.mhd.basic.domain.lease.repository.facade.ILeaseService; +import com.mhd.basic.domain.lease.repository.po.LeasePO; +import com.mhd.basic.domain.lease.repository.todo.LeaseDO; +import com.mhd.basic.domain.shipperLeaseDetails.entity.ShipperLeaseDetails; +import com.mhd.basic.domain.shipperLeaseDetails.repository.facade.IShipperLeaseDetailsService; +import com.mhd.basic.domain.shipperLeaseDetails.repository.po.ShipperLeaseDetailsPO; +import com.mhd.basic.domain.shipperLeaseDetails.repository.todo.ShipperLeaseDetailsDO; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.model.LoginUser; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; + +/** + * 租赁管理 + * + */ +@Service +@Slf4j +public class ShipperLeaseDetailsDomainService { + + @Autowired + private IShipperLeaseDetailsService shipperLeaseDetailsService; + + + /** + * 分页查询租赁管理列表 + */ + public List queryList(ShipperLeaseDetailsDO shipperLeaseDetailsDO) { + return shipperLeaseDetailsService.queryList(shipperLeaseDetailsDO); + } + + + /** + * 新增租赁管理 + */ + public Boolean insert(ShipperLeaseDetailsDO shipperLeaseDetailsDO) { + + return shipperLeaseDetailsService.insert(shipperLeaseDetailsDO); + } + + /** + * 修改租赁管理 + */ + public Boolean update(ShipperLeaseDetailsDO shipperLeaseDetailsDO) { + return shipperLeaseDetailsService.update(shipperLeaseDetailsDO); + } + + /** + * 批量删除租赁管理 + */ + public Boolean delete(Long[] shipperLeaseDetailsIds) { + return shipperLeaseDetailsService.delete(shipperLeaseDetailsIds); + } + + /** + * 获取租赁管理详细信息 + */ + public ShipperLeaseDetailsPO getInfo(Long shipperLeaseDetailsId) + { + return shipperLeaseDetailsService.getInfo(shipperLeaseDetailsId); + } + + + /** + * @description 批量作废租赁 + * @author ZhouGY + * @date 2024/5/13 9:46 + * @param leaseIds + * @return Boolean + */ + public Boolean nullifyByIds(List leaseIds) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + return shipperLeaseDetailsService.update(new UpdateWrapper().lambda() + .set(ShipperLeaseDetails::getUpdateBy, loginUser.getUserid()) + .set(ShipperLeaseDetails::getUpdateTime, new Date()) + .in(ShipperLeaseDetails::getId, leaseIds) + .eq(ShipperLeaseDetails::getDelFlag, 1)); + } +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/assember/lease/LeaseAssembler.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/assember/lease/LeaseAssembler.java new file mode 100644 index 000000000..f5e34a259 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/assember/lease/LeaseAssembler.java @@ -0,0 +1,116 @@ +package com.mhd.basic.interfaces.assember.lease; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson2.JSON; +import com.mhd.basic.domain.container.repository.todo.ContainerDO; +import com.mhd.basic.domain.lease.repository.todo.LeaseDO; +import com.mhd.basic.interfaces.dto.container.ContainerDTO; +import com.mhd.basic.interfaces.dto.lease.LeaseDTO; +import com.mhd.common.core.exception.ServiceException; +import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException; +import com.mhd.common.core.exception.digitalLogisticsException.UserError; +import com.mhd.common.core.utils.IgnoreNullUtil; +import com.mhd.common.core.utils.bean.BeanUtils; +import com.mhd.common.core.web.domain.AjaxResult; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.SystemServiceFeign; +import com.mhd.system.api.domain.WarehouseFeignPO; +import com.mhd.system.api.model.LoginUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Date; + +/** + * 容器管理Assembler + * + */ +@Component +public class LeaseAssembler { + + @Autowired + private SystemServiceFeign systemServiceFeign; + + /** + * 转换实体 + */ + public LeaseDO toDO(LeaseDTO leaseDTO) { + LeaseDO leaseDO = new LeaseDO(); + // 拷贝 + BeanUtils.copyProperties(leaseDTO, leaseDO, IgnoreNullUtil.getNullPropertyNames(leaseDTO)); + // 确保查询条件字段被正确传递(查询条件字段需要明确传递,避免被IgnoreNullUtil忽略) + leaseDO.setCreateTimeStart(leaseDTO.getCreateTimeStart()); + leaseDO.setCreateTimeEnd(leaseDTO.getCreateTimeEnd()); + leaseDO.setUpdateTimeStart(leaseDTO.getUpdateTimeStart()); + leaseDO.setUpdateTimeEnd(leaseDTO.getUpdateTimeEnd()); + return leaseDO; + } + + /** + * 转换实体 + */ + public LeaseDO toDOByEdit(LeaseDTO leaseDTO) { + LeaseDO leaseDO = new LeaseDO(); + // 拷贝 + BeanUtils.copyProperties(leaseDTO, leaseDO, IgnoreNullUtil.getNullPropertyNames(leaseDTO)); + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (ObjectUtil.isNull(loginUser)) { + throw new DigitalLogisticsException(UserError.TIMEOUT); + } + if(leaseDTO.getId() != null){ + leaseDO.setUpdateBy(loginUser.getUserid()); + leaseDO.setUpdateByName(loginUser.getUsername()); + leaseDO.setUpdateTime(new Date()); + }else { + leaseDO.setOrganizationId(loginUser.getUserPo().getOrganizationId()); + leaseDO.setOrganizationName(loginUser.getUserPo().getOrganizationName()); + leaseDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); + leaseDO.setCreateBy(loginUser.getUserid()); + leaseDO.setCreateByName(loginUser.getUsername()); + leaseDO.setCreateTime(new Date()); + // 新增时根据仓库ID查询仓库名字 + if (leaseDO.getWarehouseId() != null) { + setWarehouseInfo(leaseDO); + } + } + return leaseDO; + } + + /** + * 设置仓库信息 + */ + private void setWarehouseInfo(LeaseDO leaseDO) { + if (leaseDO.getWarehouseId() == null) { + return; + } + AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(leaseDO.getWarehouseId()); + if (ajaxResult == null) { + throw new ServiceException("获取仓库信息失败:返回结果为空,仓库ID:" + leaseDO.getWarehouseId()); + } + Object codeObj = ajaxResult.get("code"); + if (codeObj == null || !"200".equals(String.valueOf(codeObj))) { + String errorMsg = ajaxResult.get("msg") != null ? String.valueOf(ajaxResult.get("msg")) : "未知错误"; + throw new ServiceException("获取仓库信息失败,仓库ID:" + leaseDO.getWarehouseId() + ",错误信息:" + errorMsg); + } + Object dataObj = ajaxResult.get("data"); + if (dataObj == null) { + throw new ServiceException("获取仓库信息失败:返回数据为空,仓库ID:" + leaseDO.getWarehouseId()); + } + String dataJsonString = JSONObject.toJSONString(dataObj); + if (dataJsonString == null || dataJsonString.isEmpty() || "null".equals(dataJsonString)) { + throw new ServiceException("获取仓库信息失败:返回数据为空或格式不正确,仓库ID:" + leaseDO.getWarehouseId()); + } + WarehouseFeignPO warehouseFeignPO; + try { + warehouseFeignPO = JSON.parseObject(dataJsonString, WarehouseFeignPO.class); + } catch (Exception e) { + throw new ServiceException("获取仓库信息失败:数据解析异常,仓库ID:" + leaseDO.getWarehouseId() + ",错误信息:" + e.getMessage()); + } + if (warehouseFeignPO == null) { + throw new ServiceException("获取仓库信息失败:数据解析失败,仓库ID:" + leaseDO.getWarehouseId()); + } + leaseDO.setWarehouseName(warehouseFeignPO.getWarehouseName()); + } + +} \ No newline at end of file diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/assember/shipperLeaseDetails/ShipperLeaseDetailsAssembler.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/assember/shipperLeaseDetails/ShipperLeaseDetailsAssembler.java new file mode 100644 index 000000000..628823c5e --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/assember/shipperLeaseDetails/ShipperLeaseDetailsAssembler.java @@ -0,0 +1,61 @@ +package com.mhd.basic.interfaces.assember.shipperLeaseDetails; + +import cn.hutool.core.util.ObjectUtil; +import com.mhd.basic.domain.lease.repository.todo.LeaseDO; +import com.mhd.basic.domain.shipperLeaseDetails.repository.todo.ShipperLeaseDetailsDO; +import com.mhd.basic.interfaces.dto.lease.LeaseDTO; +import com.mhd.basic.interfaces.dto.shipperLeaseDetailsApi.ShipperLeaseDetailsDTO; +import com.mhd.common.core.exception.digitalLogisticsException.DigitalLogisticsException; +import com.mhd.common.core.exception.digitalLogisticsException.UserError; +import com.mhd.common.core.utils.IgnoreNullUtil; +import com.mhd.common.core.utils.bean.BeanUtils; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.model.LoginUser; +import org.springframework.stereotype.Component; + +import java.util.Date; + +/** + * 货主租赁明细Assembler + * + */ +@Component +public class ShipperLeaseDetailsAssembler { + + /** + * 转换实体 + */ + public ShipperLeaseDetailsDO toDO(ShipperLeaseDetailsDTO shipperLeaseDetailsDTO) { + ShipperLeaseDetailsDO shipperLeaseDetailsDO = new ShipperLeaseDetailsDO(); + // 拷贝 + BeanUtils.copyProperties(shipperLeaseDetailsDTO, shipperLeaseDetailsDO, IgnoreNullUtil.getNullPropertyNames(shipperLeaseDetailsDTO)); + return shipperLeaseDetailsDO; + } + + /** + * 转换实体 + */ + public ShipperLeaseDetailsDO toDOByEdit(ShipperLeaseDetailsDTO shipperLeaseDetailsDTO) { + ShipperLeaseDetailsDO shipperLeaseDetailsDO = new ShipperLeaseDetailsDO(); + // 拷贝 + BeanUtils.copyProperties(shipperLeaseDetailsDTO, shipperLeaseDetailsDO, IgnoreNullUtil.getNullPropertyNames(shipperLeaseDetailsDTO)); + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (ObjectUtil.isNull(loginUser)) { + throw new DigitalLogisticsException(UserError.TIMEOUT); + } + if(shipperLeaseDetailsDTO.getId() != null){ + shipperLeaseDetailsDO.setUpdateBy(loginUser.getUserid()); + shipperLeaseDetailsDO.setUpdateByName(loginUser.getUsername()); + shipperLeaseDetailsDO.setUpdateTime(new Date()); + }else { + shipperLeaseDetailsDO.setOrganizationId(loginUser.getUserPo().getOrganizationId()); + shipperLeaseDetailsDO.setOrganizationName(loginUser.getUserPo().getOrganizationName()); + shipperLeaseDetailsDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); + shipperLeaseDetailsDO.setCreateBy(loginUser.getUserid()); + shipperLeaseDetailsDO.setCreateByName(loginUser.getUsername()); + shipperLeaseDetailsDO.setCreateTime(new Date()); + } + return shipperLeaseDetailsDO; + } + +} \ No newline at end of file diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/dto/batchDetail/BatchDetailDTO.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/dto/batchDetail/BatchDetailDTO.java index 0e1af3b28..45eabb799 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/dto/batchDetail/BatchDetailDTO.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/dto/batchDetail/BatchDetailDTO.java @@ -44,6 +44,10 @@ public class BatchDetailDTO extends BaseVOEntity{ @Excel(name = "批次标签") private String batchLabels; + @ApiModelProperty("字段名称") + @Excel(name = "字段名称") + private String fieldName; + @ApiModelProperty("输入控制: 1-必填 2-可选") @Excel(name = "输入控制: 1-必填 2-可选") private String inputControl; @@ -56,6 +60,10 @@ public class BatchDetailDTO extends BaseVOEntity{ @Excel(name = "属性选项") private String attributeOption; + @ApiModelProperty("是否显示: 0-不显示 1-显示") + @Excel(name = "是否显示: 0-不显示 1-显示") + private Integer isDisplay; + @ApiModelProperty("备注") @Excel(name = "备注") private String remark; diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/dto/lease/LeaseDTO.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/dto/lease/LeaseDTO.java new file mode 100644 index 000000000..170b17899 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/dto/lease/LeaseDTO.java @@ -0,0 +1,80 @@ +package com.mhd.basic.interfaces.dto.lease; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.mhd.common.core.annotation.Excel; +import com.mhd.common.core.web.domain.BaseVOEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * 租赁管理对象 container + * + */ + +@Data +public class LeaseDTO extends BaseVOEntity{ + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + private Long id; + + @ApiModelProperty("组织表ID") + @Excel(name = "组织表ID") + private Long organizationId; + + @ApiModelProperty("组织名称") + @Excel(name = "组织名称") + private String organizationName; + + @ApiModelProperty("一级组织表ID") + @Excel(name = "一级组织表ID") + private Long topOrganizationId; + + @ApiModelProperty("仓库ID") + private Long warehouseId; + + @ApiModelProperty("仓库名字") + private String warehouseName; + + @ApiModelProperty("货主id") + private Long shipperId; + + @ApiModelProperty("货主名称") + private String cargoOwnerName; + + @ApiModelProperty(value = "租赁方式(整租/散租)") + private String leaseType; + + @ApiModelProperty("租赁面积(m²)") + private BigDecimal leaseArea; + + @ApiModelProperty("开始日期") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date startDate; + + @ApiModelProperty("结束日期") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date endDate; + + @ApiModelProperty("备注") + private String remark; + + @ApiModelProperty(name = "创建时间查询条件开始日期") + private String createTimeStart; + + @ApiModelProperty(name = "创建时间查询条件结束日期") + private String createTimeEnd; + + @ApiModelProperty(name = "修改时间查询条件开始日期") + private String updateTimeStart; + + @ApiModelProperty(name = "修改时间查询条件结束日期") + private String updateTimeEnd; +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/dto/materialBaseInfo/MaterialBaseInfoDTO.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/dto/materialBaseInfo/MaterialBaseInfoDTO.java index e8abbcc81..2489e47d2 100644 --- a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/dto/materialBaseInfo/MaterialBaseInfoDTO.java +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/dto/materialBaseInfo/MaterialBaseInfoDTO.java @@ -181,4 +181,183 @@ public class MaterialBaseInfoDTO extends BaseVOEntity{ @ApiModelProperty("是否公用: 1-是 2-否") @Excel(name = "是否公用: 1-是 2-否") private Integer common; -} + + + /** + * 商品名称 + */ + @ApiModelProperty("商品名称") + @Excel(name = "商品名称") + private String commodityName; + /** + * 商品编码 + */ + @ApiModelProperty("商品编码") + @Excel(name = "商品编码") + private String commodityNo; + /** + * 料号 + */ + @ApiModelProperty("料号") + @Excel(name = "料号") + private String materialNo; + /** + * 规格型号 + */ + @ApiModelProperty("规格型号") + @Excel(name = "规格型号") + private String specificationModel; + + /** + * Invoice No + */ + @ApiModelProperty("Invoice No") + @Excel(name = "Invoice No") + private String invoiceNo; + /** + * 升 + */ + @ApiModelProperty("升") + @Excel(name = "升") + private String liter; + + /** + * 尺寸 + */ + @ApiModelProperty("尺寸") + @Excel(name = "尺寸") + private String size; + + /** + * 申报单位 + */ + @ApiModelProperty("申报单位") + @Excel(name = "申报单位") + private String declareUnit; + + /** + * Batch Ref NO’s + */ + @ApiModelProperty("Batch Ref NO’s") + @Excel(name = "Batch Ref NO’s") + private String batchRefNo; + + /** + * Sheet Ref NO’s + */ + @ApiModelProperty("Sheet Ref NO’s") + @Excel(name = "Sheet Ref NO’s") + private String sheetRefNo; + + /** + * 原产国 + */ + @ApiModelProperty("原产国") + @Excel(name = "原产国") + private String countryOfOrigin; + + /** + * 箱号/卡板号 + */ + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String casePalletNo; + + /** + * 币制 + */ + @ApiModelProperty("币制") + @Excel(name = "币制") + private String currency; + + /** + * 申报数量 + */ + @ApiModelProperty("申报数量") + @Excel(name = "申报数量") + private Double declareQuantity; + + /** + * 箱数 + */ + @ApiModelProperty("箱数") + @Excel(name = "箱数") + private Double caseCount; + + /** + * 件数 + */ + @ApiModelProperty("件数") + @Excel(name = "件数") + private Double pieceCount; + + /** + * 出库数量 + */ + @ApiModelProperty("出库数量") + @Excel(name = "出库数量") + private Double outboundQuantity; + + /** + * 总净重(KG) + */ + @ApiModelProperty("总净重(KG)") + @Excel(name = "总净重(KG)") + private Double totalNetWeight; + + /** + * 总毛重(KG) + */ + @ApiModelProperty("总毛重(KG)") + @Excel(name = "总毛重(KG)") + private Double totalGrossWeight; + + /** + * 总体积(CBM) + */ + @ApiModelProperty("总体积(CBM)") + @Excel(name = "总体积(CBM)") + private Double totalVolume; + + /** + * 总面积(SQM) + */ + @ApiModelProperty("总面积(SQM)") + @Excel(name = "总面积(SQM)") + private Double totalArea; + /** + * 总价 + */ + @ApiModelProperty("总价") + @Excel(name = "总价") + private Double totalAmount; + + /** + * 单位 + */ + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unit; + + + @ApiModelProperty("SKU码") + private String skuCode; + + @ApiModelProperty("单价") + private BigDecimal unitPrice; + + @ApiModelProperty("原产国") + private String originCountry; + + @ApiModelProperty("HS码") + private String hsCode; + + @ApiModelProperty("申报单位") + private String declarationUnit; + + @ApiModelProperty("法定单位") + private String statutoryUnit; + + @ApiModelProperty("法定第二单位") + private String statutorySecondUnit; +} \ No newline at end of file diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/dto/shipperLeaseDetailsApi/ShipperLeaseDetailsDTO.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/dto/shipperLeaseDetailsApi/ShipperLeaseDetailsDTO.java new file mode 100644 index 000000000..a1e5ef99b --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/dto/shipperLeaseDetailsApi/ShipperLeaseDetailsDTO.java @@ -0,0 +1,74 @@ +package com.mhd.basic.interfaces.dto.shipperLeaseDetailsApi; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.mhd.common.core.annotation.Excel; +import com.mhd.common.core.web.domain.BaseVOEntity; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 货主租赁明细 + * + */ + +@Data +public class ShipperLeaseDetailsDTO extends BaseVOEntity{ + private static final long serialVersionUID = 1L; + + @ApiModelProperty("id") + @TableId(type = IdType.AUTO) + private Long id; + + @ApiModelProperty("组织表ID") + @Excel(name = "组织表ID") + private Long organizationId; + + @ApiModelProperty("组织名称") + @Excel(name = "组织名称") + private String organizationName; + + @ApiModelProperty("一级组织表ID") + @Excel(name = "一级组织表ID") + private Long topOrganizationId; + + @ApiModelProperty("仓库ID") + private Long warehouseId; + + @ApiModelProperty("仓库名字") + private String warehouseName; + + @ApiModelProperty("货主id") + private Long shipperId; + + @ApiModelProperty("货主名称") + private String cargoOwnerName; + + @ApiModelProperty(value = "租赁方式(整租/散租)") + private String leaseType; + + @ApiModelProperty("租赁面积(m²)") + private BigDecimal leaseArea; + + @ApiModelProperty("业务日期") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + private Date businessDate; + + @ApiModelProperty("业务日期开始时间") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + private Date businessDateStart; + + @ApiModelProperty("业务日期结束时间") + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern="yyyy-MM-dd") + private Date businessDateEnd; + + +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/facadeApi/lease/LeaseApi.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/facadeApi/lease/LeaseApi.java new file mode 100644 index 000000000..2da0ad39e --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/facadeApi/lease/LeaseApi.java @@ -0,0 +1,112 @@ +package com.mhd.basic.interfaces.facadeApi.lease; + +import com.mhd.basic.application.service.Lease.LeaseApplicationService; +import com.mhd.basic.application.service.container.ContainerApplicationService; +import com.mhd.basic.domain.container.repository.po.ContainerPO; +import com.mhd.basic.domain.container.repository.todo.ContainerDO; +import com.mhd.basic.domain.lease.repository.po.LeasePO; +import com.mhd.basic.domain.lease.repository.todo.LeaseDO; +import com.mhd.basic.domain.shipperLeaseDetails.entity.WarehouseOccupancyRate; +import com.mhd.basic.interfaces.assember.container.ContainerAssembler; +import com.mhd.basic.interfaces.assember.lease.LeaseAssembler; +import com.mhd.basic.interfaces.dto.container.ContainerDTO; +import com.mhd.basic.interfaces.dto.lease.LeaseDTO; +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 io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 租赁管理Api + */ +@RestController +@RequestMapping("/LeaseApi") +public class LeaseApi extends BaseController{ + + @Autowired + private LeaseApplicationService leaseApplicationService; + + @Resource + private LeaseAssembler leaseAssembler; + + /** + * 分页查询租赁管理列表 + */ + @ApiOperation("查询租赁管理列表") + @GetMapping("/list") + public TableDataInfo list(LeaseDTO leaseDTO) + { + //转换实体 + LeaseDO leaseDO = leaseAssembler.toDO(leaseDTO); + startPage(); + List list = leaseApplicationService.queryList(leaseDO); + return getDataTable(list); + } + + /** + * 分页查询租赁管理列表 + */ + @ApiOperation("查询租赁管理列表") + @GetMapping("/listByApp") + public AjaxResult listByApp(LeaseDTO leaseDTO) + { + //转换实体 + LeaseDO leaseDO = leaseAssembler.toDO(leaseDTO); + List list = leaseApplicationService.queryList(leaseDO); + return AjaxResult.success(list); + } + + /** + * 编辑租赁管理 + */ + @ApiOperation("编辑租赁管理") + @PostMapping("/edit") + public AjaxResult edit(@RequestBody LeaseDTO leaseDTO) + { + //转换实体 + LeaseDO leaseDO = leaseAssembler.toDOByEdit(leaseDTO); + if(leaseDTO.getId() != null){ + return toAjax(leaseApplicationService.update(leaseDO)); + }else { + return toAjax(leaseApplicationService.insert(leaseDO)); + } + } + + /** + * 批量删除租赁管理 + */ + @ApiOperation("批量删除租赁管理") + @DeleteMapping("/deleteByIds/{leaseIds}") + public AjaxResult delete(@PathVariable Long[] leaseIds) + { + return toAjax(leaseApplicationService.delete(leaseIds)); + } + + /** + * 获取租赁管理详细信息 + */ + @ApiOperation("获取租赁管理") + @GetMapping(value = "/getInfo/{leaseId}") + public AjaxResult getInfo(@PathVariable("leaseId") Long leaseId) + { + return AjaxResult.success(leaseApplicationService.getInfo(leaseId)); + } + + + /** + * 批量作废租赁 + */ + @ApiOperation("批量作废租赁") + @GetMapping("/nullifyByIds/{leaseIds}") + public AjaxResult nullifyByIds(@PathVariable("leaseIds") List leaseIds) + { + return toAjax(leaseApplicationService.nullifyByIds(leaseIds)); + } + + +} diff --git a/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/facadeApi/shipperLeaseDetails/ShipperLeaseDetailsApi.java b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/facadeApi/shipperLeaseDetails/ShipperLeaseDetailsApi.java new file mode 100644 index 000000000..4f560e24d --- /dev/null +++ b/mhd-modules/mhd-system/src/main/java/com/mhd/basic/interfaces/facadeApi/shipperLeaseDetails/ShipperLeaseDetailsApi.java @@ -0,0 +1,161 @@ +package com.mhd.basic.interfaces.facadeApi.shipperLeaseDetails; + +import com.mhd.basic.application.service.Lease.LeaseApplicationService; +import com.mhd.basic.application.service.shipperLeaseDetails.ShipperLeaseDetailsApplicationService; +import com.mhd.basic.domain.lease.repository.po.LeasePO; +import com.mhd.basic.domain.lease.repository.todo.LeaseDO; +import com.mhd.basic.domain.shipperLeaseDetails.entity.ShipperLeaseDetails; +import com.mhd.basic.domain.shipperLeaseDetails.entity.WarehouseOccupancyRate; +import com.mhd.basic.domain.shipperLeaseDetails.repository.po.ShipperLeaseDetailsPO; +import com.mhd.basic.domain.shipperLeaseDetails.repository.todo.ShipperLeaseDetailsDO; +import com.mhd.basic.interfaces.assember.lease.LeaseAssembler; +import com.mhd.basic.interfaces.assember.shipperLeaseDetails.ShipperLeaseDetailsAssembler; +import com.mhd.basic.interfaces.dto.lease.LeaseDTO; +import com.mhd.basic.interfaces.dto.shipperLeaseDetailsApi.ShipperLeaseDetailsDTO; +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 io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 货主租赁明细Api + */ +@RestController +@RequestMapping("/ShipperLeaseDetailsApi") +public class ShipperLeaseDetailsApi extends BaseController{ + + @Autowired + private LeaseApplicationService leaseApplicationService; + + @Autowired + private ShipperLeaseDetailsApplicationService shipperLeaseDetailsApplicationService; + + @Resource + private ShipperLeaseDetailsAssembler shipperLeaseDetailsAssembler; + + /** + * 分页查询货主租赁明细列表 + */ + @ApiOperation("查询货主租赁明细列表") + @GetMapping("/list") + public TableDataInfo list(ShipperLeaseDetailsDTO shipperLeaseDetailsDTO) + { + //转换实体 + ShipperLeaseDetailsDO shipperLeaseDetailsDO = shipperLeaseDetailsAssembler.toDO(shipperLeaseDetailsDTO); + startPage(); + List list = shipperLeaseDetailsApplicationService.queryList(shipperLeaseDetailsDO); + return getDataTable(list); + } + + /** + * 分页查询货主租赁明细列表 + */ + @ApiOperation("查询货主租赁明细列表") + @GetMapping("/listByApp") + public AjaxResult listByApp(ShipperLeaseDetailsDTO shipperLeaseDetailsDTO) + { + //转换实体 + ShipperLeaseDetailsDO shipperLeaseDetailsDO = shipperLeaseDetailsAssembler.toDO(shipperLeaseDetailsDTO); + List list = shipperLeaseDetailsApplicationService.queryList(shipperLeaseDetailsDO); + return AjaxResult.success(list); + } + + /** + * 编辑货主租赁明细 + */ + @ApiOperation("编辑货主租赁明细") + @PostMapping("/edit") + public AjaxResult edit(@RequestBody ShipperLeaseDetailsDTO shipperLeaseDetailsDTO) + { + //转换实体 + ShipperLeaseDetailsDO shipperLeaseDetailsDO = shipperLeaseDetailsAssembler.toDOByEdit(shipperLeaseDetailsDTO); + if(shipperLeaseDetailsDTO.getId() != null){ + return toAjax(shipperLeaseDetailsApplicationService.update(shipperLeaseDetailsDO)); + }else { + return toAjax(shipperLeaseDetailsApplicationService.insert(shipperLeaseDetailsDO)); + } + } + + /** + * 编辑货主租赁明细 + */ + @ApiOperation("编辑货主租赁明细") + @PostMapping("/editList") + public AjaxResult edit(@RequestBody List shipperLeaseDetailsDTO) + { + for (ShipperLeaseDetailsDTO leaseDetailsDTO : shipperLeaseDetailsDTO) { + //转换实体 + ShipperLeaseDetailsDO shipperLeaseDetailsDO = shipperLeaseDetailsAssembler.toDOByEdit(leaseDetailsDTO); + shipperLeaseDetailsApplicationService.update(shipperLeaseDetailsDO); + } + return AjaxResult.success(); + } + + /** + * 批量删除货主租赁明细 + */ + @ApiOperation("批量删除货主租赁明细") + @DeleteMapping("/deleteByIds/{shipperLeaseDetailsIds}") + public AjaxResult delete(@PathVariable Long[] shipperLeaseDetailsIds) + { + return toAjax(shipperLeaseDetailsApplicationService.delete(shipperLeaseDetailsIds)); + } + + /** + * 获取货主租赁明细详细信息 + */ + @ApiOperation("获取货主租赁明细") + @GetMapping(value = "/getInfo/{shipperLeaseDetailsId}") + public AjaxResult getInfo(@PathVariable("shipperLeaseDetailsId") Long shipperLeaseDetailsId) + { + return AjaxResult.success(shipperLeaseDetailsApplicationService.getInfo(shipperLeaseDetailsId)); + } + + + /** + * 批量作废租赁 + */ + @ApiOperation("批量作废租赁") + @GetMapping("/nullifyByIds/{shipperLeaseDetailsIds}") + public AjaxResult nullifyByIds(@PathVariable("shipperLeaseDetailsIds") List shipperLeaseDetailsIds) + { + return toAjax(shipperLeaseDetailsApplicationService.nullifyByIds(shipperLeaseDetailsIds)); + } + + /** + * 计算货主租赁明细 + */ + @ApiOperation("货主租赁明细") + @PostMapping("/shipperLeaseDetails") + public AjaxResult shipperLeaseDetails() + { + leaseApplicationService.shipperLeaseDetails(); + return AjaxResult.success(); + } + + /** + * 计算仓库出租率 + * warehouseId 仓库id + */ + @ApiOperation("仓库出租率") + @PostMapping("/warehouseOccupancyRate") + public TableDataInfo warehouseOccupancyRate(@RequestBody ShipperLeaseDetailsDTO shipperLeaseDetailsDTO) + { + ShipperLeaseDetailsDO shipperLeaseDetailsDO = shipperLeaseDetailsAssembler.toDO(shipperLeaseDetailsDTO); + List warehouseOccupancyRates = leaseApplicationService.warehouseOccupancyRate(shipperLeaseDetailsDO); + // 按照businessDate倒序排序 + warehouseOccupancyRates = warehouseOccupancyRates.stream() + .sorted(Comparator.comparing(WarehouseOccupancyRate::getBusinessDate, Comparator.nullsLast(Comparator.reverseOrder()))) + .collect(Collectors.toList()); + return getDataTable(warehouseOccupancyRates); + } + + +} diff --git a/mhd-modules/mhd-system/src/main/resources/bootstrap.yml b/mhd-modules/mhd-system/src/main/resources/bootstrap.yml index ac7087779..fa495b9aa 100644 --- a/mhd-modules/mhd-system/src/main/resources/bootstrap.yml +++ b/mhd-modules/mhd-system/src/main/resources/bootstrap.yml @@ -13,10 +13,10 @@ spring: cloud: nacos: discovery: -# server-addr: 127.0.0.1:8848 + server-addr: 127.0.0.1:8848 # server-addr: 10.33.0.129:6010 # 线上测试环境配置 容器名+端口号 - server-addr: 10.102.192.5:6848 +# server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 #线上正式环境 @@ -25,7 +25,7 @@ spring: # server-addr: 127.0.0.1:8848 # server-addr: 10.33.0.129:6010 # 线上测试环境配置 容器名+端口号 - server-addr: 10.102.192.5:6848 +# server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 #线上正式环境 diff --git a/mhd-modules/mhd-system/src/main/resources/mapper/basic/batchDetail/BatchDetailMapper.xml b/mhd-modules/mhd-system/src/main/resources/mapper/basic/batchDetail/BatchDetailMapper.xml index af405db1f..5b033420b 100644 --- a/mhd-modules/mhd-system/src/main/resources/mapper/basic/batchDetail/BatchDetailMapper.xml +++ b/mhd-modules/mhd-system/src/main/resources/mapper/basic/batchDetail/BatchDetailMapper.xml @@ -11,9 +11,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + @@ -26,7 +28,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select batch_detail_id, organization_id, organization_name, top_organization_id, batch_id, batch_labels, input_control, attribute_format, attribute_option, remark, create_time, create_by, create_by_name, update_time, update_by, update_by_name, del_flag from batch_detail + select batch_detail_id, organization_id, organization_name, top_organization_id, batch_id, batch_labels, field_name, input_control, attribute_format, attribute_option, is_display, remark, create_time, create_by, create_by_name, update_time, update_by, update_by_name, del_flag from batch_detail @@ -46,6 +48,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and batch_labels = #{batchLabels} + + and field_name = #{fieldName} + and input_control = #{inputControl} @@ -55,6 +60,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and attribute_option = #{attributeOption} + + and is_display = #{isDisplay} + and create_by_name like concat('%', #{createByName}, '%') diff --git a/mhd-modules/mhd-system/src/main/resources/mapper/basic/lease/LeaseMapper.xml b/mhd-modules/mhd-system/src/main/resources/mapper/basic/lease/LeaseMapper.xml new file mode 100644 index 000000000..e50d747e7 --- /dev/null +++ b/mhd-modules/mhd-system/src/main/resources/mapper/basic/lease/LeaseMapper.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select + a.id, + a.organization_id, + a.organization_name, + a.top_organization_id, + a.warehouse_id, + COALESCE(w.warehouse_name, a.warehouse_name) as warehouse_name, + a.shipper_id, + a.cargo_owner_name, + a.lease_type, + a.lease_area, + a.start_date, + a.end_date, + 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 + from lease a + LEFT JOIN warehouse w ON a.warehouse_id = w.warehouse_id AND w.del_flag = 1 + + + + + + + and a.organization_id = #{organizationId} + + + and a.top_organization_id = #{topOrganizationId} + + + and a.organization_name like concat('%', #{organizationName}, '%') + + + and a.warehouse_id = #{warehouseId} + + + and (w.warehouse_name like concat('%', #{warehouseName}, '%') or a.warehouse_name like concat('%', #{warehouseName}, '%')) + + + and a.cargo_owner_name like concat('%', #{cargoOwnerName}, '%') + + + and a.lease_type = #{leaseType} + + + and a.create_time = #{createTime} + + + and a.lease_area = #{leaseArea} + + + and a.remark like concat('%', #{remark}, '%') + + + + and a.create_by_name like concat('%', #{createByName}, '%') + + + and a.update_by_name like concat('%', #{updateByName}, '%') + + + and date_format(a.create_time,'%Y-%m-%d') >= #{createTimeStart} + + + and date_format(a.create_time,'%Y-%m-%d') <= #{createTimeEnd} + + + and date_format(a.update_time,'%Y-%m-%d') >= #{updateTimeStart} + + + and date_format(a.update_time,'%Y-%m-%d') <= #{updateTimeEnd} + + + + and a.start_date >= #{startDate} and a.start_date <= #{endDate} + + + AND a.start_date <= #{time} + AND a.end_date >= #{time} + + + + and a.del_flag = #{delFlag} + and a.del_flag = 1 + + + + + + \ No newline at end of file diff --git a/mhd-modules/mhd-system/src/main/resources/mapper/basic/materialBaseInfo/MaterialBaseInfoMapper.xml b/mhd-modules/mhd-system/src/main/resources/mapper/basic/materialBaseInfo/MaterialBaseInfoMapper.xml index 67845fb2f..7656de363 100644 --- a/mhd-modules/mhd-system/src/main/resources/mapper/basic/materialBaseInfo/MaterialBaseInfoMapper.xml +++ b/mhd-modules/mhd-system/src/main/resources/mapper/basic/materialBaseInfo/MaterialBaseInfoMapper.xml @@ -54,7 +54,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select material_base_info_id, organization_id, organization_name, top_organization_id, shipper_id, shipper_name, material_code, material_name, bar_code, material_classify_code, material_classify_name, material_type, material_type_name, pack_id, pack_code, pack_name, unit_code, unit_name, brand_id, brand_code, brand_name, shelf_life, weight_limit, volume_limit, material_shape, material_shape_name, material_size, material_length, material_width, material_height, remark, nullify, create_time, create_by, create_by_name, - update_time, update_by, update_by_name, del_flag, common,material_model,material_unit,machine_code + update_time, update_by, update_by_name, del_flag, common,material_model,material_unit,machine_code,sku_code, unit_price, currency, origin_country, hs_code, declaration_unit, statutory_unit, statutory_second_unit from material_base_info @@ -82,7 +82,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and material_name like concat('%', #{materialName}, '%') - and bar_code = #{barCode} + and bar_code like concat('%',#{barCode},'%') and material_classify_code = #{materialClassifyCode} @@ -170,7 +170,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and material_base_info_id in (SELECT DISTINCT material_base_info_id - FROM test_szwl_wms.material_inventory + FROM ngwl_test_wms.material_inventory WHERE allocation_quantity > 0 AND del_flag = 1) @@ -178,6 +178,118 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + and organization_id = #{organizationId} + + + and organization_name like concat('%', #{organizationName}, '%') + + + and top_organization_id = #{topOrganizationId} + + + and shipper_id = #{shipperId} + + + and shipper_name like concat('%', #{shipperName}, '%') + + + and material_code = #{materialCode} + + + and material_name like concat('%', #{materialName}, '%') + + + and bar_code like concat('%',#{barCode},'%') + + + and material_classify_code = #{materialClassifyCode} + + + and material_classify_name like concat('%', #{materialClassifyName}, '%') + + + and material_type = #{materialType} + + + and material_type_name like concat('%', #{materialTypeName}, '%') + + + and unit_code = #{unitCode} + + + and unit_name like concat('%', #{unitName}, '%') + + + and pack_id = #{packId} + + + and pack_code = #{packCode} + + + and pack_name like concat('%', #{packName}, '%') + + + and brand_id = #{brandId} + + + and brand_code = #{brandCode} + + + and brand_name like concat('%', #{brandName}, '%') + + + and shelf_life = #{shelfLife} + + + and weight_limit = #{weightLimit} + + + and volume_limit = #{volumeLimit} + + + and material_shape = #{materialShape} + + + and material_shape_name like concat('%', #{materialShapeName}, '%') + + + and material_size = #{materialSize} + + + and material_length = #{materialLength} + + + and material_width = #{materialWidth} + + + and material_height = #{materialHeight} + + + and nullify = #{nullify} + + + and create_by_name like concat('%', #{createByName}, '%') + + + and update_by_name like concat('%', #{updateByName}, '%') + + + + and common = #{common} + and ( + 1 = 1 + or common = 1 ) + + + and del_flag = #{delFlag} + and del_flag = 1 + + + diff --git a/mhd-modules/mhd-system/src/main/resources/mapper/basic/pack/PackMapper.xml b/mhd-modules/mhd-system/src/main/resources/mapper/basic/pack/PackMapper.xml index bc92e8e9f..08261b84a 100644 --- a/mhd-modules/mhd-system/src/main/resources/mapper/basic/pack/PackMapper.xml +++ b/mhd-modules/mhd-system/src/main/resources/mapper/basic/pack/PackMapper.xml @@ -16,6 +16,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -27,7 +28,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select pack_id, organization_id, organization_name, top_organization_id, shipper_id, shipper_name, pack_code, pack_name, remark, opening_up, nullify, create_time, create_by, create_by_name, update_time, update_by, update_by_name, del_flag from pack + select a.pack_id, a.organization_id, a.organization_name, a.top_organization_id, a.shipper_id, a.shipper_name, a.pack_code, a.pack_name, a.remark, a.opening_up, a.nullify, a.create_time, a.create_by, a.create_by_name, a.update_time, a.update_by, a.update_by_name, a.del_flag, + (SELECT b.name FROM (SELECT name, pack_id FROM pack_detail WHERE pack_id = a.pack_id AND del_flag = 1 ORDER BY pack_detail_id) b WHERE ROWNUM = 1) as unit_name + from pack a diff --git a/mhd-modules/mhd-system/src/main/resources/mapper/basic/shipperLeaseDetails/ShipperLeaseDetailsMapper.xml b/mhd-modules/mhd-system/src/main/resources/mapper/basic/shipperLeaseDetails/ShipperLeaseDetailsMapper.xml new file mode 100644 index 000000000..7e8aac7fc --- /dev/null +++ b/mhd-modules/mhd-system/src/main/resources/mapper/basic/shipperLeaseDetails/ShipperLeaseDetailsMapper.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select + id, + organization_id, + organization_name, + top_organization_id, + warehouse_id, + warehouse_name, + shipper_id, + cargo_owner_name, + lease_type, + lease_area, + business_date, + create_by, + create_by_name, + create_time, + update_by, + update_by_name, + update_time, + del_flag + from shipper_lease_details + + + + + + + and organization_id = #{organizationId} + + + and top_organization_id = #{topOrganizationId} + + + and organization_name like concat('%', #{organizationName}, '%') + + + + + and warehouse_id = #{warehouseId} + + + + + and business_date >= #{businessDateStart} + + + and business_date <= #{businessDateEnd} + + + + and warehouse_name like concat('%', #{warehouseName}, '%') + + + + + and shipper_id = #{shipperId} + + + and cargo_owner_name like concat('%', #{cargoOwnerName}, '%') + + + + + and lease_type = #{leaseType} + + + and lease_area = #{leaseArea} + + + + + and business_date = #{businessDate} + + + + + and create_by_name like concat('%', #{createByName}, '%') + + + and update_by_name like concat('%', #{updateByName}, '%') + + + + + and del_flag = #{delFlag} + and del_flag = 1 + + + + + + \ No newline at end of file diff --git a/mhd-modules/mhd-system/src/main/resources/mapper/basic/storageLocation/StorageLocationMapper.xml b/mhd-modules/mhd-system/src/main/resources/mapper/basic/storageLocation/StorageLocationMapper.xml index 4e76c1ac6..4ff52f6cc 100644 --- a/mhd-modules/mhd-system/src/main/resources/mapper/basic/storageLocation/StorageLocationMapper.xml +++ b/mhd-modules/mhd-system/src/main/resources/mapper/basic/storageLocation/StorageLocationMapper.xml @@ -51,130 +51,147 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select storage_location_id, organization_id, organization_name, top_organization_id, warehouse_id, warehouse_code, warehouse_name, storage_section_id, storage_code, storage_name, storage_location_code, storage_location_name, storage_location_classify, storage_location_classify_name, storage_location_type, storage_location_type_name, mixing_strategy, mixing_strategy_name, storage_location_group_id, storage_location_group_code, storage_location_group_name, weight_limit, volume_limit, location_size, location_length, location_width, location_height, coordinate, coordinate_area, coordinate_column, coordinate_row, coordinate_layer, remark, opening_up, nullify, status, create_time, create_by, create_by_name, update_time, update_by, update_by_name, del_flag from storage_location + select a.storage_location_id, a.organization_id, a.organization_name, a.top_organization_id, a.warehouse_id, + COALESCE(w.warehouse_code, a.warehouse_code) as warehouse_code, + COALESCE(w.warehouse_name, a.warehouse_name) as warehouse_name, + a.storage_section_id, a.storage_code, a.storage_name, a.storage_location_code, a.storage_location_name, + a.storage_location_classify, a.storage_location_classify_name, a.storage_location_type, a.storage_location_type_name, + a.mixing_strategy, a.mixing_strategy_name, a.storage_location_group_id, a.storage_location_group_code, a.storage_location_group_name, + a.weight_limit, a.volume_limit, a.location_size, a.location_length, a.location_width, a.location_height, + a.coordinate, a.coordinate_area, a.coordinate_column, a.coordinate_row, a.coordinate_layer, a.remark, + a.opening_up, a.nullify, a.status, a.create_time, a.create_by, a.create_by_name, a.update_time, a.update_by, a.update_by_name, a.del_flag + from storage_location a + LEFT JOIN warehouse w ON a.warehouse_id = w.warehouse_id AND w.del_flag = 1 - and organization_id = #{organizationId} + and a.organization_id = #{organizationId} - and organization_name like concat('%', #{organizationName}, '%') + and a.organization_name like concat('%', #{organizationName}, '%') - and top_organization_id = #{topOrganizationId} + and a.top_organization_id = #{topOrganizationId} - and warehouse_id = #{warehouseId} + and a.warehouse_id = #{warehouseId} - and warehouse_code = #{warehouseCode} + and (w.warehouse_code like concat('%', #{warehouseCode}, '%') or a.warehouse_code like concat('%', #{warehouseCode}, '%')) - and warehouse_name like concat('%', #{warehouseName}, '%') + and (w.warehouse_name like concat('%', #{warehouseName}, '%') or a.warehouse_name like concat('%', #{warehouseName}, '%')) - and storage_section_id = #{storageSectionId} + and a.storage_section_id = #{storageSectionId} - and storage_code = #{storageCode} + and a.storage_code = #{storageCode} - and storage_name like concat('%', #{storageName}, '%') + and a.storage_name like concat('%', #{storageName}, '%') - and storage_location_code = #{storageLocationCode} + and a.storage_location_code = #{storageLocationCode} - and storage_location_name like concat('%', #{storageLocationName}, '%') + and a.storage_location_name like concat('%', #{storageLocationName}, '%') - and storage_location_classify = #{storageLocationClassify} + and a.storage_location_classify = #{storageLocationClassify} - and storage_location_classify_name like concat('%', #{storageLocationClassifyName}, '%') + and a.storage_location_classify_name like concat('%', #{storageLocationClassifyName}, '%') - and storage_location_type = #{storageLocationType} + and a.storage_location_type = #{storageLocationType} - and storage_location_type_name like concat('%', #{storageLocationTypeName}, '%') + and a.storage_location_type_name like concat('%', #{storageLocationTypeName}, '%') - and mixing_strategy = #{mixingStrategy} + and a.mixing_strategy = #{mixingStrategy} - and mixing_strategy_name like concat('%', #{mixingStrategyName}, '%') + and a.mixing_strategy_name like concat('%', #{mixingStrategyName}, '%') - and storage_location_group_id = #{storageLocationGroupId} + and a.storage_location_group_id = #{storageLocationGroupId} - and storage_location_group_code = #{storageLocationGroupCode} + and a.storage_location_group_code = #{storageLocationGroupCode} - and storage_location_group_name like concat('%', #{storageLocationGroupName}, '%') + and a.storage_location_group_name like concat('%', #{storageLocationGroupName}, '%') - and weight_limit = #{weightLimit} + and a.weight_limit = #{weightLimit} - and volume_limit = #{volumeLimit} + and a.volume_limit = #{volumeLimit} - and location_size = #{locationSize} + and a.location_size = #{locationSize} - and location_length = #{locationLength} + and a.location_length = #{locationLength} - and location_width = #{locationWidth} + and a.location_width = #{locationWidth} - and location_height = #{locationHeight} + and a.location_height = #{locationHeight} - and coordinate = #{coordinate} + and a.coordinate = #{coordinate} - and coordinate_area = #{coordinateArea} + and a.coordinate_area = #{coordinateArea} - and coordinate_column = #{coordinateColumn} + and a.coordinate_column = #{coordinateColumn} - and coordinate_row = #{coordinateRow} + and a.coordinate_row = #{coordinateRow} - and coordinate_layer = #{coordinateLayer} + and a.coordinate_layer = #{coordinateLayer} - and opening_up = #{openingUp} + and a.opening_up = #{openingUp} - and nullify = #{nullify} + and a.nullify = #{nullify} - and create_by_name like concat('%', #{createByName}, '%') + and a.create_by_name like concat('%', #{createByName}, '%') - and update_by_name like concat('%', #{updateByName}, '%') + and a.update_by_name like concat('%', #{updateByName}, '%') - and remark like concat('%',#{remark},'%') + and a.remark like concat('%',#{remark},'%') + + and a.del_flag = #{delFlag} + and a.del_flag = 1 + - SELECT count(1) - from storage_locationfrom + from storage_location a + LEFT JOIN warehouse w ON a.warehouse_id = w.warehouse_id AND w.del_flag = 1 \ No newline at end of file diff --git a/mhd-modules/mhd-system/src/main/resources/mapper/basic/storageLocationGroup/StorageLocationGroupMapper.xml b/mhd-modules/mhd-system/src/main/resources/mapper/basic/storageLocationGroup/StorageLocationGroupMapper.xml index 52ca90bf2..4d49dd61c 100644 --- a/mhd-modules/mhd-system/src/main/resources/mapper/basic/storageLocationGroup/StorageLocationGroupMapper.xml +++ b/mhd-modules/mhd-system/src/main/resources/mapper/basic/storageLocationGroup/StorageLocationGroupMapper.xml @@ -31,67 +31,78 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select storage_location_group_id, organization_id, organization_name, top_organization_id, warehouse_id, warehouse_code, warehouse_name, storage_section_id, storage_code, storage_name, storage_location_group_code, storage_location_group_name, remark, number, opening_up, nullify, create_time, create_by, create_by_name, update_time, update_by, update_by_name, del_flag from storage_location_group + select a.storage_location_group_id, a.organization_id, a.organization_name, a.top_organization_id, a.warehouse_id, + COALESCE(w.warehouse_code, a.warehouse_code) as warehouse_code, + COALESCE(w.warehouse_name, a.warehouse_name) as warehouse_name, + a.storage_section_id, a.storage_code, a.storage_name, a.storage_location_group_code, a.storage_location_group_name, + a.remark, a.number, a.opening_up, a.nullify, a.create_time, a.create_by, a.create_by_name, a.update_time, a.update_by, a.update_by_name, a.del_flag + from storage_location_group a + LEFT JOIN warehouse w ON a.warehouse_id = w.warehouse_id AND w.del_flag = 1 - and organization_id = #{organizationId} + and a.organization_id = #{organizationId} - and organization_name like concat('%', #{organizationName}, '%') + and a.organization_name like concat('%', #{organizationName}, '%') - and top_organization_id = #{topOrganizationId} + and a.top_organization_id = #{topOrganizationId} - and warehouse_id = #{warehouseId} + and a.warehouse_id = #{warehouseId} - and warehouse_code = #{warehouseCode} + and (w.warehouse_code like concat('%', #{warehouseCode}, '%') or a.warehouse_code like concat('%', #{warehouseCode}, '%')) - and warehouse_name like concat('%', #{warehouseName}, '%') + and (w.warehouse_name like concat('%', #{warehouseName}, '%') or a.warehouse_name like concat('%', #{warehouseName}, '%')) - and storage_section_id = #{storageSectionId} + and a.storage_section_id = #{storageSectionId} - and storage_code = #{storageCode} + and a.storage_code = #{storageCode} - and storage_name like concat('%', #{storageName}, '%') + and a.storage_name like concat('%', #{storageName}, '%') - and storage_location_group_code = #{storageLocationGroupCode} + and a.storage_location_group_code = #{storageLocationGroupCode} - and storage_location_group_name like concat('%', #{storageLocationGroupName}, '%') + and a.storage_location_group_name like concat('%', #{storageLocationGroupName}, '%') - and opening_up = #{openingUp} + and a.opening_up = #{openingUp} - and nullify = #{nullify} + and a.nullify = #{nullify} - and create_by_name like concat('%', #{createByName}, '%') + and a.create_by_name like concat('%', #{createByName}, '%') - and update_by_name like concat('%', #{updateByName}, '%') + and a.update_by_name like concat('%', #{updateByName}, '%') - and number = #{number} + and a.number = #{number} - and remark like concat('%',#{remark},'%') + and a.remark like concat('%',#{remark},'%') + + and a.del_flag = #{delFlag} + and a.del_flag = 1 + \ No newline at end of file diff --git a/mhd-modules/mhd-system/src/main/resources/mapper/basic/storageSection/StorageSectionMapper.xml b/mhd-modules/mhd-system/src/main/resources/mapper/basic/storageSection/StorageSectionMapper.xml index c9c882f4b..ada404ef2 100644 --- a/mhd-modules/mhd-system/src/main/resources/mapper/basic/storageSection/StorageSectionMapper.xml +++ b/mhd-modules/mhd-system/src/main/resources/mapper/basic/storageSection/StorageSectionMapper.xml @@ -31,64 +31,75 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select storage_section_id, organization_id, organization_name, top_organization_id, warehouse_id, warehouse_code, warehouse_name, storage_code, storage_name, storage_type, storage_type_name, storage_region, remark, opening_up, nullify, create_time, create_by, create_by_name, update_time, update_by, update_by_name, del_flag from storage_section + select a.storage_section_id, a.organization_id, a.organization_name, a.top_organization_id, a.warehouse_id, + COALESCE(w.warehouse_code, a.warehouse_code) as warehouse_code, + COALESCE(w.warehouse_name, a.warehouse_name) as warehouse_name, + a.storage_code, a.storage_name, a.storage_type, a.storage_type_name, a.storage_region, a.remark, a.opening_up, a.nullify, + a.create_time, a.create_by, a.create_by_name, a.update_time, a.update_by, a.update_by_name, a.del_flag + from storage_section a + LEFT JOIN warehouse w ON a.warehouse_id = w.warehouse_id AND w.del_flag = 1 - and organization_id = #{organizationId} + and a.organization_id = #{organizationId} - and organization_name like concat('%', #{organizationName}, '%') + and a.organization_name like concat('%', #{organizationName}, '%') - and top_organization_id = #{topOrganizationId} + and a.top_organization_id = #{topOrganizationId} - and warehouse_id = #{warehouseId} + and a.warehouse_id = #{warehouseId} - and warehouse_code = #{warehouseCode} + and (w.warehouse_code like concat('%', #{warehouseCode}, '%') or a.warehouse_code like concat('%', #{warehouseCode}, '%')) - and warehouse_name like concat('%', #{warehouseName}, '%') + and (w.warehouse_name like concat('%', #{warehouseName}, '%') or a.warehouse_name like concat('%', #{warehouseName}, '%')) - and storage_code = #{storageCode} + and a.storage_code = #{storageCode} - and storage_name like concat('%', #{storageName}, '%') + and a.storage_name like concat('%', #{storageName}, '%') - and storage_type = #{storageType} + and a.storage_type = #{storageType} - and storage_type_name like concat('%', #{storageTypeName}, '%') + and a.storage_type_name like concat('%', #{storageTypeName}, '%') - and storage_region = #{storageRegion} + and a.storage_region = #{storageRegion} - and opening_up = #{openingUp} + and a.opening_up = #{openingUp} - and nullify = #{nullify} + and a.nullify = #{nullify} - and create_by_name like concat('%', #{createByName}, '%') + and a.create_by_name like concat('%', #{createByName}, '%') - and update_by_name like concat('%', #{updateByName}, '%') + and a.update_by_name like concat('%', #{updateByName}, '%') - and remark like concat('%',#{remark},'%') + and a.remark like concat('%',#{remark},'%') + + and a.del_flag = #{delFlag} + and a.del_flag = 1 + \ No newline at end of file diff --git a/mhd-modules/mhd-system/src/main/resources/mapper/basic/warehouse/WarehouseMapper.xml b/mhd-modules/mhd-system/src/main/resources/mapper/basic/warehouse/WarehouseMapper.xml index 012a4c227..586d81b9d 100644 --- a/mhd-modules/mhd-system/src/main/resources/mapper/basic/warehouse/WarehouseMapper.xml +++ b/mhd-modules/mhd-system/src/main/resources/mapper/basic/warehouse/WarehouseMapper.xml @@ -58,7 +58,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and top_organization_id = #{topOrganizationId} - and warehouse_code = #{warehouseCode} + and warehouse_code like concat('%', #{warehouseCode}, '%') and warehouse_name like concat('%', #{warehouseName}, '%') @@ -139,5 +139,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" \ No newline at end of file diff --git a/mhd-user-center/src/main/java/com/mhd/user/application/service/CommonApplicationService.java b/mhd-user-center/src/main/java/com/mhd/user/application/service/CommonApplicationService.java index 323f849e3..04c8c3236 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/application/service/CommonApplicationService.java +++ b/mhd-user-center/src/main/java/com/mhd/user/application/service/CommonApplicationService.java @@ -157,6 +157,10 @@ public class CommonApplicationService { UserDO queryAccount = new UserDO(); queryAccount.setTopOrganizationId(topOrganizationId); queryAccount.setUserAccount(userDO.getUserAccount()); + // 如果指定了角色,只检查相同角色的用户 + if (StrUtil.isNotEmpty(userDO.getRoleCode())) { + queryAccount.setRoleCode(userDO.getRoleCode()); + } userPo = userDomainService.findByTopOrganizationIdAndUserAccount(queryAccount); } //根据手机号查询 @@ -165,6 +169,10 @@ public class CommonApplicationService { UserDO queryPhone = new UserDO(); queryPhone.setTopOrganizationId(topOrganizationId); queryPhone.setUserPhone(userDO.getUserPhone()); + // 如果指定了角色,只检查相同角色的用户 + if (StrUtil.isNotEmpty(userDO.getRoleCode())) { + queryPhone.setRoleCode(userDO.getRoleCode()); + } userPoTwo = userDomainService.findByTopOrganizationIdAndUserPhone(queryPhone); } //根据身份证号查询 diff --git a/mhd-user-center/src/main/java/com/mhd/user/application/service/UserApplicationService.java b/mhd-user-center/src/main/java/com/mhd/user/application/service/UserApplicationService.java index 00e7d688b..894fc935e 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/application/service/UserApplicationService.java +++ b/mhd-user-center/src/main/java/com/mhd/user/application/service/UserApplicationService.java @@ -441,6 +441,32 @@ public class UserApplicationService { return userPo; } + /** + * @Description 根据用户ID获取用户信息 + * @Author Alex + * @Date 2022/12/20 17:12 + */ + public UserPo selectByUserName(String userName) { + if (StringUtils.isEmpty(userName)) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + userName = loginUser.getUsername(); + } + UserPo userPo = userDomainService.selectByUserName(userName); + if (userPo != null){ + userPo.setPrincipalAccount(userPo.getUserAccount()); + } + if (StringUtils.isNotEmpty(userPo.getRoleCode())){ + String[] split = userPo.getRoleCode().split(";"); + List list = CollectionUtil.toList(split); + userPo.setRoleCodeList(list); + } + UserShipperPo userShipperPo = userShipperDomainService.selectByUserId(userPo.getUserId()); + if(null != userShipperPo){ + userPo.setEsignEnterpriseStatus(userShipperPo.getEsignEnterpriseStatus()); + } + return userPo; + } + /** * @Description 分配用户默认普通用户角色 * @Author Alex @@ -1196,7 +1222,7 @@ public class UserApplicationService { (userDO.getUserAccountType() == null || userDO.getUserAccountType() < 4)) { //给用户分配默认普通角色权限 RoleDo roleDo = new RoleDo(); - roleDo.setRoleCode(RoleEnum.MUST.getCode()); + roleDo.setRoleCode(RoleEnum.OWNER_CARGO.getCode()); roleDo.setOrganizationId(userEntity.getOrganizationId()); RoleEntity roleEntity = roleDomainService.selectByOrganizationIdAndRoleCode(roleDo); if (roleEntity != null) { @@ -1206,8 +1232,8 @@ public class UserApplicationService { userDO.setRoleId(roleEntity.getRoleId()); userRoleDomainService.addUserRole(userRoleDo); } - userDO.setRoleCode(RoleEnum.MUST.getCode()); - userDO.setRoleName(RoleEnum.MUST.getName()); + userDO.setRoleCode(RoleEnum.OWNER_CARGO.getCode()); + userDO.setRoleName(RoleEnum.OWNER_CARGO.getName()); userDO.setUserId(userEntity.getUserId()); userDomainService.updateUser(userDO); }else{ @@ -4913,7 +4939,7 @@ public class UserApplicationService { Map sysDepartInterfaceInfoPoMap = sysDepartInterfaceInfoPos.stream().collect(Collectors.toMap(SysDepartInterfaceInfoPo::getInterfaceTypeKey, Function.identity())); SysDepartInterfaceInfoPo sysDepartInterfaceInfoPo = sysDepartInterfaceInfoPoMap.get("isWT"); //是否开启 - if ("1".equals(sysDepartInterfaceInfoPo.getInterfaceTypeValue())) { + if (sysDepartInterfaceInfoPo != null && "1".equals(sysDepartInterfaceInfoPo.getInterfaceTypeValue())) { return true; } return false; @@ -4969,4 +4995,4 @@ public class UserApplicationService { public UserPo selectUserTableByUserId(Long userId){ return userDomainService.selectByUserId(userId); } -} +} \ No newline at end of file diff --git a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/entity/UserEntity.java b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/entity/UserEntity.java index dbd88aec9..3715bca94 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/entity/UserEntity.java +++ b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/entity/UserEntity.java @@ -165,4 +165,31 @@ public class UserEntity extends BaseVOEntity { @ApiModelProperty(name = "制单员nc编码") private String documentPreparerNcCode; + + @ApiModelProperty("法人代表") + private String legalRepresentative; + + @ApiModelProperty("统一编码") + private String unifiedCode; + + @ApiModelProperty("注册电话") + private String registeredPhone; + + @ApiModelProperty("注册地址") + private String registeredAddress; + + @ApiModelProperty("传真") + private String fax; + + @ApiModelProperty("付款银行") + private String paymentBank; + + @ApiModelProperty("付款账户") + private String paymentAccount; + + @ApiModelProperty("发票抬头") + private String invoiceTitle; + + @ApiModelProperty("税号") + private String taxNumber; } diff --git a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/facade/UserRepositoryInterface.java b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/facade/UserRepositoryInterface.java index c67d7dda4..e7c2a8367 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/facade/UserRepositoryInterface.java +++ b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/facade/UserRepositoryInterface.java @@ -27,6 +27,8 @@ public interface UserRepositoryInterface extends IService { UserPo findAdminUserByOrganizationId(UserDO userDO); UserPo findByUserId(Long userId); + UserPo selectByUserName(String userName); + UserPo findByTopOrganizationIdAndUserAccount(UserDO userDO); UserPo getUserByDingUserId(String dingUserId); @@ -73,5 +75,4 @@ public interface UserRepositoryInterface extends IService { String finShipperEnterpriseNamedByUserId(Long userId); -} - +} \ No newline at end of file diff --git a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/facade/UserShipperRepositoryInterface.java b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/facade/UserShipperRepositoryInterface.java index 92328c84f..1eb3e2e92 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/facade/UserShipperRepositoryInterface.java +++ b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/facade/UserShipperRepositoryInterface.java @@ -60,4 +60,4 @@ public interface UserShipperRepositoryInterface extends IService { UserPo selectByUserId(Long userId); + UserPo selectByUserName(String userName); + UserPo selectUserShipperList(UserPo userPo); List selectUserShipperListWaybill(UserPo userPo); @@ -72,4 +74,4 @@ public interface UserMapper extends BaseMapper { String finShipperEnterpriseNamedByUserId(@Param("userId") Long userId); -} +} \ No newline at end of file diff --git a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/mapper/UserShipperMapper.java b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/mapper/UserShipperMapper.java index 1f850de4b..96f7cb79c 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/mapper/UserShipperMapper.java +++ b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/mapper/UserShipperMapper.java @@ -28,4 +28,4 @@ public interface UserShipperMapper extends BaseMapper { List selectBySealId(@Param("userShipperEntity") UserShipperEntity userShipperEntity); public com.mhd.common.core.domain.po.UserShipperPo getShipperSummaryData(Long userId); -} +} \ No newline at end of file diff --git a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/persistence/UserRepositoryImpl.java b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/persistence/UserRepositoryImpl.java index 45246c6e9..30a3ae12a 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/persistence/UserRepositoryImpl.java +++ b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/persistence/UserRepositoryImpl.java @@ -64,6 +64,11 @@ public class UserRepositoryImpl extends ServiceImpl imple return userMapper.selectByUserId(userId); } + @Override + public UserPo selectByUserName(String userName) { + return userMapper.selectByUserName(userName); + } + @Override public UserEntity selectById(Long userId) { return userMapper.selectById(userId); @@ -168,4 +173,4 @@ public class UserRepositoryImpl extends ServiceImpl imple public String finShipperEnterpriseNamedByUserId(Long userId) { return userMapper.finShipperEnterpriseNamedByUserId(userId); } -} +} \ No newline at end of file diff --git a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/persistence/UserShipperRepositoryImpl.java b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/persistence/UserShipperRepositoryImpl.java index c28d18467..87fdd882a 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/persistence/UserShipperRepositoryImpl.java +++ b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/persistence/UserShipperRepositoryImpl.java @@ -166,4 +166,4 @@ public class UserShipperRepositoryImpl extends ServiceImpl userIds; + + @ApiModelProperty("法人代表") + private String legalRepresentative; + + @ApiModelProperty("统一编码") + private String unifiedCode; + + @ApiModelProperty("注册电话") + private String registeredPhone; + + @ApiModelProperty("注册地址") + private String registeredAddress; + + @ApiModelProperty("传真") + private String fax; + + @ApiModelProperty("付款银行") + private String paymentBank; + + @ApiModelProperty("付款账户") + private String paymentAccount; + + @ApiModelProperty("发票抬头") + private String invoiceTitle; + + @ApiModelProperty("税号") + private String taxNumber; + + @ApiModelProperty(name = "邮箱") + private String userEmail; + + @ApiModelProperty(name = "备注") + private String userRemark; } diff --git a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/todo/UserDO.java b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/todo/UserDO.java index 6015ff20d..61281c395 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/todo/UserDO.java +++ b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/repository/todo/UserDO.java @@ -254,4 +254,31 @@ public class UserDO extends BaseVOEntity { @ApiModelProperty(name = "制单员nc编码") private String documentPreparerNcCode; + + @ApiModelProperty("法人代表") + private String legalRepresentative; + + @ApiModelProperty("统一编码") + private String unifiedCode; + + @ApiModelProperty("注册电话") + private String registeredPhone; + + @ApiModelProperty("注册地址") + private String registeredAddress; + + @ApiModelProperty("传真") + private String fax; + + @ApiModelProperty("付款银行") + private String paymentBank; + + @ApiModelProperty("付款账户") + private String paymentAccount; + + @ApiModelProperty("发票抬头") + private String invoiceTitle; + + @ApiModelProperty("税号") + private String taxNumber; } diff --git a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/service/UserDomainService.java b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/service/UserDomainService.java index 47eb3370f..c7fde6bbb 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/service/UserDomainService.java +++ b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/service/UserDomainService.java @@ -125,6 +125,10 @@ public class UserDomainService { return userRepositoryInterface.findByUserId(userId); } + public UserPo selectByUserName(String userName) { + return userRepositoryInterface.selectByUserName(userName); + } + public void updateWhenLogin(UserDO userDO) { userRepositoryInterface.update(new UpdateWrapper().lambda() .set(UserEntity::getLastLoginIp,userDO.getLastLoginIp()).set(UserEntity::getLastLoginTime,userDO.getLastLoginTime()) @@ -259,4 +263,4 @@ public class UserDomainService { .set(UserEntity::getHasDefaultAddress, dto.getHasDefaultAddress()) .eq(UserEntity::getUserId, dto.getUserId())); } -} +} \ No newline at end of file diff --git a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/service/UserShipperDomainService.java b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/service/UserShipperDomainService.java index 73df30675..61eaece29 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/service/UserShipperDomainService.java +++ b/mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/service/UserShipperDomainService.java @@ -236,4 +236,4 @@ public class UserShipperDomainService { public com.mhd.common.core.domain.po.UserShipperPo getShipperSummaryData(Long userId) { return userShipperRepositoryInterface.getShipperSummaryData(userId); } -} +} \ No newline at end of file diff --git a/mhd-user-center/src/main/java/com/mhd/user/interfaces/dto/addDTO/CustomerDTO.java b/mhd-user-center/src/main/java/com/mhd/user/interfaces/dto/addDTO/CustomerDTO.java index 07efe9518..2f3e1f20e 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/interfaces/dto/addDTO/CustomerDTO.java +++ b/mhd-user-center/src/main/java/com/mhd/user/interfaces/dto/addDTO/CustomerDTO.java @@ -47,4 +47,36 @@ public class CustomerDTO extends BaseVOEntity { @ApiModelProperty("详细地址") private String userAreaAddress; + @ApiModelProperty("法人代表") + private String legalRepresentative; + + @ApiModelProperty("统一编码") + private String unifiedCode; + + @ApiModelProperty("注册电话") + private String registeredPhone; + + @ApiModelProperty("注册地址") + private String registeredAddress; + + @ApiModelProperty("传真") + private String fax; + + @ApiModelProperty("付款银行") + private String paymentBank; + + @ApiModelProperty("付款账户") + private String paymentAccount; + + @ApiModelProperty("发票抬头") + private String invoiceTitle; + + @ApiModelProperty("税号") + private String taxNumber; + + @ApiModelProperty(name = "邮箱") + private String userEmail; + + @ApiModelProperty(name = "备注") + private String userRemark; } diff --git a/mhd-user-center/src/main/java/com/mhd/user/interfaces/dto/addDTO/UserDTO.java b/mhd-user-center/src/main/java/com/mhd/user/interfaces/dto/addDTO/UserDTO.java index 39e50a0e9..08c26f52e 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/interfaces/dto/addDTO/UserDTO.java +++ b/mhd-user-center/src/main/java/com/mhd/user/interfaces/dto/addDTO/UserDTO.java @@ -241,4 +241,10 @@ public class UserDTO extends BaseVOEntity { @ApiModelProperty( "制单员nc编码") private String documentPreparerNcCode; + + @ApiModelProperty(value = "紧急联系人姓名") + private String emergencyContactName; + + @ApiModelProperty(value = "紧急联系电话") + private String emergencyContactPhone; } diff --git a/mhd-user-center/src/main/java/com/mhd/user/interfaces/facade/UserAPI.java b/mhd-user-center/src/main/java/com/mhd/user/interfaces/facade/UserAPI.java index 977a61051..897f5f6b0 100644 --- a/mhd-user-center/src/main/java/com/mhd/user/interfaces/facade/UserAPI.java +++ b/mhd-user-center/src/main/java/com/mhd/user/interfaces/facade/UserAPI.java @@ -201,6 +201,14 @@ public class UserAPI extends BaseController { return AjaxResult.success(userPo); } + @Log(title = "用户中台管理-查询", description ="根据用户ID查询用户详细信息",businessType = BusinessType.INQUIRE) + @ApiOperation("根据用户ID查询用户详细信息") + @GetMapping("/getInfoByName/{userName}") + public AjaxResult getInfoByName(@PathVariable("userName") String userName) { + UserPo userPo = userApplicationService.selectByUserName(userName); + return AjaxResult.success(userPo); + } + /** * @Description 新增租户,新增货主,新增司机,新增员工,用户注册等 * @Author Alex @@ -946,4 +954,4 @@ public class UserAPI extends BaseController { public R finShipperEnterpriseNamedByUserId(@PathVariable("userId") Long userId) { return R.ok(userApplicationService.finShipperEnterpriseNamedByUserId(userId)); } -} +} \ No newline at end of file diff --git a/mhd-user-center/src/main/resources/bootstrap.yml b/mhd-user-center/src/main/resources/bootstrap.yml index 42a2695ae..319142ad3 100644 --- a/mhd-user-center/src/main/resources/bootstrap.yml +++ b/mhd-user-center/src/main/resources/bootstrap.yml @@ -18,17 +18,17 @@ spring: cloud: nacos: discovery: -# server-addr: 127.0.0.1:8848 + server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 # server-addr: 10.33.0.129:6010 - server-addr: 10.102.192.5:6848 +# server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 config: -# server-addr: 127.0.0.1:8848 + server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 # server-addr: 10.33.0.129:6010 - server-addr: 10.102.192.5:6848 +# server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 group: DEFAULT_GROUP # 默认分组就是DEFAULT_GROUP,如果使用默认分组可以不配置 diff --git a/mhd-user-center/src/main/resources/mapper/UserMapper.xml b/mhd-user-center/src/main/resources/mapper/UserMapper.xml index f56b08f72..b9e38a167 100644 --- a/mhd-user-center/src/main/resources/mapper/UserMapper.xml +++ b/mhd-user-center/src/main/resources/mapper/UserMapper.xml @@ -70,7 +70,16 @@ a.department_id, a.ding_user_id, a.ding_dept_id, - a.validity_period_management,a.salesperson_nc_code,a.document_preparer_nc_code + a.validity_period_management,a.salesperson_nc_code,a.document_preparer_nc_code, + a.legal_representative, + a.unified_code, + a.registered_phone, + a.registered_address, + a.fax, + a.payment_bank, + a.payment_account, + a.invoice_title, + a.tax_number FROM "USER" a where a.del_flag = 1 @@ -131,6 +140,9 @@ and a.top_organization_id = #{topOrganizationId} and a.user_account = #{userAccount} + + and a.role_code = #{roleCode} + and a.user_id != #{userId} @@ -159,6 +171,10 @@ and a.user_id = #{value} + + diff --git a/mhd-user-center/src/main/resources/mapper/UserShipperMapper.xml b/mhd-user-center/src/main/resources/mapper/UserShipperMapper.xml index 6d096e8b7..4e37939cf 100644 --- a/mhd-user-center/src/main/resources/mapper/UserShipperMapper.xml +++ b/mhd-user-center/src/main/resources/mapper/UserShipperMapper.xml @@ -381,4 +381,4 @@ and esign_enterprise_status = #{userShipperEntity.esignEnterpriseStatus} - + \ No newline at end of file diff --git a/mhd_finance/src/main/resources/bootstrap.yml b/mhd_finance/src/main/resources/bootstrap.yml index 05a425d45..8d4f10f81 100644 --- a/mhd_finance/src/main/resources/bootstrap.yml +++ b/mhd_finance/src/main/resources/bootstrap.yml @@ -25,7 +25,8 @@ spring: # username: nacos # password: manhuoda@2023 #线上正式环境 - server-addr: 10.102.192.5:6848 + server-addr: 127.0.0.1:8848 +# server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 #线上正式环境 @@ -39,7 +40,8 @@ spring: # username: nacos # password: manhuoda@2023 #线上正式环境 - server-addr: 10.102.192.5:6848 + server-addr: 127.0.0.1:8848 +# server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 #线上正式环境 diff --git a/mhd_oms/pom.xml b/mhd_oms/pom.xml index 1cd3d99e0..0e328f990 100644 --- a/mhd_oms/pom.xml +++ b/mhd_oms/pom.xml @@ -90,7 +90,7 @@ org.projectlombok lombok - 1.18.38 + 1.18.30 provided @@ -127,19 +127,6 @@ com.mhd mhd-common-log - - - - - - - - com.mhd - mhd-user-center - 3.6.0 - compile - - @@ -179,4 +166,4 @@ - + \ No newline at end of file diff --git a/mhd_oms/src/main/resources/bootstrap.yml b/mhd_oms/src/main/resources/bootstrap.yml index 8aa1783a7..d791822d4 100644 --- a/mhd_oms/src/main/resources/bootstrap.yml +++ b/mhd_oms/src/main/resources/bootstrap.yml @@ -17,6 +17,8 @@ spring: nacos: discovery: server-addr: 127.0.0.1:8848 + username: nacos + password: manhuoda@2023 # 演示环境 # server-addr: 47.92.229.169:8848 # 测试开发环境 @@ -31,6 +33,8 @@ spring: config: # 配置中心地址 server-addr: 127.0.0.1:8848 + username: nacos + password: manhuoda@2023 # 演示环境 # server-addr: 47.92.229.169:8848 # 测试开发环境 diff --git a/mhd_product/src/main/resources/bootstrap.yml b/mhd_product/src/main/resources/bootstrap.yml index 9bc1d51e5..6b9b2cada 100644 --- a/mhd_product/src/main/resources/bootstrap.yml +++ b/mhd_product/src/main/resources/bootstrap.yml @@ -18,9 +18,9 @@ spring: cloud: nacos: discovery: -# server-addr: 127.0.0.1:8848 + server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 - server-addr: 10.102.192.5:6848 +# server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 #线上正式环境 @@ -30,9 +30,9 @@ spring: #线上正式环境 # server-addr: 10.102.192.105:6848 config: -# server-addr: 127.0.0.1:8848 + server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 - server-addr: 10.102.192.5:6848 +# server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 #线上正式环境 diff --git a/mhd_thrid_party/src/main/resources/bootstrap.yml b/mhd_thrid_party/src/main/resources/bootstrap.yml index c5a07c32a..3a34654e5 100644 --- a/mhd_thrid_party/src/main/resources/bootstrap.yml +++ b/mhd_thrid_party/src/main/resources/bootstrap.yml @@ -18,9 +18,9 @@ spring: cloud: nacos: discovery: -# server-addr: 127.0.0.1:8848 + server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 - server-addr: 10.102.192.5:6848 +# server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 #线上正式环境 @@ -30,9 +30,9 @@ spring: #线上正式环境 # server-addr: 10.102.192.105:6848 config: -# server-addr: 127.0.0.1:8848 + server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 - server-addr: 10.102.192.5:6848 +# server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 #线上正式环境 diff --git a/mhd_transport/src/main/resources/bootstrap.yml b/mhd_transport/src/main/resources/bootstrap.yml index f0ff542dd..a06e7156e 100644 --- a/mhd_transport/src/main/resources/bootstrap.yml +++ b/mhd_transport/src/main/resources/bootstrap.yml @@ -18,10 +18,10 @@ spring: cloud: nacos: discovery: -# server-addr: 127.0.0.1:8848 + server-addr: 127.0.0.1:8848 # 线上测试环境配置使用ip+端口号 # server-addr: 10.33.0.129:6010 - server-addr: 10.102.192.5:6848 +# server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 #线上正式环境 @@ -31,9 +31,9 @@ spring: #线上正式环境 # server-addr: 10.102.192.105:6848 config: -# server-addr: 127.0.0.1:8848 + server-addr: 127.0.0.1:8848 # 线上测试环境配置使用ip+端口号 - server-addr: 10.102.192.5:6848 +# server-addr: 10.102.192.5:6848 username: nacos password: manhuoda@2023 #线上正式环境 diff --git a/mhd_wms/pom.xml b/mhd_wms/pom.xml index 59fb87a32..675c7cfa1 100644 --- a/mhd_wms/pom.xml +++ b/mhd_wms/pom.xml @@ -131,6 +131,13 @@ 4.1.2 + + + com.alibaba + easyexcel + 3.3.2 + + com.mhd diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/deliveTask/DeliveTaskApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/deliveTask/DeliveTaskApplicationService.java index e0a904dfb..e941824ee 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/deliveTask/DeliveTaskApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/deliveTask/DeliveTaskApplicationService.java @@ -109,4 +109,7 @@ public class DeliveTaskApplicationService { return deliveTaskDomainService.querySum(deliveTaskDO); } + public Boolean forward(DeliveTaskDO deliveTaskDO) { + return deliveTaskDomainService.updateById(deliveTaskDO); + } } diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/handoverTaskOrder/HandoverTaskOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/handoverTaskOrder/HandoverTaskOrderApplicationService.java index e8e544bc7..a2abba9fe 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/handoverTaskOrder/HandoverTaskOrderApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/handoverTaskOrder/HandoverTaskOrderApplicationService.java @@ -2,20 +2,31 @@ package com.mhd.wms.application.service.handoverTaskOrder; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; +import com.mhd.common.core.domain.po.UserPo; import com.mhd.common.core.exception.ServiceException; import com.mhd.common.core.utils.DateUtils; import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.SystemServiceFeign; +import com.mhd.system.api.UserServiceFeign; import com.mhd.system.api.domain.PlatformFeignPO; import com.mhd.system.api.domain.PlatformUseTimeFeignPO; 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.handoverTaskOrder.entity.HandoverTaskOrder; +import com.mhd.wms.domain.handoverTaskOrder.repository.facade.IHandoverTaskOrderService; import com.mhd.wms.domain.handoverTaskOrder.repository.po.HandoverTaskOrderPO; import com.mhd.wms.domain.handoverTaskOrder.repository.todo.HandoverTaskOrderDO; import com.mhd.wms.domain.handoverTaskOrder.service.HandoverTaskOrderDomainService; +import com.mhd.wms.domain.shiftManage.repository.todo.ShiftManageDO; +import com.mhd.wms.domain.stockOutOrder.entity.StockOutOrder; +import com.mhd.wms.domain.stockOutOrder.repository.facade.IStockOutOrderService; import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.formula.functions.T; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -36,6 +47,15 @@ public class HandoverTaskOrderApplicationService { @Autowired private SystemServiceFeign systemServiceFeign; + @Autowired + private UserServiceFeign userServiceFeign; + + @Autowired + private IHandoverTaskOrderService handoverTaskOrderService; + + @Autowired + private IStockOutOrderService stockOutOrderService; + /** * 分页查询交接作业单列表 @@ -148,4 +168,36 @@ public class HandoverTaskOrderApplicationService { } } + public boolean taskDistribution(HandoverTaskOrderDO handoverTaskOrderDO) { + // 设置作业员信息 + operatorsParam(handoverTaskOrderDO); + return handoverTaskOrderDomainService.taskDistribution(handoverTaskOrderDO); + } + + + /** + * @description 封装作业人员信息 + * @param handoverTaskOrderDO + */ + private void operatorsParam(HandoverTaskOrderDO handoverTaskOrderDO){ + AjaxResult ajaxResult = userServiceFeign.getInfo(handoverTaskOrderDO.getOperatorsBy()); + if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ + throw new ServiceException("获取作业人员信息失败"); + } + UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + handoverTaskOrderDO.setOperatorsName(userPo.getUserName()); + } + + public void pictureApp(HandoverTaskOrderDO handoverTaskOrderDO) { + //pda上传图片插入交接作业单 + handoverTaskOrderService.update(new LambdaUpdateWrapper() + .eq(HandoverTaskOrder::getOrderNumber,handoverTaskOrderDO.getOrderNumber()) + .set(HandoverTaskOrder::getPictureApp,handoverTaskOrderDO.getPictureApp())); + //pda上传图片插入出库管理 + stockOutOrderService.update(new LambdaUpdateWrapper() + .eq(StockOutOrder::getOutOrderNumber,handoverTaskOrderDO.getOrderNumber()) + .set(StockOutOrder::getStatus,"9")//设置为出库 + .set(StockOutOrder::getPictureApp,handoverTaskOrderDO.getPictureApp())//多张图片以,逗号隔开 + ); + } } diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/inventoryAdjustmentRecord/InventoryAdjustmentRecordApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/inventoryAdjustmentRecord/InventoryAdjustmentRecordApplicationService.java index e376cc272..f2560edb4 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/inventoryAdjustmentRecord/InventoryAdjustmentRecordApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/inventoryAdjustmentRecord/InventoryAdjustmentRecordApplicationService.java @@ -1,17 +1,31 @@ package com.mhd.wms.application.service.inventoryAdjustmentRecord; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.mhd.common.core.utils.StringUtils; +import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.SystemServiceFeign; +import com.mhd.system.api.domain.BatchDetailFeignPO; 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.inventoryAdjustmentRecord.repository.po.InventoryAdjustmentRecordPO; import com.mhd.wms.domain.inventoryAdjustmentRecord.repository.todo.InventoryAdjustmentRecordDO; import com.mhd.wms.domain.inventoryAdjustmentRecord.service.InventoryAdjustmentRecordDomainService; +import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper; +import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; +import com.mhd.wms.domain.statementStatistics.po.ImmediateInventoryPO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; -import java.util.List; +import java.lang.reflect.Field; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; /** * 库存调整记录ApplicationService @@ -24,6 +38,10 @@ import java.util.List; public class InventoryAdjustmentRecordApplicationService { @Autowired private InventoryAdjustmentRecordDomainService inventoryAdjustmentRecordDomainService; + @Autowired + private MaterialInventoryMapper materialInventoryMapper; + @Autowired + private SystemServiceFeign systemServiceFeign; /** @@ -40,7 +58,262 @@ public class InventoryAdjustmentRecordApplicationService { AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); inventoryAdjustmentRecordDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId()); } - return inventoryAdjustmentRecordDomainService.queryList(inventoryAdjustmentRecordDO); + List inventoryAdjustmentRecordPOS = inventoryAdjustmentRecordDomainService.queryList(inventoryAdjustmentRecordDO); + + // 性能优化:批量获取批次属性,避免N+1查询问题 + // 1. 收集所有唯一的materialBaseInfoId + Set materialBaseInfoIdSet = inventoryAdjustmentRecordPOS.stream() + .map(InventoryAdjustmentRecordPO::getMaterialBaseInfoId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 2. 批量查询批次属性(使用Map缓存,避免重复查询相同的materialBaseInfoId) + Map> batchDetailMap = new HashMap<>(); + for (Long materialBaseInfoId : materialBaseInfoIdSet) { + try { + AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + List batchDetailFeignPOList = JSON.parseArray( + JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class); + if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) { + // 过滤isDisplay=1的属性 + List filteredList = batchDetailFeignPOList.stream() + .filter(batchDetail -> batchDetail.getIsDisplay() != null && batchDetail.getIsDisplay() == 1) + .collect(Collectors.toList()); + batchDetailMap.put(materialBaseInfoId, filteredList); + } + } + } catch (Exception e) { + log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + } + + // 3. 为每个物料明细设置更多属性(从库存表中获取值) + setMaterialMoreDetailListFromInventory(inventoryAdjustmentRecordPOS, batchDetailMap); + return inventoryAdjustmentRecordPOS; + } + + /** + * 为物料库存设置更多属性(从库存表中获取值) + * @param materialInventoryPOList 物料库存列表 + * @param batchDetailMap 批次属性Map + */ + private void setMaterialMoreDetailListFromInventory(List materialInventoryPOList, + Map> batchDetailMap) { + if (CollectionUtils.isEmpty(materialInventoryPOList)) { + return; + } + + materialInventoryPOList.forEach(materialInventoryPO -> { + Long materialBaseInfoId = materialInventoryPO.getMaterialBaseInfoId(); + Long materialInventoryId = materialInventoryPO.getMaterialInventoryId(); + + // 创建新的materialMoreDetailList,只包含isDisplay=1的属性 + List materialMoreDetailList = new ArrayList<>(); + + // 从库存表获取数据(包含批次属性字段) + MaterialInventoryPO inventoryPO = null; + if (materialInventoryId != null) { + inventoryPO = materialInventoryMapper.selectByIdWithBatchAttributes(materialInventoryId); + } + + if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) { + List batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId); + // 用于跟踪已添加到列表中的batchDetailId + Set addedBatchDetailIds = new HashSet<>(); + + for (BatchDetailFeignPO batchDetailFeignPO : batchDetailFeignPOList) { + MaterialMoreDetailPO materialMoreDetailPO = new MaterialMoreDetailPO(); + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + + // 确保添加到列表中(使用batchDetailId来避免重复) + Long batchDetailId = batchDetailFeignPO.getBatchDetailId(); + if (batchDetailId != null && !addedBatchDetailIds.contains(batchDetailId)) { + materialMoreDetailList.add(materialMoreDetailPO); + addedBatchDetailIds.add(batchDetailId); + } + + // 根据fieldName或batchLabels从库存表中获取对应的字段值 + if (inventoryPO != null) { + String fieldValue = null; + String usedFieldName = null; + // 优先使用fieldName(如果存在) + if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) { + usedFieldName = batchDetailFeignPO.getFieldName(); + fieldValue = getFieldValueByFieldName(inventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, fieldName={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue); + } + // 如果fieldName为空,尝试根据batchLabels映射到字段名 + else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) { + String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels()); + if (StringUtils.isNotBlank(fieldNameByLabel)) { + usedFieldName = fieldNameByLabel; + fieldValue = getFieldValueByFieldName(inventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(), + usedFieldName, fieldValue); + } + } + // 只有当获取到值时才更新attributeValue + if (fieldValue != null) { + materialMoreDetailPO.setAttributeValue(fieldValue); + log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}", + materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(), + materialMoreDetailPO.getAttributeValue()); + } + } + } + } + materialInventoryPO.setMaterialMoreDetailList(materialMoreDetailList); + log.info("物料库存 materialInventoryId={}, materialBaseInfoId={}, materialMoreDetailList大小={}", + materialInventoryPO.getMaterialInventoryId(), materialInventoryPO.getMaterialBaseInfoId(), + materialMoreDetailList != null ? materialMoreDetailList.size() : 0); + }); + } + + /** + * 根据字段名从对象中获取字段值(使用反射) + * @param obj 对象 + * @param fieldName 字段名 + * @return 字段值(转换为字符串) + */ + private String getFieldValueByFieldName(Object obj, String fieldName) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return null; + } + + try { + // 兼容:如果传的是下划线命名(数据库列名风格),先转成驼峰字段名再取 + String normalizedFieldName = fieldName; + if (normalizedFieldName.contains("_")) { + normalizedFieldName = snakeToCamel(normalizedFieldName); + } + + // 获取对象的Class + Class clazz = obj.getClass(); + + // 尝试获取字段(包括父类字段) + Field field = null; + Class currentClass = clazz; + while (currentClass != null && field == null) { + try { + field = currentClass.getDeclaredField(normalizedFieldName); + } catch (NoSuchFieldException e) { + currentClass = currentClass.getSuperclass(); + } + } + + if (field == null) { + log.warn("字段不存在:{}(normalized:{}),对象类型:{}", fieldName, normalizedFieldName, clazz.getName()); + return null; + } + + // 设置可访问 + field.setAccessible(true); + + // 获取字段值 + Object value = field.get(obj); + + // 转换为字符串 + if (value == null) { + log.info("字段 {} 的值为 null,对象类型:{}", normalizedFieldName, clazz.getName()); + return null; + } + + String result; + // 处理日期类型字段 + if (value instanceof Date) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + result = sdf.format((Date) value); + } else { + result = value.toString(); + } + + log.info("通过反射获取字段值成功,字段名:{}(原始:{}),值:{},对象类型:{}", + normalizedFieldName, fieldName, result, clazz.getName()); + return result; + } catch (Exception e) { + log.warn("通过反射获取字段值失败,字段名:{},对象类型:{},错误:{}", fieldName, obj.getClass().getName(), e.getMessage()); + return null; + } + } + + private String snakeToCamel(String snake) { + if (StringUtils.isBlank(snake)) { + return null; + } + String s = snake.trim().toLowerCase(); + StringBuilder sb = new StringBuilder(); + boolean upperNext = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '_') { + upperNext = true; + continue; + } + if (upperNext) { + sb.append(Character.toUpperCase(c)); + upperNext = false; + } else { + sb.append(c); + } + } + return sb.toString(); + } + + /** + * 根据批次标签(batchLabels)映射到字段名 + * @param batchLabel 批次标签 + * @return 字段名,如果找不到映射则返回null + */ + private String getFieldNameByBatchLabel(String batchLabel) { + if (StringUtils.isBlank(batchLabel)) { + return null; + } + + // 批次标签到字段名的映射关系 + Map labelToFieldNameMap = new HashMap<>(); + labelToFieldNameMap.put("Invoice No.", "invoiceNo"); + labelToFieldNameMap.put("Invoice No", "invoiceNo"); + labelToFieldNameMap.put("发票号", "invoiceNo"); + labelToFieldNameMap.put("Batch Ref NO's", "batchRefNo"); + labelToFieldNameMap.put("Batch Ref NO", "batchRefNo"); + labelToFieldNameMap.put("批次参考号", "batchRefNo"); + labelToFieldNameMap.put("Sheet Ref NO's", "sheetRefNo"); + labelToFieldNameMap.put("Sheet Ref NO", "sheetRefNo"); + labelToFieldNameMap.put("单据参考号", "sheetRefNo"); + labelToFieldNameMap.put("箱号/卡板号", "boxPalletNo"); + labelToFieldNameMap.put("箱号", "boxPalletNo"); + labelToFieldNameMap.put("卡板号", "boxPalletNo"); + labelToFieldNameMap.put("生产日期", "productionDate"); + labelToFieldNameMap.put("过期日期", "expiryDate"); + labelToFieldNameMap.put("存货日期", "inventoryDate"); + labelToFieldNameMap.put("扩展字段1", "extAttr1"); + labelToFieldNameMap.put("扩展字段2", "extAttr2"); + labelToFieldNameMap.put("扩展字段3", "extAttr3"); + labelToFieldNameMap.put("扩展字段4", "extAttr4"); + + // 精确匹配 + String fieldName = labelToFieldNameMap.get(batchLabel.trim()); + if (StringUtils.isNotBlank(fieldName)) { + return fieldName; + } + + // 模糊匹配(包含关系) + for (Map.Entry entry : labelToFieldNameMap.entrySet()) { + if (batchLabel.contains(entry.getKey()) || entry.getKey().contains(batchLabel)) { + return entry.getValue(); + } + } + + return null; } @@ -99,4 +372,4 @@ public class InventoryAdjustmentRecordApplicationService { public Boolean inventoryFrozenForAll(InventoryAdjustmentRecordDO inventoryAdjustmentRecordDO) { return inventoryAdjustmentRecordDomainService.inventoryFrozenForAll(inventoryAdjustmentRecordDO); } -} +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/investigationManage/InvestigationManageApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/investigationManage/InvestigationManageApplicationService.java index 16c4b9847..e753bf178 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/investigationManage/InvestigationManageApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/investigationManage/InvestigationManageApplicationService.java @@ -5,11 +5,13 @@ 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.utils.bean.BeanUtils; import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.SystemServiceFeign; import com.mhd.system.api.UserServiceFeign; +import com.mhd.system.api.domain.BatchDetailFeignPO; import com.mhd.system.api.domain.WarehouseFeignPO; import com.mhd.system.api.domain.cache.AssociationWarehouseCacheDO; import com.mhd.system.api.domain.cache.SystemServiceCacheUtil; @@ -20,14 +22,18 @@ import com.mhd.wms.domain.investigationManage.service.InvestigationManageDomainS import com.mhd.wms.domain.investigetionManageDetail.repository.po.InvestigetionManageDetailPO; import com.mhd.wms.domain.investigetionManageDetail.repository.todo.InvestigetionManageDetailDO; import com.mhd.wms.domain.investigetionManageDetail.service.InvestigetionManageDetailDomainService; +import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper; +import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import java.lang.reflect.Field; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.text.SimpleDateFormat; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -48,6 +54,8 @@ public class InvestigationManageApplicationService { private UserServiceFeign userServiceFeign; @Autowired private SystemServiceFeign systemServiceFeign; + @Autowired + private MaterialInventoryMapper materialInventoryMapper; /** @@ -94,10 +102,273 @@ public class InvestigationManageApplicationService { } /** - * 获取盘点管理详细信息 + * 获取盘点管理详细信息(带批次属性) */ public InvestigationManagePO getInfo(Long investigationManageId) { - return investigationManageDomainService.getInfo(investigationManageId); + InvestigationManagePO investigationManagePO = investigationManageDomainService.getInfo(investigationManageId); + + if (investigationManagePO == null || CollectionUtils.isEmpty(investigationManagePO.getInvestigetionManageDetailList())) { + return investigationManagePO; + } + + List detailList = investigationManagePO.getInvestigetionManageDetailList(); + + // 性能优化:批量获取批次属性,避免N+1查询问题 + // 1. 收集所有唯一的materialBaseInfoId + Set materialBaseInfoIdSet = detailList.stream() + .map(InvestigetionManageDetailPO::getMaterialBaseInfoId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 2. 批量查询批次属性(使用Map缓存,避免重复查询相同的materialBaseInfoId) + Map> batchDetailMap = new HashMap<>(); + for (Long materialBaseInfoId : materialBaseInfoIdSet) { + try { + AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + List batchDetailFeignPOList = JSON.parseArray( + JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class); + if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) { + // 过滤isDisplay=1的属性 + List filteredList = batchDetailFeignPOList.stream() + .filter(batchDetail -> batchDetail.getIsDisplay() != null && batchDetail.getIsDisplay() == 1) + .collect(Collectors.toList()); + batchDetailMap.put(materialBaseInfoId, filteredList); + } + } + } catch (Exception e) { + log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + } + + // 3. 为每个物料明细设置更多属性(从库存表中获取值) + setMaterialMoreDetailListFromInventory(detailList, batchDetailMap); + + return investigationManagePO; + } + + /** + * 为盘点物料明细设置更多属性(从库存表中获取值) + * @param investigetionManageDetailPOList 盘点物料明细列表 + * @param batchDetailMap 批次属性Map + */ + private void setMaterialMoreDetailListFromInventory(List investigetionManageDetailPOList, + Map> batchDetailMap) { + if (CollectionUtils.isEmpty(investigetionManageDetailPOList)) { + return; + } + + investigetionManageDetailPOList.forEach(investigetionManageDetailPO -> { + Long materialBaseInfoId = investigetionManageDetailPO.getMaterialBaseInfoId(); + Long materialInventoryId = investigetionManageDetailPO.getMaterialInventoryId(); + + // 创建新的materialMoreDetailList,只包含isDisplay=1的属性 + List materialMoreDetailList = new ArrayList<>(); + + // 从库存表获取数据(包含批次属性字段) + MaterialInventoryPO materialInventoryPO = null; + if (materialInventoryId != null) { + materialInventoryPO = materialInventoryMapper.selectByIdWithBatchAttributes(materialInventoryId); + } + + if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) { + List batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId); + // 用于跟踪已添加到列表中的batchDetailId + Set addedBatchDetailIds = new HashSet<>(); + + for (BatchDetailFeignPO batchDetailFeignPO : batchDetailFeignPOList) { + MaterialMoreDetailPO materialMoreDetailPO = new MaterialMoreDetailPO(); + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + + // 确保添加到列表中(使用batchDetailId来避免重复) + Long batchDetailId = batchDetailFeignPO.getBatchDetailId(); + if (batchDetailId != null && !addedBatchDetailIds.contains(batchDetailId)) { + materialMoreDetailList.add(materialMoreDetailPO); + addedBatchDetailIds.add(batchDetailId); + } + + // 根据fieldName或batchLabels从库存表中获取对应的字段值 + if (materialInventoryPO != null) { + String fieldValue = null; + String usedFieldName = null; + // 优先使用fieldName(如果存在) + if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) { + usedFieldName = batchDetailFeignPO.getFieldName(); + fieldValue = getFieldValueByFieldName(materialInventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, fieldName={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue); + } + // 如果fieldName为空,尝试根据batchLabels映射到字段名 + else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) { + String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels()); + if (StringUtils.isNotBlank(fieldNameByLabel)) { + usedFieldName = fieldNameByLabel; + fieldValue = getFieldValueByFieldName(materialInventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(), + usedFieldName, fieldValue); + } + } + // 只有当获取到值时才更新attributeValue + if (fieldValue != null) { + materialMoreDetailPO.setAttributeValue(fieldValue); + log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}", + materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(), + materialMoreDetailPO.getAttributeValue()); + } + } + } + } + investigetionManageDetailPO.setMaterialMoreDetailList(materialMoreDetailList); + log.info("盘点物料明细 investigationManageDetailId={}, materialBaseInfoId={}, materialInventoryId={}, materialMoreDetailList大小={}", + investigetionManageDetailPO.getInvestigationManageDetailId(), investigetionManageDetailPO.getMaterialBaseInfoId(), + investigetionManageDetailPO.getMaterialInventoryId(), + materialMoreDetailList != null ? materialMoreDetailList.size() : 0); + }); + } + + /** + * 根据批次标签(batchLabels)映射到字段名 + * @param batchLabel 批次标签 + * @return 字段名,如果找不到映射则返回null + */ + private String getFieldNameByBatchLabel(String batchLabel) { + if (StringUtils.isBlank(batchLabel)) { + return null; + } + + // 批次标签到字段名的映射关系 + Map labelToFieldNameMap = new HashMap<>(); + labelToFieldNameMap.put("Invoice No.", "invoiceNo"); + labelToFieldNameMap.put("Invoice No", "invoiceNo"); + labelToFieldNameMap.put("发票号", "invoiceNo"); + labelToFieldNameMap.put("Batch Ref NO's", "batchRefNo"); + labelToFieldNameMap.put("Batch Ref NO", "batchRefNo"); + labelToFieldNameMap.put("批次参考号", "batchRefNo"); + labelToFieldNameMap.put("Sheet Ref NO's", "sheetRefNo"); + labelToFieldNameMap.put("Sheet Ref NO", "sheetRefNo"); + labelToFieldNameMap.put("单据参考号", "sheetRefNo"); + labelToFieldNameMap.put("箱号/卡板号", "boxPalletNo"); + labelToFieldNameMap.put("箱号", "boxPalletNo"); + labelToFieldNameMap.put("卡板号", "boxPalletNo"); + labelToFieldNameMap.put("生产日期", "productionDate"); + labelToFieldNameMap.put("过期日期", "expiryDate"); + labelToFieldNameMap.put("存货日期", "inventoryDate"); + labelToFieldNameMap.put("扩展字段1", "extAttr1"); + labelToFieldNameMap.put("扩展字段2", "extAttr2"); + labelToFieldNameMap.put("扩展字段3", "extAttr3"); + labelToFieldNameMap.put("扩展字段4", "extAttr4"); + + // 精确匹配 + String fieldName = labelToFieldNameMap.get(batchLabel.trim()); + if (StringUtils.isNotBlank(fieldName)) { + return fieldName; + } + + // 模糊匹配(包含关系) + for (Map.Entry entry : labelToFieldNameMap.entrySet()) { + if (batchLabel.contains(entry.getKey()) || entry.getKey().contains(batchLabel)) { + return entry.getValue(); + } + } + + return null; + } + + /** + * 根据字段名从对象中获取字段值(使用反射) + * @param obj 对象 + * @param fieldName 字段名 + * @return 字段值(转换为字符串) + */ + private String getFieldValueByFieldName(Object obj, String fieldName) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return null; + } + + try { + // 兼容:如果传的是下划线命名(数据库列名风格),先转成驼峰字段名再取 + String normalizedFieldName = fieldName; + if (normalizedFieldName.contains("_")) { + normalizedFieldName = snakeToCamel(normalizedFieldName); + } + + // 获取对象的Class + Class clazz = obj.getClass(); + + // 尝试获取字段(包括父类字段) + Field field = null; + Class currentClass = clazz; + while (currentClass != null && field == null) { + try { + field = currentClass.getDeclaredField(normalizedFieldName); + } catch (NoSuchFieldException e) { + currentClass = currentClass.getSuperclass(); + } + } + + if (field == null) { + log.warn("字段不存在:{}(normalized:{}),对象类型:{}", fieldName, normalizedFieldName, clazz.getName()); + return null; + } + + // 设置可访问 + field.setAccessible(true); + + // 获取字段值 + Object value = field.get(obj); + + // 转换为字符串 + if (value == null) { + log.info("字段 {} 的值为 null,对象类型:{}", normalizedFieldName, clazz.getName()); + return null; + } + + String result; + // 处理日期类型字段 + if (value instanceof Date) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + result = sdf.format((Date) value); + } else { + result = value.toString(); + } + + log.info("通过反射获取字段值成功,字段名:{}(原始:{}),值:{},对象类型:{}", + normalizedFieldName, fieldName, result, clazz.getName()); + return result; + } catch (Exception e) { + log.warn("通过反射获取字段值失败,字段名:{},对象类型:{},错误:{}", fieldName, obj.getClass().getName(), e.getMessage()); + return null; + } + } + + private String snakeToCamel(String snake) { + if (StringUtils.isBlank(snake)) { + return null; + } + String s = snake.trim().toLowerCase(); + StringBuilder sb = new StringBuilder(); + boolean upperNext = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '_') { + upperNext = true; + continue; + } + if (upperNext) { + sb.append(Character.toUpperCase(c)); + upperNext = false; + } else { + sb.append(c); + } + } + return sb.toString(); } /** diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/materialBaseInfo/MaterialBaseInfoApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/materialBaseInfo/MaterialBaseInfoApplicationService.java index 37aac16d1..1eff5f2c4 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/materialBaseInfo/MaterialBaseInfoApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/materialBaseInfo/MaterialBaseInfoApplicationService.java @@ -1,5 +1,6 @@ package com.mhd.wms.application.service.materialBaseInfo; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.model.LoginUser; import com.mhd.wms.domain.materialBarCode.service.MaterialBarCodeDomainService; @@ -8,17 +9,24 @@ import com.mhd.wms.domain.materialBaseInfo.repository.todo.MaterialBaseInfoDO; import com.mhd.wms.domain.materialBaseInfo.service.MaterialBaseInfoDomainService; import com.mhd.wms.domain.materialCommon.repository.todo.MaterialCommonDO; import com.mhd.wms.domain.materialCommon.service.MaterialCommonDomainService; +import com.mhd.wms.domain.materialGoodsRule.entity.MaterialGoodsRule; +import com.mhd.wms.domain.materialGoodsRule.repository.mapper.MaterialGoodsRuleMapper; +import com.mhd.wms.domain.materialGoodsRule.repository.po.MaterialGoodsRulePO; import com.mhd.wms.domain.materialGoodsRule.repository.todo.MaterialGoodsRuleDO; import com.mhd.wms.domain.materialGoodsRule.service.MaterialGoodsRuleDomainService; import com.mhd.wms.domain.materialInventoryWarning.service.MaterialInventoryWarningDomainService; import com.mhd.wms.domain.materialWarehouseControl.repository.todo.MaterialWarehouseControlDO; import com.mhd.wms.domain.materialWarehouseControl.service.MaterialWarehouseControlDomainService; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; import java.util.List; +import java.util.stream.Collectors; /** * 物料基础信息ApplicationService @@ -42,6 +50,8 @@ public class MaterialBaseInfoApplicationService { @Autowired private MaterialBarCodeDomainService materialBarCodeDomainService; + @Autowired + private MaterialGoodsRuleMapper materialGoodsRuleMapper; /** * 分页查询物料基础信息列表 @@ -55,7 +65,34 @@ public class MaterialBaseInfoApplicationService { materialBaseInfoDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); } } - return materialBaseInfoDomainService.queryList(materialBaseInfoDO); + List materialBaseInfoPOS = materialBaseInfoDomainService.queryList(materialBaseInfoDO); + for (MaterialBaseInfoPO materialBaseInfoPO : materialBaseInfoPOS) { + //物料商品规则 + MaterialGoodsRule materialGoodsRules = materialGoodsRuleMapper.selectOne(new LambdaQueryWrapper() + .eq(MaterialGoodsRule::getMaterialBaseInfoId, materialBaseInfoPO.getMaterialBaseInfoId()) + .eq(MaterialGoodsRule::getDelFlag, 1)); + if (materialGoodsRules != null){ + MaterialGoodsRulePO materialGoodsRulePO = new MaterialGoodsRulePO(); + BeanUtils.copyProperties(materialGoodsRules,materialGoodsRulePO); + materialBaseInfoPO.setMaterialGoodsRule(materialGoodsRulePO); + } + // 将物料分类的List转换为逗号分隔的字符串,用于导出 + if (!CollectionUtils.isEmpty(materialBaseInfoPO.getMaterialClassifyCode())) { + materialBaseInfoPO.setMaterialClassifyCodeStr( + materialBaseInfoPO.getMaterialClassifyCode().stream() + .filter(code -> !StringUtils.isEmpty(code)) + .collect(Collectors.joining(",")) + ); + } + if (!CollectionUtils.isEmpty(materialBaseInfoPO.getMaterialClassifyName())) { + materialBaseInfoPO.setMaterialClassifyNameStr( + materialBaseInfoPO.getMaterialClassifyName().stream() + .filter(name -> !StringUtils.isEmpty(name)) + .collect(Collectors.joining(",")) + ); + } + } + return materialBaseInfoPOS; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/materialInventory/MaterialInventoryApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/materialInventory/MaterialInventoryApplicationService.java index 44d7ca251..d99e00be0 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/materialInventory/MaterialInventoryApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/materialInventory/MaterialInventoryApplicationService.java @@ -1,21 +1,32 @@ package com.mhd.wms.application.service.materialInventory; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSONObject; import com.alibaba.nacos.common.utils.CollectionUtils; +import com.mhd.common.core.utils.StringUtils; +import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.SystemServiceFeign; +import com.mhd.system.api.domain.BatchDetailFeignPO; 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.materialInventory.repository.mapper.MaterialInventoryMapper; import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO; import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryQueryListPO; import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryDO; import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryQueryListDO; import com.mhd.wms.domain.materialInventory.service.MaterialInventoryDomainService; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.lang.reflect.Field; import java.math.BigDecimal; -import java.util.List; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; /** * 物料库存ApplicationService @@ -28,6 +39,10 @@ import java.util.List; public class MaterialInventoryApplicationService { @Autowired private MaterialInventoryDomainService materialInventoryDomainService; + @Autowired + private SystemServiceFeign systemServiceFeign; + @Autowired + private MaterialInventoryMapper materialInventoryMapper; /** @@ -47,6 +62,274 @@ public class MaterialInventoryApplicationService { return materialInventoryDomainService.queryList(materialInventoryDO); } + /** + * 查询物料库存列表(带批次属性) + * 批次属性值从库存表中获取 + */ + public List queryListWithBatchAttributes(MaterialInventoryDO materialInventoryDO) { + List list = queryList(materialInventoryDO); + + if (CollectionUtils.isEmpty(list)) { + return list; + } + + // 性能优化:批量获取批次属性,避免N+1查询问题 + // 1. 收集所有唯一的materialBaseInfoId + Set materialBaseInfoIdSet = list.stream() + .map(MaterialInventoryPO::getMaterialBaseInfoId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 2. 批量查询批次属性(使用Map缓存,避免重复查询相同的materialBaseInfoId) + Map> batchDetailMap = new HashMap<>(); + for (Long materialBaseInfoId : materialBaseInfoIdSet) { + try { + AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + List batchDetailFeignPOList = JSON.parseArray( + JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class); + if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) { + // 过滤isDisplay=1的属性 + List filteredList = batchDetailFeignPOList.stream() + .filter(batchDetail -> batchDetail.getIsDisplay() != null && batchDetail.getIsDisplay() == 1) + .collect(Collectors.toList()); + batchDetailMap.put(materialBaseInfoId, filteredList); + } + } + } catch (Exception e) { + log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + } + + // 3. 为每个物料库存设置更多属性(从库存表中获取值) + setMaterialMoreDetailListFromInventory(list, batchDetailMap); + + return list; + } + + /** + * 为物料库存设置更多属性(从库存表中获取值) + * @param materialInventoryPOList 物料库存列表 + * @param batchDetailMap 批次属性Map + */ + private void setMaterialMoreDetailListFromInventory(List materialInventoryPOList, + Map> batchDetailMap) { + if (CollectionUtils.isEmpty(materialInventoryPOList)) { + return; + } + + materialInventoryPOList.forEach(materialInventoryPO -> { + Long materialBaseInfoId = materialInventoryPO.getMaterialBaseInfoId(); + Long materialInventoryId = materialInventoryPO.getMaterialInventoryId(); + + // 创建新的materialMoreDetailList,只包含isDisplay=1的属性 + List materialMoreDetailList = new ArrayList<>(); + + // 从库存表获取数据(包含批次属性字段) + MaterialInventoryPO inventoryPO = null; + if (materialInventoryId != null) { + inventoryPO = materialInventoryMapper.selectByIdWithBatchAttributes(materialInventoryId); + } + + if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) { + List batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId); + // 用于跟踪已添加到列表中的batchDetailId + Set addedBatchDetailIds = new HashSet<>(); + + for (BatchDetailFeignPO batchDetailFeignPO : batchDetailFeignPOList) { + MaterialMoreDetailPO materialMoreDetailPO = new MaterialMoreDetailPO(); + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + + // 确保添加到列表中(使用batchDetailId来避免重复) + Long batchDetailId = batchDetailFeignPO.getBatchDetailId(); + if (batchDetailId != null && !addedBatchDetailIds.contains(batchDetailId)) { + materialMoreDetailList.add(materialMoreDetailPO); + addedBatchDetailIds.add(batchDetailId); + } + + // 根据fieldName或batchLabels从库存表中获取对应的字段值 + if (inventoryPO != null) { + String fieldValue = null; + String usedFieldName = null; + // 优先使用fieldName(如果存在) + if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) { + usedFieldName = batchDetailFeignPO.getFieldName(); + fieldValue = getFieldValueByFieldName(inventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, fieldName={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue); + } + // 如果fieldName为空,尝试根据batchLabels映射到字段名 + else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) { + String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels()); + if (StringUtils.isNotBlank(fieldNameByLabel)) { + usedFieldName = fieldNameByLabel; + fieldValue = getFieldValueByFieldName(inventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(), + usedFieldName, fieldValue); + } + } + // 只有当获取到值时才更新attributeValue + if (fieldValue != null) { + materialMoreDetailPO.setAttributeValue(fieldValue); + log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}", + materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(), + materialMoreDetailPO.getAttributeValue()); + } + } + } + } + materialInventoryPO.setMaterialMoreDetailList(materialMoreDetailList); + log.info("物料库存 materialInventoryId={}, materialBaseInfoId={}, materialMoreDetailList大小={}", + materialInventoryPO.getMaterialInventoryId(), materialInventoryPO.getMaterialBaseInfoId(), + materialMoreDetailList != null ? materialMoreDetailList.size() : 0); + }); + } + + /** + * 根据批次标签(batchLabels)映射到字段名 + * @param batchLabel 批次标签 + * @return 字段名,如果找不到映射则返回null + */ + private String getFieldNameByBatchLabel(String batchLabel) { + if (StringUtils.isBlank(batchLabel)) { + return null; + } + + // 批次标签到字段名的映射关系 + Map labelToFieldNameMap = new HashMap<>(); + labelToFieldNameMap.put("Invoice No.", "invoiceNo"); + labelToFieldNameMap.put("Invoice No", "invoiceNo"); + labelToFieldNameMap.put("发票号", "invoiceNo"); + labelToFieldNameMap.put("Batch Ref NO's", "batchRefNo"); + labelToFieldNameMap.put("Batch Ref NO", "batchRefNo"); + labelToFieldNameMap.put("批次参考号", "batchRefNo"); + labelToFieldNameMap.put("Sheet Ref NO's", "sheetRefNo"); + labelToFieldNameMap.put("Sheet Ref NO", "sheetRefNo"); + labelToFieldNameMap.put("单据参考号", "sheetRefNo"); + labelToFieldNameMap.put("箱号/卡板号", "boxPalletNo"); + labelToFieldNameMap.put("箱号", "boxPalletNo"); + labelToFieldNameMap.put("卡板号", "boxPalletNo"); + labelToFieldNameMap.put("生产日期", "productionDate"); + labelToFieldNameMap.put("过期日期", "expiryDate"); + labelToFieldNameMap.put("存货日期", "inventoryDate"); + labelToFieldNameMap.put("扩展字段1", "extAttr1"); + labelToFieldNameMap.put("扩展字段2", "extAttr2"); + labelToFieldNameMap.put("扩展字段3", "extAttr3"); + labelToFieldNameMap.put("扩展字段4", "extAttr4"); + + // 精确匹配 + String fieldName = labelToFieldNameMap.get(batchLabel.trim()); + if (StringUtils.isNotBlank(fieldName)) { + return fieldName; + } + + // 模糊匹配(包含关系) + for (Map.Entry entry : labelToFieldNameMap.entrySet()) { + if (batchLabel.contains(entry.getKey()) || entry.getKey().contains(batchLabel)) { + return entry.getValue(); + } + } + + return null; + } + + /** + * 根据字段名从对象中获取字段值(使用反射) + * @param obj 对象 + * @param fieldName 字段名 + * @return 字段值(转换为字符串) + */ + private String getFieldValueByFieldName(Object obj, String fieldName) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return null; + } + + try { + // 兼容:如果传的是下划线命名(数据库列名风格),先转成驼峰字段名再取 + String normalizedFieldName = fieldName; + if (normalizedFieldName.contains("_")) { + normalizedFieldName = snakeToCamel(normalizedFieldName); + } + + // 获取对象的Class + Class clazz = obj.getClass(); + + // 尝试获取字段(包括父类字段) + Field field = null; + Class currentClass = clazz; + while (currentClass != null && field == null) { + try { + field = currentClass.getDeclaredField(normalizedFieldName); + } catch (NoSuchFieldException e) { + currentClass = currentClass.getSuperclass(); + } + } + + if (field == null) { + log.warn("字段不存在:{}(normalized:{}),对象类型:{}", fieldName, normalizedFieldName, clazz.getName()); + return null; + } + + // 设置可访问 + field.setAccessible(true); + + // 获取字段值 + Object value = field.get(obj); + + // 转换为字符串 + if (value == null) { + log.info("字段 {} 的值为 null,对象类型:{}", normalizedFieldName, clazz.getName()); + return null; + } + + String result; + // 处理日期类型字段 + if (value instanceof Date) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + result = sdf.format((Date) value); + } else { + result = value.toString(); + } + + log.info("通过反射获取字段值成功,字段名:{}(原始:{}),值:{},对象类型:{}", + normalizedFieldName, fieldName, result, clazz.getName()); + return result; + } catch (Exception e) { + log.warn("通过反射获取字段值失败,字段名:{},对象类型:{},错误:{}", fieldName, obj.getClass().getName(), e.getMessage()); + return null; + } + } + + private String snakeToCamel(String snake) { + if (StringUtils.isBlank(snake)) { + return null; + } + String s = snake.trim().toLowerCase(); + StringBuilder sb = new StringBuilder(); + boolean upperNext = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '_') { + upperNext = true; + continue; + } + if (upperNext) { + sb.append(Character.toUpperCase(c)); + upperNext = false; + } else { + sb.append(c); + } + } + return sb.toString(); + } + public BigDecimal sumInventoryQuantity(MaterialInventoryDO materialInventoryDO) { LoginUser loginUser = SecurityUtils.getLoginUser(); if (loginUser != null){ diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/noticeOrder/NoticeOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/noticeOrder/NoticeOrderApplicationService.java index 2096ab5da..91e5fa355 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/noticeOrder/NoticeOrderApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/noticeOrder/NoticeOrderApplicationService.java @@ -139,6 +139,9 @@ public class NoticeOrderApplicationService { * @param noticeOrderDO */ private void setWarehouseInfo(NoticeOrderDO noticeOrderDO) { + if (noticeOrderDO.getWarehouseId() == null) { + throw new ServiceException("仓库ID不能为空"); + } AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(noticeOrderDO.getWarehouseId()); if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ throw new ServiceException("获取仓库信息失败"); diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/pickingOrder/PickingOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/pickingOrder/PickingOrderApplicationService.java index 46b85242b..c6049a450 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/pickingOrder/PickingOrderApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/pickingOrder/PickingOrderApplicationService.java @@ -6,15 +6,18 @@ 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.utils.bean.BeanUtils; import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.SystemServiceFeign; import com.mhd.system.api.UserServiceFeign; +import com.mhd.system.api.domain.BatchDetailFeignPO; 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.materialMoreDetail.repository.po.MaterialMoreDetailPO; import com.mhd.wms.domain.pickingMaterialDetail.repository.po.PickingMaterialDetailPO; import com.mhd.wms.domain.pickingMaterialDetail.repository.todo.PickingMaterialDetailDO; import com.mhd.wms.domain.pickingMaterialDetail.service.PickingMaterialDetailDomainService; @@ -26,10 +29,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; +import java.lang.reflect.Field; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.text.SimpleDateFormat; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -66,7 +69,52 @@ public class PickingOrderApplicationService { AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); pickingOrderDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId()); } - return pickingOrderDomainService.queryList(pickingOrderDO); + List pickingOrderPOList = pickingOrderDomainService.queryList(pickingOrderDO); + + // 重新计算物料种类数:按料号去重,一个料号算一种物料 + if (!CollectionUtils.isEmpty(pickingOrderPOList)) { + // 收集所有拣货单号 + List pickingOrderNumbers = pickingOrderPOList.stream() + .map(PickingOrderPO::getPickingOrderNumber) + .filter(Objects::nonNull) + .filter(number -> !number.trim().isEmpty()) + .collect(Collectors.toList()); + + if (!pickingOrderNumbers.isEmpty()) { + // 批量查询所有拣货单的物料明细(循环查询每个拣货单的物料明细) + Map> materialDetailsByOrderNumber = new HashMap<>(); + for (String pickingOrderNumber : pickingOrderNumbers) { + PickingMaterialDetailDO pickingMaterialDetailDO = new PickingMaterialDetailDO(); + pickingMaterialDetailDO.setPickingOrderNumber(pickingOrderNumber); + List materialDetails = pickingMaterialDetailDomainService.queryList(pickingMaterialDetailDO); + if (!CollectionUtils.isEmpty(materialDetails)) { + materialDetailsByOrderNumber.put(pickingOrderNumber, materialDetails); + } + } + + // 为每个拣货单计算物料种类数(按料号去重) + for (PickingOrderPO pickingOrderPO : pickingOrderPOList) { + String pickingOrderNumber = pickingOrderPO.getPickingOrderNumber(); + if (pickingOrderNumber != null && materialDetailsByOrderNumber.containsKey(pickingOrderNumber)) { + List materialDetails = materialDetailsByOrderNumber.get(pickingOrderNumber); + // 按料号去重,计算物料种类数 + long materialQuantity = materialDetails.stream() + .map(PickingMaterialDetailPO::getMaterialCode) + .filter(Objects::nonNull) + .filter(code -> !code.trim().isEmpty()) + .distinct() + .count(); + pickingOrderPO.setMaterialQuantity((int) materialQuantity); + log.debug("重新计算物料种类数 - 拣货单号: {}, 物料种类数: {}", pickingOrderNumber, materialQuantity); + } else { + // 如果没有物料明细,物料种类数为0 + pickingOrderPO.setMaterialQuantity(0); + } + } + } + } + + return pickingOrderPOList; } @@ -96,7 +144,295 @@ public class PickingOrderApplicationService { * 获取拣货单详细信息 */ public PickingOrderPO getInfoByIdAndType(Long pickingOrderId, Integer type) { - return pickingOrderDomainService.getInfoByIdAndType(pickingOrderId, type); + PickingOrderPO pickingOrderPO = pickingOrderDomainService.getInfoByIdAndType(pickingOrderId, type); + List pickingMaterialDetailPOList = pickingOrderPO.getMaterialDetailList(); + + if (CollectionUtils.isEmpty(pickingMaterialDetailPOList)) { + return pickingOrderPO; + } + + // 性能优化:批量获取批次属性,避免N+1查询问题 + // 1. 收集所有唯一的materialBaseInfoId + Set materialBaseInfoIdSet = pickingMaterialDetailPOList.stream() + .map(PickingMaterialDetailPO::getMaterialBaseInfoId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 2. 批量查询批次属性(使用Map缓存,避免重复查询相同的materialBaseInfoId) + Map> batchDetailMap = new HashMap<>(); + for (Long materialBaseInfoId : materialBaseInfoIdSet) { + try { + AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + List batchDetailFeignPOList = JSON.parseArray( + JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class); + if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) { + // 过滤isDisplay=1的属性 + List filteredList = batchDetailFeignPOList.stream() + .filter(batchDetail -> batchDetail.getIsDisplay() != null && batchDetail.getIsDisplay() == 1) + .collect(Collectors.toList()); + batchDetailMap.put(materialBaseInfoId, filteredList); + } + } + } catch (Exception e) { + log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + } + + // 3. 为每个物料明细设置更多属性(从物料明细中获取值),递归处理所有层级 + setMaterialMoreDetailListRecursively(pickingMaterialDetailPOList, batchDetailMap); + + pickingOrderPO.setMaterialDetailList(pickingMaterialDetailPOList); + log.info("返回拣货单信息,pickingOrderId={}, materialDetailList大小={}", + pickingOrderPO.getPickingOrderId(), + pickingMaterialDetailPOList != null ? pickingMaterialDetailPOList.size() : 0); + return pickingOrderPO; + } + + /** + * 递归为物料明细设置更多属性 + * @param pickingMaterialDetailPOList 物料明细列表 + * @param batchDetailMap 批次属性Map + */ + private void setMaterialMoreDetailListRecursively(List pickingMaterialDetailPOList, + Map> batchDetailMap) { + if (CollectionUtils.isEmpty(pickingMaterialDetailPOList)) { + return; + } + + pickingMaterialDetailPOList.forEach(pickingMaterialDetailPO -> { + Long materialBaseInfoId = pickingMaterialDetailPO.getMaterialBaseInfoId(); + + // 只保留isDisplay=1的批次属性(从batchDetailMap中获取,已经过滤过了) + // 创建新的materialMoreDetailList,只包含isDisplay=1的属性 + List materialMoreDetailList = new ArrayList<>(); + + // 创建batchDetailId到MaterialMoreDetailPO的映射,用于快速查找已有的属性值 + Map batchDetailIdToMaterialMoreDetailMap = new HashMap<>(); + List existingList = pickingMaterialDetailPO.getMaterialMoreDetailList(); + if (!CollectionUtils.isEmpty(existingList)) { + for (MaterialMoreDetailPO existing : existingList) { + if (existing.getBatchDetailId() != null) { + batchDetailIdToMaterialMoreDetailMap.put(existing.getBatchDetailId(), existing); + } + } + } + + if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) { + List batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId); + // 用于跟踪已添加到列表中的batchDetailId + Set addedBatchDetailIds = new HashSet<>(); + + for (BatchDetailFeignPO batchDetailFeignPO : batchDetailFeignPOList) { + MaterialMoreDetailPO materialMoreDetailPO = batchDetailIdToMaterialMoreDetailMap.get(batchDetailFeignPO.getBatchDetailId()); + + // 如果不存在,创建新的 + if (materialMoreDetailPO == null) { + materialMoreDetailPO = new MaterialMoreDetailPO(); + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + } else { + // 如果已存在,更新属性(保留已有的attributeValue) + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + } + + // 确保添加到列表中(使用batchDetailId来避免重复) + Long batchDetailId = batchDetailFeignPO.getBatchDetailId(); + if (batchDetailId != null && !addedBatchDetailIds.contains(batchDetailId)) { + materialMoreDetailList.add(materialMoreDetailPO); + addedBatchDetailIds.add(batchDetailId); + } + + // 根据fieldName或batchLabels从物料明细中获取对应的字段值 + if (pickingMaterialDetailPO != null) { + String fieldValue = null; + String usedFieldName = null; + // 优先使用fieldName(如果存在) + if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) { + usedFieldName = batchDetailFeignPO.getFieldName(); + fieldValue = getFieldValueByFieldName(pickingMaterialDetailPO, usedFieldName); + log.info("批次属性 batchDetailId={}, fieldName={}, 获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue); + } + // 如果fieldName为空,尝试根据batchLabels映射到字段名 + else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) { + String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels()); + if (StringUtils.isNotBlank(fieldNameByLabel)) { + usedFieldName = fieldNameByLabel; + fieldValue = getFieldValueByFieldName(pickingMaterialDetailPO, usedFieldName); + log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(), + usedFieldName, fieldValue); + } + } + // 只有当获取到值时才更新attributeValue(避免覆盖已有的值) + if (fieldValue != null) { + materialMoreDetailPO.setAttributeValue(fieldValue); + log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}", + materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(), + materialMoreDetailPO.getAttributeValue()); + } + } + } + } + pickingMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList); + log.info("物料明细 uniqueId={}, materialBaseInfoId={}, materialMoreDetailList大小={}", + pickingMaterialDetailPO.getUniqueId(), pickingMaterialDetailPO.getMaterialBaseInfoId(), + materialMoreDetailList != null ? materialMoreDetailList.size() : 0); + + // 递归处理子级 + if (!CollectionUtils.isEmpty(pickingMaterialDetailPO.getChildren())) { + setMaterialMoreDetailListRecursively(pickingMaterialDetailPO.getChildren(), batchDetailMap); + } + }); + } + + /** + * 根据批次标签(batchLabels)映射到字段名 + * @param batchLabel 批次标签 + * @return 字段名,如果找不到映射则返回null + */ + private String getFieldNameByBatchLabel(String batchLabel) { + if (StringUtils.isBlank(batchLabel)) { + return null; + } + + // 批次标签到字段名的映射关系 + Map labelToFieldNameMap = new HashMap<>(); + labelToFieldNameMap.put("Invoice No.", "invoiceNo"); + labelToFieldNameMap.put("Invoice No", "invoiceNo"); + labelToFieldNameMap.put("发票号", "invoiceNo"); + labelToFieldNameMap.put("Batch Ref NO's", "batchRefNo"); + labelToFieldNameMap.put("Batch Ref NO", "batchRefNo"); + labelToFieldNameMap.put("批次参考号", "batchRefNo"); + labelToFieldNameMap.put("Sheet Ref NO's", "sheetRefNo"); + labelToFieldNameMap.put("Sheet Ref NO", "sheetRefNo"); + labelToFieldNameMap.put("单据参考号", "sheetRefNo"); + labelToFieldNameMap.put("箱号/卡板号", "boxPalletNo"); + labelToFieldNameMap.put("箱号", "boxPalletNo"); + labelToFieldNameMap.put("卡板号", "boxPalletNo"); + labelToFieldNameMap.put("生产日期", "productionDate"); + labelToFieldNameMap.put("过期日期", "expiryDate"); + labelToFieldNameMap.put("存货日期", "inventoryDate"); + labelToFieldNameMap.put("扩展字段1", "extAttr1"); + labelToFieldNameMap.put("扩展字段2", "extAttr2"); + labelToFieldNameMap.put("扩展字段3", "extAttr3"); + labelToFieldNameMap.put("扩展字段4", "extAttr4"); + + // 精确匹配 + String fieldName = labelToFieldNameMap.get(batchLabel.trim()); + if (StringUtils.isNotBlank(fieldName)) { + return fieldName; + } + + // 模糊匹配(包含关系) + for (Map.Entry entry : labelToFieldNameMap.entrySet()) { + if (batchLabel.contains(entry.getKey()) || entry.getKey().contains(batchLabel)) { + return entry.getValue(); + } + } + + return null; + } + + /** + * 根据字段名从对象中获取字段值(使用反射) + * @param obj 对象 + * @param fieldName 字段名 + * @return 字段值(转换为字符串) + */ + private String getFieldValueByFieldName(Object obj, String fieldName) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return null; + } + + try { + // 兼容:如果传的是下划线命名(数据库列名风格),先转成驼峰字段名再取 + String normalizedFieldName = fieldName; + if (normalizedFieldName.contains("_")) { + normalizedFieldName = snakeToCamel(normalizedFieldName); + } + + // 获取对象的Class + Class clazz = obj.getClass(); + + // 尝试获取字段(包括父类字段) + Field field = null; + Class currentClass = clazz; + while (currentClass != null && field == null) { + try { + field = currentClass.getDeclaredField(normalizedFieldName); + } catch (NoSuchFieldException e) { + currentClass = currentClass.getSuperclass(); + } + } + + if (field == null) { + log.warn("字段不存在:{}(normalized:{}),对象类型:{}", fieldName, normalizedFieldName, clazz.getName()); + return null; + } + + // 设置可访问 + field.setAccessible(true); + + // 获取字段值 + Object value = field.get(obj); + + // 转换为字符串 + if (value == null) { + log.info("字段 {} 的值为 null,对象类型:{}", normalizedFieldName, clazz.getName()); + return null; + } + + String result; + // 处理日期类型字段 + if (value instanceof Date) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + result = sdf.format((Date) value); + } else { + result = value.toString(); + } + + log.info("通过反射获取字段值成功,字段名:{}(原始:{}),值:{},对象类型:{}", + normalizedFieldName, fieldName, result, clazz.getName()); + return result; + } catch (Exception e) { + log.warn("通过反射获取字段值失败,字段名:{},对象类型:{},错误:{}", fieldName, obj.getClass().getName(), e.getMessage()); + return null; + } + } + + private String snakeToCamel(String snake) { + if (StringUtils.isBlank(snake)) { + return null; + } + String s = snake.trim().toLowerCase(); + StringBuilder sb = new StringBuilder(); + boolean upperNext = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '_') { + upperNext = true; + continue; + } + if (upperNext) { + sb.append(Character.toUpperCase(c)); + upperNext = false; + } else { + sb.append(c); + } + } + return sb.toString(); } /** diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftManage/ShiftManageApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftManage/ShiftManageApplicationService.java index 6c573a755..5af67514e 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftManage/ShiftManageApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftManage/ShiftManageApplicationService.java @@ -242,6 +242,8 @@ public class ShiftManageApplicationService { if (shiftMaterialDetailPO == null){ throw new ServiceException("物料明细不存在"); } + //ShiftQuantity前端传过来是0 他那边不好赋值 和Quantity参数统一 + shiftMaterialDetailDO.setShiftQuantity(shiftMaterialDetailDO.getQuantity()); if (shiftMaterialDetailDO.getShiftQuantity().compareTo(BigDecimal.ZERO) == 0){ //未进行移位直接跳过 continue; @@ -339,6 +341,9 @@ public class ShiftManageApplicationService { * @param shiftManageDO */ private void setWarehouseInfo(ShiftManageDO shiftManageDO) { + if (shiftManageDO.getWarehouseId() == null) { + throw new ServiceException("仓库ID不能为空"); + } AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(shiftManageDO.getWarehouseId()); if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ throw new ServiceException("获取仓库信息失败"); @@ -368,14 +373,14 @@ public class ShiftManageApplicationService { shiftMaterialDetailDO.setNewStorageLocationName(storageLocationFeignPO.getStorageLocationName()); //获取容器详情 - AjaxResult ajaxResult = systemServiceFeign.getContainerInfoByContainerId(shiftMaterialDetailDO.getContainerId()); - if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ - throw new ServiceException("获取容器信息失败"); - } - ContainerFeignPO containerFeignPO = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), ContainerFeignPO.class); - shiftMaterialDetailDO.setContainerCode(containerFeignPO.getContainerCode()); - shiftMaterialDetailDO.setContainerType(containerFeignPO.getContainerType()); - shiftMaterialDetailDO.setContainerTypeName(containerFeignPO.getContainerTypeName()); +// AjaxResult ajaxResult = systemServiceFeign.getContainerInfoByContainerId(shiftMaterialDetailDO.getContainerId()); +// if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ +// throw new ServiceException("获取容器信息失败"); +// } +// ContainerFeignPO containerFeignPO = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), ContainerFeignPO.class); +// shiftMaterialDetailDO.setContainerCode(containerFeignPO.getContainerCode()); +// shiftMaterialDetailDO.setContainerType(containerFeignPO.getContainerType()); +// shiftMaterialDetailDO.setContainerTypeName(containerFeignPO.getContainerTypeName()); } /** diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftMaterialDetail/ShiftMaterialDetailApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftMaterialDetail/ShiftMaterialDetailApplicationService.java index b5184043f..256f592ea 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftMaterialDetail/ShiftMaterialDetailApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftMaterialDetail/ShiftMaterialDetailApplicationService.java @@ -1,16 +1,29 @@ package com.mhd.wms.application.service.shiftMaterialDetail; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.mhd.common.core.utils.StringUtils; +import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.SystemServiceFeign; +import com.mhd.system.api.domain.BatchDetailFeignPO; import com.mhd.system.api.model.LoginUser; +import com.mhd.wms.domain.materialInventory.entity.MaterialInventory; +import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper; +import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import com.mhd.wms.domain.shiftMaterialDetail.repository.po.ShiftMaterialDetailPO; import com.mhd.wms.domain.shiftMaterialDetail.repository.todo.ShiftMaterialDetailDO; import com.mhd.wms.domain.shiftMaterialDetail.service.ShiftMaterialDetailDomainService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; -import java.util.List; +import java.lang.reflect.Field; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; /** * 移位物料明细ApplicationService @@ -25,6 +38,8 @@ public class ShiftMaterialDetailApplicationService { private ShiftMaterialDetailDomainService shiftMaterialDetailDomainService; @Autowired private SystemServiceFeign systemServiceFeign; + @Autowired + private MaterialInventoryMapper materialInventoryMapper; /** * 分页查询移位物料明细列表 @@ -92,4 +107,273 @@ public class ShiftMaterialDetailApplicationService { return shiftMaterialDetailDomainService.getShiftMaterialDetail(shiftMaterialDetailDO); } + /** + * 查询移位物料明细列表(带批次属性) + * 批次属性值从库存表中获取 + */ + public List queryListWithBatchAttributes(ShiftMaterialDetailDO shiftMaterialDetailDO) { + List list = queryList(shiftMaterialDetailDO); + + if (CollectionUtils.isEmpty(list)) { + return list; + } + + // 性能优化:批量获取批次属性,避免N+1查询问题 + // 1. 收集所有唯一的materialBaseInfoId + Set materialBaseInfoIdSet = list.stream() + .map(ShiftMaterialDetailPO::getMaterialBaseInfoId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 2. 批量查询批次属性(使用Map缓存,避免重复查询相同的materialBaseInfoId) + Map> batchDetailMap = new HashMap<>(); + for (Long materialBaseInfoId : materialBaseInfoIdSet) { + try { + AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + List batchDetailFeignPOList = JSON.parseArray( + JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class); + if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) { + // 过滤isDisplay=1的属性 + List filteredList = batchDetailFeignPOList.stream() + .filter(batchDetail -> batchDetail.getIsDisplay() != null && batchDetail.getIsDisplay() == 1) + .collect(Collectors.toList()); + batchDetailMap.put(materialBaseInfoId, filteredList); + } + } + } catch (Exception e) { + log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + } + + // 3. 为每个物料明细设置更多属性(从库存表中获取值) + setMaterialMoreDetailListFromInventory(list, batchDetailMap); + + return list; + } + + /** + * 为移位物料明细设置更多属性(从库存表中获取值) + * @param shiftMaterialDetailPOList 移位物料明细列表 + * @param batchDetailMap 批次属性Map + */ + private void setMaterialMoreDetailListFromInventory(List shiftMaterialDetailPOList, + Map> batchDetailMap) { + if (CollectionUtils.isEmpty(shiftMaterialDetailPOList)) { + return; + } + + shiftMaterialDetailPOList.forEach(shiftMaterialDetailPO -> { + Long materialBaseInfoId = shiftMaterialDetailPO.getMaterialBaseInfoId(); + Long materialInventoryId = shiftMaterialDetailPO.getMaterialInventoryId(); + + // 创建新的materialMoreDetailList,只包含isDisplay=1的属性 + List materialMoreDetailList = new ArrayList<>(); + + // 从库存表获取数据(包含批次属性字段) + MaterialInventoryPO materialInventoryPO = null; + if (materialInventoryId != null) { + materialInventoryPO = materialInventoryMapper.selectByIdWithBatchAttributes(materialInventoryId); + } + + if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) { + List batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId); + // 用于跟踪已添加到列表中的batchDetailId + Set addedBatchDetailIds = new HashSet<>(); + + for (BatchDetailFeignPO batchDetailFeignPO : batchDetailFeignPOList) { + MaterialMoreDetailPO materialMoreDetailPO = new MaterialMoreDetailPO(); + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + + // 确保添加到列表中(使用batchDetailId来避免重复) + Long batchDetailId = batchDetailFeignPO.getBatchDetailId(); + if (batchDetailId != null && !addedBatchDetailIds.contains(batchDetailId)) { + materialMoreDetailList.add(materialMoreDetailPO); + addedBatchDetailIds.add(batchDetailId); + } + + // 根据fieldName或batchLabels从库存表中获取对应的字段值 + if (materialInventoryPO != null) { + String fieldValue = null; + String usedFieldName = null; + // 优先使用fieldName(如果存在) + if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) { + usedFieldName = batchDetailFeignPO.getFieldName(); + fieldValue = getFieldValueByFieldName(materialInventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, fieldName={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue); + } + // 如果fieldName为空,尝试根据batchLabels映射到字段名 + else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) { + String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels()); + if (StringUtils.isNotBlank(fieldNameByLabel)) { + usedFieldName = fieldNameByLabel; + fieldValue = getFieldValueByFieldName(materialInventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(), + usedFieldName, fieldValue); + } + } + // 只有当获取到值时才更新attributeValue + if (fieldValue != null) { + materialMoreDetailPO.setAttributeValue(fieldValue); + log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}", + materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(), + materialMoreDetailPO.getAttributeValue()); + } + } + } + } + shiftMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList); + log.info("移位物料明细 uniqueId={}, materialBaseInfoId={}, materialInventoryId={}, materialMoreDetailList大小={}", + shiftMaterialDetailPO.getUniqueId(), shiftMaterialDetailPO.getMaterialBaseInfoId(), + shiftMaterialDetailPO.getMaterialInventoryId(), + materialMoreDetailList != null ? materialMoreDetailList.size() : 0); + }); + } + + /** + * 根据批次标签(batchLabels)映射到字段名 + * @param batchLabel 批次标签 + * @return 字段名,如果找不到映射则返回null + */ + private String getFieldNameByBatchLabel(String batchLabel) { + if (StringUtils.isBlank(batchLabel)) { + return null; + } + + // 批次标签到字段名的映射关系 + Map labelToFieldNameMap = new HashMap<>(); + labelToFieldNameMap.put("Invoice No.", "invoiceNo"); + labelToFieldNameMap.put("Invoice No", "invoiceNo"); + labelToFieldNameMap.put("发票号", "invoiceNo"); + labelToFieldNameMap.put("Batch Ref NO's", "batchRefNo"); + labelToFieldNameMap.put("Batch Ref NO", "batchRefNo"); + labelToFieldNameMap.put("批次参考号", "batchRefNo"); + labelToFieldNameMap.put("Sheet Ref NO's", "sheetRefNo"); + labelToFieldNameMap.put("Sheet Ref NO", "sheetRefNo"); + labelToFieldNameMap.put("单据参考号", "sheetRefNo"); + labelToFieldNameMap.put("箱号/卡板号", "boxPalletNo"); + labelToFieldNameMap.put("箱号", "boxPalletNo"); + labelToFieldNameMap.put("卡板号", "boxPalletNo"); + labelToFieldNameMap.put("生产日期", "productionDate"); + labelToFieldNameMap.put("过期日期", "expiryDate"); + labelToFieldNameMap.put("存货日期", "inventoryDate"); + labelToFieldNameMap.put("扩展字段1", "extAttr1"); + labelToFieldNameMap.put("扩展字段2", "extAttr2"); + labelToFieldNameMap.put("扩展字段3", "extAttr3"); + labelToFieldNameMap.put("扩展字段4", "extAttr4"); + + // 精确匹配 + String fieldName = labelToFieldNameMap.get(batchLabel.trim()); + if (StringUtils.isNotBlank(fieldName)) { + return fieldName; + } + + // 模糊匹配(包含关系) + for (Map.Entry entry : labelToFieldNameMap.entrySet()) { + if (batchLabel.contains(entry.getKey()) || entry.getKey().contains(batchLabel)) { + return entry.getValue(); + } + } + + return null; + } + + /** + * 根据字段名从对象中获取字段值(使用反射) + * @param obj 对象 + * @param fieldName 字段名 + * @return 字段值(转换为字符串) + */ + private String getFieldValueByFieldName(Object obj, String fieldName) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return null; + } + + try { + // 兼容:如果传的是下划线命名(数据库列名风格),先转成驼峰字段名再取 + String normalizedFieldName = fieldName; + if (normalizedFieldName.contains("_")) { + normalizedFieldName = snakeToCamel(normalizedFieldName); + } + + // 获取对象的Class + Class clazz = obj.getClass(); + + // 尝试获取字段(包括父类字段) + Field field = null; + Class currentClass = clazz; + while (currentClass != null && field == null) { + try { + field = currentClass.getDeclaredField(normalizedFieldName); + } catch (NoSuchFieldException e) { + currentClass = currentClass.getSuperclass(); + } + } + + if (field == null) { + log.warn("字段不存在:{}(normalized:{}),对象类型:{}", fieldName, normalizedFieldName, clazz.getName()); + return null; + } + + // 设置可访问 + field.setAccessible(true); + + // 获取字段值 + Object value = field.get(obj); + + // 转换为字符串 + if (value == null) { + log.info("字段 {} 的值为 null,对象类型:{}", normalizedFieldName, clazz.getName()); + return null; + } + + String result; + // 处理日期类型字段 + if (value instanceof Date) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + result = sdf.format((Date) value); + } else { + result = value.toString(); + } + + log.info("通过反射获取字段值成功,字段名:{}(原始:{}),值:{},对象类型:{}", + normalizedFieldName, fieldName, result, clazz.getName()); + return result; + } catch (Exception e) { + log.warn("通过反射获取字段值失败,字段名:{},对象类型:{},错误:{}", fieldName, obj.getClass().getName(), e.getMessage()); + return null; + } + } + + private String snakeToCamel(String snake) { + if (StringUtils.isBlank(snake)) { + return null; + } + String s = snake.trim().toLowerCase(); + StringBuilder sb = new StringBuilder(); + boolean upperNext = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '_') { + upperNext = true; + continue; + } + if (upperNext) { + sb.append(Character.toUpperCase(c)); + upperNext = false; + } else { + sb.append(c); + } + } + return sb.toString(); + } + } diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/statementStatistics/StatementStatisticsService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/statementStatistics/StatementStatisticsService.java index 022d8a2d7..4b13ec963 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/statementStatistics/StatementStatisticsService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/statementStatistics/StatementStatisticsService.java @@ -1,11 +1,20 @@ package com.mhd.wms.application.service.statementStatistics; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.mhd.common.core.utils.StringUtils; +import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.SystemServiceFeign; +import com.mhd.system.api.domain.BatchDetailFeignPO; 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.inventoryStandingDetail.service.InventoryStandingDetailDomainService; +import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper; +import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO; import com.mhd.wms.domain.materialInventory.service.MaterialInventoryDomainService; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import com.mhd.wms.domain.statementStatistics.po.ImmediateInventoryPO; import com.mhd.wms.domain.statementStatistics.po.WarehousingReportPO; import com.mhd.wms.domain.statementStatistics.todo.ImmediateInventoryDO; @@ -13,8 +22,12 @@ import com.mhd.wms.domain.statementStatistics.todo.WarehousingReportDO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; -import java.util.List; +import java.lang.reflect.Field; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; /** * 报表管理ApplicationService @@ -29,6 +42,10 @@ public class StatementStatisticsService { private MaterialInventoryDomainService materialInventoryDomainService; @Autowired private InventoryStandingDetailDomainService inventoryStandingDetailDomainService; + @Autowired + private MaterialInventoryMapper materialInventoryMapper; + @Autowired + private SystemServiceFeign systemServiceFeign; /** * 分页查询即时库存列表 @@ -41,10 +58,288 @@ public class StatementStatisticsService { if (topOrganizationId != null && topOrganizationId != 1){ immediateInventoryDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); } - AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); - immediateInventoryDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId()); + // 只有在用户没有明确指定仓库参数时,才使用缓存中的仓库信息 + // 如果用户已经传递了 warehouseId、warehouseCode 或 warehouseName,优先使用这些值 + boolean hasWarehouseFilter = (immediateInventoryDO.getWarehouseId() != null) + || (immediateInventoryDO.getWarehouseCode() != null && !immediateInventoryDO.getWarehouseCode().trim().isEmpty()) + || (immediateInventoryDO.getWarehouseName() != null && !immediateInventoryDO.getWarehouseName().trim().isEmpty()); + + if (!hasWarehouseFilter) { + try { + AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); + if (associationWarehouseCacheDO != null) { + if (associationWarehouseCacheDO.getWarehouseId() != null) { + immediateInventoryDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId()); + } + if (associationWarehouseCacheDO.getWarehouseCode() != null && !associationWarehouseCacheDO.getWarehouseCode().trim().isEmpty()) { + immediateInventoryDO.setWarehouseCode(associationWarehouseCacheDO.getWarehouseCode()); + } + if (associationWarehouseCacheDO.getWarehouseName() != null && !associationWarehouseCacheDO.getWarehouseName().trim().isEmpty()) { + immediateInventoryDO.setWarehouseName(associationWarehouseCacheDO.getWarehouseName()); + } + } + } catch (Exception e) { + // 如果获取仓库信息失败,记录日志但不影响查询(允许查询所有仓库) + log.warn("获取用户关联仓库信息失败,将查询所有仓库数据,用户ID:{},错误:{}", loginUser.getUserid(), e.getMessage()); + } + } } - return materialInventoryDomainService.queryImmediateInventoryList(immediateInventoryDO); + List immediateInventoryPOS = materialInventoryDomainService.queryImmediateInventoryList(immediateInventoryDO); +// 性能优化:批量获取批次属性,避免N+1查询问题 + // 1. 收集所有唯一的materialBaseInfoId + Set materialBaseInfoIdSet = immediateInventoryPOS.stream() + .map(ImmediateInventoryPO::getMaterialBaseInfoId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 2. 批量查询批次属性(使用Map缓存,避免重复查询相同的materialBaseInfoId) + Map> batchDetailMap = new HashMap<>(); + for (Long materialBaseInfoId : materialBaseInfoIdSet) { + try { + AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + List batchDetailFeignPOList = JSON.parseArray( + JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class); + if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) { + // 过滤isDisplay=1的属性 + List filteredList = batchDetailFeignPOList.stream() + .filter(batchDetail -> batchDetail.getIsDisplay() != null && batchDetail.getIsDisplay() == 1) + .collect(Collectors.toList()); + batchDetailMap.put(materialBaseInfoId, filteredList); + } + } + } catch (Exception e) { + log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + } + + // 3. 为每个物料明细设置更多属性(从库存表中获取值) + setMaterialMoreDetailListFromInventory(immediateInventoryPOS, batchDetailMap); + + return immediateInventoryPOS; + } + + /** + * 为物料库存设置更多属性(从库存表中获取值) + * @param materialInventoryPOList 物料库存列表 + * @param batchDetailMap 批次属性Map + */ + private void setMaterialMoreDetailListFromInventory(List materialInventoryPOList, + Map> batchDetailMap) { + if (CollectionUtils.isEmpty(materialInventoryPOList)) { + return; + } + + materialInventoryPOList.forEach(materialInventoryPO -> { + Long materialBaseInfoId = materialInventoryPO.getMaterialBaseInfoId(); + Long materialInventoryId = materialInventoryPO.getMaterialInventoryId(); + + // 创建新的materialMoreDetailList,只包含isDisplay=1的属性 + List materialMoreDetailList = new ArrayList<>(); + + // 从库存表获取数据(包含批次属性字段) + MaterialInventoryPO inventoryPO = null; + if (materialInventoryId != null) { + inventoryPO = materialInventoryMapper.selectByIdWithBatchAttributes(materialInventoryId); + } + + if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) { + List batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId); + // 用于跟踪已添加到列表中的batchDetailId + Set addedBatchDetailIds = new HashSet<>(); + + for (BatchDetailFeignPO batchDetailFeignPO : batchDetailFeignPOList) { + MaterialMoreDetailPO materialMoreDetailPO = new MaterialMoreDetailPO(); + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + + // 确保添加到列表中(使用batchDetailId来避免重复) + Long batchDetailId = batchDetailFeignPO.getBatchDetailId(); + if (batchDetailId != null && !addedBatchDetailIds.contains(batchDetailId)) { + materialMoreDetailList.add(materialMoreDetailPO); + addedBatchDetailIds.add(batchDetailId); + } + + // 根据fieldName或batchLabels从库存表中获取对应的字段值 + if (inventoryPO != null) { + String fieldValue = null; + String usedFieldName = null; + // 优先使用fieldName(如果存在) + if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) { + usedFieldName = batchDetailFeignPO.getFieldName(); + fieldValue = getFieldValueByFieldName(inventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, fieldName={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue); + } + // 如果fieldName为空,尝试根据batchLabels映射到字段名 + else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) { + String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels()); + if (StringUtils.isNotBlank(fieldNameByLabel)) { + usedFieldName = fieldNameByLabel; + fieldValue = getFieldValueByFieldName(inventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(), + usedFieldName, fieldValue); + } + } + // 只有当获取到值时才更新attributeValue + if (fieldValue != null) { + materialMoreDetailPO.setAttributeValue(fieldValue); + log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}", + materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(), + materialMoreDetailPO.getAttributeValue()); + } + } + } + } + materialInventoryPO.setMaterialMoreDetailList(materialMoreDetailList); + log.info("物料库存 materialInventoryId={}, materialBaseInfoId={}, materialMoreDetailList大小={}", + materialInventoryPO.getMaterialInventoryId(), materialInventoryPO.getMaterialBaseInfoId(), + materialMoreDetailList != null ? materialMoreDetailList.size() : 0); + }); + } + + /** + * 根据字段名从对象中获取字段值(使用反射) + * @param obj 对象 + * @param fieldName 字段名 + * @return 字段值(转换为字符串) + */ + private String getFieldValueByFieldName(Object obj, String fieldName) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return null; + } + + try { + // 兼容:如果传的是下划线命名(数据库列名风格),先转成驼峰字段名再取 + String normalizedFieldName = fieldName; + if (normalizedFieldName.contains("_")) { + normalizedFieldName = snakeToCamel(normalizedFieldName); + } + + // 获取对象的Class + Class clazz = obj.getClass(); + + // 尝试获取字段(包括父类字段) + Field field = null; + Class currentClass = clazz; + while (currentClass != null && field == null) { + try { + field = currentClass.getDeclaredField(normalizedFieldName); + } catch (NoSuchFieldException e) { + currentClass = currentClass.getSuperclass(); + } + } + + if (field == null) { + log.warn("字段不存在:{}(normalized:{}),对象类型:{}", fieldName, normalizedFieldName, clazz.getName()); + return null; + } + + // 设置可访问 + field.setAccessible(true); + + // 获取字段值 + Object value = field.get(obj); + + // 转换为字符串 + if (value == null) { + log.info("字段 {} 的值为 null,对象类型:{}", normalizedFieldName, clazz.getName()); + return null; + } + + String result; + // 处理日期类型字段 + if (value instanceof Date) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + result = sdf.format((Date) value); + } else { + result = value.toString(); + } + + log.info("通过反射获取字段值成功,字段名:{}(原始:{}),值:{},对象类型:{}", + normalizedFieldName, fieldName, result, clazz.getName()); + return result; + } catch (Exception e) { + log.warn("通过反射获取字段值失败,字段名:{},对象类型:{},错误:{}", fieldName, obj.getClass().getName(), e.getMessage()); + return null; + } + } + + private String snakeToCamel(String snake) { + if (StringUtils.isBlank(snake)) { + return null; + } + String s = snake.trim().toLowerCase(); + StringBuilder sb = new StringBuilder(); + boolean upperNext = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '_') { + upperNext = true; + continue; + } + if (upperNext) { + sb.append(Character.toUpperCase(c)); + upperNext = false; + } else { + sb.append(c); + } + } + return sb.toString(); + } + + /** + * 根据批次标签(batchLabels)映射到字段名 + * @param batchLabel 批次标签 + * @return 字段名,如果找不到映射则返回null + */ + private String getFieldNameByBatchLabel(String batchLabel) { + if (StringUtils.isBlank(batchLabel)) { + return null; + } + + // 批次标签到字段名的映射关系 + Map labelToFieldNameMap = new HashMap<>(); + labelToFieldNameMap.put("Invoice No.", "invoiceNo"); + labelToFieldNameMap.put("Invoice No", "invoiceNo"); + labelToFieldNameMap.put("发票号", "invoiceNo"); + labelToFieldNameMap.put("Batch Ref NO's", "batchRefNo"); + labelToFieldNameMap.put("Batch Ref NO", "batchRefNo"); + labelToFieldNameMap.put("批次参考号", "batchRefNo"); + labelToFieldNameMap.put("Sheet Ref NO's", "sheetRefNo"); + labelToFieldNameMap.put("Sheet Ref NO", "sheetRefNo"); + labelToFieldNameMap.put("单据参考号", "sheetRefNo"); + labelToFieldNameMap.put("箱号/卡板号", "boxPalletNo"); + labelToFieldNameMap.put("箱号", "boxPalletNo"); + labelToFieldNameMap.put("卡板号", "boxPalletNo"); + labelToFieldNameMap.put("生产日期", "productionDate"); + labelToFieldNameMap.put("过期日期", "expiryDate"); + labelToFieldNameMap.put("存货日期", "inventoryDate"); + labelToFieldNameMap.put("扩展字段1", "extAttr1"); + labelToFieldNameMap.put("扩展字段2", "extAttr2"); + labelToFieldNameMap.put("扩展字段3", "extAttr3"); + labelToFieldNameMap.put("扩展字段4", "extAttr4"); + + // 精确匹配 + String fieldName = labelToFieldNameMap.get(batchLabel.trim()); + if (StringUtils.isNotBlank(fieldName)) { + return fieldName; + } + + // 模糊匹配(包含关系) + for (Map.Entry entry : labelToFieldNameMap.entrySet()) { + if (batchLabel.contains(entry.getKey()) || entry.getKey().contains(batchLabel)) { + return entry.getValue(); + } + } + + return null; } /** @@ -98,4 +393,4 @@ public class StatementStatisticsService { } -} +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java index 4db45edd8..ad72c6048 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java @@ -8,6 +8,7 @@ import com.mhd.common.core.domain.po.UserPo; import com.mhd.common.core.enums.DictCode; import com.mhd.common.core.exception.ServiceException; import com.mhd.common.core.utils.StringUtils; +import com.mhd.common.core.utils.poi.ExcelUtil; import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.SystemServiceFeign; @@ -17,14 +18,30 @@ import com.mhd.system.api.domain.WarehouseFeignPO; 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.inMaterialDetail.repository.todo.InMaterialDetailDO; +import com.mhd.wms.domain.materialBaseInfo.repository.facade.IMaterialBaseInfoService; +import com.mhd.wms.domain.materialBaseInfo.repository.po.MaterialBaseInfoPO; +import com.mhd.wms.domain.materialBaseInfo.repository.todo.MaterialBaseInfoDO; import com.mhd.wms.domain.stockInOrder.repository.po.StockInOrderPO; import com.mhd.wms.domain.stockInOrder.repository.todo.StockInOrderDO; import com.mhd.wms.domain.stockInOrder.service.StockInOrderDomainService; +import com.mhd.wms.interfaces.dto.stockInOrder.StockInOrderImportRowDTO; import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.web.multipart.MultipartFile; +import java.io.InputStream; +import java.math.BigDecimal; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * 入库单ApplicationService @@ -41,6 +58,8 @@ public class StockInOrderApplicationService { private UserServiceFeign userServiceFeign; @Autowired private SystemServiceFeign systemServiceFeign; + @Autowired + private IMaterialBaseInfoService materialBaseInfoService; /** @@ -54,8 +73,23 @@ public class StockInOrderApplicationService { if (topOrganizationId != null && topOrganizationId != 1){ stockInOrderDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); } - AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); - stockInOrderDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId()); + try { + 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()); + } + } + } catch (Exception e) { + // 如果获取仓库信息失败,记录日志但不影响查询(允许查询所有仓库) + log.warn("获取用户关联仓库信息失败,将查询所有仓库数据,用户ID:{},错误:{}", loginUser.getUserid(), e.getMessage()); + } } return stockInOrderDomainService.queryList(stockInOrderDO); } @@ -65,13 +99,25 @@ public class StockInOrderApplicationService { * 新增入库单 */ public Boolean insert(StockInOrderDO stockInOrderDO) { +// 如果仓库ID为空,从当前登录用户的关联仓库中获取 + if (stockInOrderDO.getWarehouseId() == null) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser == null) { + throw new ServiceException("登录已失效,请重新登录"); + } + AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); + if (associationWarehouseCacheDO == null || associationWarehouseCacheDO.getWarehouseId() == null) { + throw new ServiceException("当前用户未配置关联仓库,请先配置仓库"); + } + stockInOrderDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId()); + } //设置仓库 setWarehouseInfo(stockInOrderDO); - //设置货主信息 +// 设置货主信息 shipperParam(stockInOrderDO); - //设置供应商信息 +// 设置供应商信息 supplierParam(stockInOrderDO); - //设置数据字典键值 +// 设置数据字典键值 setDataDict(stockInOrderDO); return stockInOrderDomainService.insert(stockInOrderDO); } @@ -107,6 +153,7 @@ public class StockInOrderApplicationService { } + /** * @description 审核入库单 * @author ZhouGY @@ -141,6 +188,1354 @@ public class StockInOrderApplicationService { return stockInOrderDomainService.closeOrder(stockInOrderDO); } + /** + * 导入入库单(根据Excel模板:表头在第1-12行,明细表从第13行开始) + * Excel模板结构: + * - 第1-12行:表头信息(包含委托编号NO、客户名称等) + * - 第13行:明细表列名 + * - 第14行开始:明细数据 + */ + public Boolean importData(MultipartFile file) { + if (file == null || file.isEmpty()) { + throw new ServiceException("导入文件不能为空"); + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (loginUser == null) { + throw new ServiceException("登录已失效,请重新登录"); + } + + try (InputStream is = file.getInputStream()) { + // 明细表的列名在第13行(索引12),数据从第14行开始 + int detailTitleRowIndex = 12; // 第13行(索引从0开始) + + // 先读取表头信息(第1-12行),提取所有表头字段 + StockInOrderImportRowDTO headerInfo = new StockInOrderImportRowDTO(); + try (InputStream isForHeader = file.getInputStream()) { + Workbook wb = WorkbookFactory.create(isForHeader); + Sheet sheet = wb.getSheetAt(0); + + // 从表头部分(第1-12行)读取所有字段信息 + for (int rowIdx = 0; rowIdx < 12; rowIdx++) { + Row row = sheet.getRow(rowIdx); + if (row != null) { + for (int colIdx = 0; colIdx < row.getPhysicalNumberOfCells(); colIdx++) { + Cell labelCell = row.getCell(colIdx); + if (labelCell != null) { + String labelValue = getCellValueAsString(labelCell); + if (StringUtils.isNotBlank(labelValue)) { + // 调试日志:打印所有非空单元格内容 + log.info("表头第{}行第{}列: {}", rowIdx + 1, colIdx + 1, labelValue); + String value = null; + + // 先尝试从同一单元格提取值(如果包含冒号) + String extractedFromSameCell = null; + if (labelValue.contains(":")) { + String[] parts = labelValue.split(":", 2); + if (parts.length > 1) { + extractedFromSameCell = parts[1].trim(); + } + } + + // 跳过空单元格,查找下一个非空单元格作为值(最多向后查找10列) + String nextCellValue = null; + for (int searchColIdx = colIdx + 1; searchColIdx < colIdx + 10 && searchColIdx < row.getPhysicalNumberOfCells(); searchColIdx++) { + Cell valueCell = row.getCell(searchColIdx); + if (valueCell != null) { + String cellValue = getCellValueAsString(valueCell); + if (StringUtils.isNotBlank(cellValue)) { + nextCellValue = cellValue; + log.info("表头第{}行,标签'{}'在第{}列,找到值'{}'在第{}列", rowIdx + 1, labelValue, colIdx + 1, nextCellValue, searchColIdx + 1); + break; + } + } + } + + // 优先使用下一个非空单元格的值(如果存在且不为空) + // 如果下一个单元格为空,且同一单元格有冒号后的值,则使用冒号后的值 + // 但如果冒号后的值是选项列表(如"3T、5T、8T、10T"),则应该使用下一个单元格的值 + if (StringUtils.isNotBlank(nextCellValue)) { + // 如果冒号后的值是选项列表(包含顿号、逗号等),优先使用下一个单元格的值 + if (extractedFromSameCell != null && (extractedFromSameCell.contains("、") || extractedFromSameCell.contains(","))) { + value = nextCellValue; + } else { + // 否则优先使用下一个单元格的值 + value = nextCellValue; + } + } else if (StringUtils.isNotBlank(extractedFromSameCell)) { + // 如果下一个单元格为空,使用同一单元格冒号后的值 + value = extractedFromSameCell; + } + + // 根据标签匹配字段 + if (StringUtils.isNotBlank(value)) { + // 委托编号NO(支持"委托编号NO"、"委托编号"等格式) + if (labelValue.contains("委托编号") && StringUtils.isBlank(headerInfo.getConsignmentNo())) { + // 排除标签本身和包含"NO"的标签文本 + if (!value.contains("委托编号") && !value.contains("NO") && !value.equals("委托编号NO") && !value.equals("委托编号")) { + headerInfo.setConsignmentNo(value); + log.info("从表头第{}行读取到委托编号NO: {}", rowIdx + 1, value); + } + } + // 客户名称 + else if (labelValue.contains("客户名称") && StringUtils.isBlank(headerInfo.getShipperName())) { + if (!value.contains("客户") && !value.equals("客户名称")) { + headerInfo.setShipperName(value); + log.info("从表头第{}行读取到客户名称: {}", rowIdx + 1, value); + } + } + // To(需要精确匹配,避免误匹配) + else if ((labelValue.equals("To") || labelValue.equals("To:") || labelValue.equals("To:") || labelValue.startsWith("To:") || labelValue.startsWith("To:")) && StringUtils.isBlank(headerInfo.getTo())) { + // 如果值是"To"或"To:",说明可能是标签本身,继续查找下一个值 + if (value.equals("To") || value.equals("To:") || value.equals("To:")) { + // 继续向后查找,跳过标签(包含冒号的文本) + boolean found = false; + for (int searchColIdx = colIdx + 2; searchColIdx < colIdx + 10 && searchColIdx < row.getPhysicalNumberOfCells(); searchColIdx++) { + Cell nextValueCell = row.getCell(searchColIdx); + if (nextValueCell != null) { + String nextValue = getCellValueAsString(nextValueCell); + // 跳过标签文本(包含冒号、等于"To"等,以及常见的标签关键词) + if (StringUtils.isNotBlank(nextValue) && + !nextValue.equals("To") && !nextValue.equals("To:") && !nextValue.equals("To:") && + !nextValue.contains(":") && !nextValue.contains(":") && + !nextValue.contains("联系人") && !nextValue.contains("Tel") && !nextValue.contains("Fax") && + !nextValue.contains("客户") && !nextValue.contains("地址") && !nextValue.contains("日期") && + !nextValue.contains("方式") && !nextValue.contains("关区") && !nextValue.contains("关别")) { + headerInfo.setTo(nextValue); + log.info("从表头第{}行读取到To: {}", rowIdx + 1, nextValue); + found = true; + break; + } + } + } + // 如果没找到合适的值,尝试查找下一行的同一列 + if (!found) { + Row nextRow = sheet.getRow(rowIdx + 1); + if (nextRow != null) { + Cell nextRowCell = nextRow.getCell(colIdx); + if (nextRowCell != null) { + String nextRowValue = getCellValueAsString(nextRowCell); + if (StringUtils.isNotBlank(nextRowValue) && + !nextRowValue.contains(":") && !nextRowValue.contains(":") && + !nextRowValue.equals("To") && !nextRowValue.equals("To:") && !nextRowValue.equals("To:")) { + headerInfo.setTo(nextRowValue); + log.info("从表头第{}行(下一行)读取到To: {}", rowIdx + 2, nextRowValue); + } + } + } + } + } else if (!value.contains(":") && !value.contains(":") && + !value.contains("联系人") && !value.contains("Tel") && !value.contains("Fax") && + !value.contains("客户") && !value.contains("地址") && !value.contains("日期") && + !value.contains("方式") && !value.contains("关区") && !value.contains("关别")) { + // 值不是标签(不包含冒号和常见标签关键词),可以使用 + headerInfo.setTo(value); + log.info("从表头第{}行读取到To: {}", rowIdx + 1, value); + } + } else if (labelValue.contains("联系人") && StringUtils.isBlank(headerInfo.getContactPerson())) { + headerInfo.setContactPerson(value); + log.info("从表头第{}行读取到联系人: {}", rowIdx + 1, value); + } else if ((labelValue.contains("车型") || labelValue.contains("车牌")) && StringUtils.isBlank(headerInfo.getVehicleInfo())) { + // 过滤掉标签文本(包含冒号、常见标签关键词等) + if (StringUtils.isNotBlank(value) && + !value.contains(":") && !value.contains(":") && + !value.contains("委托编号") && !value.contains("NO") && !value.contains("司机签名") && + !value.contains("完成时间") && !value.contains("下单日期") && !value.contains("入仓日期") && + !value.contains("联系人") && !value.contains("Tel") && !value.contains("Fax") && + !value.contains("客户") && !value.contains("地址") && !value.contains("日期") && + !value.contains("方式") && !value.contains("关区") && !value.contains("关别") && + !value.contains("报关员") && !value.contains("生产商") && !value.contains("承运方") && + !value.contains("柜号") && !value.contains("车型") && !value.contains("车牌")) { + headerInfo.setVehicleInfo(value); + log.info("从表头第{}行读取到车型及车牌: {}", rowIdx + 1, value); + } else { + // 如果找到的值是标签,继续向后查找 + boolean found = false; + boolean stopSearch = false; // 是否遇到下一个标签,需要停止搜索 + for (int searchColIdx = colIdx + 2; searchColIdx < colIdx + 10 && searchColIdx < row.getPhysicalNumberOfCells(); searchColIdx++) { + Cell nextValueCell = row.getCell(searchColIdx); + if (nextValueCell != null) { + String nextValue = getCellValueAsString(nextValueCell); + if (StringUtils.isNotBlank(nextValue)) { + // 检查是否遇到下一个标签(如"委托编号NO"),如果遇到则停止搜索 + if (nextValue.contains("委托编号") || (nextValue.contains("NO") && nextValue.contains(":")) || + nextValue.contains("司机签名") || nextValue.contains("完成时间") || nextValue.contains("下单日期") || + nextValue.contains("入仓日期") || nextValue.contains("联系人") || nextValue.contains("Tel") || + nextValue.contains("Fax") || nextValue.contains("客户名称") || nextValue.contains("送货地址") || + nextValue.contains("申报地关区") || nextValue.contains("进出境关别") || nextValue.contains("起运") || + nextValue.contains("运抵国") || nextValue.contains("柜号") || nextValue.contains("运输方式") || + nextValue.contains("监管方式") || nextValue.contains("海关是否查验货物") || nextValue.contains("报关员")) { + // 遇到下一个标签,停止搜索 + stopSearch = true; + log.warn("表头第{}行,标签'{}'在第{}列,向后搜索到第{}列时遇到下一个标签'{}',停止搜索,车型及车牌字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, searchColIdx + 1, nextValue); + break; + } + // 跳过标签文本(包含冒号、常见标签关键词等) + if (!nextValue.contains(":") && !nextValue.contains(":") && + !nextValue.contains("委托编号") && !nextValue.contains("NO") && !nextValue.contains("司机签名") && + !nextValue.contains("完成时间") && !nextValue.contains("下单日期") && !nextValue.contains("入仓日期") && + !nextValue.contains("联系人") && !nextValue.contains("Tel") && !nextValue.contains("Fax") && + !nextValue.contains("客户") && !nextValue.contains("地址") && !nextValue.contains("日期") && + !nextValue.contains("方式") && !nextValue.contains("关区") && !nextValue.contains("关别") && + !nextValue.contains("报关员") && !nextValue.contains("生产商") && !nextValue.contains("承运方") && + !nextValue.contains("柜号") && !nextValue.contains("车型") && !nextValue.contains("车牌")) { + headerInfo.setVehicleInfo(nextValue); + log.info("从表头第{}行读取到车型及车牌: {}", rowIdx + 1, nextValue); + found = true; + break; + } + } + } + } + // 如果没找到合适的值且未遇到下一个标签,尝试查找下一行的同一列 + if (!found && !stopSearch) { + Row nextRow = sheet.getRow(rowIdx + 1); + if (nextRow != null) { + Cell nextRowCell = nextRow.getCell(colIdx); + if (nextRowCell != null) { + String nextRowValue = getCellValueAsString(nextRowCell); + if (StringUtils.isNotBlank(nextRowValue) && + !nextRowValue.contains(":") && !nextRowValue.contains(":") && + !nextRowValue.contains("委托编号") && !nextRowValue.contains("NO") && !nextRowValue.contains("司机签名") && + !nextRowValue.contains("完成时间") && !nextRowValue.contains("下单日期") && !nextRowValue.contains("入仓日期") && + !nextRowValue.contains("联系人") && !nextRowValue.contains("Tel") && !nextRowValue.contains("Fax") && + !nextRowValue.contains("客户") && !nextRowValue.contains("地址") && !nextRowValue.contains("日期") && + !nextRowValue.contains("方式") && !nextRowValue.contains("关区") && !nextRowValue.contains("关别") && + !nextRowValue.contains("报关员") && !nextRowValue.contains("生产商") && !nextRowValue.contains("承运方") && + !nextRowValue.contains("柜号") && !nextRowValue.contains("车型") && !nextRowValue.contains("车牌")) { + headerInfo.setVehicleInfo(nextRowValue); + log.info("从表头第{}行(下一行)读取到车型及车牌: {}", rowIdx + 2, nextRowValue); + found = true; + } + } + } + } + // 如果最终都没找到实际的值,不设置字段(保持为空) + if (!found && !stopSearch) { + log.warn("表头第{}行,标签'{}'在第{}列,找到的值是标签'{}',继续向后查找未找到实际值,车型及车牌字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, value); + } + } + } else if ((labelValue.contains("承运方") || labelValue.contains("承运商")) && StringUtils.isBlank(headerInfo.getCarrier())) { + headerInfo.setCarrier(value); + log.info("从表头第{}行读取到承运方: {}", rowIdx + 1, value); + } else if (labelValue.contains("Tel") && StringUtils.isBlank(headerInfo.getTel())) { + headerInfo.setTel(value); + log.info("从表头第{}行读取到Tel: {}", rowIdx + 1, value); + } else if (labelValue.contains("司机签名") && StringUtils.isBlank(headerInfo.getDriverSignature())) { + headerInfo.setDriverSignature(value); + log.info("从表头第{}行读取到司机签名: {}", rowIdx + 1, value); + } else if (labelValue.contains("入仓日期") && StringUtils.isBlank(headerInfo.getWarehouseDate())) { + headerInfo.setWarehouseDate(value); + log.info("从表头第{}行读取到入仓日期: {}", rowIdx + 1, value); + } else if (labelValue.contains("Fax") && StringUtils.isBlank(headerInfo.getFax())) { + headerInfo.setFax(value); + log.info("从表头第{}行读取到Fax: {}", rowIdx + 1, value); + } else if (labelValue.contains("申报地关区") && StringUtils.isBlank(headerInfo.getDeclarationArea())) { + headerInfo.setDeclarationArea(value); + log.info("从表头第{}行读取到申报地关区: {}", rowIdx + 1, value); + } else if (labelValue.contains("生产商") && StringUtils.isBlank(headerInfo.getManufacturer())) { + headerInfo.setManufacturer(value); + log.info("从表头第{}行读取到生产商: {}", rowIdx + 1, value); + } else if (labelValue.contains("报关员") && StringUtils.isBlank(headerInfo.getCustomsBrokerInfo())) { + // 过滤掉标签文本(包含冒号、常见标签关键词等) + if (StringUtils.isNotBlank(value) && + !value.contains(":") && !value.contains(":") && + !value.contains("完成时间") && !value.contains("下单日期") && !value.contains("入仓日期") && + !value.contains("联系人") && !value.contains("Tel") && !value.contains("Fax") && + !value.contains("客户") && !value.contains("地址") && !value.contains("日期") && + !value.contains("方式") && !value.contains("关区") && !value.contains("关别") && + !value.contains("报关员") && !value.contains("生产商") && !value.contains("承运方")) { + headerInfo.setCustomsBrokerInfo(value); + log.info("从表头第{}行读取到报关员姓名及联系方式: {}", rowIdx + 1, value); + } else { + // 如果找到的值是标签,继续向后查找 + boolean found = false; + for (int searchColIdx = colIdx + 2; searchColIdx < colIdx + 10 && searchColIdx < row.getPhysicalNumberOfCells(); searchColIdx++) { + Cell nextValueCell = row.getCell(searchColIdx); + if (nextValueCell != null) { + String nextValue = getCellValueAsString(nextValueCell); + // 跳过标签文本(包含冒号、常见标签关键词等) + if (StringUtils.isNotBlank(nextValue) && + !nextValue.contains(":") && !nextValue.contains(":") && + !nextValue.contains("完成时间") && !nextValue.contains("下单日期") && !nextValue.contains("入仓日期") && + !nextValue.contains("联系人") && !nextValue.contains("Tel") && !nextValue.contains("Fax") && + !nextValue.contains("客户") && !nextValue.contains("地址") && !nextValue.contains("日期") && + !nextValue.contains("方式") && !nextValue.contains("关区") && !nextValue.contains("关别") && + !nextValue.contains("报关员") && !nextValue.contains("生产商") && !nextValue.contains("承运方")) { + headerInfo.setCustomsBrokerInfo(nextValue); + log.info("从表头第{}行读取到报关员姓名及联系方式: {}", rowIdx + 1, nextValue); + found = true; + break; + } + } + } + // 如果没找到合适的值,尝试查找下一行的同一列 + if (!found) { + Row nextRow = sheet.getRow(rowIdx + 1); + if (nextRow != null) { + Cell nextRowCell = nextRow.getCell(colIdx); + if (nextRowCell != null) { + String nextRowValue = getCellValueAsString(nextRowCell); + if (StringUtils.isNotBlank(nextRowValue) && + !nextRowValue.contains(":") && !nextRowValue.contains(":") && + !nextRowValue.contains("完成时间") && !nextRowValue.contains("下单日期") && !nextRowValue.contains("入仓日期") && + !nextRowValue.contains("联系人") && !nextRowValue.contains("Tel") && !nextRowValue.contains("Fax") && + !nextRowValue.contains("客户") && !nextRowValue.contains("地址") && !nextRowValue.contains("日期") && + !nextRowValue.contains("方式") && !nextRowValue.contains("关区") && !nextRowValue.contains("关别") && + !nextRowValue.contains("报关员") && !nextRowValue.contains("生产商") && !nextRowValue.contains("承运方")) { + headerInfo.setCustomsBrokerInfo(nextRowValue); + log.info("从表头第{}行(下一行)读取到报关员姓名及联系方式: {}", rowIdx + 2, nextRowValue); + found = true; + } + } + } + // 如果最终都没找到实际的值,不设置字段(保持为空) + if (!found) { + log.warn("表头第{}行,标签'{}'在第{}列,找到的值是标签'{}',继续向后查找未找到实际值,报关员姓名及联系方式字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, value); + } + } + } + } else if (labelValue.contains("送货地址") && StringUtils.isBlank(headerInfo.getDeliveryAddress())) { + headerInfo.setDeliveryAddress(value); + log.info("从表头第{}行读取到送货地址: {}", rowIdx + 1, value); + } else if (labelValue.contains("进出境关别") && StringUtils.isBlank(headerInfo.getEntryExitCustoms())) { + headerInfo.setEntryExitCustoms(value); + log.info("从表头第{}行读取到进出境关别: {}", rowIdx + 1, value); + } else if ((labelValue.contains("起运") || labelValue.contains("运抵国")) && StringUtils.isBlank(headerInfo.getOriginDestinationCountry())) { + headerInfo.setOriginDestinationCountry(value); + log.info("从表头第{}行读取到起运/运抵国(地区): {}", rowIdx + 1, value); + } else if (labelValue.contains("柜号") && StringUtils.isBlank(headerInfo.getContainerNo())) { + // 过滤掉标签文本(包含冒号、常见标签关键词等) + if (StringUtils.isNotBlank(value) && + !value.contains(":") && !value.contains(":") && + !value.contains("司机签名") && !value.contains("委托编号") && !value.contains("NO") && + !value.contains("完成时间") && !value.contains("下单日期") && !value.contains("入仓日期") && + !value.contains("联系人") && !value.contains("Tel") && !value.contains("Fax") && + !value.contains("客户") && !value.contains("地址") && !value.contains("日期") && + !value.contains("方式") && !value.contains("关区") && !value.contains("关别") && + !value.contains("报关员") && !value.contains("生产商") && !value.contains("承运方") && + !value.contains("车型") && !value.contains("车牌")) { + headerInfo.setContainerNo(value); + log.info("从表头第{}行读取到柜号: {}", rowIdx + 1, value); + } else { + // 如果找到的值是标签,继续向后查找 + boolean found = false; + boolean stopSearch = false; // 是否遇到下一个标签,需要停止搜索 + for (int searchColIdx = colIdx + 2; searchColIdx < colIdx + 10 && searchColIdx < row.getPhysicalNumberOfCells(); searchColIdx++) { + Cell nextValueCell = row.getCell(searchColIdx); + if (nextValueCell != null) { + String nextValue = getCellValueAsString(nextValueCell); + if (StringUtils.isNotBlank(nextValue)) { + // 检查是否遇到下一个标签(如"委托编号NO"、"司机签名"等),如果遇到则停止搜索 + if (nextValue.contains("委托编号") || (nextValue.contains("NO") && nextValue.contains(":")) || + nextValue.contains("司机签名") || nextValue.contains("完成时间") || nextValue.contains("下单日期") || + nextValue.contains("入仓日期") || nextValue.contains("联系人") || nextValue.contains("Tel") || + nextValue.contains("Fax") || nextValue.contains("客户名称") || nextValue.contains("送货地址") || + nextValue.contains("申报地关区") || nextValue.contains("进出境关别") || nextValue.contains("起运") || + nextValue.contains("运抵国") || nextValue.contains("运输方式") || nextValue.contains("监管方式") || + nextValue.contains("海关是否查验货物") || nextValue.contains("报关员")) { + // 遇到下一个标签,停止搜索 + stopSearch = true; + log.warn("表头第{}行,标签'{}'在第{}列,向后搜索到第{}列时遇到下一个标签'{}',停止搜索,柜号字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, searchColIdx + 1, nextValue); + break; + } + // 跳过标签文本(包含冒号、常见标签关键词等) + if (!nextValue.contains(":") && !nextValue.contains(":") && + !nextValue.contains("司机签名") && !nextValue.contains("委托编号") && !nextValue.contains("NO") && + !nextValue.contains("完成时间") && !nextValue.contains("下单日期") && !nextValue.contains("入仓日期") && + !nextValue.contains("联系人") && !nextValue.contains("Tel") && !nextValue.contains("Fax") && + !nextValue.contains("客户") && !nextValue.contains("地址") && !nextValue.contains("日期") && + !nextValue.contains("方式") && !nextValue.contains("关区") && !nextValue.contains("关别") && + !nextValue.contains("报关员") && !nextValue.contains("生产商") && !nextValue.contains("承运方") && + !nextValue.contains("车型") && !nextValue.contains("车牌")) { + headerInfo.setContainerNo(nextValue); + log.info("从表头第{}行读取到柜号: {}", rowIdx + 1, nextValue); + found = true; + break; + } + } + } + } + // 如果没找到合适的值且未遇到下一个标签,尝试查找下一行的同一列 + if (!found && !stopSearch) { + Row nextRow = sheet.getRow(rowIdx + 1); + if (nextRow != null) { + Cell nextRowCell = nextRow.getCell(colIdx); + if (nextRowCell != null) { + String nextRowValue = getCellValueAsString(nextRowCell); + if (StringUtils.isNotBlank(nextRowValue) && + !nextRowValue.contains(":") && !nextRowValue.contains(":") && + !nextRowValue.contains("司机签名") && !nextRowValue.contains("委托编号") && !nextRowValue.contains("NO") && + !nextRowValue.contains("完成时间") && !nextRowValue.contains("下单日期") && !nextRowValue.contains("入仓日期") && + !nextRowValue.contains("联系人") && !nextRowValue.contains("Tel") && !nextRowValue.contains("Fax") && + !nextRowValue.contains("客户") && !nextRowValue.contains("地址") && !nextRowValue.contains("日期") && + !nextRowValue.contains("方式") && !nextRowValue.contains("关区") && !nextRowValue.contains("关别") && + !nextRowValue.contains("报关员") && !nextRowValue.contains("生产商") && !nextRowValue.contains("承运方") && + !nextRowValue.contains("车型") && !nextRowValue.contains("车牌")) { + headerInfo.setContainerNo(nextRowValue); + log.info("从表头第{}行(下一行)读取到柜号: {}", rowIdx + 2, nextRowValue); + found = true; + } + } + } + } + // 如果最终都没找到实际的值,不设置字段(保持为空) + if (!found && !stopSearch) { + log.warn("表头第{}行,标签'{}'在第{}列,找到的值是标签'{}',继续向后查找未找到实际值,柜号字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, value); + } + } + } else if (labelValue.contains("运输方式") && StringUtils.isBlank(headerInfo.getTransportMethod())) { + headerInfo.setTransportMethod(value); + log.info("从表头第{}行读取到运输方式: {}", rowIdx + 1, value); + } else if (labelValue.contains("监管方式") && StringUtils.isBlank(headerInfo.getSupervisionMethod())) { + headerInfo.setSupervisionMethod(value); + log.info("从表头第{}行读取到监管方式: {}", rowIdx + 1, value); + } else if (labelValue.contains("海关是否查验货物")) { + // 过滤掉标签文本(包含冒号、常见标签关键词等) + if (StringUtils.isNotBlank(value) && + !value.contains(":") && !value.contains(":") && + !value.contains("进出境关别") && !value.contains("委托编号") && !value.contains("NO") && + !value.contains("司机签名") && !value.contains("完成时间") && !value.contains("下单日期") && + !value.contains("入仓日期") && !value.contains("联系人") && !value.contains("Tel") && + !value.contains("Fax") && !value.contains("客户") && !value.contains("地址") && + !value.contains("日期") && !value.contains("方式") && !value.contains("关区") && + !value.contains("报关员") && !value.contains("生产商") && !value.contains("承运方") && + !value.contains("车型") && !value.contains("车牌") && !value.contains("柜号")) { + if (value.contains("是") || value.equals("1")) { + headerInfo.setCustomsInspection(1); + } else if (value.contains("否") || value.equals("0")) { + headerInfo.setCustomsInspection(0); + } + log.info("从表头第{}行读取到海关是否查验货物: {}", rowIdx + 1, value); + } else { + // 如果找到的值是标签,继续向后查找 + boolean found = false; + boolean stopSearch = false; // 是否遇到下一个标签,需要停止搜索 + for (int searchColIdx = colIdx + 2; searchColIdx < colIdx + 10 && searchColIdx < row.getPhysicalNumberOfCells(); searchColIdx++) { + Cell nextValueCell = row.getCell(searchColIdx); + if (nextValueCell != null) { + String nextValue = getCellValueAsString(nextValueCell); + if (StringUtils.isNotBlank(nextValue)) { + // 检查是否遇到下一个标签(如"委托编号NO"、"进出境关别"等),如果遇到则停止搜索 + if (nextValue.contains("委托编号") || (nextValue.contains("NO") && nextValue.contains(":")) || + nextValue.contains("司机签名") || nextValue.contains("完成时间") || nextValue.contains("下单日期") || + nextValue.contains("入仓日期") || nextValue.contains("联系人") || nextValue.contains("Tel") || + nextValue.contains("Fax") || nextValue.contains("客户名称") || nextValue.contains("送货地址") || + nextValue.contains("申报地关区") || nextValue.contains("进出境关别") || nextValue.contains("起运") || + nextValue.contains("运抵国") || nextValue.contains("柜号") || nextValue.contains("运输方式") || + nextValue.contains("监管方式") || nextValue.contains("报关员")) { + // 遇到下一个标签,停止搜索 + stopSearch = true; + log.warn("表头第{}行,标签'{}'在第{}列,向后搜索到第{}列时遇到下一个标签'{}',停止搜索,海关是否查验货物字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, searchColIdx + 1, nextValue); + break; + } + // 跳过标签文本(包含冒号、常见标签关键词等) + if (!nextValue.contains(":") && !nextValue.contains(":") && + !nextValue.contains("进出境关别") && !nextValue.contains("委托编号") && !nextValue.contains("NO") && + !nextValue.contains("司机签名") && !nextValue.contains("完成时间") && !nextValue.contains("下单日期") && + !nextValue.contains("入仓日期") && !nextValue.contains("联系人") && !nextValue.contains("Tel") && + !nextValue.contains("Fax") && !nextValue.contains("客户") && !nextValue.contains("地址") && + !nextValue.contains("日期") && !nextValue.contains("方式") && !nextValue.contains("关区") && + !nextValue.contains("报关员") && !nextValue.contains("生产商") && !nextValue.contains("承运方") && + !nextValue.contains("车型") && !nextValue.contains("车牌") && !nextValue.contains("柜号")) { + if (nextValue.contains("是") || nextValue.equals("1")) { + headerInfo.setCustomsInspection(1); + } else if (nextValue.contains("否") || nextValue.equals("0")) { + headerInfo.setCustomsInspection(0); + } + log.info("从表头第{}行读取到海关是否查验货物: {}", rowIdx + 1, nextValue); + found = true; + break; + } + } + } + } + // 如果没找到合适的值且未遇到下一个标签,尝试查找下一行的同一列 + if (!found && !stopSearch) { + Row nextRow = sheet.getRow(rowIdx + 1); + if (nextRow != null) { + Cell nextRowCell = nextRow.getCell(colIdx); + if (nextRowCell != null) { + String nextRowValue = getCellValueAsString(nextRowCell); + if (StringUtils.isNotBlank(nextRowValue) && + !nextRowValue.contains(":") && !nextRowValue.contains(":") && + !nextRowValue.contains("进出境关别") && !nextRowValue.contains("委托编号") && !nextRowValue.contains("NO") && + !nextRowValue.contains("司机签名") && !nextRowValue.contains("完成时间") && !nextRowValue.contains("下单日期") && + !nextRowValue.contains("入仓日期") && !nextRowValue.contains("联系人") && !nextRowValue.contains("Tel") && + !nextRowValue.contains("Fax") && !nextRowValue.contains("客户") && !nextRowValue.contains("地址") && + !nextRowValue.contains("日期") && !nextRowValue.contains("方式") && !nextRowValue.contains("关区") && + !nextRowValue.contains("报关员") && !nextRowValue.contains("生产商") && !nextRowValue.contains("承运方") && + !nextRowValue.contains("车型") && !nextRowValue.contains("车牌") && !nextRowValue.contains("柜号")) { + if (nextRowValue.contains("是") || nextRowValue.equals("1")) { + headerInfo.setCustomsInspection(1); + } else if (nextRowValue.contains("否") || nextRowValue.equals("0")) { + headerInfo.setCustomsInspection(0); + } + log.info("从表头第{}行(下一行)读取到海关是否查验货物: {}", rowIdx + 2, nextRowValue); + found = true; + } + } + } + } + // 如果最终都没找到实际的值,不设置字段(保持为空) + if (!found && !stopSearch) { + log.warn("表头第{}行,标签'{}'在第{}列,找到的值是标签'{}',继续向后查找未找到实际值,海关是否查验货物字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, value); + } + } + } else if (labelValue.contains("是否需要报关")) { + if (value.contains("是") || value.equals("1")) { + headerInfo.setNeedCustomsDeclaration(1); + } else if (value.contains("否") || value.equals("0")) { + headerInfo.setNeedCustomsDeclaration(0); + } + log.info("从表头第{}行读取到是否需要报关: {}", rowIdx + 1, value); + } else if (labelValue.contains("是否需要运输")) { + if (value.contains("是") || value.equals("1")) { + headerInfo.setNeedTransport(1); + } else if (value.contains("否") || value.equals("0")) { + headerInfo.setNeedTransport(0); + } + log.info("从表头第{}行读取到是否需要运输: {}", rowIdx + 1, value); + } else if (labelValue.contains("完成时间") && StringUtils.isBlank(headerInfo.getCompletionTime())) { + // 过滤掉标签文本(包含冒号、常见标签关键词等) + if (StringUtils.isNotBlank(value) && + !value.contains(":") && !value.contains(":") && + !value.contains("下单日期") && !value.contains("入仓日期") && + !value.contains("起运") && !value.contains("运抵国") && !value.contains("地区") && + !value.contains("联系人") && !value.contains("Tel") && !value.contains("Fax") && + !value.contains("客户") && !value.contains("地址") && !value.contains("日期") && + !value.contains("方式") && !value.contains("关区") && !value.contains("关别") && + !value.contains("报关员") && !value.contains("生产商") && !value.contains("承运方")) { + headerInfo.setCompletionTime(value); + log.info("从表头第{}行读取到完成时间: {}", rowIdx + 1, value); + } else { + // 如果找到的值是标签,继续向后查找 + boolean found = false; + boolean stopSearch = false; // 是否遇到下一个标签,需要停止搜索 + for (int searchColIdx = colIdx + 2; searchColIdx < colIdx + 10 && searchColIdx < row.getPhysicalNumberOfCells(); searchColIdx++) { + Cell nextValueCell = row.getCell(searchColIdx); + if (nextValueCell != null) { + String nextValue = getCellValueAsString(nextValueCell); + if (StringUtils.isNotBlank(nextValue)) { + // 检查是否遇到下一个标签(如"委托编号NO"、"下单日期"等),如果遇到则停止搜索 + if (nextValue.contains("委托编号") || (nextValue.contains("NO") && nextValue.contains(":")) || + nextValue.contains("司机签名") || nextValue.contains("下单日期") || + nextValue.contains("入仓日期") || nextValue.contains("联系人") || nextValue.contains("Tel") || + nextValue.contains("Fax") || nextValue.contains("客户名称") || nextValue.contains("送货地址") || + nextValue.contains("申报地关区") || nextValue.contains("进出境关别") || nextValue.contains("起运") || + nextValue.contains("运抵国") || nextValue.contains("柜号") || nextValue.contains("运输方式") || + nextValue.contains("监管方式") || nextValue.contains("海关是否查验货物") || nextValue.contains("报关员")) { + // 遇到下一个标签,停止搜索 + stopSearch = true; + log.warn("表头第{}行,标签'{}'在第{}列,向后搜索到第{}列时遇到下一个标签'{}',停止搜索,完成时间字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, searchColIdx + 1, nextValue); + break; + } + // 跳过标签文本(包含冒号、常见标签关键词等) + if (!nextValue.contains(":") && !nextValue.contains(":") && + !nextValue.contains("下单日期") && !nextValue.contains("入仓日期") && + !nextValue.contains("起运") && !nextValue.contains("运抵国") && !nextValue.contains("地区") && + !nextValue.contains("联系人") && !nextValue.contains("Tel") && !nextValue.contains("Fax") && + !nextValue.contains("客户") && !nextValue.contains("地址") && !nextValue.contains("日期") && + !nextValue.contains("方式") && !nextValue.contains("关区") && !nextValue.contains("关别") && + !nextValue.contains("报关员") && !nextValue.contains("生产商") && !nextValue.contains("承运方")) { + headerInfo.setCompletionTime(nextValue); + log.info("从表头第{}行读取到完成时间: {}", rowIdx + 1, nextValue); + found = true; + break; + } + } + } + } + // 如果没找到合适的值且未遇到下一个标签,尝试查找下一行的同一列 + if (!found && !stopSearch) { + Row nextRow = sheet.getRow(rowIdx + 1); + if (nextRow != null) { + Cell nextRowCell = nextRow.getCell(colIdx); + if (nextRowCell != null) { + String nextRowValue = getCellValueAsString(nextRowCell); + if (StringUtils.isNotBlank(nextRowValue) && + !nextRowValue.contains(":") && !nextRowValue.contains(":") && + !nextRowValue.contains("下单日期") && !nextRowValue.contains("入仓日期") && + !nextRowValue.contains("起运") && !nextRowValue.contains("运抵国") && !nextRowValue.contains("地区") && + !nextRowValue.contains("联系人") && !nextRowValue.contains("Tel") && !nextRowValue.contains("Fax") && + !nextRowValue.contains("客户") && !nextRowValue.contains("地址") && !nextRowValue.contains("日期") && + !nextRowValue.contains("方式") && !nextRowValue.contains("关区") && !nextRowValue.contains("关别") && + !nextRowValue.contains("报关员") && !nextRowValue.contains("生产商") && !nextRowValue.contains("承运方")) { + headerInfo.setCompletionTime(nextRowValue); + log.info("从表头第{}行(下一行)读取到完成时间: {}", rowIdx + 2, nextRowValue); + found = true; + } + } + } + } + // 如果最终都没找到实际的值,不设置字段(保持为空) + if (!found && !stopSearch) { + log.warn("表头第{}行,标签'{}'在第{}列,找到的值是标签'{}',继续向后查找未找到实际值,完成时间字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, value); + } + } + } else if (labelValue.contains("下单日期") && StringUtils.isBlank(headerInfo.getOrderDate())) { + // 过滤掉标签文本(包含冒号、常见标签关键词等) + if (StringUtils.isNotBlank(value) && + !value.contains(":") && !value.contains(":") && + !value.contains("起运") && !value.contains("运抵国") && !value.contains("地区") && + !value.contains("完成时间") && !value.contains("入仓日期") && + !value.contains("联系人") && !value.contains("Tel") && !value.contains("Fax") && + !value.contains("客户") && !value.contains("地址") && !value.contains("日期") && + !value.contains("方式") && !value.contains("关区") && !value.contains("关别") && + !value.contains("报关员") && !value.contains("生产商") && !value.contains("承运方")) { + headerInfo.setOrderDate(value); + log.info("从表头第{}行读取到下单日期: {}", rowIdx + 1, value); + } else { + // 如果找到的值是标签,继续向后查找 + boolean found = false; + boolean stopSearch = false; // 是否遇到下一个标签,需要停止搜索 + for (int searchColIdx = colIdx + 2; searchColIdx < colIdx + 10 && searchColIdx < row.getPhysicalNumberOfCells(); searchColIdx++) { + Cell nextValueCell = row.getCell(searchColIdx); + if (nextValueCell != null) { + String nextValue = getCellValueAsString(nextValueCell); + if (StringUtils.isNotBlank(nextValue)) { + // 检查是否遇到下一个标签(如"委托编号NO"、"起运/运抵国"等),如果遇到则停止搜索 + if (nextValue.contains("委托编号") || (nextValue.contains("NO") && nextValue.contains(":")) || + nextValue.contains("司机签名") || nextValue.contains("完成时间") || + nextValue.contains("入仓日期") || nextValue.contains("联系人") || nextValue.contains("Tel") || + nextValue.contains("Fax") || nextValue.contains("客户名称") || nextValue.contains("送货地址") || + nextValue.contains("申报地关区") || nextValue.contains("进出境关别") || nextValue.contains("起运") || + nextValue.contains("运抵国") || nextValue.contains("柜号") || nextValue.contains("运输方式") || + nextValue.contains("监管方式") || nextValue.contains("海关是否查验货物") || nextValue.contains("报关员")) { + // 遇到下一个标签,停止搜索 + stopSearch = true; + log.warn("表头第{}行,标签'{}'在第{}列,向后搜索到第{}列时遇到下一个标签'{}',停止搜索,下单日期字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, searchColIdx + 1, nextValue); + break; + } + // 跳过标签文本(包含冒号、常见标签关键词等) + if (!nextValue.contains(":") && !nextValue.contains(":") && + !nextValue.contains("起运") && !nextValue.contains("运抵国") && !nextValue.contains("地区") && + !nextValue.contains("完成时间") && !nextValue.contains("入仓日期") && + !nextValue.contains("联系人") && !nextValue.contains("Tel") && !nextValue.contains("Fax") && + !nextValue.contains("客户") && !nextValue.contains("地址") && !nextValue.contains("日期") && + !nextValue.contains("方式") && !nextValue.contains("关区") && !nextValue.contains("关别") && + !nextValue.contains("报关员") && !nextValue.contains("生产商") && !nextValue.contains("承运方")) { + headerInfo.setOrderDate(nextValue); + log.info("从表头第{}行读取到下单日期: {}", rowIdx + 1, nextValue); + found = true; + break; + } + } + } + } + // 如果没找到合适的值且未遇到下一个标签,尝试查找下一行的同一列 + if (!found && !stopSearch) { + Row nextRow = sheet.getRow(rowIdx + 1); + if (nextRow != null) { + Cell nextRowCell = nextRow.getCell(colIdx); + if (nextRowCell != null) { + String nextRowValue = getCellValueAsString(nextRowCell); + if (StringUtils.isNotBlank(nextRowValue) && + !nextRowValue.contains(":") && !nextRowValue.contains(":") && + !nextRowValue.contains("起运") && !nextRowValue.contains("运抵国") && !nextRowValue.contains("地区") && + !nextRowValue.contains("完成时间") && !nextRowValue.contains("入仓日期") && + !nextRowValue.contains("联系人") && !nextRowValue.contains("Tel") && !nextRowValue.contains("Fax") && + !nextRowValue.contains("客户") && !nextRowValue.contains("地址") && !nextRowValue.contains("日期") && + !nextRowValue.contains("方式") && !nextRowValue.contains("关区") && !nextRowValue.contains("关别") && + !nextRowValue.contains("报关员") && !nextRowValue.contains("生产商") && !nextRowValue.contains("承运方")) { + headerInfo.setOrderDate(nextRowValue); + log.info("从表头第{}行(下一行)读取到下单日期: {}", rowIdx + 2, nextRowValue); + found = true; + } + } + } + } + // 如果最终都没找到实际的值,不设置字段(保持为空) + if (!found && !stopSearch) { + log.warn("表头第{}行,标签'{}'在第{}列,找到的值是标签'{}',继续向后查找未找到实际值,下单日期字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, value); + } + } + } else if (labelValue.contains("备注") && StringUtils.isBlank(headerInfo.getRemark())) { + headerInfo.setRemark(value); + log.info("从表头第{}行读取到备注: {}", rowIdx + 1, value); + } + } + } + } + } + } + } + log.info("表头信息读取完成 - 委托编号NO: {}, 客户名称: {}, To: {}, 联系人: {}, Tel: {}, Fax: {}, 送货地址: {}, 起运/运抵国: {}, 车型及车牌: {}, 承运方: {}, 司机签名: {}, 入仓日期: {}, 申报地关区: {}, 生产商: {}, 报关员: {}, 完成时间: {}, 进出境关别: {}, 下单日期: {}, 备注: {}", + headerInfo.getConsignmentNo(), headerInfo.getShipperName(), headerInfo.getTo(), + headerInfo.getContactPerson(), headerInfo.getTel(), headerInfo.getFax(), + headerInfo.getDeliveryAddress(), headerInfo.getOriginDestinationCountry(), + headerInfo.getVehicleInfo(), headerInfo.getCarrier(), headerInfo.getDriverSignature(), + headerInfo.getWarehouseDate(), headerInfo.getDeclarationArea(), headerInfo.getManufacturer(), + headerInfo.getCustomsBrokerInfo(), headerInfo.getCompletionTime(), headerInfo.getEntryExitCustoms(), + headerInfo.getOrderDate(), headerInfo.getRemark()); + } catch (Exception e) { + log.error("读取Excel表头信息失败", e); + // 不抛出异常,继续尝试从明细行读取 + } + + // 为了兼容旧代码,保留这两个变量 + String headerConsignmentNo = headerInfo.getConsignmentNo(); + String headerCustomerName = headerInfo.getShipperName(); + + // 先读取Excel第13行的列名,用于调试 + try (InputStream isForDebug = file.getInputStream()) { + Workbook wbDebug = WorkbookFactory.create(isForDebug); + Sheet sheetDebug = wbDebug.getSheetAt(0); + Row headerRow = sheetDebug.getRow(detailTitleRowIndex); + if (headerRow != null) { + log.info("Excel第{}行(明细表列名行)的列名:", detailTitleRowIndex + 1); + for (int colIdx = 0; colIdx < headerRow.getPhysicalNumberOfCells(); colIdx++) { + Cell cell = headerRow.getCell(colIdx); + if (cell != null) { + String colName = getCellValueAsString(cell); + if (StringUtils.isNotBlank(colName)) { + // 打印列名及其长度、字符编码等信息,便于排查 + log.info(" 第{}列: [{}] (长度: {}, 包含换行: {}, 包含空格: {})", + colIdx + 1, colName, colName.length(), + colName.contains("\n"), colName.contains(" ")); + } + } + } + } + } catch (Exception e) { + log.warn("读取Excel列名失败,继续导入", e); + } + + ExcelUtil util = new ExcelUtil<>(StockInOrderImportRowDTO.class); + // 从第13行(索引12)读取明细数据 + List rows = null; + try { + rows = util.importExcel(is, detailTitleRowIndex); + log.info("成功读取 {} 行明细数据", rows != null ? rows.size() : 0); + // 调试:打印第一行数据的关键字段 + if (rows != null && !rows.isEmpty()) { + StockInOrderImportRowDTO firstRow = rows.get(0); + log.info("第一行明细数据 - 规格型号: [{}], SKU码: [{}], 升: [{}], 箱数: [{}], 尺寸: [{}], 仓库数量: [{}], 入库数量: [{}], 单位: [{}], 总净重: [{}], 总净重2: [{}], 总毛重: [{}], 总毛重2: [{}], 总体积: [{}], 总体积2: [{}], 总面积: [{}], 总面积2: [{}], 原产国: [{}], 币制: [{}]", + firstRow.getSpecificationModel(), firstRow.getSkuCode(), firstRow.getLiter(), + firstRow.getBoxCount(), firstRow.getDimensions(), firstRow.getWarehouseQuantity(), + firstRow.getInboundQuantity(), firstRow.getUnit(), + firstRow.getTotalNetWeight(), firstRow.getTotalNetWeight2(), + firstRow.getTotalGrossWeight(), firstRow.getTotalGrossWeight2(), + firstRow.getTotalVolume(), firstRow.getTotalVolume2(), + firstRow.getTotalArea(), firstRow.getTotalArea2(), + firstRow.getOriginCountry(), firstRow.getCurrency()); + } + } catch (Exception e) { + log.error("读取Excel明细数据失败", e); + throw new ServiceException("读取Excel明细数据失败:" + e.getMessage() + "。请检查Excel第13行是否为明细表列名,第14行开始是否为数据行"); + } + if (rows == null || rows.isEmpty()) { + throw new ServiceException("导入数据为空。请检查Excel第13行是否为明细表列名(包含'商品名称'列),第14行开始是否为数据行"); + } + log.info("成功读取 {} 行明细数据", rows.size()); + + // 将表头信息应用到每一行明细数据 + for (StockInOrderImportRowDTO row : rows) { + if (row != null) { + // 应用表头中的委托编号NO + if (StringUtils.isBlank(row.getConsignmentNo()) && StringUtils.isNotBlank(headerInfo.getConsignmentNo())) { + row.setConsignmentNo(headerInfo.getConsignmentNo()); + } + // 应用表头中的客户名称(表头有客户名称时,强制应用到所有明细行) + if (StringUtils.isNotBlank(headerInfo.getShipperName())) { + row.setShipperName(headerInfo.getShipperName()); + } + // 应用表头中的货主编号(表头有货主编号时,强制应用到所有明细行) + if (StringUtils.isNotBlank(headerInfo.getShipperCode())) { + row.setShipperCode(headerInfo.getShipperCode()); + } + // 应用其他表头字段(如果明细行为空,则使用表头值) + if (StringUtils.isBlank(row.getTo()) && StringUtils.isNotBlank(headerInfo.getTo())) { + row.setTo(headerInfo.getTo()); + } + if (StringUtils.isBlank(row.getContactPerson()) && StringUtils.isNotBlank(headerInfo.getContactPerson())) { + row.setContactPerson(headerInfo.getContactPerson()); + } + if (StringUtils.isBlank(row.getVehicleInfo()) && StringUtils.isNotBlank(headerInfo.getVehicleInfo())) { + row.setVehicleInfo(headerInfo.getVehicleInfo()); + } + if (StringUtils.isBlank(row.getCarrier()) && StringUtils.isNotBlank(headerInfo.getCarrier())) { + row.setCarrier(headerInfo.getCarrier()); + } + if (StringUtils.isBlank(row.getTel()) && StringUtils.isNotBlank(headerInfo.getTel())) { + row.setTel(headerInfo.getTel()); + } + if (StringUtils.isBlank(row.getDriverSignature()) && StringUtils.isNotBlank(headerInfo.getDriverSignature())) { + row.setDriverSignature(headerInfo.getDriverSignature()); + } + if (StringUtils.isBlank(row.getFax()) && StringUtils.isNotBlank(headerInfo.getFax())) { + row.setFax(headerInfo.getFax()); + } + if (StringUtils.isBlank(row.getDeclarationArea()) && StringUtils.isNotBlank(headerInfo.getDeclarationArea())) { + row.setDeclarationArea(headerInfo.getDeclarationArea()); + } + if (StringUtils.isBlank(row.getManufacturer()) && StringUtils.isNotBlank(headerInfo.getManufacturer())) { + row.setManufacturer(headerInfo.getManufacturer()); + } + if (StringUtils.isBlank(row.getCustomsBrokerInfo()) && StringUtils.isNotBlank(headerInfo.getCustomsBrokerInfo())) { + row.setCustomsBrokerInfo(headerInfo.getCustomsBrokerInfo()); + } + if (StringUtils.isBlank(row.getDeliveryAddress()) && StringUtils.isNotBlank(headerInfo.getDeliveryAddress())) { + row.setDeliveryAddress(headerInfo.getDeliveryAddress()); + } + if (StringUtils.isBlank(row.getEntryExitCustoms()) && StringUtils.isNotBlank(headerInfo.getEntryExitCustoms())) { + row.setEntryExitCustoms(headerInfo.getEntryExitCustoms()); + } + if (StringUtils.isBlank(row.getOriginDestinationCountry()) && StringUtils.isNotBlank(headerInfo.getOriginDestinationCountry())) { + row.setOriginDestinationCountry(headerInfo.getOriginDestinationCountry()); + } + if (StringUtils.isBlank(row.getContainerNo()) && StringUtils.isNotBlank(headerInfo.getContainerNo())) { + row.setContainerNo(headerInfo.getContainerNo()); + } + if (StringUtils.isBlank(row.getTransportMethod()) && StringUtils.isNotBlank(headerInfo.getTransportMethod())) { + row.setTransportMethod(headerInfo.getTransportMethod()); + } + if (StringUtils.isBlank(row.getSupervisionMethod()) && StringUtils.isNotBlank(headerInfo.getSupervisionMethod())) { + row.setSupervisionMethod(headerInfo.getSupervisionMethod()); + } + if (row.getCustomsInspection() == null && headerInfo.getCustomsInspection() != null) { + row.setCustomsInspection(headerInfo.getCustomsInspection()); + } + if (row.getNeedCustomsDeclaration() == null && headerInfo.getNeedCustomsDeclaration() != null) { + row.setNeedCustomsDeclaration(headerInfo.getNeedCustomsDeclaration()); + } + if (row.getNeedTransport() == null && headerInfo.getNeedTransport() != null) { + row.setNeedTransport(headerInfo.getNeedTransport()); + } + if (StringUtils.isBlank(row.getWarehouseDate()) && StringUtils.isNotBlank(headerInfo.getWarehouseDate())) { + row.setWarehouseDate(headerInfo.getWarehouseDate()); + } + if (StringUtils.isBlank(row.getCompletionTime()) && StringUtils.isNotBlank(headerInfo.getCompletionTime())) { + row.setCompletionTime(headerInfo.getCompletionTime()); + } + if (StringUtils.isBlank(row.getOrderDate()) && StringUtils.isNotBlank(headerInfo.getOrderDate())) { + row.setOrderDate(headerInfo.getOrderDate()); + } + if (StringUtils.isBlank(row.getRemark()) && StringUtils.isNotBlank(headerInfo.getRemark())) { + row.setRemark(headerInfo.getRemark()); + } + } + } + + // 过滤掉关键字段都为空的空行(只需要商品名称不为空即可) + List validRows = rows.stream() + .filter(r -> r != null && StringUtils.isNotBlank(r.getMaterialName())) + .collect(Collectors.toList()); + if (validRows.isEmpty()) { + String errorMsg = String.format("导入数据为空(可能全为空行)。共读取 %d 行数据,但商品名称都为空。\n" + + "请检查Excel第13行是否为明细表列名(包含'商品名称'列),第14行开始是否为数据行。", rows.size()); + throw new ServiceException(errorMsg); + } + + // 以委托编号NO分组;若为空则归到同一组 + Map> groupMap = validRows.stream() + .collect(Collectors.groupingBy(r -> StringUtils.isBlank(r.getConsignmentNo()) ? "__EMPTY_CONSIGNMENT__" : r.getConsignmentNo())); + + List orderList = new ArrayList<>(); + for (Map.Entry> entry : groupMap.entrySet()) { + List 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("导入失败:未配置用户关联仓库,请先配置仓库"); + } + warehouseId = associationWarehouseCacheDO.getWarehouseId(); + + // 客户名称应该从表头获取(优先使用表头,如果表头为空则使用明细行) + String customerName = StringUtils.isNotBlank(headerInfo.getShipperName()) ? headerInfo.getShipperName() : h.getShipperName(); + if (StringUtils.isBlank(customerName)) { + throw new ServiceException("导入失败:客户名称不能为空(委托编号NO=" + h.getConsignmentNo() + ")。请确保Excel表头(第1-12行)中包含'客户名称'字段"); + } + // 如果明细行的客户名称为空,使用表头的客户名称 + if (StringUtils.isBlank(h.getShipperName()) && StringUtils.isNotBlank(headerInfo.getShipperName())) { + h.setShipperName(headerInfo.getShipperName()); + } + + StockInOrderDO order = new StockInOrderDO(); + // 组织/审计字段 + order.setOrganizationId(loginUser.getUserPo().getOrganizationId()); + order.setOrganizationName(loginUser.getUserPo().getOrganizationName()); + order.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); + order.setCreateBy(loginUser.getUserid()); + order.setCreateByName(loginUser.getUsername()); + // 设置创建时间为当前时间 + order.setCreateTime(new Date()); + + // 必填/基础字段 + order.setWarehouseId(warehouseId); + // 设置仓库完整信息(warehouseCode 和 warehouseName) + setWarehouseInfo(order); + // 货主信息:优先使用表头,如果表头为空则使用明细行 + String shipperName = StringUtils.isNotBlank(headerInfo.getShipperName()) ? headerInfo.getShipperName() : h.getShipperName(); + String shipperCode = StringUtils.isNotBlank(headerInfo.getShipperCode()) ? headerInfo.getShipperCode() : h.getShipperCode(); + // 提前获取货主ID,用于查询物料基础信息时过滤 + Long shipperId = getShipperIdByNameOrCode(shipperName, shipperCode); + // 货主ID先设置为获取到的值,后续在shipperParam方法中会再次确认 + order.setShipperId(shipperId); + if (StringUtils.isNotBlank(shipperName)) { + order.setShipperName(shipperName); + } + if (StringUtils.isNotBlank(shipperCode)) { + order.setShipperCode(shipperCode); + } +// order.setSupplierId(h.getSupplierId()); +// order.setOrderTypeCode(h.getOrderTypeCode()); + order.setConsignmentNo(h.getConsignmentNo()); + order.setRemark(h.getRemark()); + // 导入入库单时,如果入库单类型为空,默认设置为普通入库 + if (StringUtils.isBlank(order.getOrderTypeCode())) { + order.setOrderTypeCode("pu_tong_ru_ku"); + } + if (StringUtils.isBlank(order.getOrderTypeName())) { + order.setOrderTypeName("普通入库单"); + } + + // 报关表头字段(优先使用表头字段,如果表头为空则使用明细行字段) + order.setTo(StringUtils.isNotBlank(headerInfo.getTo()) ? headerInfo.getTo() : h.getTo()); + order.setContactPerson(StringUtils.isNotBlank(headerInfo.getContactPerson()) ? headerInfo.getContactPerson() : h.getContactPerson()); + order.setVehicleInfo(StringUtils.isNotBlank(headerInfo.getVehicleInfo()) ? headerInfo.getVehicleInfo() : h.getVehicleInfo()); + order.setTel(StringUtils.isNotBlank(headerInfo.getTel()) ? headerInfo.getTel() : h.getTel()); + order.setDriverSignature(StringUtils.isNotBlank(headerInfo.getDriverSignature()) ? headerInfo.getDriverSignature() : h.getDriverSignature()); + order.setFax(StringUtils.isNotBlank(headerInfo.getFax()) ? headerInfo.getFax() : h.getFax()); + order.setDeclarationArea(StringUtils.isNotBlank(headerInfo.getDeclarationArea()) ? headerInfo.getDeclarationArea() : h.getDeclarationArea()); + order.setManufacturer(StringUtils.isNotBlank(headerInfo.getManufacturer()) ? headerInfo.getManufacturer() : h.getManufacturer()); + order.setCustomsBrokerInfo(StringUtils.isNotBlank(headerInfo.getCustomsBrokerInfo()) ? headerInfo.getCustomsBrokerInfo() : h.getCustomsBrokerInfo()); + order.setDeliveryAddress(StringUtils.isNotBlank(headerInfo.getDeliveryAddress()) ? headerInfo.getDeliveryAddress() : h.getDeliveryAddress()); + order.setEntryExitCustoms(StringUtils.isNotBlank(headerInfo.getEntryExitCustoms()) ? headerInfo.getEntryExitCustoms() : h.getEntryExitCustoms()); + order.setOriginDestinationCountry(StringUtils.isNotBlank(headerInfo.getOriginDestinationCountry()) ? headerInfo.getOriginDestinationCountry() : h.getOriginDestinationCountry()); + order.setCarrier(StringUtils.isNotBlank(headerInfo.getCarrier()) ? headerInfo.getCarrier() : h.getCarrier()); + order.setContainerNo(StringUtils.isNotBlank(headerInfo.getContainerNo()) ? headerInfo.getContainerNo() : h.getContainerNo()); + order.setTransportMethod(StringUtils.isNotBlank(headerInfo.getTransportMethod()) ? headerInfo.getTransportMethod() : h.getTransportMethod()); + order.setSupervisionMethod(StringUtils.isNotBlank(headerInfo.getSupervisionMethod()) ? headerInfo.getSupervisionMethod() : h.getSupervisionMethod()); + + // 报关字段默认值(优先使用表头字段) + Integer customsInspection = headerInfo.getCustomsInspection() != null ? headerInfo.getCustomsInspection() : h.getCustomsInspection(); + if (customsInspection == null) { + order.setCustomsInspection(0); // 默认:否 + } else { + order.setCustomsInspection(customsInspection); + } + Integer needCustomsDeclaration = headerInfo.getNeedCustomsDeclaration() != null ? headerInfo.getNeedCustomsDeclaration() : h.getNeedCustomsDeclaration(); + if (needCustomsDeclaration == null) { + order.setNeedCustomsDeclaration(1); // 默认:是 + } else { + order.setNeedCustomsDeclaration(needCustomsDeclaration); + } + Integer needTransport = headerInfo.getNeedTransport() != null ? headerInfo.getNeedTransport() : h.getNeedTransport(); + if (needTransport == null) { + order.setNeedTransport(0); // 默认:否 + } else { + order.setNeedTransport(needTransport); + } + + // 日期字段(优先使用表头字段,如果表头为空则使用明细行字段) + String warehouseDateStr = StringUtils.isNotBlank(headerInfo.getWarehouseDate()) ? headerInfo.getWarehouseDate() : h.getWarehouseDate(); + if (StringUtils.isNotBlank(warehouseDateStr)) { + Date warehouseDate = parseDateString(warehouseDateStr); + if (warehouseDate != null) { + order.setWarehouseDate(warehouseDate); + log.info("设置入仓日期: {}", warehouseDate); + } + } + + String completionTimeStr = StringUtils.isNotBlank(headerInfo.getCompletionTime()) ? headerInfo.getCompletionTime() : h.getCompletionTime(); + if (StringUtils.isNotBlank(completionTimeStr)) { + Date completionTime = parseDateString(completionTimeStr); + if (completionTime != null) { + order.setCompletionTime(completionTime); + log.info("设置完成时间: {}", completionTime); + } + } + + String orderDateStr = StringUtils.isNotBlank(headerInfo.getOrderDate()) ? headerInfo.getOrderDate() : h.getOrderDate(); + if (StringUtils.isNotBlank(orderDateStr)) { + Date orderDate = parseDateString(orderDateStr); + if (orderDate != null) { + order.setOrderDate(orderDate); + log.info("设置下单日期: {}", orderDate); + } + } + + // 明细 + List details = new ArrayList<>(); + for (StockInOrderImportRowDTO r : groupRows) { + // 记录当前明细行的关键信息,用于调试 + log.info("处理明细行 - 委托编号NO: {}, 商品名称: [{}], 料号: [{}], SKU码: [{}], 仓库数量: [{}], 入库数量: [{}]", + h.getConsignmentNo(), r.getMaterialName(), r.getMaterialCode(), r.getSkuCode(), + r.getWarehouseQuantity(), r.getInboundQuantity()); + + // 先检查数量,如果数量为空,直接跳过该明细行(不需要检查物料) + BigDecimal quantity = r.getWarehouseQuantity(); + if (quantity == null) { + quantity = r.getInboundQuantity(); + } + if (quantity == null) { + log.warn("跳过明细行:仓库数量或入库数量不能为空 - 委托编号NO: [{}], 商品名称: [{}], 料号: [{}], SKU码: [{}]", + h.getConsignmentNo(), r.getMaterialName(), r.getMaterialCode(), r.getSkuCode()); + continue; // 跳过该明细行,继续处理下一行 + } + + // 检查是否为容器类型等非物料信息,如果是则跳过 + String materialName = r.getMaterialName(); + if (StringUtils.isNotBlank(materialName)) { + String lowerName = materialName.trim(); + // 常见的容器类型关键词(不区分大小写) + if (lowerName.contains("尺柜") || lowerName.contains("尺集装箱") || + lowerName.contains("Container") || lowerName.contains("container") || + (lowerName.contains("柜") && (lowerName.contains("20") || lowerName.contains("40") || lowerName.contains("45")))) { + log.info("跳过明细行:识别为容器类型信息,非实际物料 - 委托编号NO: [{}], 商品名称: [{}]", + h.getConsignmentNo(), materialName); + continue; // 跳过该明细行,继续处理下一行 + } + } + + // 根据明细表中的字段查询物料基础信息(优先:料号 > 商品SKU码 > 商品名称) + // 注意:查询时必须加上货主ID条件,确保查询到的是该货主绑定的物料 + 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 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); + } + } 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 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 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()); + } + + // 数量已在前面检查过,这里直接使用 + log.info("数量字段检查 - 仓库数量: [{}], 入库数量: [{}], 使用数量: [{}]", + r.getWarehouseQuantity(), r.getInboundQuantity(), quantity); + + InMaterialDetailDO d = new InMaterialDetailDO(); + d.setMaterialBaseInfoId(materialBaseInfoId); + // 设置商品名称和料号(从Excel读取) + d.setMaterialName(r.getMaterialName()); + // 如果料号为空但物料ID有值,根据物料ID查询并补充料号 + String materialCode = r.getMaterialCode(); + if (StringUtils.isBlank(materialCode) && materialBaseInfoId != null) { + try { + MaterialBaseInfoPO materialBaseInfo = materialBaseInfoService.getInfo(materialBaseInfoId); + if (materialBaseInfo != null && StringUtils.isNotBlank(materialBaseInfo.getMaterialCode())) { + materialCode = materialBaseInfo.getMaterialCode(); + log.info("根据物料ID自动补充料号,物料ID: {}, 料号: {}", materialBaseInfoId, materialCode); + } + } catch (Exception e) { + log.warn("根据物料ID查询料号失败,物料ID: {}, 错误: {}", materialBaseInfoId, e.getMessage()); + } + } + d.setMaterialCode(materialCode); + d.setQuantity(quantity); + d.setSpecificationModel(r.getSpecificationModel()); + d.setSkuCode(r.getSkuCode()); + d.setInvoiceNo(r.getInvoiceNo()); + d.setDeclaredQuantity(r.getDeclaredQuantity()); + d.setDeclarationUnit(r.getDeclarationUnit()); + d.setLiter(r.getLiter()); + d.setBoxCount(r.getBoxCount()); + d.setPieceCount(r.getPieceCount()); + d.setDimensions(r.getDimensions()); + // 入库数量:优先使用入库数量,如果为空则使用仓库数量 + BigDecimal inboundQuantity = r.getInboundQuantity(); + if (inboundQuantity == null) { + inboundQuantity = r.getWarehouseQuantity(); + if (inboundQuantity != null) { + log.info("入库数量为空,使用仓库数量作为入库数量: [{}]", inboundQuantity); + } + } + d.setInboundQuantity(inboundQuantity); + // 单位:优先使用"单位"字段,如果为空则使用"申报单位" + String unit = StringUtils.isNotBlank(r.getUnit()) ? r.getUnit() : null; + if (StringUtils.isBlank(unit) && StringUtils.isNotBlank(r.getDeclarationUnit())) { + unit = r.getDeclarationUnit(); + log.info("单位字段为空,使用申报单位: {}", unit); + } + d.setUnit(unit); + // 总净重:优先使用主字段,如果为空则使用备用字段 + d.setTotalNetWeight(r.getTotalNetWeight() != null ? r.getTotalNetWeight() : r.getTotalNetWeight2()); + // 总毛重:优先使用主字段,如果为空则使用备用字段 + d.setTotalGrossWeight(r.getTotalGrossWeight() != null ? r.getTotalGrossWeight() : r.getTotalGrossWeight2()); + // 总体积:优先使用主字段,如果为空则使用备用字段 + d.setTotalVolume(r.getTotalVolume() != null ? r.getTotalVolume() : r.getTotalVolume2()); + // 总面积:优先使用主字段,如果为空则使用备用字段 + d.setTotalArea(r.getTotalArea() != null ? r.getTotalArea() : r.getTotalArea2()); + d.setBatchRefNo(r.getBatchRefNo()); + d.setSheetRefNo(r.getSheetRefNo()); + d.setOriginCountry(r.getOriginCountry()); + d.setBoxPalletNo(r.getBoxPalletNo()); + d.setTotalPrice(r.getTotalPrice()); + d.setCurrency(r.getCurrency()); + d.setRemark(r.getDetailRemark()); + + // 记录即将保存的明细数据,用于调试 + log.info("准备保存明细数据 - 商品名称: [{}], 料号: [{}], SKU码: [{}], 规格型号: [{}], 入库数量: [{}], 数量: [{}], 单位: [{}], 总净重: [{}], 总毛重: [{}], 总体积: [{}], 总面积: [{}], 原产国: [{}], 币制: [{}], 备注: [{}]", + r.getMaterialName(), r.getMaterialCode(), r.getSkuCode(), r.getSpecificationModel(), + r.getInboundQuantity(), quantity, unit, d.getTotalNetWeight(), d.getTotalGrossWeight(), + d.getTotalVolume(), d.getTotalArea(), r.getOriginCountry(), r.getCurrency(), r.getDetailRemark()); + + details.add(d); + } + + // 如果该订单的所有明细行都被跳过(details为空),跳过该订单 + if (details.isEmpty()) { + log.warn("跳过入库单:委托编号NO [{}] 的所有明细行都因数据不完整被跳过,该入库单将不会被导入", h.getConsignmentNo()); + continue; // 跳过该订单,继续处理下一个订单 + } + + order.setMaterialDetailList(details); + + // 导入入库单时,计划数量取所有明细行的入库数量之和 + if (!CollectionUtils.isEmpty(details)) { + BigDecimal totalInboundQuantity = details.stream() + .map(detail -> detail.getInboundQuantity() != null ? detail.getInboundQuantity() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + order.setQuantity(totalInboundQuantity); + log.info("计算计划数量 - 委托编号NO: [{}], 明细行数: {}, 计划数量(入库数量之和): [{}]", + h.getConsignmentNo(), details.size(), totalInboundQuantity); + } + + // 在导入时,需要调用shipperParam、supplierParam和setDataDict方法,确保货主信息被正确填充 + // 注意:这里只调用shipperParam,因为导入时只提供了货主名称,需要根据名称查找货主ID和编号 + try { + shipperParam(order); + } catch (Exception e) { + log.error("导入入库单时设置货主信息失败,委托编号NO:{},货主名称:{},错误:{}", + h.getConsignmentNo(), order.getShipperName(), e.getMessage()); + throw new ServiceException("导入失败:设置货主信息失败(委托编号NO=" + h.getConsignmentNo() + ",货主名称=" + order.getShipperName() + ")。" + e.getMessage()); + } + // 设置供应商信息(如果提供了供应商ID) + supplierParam(order); + // 设置数据字典键值 + setDataDict(order); + + orderList.add(order); + } + + // 如果所有订单都被跳过(orderList为空),抛出异常提示用户 + if (orderList.isEmpty()) { + throw new ServiceException("导入失败:所有入库单的明细行都因数据不完整(数量为空或物料基础信息缺失)被跳过,请检查Excel数据"); + } + + return stockInOrderDomainService.batchInsert(orderList); + } catch (ServiceException e) { + throw e; + } catch (Exception e) { + log.error("导入入库单失败", e); + throw new ServiceException("导入入库单失败:" + e.getMessage()); + } + } + + /** + * 解析日期字符串为Date对象 + * 支持多种日期格式:yyyy-MM-dd, yyyy/MM/dd, yyyy年MM月dd日, Date.toString()格式等 + */ + private Date parseDateString(String dateStr) { + if (StringUtils.isBlank(dateStr)) { + return null; + } + + // 如果已经是Date.toString()格式(如 "Sun Feb 01 00:00:00 CST 2026"),尝试直接解析 + if (dateStr.contains("CST") || dateStr.contains("GMT") || dateStr.contains("UTC")) { + try { + // 尝试解析标准Date.toString()格式 + SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", java.util.Locale.ENGLISH); + return sdf.parse(dateStr); + } catch (ParseException e) { + log.warn("无法解析日期格式: {}", dateStr); + } + } + + // 尝试多种日期格式 + String[] datePatterns = { + "yyyy-MM-dd", + "yyyy/MM/dd", + "yyyy.MM.dd", + "yyyy年MM月dd日", + "yyyy-MM-dd HH:mm:ss", + "yyyy/MM/dd HH:mm:ss", + "yyyy-MM-dd HH:mm", + "yyyy/MM/dd HH:mm" + }; + + for (String pattern : datePatterns) { + try { + SimpleDateFormat sdf = new SimpleDateFormat(pattern); + sdf.setLenient(false); + return sdf.parse(dateStr.trim()); + } catch (ParseException e) { + // 继续尝试下一个格式 + } + } + + // 如果所有格式都失败,记录警告 + log.warn("无法解析日期字符串: {},尝试使用DateUtils.parseDate", dateStr); + try { + // 使用DateUtils的parseDate方法(支持多种格式) + return com.mhd.common.core.utils.DateUtils.parseDate(dateStr); + } catch (Exception e) { + log.error("解析日期失败: {}", dateStr, e); + return null; + } + } + + /** + * 获取Excel单元格的字符串值 + */ + private String getCellValueAsString(Cell cell) { + if (cell == null) { + return ""; + } + switch (cell.getCellType()) { + case STRING: + return cell.getStringCellValue(); + case NUMERIC: + if (DateUtil.isCellDateFormatted(cell)) { + // 日期类型单元格,格式化为 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss + Date dateValue = cell.getDateCellValue(); + SimpleDateFormat sdf; + // 检查是否包含时间部分 + if (dateValue.getHours() == 0 && dateValue.getMinutes() == 0 && dateValue.getSeconds() == 0) { + sdf = new SimpleDateFormat("yyyy-MM-dd"); + } else { + sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + return sdf.format(dateValue); + } else { + double numericValue = cell.getNumericCellValue(); + if (numericValue == (long) numericValue) { + return String.valueOf((long) numericValue); + } else { + return String.valueOf(numericValue); + } + } + case BOOLEAN: + return String.valueOf(cell.getBooleanCellValue()); + case FORMULA: + return cell.getCellFormula(); + default: + return ""; + } + } + /** * @description 设置仓库信息 * @author ZhouGY @@ -148,29 +1543,212 @@ public class StockInOrderApplicationService { * @param stockInOrderDO */ private void setWarehouseInfo(StockInOrderDO stockInOrderDO) { + if (stockInOrderDO.getWarehouseId() == null) { + throw new ServiceException("仓库ID不能为空"); + } AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(stockInOrderDO.getWarehouseId()); - if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ - throw new ServiceException("获取仓库信息失败"); + if (ajaxResult == null) { + throw new ServiceException("获取仓库信息失败:返回结果为空,仓库ID:" + stockInOrderDO.getWarehouseId()); + } + Object codeObj = ajaxResult.get("code"); + if (codeObj == null || !"200".equals(String.valueOf(codeObj))) { + String errorMsg = ajaxResult.get("msg") != null ? String.valueOf(ajaxResult.get("msg")) : "未知错误"; + throw new ServiceException("获取仓库信息失败,仓库ID:" + stockInOrderDO.getWarehouseId() + ",错误信息:" + errorMsg); + } + Object dataObj = ajaxResult.get("data"); + if (dataObj == null) { + throw new ServiceException("获取仓库信息失败:返回数据为空,仓库ID:" + stockInOrderDO.getWarehouseId()); + } + WarehouseFeignPO warehouseFeignPO = JSON.parseObject(JSONObject.toJSONString(dataObj), WarehouseFeignPO.class); + if (warehouseFeignPO == null) { + throw new ServiceException("获取仓库信息失败:数据解析失败,仓库ID:" + stockInOrderDO.getWarehouseId()); } - WarehouseFeignPO warehouseFeignPO = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), WarehouseFeignPO.class); stockInOrderDO.setWarehouseCode(warehouseFeignPO.getWarehouseCode()); stockInOrderDO.setWarehouseName(warehouseFeignPO.getWarehouseName()); } /** - * @description 封装货主信息 + * @description 根据货主名称或编号获取货主ID(用于导入时提前获取货主ID) + * @param shipperName 货主名称 + * @param shipperCode 货主编号 + * @return 货主ID,如果找不到则返回null + */ + private Long getShipperIdByNameOrCode(String shipperName, String shipperCode) { + if (StringUtils.isBlank(shipperName) && StringUtils.isBlank(shipperCode)) { + return null; + } + + Long shipperId = null; + + // 优先尝试:如果名称是纯数字,可能是误传的ID,直接按ID查询 + if (StringUtils.isNotEmpty(shipperName) && shipperName.matches("\\d+")) { + try { + Long possibleId = Long.valueOf(shipperName); + AjaxResult ajaxResult = userServiceFeign.getInfo(possibleId); + 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) { + shipperId = userPo.getUserId(); + log.info("根据货主名称(实际为ID)找到货主ID:{}", shipperId); + return shipperId; + } + } + } catch (Exception e) { + log.debug("尝试将货主名称作为ID查询失败,货主名称:{},错误:{}", shipperName, e.getMessage()); + } + } + + // 如果仍未找到,尝试根据名称查询 + if (shipperId == null && StringUtils.isNotEmpty(shipperName) && !shipperName.matches("\\d+")) { + try { + AjaxResult ajaxResult = userServiceFeign.getInfoByName(shipperName); + String code = String.valueOf(ajaxResult.get("code")); + if ("200".equals(code) && ajaxResult.get("data") != null) { + UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + if (userPo != null) { + shipperId = userPo.getUserId(); + log.info("根据货主名称找到货主ID,货主名称:{},货主ID:{}", shipperName, shipperId); + return shipperId; + } + } + } catch (Exception e) { + log.debug("根据货主名称查询失败,货主名称:{},错误:{}", shipperName, e.getMessage()); + } + } + + // 如果仍未找到,尝试从货主列表中根据编号或名称查找 + if (shipperId == null && (StringUtils.isNotEmpty(shipperName) || StringUtils.isNotEmpty(shipperCode))) { + try { + AjaxResult shipperListResult = userServiceFeign.userShipperListAll(); + if ("200".equals(String.valueOf(shipperListResult.get("code"))) && shipperListResult.get("data") != null) { + Object data = shipperListResult.get("data"); + List> shipperList = null; + if (data instanceof List) { + @SuppressWarnings("unchecked") + List rawList = (List) data; + shipperList = new ArrayList<>(); + for (Object item : rawList) { + if (item instanceof Map) { + @SuppressWarnings("unchecked") + Map mapItem = (Map) item; + shipperList.add(mapItem); + } else { + Map mapItem = JSON.parseObject(JSONObject.toJSONString(item), Map.class); + shipperList.add(mapItem); + } + } + } else { + String jsonStr = JSONObject.toJSONString(data); + shipperList = JSON.parseObject(jsonStr, new com.alibaba.fastjson.TypeReference>>(){}); + } + + if (shipperList != null && !shipperList.isEmpty()) { + String normalizedShipperName = shipperName != null ? shipperName.trim() : ""; + String normalizedShipperCode = shipperCode != null ? shipperCode.trim() : ""; + + for (Map shipper : shipperList) { + Object userId = shipper.get("userId"); + Object userName = shipper.get("userName"); + Object userCode = shipper.get("userCode"); + Object userMemberCode = shipper.get("userMemberCode"); + + if (userName == null) { + userName = shipper.get("name"); + } + if (userName == null) { + userName = shipper.get("shipperName"); + } + + boolean matched = false; + // 优先根据编号匹配 + if (StringUtils.isNotEmpty(normalizedShipperCode)) { + String normalizedUserCode = userCode != null ? String.valueOf(userCode).trim() : ""; + String normalizedUserMemberCode = userMemberCode != null ? String.valueOf(userMemberCode).trim() : ""; + if (normalizedShipperCode.equals(normalizedUserCode) || + normalizedShipperCode.equals(normalizedUserMemberCode)) { + matched = true; + } + } + // 如果编号不匹配,再根据名称匹配 + if (!matched && StringUtils.isNotEmpty(normalizedShipperName) && userName != null) { + String normalizedUserName = String.valueOf(userName).trim(); + if (normalizedShipperName.equals(normalizedUserName) || + normalizedUserName.contains(normalizedShipperName)) { + matched = true; + } + } + + if (matched && userId != null) { + shipperId = Long.valueOf(String.valueOf(userId)); + log.info("从货主列表中找到货主ID,货主名称:{},货主编号:{},货主ID:{}", + shipperName, shipperCode, shipperId); + return shipperId; + } + } + } + } + } catch (Exception e) { + log.debug("从货主列表中查找货主ID失败,货主名称:{},货主编号:{},错误:{}", + shipperName, shipperCode, e.getMessage()); + } + } + + if (shipperId == null) { + log.warn("未找到货主ID,货主名称:{},货主编号:{}", shipperName, shipperCode); + } + + return shipperId; + } + + /** + * @description 封装货主信息(改为与出库单相同的简洁逻辑,使用入库单的字段shipperName) * @author ZhouGY * @date 2024/5/9 20:43 * @param stockInOrderDO */ private void shipperParam(StockInOrderDO stockInOrderDO){ - AjaxResult ajaxResult = userServiceFeign.getInfo(stockInOrderDO.getShipperId()); - if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ - throw new ServiceException("获取货主信息失败"); + // 新增/编辑时前端可能只传 shipperId(下拉选中值),shipperName 为空。 + // 这里优先按 shipperId 回填货主编码/名称;其次再按 shipperName(名称或数字ID字符串)回填。 + + // 1) 优先按 shipperId 查询 + if (ObjectUtil.isNotNull(stockInOrderDO.getShipperId())) { + AjaxResult ajaxResult = userServiceFeign.getInfo(stockInOrderDO.getShipperId()); + if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ + throw new ServiceException("获取货主信息失败"); + } + UserPo userPo = JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + stockInOrderDO.setShipperId(userPo.getUserId()); + stockInOrderDO.setShipperCode(userPo.getUserMemberCode()); + stockInOrderDO.setShipperName(userPo.getUserName()); + return; + } + + // 2) shipperId 为空时,按 shipperName 兜底 + String shipperName = stockInOrderDO.getShipperName(); + if (StringUtils.isEmpty(shipperName)) { + return; + } + if (!shipperName.matches("\\d+")) { + // 按名称查询 + AjaxResult ajaxResult = userServiceFeign.getInfoByName(shipperName); + if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ + throw new ServiceException("获取货主信息失败"); + } + UserPo userPo = JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + stockInOrderDO.setShipperId(userPo.getUserId()); + stockInOrderDO.setShipperCode(userPo.getUserMemberCode()); + stockInOrderDO.setShipperName(userPo.getUserName()); + } else { + // shipperName 是数字:按ID查询 + AjaxResult ajaxResult = userServiceFeign.getInfo(Long.valueOf(shipperName)); + if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ + throw new ServiceException("获取货主信息失败"); + } + UserPo userPo = JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + stockInOrderDO.setShipperId(userPo.getUserId()); + stockInOrderDO.setShipperCode(userPo.getUserMemberCode()); + stockInOrderDO.setShipperName(userPo.getUserName()); } - UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); - stockInOrderDO.setShipperCode(userPo.getUserMemberCode()); - stockInOrderDO.setShipperName(userPo.getUserName()); } /** @@ -198,17 +1776,19 @@ public class StockInOrderApplicationService { */ private void setDataDict(StockInOrderDO stockInOrderDO){ //翻译单据类型 - AjaxResult documentTypeResult = systemServiceFeign.selectListByDictType(DictCode.DOCUMENT_TYPE.getCode()); - if (!"200".equals(String.valueOf(documentTypeResult.get("code")))) { - throw new ServiceException("单据类型数据字典不存在"); - } - List documentTypeDataList = JSON.parseArray(JSONUtil.toJsonStr(documentTypeResult.get("data")), SysDictData.class); + if (StringUtils.isNotBlank(stockInOrderDO.getOrderTypeCode())){ + AjaxResult documentTypeResult = systemServiceFeign.selectListByDictType(DictCode.DOCUMENT_TYPE.getCode()); + if (!"200".equals(String.valueOf(documentTypeResult.get("code")))) { + throw new ServiceException("单据类型数据字典不存在"); + } + List documentTypeDataList = JSON.parseArray(JSONUtil.toJsonStr(documentTypeResult.get("data")), SysDictData.class); - SysDictData documentTypeData = documentTypeDataList.stream().filter(info -> ObjectUtil.equal(info.getDictValue(), stockInOrderDO.getOrderTypeCode())).findAny().orElse(null); - if (null == documentTypeData) { - throw new ServiceException("单据类型【" + stockInOrderDO.getOrderTypeCode() + "】数据字典不存在 请联系管理员"); + SysDictData documentTypeData = documentTypeDataList.stream().filter(info -> ObjectUtil.equal(info.getDictValue(), stockInOrderDO.getOrderTypeCode())).findAny().orElse(null); + if (null == documentTypeData) { + throw new ServiceException("单据类型【" + stockInOrderDO.getOrderTypeCode() + "】数据字典不存在 请联系管理员"); + } + stockInOrderDO.setOrderTypeName(documentTypeData.getDictLabel()); } - stockInOrderDO.setOrderTypeName(documentTypeData.getDictLabel()); //翻译优先级别类型 if (StringUtils.isNotBlank(stockInOrderDO.getPriorityLevelCode())){ @@ -225,4 +1805,5 @@ public class StockInOrderApplicationService { stockInOrderDO.setPriorityLevelName(priorityLevelData.getDictLabel()); } } + } diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockOutOrder/StockOutOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockOutOrder/StockOutOrderApplicationService.java index 28e3f82d8..d24d10301 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockOutOrder/StockOutOrderApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockOutOrder/StockOutOrderApplicationService.java @@ -16,14 +16,17 @@ import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.SystemServiceFeign; import com.mhd.system.api.UserServiceFeign; +import com.mhd.system.api.domain.BatchDetailFeignPO; import com.mhd.system.api.domain.StorageLocationFeignPO; import com.mhd.system.api.domain.SysDictData; import com.mhd.system.api.domain.WarehouseFeignPO; 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.materialInventory.repository.mapper.MaterialInventoryMapper; import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO; import com.mhd.wms.domain.materialInventory.service.MaterialInventoryDomainService; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import com.mhd.wms.domain.outMaterialDetail.repository.po.OutMaterialCheckPO; import com.mhd.wms.domain.outMaterialDetail.repository.po.OutMaterialDetailPO; import com.mhd.wms.domain.outMaterialDetail.repository.todo.OutMaterialDetailDO; @@ -36,10 +39,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; +import java.lang.reflect.Field; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.text.SimpleDateFormat; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -59,6 +62,8 @@ public class StockOutOrderApplicationService { @Autowired private MaterialInventoryDomainService materialInventoryDomainService; @Autowired + private MaterialInventoryMapper materialInventoryMapper; + @Autowired private UserServiceFeign userServiceFeign; @Autowired private SystemServiceFeign systemServiceFeign; @@ -72,14 +77,14 @@ public class StockOutOrderApplicationService { public List queryList(StockOutOrderDO stockOutOrderDO) { LoginUser loginUser = SecurityUtils.getLoginUser(); - if (loginUser != null){ + /*if (loginUser != null){ Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); if (topOrganizationId != null && topOrganizationId != 1){ stockOutOrderDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); } AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); stockOutOrderDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId()); - } + }*/ return stockOutOrderDomainService.queryList(stockOutOrderDO); } @@ -89,13 +94,15 @@ public class StockOutOrderApplicationService { */ public Boolean insert(StockOutOrderDO stockOutOrderDO) { //设置仓库 - setWarehouseInfo(stockOutOrderDO); + //setWarehouseInfo(stockOutOrderDO); //设置货主信息 shipperParam(stockOutOrderDO); //设置客户信息 customerParam(stockOutOrderDO); + stockOutOrderDO.setOrderTypeCode("pu_tong_chu_ku"); + stockOutOrderDO.setOrderTypeName("普通出库"); //设置数据字典键值 - setDataDict(stockOutOrderDO); + //setDataDict(stockOutOrderDO); return stockOutOrderDomainService.insert(stockOutOrderDO); } @@ -121,11 +128,367 @@ public class StockOutOrderApplicationService { } /** - * 获取出库单详细信息 + * 获取出库单详细信息(带批次属性) */ public StockOutOrderPO getInfoChildren(Long outOrderId) { - return stockOutOrderDomainService.getInfoChildren(outOrderId); + StockOutOrderPO stockOutOrderPO = stockOutOrderDomainService.getInfoChildren(outOrderId); + + if (stockOutOrderPO == null || CollectionUtils.isEmpty(stockOutOrderPO.getMaterialDetailList())) { + return stockOutOrderPO; + } + + List detailList = stockOutOrderPO.getMaterialDetailList(); + + // 性能优化:批量获取批次属性,避免N+1查询问题 + // 1. 收集所有唯一的materialBaseInfoId + Set materialBaseInfoIdSet = detailList.stream() + .map(OutMaterialDetailPO::getMaterialBaseInfoId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 2. 批量查询批次属性(使用Map缓存,避免重复查询相同的materialBaseInfoId) + Map> batchDetailMap = new HashMap<>(); + for (Long materialBaseInfoId : materialBaseInfoIdSet) { + try { + AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + List batchDetailFeignPOList = JSON.parseArray( + JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class); + if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) { + // 过滤isDisplay=1的属性 + List filteredList = batchDetailFeignPOList.stream() + .filter(batchDetail -> batchDetail.getIsDisplay() != null && batchDetail.getIsDisplay() == 1) + .collect(Collectors.toList()); + batchDetailMap.put(materialBaseInfoId, filteredList); + } + } + } catch (Exception e) { + log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + } + + // 3. 为每个物料明细设置更多属性(从物料明细表中获取值),递归处理所有层级 + setMaterialMoreDetailListRecursively(detailList, batchDetailMap); + + // 4. 为每个物料明细设置分配按钮显示类型,递归处理所有层级 + setAllocationButtonTypeRecursively(detailList); + + return stockOutOrderPO; + } + + /** + * 递归为出库物料明细设置更多属性 + * 如果已分配库存(materialInventoryId不为空),则从库存表中获取批次属性值 + * 否则从物料明细表中获取值 + * @param outMaterialDetailPOList 出库物料明细列表 + * @param batchDetailMap 批次属性Map + */ + private void setMaterialMoreDetailListRecursively(List outMaterialDetailPOList, + Map> batchDetailMap) { + if (CollectionUtils.isEmpty(outMaterialDetailPOList)) { + return; + } + + outMaterialDetailPOList.forEach(outMaterialDetailPO -> { + Long materialBaseInfoId = outMaterialDetailPO.getMaterialBaseInfoId(); + Long materialInventoryId = outMaterialDetailPO.getMaterialInventoryId(); + + // 创建新的materialMoreDetailList,只包含isDisplay=1的属性 + List materialMoreDetailList = new ArrayList<>(); + + // 创建batchDetailId到MaterialMoreDetailPO的映射,用于快速查找已有的属性值 + Map batchDetailIdToMaterialMoreDetailMap = new HashMap<>(); + List existingList = outMaterialDetailPO.getMaterialMoreDetailList(); + if (!CollectionUtils.isEmpty(existingList)) { + for (MaterialMoreDetailPO existing : existingList) { + if (existing.getBatchDetailId() != null) { + batchDetailIdToMaterialMoreDetailMap.put(existing.getBatchDetailId(), existing); + } + } + } + + // 如果已分配库存,从库存表中获取批次属性值 + MaterialInventoryPO inventoryPO = null; + if (materialInventoryId != null && materialInventoryId > 0) { + try { + inventoryPO = materialInventoryMapper.selectByIdWithBatchAttributes(materialInventoryId); + log.info("从库存表获取批次属性,materialInventoryId={}", materialInventoryId); + } catch (Exception e) { + log.warn("从库存表获取批次属性失败,materialInventoryId={},错误:{}", materialInventoryId, e.getMessage()); + } + } + + // 只保留isDisplay=1的批次属性(从batchDetailMap中获取,已经过滤过了) + if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) { + List batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId); + // 用于跟踪已添加到列表中的batchDetailId + Set addedBatchDetailIds = new HashSet<>(); + + for (BatchDetailFeignPO batchDetailFeignPO : batchDetailFeignPOList) { + MaterialMoreDetailPO materialMoreDetailPO = batchDetailIdToMaterialMoreDetailMap.get(batchDetailFeignPO.getBatchDetailId()); + + // 如果不存在,创建新的 + if (materialMoreDetailPO == null) { + materialMoreDetailPO = new MaterialMoreDetailPO(); + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + } else { + // 如果已存在,更新属性(保留已有的attributeValue) + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + } + + // 确保添加到列表中(使用batchDetailId来避免重复) + Long batchDetailId = batchDetailFeignPO.getBatchDetailId(); + if (batchDetailId != null && !addedBatchDetailIds.contains(batchDetailId)) { + materialMoreDetailList.add(materialMoreDetailPO); + addedBatchDetailIds.add(batchDetailId); + } + + // 根据fieldName或batchLabels获取对应的字段值 + String fieldValue = null; + String usedFieldName = null; + + // 只有在已分配库存时,才从库存表获取值并设置到attributeValue + if (inventoryPO != null) { + // 优先使用fieldName(如果存在) + if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) { + usedFieldName = batchDetailFeignPO.getFieldName(); + fieldValue = getFieldValueByFieldName(inventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, fieldName={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue); + } + // 如果fieldName为空,尝试根据batchLabels映射到字段名 + else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) { + String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels()); + if (StringUtils.isNotBlank(fieldNameByLabel)) { + usedFieldName = fieldNameByLabel; + fieldValue = getFieldValueByFieldName(inventoryPO, usedFieldName); + log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 从库存表获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(), + usedFieldName, fieldValue); + } + } + + // 只有当获取到值时才更新attributeValue(已分配库存时) + if (fieldValue != null) { + materialMoreDetailPO.setAttributeValue(fieldValue); + log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}", + materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(), + materialMoreDetailPO.getAttributeValue()); + } + } else { + // 未分配库存时,attributeValue保持为空(不设置值) + log.info("批次属性未分配库存,batchDetailId={}, batchLabels={}, attributeValue为空", + materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels()); + } + } + } + outMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList); + log.info("出库物料明细 uniqueId={}, materialBaseInfoId={}, materialInventoryId={}, materialMoreDetailList大小={}", + outMaterialDetailPO.getUniqueId(), outMaterialDetailPO.getMaterialBaseInfoId(), + outMaterialDetailPO.getMaterialInventoryId(), + materialMoreDetailList != null ? materialMoreDetailList.size() : 0); + + // 递归处理子集 + if (!CollectionUtils.isEmpty(outMaterialDetailPO.getChildren())) { + setMaterialMoreDetailListRecursively(outMaterialDetailPO.getChildren(), batchDetailMap); + } + }); + } + + /** + * 根据批次标签(batchLabels)映射到字段名 + * @param batchLabel 批次标签 + * @return 字段名,如果找不到映射则返回null + */ + private String getFieldNameByBatchLabel(String batchLabel) { + if (StringUtils.isBlank(batchLabel)) { + return null; + } + + // 批次标签到字段名的映射关系 + Map labelToFieldNameMap = new HashMap<>(); + labelToFieldNameMap.put("Invoice No.", "invoiceNo"); + labelToFieldNameMap.put("Invoice No", "invoiceNo"); + labelToFieldNameMap.put("发票号", "invoiceNo"); + labelToFieldNameMap.put("Batch Ref NO's", "batchRefNo"); + labelToFieldNameMap.put("Batch Ref NO", "batchRefNo"); + labelToFieldNameMap.put("批次参考号", "batchRefNo"); + labelToFieldNameMap.put("Sheet Ref NO's", "sheetRefNo"); + labelToFieldNameMap.put("Sheet Ref NO", "sheetRefNo"); + labelToFieldNameMap.put("单据参考号", "sheetRefNo"); + labelToFieldNameMap.put("箱号/卡板号", "boxPalletNo"); + labelToFieldNameMap.put("箱号", "boxPalletNo"); + labelToFieldNameMap.put("卡板号", "boxPalletNo"); + labelToFieldNameMap.put("申报数量", "declareQuantity"); + labelToFieldNameMap.put("申报单位", "declareUnit"); + labelToFieldNameMap.put("原产国", "countryOfOrigin"); + labelToFieldNameMap.put("币制", "currency"); + labelToFieldNameMap.put("单位", "unit"); + labelToFieldNameMap.put("升", "liter"); + labelToFieldNameMap.put("尺寸", "size"); + labelToFieldNameMap.put("箱数", "caseCount"); + labelToFieldNameMap.put("件数", "pieceCount"); + labelToFieldNameMap.put("出库数量", "outboundQuantity"); + labelToFieldNameMap.put("总净重", "totalNetWeight"); + labelToFieldNameMap.put("总毛重", "totalGrossWeight"); + labelToFieldNameMap.put("总体积", "totalVolume"); + labelToFieldNameMap.put("总面积", "totalArea"); + labelToFieldNameMap.put("总价", "totalAmount"); + + // 精确匹配 + String fieldName = labelToFieldNameMap.get(batchLabel.trim()); + if (StringUtils.isNotBlank(fieldName)) { + return fieldName; + } + + // 模糊匹配(包含关系) + for (Map.Entry entry : labelToFieldNameMap.entrySet()) { + if (batchLabel.contains(entry.getKey()) || entry.getKey().contains(batchLabel)) { + return entry.getValue(); + } + } + + // 如果找不到映射,尝试将批次标签转换为驼峰命名(简单处理) + return convertLabelToFieldName(batchLabel); + } + + /** + * 将批次标签转换为字段名(驼峰命名) + * @param label 批次标签 + * @return 字段名 + */ + private String convertLabelToFieldName(String label) { + if (StringUtils.isBlank(label)) { + return null; + } + + // 移除特殊字符,转换为小写,用空格或特殊字符分割 + String cleaned = label.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5\\s]", " ") + .trim() + .toLowerCase(); + + // 如果是中文,无法自动转换,返回null + if (cleaned.matches(".*[\\u4e00-\\u9fa5].*")) { + return null; + } + + // 将空格分割的单词转换为驼峰命名 + String[] words = cleaned.split("\\s+"); + if (words.length == 0) { + return null; + } + + StringBuilder fieldName = new StringBuilder(words[0]); + for (int i = 1; i < words.length; i++) { + if (words[i].length() > 0) { + fieldName.append(words[i].substring(0, 1).toUpperCase()) + .append(words[i].substring(1)); + } + } + + return fieldName.toString(); + } + + /** + * 根据字段名从对象中获取字段值(使用反射) + * @param obj 对象 + * @param fieldName 字段名 + * @return 字段值(转换为字符串) + */ + private String getFieldValueByFieldName(Object obj, String fieldName) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return null; + } + + try { + // 兼容:如果传的是下划线命名(数据库列名风格),先转成驼峰字段名再取 + String normalizedFieldName = fieldName; + if (normalizedFieldName.contains("_")) { + normalizedFieldName = snakeToCamel(normalizedFieldName); + } + + // 获取对象的Class + Class clazz = obj.getClass(); + + // 尝试获取字段(包括父类字段) + Field field = null; + Class currentClass = clazz; + while (currentClass != null && field == null) { + try { + field = currentClass.getDeclaredField(normalizedFieldName); + } catch (NoSuchFieldException e) { + currentClass = currentClass.getSuperclass(); + } + } + + if (field == null) { + log.warn("字段不存在:{}(normalized:{}),对象类型:{}", fieldName, normalizedFieldName, clazz.getName()); + return null; + } + + // 设置可访问 + field.setAccessible(true); + + // 获取字段值 + Object value = field.get(obj); + + // 转换为字符串 + if (value == null) { + log.info("字段 {} 的值为 null,对象类型:{}", normalizedFieldName, clazz.getName()); + return null; + } + + String result; + // 处理日期类型字段 + if (value instanceof Date) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + result = sdf.format((Date) value); + } else { + result = value.toString(); + } + + log.info("通过反射获取字段值成功,字段名:{}(原始:{}),值:{},对象类型:{}", + normalizedFieldName, fieldName, result, clazz.getName()); + return result; + } catch (Exception e) { + log.warn("通过反射获取字段值失败,字段名:{},对象类型:{},错误:{}", fieldName, obj.getClass().getName(), e.getMessage()); + return null; + } + } + + private String snakeToCamel(String snake) { + if (StringUtils.isBlank(snake)) { + return null; + } + String s = snake.trim().toLowerCase(); + StringBuilder sb = new StringBuilder(); + boolean upperNext = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '_') { + upperNext = true; + continue; + } + if (upperNext) { + sb.append(Character.toUpperCase(c)); + upperNext = false; + } else { + sb.append(c); + } + } + return sb.toString(); } /** @@ -175,6 +538,19 @@ public class StockOutOrderApplicationService { return stockOutOrderDomainService.cancelAssign(stockOutOrderDO); } + /** + * @description 手动取消分配(点击确认后直接取消分配) + * @author ZhouGY + * @date 2024/5/28 13:47 + * @param stockOutOrderDO + * @return Boolean + */ + public Boolean manualCancelAssign(StockOutOrderDO stockOutOrderDO){ + // 取消分配不需要经过assembleParamByOutOrder,因为该方法是为分配设计的,会过滤掉allocationQuantity为0的明细 + // 直接调用领域服务,传递原始参数 + return stockOutOrderDomainService.manualCancelAssign(stockOutOrderDO); + } + /** * @description 复核下发 @@ -384,6 +760,9 @@ public class StockOutOrderApplicationService { * @param stockOutOrderDO */ private void setWarehouseInfo(StockOutOrderDO stockOutOrderDO) { + if (stockOutOrderDO.getWarehouseId() == null) { + throw new ServiceException("仓库ID不能为空"); + } AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(stockOutOrderDO.getWarehouseId()); if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ throw new ServiceException("获取仓库信息失败"); @@ -400,13 +779,26 @@ public class StockOutOrderApplicationService { * @param stockOutOrderDO */ private void shipperParam(StockOutOrderDO stockOutOrderDO){ - AjaxResult ajaxResult = userServiceFeign.getInfo(stockOutOrderDO.getShipperId()); - if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ - throw new ServiceException("获取货主信息失败"); + String customerName = stockOutOrderDO.getCustomerName(); + if (customerName == null || !customerName.matches("\\d+")) { + AjaxResult ajaxResult = userServiceFeign.getInfoByName(customerName); + if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ + throw new ServiceException("获取客户信息失败"); + } + UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + stockOutOrderDO.setShipperId(userPo.getUserId()); + stockOutOrderDO.setShipperCode(userPo.getUserMemberCode()); + stockOutOrderDO.setShipperName(userPo.getUserName()); + } else { + AjaxResult ajaxResult = userServiceFeign.getInfo(Long.valueOf(customerName)); + if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ + throw new ServiceException("获取货主信息失败"); + } + UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + stockOutOrderDO.setShipperId(userPo.getUserId()); + stockOutOrderDO.setShipperCode(userPo.getUserMemberCode()); + stockOutOrderDO.setShipperName(userPo.getUserName()); } - UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); - stockOutOrderDO.setShipperCode(userPo.getUserMemberCode()); - stockOutOrderDO.setShipperName(userPo.getUserName()); } /** @@ -416,13 +808,26 @@ public class StockOutOrderApplicationService { * @param stockOutOrderDO */ private void customerParam(StockOutOrderDO stockOutOrderDO){ - AjaxResult ajaxResult = userServiceFeign.getInfo(stockOutOrderDO.getCustomerId()); - if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ - throw new ServiceException("获取客户信息失败"); + String customerName = stockOutOrderDO.getCustomerName(); + if (customerName == null || !customerName.matches("\\d+")) { + AjaxResult ajaxResult = userServiceFeign.getInfoByName(customerName); + if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ + throw new ServiceException("获取客户信息失败"); + } + UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + stockOutOrderDO.setCustomerId(userPo.getUserId()); + stockOutOrderDO.setCustomerCode(userPo.getUserMemberCode()); + stockOutOrderDO.setCustomerName(userPo.getUserName()); + } else { + AjaxResult ajaxResult = userServiceFeign.getInfo(Long.valueOf(customerName)); + if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ + throw new ServiceException("获取客户信息失败"); + } + UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + stockOutOrderDO.setCustomerId(userPo.getUserId()); + stockOutOrderDO.setCustomerCode(userPo.getUserMemberCode()); + stockOutOrderDO.setCustomerName(userPo.getUserName()); } - UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); - stockOutOrderDO.setCustomerCode(userPo.getUserMemberCode()); - stockOutOrderDO.setCustomerName(userPo.getUserName()); } /** @@ -520,5 +925,43 @@ public class StockOutOrderApplicationService { outMaterialDetailDO.setContainerCode(materialInventoryPO.getContainerCode()); outMaterialDetailDO.setContainerType(materialInventoryPO.getContainerType()); outMaterialDetailDO.setContainerTypeName(materialInventoryPO.getContainerTypeName()); + // 库存数量,仅用于前端展示 + outMaterialDetailDO.setInventoryQuantity(materialInventoryPO.getInventoryQuantity()); } -} + + /** + * 递归为出库物料明细设置分配按钮显示类型 + * @param outMaterialDetailPOList 出库物料明细列表 + */ + private void setAllocationButtonTypeRecursively(List outMaterialDetailPOList) { + if (CollectionUtils.isEmpty(outMaterialDetailPOList)) { + return; + } + + outMaterialDetailPOList.forEach(outMaterialDetailPO -> { + BigDecimal quantity = outMaterialDetailPO.getQuantity(); // 计划数量 + BigDecimal alreadyAllocationQuantity = outMaterialDetailPO.getAlreadyAllocationQuantity(); // 已分配数量 + + // 判断按钮显示类型 + // 已分配数量 = 0:显示"库存分配"按钮(类型1) + // 已分配数量 = 计划数量:显示"取消分配"按钮(类型2) + if (alreadyAllocationQuantity == null || alreadyAllocationQuantity.compareTo(BigDecimal.ZERO) == 0) { + // 已分配数量为0或null,显示"库存分配"按钮 + outMaterialDetailPO.setAllocationButtonType(1); + } else if (quantity != null && alreadyAllocationQuantity.compareTo(quantity) == 0) { + // 已分配数量等于计划数量,显示"取消分配"按钮 + outMaterialDetailPO.setAllocationButtonType(2); + } else { + // 其他情况(已分配数量 > 0 但 < 计划数量),不显示按钮或显示其他状态 + outMaterialDetailPO.setAllocationButtonType(0); + } + + // 递归处理子级 + List children = outMaterialDetailPO.getChildren(); + if (!CollectionUtils.isEmpty(children)) { + setAllocationButtonTypeRecursively(children); + } + }); + } + +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockReceiptOrder/StockReceiptOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockReceiptOrder/StockReceiptOrderApplicationService.java index 392287747..b304fb3a6 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockReceiptOrder/StockReceiptOrderApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockReceiptOrder/StockReceiptOrderApplicationService.java @@ -28,6 +28,7 @@ import com.mhd.wms.domain.materialGoodsRule.repository.facade.IMaterialGoodsRule import com.mhd.wms.domain.materialGoodsRule.repository.po.MaterialGoodsRulePO; import com.mhd.wms.domain.materialWarehouseControl.repository.facade.IMaterialWarehouseControlService; import com.mhd.wms.domain.materialWarehouseControl.repository.po.MaterialWarehouseControlPO; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import com.mhd.wms.domain.receiptMaterialDetail.repository.po.ReceiptMaterialDetailPO; import com.mhd.wms.domain.receiptMaterialDetail.repository.todo.ReceiptMaterialDetailDO; import com.mhd.wms.domain.receiptMaterialDetail.service.ReceiptMaterialDetailDomainService; @@ -39,14 +40,20 @@ import com.mhd.wms.domain.stockReceiptOrder.service.StockReceiptOrderDomainServi import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import com.mhd.common.core.utils.StringUtils; import org.springframework.util.CollectionUtils; +import java.lang.reflect.Field; import java.math.BigDecimal; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -84,11 +91,28 @@ public class StockReceiptOrderApplicationService { public List queryList(StockReceiptOrderDO stockReceiptOrderDO) { LoginUser loginUser = SecurityUtils.getLoginUser(); - Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); - if (topOrganizationId != null && topOrganizationId != 1){ - stockReceiptOrderDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); - AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); - stockReceiptOrderDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId()); + if (loginUser != null){ + Long topOrganizationId = loginUser.getUserPo().getTopOrganizationId(); + if (topOrganizationId != null && topOrganizationId != 1){ + stockReceiptOrderDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); + } + try { + AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); + if (associationWarehouseCacheDO != null) { + if (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) { + // 如果获取仓库信息失败,记录日志但不影响查询(允许查询所有仓库) + log.warn("获取用户关联仓库信息失败,将查询所有仓库数据,用户ID:{},错误:{}", loginUser.getUserid(), e.getMessage()); + } } return stockReceiptOrderDomainService.queryList(stockReceiptOrderDO); } @@ -116,9 +140,408 @@ public class StockReceiptOrderApplicationService { ReceiptMaterialDetailDO receiptMaterialDetailDO = new ReceiptMaterialDetailDO(); receiptMaterialDetailDO.setReceiptOrderNumber(stockReceiptOrderPO.getReceiptOrderNumber()); List receiptMaterialDetailPOList = receiptMaterialDetailDomainService.queryListChildren(receiptMaterialDetailDO); + + // 性能优化:批量获取批次属性,避免N+1查询问题 + // 1. 收集所有唯一的materialBaseInfoId + Set materialBaseInfoIdSet = receiptMaterialDetailPOList.stream() + .map(ReceiptMaterialDetailPO::getMaterialBaseInfoId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 2. 批量查询批次属性(使用Map缓存,避免重复查询相同的materialBaseInfoId) + Map> batchDetailMap = new HashMap<>(); + for (Long materialBaseInfoId : materialBaseInfoIdSet) { + try { + AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + List batchDetailFeignPOList = JSON.parseArray( + JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class); + if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) { + // 过滤isDisplay=1的属性 + List filteredList = batchDetailFeignPOList.stream() + .filter(batchDetail -> batchDetail.getIsDisplay() != null && batchDetail.getIsDisplay() == 1) + .collect(Collectors.toList()); + batchDetailMap.put(materialBaseInfoId, filteredList); + } + } + } catch (Exception e) { + log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + } + + // 3. 为每个物料明细设置更多属性(从缓存中获取),递归处理所有层级 + setMaterialMoreDetailListRecursively(receiptMaterialDetailPOList, batchDetailMap); + stockReceiptOrderPO.setMaterialDetailList(receiptMaterialDetailPOList); + log.info("返回收货单信息,receiptOrderId={}, materialDetailList大小={}", + stockReceiptOrderPO.getReceiptOrderId(), + receiptMaterialDetailPOList != null ? receiptMaterialDetailPOList.size() : 0); return stockReceiptOrderPO; } + + /** + * 根据物料基础信息ID获取批次属性(更多属性),只返回isDisplay=1的属性 + * 并根据fieldName从物料明细中获取对应的字段值 + * @param materialBaseInfoId 物料基础信息ID + * @param receiptMaterialDetailPO 收货物料明细对象,用于根据fieldName获取字段值 + * @return 更多属性列表 + */ + private List getMaterialMoreDetailByBatch(Long materialBaseInfoId, ReceiptMaterialDetailPO receiptMaterialDetailPO) { + List materialMoreDetailPOList = new ArrayList<>(); + if (materialBaseInfoId == null) { + return materialMoreDetailPOList; + } + + try { + // 根据物料基础信息ID获取批次属性列表 + AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + List batchDetailFeignPOList = JSON.parseArray( + JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class); + + if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) { + // 过滤isDisplay=1的属性 + batchDetailFeignPOList.stream() + .filter(batchDetail -> batchDetail.getIsDisplay() != null && batchDetail.getIsDisplay() == 1) + .forEach(batchDetailFeignPO -> { + MaterialMoreDetailPO materialMoreDetailPO = new MaterialMoreDetailPO(); + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + + // 根据fieldName或batchLabels从物料明细中获取对应的字段值 + if (receiptMaterialDetailPO != null) { + String fieldValue = null; + String usedFieldName = null; + // 优先使用fieldName(如果存在) + if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) { + usedFieldName = batchDetailFeignPO.getFieldName(); + fieldValue = getFieldValueByFieldName(receiptMaterialDetailPO, usedFieldName); + log.debug("批次属性 batchDetailId={}, fieldName={}, 获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue); + } + // 如果fieldName为空,尝试根据batchLabels映射到字段名 + else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) { + String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels()); + if (StringUtils.isNotBlank(fieldNameByLabel)) { + usedFieldName = fieldNameByLabel; + fieldValue = getFieldValueByFieldName(receiptMaterialDetailPO, usedFieldName); + log.debug("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(), + usedFieldName, fieldValue); + } + } + materialMoreDetailPO.setAttributeValue(fieldValue); + } + + materialMoreDetailPOList.add(materialMoreDetailPO); + }); + } + } + } catch (Exception e) { + log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + + return materialMoreDetailPOList; + } + + /** + * 递归为物料明细设置更多属性 + * @param receiptMaterialDetailPOList 物料明细列表 + * @param batchDetailMap 批次属性Map + */ + private void setMaterialMoreDetailListRecursively(List receiptMaterialDetailPOList, + Map> batchDetailMap) { + if (CollectionUtils.isEmpty(receiptMaterialDetailPOList)) { + return; + } + + receiptMaterialDetailPOList.forEach(receiptMaterialDetailPO -> { + Long materialBaseInfoId = receiptMaterialDetailPO.getMaterialBaseInfoId(); + + // 只保留isDisplay=1的批次属性(从batchDetailMap中获取,已经过滤过了) + // 创建新的materialMoreDetailList,只包含isDisplay=1的属性 + List materialMoreDetailList = new ArrayList<>(); + + // 创建batchDetailId到MaterialMoreDetailPO的映射,用于快速查找已有的属性值 + Map batchDetailIdToMaterialMoreDetailMap = new HashMap<>(); + List existingList = receiptMaterialDetailPO.getMaterialMoreDetailList(); + if (!CollectionUtils.isEmpty(existingList)) { + for (MaterialMoreDetailPO existing : existingList) { + if (existing.getBatchDetailId() != null) { + batchDetailIdToMaterialMoreDetailMap.put(existing.getBatchDetailId(), existing); + } + } + } + + if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) { + List batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId); + // 用于跟踪已添加到列表中的batchDetailId + Set addedBatchDetailIds = new HashSet<>(); + + for (BatchDetailFeignPO batchDetailFeignPO : batchDetailFeignPOList) { + MaterialMoreDetailPO materialMoreDetailPO = batchDetailIdToMaterialMoreDetailMap.get(batchDetailFeignPO.getBatchDetailId()); + + // 如果不存在,创建新的 + if (materialMoreDetailPO == null) { + materialMoreDetailPO = new MaterialMoreDetailPO(); + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + } else { + // 如果已存在,更新属性(保留已有的attributeValue) + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + } + + // 确保添加到列表中(使用batchDetailId来避免重复) + Long batchDetailId = batchDetailFeignPO.getBatchDetailId(); + if (batchDetailId != null && !addedBatchDetailIds.contains(batchDetailId)) { + materialMoreDetailList.add(materialMoreDetailPO); + addedBatchDetailIds.add(batchDetailId); + } + + // 根据fieldName或batchLabels从物料明细中获取对应的字段值 + if (receiptMaterialDetailPO != null) { + String fieldValue = null; + String usedFieldName = null; + // 优先使用fieldName(如果存在) + if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) { + usedFieldName = batchDetailFeignPO.getFieldName(); + fieldValue = getFieldValueByFieldName(receiptMaterialDetailPO, usedFieldName); + log.info("批次属性 batchDetailId={}, fieldName={}, 获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue); + } + // 如果fieldName为空,尝试根据batchLabels映射到字段名 + else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) { + String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels()); + if (StringUtils.isNotBlank(fieldNameByLabel)) { + usedFieldName = fieldNameByLabel; + fieldValue = getFieldValueByFieldName(receiptMaterialDetailPO, usedFieldName); + log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(), + usedFieldName, fieldValue); + } + } + // 只有当获取到值时才更新attributeValue(避免覆盖已有的值) + if (fieldValue != null) { + materialMoreDetailPO.setAttributeValue(fieldValue); + log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}", + materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(), + materialMoreDetailPO.getAttributeValue()); + } + } + } + } + receiptMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList); + log.info("物料明细 uniqueId={}, materialBaseInfoId={}, materialMoreDetailList大小={}", + receiptMaterialDetailPO.getUniqueId(), receiptMaterialDetailPO.getMaterialBaseInfoId(), + materialMoreDetailList != null ? materialMoreDetailList.size() : 0); + + // 递归处理子集 + if (!CollectionUtils.isEmpty(receiptMaterialDetailPO.getChildren())) { + setMaterialMoreDetailListRecursively(receiptMaterialDetailPO.getChildren(), batchDetailMap); + } + }); + } + + /** + * 根据批次标签(batchLabels)映射到字段名 + * @param batchLabel 批次标签 + * @return 字段名,如果找不到映射则返回null + */ + private String getFieldNameByBatchLabel(String batchLabel) { + if (StringUtils.isBlank(batchLabel)) { + return null; + } + + // 批次标签到字段名的映射关系 + // 可以根据实际业务需求扩展这个映射表 + Map labelToFieldNameMap = new HashMap<>(); + labelToFieldNameMap.put("Invoice No.", "invoiceNo"); + labelToFieldNameMap.put("Invoice No", "invoiceNo"); + labelToFieldNameMap.put("发票号", "invoiceNo"); + labelToFieldNameMap.put("Batch Ref NO's", "batchRefNo"); + labelToFieldNameMap.put("Batch Ref NO", "batchRefNo"); + labelToFieldNameMap.put("批次参考号", "batchRefNo"); + labelToFieldNameMap.put("Sheet Ref NO's", "sheetRefNo"); + labelToFieldNameMap.put("Sheet Ref NO", "sheetRefNo"); + labelToFieldNameMap.put("单据参考号", "sheetRefNo"); + labelToFieldNameMap.put("箱号/卡板号", "boxPalletNo"); + labelToFieldNameMap.put("箱号", "boxPalletNo"); + labelToFieldNameMap.put("卡板号", "boxPalletNo"); + labelToFieldNameMap.put("申报数量", "declaredQuantity"); + labelToFieldNameMap.put("申报单位", "declarationUnit"); + labelToFieldNameMap.put("原产国", "originCountry"); + labelToFieldNameMap.put("币制", "currency"); + labelToFieldNameMap.put("单位", "unit"); + labelToFieldNameMap.put("升", "liter"); + labelToFieldNameMap.put("尺寸", "dimensions"); + labelToFieldNameMap.put("箱数", "boxCount"); + labelToFieldNameMap.put("件数", "pieceCount"); + labelToFieldNameMap.put("入库数量", "inboundQuantity"); + labelToFieldNameMap.put("总净重", "totalNetWeight"); + labelToFieldNameMap.put("总毛重", "totalGrossWeight"); + labelToFieldNameMap.put("总体积", "totalVolume"); + labelToFieldNameMap.put("总面积", "totalArea"); + labelToFieldNameMap.put("总价", "totalPrice"); + + // 精确匹配 + String fieldName = labelToFieldNameMap.get(batchLabel.trim()); + if (StringUtils.isNotBlank(fieldName)) { + return fieldName; + } + + // 模糊匹配(包含关系) + for (Map.Entry entry : labelToFieldNameMap.entrySet()) { + if (batchLabel.contains(entry.getKey()) || entry.getKey().contains(batchLabel)) { + return entry.getValue(); + } + } + + // 如果找不到映射,尝试将批次标签转换为驼峰命名(简单处理) + // 例如:"Invoice No." -> "invoiceNo" + return convertLabelToFieldName(batchLabel); + } + + /** + * 将批次标签转换为字段名(驼峰命名) + * @param label 批次标签 + * @return 字段名 + */ + private String convertLabelToFieldName(String label) { + if (StringUtils.isBlank(label)) { + return null; + } + + // 移除特殊字符,转换为小写,用空格或特殊字符分割 + String cleaned = label.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5\\s]", " ") + .trim() + .toLowerCase(); + + // 如果是中文,无法自动转换,返回null + if (cleaned.matches(".*[\\u4e00-\\u9fa5].*")) { + return null; + } + + // 将空格分割的单词转换为驼峰命名 + String[] words = cleaned.split("\\s+"); + if (words.length == 0) { + return null; + } + + StringBuilder fieldName = new StringBuilder(words[0]); + for (int i = 1; i < words.length; i++) { + if (words[i].length() > 0) { + fieldName.append(words[i].substring(0, 1).toUpperCase()) + .append(words[i].substring(1)); + } + } + + return fieldName.toString(); + } + + /** + * 根据字段名从对象中获取字段值(使用反射) + * @param obj 对象 + * @param fieldName 字段名 + * @return 字段值(转换为字符串) + */ + private String getFieldValueByFieldName(Object obj, String fieldName) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return null; + } + + try { + // 兼容:如果传的是下划线命名(数据库列名风格),先转成驼峰字段名再取 + // 例如:box_pallet_no -> boxPalletNo + String normalizedFieldName = fieldName; + if (normalizedFieldName.contains("_")) { + normalizedFieldName = snakeToCamel(normalizedFieldName); + } + + // 获取对象的Class + Class clazz = obj.getClass(); + + // 尝试获取字段(包括父类字段) + Field field = null; + Class currentClass = clazz; + while (currentClass != null && field == null) { + try { + field = currentClass.getDeclaredField(normalizedFieldName); + } catch (NoSuchFieldException e) { + currentClass = currentClass.getSuperclass(); + } + } + + if (field == null) { + log.warn("字段不存在:{}(normalized:{}),对象类型:{}", fieldName, normalizedFieldName, clazz.getName()); + return null; + } + + // 设置可访问 + field.setAccessible(true); + + // 获取字段值 + Object value = field.get(obj); + + // 转换为字符串 + if (value == null) { + log.info("字段 {} 的值为 null,对象类型:{}", normalizedFieldName, clazz.getName()); + return null; + } + + String result; + // 处理日期类型字段 + if (value instanceof Date) { + result = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, (Date) value); + } else { + result = value.toString(); + } + + log.info("通过反射获取字段值成功,字段名:{}(原始:{}),值:{},对象类型:{}", + normalizedFieldName, fieldName, result, clazz.getName()); + return result; + } catch (Exception e) { + log.warn("通过反射获取字段值失败,字段名:{},对象类型:{},错误:{}", fieldName, obj.getClass().getName(), e.getMessage()); + return null; + } + } + + private String snakeToCamel(String snake) { + if (StringUtils.isBlank(snake)) { + return null; + } + String s = snake.trim().toLowerCase(); + StringBuilder sb = new StringBuilder(); + boolean upperNext = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '_') { + upperNext = true; + continue; + } + if (upperNext) { + sb.append(Character.toUpperCase(c)); + upperNext = false; + } else { + sb.append(c); + } + } + return sb.toString(); + } /** * 获取收货单详细信息 @@ -162,7 +585,21 @@ public class StockReceiptOrderApplicationService { * @return Boolean */ public Boolean taskDistribution(StockReceiptOrderDO stockReceiptOrderDO){ - //设置作业人员信息 + //获取收货单信息,用于获取仓库ID + if (stockReceiptOrderDO.getReceiptOrderIds() != null && stockReceiptOrderDO.getReceiptOrderIds().size() > 0) { + StockReceiptOrderDO queryDO = new StockReceiptOrderDO(); + queryDO.setReceiptOrderId(stockReceiptOrderDO.getReceiptOrderIds().get(0)); + StockReceiptOrderPO stockReceiptOrderPO = stockReceiptOrderDomainService.getInfo(queryDO.getReceiptOrderId()); + if (stockReceiptOrderPO != null && stockReceiptOrderPO.getWarehouseId() != null) { + //查询该仓库绑定的用户ID列表 + AjaxResult ajaxResult = systemServiceFeign.queryListCorrelationId(stockReceiptOrderPO.getWarehouseId()); + if ("200".equals(String.valueOf(ajaxResult.get("code")))) { + List warehouseUserIds = JSON.parseArray(JSONUtil.toJsonStr(ajaxResult.get("data")), Long.class); + stockReceiptOrderDO.setWarehouseUserIds(warehouseUserIds); + } + } + } + //设置作业人员信息(会验证操作人员是否属于该仓库绑定的用户) operatorsParam(stockReceiptOrderDO); return stockReceiptOrderDomainService.taskDistribution(stockReceiptOrderDO); } @@ -313,6 +750,15 @@ public class StockReceiptOrderApplicationService { * @param stockReceiptOrderDO */ private void operatorsParam(StockReceiptOrderDO stockReceiptOrderDO){ + if (stockReceiptOrderDO.getOperatorsBy() == null) { + throw new ServiceException("操作人员不能为空"); + } + //如果指定了仓库绑定的用户列表,验证操作人员是否在该列表中 + if (stockReceiptOrderDO.getWarehouseUserIds() != null && !stockReceiptOrderDO.getWarehouseUserIds().isEmpty()) { + if (!stockReceiptOrderDO.getWarehouseUserIds().contains(stockReceiptOrderDO.getOperatorsBy())) { + throw new ServiceException("操作人员必须属于当前收货单对应仓库绑定的用户"); + } + } AjaxResult ajaxResult = userServiceFeign.getInfo(stockReceiptOrderDO.getOperatorsBy()); if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ throw new ServiceException("获取作业人员信息失败"); @@ -591,7 +1037,7 @@ public class StockReceiptOrderApplicationService { */ private void setMaterialMoreDetailInfo(ReceiptMaterialDetailDO receiptMaterialDetailDO){ - if(ObjectUtil.isNotNull(receiptMaterialDetailDO.getMaterialStatusCode())){ + if(ObjectUtil.isNotNull(receiptMaterialDetailDO.getMaterialStatusCode()) && StringUtils.isNotBlank(receiptMaterialDetailDO.getMaterialStatusCode())){ //翻译物料状态 AjaxResult materialsStatusResult = systemServiceFeign.selectListByDictType(DictCode.MATERIALS_STATUS.getCode()); if (!"200".equals(String.valueOf(materialsStatusResult.get("code")))) { @@ -645,6 +1091,9 @@ public class StockReceiptOrderApplicationService { * @param stockReceiptOrderDO */ private void setWarehouseInfo(StockReceiptOrderDO stockReceiptOrderDO) { + if (stockReceiptOrderDO.getWarehouseId() == null) { + throw new ServiceException("仓库ID不能为空"); + } AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(stockReceiptOrderDO.getWarehouseId()); if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ throw new ServiceException("获取仓库信息失败"); @@ -741,3 +1190,4 @@ public class StockReceiptOrderApplicationService { receiptMaterialDetailDO.setDistributeRuleName(materialGoodsRulePO.getRuleName()); } } + diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockShelfOrder/StockShelfOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockShelfOrder/StockShelfOrderApplicationService.java index e9e059efe..a88586bbd 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockShelfOrder/StockShelfOrderApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockShelfOrder/StockShelfOrderApplicationService.java @@ -3,9 +3,11 @@ package com.mhd.wms.application.service.stockShelfOrder; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSONObject; import com.mhd.common.core.constant.SnowFlakeConstants; +import com.mhd.common.core.domain.po.UserConfigSwitchPo; import com.mhd.common.core.domain.po.UserPo; import com.mhd.common.core.exception.ServiceException; import com.mhd.common.core.utils.IgnoreNullUtil; +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; @@ -17,6 +19,18 @@ 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.materialBaseInfo.entity.MaterialBaseInfo; +import com.mhd.wms.domain.materialBaseInfo.repository.mapper.MaterialBaseInfoMapper; +import com.mhd.wms.domain.materialBaseInfo.repository.po.MaterialBaseInfoPO; +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; +import com.mhd.wms.domain.materialGoodsRule.repository.po.MaterialGoodsRulePO; +import com.mhd.wms.domain.materialInventory.entity.MaterialInventory; +import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper; +import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO; +import com.mhd.system.api.domain.BatchDetailFeignPO; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import com.mhd.wms.domain.shelfMaterialDetail.repository.po.ShelfMaterialDetailPO; import com.mhd.wms.domain.shelfMaterialDetail.repository.todo.ShelfMaterialDetailDO; import com.mhd.wms.domain.shelfMaterialDetail.service.ShelfMaterialDetailDomainService; @@ -28,10 +42,16 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; +import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -54,6 +74,13 @@ public class StockShelfOrderApplicationService { private SystemServiceFeign systemServiceFeign; @Autowired private IdGenerator idGenerator; + @Autowired + private MaterialBaseInfoMapper materialBaseInfoMapper; + @Autowired + private MaterialInventoryMapper materialInventoryMapper; + @Autowired + private IMaterialGoodsRuleService materialGoodsRuleService; + /** @@ -67,8 +94,23 @@ public class StockShelfOrderApplicationService { if (topOrganizationId != null && topOrganizationId != 1){ stockShelfOrderDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); } - AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); - stockShelfOrderDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId()); + try { + AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid()); + if (associationWarehouseCacheDO != null) { + if (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) { + // 如果获取仓库信息失败,记录日志但不影响查询(允许查询所有仓库) + log.warn("获取用户关联仓库信息失败,将查询所有仓库数据,用户ID:{},错误:{}", loginUser.getUserid(), e.getMessage()); + } } return stockShelfOrderDomainService.queryList(stockShelfOrderDO); } @@ -101,7 +143,47 @@ public class StockShelfOrderApplicationService { */ public StockShelfOrderPO getInfo(Long shelfOrderId) { - return stockShelfOrderDomainService.getInfo(shelfOrderId); + StockShelfOrderPO stockShelfOrderPO = stockShelfOrderDomainService.getInfo(shelfOrderId); + ShelfMaterialDetailDO shelfMaterialDetailDO = new ShelfMaterialDetailDO(); + shelfMaterialDetailDO.setShelfOrderNumber(stockShelfOrderPO.getShelfOrderNumber()); + List shelfMaterialDetailPOList = shelfMaterialDetailDomainService.queryListChildren(shelfMaterialDetailDO); + + // 性能优化:批量获取批次属性,避免N+1查询问题 + // 1. 收集所有唯一的materialBaseInfoId + Set materialBaseInfoIdSet = shelfMaterialDetailPOList.stream() + .map(ShelfMaterialDetailPO::getMaterialBaseInfoId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + + // 2. 批量查询批次属性(使用Map缓存,避免重复查询相同的materialBaseInfoId) + Map> batchDetailMap = new HashMap<>(); + for (Long materialBaseInfoId : materialBaseInfoIdSet) { + try { + AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + List batchDetailFeignPOList = JSON.parseArray( + JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class); + if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) { + // 过滤isDisplay=1的属性 + List filteredList = batchDetailFeignPOList.stream() + .filter(batchDetail -> batchDetail.getIsDisplay() != null && batchDetail.getIsDisplay() == 1) + .collect(Collectors.toList()); + batchDetailMap.put(materialBaseInfoId, filteredList); + } + } + } catch (Exception e) { + log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + } + + // 3. 为每个物料明细设置更多属性(从缓存中获取),递归处理所有层级 + setMaterialMoreDetailListRecursively(shelfMaterialDetailPOList, batchDetailMap); + + stockShelfOrderPO.setMaterialDetailList(shelfMaterialDetailPOList); + log.info("返回上架单信息,shelfOrderId={}, materialDetailList大小={}", + stockShelfOrderPO.getShelfOrderId(), + shelfMaterialDetailPOList != null ? shelfMaterialDetailPOList.size() : 0); + return stockShelfOrderPO; } /** @@ -132,6 +214,7 @@ public class StockShelfOrderApplicationService { * @param stockReceiptOrderDO * @return Boolean */ + public Boolean upShelf(StockShelfOrderDO stockReceiptOrderDO){ //上架装配参数 StockShelfOrderDO assembleStockShelfOrderDO = assembleParamByShelf(stockReceiptOrderDO); @@ -168,6 +251,52 @@ public class StockShelfOrderApplicationService { } + private MaterialInventory getParam(ShelfMaterialDetailDO shelfMaterialDetailDO, List fieldNames,Long shipperId){ + MaterialInventory param = new MaterialInventory(); + param.setShipperId(shipperId); + param.setWarehouseId(shelfMaterialDetailDO.getWarehouseId()); + param.setMaterialBaseInfoId(shelfMaterialDetailDO.getMaterialBaseInfoId()); + param.setStorageSectionId(shelfMaterialDetailDO.getStorageSectionId()); + param.setStorageLocationId(shelfMaterialDetailDO.getStorageLocationId()); + param.setOrganizationId(shelfMaterialDetailDO.getOrganizationId()); + for (String fieldName : fieldNames) { + switch (fieldName) { + case "ext_attr_4": + param.setExtAttr4(shelfMaterialDetailDO.getExtAttr4()); + break; + case "ext_attr_3": + param.setExtAttr3(shelfMaterialDetailDO.getExtAttr3()); + break; + case "ext_attr_2": + param.setExtAttr2(shelfMaterialDetailDO.getExtAttr2()); + break; + case "ext_attr_1": + param.setExtAttr1(shelfMaterialDetailDO.getExtAttr1()); + break; + case "box_pallet_no": + param.setBoxPalletNo(shelfMaterialDetailDO.getBoxPalletNo()); + break; + case "sheet_ref_no": + param.setSheetRefNo(shelfMaterialDetailDO.getSheetRefNo()); + break; + case "batch_ref_no": + param.setBatchRefNo(shelfMaterialDetailDO.getBatchRefNo()); + break; + case "inventory_date": + param.setInventoryDate(shelfMaterialDetailDO.getInventoryDate()); + break; + case "expiry_date": + param.setExpiryDate(shelfMaterialDetailDO.getExpiryDate()); + break; + case "production_date": + param.setProductionDate(shelfMaterialDetailDO.getProductionDate()); + break; + } + } + return param; + } + + /** * @description 完成上架 * @author ZhouGY @@ -245,7 +374,7 @@ public class StockShelfOrderApplicationService { //设置上架信息 setStorageLocationInfo(shelfMaterialDetailDO); //设置容器信息 - setContainerInfo(shelfMaterialDetailDO); +// setContainerInfo(shelfMaterialDetailDO); //上架后 设置该记录不允许被修改 shelfMaterialDetailDO.setAllowModify(2); //未上过架 统计到当前收货单作业收货数 @@ -267,9 +396,9 @@ public class StockShelfOrderApplicationService { //设置上架信息 setStorageLocationInfo(shelfMaterialDetailDOChild); //设置容器信息 - setContainerInfo(returnShelfMaterialDetailDOChild); +// setContainerInfo(returnShelfMaterialDetailDOChild); //上架后 设置该记录不允许被修改 - shelfMaterialDetailDO.setAllowModify(2); + returnShelfMaterialDetailDOChild.setAllowModify(2); returnShelfMaterialDetailDOChild.setMaterialDetailSerialNumberList(shelfMaterialDetailDOChild.getMaterialDetailSerialNumberList()); returnShelfMaterialDetailDOChild.setUniqueId(idGenerator.snowflakeId(SnowFlakeConstants.wmsId)); returnShelfMaterialDetailDOChild.setLevel(2); @@ -281,6 +410,8 @@ public class StockShelfOrderApplicationService { } } returnShelfMaterialDetailDOChild.setMaterialDetailSerialNumberList(shelfMaterialDetailDO.getMaterialDetailSerialNumberList()); + //设置子项的实际数量(等于上架数量) + returnShelfMaterialDetailDOChild.setActualQuantity(returnShelfMaterialDetailDOChild.getShelvesQuantity()); returnShelfMaterialDetailDOChildList.add(returnShelfMaterialDetailDOChild); actualQuantity = actualQuantity.add(returnShelfMaterialDetailDOChild.getShelvesQuantity()); } @@ -326,20 +457,47 @@ public class StockShelfOrderApplicationService { * @param shelfMaterialDetailDO */ private void setStorageLocationInfo(ShelfMaterialDetailDO shelfMaterialDetailDO){ + if (shelfMaterialDetailDO.getStorageLocationId() == null || shelfMaterialDetailDO.getStorageLocationId() == 0) { + throw new ServiceException("库位ID不能为空或0"); + } AjaxResult storageLocationResult = systemServiceFeign.getStorageLocationInfoByStorageLocationId(shelfMaterialDetailDO.getStorageLocationId()); - if(!"200".equals(String.valueOf(storageLocationResult.get("code")))){ - throw new ServiceException("获取上架库位信息失败"); + if (storageLocationResult == null) { + throw new ServiceException("获取上架库位信息失败:返回结果为空"); + } + Object codeObj = storageLocationResult.get("code"); + if (codeObj == null || !"200".equals(String.valueOf(codeObj))) { + String errorMsg = storageLocationResult.get("msg") != null ? String.valueOf(storageLocationResult.get("msg")) : "未知错误"; + throw new ServiceException("获取上架库位信息失败,库位ID:" + shelfMaterialDetailDO.getStorageLocationId() + ",错误信息:" + errorMsg); + } + Object dataObj = storageLocationResult.get("data"); + if (dataObj == null) { + throw new ServiceException("获取上架库位信息失败:返回数据为空,库位ID:" + shelfMaterialDetailDO.getStorageLocationId()); + } + try { + String jsonString = JSONObject.toJSONString(dataObj); + if (jsonString == null || jsonString.trim().isEmpty() || "null".equals(jsonString)) { + throw new ServiceException("获取上架库位信息失败:数据序列化失败,库位ID:" + shelfMaterialDetailDO.getStorageLocationId()); + } + StorageLocationFeignPO storageLocationFeignPO = JSON.parseObject(jsonString, StorageLocationFeignPO.class); + if (storageLocationFeignPO == null) { + throw new ServiceException("获取上架库位信息失败:数据解析失败,库位ID:" + shelfMaterialDetailDO.getStorageLocationId()); + } + shelfMaterialDetailDO.setWarehouseId(storageLocationFeignPO.getWarehouseId()); + shelfMaterialDetailDO.setWarehouseCode(storageLocationFeignPO.getWarehouseCode()); + shelfMaterialDetailDO.setWarehouseName(storageLocationFeignPO.getWarehouseName()); + shelfMaterialDetailDO.setStorageSectionId(storageLocationFeignPO.getStorageSectionId()); + shelfMaterialDetailDO.setStorageCode(storageLocationFeignPO.getStorageCode()); + shelfMaterialDetailDO.setStorageName(storageLocationFeignPO.getStorageName()); + shelfMaterialDetailDO.setStorageLocationId(storageLocationFeignPO.getStorageLocationId()); + shelfMaterialDetailDO.setStorageLocationCode(storageLocationFeignPO.getStorageLocationCode()); + shelfMaterialDetailDO.setStorageLocationName(storageLocationFeignPO.getStorageLocationName()); + } catch (Exception e) { + log.error("解析库位信息失败,库位ID:{},错误:{}", shelfMaterialDetailDO.getStorageLocationId(), e.getMessage(), e); + if (e instanceof ServiceException) { + throw e; + } + throw new ServiceException("获取上架库位信息失败:数据解析异常,库位ID:" + shelfMaterialDetailDO.getStorageLocationId() + ",错误信息:" + e.getMessage()); } - StorageLocationFeignPO storageLocationFeignPO = JSON.parseObject(JSONObject.toJSONString(storageLocationResult.get("data")), StorageLocationFeignPO.class); - shelfMaterialDetailDO.setWarehouseId(storageLocationFeignPO.getWarehouseId()); - shelfMaterialDetailDO.setWarehouseCode(storageLocationFeignPO.getWarehouseCode()); - shelfMaterialDetailDO.setWarehouseName(storageLocationFeignPO.getWarehouseName()); - shelfMaterialDetailDO.setStorageSectionId(storageLocationFeignPO.getStorageSectionId()); - shelfMaterialDetailDO.setStorageCode(storageLocationFeignPO.getStorageCode()); - shelfMaterialDetailDO.setStorageName(storageLocationFeignPO.getStorageName()); - shelfMaterialDetailDO.setStorageLocationId(storageLocationFeignPO.getStorageLocationId()); - shelfMaterialDetailDO.setStorageLocationCode(storageLocationFeignPO.getStorageLocationCode()); - shelfMaterialDetailDO.setStorageLocationName(storageLocationFeignPO.getStorageLocationName()); } /** @@ -348,18 +506,18 @@ public class StockShelfOrderApplicationService { * @date 2024/5/23 14:03 * @param shelfMaterialDetailDO */ - private void setContainerInfo(ShelfMaterialDetailDO shelfMaterialDetailDO){ - - //获取容器详情 - AjaxResult ajaxResult = systemServiceFeign.getContainerInfoByContainerId(shelfMaterialDetailDO.getContainerId()); - if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ - throw new ServiceException("获取容器信息失败"); - } - ContainerFeignPO containerFeignPO = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), ContainerFeignPO.class); - shelfMaterialDetailDO.setContainerCode(containerFeignPO.getContainerCode()); - shelfMaterialDetailDO.setContainerType(containerFeignPO.getContainerType()); - shelfMaterialDetailDO.setContainerTypeName(containerFeignPO.getContainerTypeName()); - } +// private void setContainerInfo(ShelfMaterialDetailDO shelfMaterialDetailDO){ +// +// //获取容器详情 +// AjaxResult ajaxResult = systemServiceFeign.getContainerInfoByContainerId(shelfMaterialDetailDO.getContainerId()); +// if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ +// throw new ServiceException("获取容器信息失败"); +// } +// ContainerFeignPO containerFeignPO = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), ContainerFeignPO.class); +// shelfMaterialDetailDO.setContainerCode(containerFeignPO.getContainerCode()); +// shelfMaterialDetailDO.setContainerType(containerFeignPO.getContainerType()); +// shelfMaterialDetailDO.setContainerTypeName(containerFeignPO.getContainerTypeName()); +// } /** * @description 判断上架数量是否存在超收 @@ -378,4 +536,299 @@ public class StockShelfOrderApplicationService { return 2; } } -} + + /** + * 递归为物料明细设置更多属性 + * @param shelfMaterialDetailPOList 物料明细列表 + * @param batchDetailMap 批次属性Map + */ + private void setMaterialMoreDetailListRecursively(List shelfMaterialDetailPOList, + Map> batchDetailMap) { + if (CollectionUtils.isEmpty(shelfMaterialDetailPOList)) { + return; + } + + shelfMaterialDetailPOList.forEach(shelfMaterialDetailPO -> { + Long materialBaseInfoId = shelfMaterialDetailPO.getMaterialBaseInfoId(); + + // 只保留isDisplay=1的批次属性(从batchDetailMap中获取,已经过滤过了) + // 创建新的materialMoreDetailList,只包含isDisplay=1的属性 + List materialMoreDetailList = new ArrayList<>(); + + // 创建batchDetailId到MaterialMoreDetailPO的映射,用于快速查找已有的属性值 + Map batchDetailIdToMaterialMoreDetailMap = new HashMap<>(); + List existingList = shelfMaterialDetailPO.getMaterialMoreDetailList(); + if (!CollectionUtils.isEmpty(existingList)) { + for (MaterialMoreDetailPO existing : existingList) { + if (existing.getBatchDetailId() != null) { + batchDetailIdToMaterialMoreDetailMap.put(existing.getBatchDetailId(), existing); + } + } + } + + if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) { + List batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId); + // 用于跟踪已添加到列表中的batchDetailId + Set addedBatchDetailIds = new HashSet<>(); + + for (BatchDetailFeignPO batchDetailFeignPO : batchDetailFeignPOList) { + MaterialMoreDetailPO materialMoreDetailPO = batchDetailIdToMaterialMoreDetailMap.get(batchDetailFeignPO.getBatchDetailId()); + + // 如果不存在,创建新的 + if (materialMoreDetailPO == null) { + materialMoreDetailPO = new MaterialMoreDetailPO(); + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + } else { + // 如果已存在,更新属性(保留已有的attributeValue) + materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId()); + materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels()); + materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl()); + materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat()); + materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption()); + materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark()); + } + + // 确保添加到列表中(使用batchDetailId来避免重复) + Long batchDetailId = batchDetailFeignPO.getBatchDetailId(); + if (batchDetailId != null && !addedBatchDetailIds.contains(batchDetailId)) { + materialMoreDetailList.add(materialMoreDetailPO); + addedBatchDetailIds.add(batchDetailId); + } + + // 根据fieldName或batchLabels从物料明细中获取对应的字段值 + if (shelfMaterialDetailPO != null) { + String fieldValue = null; + String usedFieldName = null; + // 优先使用fieldName(如果存在) + if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) { + usedFieldName = batchDetailFeignPO.getFieldName(); + fieldValue = getFieldValueByFieldName(shelfMaterialDetailPO, usedFieldName); + log.info("批次属性 batchDetailId={}, fieldName={}, 获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue); + } + // 如果fieldName为空,尝试根据batchLabels映射到字段名 + else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) { + String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels()); + if (StringUtils.isNotBlank(fieldNameByLabel)) { + usedFieldName = fieldNameByLabel; + fieldValue = getFieldValueByFieldName(shelfMaterialDetailPO, usedFieldName); + log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 获取到的值={}", + batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(), + usedFieldName, fieldValue); + } + } + // 只有当获取到值时才更新attributeValue(避免覆盖已有的值) + if (fieldValue != null) { + materialMoreDetailPO.setAttributeValue(fieldValue); + log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}", + materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(), + materialMoreDetailPO.getAttributeValue()); + } + } + } + } + shelfMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList); + log.info("物料明细 uniqueId={}, materialBaseInfoId={}, materialMoreDetailList大小={}", + shelfMaterialDetailPO.getUniqueId(), shelfMaterialDetailPO.getMaterialBaseInfoId(), + materialMoreDetailList != null ? materialMoreDetailList.size() : 0); + + // 递归处理子集 + if (!CollectionUtils.isEmpty(shelfMaterialDetailPO.getChildren())) { + setMaterialMoreDetailListRecursively(shelfMaterialDetailPO.getChildren(), batchDetailMap); + } + }); + } + + /** + * 根据批次标签(batchLabels)映射到字段名 + * @param batchLabel 批次标签 + * @return 字段名,如果找不到映射则返回null + */ + private String getFieldNameByBatchLabel(String batchLabel) { + if (StringUtils.isBlank(batchLabel)) { + return null; + } + + // 批次标签到字段名的映射关系 + // 可以根据实际业务需求扩展这个映射表 + Map labelToFieldNameMap = new HashMap<>(); + labelToFieldNameMap.put("Invoice No.", "invoiceNo"); + labelToFieldNameMap.put("Invoice No", "invoiceNo"); + labelToFieldNameMap.put("发票号", "invoiceNo"); + labelToFieldNameMap.put("Batch Ref NO's", "batchRefNo"); + labelToFieldNameMap.put("Batch Ref NO", "batchRefNo"); + labelToFieldNameMap.put("批次参考号", "batchRefNo"); + labelToFieldNameMap.put("Sheet Ref NO's", "sheetRefNo"); + labelToFieldNameMap.put("Sheet Ref NO", "sheetRefNo"); + labelToFieldNameMap.put("单据参考号", "sheetRefNo"); + labelToFieldNameMap.put("箱号/卡板号", "boxPalletNo"); + labelToFieldNameMap.put("箱号", "boxPalletNo"); + labelToFieldNameMap.put("卡板号", "boxPalletNo"); + labelToFieldNameMap.put("申报数量", "declaredQuantity"); + labelToFieldNameMap.put("申报单位", "declarationUnit"); + labelToFieldNameMap.put("原产国", "originCountry"); + labelToFieldNameMap.put("币制", "currency"); + labelToFieldNameMap.put("单位", "unit"); + labelToFieldNameMap.put("升", "liter"); + labelToFieldNameMap.put("尺寸", "dimensions"); + labelToFieldNameMap.put("箱数", "boxCount"); + labelToFieldNameMap.put("件数", "pieceCount"); + labelToFieldNameMap.put("入库数量", "inboundQuantity"); + labelToFieldNameMap.put("总净重", "totalNetWeight"); + labelToFieldNameMap.put("总毛重", "totalGrossWeight"); + labelToFieldNameMap.put("总体积", "totalVolume"); + labelToFieldNameMap.put("总面积", "totalArea"); + labelToFieldNameMap.put("总价", "totalPrice"); + + // 精确匹配 + String fieldName = labelToFieldNameMap.get(batchLabel.trim()); + if (StringUtils.isNotBlank(fieldName)) { + return fieldName; + } + + // 模糊匹配(包含关系) + for (Map.Entry entry : labelToFieldNameMap.entrySet()) { + if (batchLabel.contains(entry.getKey()) || entry.getKey().contains(batchLabel)) { + return entry.getValue(); + } + } + + // 如果找不到映射,尝试将批次标签转换为驼峰命名(简单处理) + // 例如:"Invoice No." -> "invoiceNo" + return convertLabelToFieldName(batchLabel); + } + + /** + * 将批次标签转换为字段名(驼峰命名) + * @param label 批次标签 + * @return 字段名 + */ + private String convertLabelToFieldName(String label) { + if (StringUtils.isBlank(label)) { + return null; + } + + // 移除特殊字符,转换为小写,用空格或特殊字符分割 + String cleaned = label.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5\\s]", " ") + .trim() + .toLowerCase(); + + // 如果是中文,无法自动转换,返回null + if (cleaned.matches(".*[\\u4e00-\\u9fa5].*")) { + return null; + } + + // 将空格分割的单词转换为驼峰命名 + String[] words = cleaned.split("\\s+"); + if (words.length == 0) { + return null; + } + + StringBuilder fieldName = new StringBuilder(words[0]); + for (int i = 1; i < words.length; i++) { + if (words[i].length() > 0) { + fieldName.append(words[i].substring(0, 1).toUpperCase()) + .append(words[i].substring(1)); + } + } + + return fieldName.toString(); + } + + /** + * 根据字段名从对象中获取字段值(使用反射) + * @param obj 对象 + * @param fieldName 字段名 + * @return 字段值(转换为字符串) + */ + private String getFieldValueByFieldName(Object obj, String fieldName) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return null; + } + + try { + // 兼容:如果传的是下划线命名(数据库列名风格),先转成驼峰字段名再取 + // 例如:box_pallet_no -> boxPalletNo + String normalizedFieldName = fieldName; + if (normalizedFieldName.contains("_")) { + normalizedFieldName = snakeToCamel(normalizedFieldName); + } + + // 获取对象的Class + Class clazz = obj.getClass(); + + // 尝试获取字段(包括父类字段) + Field field = null; + Class currentClass = clazz; + while (currentClass != null && field == null) { + try { + field = currentClass.getDeclaredField(normalizedFieldName); + } catch (NoSuchFieldException e) { + currentClass = currentClass.getSuperclass(); + } + } + + if (field == null) { + log.warn("字段不存在:{}(normalized:{}),对象类型:{}", fieldName, normalizedFieldName, clazz.getName()); + return null; + } + + // 设置可访问 + field.setAccessible(true); + + // 获取字段值 + Object value = field.get(obj); + + // 转换为字符串 + if (value == null) { + log.info("字段 {} 的值为 null,对象类型:{}", normalizedFieldName, clazz.getName()); + return null; + } + + String result; + // 处理日期类型字段 + if (value instanceof Date) { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd"); + result = sdf.format((Date) value); + } else { + result = value.toString(); + } + + log.info("通过反射获取字段值成功,字段名:{}(原始:{}),值:{},对象类型:{}", + normalizedFieldName, fieldName, result, clazz.getName()); + return result; + } catch (Exception e) { + log.warn("通过反射获取字段值失败,字段名:{},对象类型:{},错误:{}", fieldName, obj.getClass().getName(), e.getMessage()); + return null; + } + } + + private String snakeToCamel(String snake) { + if (StringUtils.isBlank(snake)) { + return null; + } + String s = snake.trim().toLowerCase(); + StringBuilder sb = new StringBuilder(); + boolean upperNext = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '_') { + upperNext = true; + continue; + } + if (upperNext) { + sb.append(Character.toUpperCase(c)); + upperNext = false; + } else { + sb.append(c); + } + } + return sb.toString(); + } +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/repository/persistence/DeliveTaskImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/repository/persistence/DeliveTaskImpl.java index 992200e6f..f8556e414 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/repository/persistence/DeliveTaskImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/repository/persistence/DeliveTaskImpl.java @@ -1,5 +1,6 @@ package com.mhd.wms.domain.deliveTask.repository.persistence; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.mhd.common.core.domain.dto.NoticeMessageLoggingDto; import com.mhd.common.core.enums.MessageTypeEnum; @@ -8,17 +9,35 @@ import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.SystemServiceFeign; import com.mhd.system.api.model.LoginUser; +import com.mhd.wms.application.service.pickingOrder.PickingOrderApplicationService; +import com.mhd.wms.application.service.stockOutOrder.StockOutOrderApplicationService; import com.mhd.wms.domain.deliveTask.entity.DeliveTask; import com.mhd.wms.domain.deliveTask.repository.facade.IDeliveTaskService; import com.mhd.wms.domain.deliveTask.repository.mapper.DeliveTaskMapper; import com.mhd.wms.domain.deliveTask.repository.po.DeliveTaskPO; import com.mhd.wms.domain.deliveTask.repository.po.DeliveTaskSumPO; import com.mhd.wms.domain.deliveTask.repository.todo.DeliveTaskDO; +import com.mhd.wms.domain.handoverTaskOrder.entity.HandoverTaskOrder; +import com.mhd.wms.domain.handoverTaskOrder.repository.facade.IHandoverTaskOrderService; +import com.mhd.wms.domain.pickingOrder.repository.facade.IPickingOrderService; +import com.mhd.wms.domain.pickingOrder.repository.po.PickingOrderPO; +import com.mhd.wms.domain.pickingOrder.repository.todo.PickingOrderDO; +import com.mhd.wms.domain.stockOutOrder.entity.StockOutOrder; +import com.mhd.wms.domain.stockOutOrder.repository.facade.IStockOutOrderService; +import com.mhd.wms.domain.stockOutOrder.repository.po.StockOutOrderPO; +import com.mhd.wms.domain.stockOutOrder.repository.todo.StockOutOrderDO; +import com.mhd.wms.interfaces.assember.pickingOrder.PickingOrderAssembler; +import com.mhd.wms.interfaces.assember.stockOutOrder.StockOutOrderAssembler; +import com.mhd.wms.interfaces.dto.pickingOrder.PickingOrderDTO; +import com.mhd.wms.interfaces.dto.stockOutOrder.StockOutOrderDTO; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import javax.annotation.Resource; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -35,6 +54,26 @@ public class DeliveTaskImpl extends ServiceImpl im private DeliveTaskMapper deliveTaskMapper; @Autowired private SystemServiceFeign systemServiceFeign; + + @Autowired + private IHandoverTaskOrderService handoverTaskOrderService; + + @Autowired + private IPickingOrderService pickingOrderService; + + @Resource + private PickingOrderAssembler pickingOrderAssembler; + + @Lazy + @Autowired + private StockOutOrderApplicationService stockOutOrderApplicationService; + + @Resource + private StockOutOrderAssembler stockOutOrderAssembler; + + @Autowired + private IStockOutOrderService stockOutOrderService; + /** * 查询下发任务列表 */ @@ -55,8 +94,51 @@ public class DeliveTaskImpl extends ServiceImpl im }else{ } - return deliveTaskMapper.queryListApp(deliveTaskDO); + List deliveTaskPOS = deliveTaskMapper.queryListApp(deliveTaskDO); + if (deliveTaskDO.getTaskType() == 7){ + statistics(deliveTaskPOS); + } + return deliveTaskPOS; } + + //关联查询物料种类 + private void statistics(List deliveTaskPOS) { + for (DeliveTaskPO deliveTaskPO : deliveTaskPOS) { + String trackingNumber = deliveTaskPO.getTrackingNumber(); + HandoverTaskOrder handoverTaskOrder = handoverTaskOrderService.getOne(new LambdaQueryWrapper() + .eq(HandoverTaskOrder::getTaskNumber, trackingNumber)); + String orderNumber = handoverTaskOrder.getOrderNumber();//出库单号 + PickingOrderDTO pickingOrderDTO = new PickingOrderDTO(); + pickingOrderDTO.setOrderNumber(orderNumber); + PickingOrderDO pickingOrderDO = pickingOrderAssembler.toDO(pickingOrderDTO); + PickingOrderPO pickingOrderPOS = pickingOrderService.queryList(pickingOrderDO).get(0); + if (pickingOrderPOS != null){ + Integer materialQuantity = pickingOrderPOS.getMaterialQuantity();//物料种类数 + BigDecimal pickingQuantity = pickingOrderPOS.getPickingQuantity();//已拣货数量 + deliveTaskPO.setMaterialQuantity(materialQuantity); + deliveTaskPO.setPickingQuantity(pickingQuantity); + } + StockOutOrderDTO stockOutOrderDTO = new StockOutOrderDTO(); + stockOutOrderDTO.setOutOrderNumber(orderNumber); + StockOutOrderDO stockOutOrderDO = stockOutOrderAssembler.toDO(stockOutOrderDTO); + StockOutOrderPO checkInfo = null; + try { + checkInfo = stockOutOrderApplicationService.getCheckInfo(stockOutOrderDO); + BigDecimal checkQuantity = checkInfo.getCheckQuantity();//复核数量 + deliveTaskPO.setCheckQuantity(checkQuantity); + } catch (Exception e) { + } + StockOutOrder stockOutOrder = stockOutOrderService.getOne(new LambdaQueryWrapper() + .eq(StockOutOrder::getOutOrderNumber, orderNumber)); + if (stockOutOrder != null){ + deliveTaskPO.setOutOrderNumber(stockOutOrder.getOutOrderNumber()); + deliveTaskPO.setOutOrderStatus(stockOutOrder.getStatus()); + deliveTaskPO.setShipperName(stockOutOrder.getShipperName()); + deliveTaskPO.setCarrier(stockOutOrder.getCarrier()); + } + } + } + /** * 新增下发任务 */ diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/repository/po/DeliveTaskPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/repository/po/DeliveTaskPO.java index 2e233188b..b3b24c13a 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/repository/po/DeliveTaskPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/repository/po/DeliveTaskPO.java @@ -7,6 +7,7 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import java.math.BigDecimal; import java.util.Date; @@ -115,4 +116,25 @@ public class DeliveTaskPO extends BaseVOEntity { @Excel(name = "是否下发 0-否 1-是") private Integer taskSum; + @ApiModelProperty("物料种类数") + private Integer materialQuantity; + + @ApiModelProperty("拣货数量") + private BigDecimal pickingQuantity; + + @ApiModelProperty("复核数量") + private BigDecimal checkQuantity; + + @ApiModelProperty("出库单号") + private String outOrderNumber; + + @ApiModelProperty("出库状态: 1-已创建 2-已审核 3-部分分配 4-已分配 5-波次中 6-拣货中 7-拣货完成 8-复核中 9-已出库 10-已取消 11-已关闭") + private Integer outOrderStatus; + + @ApiModelProperty("货主名称") + private String shipperName; + + @ApiModelProperty("承运商") + private String carrier; + } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/repository/todo/DeliveTaskDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/repository/todo/DeliveTaskDO.java index c880530f8..8da01aba6 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/repository/todo/DeliveTaskDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/repository/todo/DeliveTaskDO.java @@ -56,8 +56,8 @@ public class DeliveTaskDO extends BaseVOEntity { @Excel(name = "仓库名称") private String warehouseName; - @ApiModelProperty("任务类型 0-无 1-收货 2-上架 3-拣货 4-复核 5-移位 6-盘点") - @Excel(name = "任务类型 0-无 1-收货 2-上架 3-拣货 4-复核 5-移位 6-盘点") + @ApiModelProperty("任务类型 0-无 1-收货 2-上架 3-拣货 4-复核 5-移位 6-盘点 7-交接作业单") + @Excel(name = "任务类型 0-无 1-收货 2-上架 3-拣货 4-复核 5-移位 6-盘点 7-交接作业单") private Integer taskType; @ApiModelProperty("任务状态 0-未接收 1-已接收 2-已拒绝 3-已完成 4-已关闭") diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/service/DeliveTaskDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/service/DeliveTaskDomainService.java index d4e99c3fe..ecc412453 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/service/DeliveTaskDomainService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/deliveTask/service/DeliveTaskDomainService.java @@ -1,6 +1,7 @@ package com.mhd.wms.domain.deliveTask.service; import com.mhd.common.core.exception.ServiceException; +import com.mhd.common.core.utils.bean.BeanUtils; import com.mhd.wms.domain.deliveTask.entity.DeliveTask; import com.mhd.wms.domain.deliveTask.factorys.DeliveTaskServiceFactory; import com.mhd.wms.domain.deliveTask.repository.facade.IDeliveTaskService; @@ -114,4 +115,13 @@ public class DeliveTaskDomainService { public DeliveTaskPO querySum(DeliveTaskDO deliveTaskDO) { return deliveTaskService.querySum(deliveTaskDO); } + + /** + * 根据id修改 + */ + public Boolean updateById(DeliveTaskDO deliveTaskDO) { + DeliveTask deliveTask = new DeliveTask(); + BeanUtils.copyProperties(deliveTaskDO, deliveTask); + return deliveTaskService.updateById(deliveTask); + } } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/entity/HandoverTaskOrder.java b/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/entity/HandoverTaskOrder.java index a16cbc689..f9e2b4e5b 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/entity/HandoverTaskOrder.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/entity/HandoverTaskOrder.java @@ -125,5 +125,16 @@ public class HandoverTaskOrder extends BaseVOEntity { @Excel(name = "备注") private String remark; + @ApiModelProperty("任务是否下发: 1-是 2-否") + @Excel(name = "任务是否下发: 1-是 2-否") + private Integer taskDistribution; + + @ApiModelProperty("任务下发时间") + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "任务下发时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date taskDistributionTime; + + @ApiModelProperty("app上传的图片") + private String pictureApp; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/facade/IHandoverTaskOrderService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/facade/IHandoverTaskOrderService.java index 4c6826611..74eb0284a 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/facade/IHandoverTaskOrderService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/facade/IHandoverTaskOrderService.java @@ -40,4 +40,6 @@ public interface IHandoverTaskOrderService extends IService * 查询交接作业单 */ public HandoverTaskOrderPO getInfo(Long outTaskOrderId); + + boolean taskDistribution(HandoverTaskOrderDO handoverTaskOrderDO); } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/persistence/HandoverTaskOrderImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/persistence/HandoverTaskOrderImpl.java index de919fd5e..d89cf45fc 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/persistence/HandoverTaskOrderImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/persistence/HandoverTaskOrderImpl.java @@ -1,16 +1,22 @@ package com.mhd.wms.domain.handoverTaskOrder.repository.persistence; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.model.LoginUser; import com.mhd.wms.domain.handoverTaskOrder.entity.HandoverTaskOrder; import com.mhd.wms.domain.handoverTaskOrder.repository.facade.IHandoverTaskOrderService; import com.mhd.wms.domain.handoverTaskOrder.repository.mapper.HandoverTaskOrderMapper; import com.mhd.wms.domain.handoverTaskOrder.repository.po.HandoverTaskOrderPO; import com.mhd.wms.domain.handoverTaskOrder.repository.todo.HandoverTaskOrderDO; +import com.mhd.wms.domain.shiftManage.entity.ShiftManage; +import com.mhd.wms.domain.shiftManage.repository.todo.ShiftManageDO; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.ArrayList; +import java.util.Date; import java.util.List; /** @@ -78,4 +84,19 @@ public class HandoverTaskOrderImpl extends ServiceImpl().lambda() + .in(HandoverTaskOrder::getHandoverTaskOrderId, handoverTaskOrderDO.getHandoverTaskOrderIds())); + return i > 0; + } + } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/po/HandoverTaskOrderPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/po/HandoverTaskOrderPO.java index e8e86272c..d374c2b34 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/po/HandoverTaskOrderPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/po/HandoverTaskOrderPO.java @@ -124,6 +124,7 @@ public class HandoverTaskOrderPO extends BaseVOEntity { @Excel(name = "备注") private String remark; - + @ApiModelProperty("app上传的图片") + private String pictureApp; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/todo/HandoverTaskOrderDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/todo/HandoverTaskOrderDO.java index 3d89bd667..04f91dd83 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/todo/HandoverTaskOrderDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/repository/todo/HandoverTaskOrderDO.java @@ -131,4 +131,15 @@ public class HandoverTaskOrderDO extends BaseVOEntity { @ApiModelProperty("交接作业单id") private List handoverTaskOrderIds; + + @ApiModelProperty("作业人用户ID") + @Excel(name = "作业人用户ID") + private Long operatorsBy; + + @ApiModelProperty("作业人姓名") + @Excel(name = "作业人姓名") + private String operatorsName; + + @ApiModelProperty("app上传的图片") + private String pictureApp; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/service/HandoverTaskOrderDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/service/HandoverTaskOrderDomainService.java index 9513e558c..08eaf146a 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/service/HandoverTaskOrderDomainService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/handoverTaskOrder/service/HandoverTaskOrderDomainService.java @@ -1,16 +1,38 @@ package com.mhd.wms.domain.handoverTaskOrder.service; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.mhd.common.core.exception.ServiceException; +import com.mhd.common.core.utils.OrderSequence; +import com.mhd.common.core.utils.bean.BeanUtils; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.model.LoginUser; +import com.mhd.wms.domain.deliveTask.repository.facade.IDeliveTaskService; +import com.mhd.wms.domain.deliveTask.repository.todo.DeliveTaskDO; import com.mhd.wms.domain.handoverTaskOrder.entity.HandoverTaskOrder; import com.mhd.wms.domain.handoverTaskOrder.repository.facade.IHandoverTaskOrderService; import com.mhd.wms.domain.handoverTaskOrder.repository.po.HandoverTaskOrderPO; import com.mhd.wms.domain.handoverTaskOrder.repository.todo.HandoverTaskOrderDO; +import com.mhd.wms.domain.inventoryAdjustmentRecord.entity.InventoryAdjustmentRecord; +import com.mhd.wms.domain.inventoryAdjustmentRecord.repository.mapper.InventoryAdjustmentRecordMapper; +import com.mhd.wms.domain.materialInventory.entity.MaterialInventory; +import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper; +import com.mhd.wms.domain.outMaterialDetail.entity.OutMaterialDetail; +import com.mhd.wms.domain.outMaterialDetail.repository.mapper.OutMaterialDetailMapper; +import com.mhd.wms.domain.shiftManage.repository.po.ShiftManagePO; +import com.mhd.wms.domain.shiftManage.repository.todo.ShiftManageDO; +import com.mhd.wms.domain.stockOutOrder.entity.StockOutOrder; +import com.mhd.wms.domain.stockOutOrder.repository.mapper.StockOutOrderMapper; +import com.mhd.wms.domain.stockOutOrder.repository.po.StockOutOrderPO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -26,6 +48,16 @@ public class HandoverTaskOrderDomainService { @Autowired private IHandoverTaskOrderService handoverTaskOrderService; + @Autowired + private MaterialInventoryMapper materialInventoryMapper; + @Autowired + private OutMaterialDetailMapper outMaterialDetailMapper; + @Autowired + private InventoryAdjustmentRecordMapper inventoryAdjustmentRecordMapper; + @Autowired + private StockOutOrderMapper stockOutOrderMapper; + @Autowired + private IDeliveTaskService deliveTaskService; /** @@ -117,8 +149,14 @@ public class HandoverTaskOrderDomainService { * @param handoverTaskOrderDO * @return Boolean */ - public Boolean completeHandover(HandoverTaskOrderDO handoverTaskOrderDO){ + public Boolean completeHandover(HandoverTaskOrderDO handoverTaskOrderDO) { + List handoverTaskOrderIds = handoverTaskOrderDO.getHandoverTaskOrderIds(); + if (handoverTaskOrderIds == null || handoverTaskOrderIds.size() == 0) { + return false; + } LoginUser loginUser = SecurityUtils.getLoginUser(); + //修改库存 + xgkc(handoverTaskOrderIds,loginUser); return handoverTaskOrderService.update(null, new UpdateWrapper().lambda() .set(HandoverTaskOrder::getStatus, 2) .set(HandoverTaskOrder::getUpdateBy, loginUser.getUserid()) @@ -127,4 +165,159 @@ public class HandoverTaskOrderDomainService { .in(HandoverTaskOrder::getHandoverTaskOrderId, handoverTaskOrderDO.getHandoverTaskOrderIds()) ); } -} + + public synchronized void xgkc(List handoverTaskOrderIds,LoginUser loginUser) { + for (Long handoverTaskOrderId : handoverTaskOrderIds) { + HandoverTaskOrder handoverTaskOrder = handoverTaskOrderService.getById(handoverTaskOrderId); + if (handoverTaskOrder == null) { + return; + } + //交接完成节点修改库存 + String orderNumber = handoverTaskOrder.getOrderNumber(); + StockOutOrder stockOutOrder = stockOutOrderMapper.selectOne(new QueryWrapper().lambda() + .eq(StockOutOrder::getOutOrderNumber, orderNumber)); + List outMaterialDetailList = outMaterialDetailMapper.selectList(new QueryWrapper().lambda() + .eq(OutMaterialDetail::getOutOrderNumber, orderNumber)); + for (OutMaterialDetail outMaterialDetail : outMaterialDetailList) { + Long materialInventoryId = outMaterialDetail.getMaterialInventoryId(); + BigDecimal checkQuantity = outMaterialDetail.getCheckQuantity(); + BigDecimal checkArea = outMaterialDetail.getCheckArea(); + BigDecimal checkVolume = outMaterialDetail.getCheckVolume(); + BigDecimal checkGrossWeight = outMaterialDetail.getCheckGrossWeight(); + BigDecimal checkNetWeight = outMaterialDetail.getCheckNetWeight(); + + // 初始化检查数据,避免空指针 + checkQuantity = checkQuantity != null ? checkQuantity : BigDecimal.ZERO; + checkArea = checkArea != null ? checkArea : BigDecimal.ZERO; + checkVolume = checkVolume != null ? checkVolume : BigDecimal.ZERO; + checkGrossWeight = checkGrossWeight != null ? checkGrossWeight : BigDecimal.ZERO; + checkNetWeight = checkNetWeight != null ? checkNetWeight : BigDecimal.ZERO; + + MaterialInventory materialInventoryPO = materialInventoryMapper.selectById(materialInventoryId); + if (materialInventoryPO != null) { + //更新库存数量 + //库存数量 + BigDecimal oldInventoryQuantity = materialInventoryPO.getInventoryQuantity(); + //冻结数量 + BigDecimal oldFreezeQuantity = materialInventoryPO.getFreezeQuantity(); + //分配后库存数量 + 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(); + BigDecimal newArea = oldArea.subtract(checkArea); + BigDecimal newVolume = oldVolume.subtract(checkVolume); + BigDecimal newGrossWeight = oldGrossWeight.subtract(checkGrossWeight); + BigDecimal newNetWeight = oldNetWeight.subtract(checkNetWeight); + + materialInventoryPO.setInventoryQuantity(newInventoryQuantity); + materialInventoryPO.setFreezeQuantity(newFreezeQuantity); + materialInventoryPO.setArea(newArea); + materialInventoryPO.setVolume(newVolume); + materialInventoryPO.setGrossWeight(newGrossWeight); + materialInventoryPO.setNetWeight(newNetWeight); + MaterialInventory materialInventory = new MaterialInventory(); + BeanUtils.copyProperties(materialInventoryPO, materialInventory); + materialInventoryMapper.updateById(materialInventory); + + //库存调整记录 + InventoryAdjustmentRecord inventoryAdjustmentRecord = new InventoryAdjustmentRecord(); + inventoryAdjustmentRecord.setAdjustAfterStatusCode("he_ge"); + inventoryAdjustmentRecord.setAdjustBeforeStatusCode("he_ge"); + inventoryAdjustmentRecord.setAdjustAfterStatusName("合格"); + inventoryAdjustmentRecord.setAdjustBeforeStatusName("合格"); + inventoryAdjustmentRecord.setMaterialBaseInfoId(materialInventoryPO.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setMaterialCode(outMaterialDetail.getMaterialNo()); + inventoryAdjustmentRecord.setMaterialName(outMaterialDetail.getCommodityName()); + inventoryAdjustmentRecord.setBarCode(outMaterialDetail.getBarCode()); + inventoryAdjustmentRecord.setMaterialBaseInfoId(outMaterialDetail.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setAdjustType(1L); + inventoryAdjustmentRecord.setOrganizationId(stockOutOrder.getOrganizationId()); + inventoryAdjustmentRecord.setOrganizationName(stockOutOrder.getOrganizationName()); + inventoryAdjustmentRecord.setTopOrganizationId(stockOutOrder.getTopOrganizationId()); + inventoryAdjustmentRecord.setWarehouseCode(stockOutOrder.getWarehouseCode()); + inventoryAdjustmentRecord.setWarehouseName(stockOutOrder.getWarehouseName()); + inventoryAdjustmentRecord.setWarehouseId(stockOutOrder.getWarehouseId()); + inventoryAdjustmentRecord.setStorageCode(materialInventoryPO.getStorageCode()); + inventoryAdjustmentRecord.setStorageName(materialInventoryPO.getStorageName()); + inventoryAdjustmentRecord.setStorageLocationId(materialInventoryPO.getStorageLocationId()); + inventoryAdjustmentRecord.setStorageLocationCode(materialInventoryPO.getStorageLocationCode()); + inventoryAdjustmentRecord.setStorageLocationName(materialInventoryPO.getStorageLocationName()); + inventoryAdjustmentRecord.setMaterialInventoryId(materialInventoryPO.getMaterialInventoryId()); + inventoryAdjustmentRecord.setMaterialBaseInfoId(materialInventoryPO.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setShipperId(stockOutOrder.getShipperId()); + inventoryAdjustmentRecord.setShipperName(stockOutOrder.getShipperName()); + inventoryAdjustmentRecord.setStorageSectionId(materialInventoryPO.getStorageSectionId()); + inventoryAdjustmentRecord.setStorageLocationId(materialInventoryPO.getStorageLocationId()); + inventoryAdjustmentRecord.setCreateBy(loginUser.getUserid()); + inventoryAdjustmentRecord.setCreateByName(loginUser.getUsername()); + inventoryAdjustmentRecord.setCreateTime(new Date()); + inventoryAdjustmentRecord.setAllocationAfterQuantity(materialInventoryPO.getAllocationQuantity()); + inventoryAdjustmentRecord.setAllocationBeforeQuantity(materialInventoryPO.getAllocationQuantity()); + inventoryAdjustmentRecord.setFreezeBeforeQuantity(oldFreezeQuantity); + inventoryAdjustmentRecord.setFreezeAfterQuantity(newFreezeQuantity); + inventoryAdjustmentRecord.setInventoryBeforeQuantity(oldInventoryQuantity); + inventoryAdjustmentRecord.setInventoryAfterQuantity(newInventoryQuantity); + inventoryAdjustmentRecord.setCreateBy(loginUser.getUserid()); + inventoryAdjustmentRecord.setCreateByName(loginUser.getUsername()); + inventoryAdjustmentRecord.setCreateTime(new Date()); + inventoryAdjustmentRecordMapper.insert(inventoryAdjustmentRecord); + } + } + } + } + + + /** + * @description 任务下发 + */ + @Transactional(rollbackFor = Exception.class) + public boolean taskDistribution(HandoverTaskOrderDO handoverTaskOrderDO) { + List handoverTaskOrders = handoverTaskOrderService.list(new LambdaQueryWrapper() + .in(HandoverTaskOrder::getHandoverTaskOrderId, handoverTaskOrderDO.getHandoverTaskOrderIds()) + .eq(HandoverTaskOrder::getTaskDistribution, 2) + ); + if (CollectionUtils.isEmpty(handoverTaskOrders)) { + throw new ServiceException("作业单不存在或已下发,请重新选择"); + } + //交付生成下发任务 + genDeliveTask(handoverTaskOrders, handoverTaskOrderDO); + return handoverTaskOrderService.taskDistribution(handoverTaskOrderDO); + } + + private void genDeliveTask(List handoverTaskOrders, HandoverTaskOrderDO handoverTaskOrderDO) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + List deliveTaskDOList = new ArrayList<>(); + for (HandoverTaskOrder handoverTaskOrder : handoverTaskOrders) { + DeliveTaskDO deliveTaskDO = new DeliveTaskDO(); + deliveTaskDO.setOrganizationId(loginUser.getUserPo().getOrganizationId()); + deliveTaskDO.setOrganizationName(loginUser.getUserPo().getOrganizationName()); + deliveTaskDO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); + deliveTaskDO.setTaskNumber(OrderSequence.getOrderCode("RW")); + deliveTaskDO.setTrackingNumber(handoverTaskOrder.getTaskNumber()); + deliveTaskDO.setWarehouseId(handoverTaskOrder.getWarehouseId()); + deliveTaskDO.setWarehouseCode(handoverTaskOrder.getWarehouseCode()); + deliveTaskDO.setWarehouseName(handoverTaskOrder.getWarehouseName()); + deliveTaskDO.setTaskType(7); + deliveTaskDO.setTaskDistribution(1); + deliveTaskDO.setTaskDistributionId(loginUser.getUserid()); + deliveTaskDO.setTaskDistributionName(loginUser.getUsername()); + deliveTaskDO.setTaskDistributionTime(new Date()); + deliveTaskDO.setOperatorsBy(handoverTaskOrderDO.getOperatorsBy()); + deliveTaskDO.setOperatorsName(handoverTaskOrderDO.getOperatorsName()); + deliveTaskDO.setCreateBy(loginUser.getUserid()); + deliveTaskDO.setCreateByName(loginUser.getUsername()); + deliveTaskDO.setCreateTime(new Date()); + deliveTaskDOList.add(deliveTaskDO); + } + deliveTaskService.batchInsert(deliveTaskDOList); + } + + + +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/entity/InMaterialDetail.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/entity/InMaterialDetail.java index 9f0cfe107..e62a67ce7 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/entity/InMaterialDetail.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/entity/InMaterialDetail.java @@ -251,4 +251,89 @@ public class InMaterialDetail extends BaseVOEntity { @ApiModelProperty("越库类型:1-直接越库 2-分拨越库") @Excel(name = "越库类型:1-直接越库 2-分拨越库") private Long overStockType; + + // ========== 报关相关明细字段 ========== + @ApiModelProperty("规格型号") + @Excel(name = "规格型号/ITEM") + private String specificationModel; + + @ApiModelProperty("SKU码") + @Excel(name = "SKU码") + private String skuCode; + + @ApiModelProperty("Invoice No.") + @Excel(name = "Invoice No.") + private String invoiceNo; + + @ApiModelProperty("升") + @Excel(name = "升") + private BigDecimal liter; + + @ApiModelProperty("尺寸") + @Excel(name = "尺寸") + private String dimensions; + + @ApiModelProperty("申报单位") + @Excel(name = "申报单位") + private String declarationUnit; + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("原产国") + @Excel(name = "原产国") + private String originCountry; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("币制") + @Excel(name = "币制") + private String currency; + + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unit; + + @ApiModelProperty("申报数量") + @Excel(name = "申报数量") + private BigDecimal declaredQuantity; + + @ApiModelProperty("箱数") + @Excel(name = "箱数") + private BigDecimal boxCount; + + @ApiModelProperty("件数") + @Excel(name = "件数") + private BigDecimal pieceCount; + + @ApiModelProperty("入库数量(输入大于等于0的数字,可以为小数)") + @Excel(name = "入库数量") + private BigDecimal inboundQuantity; + + @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; + + @ApiModelProperty("总价") + @Excel(name = "总价") + private BigDecimal totalPrice; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/repository/persistence/InMaterialDetailImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/repository/persistence/InMaterialDetailImpl.java index e920c49bc..d02e44bbc 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/repository/persistence/InMaterialDetailImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/repository/persistence/InMaterialDetailImpl.java @@ -168,23 +168,49 @@ public class InMaterialDetailImpl extends ServiceImpl inMaterialDetailDbList = inMaterialDetailMapper.selectList(new QueryWrapper().lambda().eq(InMaterialDetail::getInOrderNumber, inMaterialDetailBaseDO.getInOrderNumber())); + // 查询所有记录(包括已删除的),用于判断是否需要恢复已删除的记录 + List inMaterialDetailDbAllList = inMaterialDetailMapper.selectList(new QueryWrapper().lambda() + .eq(InMaterialDetail::getInOrderNumber, inMaterialDetailBaseDO.getInOrderNumber())); + // 查询未删除的记录,用于正常的更新逻辑 + List inMaterialDetailDbList = inMaterialDetailDbAllList.stream() + .filter(item -> item.getDelFlag() != null && item.getDelFlag() == 1) + .collect(Collectors.toList()); Map materialDetailMap = inMaterialDetailDbList.stream().collect(Collectors.toMap(InMaterialDetail::getMaterialDetailId, Function.identity())); + // 查询已删除的记录,用于恢复逻辑 + Map materialDetailDeletedMap = inMaterialDetailDbAllList.stream() + .filter(item -> item.getDelFlag() != null && item.getDelFlag() == 2) + .collect(Collectors.toMap(InMaterialDetail::getMaterialDetailId, Function.identity())); //批量新增或修改物料信息 List inMaterialDetailList = new ArrayList<>(); //需要修改的物流明细 List materialDetailIdsByUpdate = new ArrayList<>(); for (InMaterialDetailDO inMaterialDetailDO : inMaterialDetailDOList){ //判断是否需要修改 - InMaterialDetail inMaterialDetail = materialDetailMap.get(inMaterialDetailDO.getMaterialDetailId()); + InMaterialDetail inMaterialDetail = null; + if (inMaterialDetailDO.getMaterialDetailId() != null) { + // 先查找未删除的记录 + inMaterialDetail = materialDetailMap.get(inMaterialDetailDO.getMaterialDetailId()); + // 如果未删除的记录中找不到,检查是否在已删除的记录中 + if (inMaterialDetail == null) { + InMaterialDetail deletedDetail = materialDetailDeletedMap.get(inMaterialDetailDO.getMaterialDetailId()); + if (deletedDetail != null) { + // 恢复已删除的记录 + inMaterialDetail = deletedDetail; + inMaterialDetail.setDelFlag(1); // 恢复记录 + } + } + } if (inMaterialDetail == null){ + // 新增明细:清空 materialDetailId,让数据库自动生成 inMaterialDetail = new InMaterialDetail(); BeanUtils.copyProperties(inMaterialDetailDO, inMaterialDetail); + inMaterialDetail.setMaterialDetailId(null); // 清空ID,确保新增 inMaterialDetail.setUniqueId(idGenerator.snowflakeId(SnowFlakeConstants.wmsId)); inMaterialDetail.setInOrderNumber(inMaterialDetailBaseDO.getInOrderNumber()); inMaterialDetail.setOrganizationId(inMaterialDetailBaseDO.getOrganizationId()); inMaterialDetail.setOrganizationName(inMaterialDetailBaseDO.getOrganizationName()); inMaterialDetail.setTopOrganizationId(inMaterialDetailBaseDO.getTopOrganizationId()); + inMaterialDetail.setDelFlag(1); // 确保新增记录的delFlag为1 }else { BeanUtils.copyProperties(inMaterialDetailDO, inMaterialDetail); inMaterialDetail.setUpdateBy(loginUser.getUserid()); diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/repository/po/InMaterialDetailPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/repository/po/InMaterialDetailPO.java index 050894b61..86affc133 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/repository/po/InMaterialDetailPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/repository/po/InMaterialDetailPO.java @@ -10,6 +10,8 @@ import lombok.Data; import java.math.BigDecimal; import java.util.List; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; /** @@ -263,4 +265,120 @@ public class InMaterialDetailPO extends StockInOrderBasePO { @Excel(name = "越库类型:1-直接越库 2-分拨越库") private Long overStockType; + // ========== 报关相关明细字段 ========== + @ApiModelProperty("规格型号") + @Excel(name = "规格型号/ITEM") + private String specificationModel; + + @ApiModelProperty("SKU码") + @Excel(name = "SKU码") + private String skuCode; + + @ApiModelProperty("Invoice No.") + @Excel(name = "Invoice No.") + private String invoiceNo; + + @ApiModelProperty("升") + @Excel(name = "升") + private BigDecimal liter; + + @ApiModelProperty("尺寸") + @Excel(name = "尺寸") + private String dimensions; + + @ApiModelProperty("申报单位") + @Excel(name = "申报单位") + private String declarationUnit; + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("原产国") + @Excel(name = "原产国") + private String originCountry; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("币制") + @Excel(name = "币制") + private String currency; + + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unit; + + @ApiModelProperty("申报数量") + @Excel(name = "申报数量") + private BigDecimal declaredQuantity; + + @ApiModelProperty("箱数") + @Excel(name = "箱数") + private BigDecimal boxCount; + + @ApiModelProperty("件数") + @Excel(name = "件数") + private BigDecimal pieceCount; + + @ApiModelProperty("入库数量") + @Excel(name = "入库数量") + private BigDecimal inboundQuantity; + + @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; + + @ApiModelProperty("总价") + @Excel(name = "总价") + private BigDecimal totalPrice; + + @ApiModelProperty("生产日期") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date productionDate; + + @ApiModelProperty("过期日期") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date inventoryDate; + + @ApiModelProperty("扩展属性1") + @Excel(name = "扩展属性1") + private String extAttr1; + + @ApiModelProperty("扩展属性2") + @Excel(name = "扩展属性2") + private String extAttr2; + + @ApiModelProperty("扩展属性3") + @Excel(name = "扩展属性3") + private String extAttr3; + + @ApiModelProperty("扩展属性4") + @Excel(name = "扩展属性4") + private String extAttr4; + } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/repository/todo/InMaterialDetailDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/repository/todo/InMaterialDetailDO.java index 785b6dbde..3b6142704 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/repository/todo/InMaterialDetailDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/repository/todo/InMaterialDetailDO.java @@ -258,4 +258,89 @@ public class InMaterialDetailDO extends StockInOrderBaseDO { @ApiModelProperty("入库单号集合") @Excel(name = "入库单号集合") private List inOrderNumberList; + + // ========== 报关相关明细字段 ========== + @ApiModelProperty("规格型号(选择物料后自动带出,不可编辑)") + @Excel(name = "规格型号/ITEM") + private String specificationModel; + + @ApiModelProperty("SKU码(选择物料后自动带出,不可编辑)") + @Excel(name = "SKU码") + private String skuCode; + + @ApiModelProperty("Invoice No.") + @Excel(name = "Invoice No.") + private String invoiceNo; + + @ApiModelProperty("升(输入大于等于0的数字,可以为小数)") + @Excel(name = "升") + private BigDecimal liter; + + @ApiModelProperty("尺寸") + @Excel(name = "尺寸") + private String dimensions; + + @ApiModelProperty("申报单位") + @Excel(name = "申报单位") + private String declarationUnit; + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("原产国") + @Excel(name = "原产国") + private String originCountry; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("币制") + @Excel(name = "币制") + private String currency; + + @ApiModelProperty("单位(数据字典下拉选择框)") + @Excel(name = "单位") + private String unit; + + @ApiModelProperty("申报数量(输入大于等于0的数字,可以为小数)") + @Excel(name = "申报数量") + private BigDecimal declaredQuantity; + + @ApiModelProperty("箱数(输入大于等于0的数字,可以为小数)") + @Excel(name = "箱数") + private BigDecimal boxCount; + + @ApiModelProperty("件数(输入大于等于0的数字,可以为小数)") + @Excel(name = "件数") + private BigDecimal pieceCount; + + @ApiModelProperty("入库数量(输入大于等于0的数字,可以为小数)") + @Excel(name = "ruku数量") + private BigDecimal inboundQuantity; + + @ApiModelProperty("总净重(KG)(输入大于等于0的数字,可以为小数)") + @Excel(name = "总净重(KG)") + private BigDecimal totalNetWeight; + + @ApiModelProperty("总毛重(KG)(输入大于等于0的数字,可以为小数)") + @Excel(name = "总毛重(KG)") + private BigDecimal totalGrossWeight; + + @ApiModelProperty("总体积(CBM)(输入大于等于0的数字,可以为小数)") + @Excel(name = "总体积(CBM)") + private BigDecimal totalVolume; + + @ApiModelProperty("总面积(SQM)(输入大于等于0的数字,可以为小数)") + @Excel(name = "总面积(SQM)") + private BigDecimal totalArea; + + @ApiModelProperty("总价(输入大于等于0的数字,可以为小数)") + @Excel(name = "总价") + private BigDecimal totalPrice; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/repository/persistence/InOrderAbnormalImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/repository/persistence/InOrderAbnormalImpl.java index 3205327d8..329da5028 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/repository/persistence/InOrderAbnormalImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/repository/persistence/InOrderAbnormalImpl.java @@ -143,7 +143,7 @@ public class InOrderAbnormalImpl extends ServiceImpl inOrderAbnormalList = new ArrayList<>(); for (ShelfMaterialDetail shelfMaterialDetail : shelfMaterialDetailList){ //上架 - if (shelfMaterialDetail.getShelvesQuantity().compareTo(shelfMaterialDetail.getQuantity()) != 0){ + if (shelfMaterialDetail.getShelvesQuantity().compareTo(shelfMaterialDetail.getQuantity()) != 0&&shelfMaterialDetail.getLevel() == 1){ //判断是否存在异常 根据设置的是否允许超收 取值动态赋值 先默认写死 收货异常 InOrderAbnormal inOrderAbnormal = new InOrderAbnormal(); //赋值基础数据 @@ -151,12 +151,12 @@ public class InOrderAbnormalImpl extends ServiceImpl 0){ + if (shelfMaterialDetail.getAlreadyShelvesQuantity().compareTo(shelfMaterialDetail.getQuantity()) > 0){ //上架数量大于收货数量 inOrderAbnormal.setAbnormalType(1); inOrderAbnormal.setActualQuantity(shelfMaterialDetail.getShelvesQuantity()); inOrderAbnormal.setAbnormalReason("上架数量大于收货数量"); - }else if (shelfMaterialDetail.getShelvesQuantity().compareTo(shelfMaterialDetail.getQuantity()) < 0){ + }else if (shelfMaterialDetail.getAlreadyShelvesQuantity().compareTo(shelfMaterialDetail.getQuantity()) < 0){ //上架数量小于收货数量 inOrderAbnormal.setAbnormalType(1); inOrderAbnormal.setActualQuantity(shelfMaterialDetail.getShelvesQuantity()); @@ -261,4 +261,4 @@ public class InOrderAbnormalImpl extends ServiceImpl materialMoreDetailList; -} +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/investigationManage/repository/persistence/InvestigationManageImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/investigationManage/repository/persistence/InvestigationManageImpl.java index d2e5f66e5..738d92dd5 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/investigationManage/repository/persistence/InvestigationManageImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/investigationManage/repository/persistence/InvestigationManageImpl.java @@ -138,7 +138,39 @@ public class InvestigationManageImpl extends ServiceImpl detailLambdaQueryWrapper = new LambdaQueryWrapper() + .eq(InvestigetionManageDetail::getInvestigationNumber, investigationManage.getInvestigationNumber()) + .notIn(InvestigetionManageDetail::getInvestigationManageDetailId, ids); + investigetionManageDetailService.remove(detailLambdaQueryWrapper); +// investigetionManageDetailService.delete(ids); + List updateList = investigetionManageDetailList.stream().filter(detail -> + detail.getInvestigationManageDetailId() != null).collect(Collectors.toList()); + investigetionManageDetailService.updateBatchById(updateList); + + List saveList = investigetionManageDetailList.stream() + .filter(detail -> detail.getInvestigationManageDetailId() == null) + .collect(Collectors.toList()); + LoginUser loginUser = SecurityUtils.getLoginUser(); + UserPo userPo = loginUser.getUserPo(); + saveList.forEach(e -> { + e.setWarehouseCode(e.getWarehouseCode()); + e.setWarehouseId(e.getWarehouseId()); + e.setWarehouseName(e.getWarehouseName()); + e.setOrganizationId(userPo.getOrganizationId()); + e.setOrganizationName(userPo.getOrganizationName()); + e.setTopOrganizationId(userPo.getTopOrganizationId()); + e.setCreateByName(loginUser.getUsername()); + e.setCreateBy(loginUser.getUserid()); + e.setCreateTime(new Date()); + e.setUpdateByName(loginUser.getUsername()); + e.setUpdateBy(loginUser.getUserid()); + e.setUpdateTime(new Date()); + e.setInvestigationNumber(investigationManage.getInvestigationNumber()); + e.setInvestigationFrequency(1); + InvestigetionManageDetailDO investigetionManageDetailDO = new InvestigetionManageDetailDO(); + BeanUtils.copyProperties(e, investigetionManageDetailDO); + investigetionManageDetailService.insert(investigetionManageDetailDO); + }); return this.updateById(investigationManage); } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/investigetionManageDetail/repository/po/InvestigetionManageDetailPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/investigetionManageDetail/repository/po/InvestigetionManageDetailPO.java index ccae1e974..c3252dfac 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/investigetionManageDetail/repository/po/InvestigetionManageDetailPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/investigetionManageDetail/repository/po/InvestigetionManageDetailPO.java @@ -1,12 +1,15 @@ package com.mhd.wms.domain.investigetionManageDetail.repository.po; +import com.baomidou.mybatisplus.annotation.TableField; import com.mhd.common.core.annotation.Excel; import com.mhd.common.core.web.domain.BaseVOEntity; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; +import java.util.List; /** @@ -204,5 +207,8 @@ public class InvestigetionManageDetailPO extends BaseVOEntity { @Excel(name = "物料状态名称") private String materialStatusName; + @ApiModelProperty("更多属性明细列表") + @TableField(exist = false) + private List materialMoreDetailList; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialBaseInfo/entity/MaterialBaseInfo.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialBaseInfo/entity/MaterialBaseInfo.java index d953bb484..de3f47c7f 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/materialBaseInfo/entity/MaterialBaseInfo.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialBaseInfo/entity/MaterialBaseInfo.java @@ -169,4 +169,31 @@ public class MaterialBaseInfo extends BaseVOEntity { @ApiModelProperty("是否公用: 1-是 2-否") @Excel(name = "是否公用: 1-是 2-否") private Integer common; + + @ApiModelProperty("SKU码") + private String skuCode; + + @ApiModelProperty("单价") + private BigDecimal unitPrice; + + @ApiModelProperty("币制") + private String currency; + + @ApiModelProperty("原产国") + private String originCountry; + + @ApiModelProperty("HS码") + private String hsCode; + + @ApiModelProperty("申报单位") + private String declarationUnit; + + @ApiModelProperty("法定单位") + private String statutoryUnit; + + @ApiModelProperty("法定第二单位") + private String statutorySecondUnit; + + @ApiModelProperty("规格型号") + private String specificationModel; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialBaseInfo/repository/po/MaterialBaseInfoPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialBaseInfo/repository/po/MaterialBaseInfoPO.java index baf2d61d2..f92066b5a 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/materialBaseInfo/repository/po/MaterialBaseInfoPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialBaseInfo/repository/po/MaterialBaseInfoPO.java @@ -70,15 +70,21 @@ public class MaterialBaseInfoPO extends BaseVOEntity { private String barCode; @ApiModelProperty("物料分类编码") - @Excel(name = "物料分类编码") @TableField(typeHandler = ListTypeHandler.class) private List materialClassifyCode; @ApiModelProperty("物料分类名称") - @Excel(name = "物料分类名称") @TableField(typeHandler = ListTypeHandler.class) private List materialClassifyName; + @ApiModelProperty("物料分类编码(导出用,逗号分隔)") + @Excel(name = "物料分类编码") + private String materialClassifyCodeStr; + + @ApiModelProperty("物料分类名称(导出用,逗号分隔)") + @Excel(name = "物料分类名称") + private String materialClassifyNameStr; + @ApiModelProperty("物料种类编码 数据字典") @Excel(name = "物料种类编码 数据字典") private String materialType; @@ -189,4 +195,32 @@ public class MaterialBaseInfoPO extends BaseVOEntity { @Excel(name = "是否公用: 1-是 2-否") private Integer common; + + @ApiModelProperty("SKU码") + private String skuCode; + + @ApiModelProperty("单价") + private BigDecimal unitPrice; + + @ApiModelProperty("币制") + private String currency; + + @ApiModelProperty("原产国") + private String originCountry; + + @ApiModelProperty("HS码") + private String hsCode; + + @ApiModelProperty("申报单位") + private String declarationUnit; + + @ApiModelProperty("法定单位") + private String statutoryUnit; + + @ApiModelProperty("法定第二单位") + private String statutorySecondUnit; + + @ApiModelProperty("规格型号") + private String specificationModel; + } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialBaseInfo/repository/todo/MaterialBaseInfoDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialBaseInfo/repository/todo/MaterialBaseInfoDO.java index 9d9d2b6c8..ccb2fe5b9 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/materialBaseInfo/repository/todo/MaterialBaseInfoDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialBaseInfo/repository/todo/MaterialBaseInfoDO.java @@ -187,4 +187,31 @@ public class MaterialBaseInfoDO extends BaseVOEntity { @ApiModelProperty("是否公用: 1-是 2-否") @Excel(name = "是否公用: 1-是 2-否") private Integer common; + + @ApiModelProperty("SKU码") + private String skuCode; + + @ApiModelProperty("单价") + private BigDecimal unitPrice; + + @ApiModelProperty("币制") + private String currency; + + @ApiModelProperty("原产国") + private String originCountry; + + @ApiModelProperty("HS码") + private String hsCode; + + @ApiModelProperty("申报单位") + private String declarationUnit; + + @ApiModelProperty("法定单位") + private String statutoryUnit; + + @ApiModelProperty("法定第二单位") + private String statutorySecondUnit; + + @ApiModelProperty("规格型号") + private String specificationModel; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialGoodsRule/repository/po/BatchDetailPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialGoodsRule/repository/po/BatchDetailPO.java new file mode 100644 index 000000000..8cbcb93f9 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialGoodsRule/repository/po/BatchDetailPO.java @@ -0,0 +1,69 @@ +package com.mhd.wms.domain.materialGoodsRule.repository.po; + +import com.mhd.common.core.annotation.Excel; +import lombok.Data; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import com.mhd.common.core.web.domain.BaseVOEntity; + + +/** + * 批次管理详情对象 batch_detail + * + * @author gen + * @date 2024-05-07 + */ + +@Data +@ApiModel(value = "批次管理详情对象", description = "批次管理详情响应对象") +public class BatchDetailPO extends BaseVOEntity{ + private static final long serialVersionUID = 1L; + + @ApiModelProperty("批次管理详情id") + private Long batchDetailId; + + @ApiModelProperty("组织表ID") + @Excel(name = "组织表ID") + private Long organizationId; + + @ApiModelProperty("组织名称") + @Excel(name = "组织名称") + private String organizationName; + + @ApiModelProperty("一级组织表ID") + @Excel(name = "一级组织表ID") + private Long topOrganizationId; + + @ApiModelProperty("批次id") + @Excel(name = "批次id") + private Long batchId; + + @ApiModelProperty("批次标签") + @Excel(name = "批次标签") + private String batchLabels; + + @ApiModelProperty("字段名称") + @Excel(name = "字段名称") + private String fieldName; + + @ApiModelProperty("输入控制: 1-必填 2-可选") + @Excel(name = "输入控制: 1-必填 2-可选") + private String inputControl; + + @ApiModelProperty("属性格式:1-下拉框 2-日期 3-日期时间 4-数字 5-文本") + @Excel(name = "属性格式:1-下拉框 2-日期 3-日期时间 4-数字 5-文本") + private String attributeFormat; + + @ApiModelProperty("属性选项") + @Excel(name = "属性选项") + private String attributeOption; + + @ApiModelProperty("是否显示: 0-不显示 1-显示") + @Excel(name = "是否显示: 0-不显示 1-显示") + private Integer isDisplay; + + @ApiModelProperty("备注") + @Excel(name = "备注") + private String remark; + +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialGoodsRule/repository/po/BatchPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialGoodsRule/repository/po/BatchPO.java new file mode 100644 index 000000000..c5c53b4f1 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialGoodsRule/repository/po/BatchPO.java @@ -0,0 +1,66 @@ +package com.mhd.wms.domain.materialGoodsRule.repository.po; + + + +import com.mhd.common.core.annotation.Excel; +import lombok.Data; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.List; + +import com.mhd.common.core.web.domain.BaseVOEntity; + + +/** + * 批次管理对象 batch + * + * @author gen + * @date 2024-05-07 + */ + +@Data +@ApiModel(value = "批次管理对象", description = "批次管理响应对象") +public class BatchPO extends BaseVOEntity{ + private static final long serialVersionUID = 1L; + + @ApiModelProperty("批次id") + private Long batchId; + + @ApiModelProperty("组织表ID") + @Excel(name = "组织表ID") + private Long organizationId; + + @ApiModelProperty("组织名称") + @Excel(name = "组织名称") + private String organizationName; + + @ApiModelProperty("一级组织表ID") + @Excel(name = "一级组织表ID") + private Long topOrganizationId; + + @ApiModelProperty("批次编码") + @Excel(name = "批次编码") + private String batchCode; + + @ApiModelProperty("批次名称") + @Excel(name = "批次名称") + private String batchName; + + @ApiModelProperty("备注") + @Excel(name = "备注") + private String remark; + + @ApiModelProperty("启用状态: 1-启用 2-停用") + @Excel(name = "启用状态: 1-启用 2-停用") + private Integer openingUp; + + @ApiModelProperty("是否作废: 1-否 2-是") + @Excel(name = "是否作废: 1-否 2-是") + private Integer nullify; + + @ApiModelProperty("批次明细集合") + private List batchDetailList; + + + +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialGoodsRule/service/MaterialGoodsRuleDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialGoodsRule/service/MaterialGoodsRuleDomainService.java index aea259173..5002bdd30 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/materialGoodsRule/service/MaterialGoodsRuleDomainService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialGoodsRule/service/MaterialGoodsRuleDomainService.java @@ -67,10 +67,10 @@ public class MaterialGoodsRuleDomainService { } //封装批次信息 batchParam(materialGoodsRuleDO); - //封装库区信息 - storageSectionParam(materialGoodsRuleDO); - //封装库位信息 - storageLocationParam(materialGoodsRuleDO); +// //封装库区信息 +// storageSectionParam(materialGoodsRuleDO); +// //封装库位信息 +// storageLocationParam(materialGoodsRuleDO); return materialGoodsRuleService.update(materialGoodsRuleDO); } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/entity/MaterialInventory.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/entity/MaterialInventory.java index 81de5c78f..ffe3c401c 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/entity/MaterialInventory.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/entity/MaterialInventory.java @@ -1,13 +1,17 @@ package com.mhd.wms.domain.materialInventory.entity; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; import com.mhd.common.core.annotation.Excel; import com.mhd.common.core.web.domain.BaseVOEntity; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; +import java.util.Date; /** @@ -41,6 +45,18 @@ public class MaterialInventory extends BaseVOEntity { @Excel(name = "物料基础信息id") private Long materialBaseInfoId; + @ApiModelProperty("货主ID") + @Excel(name = "货主ID") + private Long shipperId; + + @ApiModelProperty("货主编码") + @Excel(name = "货主编码") + private String shipperCode; + + @ApiModelProperty("货主名称") + @Excel(name = "货主名称") + private String shipperName; + @ApiModelProperty("上架单物料明细id") @Excel(name = "上架单物料明细id") private Long materialDetailId; @@ -129,5 +145,82 @@ public class MaterialInventory extends BaseVOEntity { @Excel(name = "盘点是否可用:0-禁用 1-可用") private Integer isAble; + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unit; -} + @ApiModelProperty("单位名称") + @Excel(name = "单位名称") + private String unitName; + + @ApiModelProperty("净重(KG)") + @Excel(name = "净重(KG)") + private BigDecimal netWeight; + + @ApiModelProperty("毛重(KG)") + @Excel(name = "毛重(KG)") + private BigDecimal grossWeight; + + @ApiModelProperty("体积") + @Excel(name = "体积") + private BigDecimal volume; + + @ApiModelProperty("面积") + @Excel(name = "面积") + private BigDecimal area; + + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("扩展字段1") + @Excel(name = "扩展字段1") + @TableField("ext_attr_1") + private String extAttr1; + + @ApiModelProperty("扩展字段2") + @Excel(name = "扩展字段2") + @TableField("ext_attr_2") + private String extAttr2; + + @ApiModelProperty("生产日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date productionDate; + + @ApiModelProperty("过期日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date inventoryDate; + + @ApiModelProperty("ExtAttr3") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr3", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("ext_attr_3") + private Date extAttr3; + + @ApiModelProperty("ExtAttr4") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr4", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("ext_attr_4") + private Date extAttr4; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/mapper/MaterialInventoryMapper.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/mapper/MaterialInventoryMapper.java index d576d1d8a..a333dd8a8 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/mapper/MaterialInventoryMapper.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/mapper/MaterialInventoryMapper.java @@ -23,10 +23,16 @@ import java.util.List; */ public interface MaterialInventoryMapper extends BaseMapper { - /** - * 查询物料库存列表 - */ + //查全部 public List queryList(MaterialInventoryDO materialInventoryDO); + //查物料库存列表-物料/库位 + public List queryListByWlKw(MaterialInventoryDO materialInventoryDO); + //查物料库存列表-库位 + public List queryListByKw(MaterialInventoryDO materialInventoryDO); + //查物料库存列表-物料 + public List queryListByWl(MaterialInventoryDO materialInventoryDO); + //查物料库存列表-货主 + public List queryListByHz(MaterialInventoryDO materialInventoryDO); /** * @description 批量增加库存 @@ -86,4 +92,13 @@ public interface MaterialInventoryMapper extends BaseMapper MaterialInventoryPO selectOneByWhere(MaterialInventoryDO materialInventoryDO); -} + + List selectListByWhere(MaterialInventory materialInventory); + + /** + * 根据库存ID查询库存信息(包含批次属性字段) + * @param materialInventoryId 库存ID + * @return 库存信息 + */ + MaterialInventoryPO selectByIdWithBatchAttributes(@Param("materialInventoryId") Long materialInventoryId); +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/persistence/MaterialInventoryImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/persistence/MaterialInventoryImpl.java index 93bb64ce4..f6573dbbf 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/persistence/MaterialInventoryImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/persistence/MaterialInventoryImpl.java @@ -14,6 +14,9 @@ import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryQuery import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryDO; import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryParentDO; import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryQueryListDO; +import com.mhd.wms.domain.materialBaseInfo.repository.facade.IMaterialBaseInfoService; +import com.mhd.wms.domain.materialBaseInfo.repository.po.MaterialBaseInfoPO; +import com.mhd.wms.domain.materialBaseInfo.repository.todo.MaterialBaseInfoDO; import com.mhd.wms.domain.statementStatistics.po.ImmediateInventoryPO; import com.mhd.wms.domain.statementStatistics.todo.ImmediateInventoryDO; import org.springframework.beans.BeanUtils; @@ -24,6 +27,7 @@ import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.util.*; +import java.util.stream.Collectors; /** * 物料库存Service业务层处理 @@ -35,6 +39,8 @@ import java.util.*; public class MaterialInventoryImpl extends ServiceImpl implements IMaterialInventoryService{ @Autowired private MaterialInventoryMapper materialInventoryMapper; + @Autowired + private IMaterialBaseInfoService materialBaseInfoService; /** * 查询物料库存列表 @@ -42,7 +48,21 @@ public class MaterialInventoryImpl extends ServiceImpl queryList(MaterialInventoryDO materialInventoryDO) { - return materialInventoryMapper.queryList(materialInventoryDO); + String queryRule = materialInventoryDO.getQueryRule(); + if ("hz".equals(queryRule)) { + return materialInventoryMapper.queryListByHz(materialInventoryDO); + } else if ("wl".equals(queryRule)) { + return materialInventoryMapper.queryListByWl(materialInventoryDO); + } else if ("kw".equals(queryRule)) { + return materialInventoryMapper.queryListByKw(materialInventoryDO); + } else if ("wlkw".equals(queryRule)) { + return materialInventoryMapper.queryListByWlKw(materialInventoryDO); + } else if ("all".equals(queryRule)) { + return materialInventoryMapper.queryList(materialInventoryDO); + } else { + //不传返回全部 + return materialInventoryMapper.queryList(materialInventoryDO); + } } /** @@ -133,50 +153,145 @@ public class MaterialInventoryImpl extends ServiceImpl materialInventoryDOList) { LoginUser loginUser = SecurityUtils.getLoginUser(); + // 需要新增的库存记录(库位+物料+货主 维度) List materialInventoryList = new ArrayList<>(); - List materialInventoryDOListByUpdate = new ArrayList<>(); + // 需要更新的库存记录,按 materialInventoryId 聚合(同一库存只能更新一次,否则 CASE WHEN 只认第一条) + Map materialInventoryDOMapByUpdate = new HashMap<>(); + // 当前本次 add 操作内,用于合并同一库位+物料+货主 的新增记录 Map materialInventoryAddNowMap = new HashMap<>(); - for (MaterialInventoryDO materialInventoryDO : materialInventoryDOList) { - //TODO 若数据量升级 后期优化 - MaterialInventory materialInventoryDb = materialInventoryMapper.selectOne(new QueryWrapper().lambda() - .eq(MaterialInventory::getStorageSectionId, materialInventoryDO.getStorageSectionId()) - .eq(MaterialInventory::getMaterialBaseInfoId, materialInventoryDO.getMaterialBaseInfoId()) - .eq(MaterialInventory::getBatchNumber, materialInventoryDO.getBatchNumber()) - .eq(MaterialInventory::getContainerId, materialInventoryDO.getContainerId())); - if (ObjectUtil.isNull(materialInventoryDb)){ - String key = materialInventoryDO.getStorageLocationId() + "_" + materialInventoryDO.getMaterialBaseInfoId() - + "_" + materialInventoryDO.getBatchNumber() + "_" + materialInventoryDO.getMaterialStatusCode(); - if (ObjectUtil.isNotNull(materialInventoryDO.getContainerId())){ - key = key + "_" + materialInventoryDO.getContainerId(); + + // 批量获取物料基础信息,以获取货主ID(用于查询和key生成) + Map materialBaseInfoIdToShipperIdMap = new HashMap<>(); + if (!CollectionUtils.isEmpty(materialInventoryDOList)) { + Set materialBaseInfoIds = new HashSet<>(); + for (MaterialInventoryDO materialInventoryDO : materialInventoryDOList) { + if (materialInventoryDO.getMaterialBaseInfoId() != null) { + materialBaseInfoIds.add(materialInventoryDO.getMaterialBaseInfoId()); } + } + // 批量查询物料基础信息,获取货主ID + for (Long materialBaseInfoId : materialBaseInfoIds) { + try { + MaterialBaseInfoDO materialBaseInfoDO = new MaterialBaseInfoDO(); + materialBaseInfoDO.setMaterialBaseInfoId(materialBaseInfoId); + List materialBaseInfoList = materialBaseInfoService.queryList(materialBaseInfoDO); + if (!CollectionUtils.isEmpty(materialBaseInfoList)) { + MaterialBaseInfoPO materialBaseInfoPO = materialBaseInfoList.get(0); + if (materialBaseInfoPO.getShipperId() != null) { + materialBaseInfoIdToShipperIdMap.put(materialBaseInfoId, materialBaseInfoPO.getShipperId()); + } + } + } catch (Exception e) { + // 如果查询失败,记录日志但继续处理 + // log.warn("查询物料基础信息失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + } + } + + for (MaterialInventoryDO materialInventoryDO : materialInventoryDOList) { + // 获取货主ID(优先使用materialInventoryDO中的,如果没有则从物料基础信息中获取) + Long shipperId = materialInventoryDO.getShipperId(); + if (shipperId == null && materialInventoryDO.getMaterialBaseInfoId() != null) { + shipperId = materialBaseInfoIdToShipperIdMap.get(materialInventoryDO.getMaterialBaseInfoId()); + } + + //TODO 若数据量升级 后期优化 + // 查询现有库存时,按唯一索引(storage_location_id, material_base_info_id, shipper_id) 查询 + MaterialInventory materialInventoryDb = null; + + if (materialInventoryDO.getStorageLocationId() != null && materialInventoryDO.getMaterialBaseInfoId() != null) { + // 使用 LambdaQueryWrapper 构造查询条件 + com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper wrapper = + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(MaterialInventory::getStorageLocationId, materialInventoryDO.getStorageLocationId()) + .eq(MaterialInventory::getMaterialBaseInfoId, materialInventoryDO.getMaterialBaseInfoId()) + .eq(MaterialInventory::getDelFlag, 1); + // 有货主信息时,按货主再细分库存 + if (shipperId != null) { + wrapper.eq(MaterialInventory::getShipperId, shipperId); + } + materialInventoryDb = materialInventoryMapper.selectOne(wrapper); + } + + if (ObjectUtil.isNull(materialInventoryDb)){ + // 生成key时,需要与唯一性约束保持一致:storage_location_id + material_base_info_id + shipper_id + String key = (shipperId != null ? shipperId : "null") + "_" + + materialInventoryDO.getStorageLocationId() + "_" + + materialInventoryDO.getMaterialBaseInfoId(); + + // 注意:如果唯一性约束包含批次号、容器ID、物料状态等字段,那么key也应该包含这些字段 + // 但是,根据唯一性约束名称IDX_MAT_INV_LOC_MAT_ID,它应该只包含storage_location_id和material_base_info_id + // 因此,我们只使用这两个字段生成key,其他字段(批次号、容器ID等)的值会被合并到同一条记录中 + if (ObjectUtil.isNull(materialInventoryAddNowMap.get(key))){ MaterialInventory materialInventory = new MaterialInventory(); BeanUtils.copyProperties(materialInventoryDO, materialInventory); + // 确保把货主字段带到实体里 + materialInventory.setShipperId(shipperId); + // 如果批次号、容器ID、物料状态等字段在唯一性约束中,应该保留;否则,使用第一个值 + // 由于唯一性约束只包含storage_location_id和material_base_info_id,我们保留这些字段的值 materialInventoryList.add(materialInventory); materialInventoryAddNowMap.put(key, materialInventory); }else { + // 合并数量:同一库位和物料的库存应该合并数量 BigDecimal inventoryQuantity = materialInventoryAddNowMap.get(key).getInventoryQuantity().add(materialInventoryDO.getInventoryQuantity()); BigDecimal allocationQuantity = materialInventoryAddNowMap.get(key).getAllocationQuantity().add(materialInventoryDO.getInventoryQuantity()); materialInventoryAddNowMap.get(key).setInventoryQuantity(inventoryQuantity); materialInventoryAddNowMap.get(key).setAllocationQuantity(allocationQuantity); } - }else { - materialInventoryDO.setMaterialInventoryId(materialInventoryDb.getMaterialInventoryId()); - materialInventoryDOListByUpdate.add(materialInventoryDO); + }else { + // 走更新逻辑:同一个 material_inventory_id 可能会被多条明细命中 + // 由于 Mapper 中使用的是 + // inventory_quantity = CASE material_inventory_id + // WHEN id THEN inventory_quantity + #{item.inventoryQuantity} + // END + // 且同一个 id 出现多次时 DB 只会匹配到第一条 WHEN, + // 所以这里必须先在 Java 侧把同一个 materialInventoryId 的数量汇总。 + Long inventoryId = materialInventoryDb.getMaterialInventoryId(); + materialInventoryDO.setMaterialInventoryId(inventoryId); + // 默认数量为 0,避免空指针 + BigDecimal delta = materialInventoryDO.getInventoryQuantity() != null + ? materialInventoryDO.getInventoryQuantity() + : BigDecimal.ZERO; + if (delta.compareTo(BigDecimal.ZERO) == 0) { + // 数量为 0 没有必要参与更新 + continue; + } + MaterialInventoryDO exist = materialInventoryDOMapByUpdate.get(inventoryId); + if (exist == null) { + // 首次命中该库存记录 + MaterialInventoryDO copy = new MaterialInventoryDO(); + BeanUtils.copyProperties(materialInventoryDO, copy); + copy.setInventoryQuantity(delta); + copy.setAllocationQuantity(delta); + materialInventoryDOMapByUpdate.put(inventoryId, copy); + } else { + // 累加同一库存记录的数量 + BigDecimal existDelta = exist.getInventoryQuantity() != null + ? exist.getInventoryQuantity() + : BigDecimal.ZERO; + BigDecimal newDelta = existDelta.add(delta); + exist.setInventoryQuantity(newDelta); + // allocationQuantity 与 inventoryQuantity 保持一致累加 + BigDecimal existAlloc = exist.getAllocationQuantity() != null + ? exist.getAllocationQuantity() + : BigDecimal.ZERO; + exist.setAllocationQuantity(existAlloc.add(delta)); + } + } + } + if (!CollectionUtils.isEmpty(materialInventoryList)){ + saveBatch(materialInventoryList); + } + if (!materialInventoryDOMapByUpdate.isEmpty()){ + MaterialInventoryParentDO materialInventoryParentDO = new MaterialInventoryParentDO(); + materialInventoryParentDO.setUpdateBy(loginUser.getUserid()); + materialInventoryParentDO.setUpdateByName(loginUser.getUsername()); + materialInventoryParentDO.setUpdateTime(new Date()); + materialInventoryParentDO.setMaterialInventoryDOList(new ArrayList<>(materialInventoryDOMapByUpdate.values())); + materialInventoryMapper.batchAddInventoryQuantity(materialInventoryParentDO); } } - if (!CollectionUtils.isEmpty(materialInventoryList)){ - saveBatch(materialInventoryList); - } - if (!CollectionUtils.isEmpty(materialInventoryDOListByUpdate)){ - MaterialInventoryParentDO materialInventoryParentDO = new MaterialInventoryParentDO(); - materialInventoryParentDO.setUpdateBy(loginUser.getUserid()); - materialInventoryParentDO.setUpdateByName(loginUser.getUsername()); - materialInventoryParentDO.setUpdateTime(new Date()); - materialInventoryParentDO.setMaterialInventoryDOList(materialInventoryDOListByUpdate); - materialInventoryMapper.batchAddInventoryQuantity(materialInventoryParentDO); - } - } /** * @description 减少物料库存信息 @@ -264,4 +379,4 @@ public class MaterialInventoryImpl extends ServiceImpl materialMoreDetailList; + + @ApiModelProperty("包装名") + @Excel(name = "包装名") + private String packName; + + + @ApiModelProperty("单位名") + @Excel(name = "单位名") + private String unitName; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/po/MaterialInventoryQueryListPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/po/MaterialInventoryQueryListPO.java index 76bcd0f94..5e6debb3f 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/po/MaterialInventoryQueryListPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/po/MaterialInventoryQueryListPO.java @@ -1,12 +1,15 @@ package com.mhd.wms.domain.materialInventory.repository.po; +import com.fasterxml.jackson.annotation.JsonFormat; import com.mhd.common.core.annotation.Excel; import com.mhd.wms.domain.materialBaseInfo.repository.po.MaterialBasePO; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; +import java.util.Date; /** @@ -147,4 +150,76 @@ public class MaterialInventoryQueryListPO extends MaterialBasePO { @ApiModelProperty("盘点是否可用:0-禁用 1-可用") @Excel(name = "盘点是否可用:0-禁用 1-可用") private Integer isAble; -} + + + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unit; + + @ApiModelProperty("净重(KG)") + @Excel(name = "净重(KG)") + private BigDecimal netWeight; + + @ApiModelProperty("毛重(KG)") + @Excel(name = "毛重(KG)") + private BigDecimal grossWeight; + + @ApiModelProperty("体积") + @Excel(name = "体积") + private BigDecimal volume; + + @ApiModelProperty("面积") + @Excel(name = "面积") + private BigDecimal area; + + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("扩展字段1") + @Excel(name = "扩展字段1") + private String extAttr1; + + @ApiModelProperty("扩展字段2") + @Excel(name = "扩展字段2") + private String extAttr2; + + @ApiModelProperty("生产日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date productionDate; + + @ApiModelProperty("过期日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date inventoryDate; + + @ApiModelProperty("ExtAttr3") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr3", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date extAttr3; + + @ApiModelProperty("ExtAttr4") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr4", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date extAttr4; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/todo/MaterialInventoryDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/todo/MaterialInventoryDO.java index b379dd24e..55ae816b8 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/todo/MaterialInventoryDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/todo/MaterialInventoryDO.java @@ -1,11 +1,14 @@ package com.mhd.wms.domain.materialInventory.repository.todo; +import com.fasterxml.jackson.annotation.JsonFormat; import com.mhd.common.core.annotation.Excel; import com.mhd.wms.domain.materialBaseInfo.repository.todo.MaterialBaseDO; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; +import java.util.Date; import java.util.List; @@ -144,4 +147,86 @@ public class MaterialInventoryDO extends MaterialBaseDO { @ApiModelProperty("物料/库位信息") @Excel(name = "物料/库位信息") private String storageInfo; -} + + + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unit; + + @ApiModelProperty("单位名称") + @Excel(name = "单位名称") + private String unitName; + + @ApiModelProperty("净重(KG)") + @Excel(name = "净重(KG)") + private BigDecimal netWeight; + + @ApiModelProperty("毛重(KG)") + @Excel(name = "毛重(KG)") + private BigDecimal grossWeight; + + @ApiModelProperty("体积") + @Excel(name = "体积") + private BigDecimal volume; + + @ApiModelProperty("面积") + @Excel(name = "面积") + private BigDecimal area; + + @ApiModelProperty("货主id") + private Long shipperId; + + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("扩展字段1") + @Excel(name = "扩展字段1") + private String extAttr1; + + @ApiModelProperty("扩展字段2") + @Excel(name = "扩展字段2") + private String extAttr2; + + @ApiModelProperty("生产日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date productionDate; + + @ApiModelProperty("过期日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date inventoryDate; + + @ApiModelProperty("ExtAttr3") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr3", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date extAttr3; + + @ApiModelProperty("ExtAttr4") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr4", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date extAttr4; + + //查询规则 hz:货主,wl:物料,kw:库位,wlkw:物料库位,all:全部 + private String queryRule; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/todo/MaterialInventoryQueryListDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/todo/MaterialInventoryQueryListDO.java index 08ef7a08f..cf7517ffe 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/todo/MaterialInventoryQueryListDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/todo/MaterialInventoryQueryListDO.java @@ -1,11 +1,14 @@ package com.mhd.wms.domain.materialInventory.repository.todo; +import com.fasterxml.jackson.annotation.JsonFormat; import com.mhd.common.core.annotation.Excel; import com.mhd.wms.domain.materialBaseInfo.repository.todo.MaterialBaseDO; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; +import java.util.Date; import java.util.List; @@ -168,4 +171,83 @@ public class MaterialInventoryQueryListDO extends MaterialBaseDO { @ApiModelProperty("物料/库位信息") @Excel(name = "物料/库位信息") private String storageInfo; -} + + + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unit; + + @ApiModelProperty("单位名称") + @Excel(name = "单位名称") + private String unitName; + + @ApiModelProperty("净重(KG)") + @Excel(name = "净重(KG)") + private BigDecimal netWeight; + + @ApiModelProperty("毛重(KG)") + @Excel(name = "毛重(KG)") + private BigDecimal grossWeight; + + @ApiModelProperty("体积") + @Excel(name = "体积") + private BigDecimal volume; + + @ApiModelProperty("面积") + @Excel(name = "面积") + private BigDecimal area; + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("扩展字段1") + @Excel(name = "扩展字段1") + private String extAttr1; + + @ApiModelProperty("扩展字段2") + @Excel(name = "扩展字段2") + private String extAttr2; + + @ApiModelProperty("生产日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date productionDate; + + @ApiModelProperty("过期日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date inventoryDate; + + @ApiModelProperty("ExtAttr3") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr3", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date extAttr3; + + @ApiModelProperty("ExtAttr4") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr4", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date extAttr4; + + @ApiModelProperty("订单物料明细id") + private Long materialDetailId; + +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventoryWarning/repository/persistence/MaterialInventoryWarningImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventoryWarning/repository/persistence/MaterialInventoryWarningImpl.java index 46e081c29..5cecad1f1 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventoryWarning/repository/persistence/MaterialInventoryWarningImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventoryWarning/repository/persistence/MaterialInventoryWarningImpl.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; +import java.util.stream.Collectors; /** * 物料库存预警Service业务层处理 @@ -91,6 +92,7 @@ public class MaterialInventoryWarningImpl extends ServiceImpl materialInventoryWarningPOList = new ArrayList<>(); - BeanUtils.copyProperties(materialInventoryWarningList, materialInventoryWarningPOList); + List materialInventoryWarningPOList = materialInventoryWarningList.stream().map(item -> { + MaterialInventoryWarningPO materialInventoryWarningPO = new MaterialInventoryWarningPO(); + BeanUtils.copyProperties(item, materialInventoryWarningPO); + return materialInventoryWarningPO; + }).collect(Collectors.toList()); return materialInventoryWarningPOList; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialMoreDetail/repository/todo/MaterialMoreDetailDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialMoreDetail/repository/todo/MaterialMoreDetailDO.java index 14c72011f..5d2fd39c7 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/materialMoreDetail/repository/todo/MaterialMoreDetailDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialMoreDetail/repository/todo/MaterialMoreDetailDO.java @@ -54,6 +54,7 @@ public class MaterialMoreDetailDO extends BaseVOEntity { @Excel(name = "批次标签") private String batchLabels; + @ApiModelProperty("输入控制: 1-必填 2-可选") @Excel(name = "输入控制: 1-必填 2-可选") private String inputControl; diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/entity/OutMaterialDetail.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/entity/OutMaterialDetail.java index a5d85c87b..48325915c 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/entity/OutMaterialDetail.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/entity/OutMaterialDetail.java @@ -1,6 +1,7 @@ package com.mhd.wms.domain.outMaterialDetail.entity; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; @@ -10,6 +11,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; +import java.util.Date; /** @@ -222,4 +224,224 @@ public class OutMaterialDetail extends BaseVOEntity { @ApiModelProperty("越库类型:1-直接越库 2-分拨越库") @Excel(name = "越库类型:1-直接越库 2-分拨越库") private Long overStockType; -} + + + /** + * 商品名称 + */ + @ApiModelProperty("商品名称") + @Excel(name = "商品名称") + private String commodityName; + /** + * 商品编码 + */ + @ApiModelProperty("商品编码") + @Excel(name = "商品编码") + private String commodityNo; + /** + * 料号 + */ + @ApiModelProperty("料号") + @Excel(name = "料号") + private String materialNo; + /** + * 规格型号 + */ + @ApiModelProperty("规格型号") + @Excel(name = "规格型号") + private String specificationModel; + /** + * 商品SKU码 + */ + @ApiModelProperty("商品SKU码") + @Excel(name = "商品SKU码") + private String skucode; + /** + * Invoice No + */ + @ApiModelProperty("Invoice No") + @Excel(name = "Invoice No") + private String invoiceNo; + /** + * 升 + */ + @ApiModelProperty("升") + @Excel(name = "升") + private String liter; + + /** + * 尺寸 + */ + @ApiModelProperty("尺寸") + @Excel(name = "尺寸") + private String size; + + /** + * 申报单位 + */ + @ApiModelProperty("申报单位") + @Excel(name = "申报单位") + private String declareUnit; + + /** + * Batch Ref NO’s + */ + @ApiModelProperty("Batch Ref NO’s") + @Excel(name = "Batch Ref NO’s") + private String batchRefNo; + + /** + * Sheet Ref NO’s + */ + @ApiModelProperty("Sheet Ref NO’s") + @Excel(name = "Sheet Ref NO’s") + private String sheetRefNo; + + /** + * 原产国 + */ + @ApiModelProperty("原产国") + @Excel(name = "原产国") + private String countryOfOrigin; + + /** + * 箱号/卡板号 + */ + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + /** + * 币制 + */ + @ApiModelProperty("币制") + @Excel(name = "币制") + private String currency; + + /** + * 申报数量 + */ + @ApiModelProperty("申报数量") + @Excel(name = "申报数量") + private BigDecimal declareQuantity; + + /** + * 箱数 + */ + @ApiModelProperty("箱数") + @Excel(name = "箱数") + private BigDecimal caseCount; + + /** + * 件数 + */ + @ApiModelProperty("件数") + @Excel(name = "件数") + private BigDecimal pieceCount; + + /** + * 出库数量 + */ + @ApiModelProperty("出库数量") + @Excel(name = "出库数量") + private BigDecimal outboundQuantity; + + /** + * 总净重(KG) + */ + @ApiModelProperty("总净重(KG)") + @Excel(name = "总净重(KG)") + private BigDecimal totalNetWeight; + + /** + * 总毛重(KG) + */ + @ApiModelProperty("总毛重(KG)") + @Excel(name = "总毛重(KG)") + private BigDecimal totalGrossWeight; + + /** + * 总体积(CBM) + */ + @ApiModelProperty("总体积(CBM)") + @Excel(name = "总体积(CBM)") + private BigDecimal totalVolume; + + /** + * 总面积(SQM) + */ + @ApiModelProperty("总面积(SQM)") + @Excel(name = "总面积(SQM)") + private BigDecimal totalArea; + /** + * 总价 + */ + @ApiModelProperty("总价") + @Excel(name = "总价") + private BigDecimal totalAmount; + + /** + * 单位 + */ + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unit; + + @ApiModelProperty("扩展属性1") + @Excel(name = "扩展属性1") + @TableField("ext_attr_1") + private String extAttr1; + + @ApiModelProperty("扩展属性2") + @Excel(name = "扩展属性2") + @TableField("ext_attr_2") + private String extAttr2; + + @ApiModelProperty("生产日期") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date productionDate; + + @ApiModelProperty("过期日期") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date inventoryDate; + + @ApiModelProperty("扩展属性3") + @Excel(name = "扩展属性3", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("ext_attr_3") + private Date extAttr3; + + @ApiModelProperty("扩展属性4") + @Excel(name = "扩展属性4", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("ext_attr_4") + private Date extAttr4; + + /** + * 库存数量(仅用于前端展示,从material_inventory表中带出) + */ + @ApiModelProperty("库存数量") + @TableField(exist = false) + private BigDecimal inventoryQuantity; + + @TableField(exist = false) + private BigDecimal actualQuantity; + + @ApiModelProperty("复核总净重(KG)") + @Excel(name = "复核总净重(KG)") + private BigDecimal checkNetWeight; + + @ApiModelProperty("复核总毛重(KG)") + @Excel(name = "复核总毛重(KG)") + private BigDecimal checkGrossWeight; + + @ApiModelProperty("复核总体积(CBM)") + @Excel(name = "复核总体积(CBM)") + private BigDecimal checkVolume; + + @ApiModelProperty("复核总面积(SQM)") + @Excel(name = "复核总面积(SQM)") + private BigDecimal checkArea; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/facade/IOutMaterialDetailService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/facade/IOutMaterialDetailService.java index e7a7b0843..4dc11fc83 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/facade/IOutMaterialDetailService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/facade/IOutMaterialDetailService.java @@ -74,6 +74,16 @@ public interface IOutMaterialDetailService extends IService */ public StockOutOrderPO batchCancelAssignUpdate(String outOrderNumber, List outMaterialDetailDOList); + /** + * @description 手动取消分配批量修改物流明细(弹窗方式,类似batchAssignUpdate) + * @author ZhouGY + * @date 2024/5/22 9:27 + * @param outOrderNumber + * @param outMaterialDetailDOList + * @return StockOutOrderPO + */ + public StockOutOrderPO batchManualCancelAssignUpdate(String outOrderNumber, List outMaterialDetailDOList); + /** * @description 拣货批量修改物流明细 * @author ZhouGY diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/persistence/OutMaterialDetailImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/persistence/OutMaterialDetailImpl.java index 31f9ea0a0..dd780143c 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/persistence/OutMaterialDetailImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/persistence/OutMaterialDetailImpl.java @@ -12,6 +12,14 @@ import com.mhd.common.core.utils.bean.BeanUtils; import com.mhd.common.core.utils.uuid.IdGenerator; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.model.LoginUser; +import com.mhd.wms.domain.inventoryAdjustmentRecord.entity.InventoryAdjustmentRecord; +import com.mhd.wms.domain.inventoryAdjustmentRecord.repository.mapper.InventoryAdjustmentRecordMapper; +import com.mhd.wms.domain.materialBaseInfo.entity.MaterialBaseInfo; +import com.mhd.wms.domain.materialBaseInfo.repository.mapper.MaterialBaseInfoMapper; +import com.mhd.wms.domain.materialInventory.entity.MaterialInventory; +import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper; +import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO; +import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryDO; import com.mhd.wms.domain.outMaterialDetail.entity.OutMaterialDetail; import com.mhd.wms.domain.outMaterialDetail.repository.facade.IOutMaterialDetailService; import com.mhd.wms.domain.outMaterialDetail.repository.mapper.OutMaterialDetailMapper; @@ -23,12 +31,15 @@ import com.mhd.wms.domain.outMaterialDetailSerialNumber.entity.OutMaterialDetail import com.mhd.wms.domain.outMaterialDetailSerialNumber.repository.facade.IOutMaterialDetailSerialNumberService; import com.mhd.wms.domain.overStock.repository.todo.QueryOrderOverStockDO; import com.mhd.wms.domain.pickingMaterialDetail.entity.PickingMaterialDetail; +import com.mhd.wms.domain.stockOutOrder.entity.StockOutOrder; +import com.mhd.wms.domain.stockOutOrder.repository.mapper.StockOutOrderMapper; import com.mhd.wms.domain.stockOutOrder.repository.po.StockOutOrderPO; import com.mhd.wms.domain.stockOutOrder.repository.todo.StockOutOrderDO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; +import org.springframework.util.ObjectUtils; import java.math.BigDecimal; import java.util.ArrayList; @@ -52,6 +63,14 @@ public class OutMaterialDetailImpl extends ServiceImpl materialBaseInfos = materialBaseInfoMapper.selectList(new QueryWrapper().lambda().eq(MaterialBaseInfo::getMaterialCode, materialNo)); + if (!CollectionUtils.isEmpty(materialBaseInfos) && materialBaseInfos.size() > 0) { + outMaterialDetail.setCommodityName(materialBaseInfos.get(0).getMaterialName()); + outMaterialDetail.setBarCode(materialBaseInfos.get(0).getBarCode()); + outMaterialDetail.setPackName(materialBaseInfos.get(0).getPackName()); + outMaterialDetail.setPackCode(materialBaseInfos.get(0).getPackCode()); + outMaterialDetail.setUnitCode(materialBaseInfos.get(0).getUnitCode()); + outMaterialDetail.setUnitName(materialBaseInfos.get(0).getUnitName()); + } outMaterialDetailList.add(outMaterialDetail); } return saveBatch(outMaterialDetailList); @@ -271,9 +301,188 @@ public class OutMaterialDetailImpl extends ServiceImpl outMaterialDetailDOList) { + if (CollectionUtils.isEmpty(outMaterialDetailDOList)) { + throw new ServiceException("物料明细不能为空"); + } + StockOutOrderPO stockOutOrderPO = new StockOutOrderPO(); + LoginUser loginUser = SecurityUtils.getLoginUser(); + List outMaterialDetailDbList = outMaterialDetailMapper.selectList(new QueryWrapper().lambda() + .eq(OutMaterialDetail::getOutOrderNumber, outOrderNumber) + .eq(OutMaterialDetail::getLevel, 1) + .eq(OutMaterialDetail::getDelFlag, 1)); + Map materialDetailMap = outMaterialDetailDbList.stream().collect(Collectors.toMap(OutMaterialDetail::getMaterialDetailId, Function.identity())); + //批量修改物料信息 + List outMaterialDetailList = new ArrayList<>(); + BigDecimal totalAllocationQuantity = BigDecimal.ZERO;//出库单总取消分配数量 + BigDecimal totalAlreadyAllocationQuantity = BigDecimal.ZERO;//出库单总取消已分配数量 + for (OutMaterialDetailDO outMaterialDetailDO : outMaterialDetailDOList){ + OutMaterialDetail outMaterialDetailDb = materialDetailMap.get(outMaterialDetailDO.getMaterialDetailId()); + if (outMaterialDetailDb == null){ + throw new ServiceException("物料信息不存在"); + } + OutMaterialDetail outMaterialDetail = new OutMaterialDetail(); + BeanUtils.copyProperties(outMaterialDetailDO, outMaterialDetail); + outMaterialDetail.setUpdateBy(loginUser.getUserid()); + outMaterialDetail.setUpdateByName(loginUser.getUsername()); + outMaterialDetail.setUpdateTime(new Date()); + outMaterialDetail.setAllowModify(1); + + //判断是否存在子项 + BigDecimal cancelAllocationQuantity = outMaterialDetailDO.getAllocationQuantity() != null ? outMaterialDetailDO.getAllocationQuantity() : BigDecimal.ZERO; // 要取消的分配数量 + List materialDetailDOChildList = outMaterialDetailDO.getChildren(); + List outMaterialDetailListChild = new ArrayList<>(); + if (!CollectionUtils.isEmpty(materialDetailDOChildList)){ + for (OutMaterialDetailDO outMaterialDetailDOChild : materialDetailDOChildList){ + OutMaterialDetail outMaterialDetailChild = new OutMaterialDetail(); + BeanUtils.copyProperties(outMaterialDetailDOChild, outMaterialDetailChild, IgnoreNullUtil.getNullPropertyNames(outMaterialDetailDOChild)); + outMaterialDetailChild.setMaterialDetailId(null); + outMaterialDetailChild.setUniqueId(idGenerator.snowflakeId(SnowFlakeConstants.wmsId)); + outMaterialDetailChild.setLevel(2); + outMaterialDetailChild.setParentUniqueId(outMaterialDetailDO.getUniqueId()); + outMaterialDetailChild.setUpdateBy(loginUser.getUserid()); + outMaterialDetailChild.setUpdateByName(loginUser.getUsername()); + outMaterialDetailChild.setUpdateTime(new Date()); + outMaterialDetailChild.setAllowModify(1); + // 设置 actualQuantity 用于 qxfp 方法更新库存 + outMaterialDetailChild.setActualQuantity(outMaterialDetailDOChild.getAllocationQuantity() != null ? outMaterialDetailDOChild.getAllocationQuantity() : BigDecimal.ZERO); + outMaterialDetailListChild.add(outMaterialDetailChild); + // 累加子项的取消分配数量 + if (outMaterialDetailDOChild.getAllocationQuantity() != null) { + cancelAllocationQuantity = cancelAllocationQuantity.add(outMaterialDetailDOChild.getAllocationQuantity()); + } + } + } + if (CollectionUtil.isNotEmpty(outMaterialDetailListChild)){ + outMaterialDetailList.addAll(outMaterialDetailListChild); + } + + //判断取消分配数量不能大于分配总数 + if(cancelAllocationQuantity.compareTo(outMaterialDetailDb.getAllocationQuantity()) > 0){ + throw new ServiceException("物料" + outMaterialDetailDb.getMaterialName() + ",取消分配数量不能大于分配总数"); + } + + // 更新分配数量和已分配数量 + // 手动取消分配的业务含义:将该明细上“已经分配”的库存全部撤回,回到可再次分配的状态 + // 因此这里直接将分配数量、已分配数量都置为 0 + outMaterialDetail.setAllocationQuantity(BigDecimal.ZERO); + outMaterialDetail.setAlreadyAllocationQuantity(BigDecimal.ZERO); + + // 同时清空目标库位 / 目标库区 / 目标仓库等分配相关的信息(仅保留计划信息) + outMaterialDetail.setWarehouseId(null); + outMaterialDetail.setWarehouseCode(null); + outMaterialDetail.setWarehouseName(null); + outMaterialDetail.setStorageSectionId(null); + outMaterialDetail.setStorageCode(null); + outMaterialDetail.setStorageName(null); + outMaterialDetail.setStorageLocationId(null); + outMaterialDetail.setStorageLocationCode(null); + outMaterialDetail.setStorageLocationName(null); + // 设置 actualQuantity 用于 qxfp 方法更新库存(表示本次实际取消的数量) + outMaterialDetail.setActualQuantity(cancelAllocationQuantity); + outMaterialDetailList.add(outMaterialDetail); + + //记录出库单取消分配总数 + totalAllocationQuantity = totalAllocationQuantity.add(cancelAllocationQuantity); + totalAlreadyAllocationQuantity = totalAlreadyAllocationQuantity.add(cancelAllocationQuantity); + } + stockOutOrderPO.setAllocationQuantity(totalAllocationQuantity); + stockOutOrderPO.setAlreadyAllocationQuantity(totalAlreadyAllocationQuantity); + //保存物料明细信息 + saveOrUpdateBatch(outMaterialDetailList); + //取消分配(修改库存) + qxfp(outMaterialDetailList,outOrderNumber,loginUser); + + return stockOutOrderPO; + } + + public synchronized void xgkc(List outMaterialDetailList,String outOrderNumber,LoginUser loginUser) { + StockOutOrder stockOutOrder = stockOutOrderMapper.selectOne(new QueryWrapper().lambda().eq(StockOutOrder::getOutOrderNumber, outOrderNumber)); + for (OutMaterialDetail outMaterialDetail : outMaterialDetailList) { + Long materialInventoryId = outMaterialDetail.getMaterialInventoryId(); + BigDecimal allocationQuantity = outMaterialDetail.getAllocationQuantity(); + if (ObjectUtils.isEmpty(allocationQuantity)) { + allocationQuantity = BigDecimal.ZERO; + } + MaterialInventory materialInventoryPO = materialInventoryMapper.selectById(materialInventoryId); + if (materialInventoryPO != null) { + //更新库存数量 + //可用数量 + BigDecimal oldAllocationQuantity = materialInventoryPO.getAllocationQuantity(); + //冻结数量 + BigDecimal oldFreezeQuantity = materialInventoryPO.getFreezeQuantity(); + //分配后可用数量 + BigDecimal newAllocationQuantity = oldAllocationQuantity.subtract(allocationQuantity); + //分配后冻结数量 + BigDecimal newFreezeQuantity = oldFreezeQuantity.add(allocationQuantity); + materialInventoryPO.setAllocationQuantity(newAllocationQuantity); + materialInventoryPO.setFreezeQuantity(newFreezeQuantity); + MaterialInventory materialInventory = new MaterialInventory(); + BeanUtils.copyProperties(materialInventoryPO, materialInventory); + materialInventoryMapper.updateById(materialInventory); + + //库存调整记录 + InventoryAdjustmentRecord inventoryAdjustmentRecord = new InventoryAdjustmentRecord(); + inventoryAdjustmentRecord.setAdjustAfterStatusCode("he_ge"); + inventoryAdjustmentRecord.setAdjustBeforeStatusCode("he_ge"); + inventoryAdjustmentRecord.setAdjustAfterStatusName("合格"); + inventoryAdjustmentRecord.setAdjustBeforeStatusName("合格"); + inventoryAdjustmentRecord.setAdjustType(1L); + inventoryAdjustmentRecord.setMaterialBaseInfoId(materialInventoryPO.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setMaterialCode(outMaterialDetail.getMaterialNo()); + inventoryAdjustmentRecord.setMaterialName(outMaterialDetail.getCommodityName()); + inventoryAdjustmentRecord.setBarCode(outMaterialDetail.getBarCode()); + inventoryAdjustmentRecord.setMaterialBaseInfoId(outMaterialDetail.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setOrganizationId(stockOutOrder.getOrganizationId()); + inventoryAdjustmentRecord.setOrganizationName(stockOutOrder.getOrganizationName()); + inventoryAdjustmentRecord.setTopOrganizationId(stockOutOrder.getTopOrganizationId()); + inventoryAdjustmentRecord.setWarehouseCode(stockOutOrder.getWarehouseCode()); + inventoryAdjustmentRecord.setWarehouseName(stockOutOrder.getWarehouseName()); + inventoryAdjustmentRecord.setWarehouseId(stockOutOrder.getWarehouseId()); + inventoryAdjustmentRecord.setStorageCode(materialInventoryPO.getStorageCode()); + inventoryAdjustmentRecord.setStorageName(materialInventoryPO.getStorageName()); + inventoryAdjustmentRecord.setStorageLocationId(materialInventoryPO.getStorageLocationId()); + inventoryAdjustmentRecord.setStorageLocationCode(materialInventoryPO.getStorageLocationCode()); + inventoryAdjustmentRecord.setStorageLocationName(materialInventoryPO.getStorageLocationName()); + inventoryAdjustmentRecord.setMaterialInventoryId(materialInventoryPO.getMaterialInventoryId()); + inventoryAdjustmentRecord.setMaterialBaseInfoId(materialInventoryPO.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setShipperId(stockOutOrder.getShipperId()); + inventoryAdjustmentRecord.setShipperName(stockOutOrder.getShipperName()); + inventoryAdjustmentRecord.setStorageSectionId(materialInventoryPO.getStorageSectionId()); + inventoryAdjustmentRecord.setStorageLocationId(materialInventoryPO.getStorageLocationId()); + inventoryAdjustmentRecord.setCreateBy(loginUser.getUserid()); + inventoryAdjustmentRecord.setCreateByName(loginUser.getUsername()); + inventoryAdjustmentRecord.setCreateTime(new Date()); + inventoryAdjustmentRecord.setAllocationAfterQuantity(newAllocationQuantity); + inventoryAdjustmentRecord.setAllocationBeforeQuantity(oldAllocationQuantity); + inventoryAdjustmentRecord.setFreezeBeforeQuantity(oldFreezeQuantity); + inventoryAdjustmentRecord.setFreezeAfterQuantity(newFreezeQuantity); + inventoryAdjustmentRecord.setInventoryBeforeQuantity(materialInventoryPO.getInventoryQuantity()); + inventoryAdjustmentRecord.setInventoryAfterQuantity(materialInventoryPO.getInventoryQuantity()); + inventoryAdjustmentRecord.setCreateBy(loginUser.getUserid()); + inventoryAdjustmentRecord.setCreateByName(loginUser.getUsername()); + inventoryAdjustmentRecord.setCreateTime(new Date()); + inventoryAdjustmentRecordMapper.insert(inventoryAdjustmentRecord); + } + } + } + /** * @description 取消分配批量修改物流明细 * @author ZhouGY @@ -305,12 +514,21 @@ public class OutMaterialDetailImpl extends ServiceImpl materialDetailDOChildList = outMaterialDetailDO.getChildren(); @@ -322,23 +540,94 @@ public class OutMaterialDetailImpl extends ServiceImpl0){ + //判断取消分配数量不能大于已分配数量(取消分配应该检查alreadyAllocationQuantity,而不是allocationQuantity) + BigDecimal dbAlreadyAllocationQuantity = outMaterialDetailDb.getAlreadyAllocationQuantity() != null + ? outMaterialDetailDb.getAlreadyAllocationQuantity() + : BigDecimal.ZERO; + if(allocationQuantity.compareTo(dbAlreadyAllocationQuantity) > 0){ + throw new ServiceException("物料" + outMaterialDetailDb.getMaterialName() + ",取消分配数量不能大于已分配数量"); + } + BigDecimal dbAllocationQuantity = outMaterialDetailDb.getAllocationQuantity() != null + ? outMaterialDetailDb.getAllocationQuantity() + : BigDecimal.ZERO; + // 分配数量和已分配数量都减少:本次手动取消分配视为“把这条明细已分配的全部撤回” + BigDecimal newAllocationQuantity = dbAllocationQuantity.subtract(allocationQuantity); + if (newAllocationQuantity.compareTo(BigDecimal.ZERO) < 0) { throw new ServiceException("物料" + outMaterialDetailDb.getMaterialName() + ",取消分配数量不能大于分配总数"); } - outMaterialDetail.setAllocationQuantity(outMaterialDetailDb.getAllocationQuantity().subtract(allocationQuantity)); - outMaterialDetail.setAlreadyAllocationQuantity(outMaterialDetailDb.getAlreadyAllocationQuantity().subtract(allocationQuantity)); + outMaterialDetail.setAllocationQuantity(newAllocationQuantity); + outMaterialDetail.setAlreadyAllocationQuantity(dbAlreadyAllocationQuantity.subtract(allocationQuantity)); + + // 同时清空该明细的目标仓库/库区/库位信息(回到未分配状态) + outMaterialDetail.setWarehouseId(null); + outMaterialDetail.setWarehouseCode(null); + outMaterialDetail.setWarehouseName(null); + outMaterialDetail.setStorageSectionId(null); + outMaterialDetail.setStorageCode(null); + outMaterialDetail.setStorageName(null); + outMaterialDetail.setStorageLocationId(null); + outMaterialDetail.setStorageLocationCode(null); + outMaterialDetail.setStorageLocationName(null); + + // 清空与分配库存相关的批次、容器信息 + outMaterialDetail.setMaterialInventoryId(null); + outMaterialDetail.setBatchNumber(null); + outMaterialDetail.setMaterialStatusCode(null); + outMaterialDetail.setMaterialStatusName(null); + outMaterialDetail.setContainerId(null); + outMaterialDetail.setContainerCode(null); + outMaterialDetail.setContainerType(null); + outMaterialDetail.setContainerTypeName(null); + // 设置 actualQuantity 用于 qxfp 方法更新库存(取消分配的数量) + outMaterialDetail.setActualQuantity(allocationQuantity); outMaterialDetailList.add(outMaterialDetail); materialDetailIdsByUpdate.add(outMaterialDetailDO.getMaterialDetailId()); //记录收货单收货总数 @@ -347,26 +636,85 @@ public class OutMaterialDetailImpl extends ServiceImpl materialDetailIdsByDb = outMaterialDetailDbList.stream().map(OutMaterialDetail::getMaterialDetailId).collect(Collectors.toList()); - //过滤需要修改的id集合 - materialDetailIdsByDb.removeAll(materialDetailIdsByUpdate); - //判断是否存在需要删除的物流明细 标记删除 - if (!CollectionUtils.isEmpty(materialDetailIdsByDb)){ - update(new UpdateWrapper().lambda() - .set(OutMaterialDetail::getDelFlag, 2) - .set(OutMaterialDetail::getUpdateBy, loginUser.getUserid()) - .set(OutMaterialDetail::getUpdateByName, loginUser.getUsername()) - .set(OutMaterialDetail::getUpdateTime, new Date()) - .in(OutMaterialDetail::getMaterialDetailId, materialDetailIdsByDb)); - } - } + // 取消分配时,只更新需要取消分配的明细,不删除其他明细 + // 注意:这里移除了删除其他明细的逻辑,因为取消分配只是减少已分配数量,不应该删除明细 //保存物料明细信息 updateBatchById(outMaterialDetailList); + //取消分配 + qxfp(outMaterialDetailList,outOrderNumber,loginUser); return stockOutOrderPO; } + private synchronized void qxfp(List outMaterialDetailList,String outOrderNumber,LoginUser loginUser) { + StockOutOrder stockOutOrder = stockOutOrderMapper.selectOne(new QueryWrapper().lambda().eq(StockOutOrder::getOutOrderNumber, outOrderNumber)); + for (OutMaterialDetail outMaterialDetail : outMaterialDetailList) { + Long materialInventoryId = outMaterialDetail.getMaterialInventoryId(); + BigDecimal allocationQuantity = outMaterialDetail.getActualQuantity(); + MaterialInventory materialInventoryPO = materialInventoryMapper.selectById(materialInventoryId); + if (materialInventoryPO != null) { + //更新库存数量 + //可用数量 + BigDecimal oldAllocationQuantity = materialInventoryPO.getAllocationQuantity(); + //冻结数量 + BigDecimal oldFreezeQuantity = materialInventoryPO.getFreezeQuantity(); + //分配后可用数量 + BigDecimal newAllocationQuantity = oldAllocationQuantity.add(allocationQuantity); + //分配后冻结数量 + BigDecimal newFreezeQuantity = oldFreezeQuantity.subtract(allocationQuantity); + materialInventoryPO.setAllocationQuantity(newAllocationQuantity); + materialInventoryPO.setFreezeQuantity(newFreezeQuantity); + //MaterialInventory materialInventory = new MaterialInventory(); + //BeanUtils.copyProperties(materialInventoryPO, materialInventory); + materialInventoryMapper.updateById(materialInventoryPO); + + + + //库存调整记录 + InventoryAdjustmentRecord inventoryAdjustmentRecord = new InventoryAdjustmentRecord(); + inventoryAdjustmentRecord.setAdjustAfterStatusCode("he_ge"); + inventoryAdjustmentRecord.setAdjustBeforeStatusCode("he_ge"); + inventoryAdjustmentRecord.setAdjustAfterStatusName("合格"); + inventoryAdjustmentRecord.setAdjustBeforeStatusName("合格"); + inventoryAdjustmentRecord.setAdjustType(1L); + inventoryAdjustmentRecord.setMaterialBaseInfoId(materialInventoryPO.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setMaterialCode(outMaterialDetail.getMaterialNo()); + inventoryAdjustmentRecord.setMaterialName(outMaterialDetail.getCommodityName()); + inventoryAdjustmentRecord.setBarCode(outMaterialDetail.getBarCode()); + inventoryAdjustmentRecord.setMaterialBaseInfoId(outMaterialDetail.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setOrganizationId(stockOutOrder.getOrganizationId()); + inventoryAdjustmentRecord.setOrganizationName(stockOutOrder.getOrganizationName()); + inventoryAdjustmentRecord.setTopOrganizationId(stockOutOrder.getTopOrganizationId()); + inventoryAdjustmentRecord.setWarehouseCode(stockOutOrder.getWarehouseCode()); + inventoryAdjustmentRecord.setWarehouseName(stockOutOrder.getWarehouseName()); + inventoryAdjustmentRecord.setWarehouseId(stockOutOrder.getWarehouseId()); + inventoryAdjustmentRecord.setStorageCode(materialInventoryPO.getStorageCode()); + inventoryAdjustmentRecord.setStorageName(materialInventoryPO.getStorageName()); + inventoryAdjustmentRecord.setStorageLocationId(materialInventoryPO.getStorageLocationId()); + inventoryAdjustmentRecord.setStorageLocationCode(materialInventoryPO.getStorageLocationCode()); + inventoryAdjustmentRecord.setStorageLocationName(materialInventoryPO.getStorageLocationName()); + inventoryAdjustmentRecord.setMaterialInventoryId(materialInventoryPO.getMaterialInventoryId()); + inventoryAdjustmentRecord.setMaterialBaseInfoId(materialInventoryPO.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setShipperId(stockOutOrder.getShipperId()); + inventoryAdjustmentRecord.setShipperName(stockOutOrder.getShipperName()); + inventoryAdjustmentRecord.setStorageSectionId(materialInventoryPO.getStorageSectionId()); + inventoryAdjustmentRecord.setStorageLocationId(materialInventoryPO.getStorageLocationId()); + inventoryAdjustmentRecord.setCreateBy(loginUser.getUserid()); + inventoryAdjustmentRecord.setCreateByName(loginUser.getUsername()); + inventoryAdjustmentRecord.setCreateTime(new Date()); + inventoryAdjustmentRecord.setAllocationAfterQuantity(newAllocationQuantity); + inventoryAdjustmentRecord.setAllocationBeforeQuantity(oldAllocationQuantity); + inventoryAdjustmentRecord.setFreezeBeforeQuantity(oldFreezeQuantity); + inventoryAdjustmentRecord.setFreezeAfterQuantity(newFreezeQuantity); + inventoryAdjustmentRecord.setInventoryBeforeQuantity(materialInventoryPO.getInventoryQuantity()); + inventoryAdjustmentRecord.setInventoryAfterQuantity(materialInventoryPO.getInventoryQuantity()); + inventoryAdjustmentRecord.setCreateBy(loginUser.getUserid()); + inventoryAdjustmentRecord.setCreateByName(loginUser.getUsername()); + inventoryAdjustmentRecord.setCreateTime(new Date()); + inventoryAdjustmentRecordMapper.insert(inventoryAdjustmentRecord); + } + } + } + /** * @description 拣货批量修改物流明细 * @author ZhouGY @@ -482,6 +830,11 @@ public class OutMaterialDetailImpl extends ServiceImpl materialMoreDetailList; + + @ApiModelProperty("分配按钮显示类型:1-显示库存分配,2-显示取消分配") + @TableField(exist = false) + private Integer allocationButtonType; + + @ApiModelProperty("复核总净重(KG)") + @Excel(name = "复核总净重(KG)") + private BigDecimal checkNetWeight; + + @ApiModelProperty("复核总毛重(KG)") + @Excel(name = "复核总毛重(KG)") + private BigDecimal checkGrossWeight; + + @ApiModelProperty("复核总体积(CBM)") + @Excel(name = "复核总体积(CBM)") + private BigDecimal checkVolume; + + @ApiModelProperty("复核总面积(SQM)") + @Excel(name = "复核总面积(SQM)") + private BigDecimal checkArea; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/todo/OutMaterialDetailDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/todo/OutMaterialDetailDO.java index 0cbf9ff15..a67396c86 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/todo/OutMaterialDetailDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outMaterialDetail/repository/todo/OutMaterialDetailDO.java @@ -158,6 +158,9 @@ public class OutMaterialDetailDO extends BaseVOEntity { @Excel(name = "容器类型名称 数据字典") private String containerTypeName; + @ApiModelProperty("库存数量(仅展示)") + private BigDecimal inventoryQuantity; + @ApiModelProperty("分配仓库id") private Long warehouseId; @@ -238,4 +241,183 @@ public class OutMaterialDetailDO extends BaseVOEntity { @Excel(name = "作业数量(例如:分配数量 拣货数量 复核数量)") private BigDecimal actualQuantity; -} + + + /** + * 商品名称 + */ + @ApiModelProperty("商品名称") + @Excel(name = "商品名称") + private String commodityName; + /** + * 商品编码 + */ + @ApiModelProperty("商品编码") + @Excel(name = "商品编码") + private String commodityNo; + /** + * 料号 + */ + @ApiModelProperty("料号") + @Excel(name = "料号") + private String materialNo; + /** + * 规格型号 + */ + @ApiModelProperty("规格型号") + @Excel(name = "规格型号") + private String specificationModel; + /** + * 商品SKU码 + */ + @ApiModelProperty("商品SKU码") + @Excel(name = "商品SKU码") + private String skucode; + /** + * Invoice No + */ + @ApiModelProperty("Invoice No") + @Excel(name = "Invoice No") + private String invoiceNo; + /** + * 升 + */ + @ApiModelProperty("升") + @Excel(name = "升") + private String liter; + + /** + * 尺寸 + */ + @ApiModelProperty("尺寸") + @Excel(name = "尺寸") + private String size; + + /** + * 申报单位 + */ + @ApiModelProperty("申报单位") + @Excel(name = "申报单位") + private String declareUnit; + + /** + * Batch Ref NO’s + */ + @ApiModelProperty("Batch Ref NO’s") + @Excel(name = "Batch Ref NO’s") + private String batchRefNo; + + /** + * Sheet Ref NO’s + */ + @ApiModelProperty("Sheet Ref NO’s") + @Excel(name = "Sheet Ref NO’s") + private String sheetRefNo; + + /** + * 原产国 + */ + @ApiModelProperty("原产国") + @Excel(name = "原产国") + private String countryOfOrigin; + + /** + * 箱号/卡板号 + */ + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + /** + * 币制 + */ + @ApiModelProperty("币制") + @Excel(name = "币制") + private String currency; + + /** + * 申报数量 + */ + @ApiModelProperty("申报数量") + @Excel(name = "申报数量") + private BigDecimal declareQuantity; + + /** + * 箱数 + */ + @ApiModelProperty("箱数") + @Excel(name = "箱数") + private BigDecimal caseCount; + + /** + * 件数 + */ + @ApiModelProperty("件数") + @Excel(name = "件数") + private BigDecimal pieceCount; + + /** + * 出库数量 + */ + @ApiModelProperty("出库数量") + @Excel(name = "出库数量") + private BigDecimal outboundQuantity; + + /** + * 总净重(KG) + */ + @ApiModelProperty("总净重(KG)") + @Excel(name = "总净重(KG)") + private BigDecimal totalNetWeight; + + /** + * 总毛重(KG) + */ + @ApiModelProperty("总毛重(KG)") + @Excel(name = "总毛重(KG)") + private BigDecimal totalGrossWeight; + + /** + * 总体积(CBM) + */ + @ApiModelProperty("总体积(CBM)") + @Excel(name = "总体积(CBM)") + private BigDecimal totalVolume; + + /** + * 总面积(SQM) + */ + @ApiModelProperty("总面积(SQM)") + @Excel(name = "总面积(SQM)") + private BigDecimal totalArea; + /** + * 总价 + */ + @ApiModelProperty("总价") + @Excel(name = "总价") + private BigDecimal totalAmount; + + /** + * 单位 + */ + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unit; + + @ApiModelProperty("复核总净重(KG)") + @Excel(name = "复核总净重(KG)") + private BigDecimal checkNetWeight; + + @ApiModelProperty("复核总毛重(KG)") + @Excel(name = "复核总毛重(KG)") + private BigDecimal checkGrossWeight; + + @ApiModelProperty("复核总体积(CBM)") + @Excel(name = "复核总体积(CBM)") + private BigDecimal checkVolume; + + @ApiModelProperty("复核总面积(SQM)") + @Excel(name = "复核总面积(SQM)") + private BigDecimal checkArea; + +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/pickingMaterialDetail/entity/PickingMaterialDetail.java b/mhd_wms/src/main/java/com/mhd/wms/domain/pickingMaterialDetail/entity/PickingMaterialDetail.java index 1a5b8f3f1..3ac13f27b 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/pickingMaterialDetail/entity/PickingMaterialDetail.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/pickingMaterialDetail/entity/PickingMaterialDetail.java @@ -1,6 +1,7 @@ package com.mhd.wms.domain.pickingMaterialDetail.entity; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; @@ -9,7 +10,10 @@ import com.mhd.common.core.web.domain.BaseVOEntity; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; +import java.util.Date; /** @@ -187,5 +191,73 @@ public class PickingMaterialDetail extends BaseVOEntity { @Excel(name = "备注") private String remark; + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; -} + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("扩展字段1") + @Excel(name = "扩展字段1") + @TableField("ext_attr_1") + private String extAttr1; + + @ApiModelProperty("扩展字段2") + @Excel(name = "扩展字段2") + @TableField("ext_attr_2") + private String extAttr2; + + @ApiModelProperty("生产日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date productionDate; + + @ApiModelProperty("过期日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date inventoryDate; + + @ApiModelProperty("ExtAttr3") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr3", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("ext_attr_3") + private Date extAttr3; + + @ApiModelProperty("ExtAttr4") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr4", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("ext_attr_4") + 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; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/pickingMaterialDetail/repository/persistence/PickingMaterialDetailImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/pickingMaterialDetail/repository/persistence/PickingMaterialDetailImpl.java index d3ae71a12..3757a1f66 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/pickingMaterialDetail/repository/persistence/PickingMaterialDetailImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/pickingMaterialDetail/repository/persistence/PickingMaterialDetailImpl.java @@ -141,6 +141,12 @@ public class PickingMaterialDetailImpl extends ServiceImpl materialDetailSerialNumberList; + @ApiModelProperty("物料更多属性列表(批次属性)") + private List materialMoreDetailList; -} + @ApiModelProperty("Invoice No.") + @Excel(name = "Invoice No.") + @TableField(exist = false) + private String invoiceNo; + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("扩展字段1") + @Excel(name = "扩展字段1") + private String extAttr1; + + @ApiModelProperty("扩展字段2") + @Excel(name = "扩展字段2") + private String extAttr2; + + @ApiModelProperty("生产日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date productionDate; + + @ApiModelProperty("过期日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date inventoryDate; + + @ApiModelProperty("ExtAttr3") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr3", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date extAttr3; + + @ApiModelProperty("ExtAttr4") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @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; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/pickingMaterialDetail/repository/todo/PickingMaterialDetailDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/pickingMaterialDetail/repository/todo/PickingMaterialDetailDO.java index f8b9df26d..2f5d1996a 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/pickingMaterialDetail/repository/todo/PickingMaterialDetailDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/pickingMaterialDetail/repository/todo/PickingMaterialDetailDO.java @@ -8,7 +8,10 @@ import com.mhd.wms.domain.outMaterialDetailSerialNumber.repository.todo.OutMater import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; +import java.util.Date; import java.util.List; @@ -205,4 +208,71 @@ public class PickingMaterialDetailDO extends BaseVOEntity { @ApiModelProperty("作业数量:拣货数量") @Excel(name = "作业数量:拣货数量") private BigDecimal actualQuantity; -} + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("扩展字段1") + @Excel(name = "扩展字段1") + private String extAttr1; + + @ApiModelProperty("扩展字段2") + @Excel(name = "扩展字段2") + private String extAttr2; + + @ApiModelProperty("生产日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date productionDate; + + @ApiModelProperty("过期日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date inventoryDate; + + @ApiModelProperty("ExtAttr3") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr3", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date extAttr3; + + @ApiModelProperty("ExtAttr4") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @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; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/pickingOrder/service/PickingOrderDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/pickingOrder/service/PickingOrderDomainService.java index 35966e2cb..440d60afe 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/pickingOrder/service/PickingOrderDomainService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/pickingOrder/service/PickingOrderDomainService.java @@ -20,6 +20,8 @@ import com.mhd.wms.domain.handoverTaskOrder.repository.todo.HandoverTaskOrderDO; import com.mhd.wms.domain.inMaterialDetail.repository.todo.InMaterialDetailDO; import com.mhd.wms.domain.inventoryStandingDetail.repository.facade.IInventoryStandingDetailService; import com.mhd.wms.domain.inventoryStandingDetail.repository.todo.InventoryStandingDetailDO; +import com.mhd.wms.domain.materialBaseInfo.entity.MaterialBaseInfo; +import com.mhd.wms.domain.materialBaseInfo.repository.mapper.MaterialBaseInfoMapper; import com.mhd.wms.domain.materialInventory.entity.MaterialInventory; import com.mhd.wms.domain.materialInventory.repository.facade.IMaterialInventoryService; import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryDO; @@ -111,6 +113,8 @@ public class PickingOrderDomainService { private PushSyncBmsDomainService pushSyncBmsDomainService; @Resource private OutMaterialDetailMapper outMaterialDetailMapper; + @Resource + private MaterialBaseInfoMapper materialBaseInfoMapper; @@ -191,6 +195,14 @@ public class PickingOrderDomainService { PickingMaterialDetailDO pickingMaterialDetailDO = new PickingMaterialDetailDO(); pickingMaterialDetailDO.setPickingOrderNumber(pickingOrderPO.getPickingOrderNumber()); List pickingMaterialDetailPOList = pickingMaterialDetailService.queryList(pickingMaterialDetailDO); + for (PickingMaterialDetailPO pickingMaterialDetailPO : pickingMaterialDetailPOList) { + Long materialBaseInfoId = pickingMaterialDetailPO.getMaterialBaseInfoId(); + MaterialBaseInfo materialBaseInfo = materialBaseInfoMapper.selectById(materialBaseInfoId); + if(materialBaseInfo!=null){ + pickingMaterialDetailPO.setMaterialCode(materialBaseInfo.getMaterialCode()); + pickingMaterialDetailPO.setMaterialName(materialBaseInfo.getMaterialName()); + } + } pickingOrderPO.setMaterialDetailList(pickingMaterialDetailPOList); return pickingOrderPO; } @@ -276,7 +288,7 @@ public class PickingOrderDomainService { pickingOrderDO.setPickingOrderNumber(pickingOrderPODb.getPickingOrderNumber()); PickingOrderPO pickingOrderPO = pickingMaterialDetailService.batchPickingUpdate(pickingOrderDO); //修改库存 - updateMaterialInventory(pickingOrderDO); + //updateMaterialInventory(pickingOrderDO); //设置拣货单拣货需要更新的数据数据 updatePickingOrder(pickingOrderPO, pickingOrderPODb); //更新出库单状态 @@ -749,4 +761,4 @@ public class PickingOrderDomainService { } deliveTaskService.batchInsert(deliveTaskDOList); } -} +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/entity/ReceiptMaterialDetail.java b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/entity/ReceiptMaterialDetail.java index 0a60ce242..33372633e 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/entity/ReceiptMaterialDetail.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/entity/ReceiptMaterialDetail.java @@ -1,7 +1,9 @@ package com.mhd.wms.domain.receiptMaterialDetail.entity; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.mhd.common.core.annotation.Excel; @@ -10,6 +12,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; +import java.util.Date; /** @@ -214,5 +217,117 @@ public class ReceiptMaterialDetail extends BaseVOEntity { @Excel(name = "备注") private String remark; + @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; + + @ApiModelProperty("Invoice No.") + @Excel(name = "Invoice No.") + private String invoiceNo; + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("生产日期") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date productionDate; + + @ApiModelProperty("过期日期") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date inventoryDate; + + @ApiModelProperty("扩展属性1") + @Excel(name = "扩展属性1") + @TableField("ext_attr_1") + private String extAttr1; + + @ApiModelProperty("扩展属性2") + @Excel(name = "扩展属性2") + @TableField("ext_attr_2") + private String extAttr2; + + @ApiModelProperty("扩展属性3") + @Excel(name = "扩展属性3") + @TableField("ext_attr_3") + private String extAttr3; + + @ApiModelProperty("扩展属性4") + @Excel(name = "扩展属性4") + @TableField("ext_attr_4") + private String extAttr4; + + @ApiModelProperty("申报数量") + @Excel(name = "申报数量") + @TableField(exist = false) + private BigDecimal declaredQuantity; + + @ApiModelProperty("申报单位") + @Excel(name = "申报单位") + @TableField(exist = false) + private String declarationUnit; + + @ApiModelProperty("原产国") + @Excel(name = "原产国") + @TableField(exist = false) + private String originCountry; + + @ApiModelProperty("币制") + @Excel(name = "币制") + @TableField(exist = false) + private String currency; + + @ApiModelProperty("单位") + @Excel(name = "单位") + @TableField(exist = false) + private String unit; + + @ApiModelProperty("升") + @Excel(name = "升") + @TableField(exist = false) + private BigDecimal liter; + + @ApiModelProperty("尺寸") + @Excel(name = "尺寸") + @TableField(exist = false) + private String dimensions; + + @ApiModelProperty("箱数") + @Excel(name = "箱数") + @TableField(exist = false) + private BigDecimal boxCount; + + @ApiModelProperty("件数") + @Excel(name = "件数") + @TableField(exist = false) + private BigDecimal pieceCount; + + +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/persistence/ReceiptMaterialDetailImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/persistence/ReceiptMaterialDetailImpl.java index 21a076543..8c9d92940 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/persistence/ReceiptMaterialDetailImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/persistence/ReceiptMaterialDetailImpl.java @@ -7,13 +7,19 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.mhd.common.core.constant.SnowFlakeConstants; import com.mhd.common.core.exception.ServiceException; +import com.mhd.common.core.utils.DateUtils; import com.mhd.common.core.utils.IgnoreNullUtil; import com.mhd.common.core.utils.OrderSequence; import com.mhd.common.core.utils.uuid.IdGenerator; import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.SystemServiceFeign; +import com.mhd.system.api.domain.BatchDetailFeignPO; import com.mhd.system.api.model.LoginUser; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +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.entity.InMaterialDetailSerialNumber; import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.facade.IInMaterialDetailSerialNumberService; import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.todo.InMaterialDetailSerialNumberDO; @@ -29,16 +35,25 @@ import com.mhd.wms.domain.receiptMaterialDetail.repository.todo.ReceiptMaterialD import com.mhd.wms.domain.stockReceiptOrder.entity.StockReceiptOrder; import com.mhd.wms.domain.stockReceiptOrder.repository.mapper.StockReceiptOrderMapper; import com.mhd.wms.domain.stockReceiptOrder.repository.todo.StockReceiptOrderDO; +import com.mhd.wms.domain.materialInventory.entity.MaterialInventory; +import com.mhd.wms.domain.materialInventory.repository.facade.IMaterialInventoryService; +import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryDO; +import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; +import com.mhd.common.core.utils.StringUtils; +import lombok.extern.slf4j.Slf4j; import javax.annotation.Resource; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; /** @@ -47,6 +62,7 @@ import java.util.stream.Collectors; * @author gen * @date 2024-06-17 */ +@Slf4j @Service public class ReceiptMaterialDetailImpl extends ServiceImpl implements IReceiptMaterialDetailService{ @Autowired @@ -58,9 +74,17 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl children = getChildren(materialDetailPO.getUniqueId(), receiptMaterialDetailPOList, 2); children.forEach(childrenDetailPO -> { MaterialMoreDetailDO materialMoreDetailDO = new MaterialMoreDetailDO(); - materialMoreDetailDO.setMaterialDetailUniqueId(childrenDetailPO.getMaterialDetailId()); + materialMoreDetailDO.setMaterialDetailUniqueId(childrenDetailPO.getUniqueId()); List materialMoreDetailList = IMaterialMoreDetailService.queryList(materialMoreDetailDO); //如果收货单的物料批属性还没存入值,那么需要从批属性表获取 AjaxResult ajaxResult = null; if (CollectionUtils.isEmpty(materialMoreDetailList)) { - ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(childrenDetailPO.getMaterialDetailId()); - - } - if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { - materialMoreDetailList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), MaterialMoreDetailPO.class); + ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(childrenDetailPO.getMaterialBaseInfoId()); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + materialMoreDetailList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), MaterialMoreDetailPO.class); + } } + // 从入库单明细表中获取InvoiceNo、BatchRefNo、SheetRefNo、BoxPalletNo字段的值 + fillAttributeValueFromInMaterialDetail(childrenDetailPO, materialMoreDetailList); childrenDetailPO.setMaterialMoreDetailList(materialMoreDetailList); }); @@ -195,12 +222,94 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl stockInOrderList = stockInOrderService.queryList(stockInOrderDO); + if (!CollectionUtils.isEmpty(stockInOrderList)) { + shipperId = stockInOrderList.get(0).getShipperId(); + } + } catch (Exception e) { + // 如果获取失败,记录日志但继续处理 + } + } + //批量新增或修改物料信息 List receiptMaterialDetailList = new ArrayList<>(); // 批量修改更多属性和新增序列号 List materialMoreDetailList = new ArrayList<>(); List materialDetailSerialNumberList = new ArrayList<>(); for (ReceiptMaterialDetailDO receiptMaterialDetailDO : receiptMaterialDetailDOList){ + List materialMoreDetailList1 = receiptMaterialDetailDO.getMaterialMoreDetailList(); + for (MaterialMoreDetailDO materialMoreDetailDO : materialMoreDetailList1) { + String batchLabels = materialMoreDetailDO.getBatchLabels(); + String attributeValue = materialMoreDetailDO.getAttributeValue(); + if (attributeValue != null && !attributeValue.isEmpty() && attributeValue != "" && attributeValue.length() > 0 ) { + attributeValue = attributeValue.trim(); + switch (batchLabels) { + case "扩展字段4": + receiptMaterialDetailDO.setExtAttr4(attributeValue); + break; + case "扩展字段3": + receiptMaterialDetailDO.setExtAttr3(attributeValue); + break; + case "扩展字段2": + receiptMaterialDetailDO.setExtAttr2(attributeValue); + break; + case "扩展字段1": + receiptMaterialDetailDO.setExtAttr1(attributeValue); + break; + case "箱号/卡板号": + receiptMaterialDetailDO.setBoxPalletNo(attributeValue); + break; + case "Sheet Ref NO's": + receiptMaterialDetailDO.setSheetRefNo(attributeValue); + break; + case "Batch Ref NO's": + receiptMaterialDetailDO.setBatchRefNo(attributeValue); + break; + case "存货日期": + // 判断是否是日期格式再赋值避免报错 + try { + if (attributeValue.matches("\\d{4}-\\d{2}-\\d{2}.*")) { + receiptMaterialDetailDO.setInventoryDate(DateUtils.parseDate(attributeValue)); + } + } catch (Exception e) { + log.warn("库存日期格式转换失败,物料:{},原始值:{}", receiptMaterialDetailDO.getMaterialName(), attributeValue); + } + //receiptMaterialDetailDO.setInventoryDate(DateUtils.parseDate(attributeValue)); + break; + case "过期日期": + // 判断是否是日期格式再赋值避免报错 + try { + if (attributeValue.matches("\\d{4}-\\d{2}-\\d{2}.*")) { + receiptMaterialDetailDO.setExpiryDate(DateUtils.parseDate(attributeValue)); + } + } catch (Exception e) { + log.warn("库存日期格式转换失败,物料:{},原始值:{}", receiptMaterialDetailDO.getMaterialName(), attributeValue); + } + //receiptMaterialDetailDO.setExpiryDate(DateUtils.parseDate(attributeValue)); + break; + case "生产日期": + // 判断是否是日期格式再赋值避免报错 + try { + if (attributeValue.matches("\\d{4}-\\d{2}-\\d{2}.*")) { + receiptMaterialDetailDO.setProductionDate(DateUtils.parseDate(attributeValue)); + } + } catch (Exception e) { + log.warn("库存日期格式转换失败,物料:{},原始值:{}", receiptMaterialDetailDO.getMaterialName(), attributeValue); + } + //receiptMaterialDetailDO.setProductionDate(DateUtils.parseDate(attributeValue)); + break; + } + } + } + // 自动生成批次号并校验唯一性(包括子项) + generateAndValidateBatchNumber(receiptMaterialDetailDO, shipperId); //更多属性 materialMoreDetailList.addAll(genMaterialMoreDetail(receiptMaterialDetailDO)); //序列号 @@ -253,6 +362,258 @@ public class ReceiptMaterialDetailImpl extends ServiceImplfieldName映射,兼容attributeOption) + updateInMaterialDetailFromAttributeOption(receiptMaterialDetailDOList); + } + + /** + * @description 从materialMoreDetailList中根据attributeOption提取字段值并更新入库单明细 + * @author Auto + * @date 2026/1/24 + * @param receiptMaterialDetailDOList + * @return void + */ + private void updateInMaterialDetailFromAttributeOption(List receiptMaterialDetailDOList) { + if (CollectionUtils.isEmpty(receiptMaterialDetailDOList)) { + return; + } + // 缓存:materialBaseInfoId -> (batchDetailId -> fieldName) + Map> batchFieldNameCache = new HashMap<>(); + updateInMaterialDetailFromAttributeOption(receiptMaterialDetailDOList, batchFieldNameCache); + } + + private void updateInMaterialDetailFromAttributeOption(List receiptMaterialDetailDOList, + Map> batchFieldNameCache) { + if (CollectionUtils.isEmpty(receiptMaterialDetailDOList)) { + return; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + for (ReceiptMaterialDetailDO receiptMaterialDetailDO : receiptMaterialDetailDOList) { + Long inUniqueId = receiptMaterialDetailDO.getInUniqueId(); + if (inUniqueId == null) { + // 处理子项 + List children = receiptMaterialDetailDO.getChildren(); + if (!CollectionUtils.isEmpty(children)) { + updateInMaterialDetailFromAttributeOption(children, batchFieldNameCache); + } + continue; + } + + List materialMoreDetailList = receiptMaterialDetailDO.getMaterialMoreDetailList(); + if (CollectionUtils.isEmpty(materialMoreDetailList)) { + // 处理子项 + List children = receiptMaterialDetailDO.getChildren(); + if (!CollectionUtils.isEmpty(children)) { + updateInMaterialDetailFromAttributeOption(children, batchFieldNameCache); + } + continue; + } + + // 构建UpdateWrapper(用列名动态set) + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("unique_id", inUniqueId); + boolean hasUpdate = false; + + // 构建 batchDetailId -> fieldName 映射(按物料维度缓存) + Map batchDetailIdToFieldName = null; + Long materialBaseInfoId = receiptMaterialDetailDO.getMaterialBaseInfoId(); + if (materialBaseInfoId != null) { + batchDetailIdToFieldName = batchFieldNameCache.get(materialBaseInfoId); + if (batchDetailIdToFieldName == null) { + batchDetailIdToFieldName = loadBatchDetailIdToFieldName(materialBaseInfoId); + batchFieldNameCache.put(materialBaseInfoId, batchDetailIdToFieldName); + } + } + + for (MaterialMoreDetailDO materialMoreDetail : materialMoreDetailList) { + String attributeValue = materialMoreDetail.getAttributeValue(); + if (StringUtils.isBlank(attributeValue)) { + continue; + } + + String fieldName = null; + Long batchDetailId = materialMoreDetail.getBatchDetailId(); + if (batchDetailId != null && batchDetailIdToFieldName != null) { + fieldName = batchDetailIdToFieldName.get(batchDetailId); + } + + // 兼容旧逻辑:fieldName取不到时用attributeOption(例如 InvoiceNo -> invoiceNo) + if (StringUtils.isBlank(fieldName)) { + String attributeOption = materialMoreDetail.getAttributeOption(); + fieldName = lowerFirst(attributeOption); + } + + if (StringUtils.isBlank(fieldName)) { + continue; + } + + // camelCase -> snake_case 列名 + String columnName = camelToSnake(fieldName); + if (StringUtils.isBlank(columnName)) { + continue; + } + + // 数字字段尝试转BigDecimal,其它按String + Object val = coerceInMaterialDetailValue(fieldName, attributeValue); + updateWrapper.set(columnName, val); + hasUpdate = true; + } + + if (hasUpdate) { + updateWrapper + .set("update_by", loginUser.getUserid()) + .set("update_by_name", loginUser.getUsername()) + .set("update_time", new Date()); + iInMaterialDetailService.update(updateWrapper); + } + + // 处理子项 + List children = receiptMaterialDetailDO.getChildren(); + if (!CollectionUtils.isEmpty(children)) { + updateInMaterialDetailFromAttributeOption(children, batchFieldNameCache); + } + } + } + + private Map loadBatchDetailIdToFieldName(Long materialBaseInfoId) { + Map result = new HashMap<>(); + try { + AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId); + if (ajaxResult == null || !"200".equals(String.valueOf(ajaxResult.get("code")))) { + return result; + } + List list = JSON.parseArray(JSON.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class); + if (CollectionUtils.isEmpty(list)) { + return result; + } + for (BatchDetailFeignPO po : list) { + if (po.getBatchDetailId() == null) { + continue; + } + String fieldName = po.getFieldName(); + if (StringUtils.isBlank(fieldName)) { + // 兼容:fieldName为空时尝试用attributeOption + fieldName = lowerFirst(po.getAttributeOption()); + } + if (StringUtils.isNotBlank(fieldName)) { + result.put(po.getBatchDetailId(), fieldName); + } + } + } catch (Exception e) { + log.warn("加载批次属性fieldName失败,materialBaseInfoId:{},错误:{}", materialBaseInfoId, e.getMessage()); + } + return result; + } + + private String lowerFirst(String s) { + if (StringUtils.isBlank(s)) { + return null; + } + if (s.length() == 1) { + return s.toLowerCase(); + } + return s.substring(0, 1).toLowerCase() + s.substring(1); + } + + private String camelToSnake(String camel) { + if (StringUtils.isBlank(camel)) { + return null; + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < camel.length(); i++) { + char c = camel.charAt(i); + if (Character.isUpperCase(c)) { + if (i > 0) { + sb.append('_'); + } + sb.append(Character.toLowerCase(c)); + } else { + sb.append(c); + } + } + return sb.toString(); + } + + private Object coerceInMaterialDetailValue(String fieldName, String raw) { + if (raw == null) { + return null; + } + // 这些字段在库里通常是NUMBER + if ("liter".equals(fieldName) + || "declaredQuantity".equals(fieldName) + || "boxCount".equals(fieldName) + || "pieceCount".equals(fieldName) + || "totalNetWeight".equals(fieldName) + || "totalGrossWeight".equals(fieldName) + || "totalVolume".equals(fieldName) + || "totalArea".equals(fieldName)) { + try { + return new BigDecimal(raw.trim()); + } catch (Exception ignored) { + return raw; + } + } + return raw; + } + + /** + * @description 从入库单明细表中获取InvoiceNo、BatchRefNo、SheetRefNo、BoxPalletNo字段的值并填充到materialMoreDetailList的attributeValue中 + * @author Auto + * @date 2026/1/24 + * @param receiptMaterialDetailPO + * @param materialMoreDetailList + * @return void + */ + private void fillAttributeValueFromInMaterialDetail(ReceiptMaterialDetailPO receiptMaterialDetailPO, List materialMoreDetailList) { + if (receiptMaterialDetailPO.getInUniqueId() == null) { + return; + } + // 查询入库单明细 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("unique_id", receiptMaterialDetailPO.getInUniqueId()); + queryWrapper.eq("del_flag", 1); + InMaterialDetail inMaterialDetail = iInMaterialDetailService.getOne(queryWrapper); + if (inMaterialDetail == null) { + return; + } + + // 如果收货单明细中的料号、物料名称、规格型号、批次号为空,则从入库单明细中获取 + if (StringUtils.isBlank(receiptMaterialDetailPO.getMaterialCode()) && StringUtils.isNotBlank(inMaterialDetail.getMaterialCode())) { + receiptMaterialDetailPO.setMaterialCode(inMaterialDetail.getMaterialCode()); + } + if (StringUtils.isBlank(receiptMaterialDetailPO.getMaterialName()) && StringUtils.isNotBlank(inMaterialDetail.getMaterialName())) { + receiptMaterialDetailPO.setMaterialName(inMaterialDetail.getMaterialName()); + } + if (StringUtils.isBlank(receiptMaterialDetailPO.getSpecificationModel()) && StringUtils.isNotBlank(inMaterialDetail.getSpecificationModel())) { + receiptMaterialDetailPO.setSpecificationModel(inMaterialDetail.getSpecificationModel()); + } + if (StringUtils.isBlank(receiptMaterialDetailPO.getBatchNumber()) && StringUtils.isNotBlank(inMaterialDetail.getBatchNumber())) { + receiptMaterialDetailPO.setBatchNumber(inMaterialDetail.getBatchNumber()); + } + + // 如果materialMoreDetailList为空,直接返回 + if (CollectionUtils.isEmpty(materialMoreDetailList)) { + return; + } + + // 根据attributeOption从入库单明细中获取对应的值并填充到attributeValue + for (MaterialMoreDetailPO materialMoreDetail : materialMoreDetailList) { + String attributeOption = materialMoreDetail.getAttributeOption(); + // 如果attributeValue已经有值,跳过 + if (materialMoreDetail.getAttributeValue() != null && !materialMoreDetail.getAttributeValue().trim().isEmpty()) { + continue; + } + // 根据attributeOption映射到入库单明细表的字段 + if ("InvoiceNo".equalsIgnoreCase(attributeOption)) { + materialMoreDetail.setAttributeValue(inMaterialDetail.getInvoiceNo()); + } else if ("BatchRefNo".equalsIgnoreCase(attributeOption)) { + materialMoreDetail.setAttributeValue(inMaterialDetail.getBatchRefNo()); + } else if ("SheetRefNo".equalsIgnoreCase(attributeOption)) { + materialMoreDetail.setAttributeValue(inMaterialDetail.getSheetRefNo()); + } else if ("BoxPalletNo".equalsIgnoreCase(attributeOption)) { + materialMoreDetail.setAttributeValue(inMaterialDetail.getBoxPalletNo()); + } + } } @@ -426,4 +787,84 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl children = receiptMaterialDetailDO.getChildren(); + if (!CollectionUtils.isEmpty(children)) { + for (ReceiptMaterialDetailDO child : children) { + generateAndValidateBatchNumber(child, shipperId); + } + } + } + + /** + * @description 为单个收货明细生成批次号并校验唯一性 + * @author Auto + * @date 2026/1/28 + * @param receiptMaterialDetailDO 收货明细 + * @param shipperId 货主ID + * @return void + */ + private void processBatchNumberForDetail(ReceiptMaterialDetailDO receiptMaterialDetailDO, Long shipperId) { + if (receiptMaterialDetailDO == null) { + return; + } + + Long materialBaseInfoId = receiptMaterialDetailDO.getMaterialBaseInfoId(); + String materialStatusCode = receiptMaterialDetailDO.getMaterialStatusCode(); + String batchNumber = receiptMaterialDetailDO.getBatchNumber(); + + // 如果批次号为空,自动生成 + if (batchNumber == null || batchNumber.trim().isEmpty()) { + batchNumber = OrderSequence.getOrderCode("PC"); // PC = 批次号前缀 + receiptMaterialDetailDO.setBatchNumber(batchNumber); + } + + // 校验批次号唯一性:货主+商品+库存属性值相同时,批次号不能重复 + if (shipperId != null && materialBaseInfoId != null && batchNumber != null && !batchNumber.trim().isEmpty()) { + // 使用 LambdaQueryWrapper 查询库存表中是否存在相同的货主+商品+库存属性值+批次号的记录 + com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper wrapper = + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(MaterialInventory::getShipperId, shipperId) + .eq(MaterialInventory::getMaterialBaseInfoId, materialBaseInfoId) + .eq(MaterialInventory::getBatchNumber, batchNumber) + .eq(MaterialInventory::getDelFlag, 1); + + // 如果库存属性值不为空,需要精确匹配;如果为空,查询库存属性值为空或null的记录 + if (materialStatusCode != null && !materialStatusCode.trim().isEmpty()) { + wrapper.eq(MaterialInventory::getMaterialStatusCode, materialStatusCode); + } else { + // 如果库存属性值为空,查询库存属性值为null或空字符串的记录 + wrapper.and(w -> w.isNull(MaterialInventory::getMaterialStatusCode) + .or() + .eq(MaterialInventory::getMaterialStatusCode, "")); + } + + List existingInventoryList = materialInventoryMapper.selectList(wrapper); + + // 如果存在相同的货主+商品+库存属性值+批次号的记录,抛出异常 + if (!CollectionUtils.isEmpty(existingInventoryList)) { + String statusCodeDesc = (materialStatusCode != null && !materialStatusCode.trim().isEmpty()) + ? ",库存属性值:" + materialStatusCode + : ",库存属性值:空"; + throw new ServiceException("批次号【" + batchNumber + "】已存在,货主ID【" + shipperId + "】+商品ID【" + materialBaseInfoId + "】" + statusCodeDesc + "相同的记录不允许使用重复的批次号"); + } + } + } + +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/po/ReceiptMaterialDetailPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/po/ReceiptMaterialDetailPO.java index 2d68494c2..d0a122512 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/po/ReceiptMaterialDetailPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/po/ReceiptMaterialDetailPO.java @@ -12,6 +12,8 @@ import lombok.Data; import java.math.BigDecimal; import java.util.List; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; /** @@ -66,6 +68,10 @@ public class ReceiptMaterialDetailPO extends BaseVOEntity { @Excel(name = "物料条形码") private String barCode; + @ApiModelProperty("规格型号") + @Excel(name = "规格型号") + private String specificationModel; + @ApiModelProperty("计划数量") @Excel(name = "计划数量") private BigDecimal quantity; @@ -216,6 +222,69 @@ public class ReceiptMaterialDetailPO extends BaseVOEntity { @Excel(name = "是否生成上架单: 1-是 2-否") private Integer genStockShelf; + @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; + + @ApiModelProperty("Invoice No.") + @Excel(name = "Invoice No.") + private String invoiceNo; + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("生产日期") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date productionDate; + + @ApiModelProperty("过期日期") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date inventoryDate; + + @ApiModelProperty("扩展属性1") + @Excel(name = "扩展属性1") + private String extAttr1; + + @ApiModelProperty("扩展属性2") + @Excel(name = "扩展属性2") + private String extAttr2; + + @ApiModelProperty("扩展属性3") + @Excel(name = "扩展属性3") + private String extAttr3; + + @ApiModelProperty("扩展属性4") + @Excel(name = "扩展属性4") + private String extAttr4; + @ApiModelProperty("物料明细子集") private List children; diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/todo/ReceiptMaterialDetailDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/todo/ReceiptMaterialDetailDO.java index d00d21761..29aa26dc5 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/todo/ReceiptMaterialDetailDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/todo/ReceiptMaterialDetailDO.java @@ -11,6 +11,8 @@ import lombok.Data; import java.math.BigDecimal; import java.util.List; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; /** @@ -64,6 +66,10 @@ public class ReceiptMaterialDetailDO extends BaseVOEntity { @Excel(name = "物料条形码") private String barCode; + @ApiModelProperty("规格型号") + @Excel(name = "规格型号") + private String specificationModel; + @ApiModelProperty("计划数量") @Excel(name = "计划数量") private BigDecimal quantity; @@ -214,6 +220,69 @@ public class ReceiptMaterialDetailDO extends BaseVOEntity { @Excel(name = "是否生成上架单: 1-是 2-否") private Integer genStockShelf; + @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; + + @ApiModelProperty("Invoice No.") + @Excel(name = "Invoice No.") + private String invoiceNo; + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("生产日期") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date productionDate; + + @ApiModelProperty("过期日期") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date inventoryDate; + + @ApiModelProperty("扩展属性1") + @Excel(name = "扩展属性1") + private String extAttr1; + + @ApiModelProperty("扩展属性2") + @Excel(name = "扩展属性2") + private String extAttr2; + + @ApiModelProperty("扩展属性3") + @Excel(name = "扩展属性3") + private String extAttr3; + + @ApiModelProperty("扩展属性4") + @Excel(name = "扩展属性4") + private String extAttr4; + @ApiModelProperty(name = "组织ID集合") private List organizationIdList; diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/shelfMaterialDetail/entity/ShelfMaterialDetail.java b/mhd_wms/src/main/java/com/mhd/wms/domain/shelfMaterialDetail/entity/ShelfMaterialDetail.java index 792fe26bc..76e627527 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/shelfMaterialDetail/entity/ShelfMaterialDetail.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/shelfMaterialDetail/entity/ShelfMaterialDetail.java @@ -1,15 +1,19 @@ package com.mhd.wms.domain.shelfMaterialDetail.entity; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.mhd.common.core.annotation.Excel; import com.mhd.common.core.web.domain.BaseVOEntity; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; +import java.util.Date; /** @@ -249,5 +253,76 @@ public class ShelfMaterialDetail extends BaseVOEntity { @Excel(name = "备注") private String remark; + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; -} + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("扩展字段1") + @Excel(name = "扩展字段1") + @TableField("ext_attr_1") + private String extAttr1; + + @ApiModelProperty("扩展字段2") + @Excel(name = "扩展字段2") + @TableField("ext_attr_2") + private String extAttr2; + + @ApiModelProperty("生产日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("production_date") + private Date productionDate; + + @ApiModelProperty("过期日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("expiry_date") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("inventory_date") + private Date inventoryDate; + + @ApiModelProperty("ExtAttr3") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr3", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("ext_attr_3") + private Date extAttr3; + + @ApiModelProperty("ExtAttr4") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr4", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + @TableField("ext_attr_4") + 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; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/shelfMaterialDetail/repository/persistence/ShelfMaterialDetailImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/shelfMaterialDetail/repository/persistence/ShelfMaterialDetailImpl.java index 90774252e..d10b0a559 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/shelfMaterialDetail/repository/persistence/ShelfMaterialDetailImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/shelfMaterialDetail/repository/persistence/ShelfMaterialDetailImpl.java @@ -1,12 +1,19 @@ package com.mhd.wms.domain.shelfMaterialDetail.repository.persistence; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.mhd.common.core.exception.ServiceException; +import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.SystemServiceFeign; import com.mhd.system.api.model.LoginUser; import com.mhd.wms.domain.inMaterialDetailSerialNumber.entity.InMaterialDetailSerialNumber; import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.facade.IInMaterialDetailSerialNumberService; import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.todo.InMaterialDetailSerialNumberDO; +import com.mhd.wms.domain.materialMoreDetail.repository.facade.IMaterialMoreDetailService; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; +import com.mhd.wms.domain.materialMoreDetail.repository.todo.MaterialMoreDetailDO; import com.mhd.wms.domain.shelfMaterialDetail.entity.ShelfMaterialDetail; import com.mhd.wms.domain.shelfMaterialDetail.repository.facade.IShelfMaterialDetailService; import com.mhd.wms.domain.shelfMaterialDetail.repository.mapper.ShelfMaterialDetailMapper; @@ -19,6 +26,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; +import javax.annotation.Resource; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; @@ -37,6 +45,10 @@ public class ShelfMaterialDetailImpl extends ServiceImpl queryListChildren(ShelfMaterialDetailDO shelfMaterialDetailDO) { List shelfMaterialDetailPOList = shelfMaterialDetailMapper.queryList(shelfMaterialDetailDO); + //回显带上更多属性值(批次标签) + shelfMaterialDetailPOList.forEach(shelfMaterialDetailPO -> { + MaterialMoreDetailDO materialMoreDetailDO = new MaterialMoreDetailDO(); + materialMoreDetailDO.setMaterialDetailUniqueId(shelfMaterialDetailPO.getUniqueId()); + List materialMoreDetailList = IMaterialMoreDetailService.queryList(materialMoreDetailDO); + //如果上架单的物料批属性还没存入值,那么需要从批属性表获取 + AjaxResult ajaxResult = null; + if (CollectionUtils.isEmpty(materialMoreDetailList)) { + ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(shelfMaterialDetailPO.getMaterialBaseInfoId()); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + materialMoreDetailList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), MaterialMoreDetailPO.class); + } + } + shelfMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList); + }); + // 获取查询的层级 List receiptMaterialDetailPOParentList = shelfMaterialDetailPOList .stream().filter(e -> 1 == e.getLevel()).collect(Collectors.toList()); // 递归查询子集 - receiptMaterialDetailPOParentList.forEach(materialDetailPO -> materialDetailPO.setChildren(getChildren(materialDetailPO.getUniqueId(), shelfMaterialDetailPOList, 2))); + for(ShelfMaterialDetailPO materialDetailPO : receiptMaterialDetailPOParentList){ + List children = getChildren(materialDetailPO.getUniqueId(), shelfMaterialDetailPOList, 2); + children.forEach(childrenDetailPO -> { + MaterialMoreDetailDO materialMoreDetailDO = new MaterialMoreDetailDO(); + materialMoreDetailDO.setMaterialDetailUniqueId(childrenDetailPO.getUniqueId()); + List materialMoreDetailList = IMaterialMoreDetailService.queryList(materialMoreDetailDO); + //如果上架单的物料批属性还没存入值,那么需要从批属性表获取 + AjaxResult ajaxResult = null; + if (CollectionUtils.isEmpty(materialMoreDetailList)) { + ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(childrenDetailPO.getMaterialBaseInfoId()); + if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) { + materialMoreDetailList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), MaterialMoreDetailPO.class); + } + } + childrenDetailPO.setMaterialMoreDetailList(materialMoreDetailList); + }); + materialDetailPO.setChildren(children); + } return receiptMaterialDetailPOParentList; } @@ -147,7 +192,7 @@ public class ShelfMaterialDetailImpl extends ServiceImpl inMaterialDetailDOChildList = shelfMaterialDetailDO.getChildren(); List shelfMaterialDetailChildList = new ArrayList<>(); @@ -167,7 +212,8 @@ public class ShelfMaterialDetailImpl extends ServiceImpl materialDetailSerialNumberList; + @ApiModelProperty("更多属性") + private List materialMoreDetailList; -} + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("扩展字段1") + @Excel(name = "扩展字段1") + private String extAttr1; + + @ApiModelProperty("扩展字段2") + @Excel(name = "扩展字段2") + private String extAttr2; + + @ApiModelProperty("生产日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date productionDate; + + @ApiModelProperty("过期日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date inventoryDate; + + @ApiModelProperty("ExtAttr3") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr3", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date extAttr3; + + @ApiModelProperty("ExtAttr4") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @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; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/shelfMaterialDetail/repository/todo/ShelfMaterialDetailDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/shelfMaterialDetail/repository/todo/ShelfMaterialDetailDO.java index f1d120b78..c60aa76ab 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/shelfMaterialDetail/repository/todo/ShelfMaterialDetailDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/shelfMaterialDetail/repository/todo/ShelfMaterialDetailDO.java @@ -1,5 +1,6 @@ package com.mhd.wms.domain.shelfMaterialDetail.repository.todo; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.mhd.common.core.annotation.Excel; @@ -7,8 +8,10 @@ import com.mhd.common.core.web.domain.BaseVOEntity; import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.todo.InMaterialDetailSerialNumberDO; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; +import java.util.Date; import java.util.List; @@ -263,4 +266,70 @@ public class ShelfMaterialDetailDO extends BaseVOEntity { @ApiModelProperty("序列号") private List materialDetailSerialNumberList; -} + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("扩展字段1") + @Excel(name = "扩展字段1") + private String extAttr1; + + @ApiModelProperty("扩展字段2") + @Excel(name = "扩展字段2") + private String extAttr2; + + @ApiModelProperty("生产日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date productionDate; + + @ApiModelProperty("过期日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date inventoryDate; + + @ApiModelProperty("ExtAttr3") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr3", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date extAttr3; + + @ApiModelProperty("ExtAttr4") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @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; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/shiftManage/repository/persistence/ShiftManageImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/shiftManage/repository/persistence/ShiftManageImpl.java index 2f52486c6..1e0f11c85 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/shiftManage/repository/persistence/ShiftManageImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/shiftManage/repository/persistence/ShiftManageImpl.java @@ -106,6 +106,7 @@ public class ShiftManageImpl extends ServiceImpl LoginUser loginUser = SecurityUtils.getLoginUser(); List shiftMaterialDetailList =new ArrayList<>(); shiftMaterialDetailDOList.forEach(e -> { + String newStorageLocationName = e.getNewStorageLocationName(); //设置库存信息 setMaterialInventory(e); //设置库位信息 @@ -126,10 +127,17 @@ public class ShiftManageImpl extends ServiceImpl e.setSerialNumberManage(e.getSerialNumberManage()); ShiftMaterialDetail shiftMaterialDetail = new ShiftMaterialDetail(); BeanUtils.copyProperties(e, shiftMaterialDetail); + shiftMaterialDetail.setNewStorageLocationName(newStorageLocationName); shiftMaterialDetailList.add(shiftMaterialDetail); }); iShiftMaterialDetailService.saveBatch(shiftMaterialDetailList); - return this.save(shiftManage); + Boolean b; + if (shiftManage.getShiftManageId() == null){ + b = this.save(shiftManage); + }else { + b = this.updateById(shiftManage); + } + return b; } /** diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/shiftMaterialDetail/repository/po/ShiftMaterialDetailPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/shiftMaterialDetail/repository/po/ShiftMaterialDetailPO.java index 6bd63cb60..1e71768f1 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/shiftMaterialDetail/repository/po/ShiftMaterialDetailPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/shiftMaterialDetail/repository/po/ShiftMaterialDetailPO.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.mhd.common.core.annotation.Excel; import com.mhd.common.core.web.domain.BaseVOEntity; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import com.mhd.wms.domain.outMaterialDetailSerialNumber.repository.po.OutMaterialDetailSerialNumberPO; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @@ -250,5 +251,8 @@ public class ShiftMaterialDetailPO extends BaseVOEntity { @ApiModelProperty("序列号") private List materialDetailSerialNumberList; + @ApiModelProperty("更多属性明细列表") + @TableField(exist = false) + private List materialMoreDetailList; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/statementStatistics/po/ImmediateInventoryPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/statementStatistics/po/ImmediateInventoryPO.java index 081b2dc04..205eb5638 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/statementStatistics/po/ImmediateInventoryPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/statementStatistics/po/ImmediateInventoryPO.java @@ -1,14 +1,24 @@ package com.mhd.wms.domain.statementStatistics.po; +import com.fasterxml.jackson.annotation.JsonFormat; import com.mhd.common.core.annotation.Excel; +import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; +import java.util.Date; +import java.util.List; @Data public class ImmediateInventoryPO { + @ApiModelProperty("物料库存id") + private Long materialInventoryId; + + @ApiModelProperty("物料基础信息id") + private Long materialBaseInfoId; @ApiModelProperty("仓库名称") @Excel(name = "仓库名称") @@ -56,4 +66,54 @@ public class ImmediateInventoryPO { @Excel(name = "拣货数量") private BigDecimal pickQuantity; -} + + @ApiModelProperty("复核数量") + @Excel(name = "复核数量") + private BigDecimal checkQuantity; + + //批次属性字段 + @ApiModelProperty("Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("扩展字段1") + private String extAttr1; + + @ApiModelProperty("扩展字段2") + private String extAttr2; + + @ApiModelProperty("生产日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date productionDate; + + @ApiModelProperty("过期日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date inventoryDate; + + @ApiModelProperty("ExtAttr3") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date extAttr3; + + @ApiModelProperty("ExtAttr4") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date extAttr4; + + @ApiModelProperty("物料更多属性列表(批次属性)") + private List materialMoreDetailList; + + +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/statementStatistics/todo/ImmediateInventoryDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/statementStatistics/todo/ImmediateInventoryDO.java index 6941c7ffd..df7079c49 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/statementStatistics/todo/ImmediateInventoryDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/statementStatistics/todo/ImmediateInventoryDO.java @@ -69,6 +69,10 @@ public class ImmediateInventoryDO extends BaseVOEntity { @Excel(name = "库存数量") private BigDecimal inventoryQuantity; + @ApiModelProperty("复核数量") + @Excel(name = "复核数量") + private BigDecimal checkQuantity; + @ApiModelProperty("可用数量 ") @Excel(name = "可用数量 ") private BigDecimal allocationQuantity; @@ -144,4 +148,4 @@ public class ImmediateInventoryDO extends BaseVOEntity { @Excel(name = "拣货数量结束") private BigDecimal pickQuantityEnd; -} +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/entity/StockInOrder.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/entity/StockInOrder.java index 9dfbca118..a6916fb29 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/entity/StockInOrder.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/entity/StockInOrder.java @@ -1,6 +1,7 @@ package com.mhd.wms.domain.stockInOrder.entity; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.fasterxml.jackson.annotation.JsonFormat; import com.mhd.common.core.annotation.Excel; @@ -225,4 +226,104 @@ public class StockInOrder extends BaseVOEntity { @ApiModelProperty("越库类型:1-直接越库 2-分拨越库") @Excel(name = "越库类型:1-直接越库 2-分拨越库") private Long overStockType; + + // ========== 报关相关字段 ========== + @ApiModelProperty("To") + @Excel(name = "To") + @TableField(value = "\"TO\"") + private String to; + + @ApiModelProperty("联系人") + @Excel(name = "联系人") + private String contactPerson; + + @ApiModelProperty("车型及车牌") + @Excel(name = "车型及车牌") + private String vehicleInfo; + + @ApiModelProperty("委托编号NO") + @Excel(name = "委托编号NO") + private String consignmentNo; + + @ApiModelProperty("Tel") + @Excel(name = "Tel") + private String tel; + + @ApiModelProperty("司机签名") + @Excel(name = "司机签名") + private String driverSignature; + + @ApiModelProperty("Fax") + @Excel(name = "Fax") + private String fax; + + @ApiModelProperty("申报地关区") + @Excel(name = "申报地关区") + private String declarationArea; + + @ApiModelProperty("生产商") + @Excel(name = "生产商") + private String manufacturer; + + @ApiModelProperty("报关员姓名及联系方式") + @Excel(name = "报关员姓名及联系方式") + private String customsBrokerInfo; + + @ApiModelProperty("送货地址") + @Excel(name = "送货地址") + private String deliveryAddress; + + @ApiModelProperty("进出境关别") + @Excel(name = "进出境关别") + private String entryExitCustoms; + + @ApiModelProperty("起运/运抵国(地区)") + @Excel(name = "起运/运抵国(地区)") + private String originDestinationCountry; + + @ApiModelProperty("承运商") + @Excel(name = "承运商") + private String carrier; + + @ApiModelProperty("柜号") + @Excel(name = "柜号") + private String containerNo; + + @ApiModelProperty("运输方式") + @Excel(name = "运输方式") + private String transportMethod; + + @ApiModelProperty("监管方式") + @Excel(name = "监管方式") + private String supervisionMethod; + + @ApiModelProperty("海关是否查验货物") + @Excel(name = "海关是否查验货物") + private Integer customsInspection; + + @ApiModelProperty("是否需要报关") + @Excel(name = "是否需要报关") + private Integer needCustomsDeclaration; + + @ApiModelProperty("是否需要运输") + @Excel(name = "是否需要运输") + private Integer needTransport; + + @ApiModelProperty("入仓日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Excel(name = "入仓日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date warehouseDate; + + @ApiModelProperty("完成时间") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date completionTime; + + @ApiModelProperty("下单日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Excel(name = "下单日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date orderDate; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/repository/po/StockInOrderPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/repository/po/StockInOrderPO.java index e2500ede3..b50bce6f6 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/repository/po/StockInOrderPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/repository/po/StockInOrderPO.java @@ -226,4 +226,103 @@ public class StockInOrderPO extends BaseVOEntity { @ApiModelProperty("越库类型:1-直接越库 2-分拨越库") @Excel(name = "越库类型:1-直接越库 2-分拨越库") private Long overStockType; + + // ========== 报关相关字段 ========== + @ApiModelProperty("To") + @Excel(name = "To") + private String to; + + @ApiModelProperty("联系人") + @Excel(name = "联系人") + private String contactPerson; + + @ApiModelProperty("车型及车牌") + @Excel(name = "车型及车牌") + private String vehicleInfo; + + @ApiModelProperty("委托编号NO") + @Excel(name = "委托编号NO") + private String consignmentNo; + + @ApiModelProperty("Tel") + @Excel(name = "Tel") + private String tel; + + @ApiModelProperty("司机签名") + @Excel(name = "司机签名") + private String driverSignature; + + @ApiModelProperty("Fax") + @Excel(name = "Fax") + private String fax; + + @ApiModelProperty("申报地关区") + @Excel(name = "申报地关区") + private String declarationArea; + + @ApiModelProperty("生产商") + @Excel(name = "生产商") + private String manufacturer; + + @ApiModelProperty("报关员姓名及联系方式") + @Excel(name = "报关员姓名及联系方式") + private String customsBrokerInfo; + + @ApiModelProperty("送货地址") + @Excel(name = "送货地址") + private String deliveryAddress; + + @ApiModelProperty("进出境关别") + @Excel(name = "进出境关别") + private String entryExitCustoms; + + @ApiModelProperty("起运/运抵国(地区)") + @Excel(name = "起运/运抵国(地区)") + private String originDestinationCountry; + + @ApiModelProperty("承运商") + @Excel(name = "承运商") + private String carrier; + + @ApiModelProperty("柜号") + @Excel(name = "柜号") + private String containerNo; + + @ApiModelProperty("运输方式") + @Excel(name = "运输方式") + private String transportMethod; + + @ApiModelProperty("监管方式") + @Excel(name = "监管方式") + private String supervisionMethod; + + @ApiModelProperty("海关是否查验货物") + @Excel(name = "海关是否查验货物") + private Integer customsInspection; + + @ApiModelProperty("是否需要报关") + @Excel(name = "是否需要报关") + private Integer needCustomsDeclaration; + + @ApiModelProperty("是否需要运输") + @Excel(name = "是否需要运输") + private Integer needTransport; + + @ApiModelProperty("入仓日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Excel(name = "入仓日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date warehouseDate; + + @ApiModelProperty("完成时间") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date completionTime; + + @ApiModelProperty("下单日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Excel(name = "下单日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date orderDate; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/repository/todo/StockInOrderDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/repository/todo/StockInOrderDO.java index f987d9e92..bad716bfe 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/repository/todo/StockInOrderDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/repository/todo/StockInOrderDO.java @@ -241,4 +241,109 @@ public class StockInOrderDO extends BaseVOEntity { @ApiModelProperty("调度单号") private String mobilizeCode; + + // ========== 报关相关字段 ========== + @ApiModelProperty("To") + @Excel(name = "To") + private String to; + + @ApiModelProperty("联系人") + @Excel(name = "联系人") + private String contactPerson; + + @ApiModelProperty("车型及车牌") + @Excel(name = "车型及车牌") + private String vehicleInfo; + + @ApiModelProperty("委托编号NO") + @Excel(name = "委托编号NO") + private String consignmentNo; + + @ApiModelProperty("Tel") + @Excel(name = "Tel") + private String tel; + + @ApiModelProperty("司机签名") + @Excel(name = "司机签名") + private String driverSignature; + + @ApiModelProperty("Fax") + @Excel(name = "Fax") + private String fax; + + @ApiModelProperty("申报地关区") + @Excel(name = "申报地关区") + private String declarationArea; + + @ApiModelProperty("生产商") + @Excel(name = "生产商") + private String manufacturer; + + @ApiModelProperty("报关员姓名及联系方式") + @Excel(name = "报关员姓名及联系方式") + private String customsBrokerInfo; + + @ApiModelProperty("送货地址") + @Excel(name = "送货地址") + private String deliveryAddress; + + @ApiModelProperty("进出境关别") + @Excel(name = "进出境关别") + private String entryExitCustoms; + + @ApiModelProperty("起运/运抵国(地区)") + @Excel(name = "起运/运抵国(地区)") + private String originDestinationCountry; + + @ApiModelProperty("承运商(先做成输入框,待定)") + @Excel(name = "承运商") + private String carrier; + + @ApiModelProperty("柜号(数据字典:20尺/40尺)") + @Excel(name = "柜号") + private String containerNo; + + @ApiModelProperty("运输方式(数据字典:公路运输/其他运输)") + @Excel(name = "运输方式") + private String transportMethod; + + @ApiModelProperty("监管方式(数据字典:一般贸易)") + @Excel(name = "监管方式") + private String supervisionMethod; + + @ApiModelProperty("海关是否查验货物(默认:否)") + @Excel(name = "海关是否查验货物") + private Integer customsInspection; + + @ApiModelProperty("是否需要报关(默认:是)") + @Excel(name = "是否需要报关") + private Integer needCustomsDeclaration; + + @ApiModelProperty("是否需要运输(默认:否)") + @Excel(name = "是否需要运输") + private Integer needTransport; + + @ApiModelProperty("入仓日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Excel(name = "入仓日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date warehouseDate; + + @ApiModelProperty("完成时间") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date completionTime; + + @ApiModelProperty("下单日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Excel(name = "下单日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date orderDate; + + @ApiModelProperty(name = "创建时间查询条件开始日期") + private String createTimeStart; + + @ApiModelProperty(name = "创建时间查询条件结束日期") + private String createTimeEnd; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/service/StockInOrderDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/service/StockInOrderDomainService.java index 8cf860dbd..f755574a1 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/service/StockInOrderDomainService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockInOrder/service/StockInOrderDomainService.java @@ -31,6 +31,7 @@ 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; 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 lombok.extern.slf4j.Slf4j; @@ -39,6 +40,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; +import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; @@ -84,19 +86,21 @@ public class StockInOrderDomainService { @Transactional(rollbackFor = Exception.class) public Boolean insert(StockInOrderDO stockInOrderDO) { stockInOrderDO.setInOrderNumber(OrderSequence.getOrderCode("RK")); - //设置物料信息 - setMaterialDetailInfo(stockInOrderDO); - //统计总物料种数 - stockInOrderDO.setMaterialQuantity(stockInOrderDO.getMaterialDetailList().size()); - //统计总计划数 - BigDecimal quantity = stockInOrderDO.getMaterialDetailList().stream().map(InMaterialDetailDO::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add); - stockInOrderDO.setQuantity(quantity); - //统计总重量 - BigDecimal weightLimit = stockInOrderDO.getMaterialDetailList().stream().map(InMaterialDetailDO::getWeightLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); - stockInOrderDO.setWeightLimit(weightLimit); - //统计总体积 - BigDecimal volumeLimit = stockInOrderDO.getMaterialDetailList().stream().map(InMaterialDetailDO::getVolumeLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); - stockInOrderDO.setVolumeLimit(volumeLimit); +// //设置默认值 +// setDefaultValues(stockInOrderDO); +// //设置物料信息 +// setMaterialDetailInfo(stockInOrderDO); +// //统计总物料种数 +// stockInOrderDO.setMaterialQuantity(stockInOrderDO.getMaterialDetailList().size()); +// //统计总计划数 +// BigDecimal quantity = stockInOrderDO.getMaterialDetailList().stream().map(InMaterialDetailDO::getQuantity).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); +// stockInOrderDO.setQuantity(quantity); +// //统计总重量 +// BigDecimal weightLimit = stockInOrderDO.getMaterialDetailList().stream().map(InMaterialDetailDO::getWeightLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); +// stockInOrderDO.setWeightLimit(weightLimit); +// //统计总体积 +// BigDecimal volumeLimit = stockInOrderDO.getMaterialDetailList().stream().map(InMaterialDetailDO::getVolumeLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); +// stockInOrderDO.setVolumeLimit(volumeLimit); stockInOrderService.insert(stockInOrderDO); return materialDetailService.batchInsert(stockInOrderDO.getInOrderNumber(), stockInOrderDO.getMaterialDetailList()); } @@ -104,25 +108,24 @@ public class StockInOrderDomainService { /** * 批量新增入库单 */ - @Transactional(rollbackFor = Exception.class) public Boolean batchInsert(List stockInOrderDOList) { for (StockInOrderDO stockInOrderDO : stockInOrderDOList){ if (StringUtils.isBlank(stockInOrderDO.getInOrderNumber())){ stockInOrderDO.setInOrderNumber(OrderSequence.getOrderCode("RK")); } - //设置物料信息 - setMaterialDetailInfo(stockInOrderDO); - //统计总物料种数 - stockInOrderDO.setMaterialQuantity(stockInOrderDO.getMaterialDetailList().size()); - //统计总计划数 - BigDecimal quantity = stockInOrderDO.getMaterialDetailList().stream().map(InMaterialDetailDO::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add); - stockInOrderDO.setQuantity(quantity); - //统计总重量 - BigDecimal weightLimit = stockInOrderDO.getMaterialDetailList().stream().map(InMaterialDetailDO::getWeightLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); - stockInOrderDO.setWeightLimit(weightLimit); - //统计总体积 - BigDecimal volumeLimit = stockInOrderDO.getMaterialDetailList().stream().map(InMaterialDetailDO::getVolumeLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); - stockInOrderDO.setVolumeLimit(volumeLimit); +// //设置物料信息 +// setMaterialDetailInfo(stockInOrderDO); +// //统计总物料种数 +// stockInOrderDO.setMaterialQuantity(stockInOrderDO.getMaterialDetailList().size()); +// //统计总计划数 +// BigDecimal quantity = stockInOrderDO.getMaterialDetailList().stream().map(InMaterialDetailDO::getQuantity).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); +// stockInOrderDO.setQuantity(quantity); +// //统计总重量 +// BigDecimal weightLimit = stockInOrderDO.getMaterialDetailList().stream().map(InMaterialDetailDO::getWeightLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); +// stockInOrderDO.setWeightLimit(weightLimit); +// //统计总体积 +// BigDecimal volumeLimit = stockInOrderDO.getMaterialDetailList().stream().map(InMaterialDetailDO::getVolumeLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); +// stockInOrderDO.setVolumeLimit(volumeLimit); stockInOrderService.insert(stockInOrderDO); materialDetailService.batchInsert(stockInOrderDO.getInOrderNumber(), stockInOrderDO.getMaterialDetailList()); } @@ -143,7 +146,7 @@ public class StockInOrderDomainService { //统计总物料种数 stockInOrderDO.setMaterialQuantity(stockInOrderDO.getMaterialDetailList().size()); //统计总计划数 - BigDecimal quantity = stockInOrderDO.getMaterialDetailList().stream().map(InMaterialDetailDO::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal quantity = stockInOrderDO.getMaterialDetailList().stream().map(InMaterialDetailDO::getQuantity).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); stockInOrderPO.setQuantity(quantity); stockInOrderDO.setQuantity(quantity); //统计总重量 @@ -295,16 +298,49 @@ public class StockInOrderDomainService { ReceiptMaterialDetailDO receiptMaterialDetailDO = new ReceiptMaterialDetailDO(); BeanUtils.copyProperties(inMaterialDetailPO, receiptMaterialDetailDO); receiptMaterialDetailDO.setInUniqueId(inMaterialDetailPO.getUniqueId()); + + // 复制特定字段:生产日期、过期日期、存货日期、批次参考号、单据参考号、箱号/卡板号、扩展属性1-4 + // 这些字段可能使用驼峰命名或下划线命名,使用反射获取和设置 + copySpecialFields(inMaterialDetailPO, receiptMaterialDetailDO); + //收货计划数量赋值 + receiptMaterialDetailDO.setQuantity(inMaterialDetailPO.getInboundQuantity()); receiptMaterialDetailDOList.add(receiptMaterialDetailDO); }); stockReceiptOrderDO.setMaterialDetailList(receiptMaterialDetailDOList); stockReceiptOrderDO.setMaterialQuantity(receiptMaterialDetailDOList.size()); + // 重新计算计划数量:从物料明细中汇总quantity字段 + BigDecimal quantity = receiptMaterialDetailDOList.stream() + .map(ReceiptMaterialDetailDO::getQuantity) + .filter(Objects::nonNull) + .reduce(BigDecimal.ZERO, BigDecimal::add); + stockReceiptOrderDO.setQuantity(quantity); + } else { + // 如果没有物料明细,将数量设置为0 + stockReceiptOrderDO.setQuantity(BigDecimal.ZERO); } stockReceiptOrderDOList.add(stockReceiptOrderDO); }); //判断物流是否需要生成质检单 genQualityInspection(stockReceiptOrderDOList); - return stockReceiptOrderDomainService.batchInsert(stockReceiptOrderDOList); + //生成收货单 + Boolean batchInsertResult = stockReceiptOrderDomainService.batchInsert(stockReceiptOrderDOList); + if (!batchInsertResult) { + throw new ServiceException("生成收货单失败"); + } + //生成收货任务:根据入库单号查询刚生成的收货单 + List stockReceiptOrderPOList = new ArrayList<>(); + for (String inOrderNumber : inOrderNumberList) { + StockReceiptOrderDO stockReceiptOrderDOQuery = new StockReceiptOrderDO(); + stockReceiptOrderDOQuery.setInOrderNumber(inOrderNumber); + List receiptOrderList = stockReceiptOrderDomainService.queryList(stockReceiptOrderDOQuery); + if (!CollectionUtils.isEmpty(receiptOrderList)) { + stockReceiptOrderPOList.addAll(receiptOrderList); + } + } + if (!CollectionUtils.isEmpty(stockReceiptOrderPOList)) { + stockReceiptOrderDomainService.genStockReceiptTaskOrder(stockReceiptOrderPOList); + } + return batchInsertResult; } /** @@ -385,7 +421,234 @@ public class StockInOrderDomainService { inMaterialDetailDO.setDistributeRuleId(materialGoodsRulePO.getMaterialGoodsRuleId()); inMaterialDetailDO.setDistributeRuleCode(materialGoodsRulePO.getRuleCode()); inMaterialDetailDO.setDistributeRuleName(materialGoodsRulePO.getRuleName()); + + //自动填充规格型号和SKU码(如果物料基础信息中有相关字段且明细中未设置) + //规格型号:优先使用物料种类名称,如果为空则使用物料类型名称 + if (StringUtils.isBlank(inMaterialDetailDO.getSpecificationModel())) { + if (StringUtils.isNotBlank(materialBaseInfoPO.getMaterialTypeName())) { + inMaterialDetailDO.setSpecificationModel(materialBaseInfoPO.getMaterialTypeName()); + } + } + //SKU码:使用物料条形码 + if (StringUtils.isBlank(inMaterialDetailDO.getSkuCode())) { + if (StringUtils.isNotBlank(materialBaseInfoPO.getBarCode())) { + inMaterialDetailDO.setSkuCode(materialBaseInfoPO.getBarCode()); + } + } }); } -} + /** + * @description 设置默认值 + * @author gen + * @date 2026/1/16 + * @param stockInOrderDO + */ + private void setDefaultValues(StockInOrderDO stockInOrderDO) { + //海关是否查验货物(默认:0=否) + if (stockInOrderDO.getCustomsInspection() == null) { + stockInOrderDO.setCustomsInspection(0); + } + //是否需要报关(默认:1=是) + if (stockInOrderDO.getNeedCustomsDeclaration() == null) { + stockInOrderDO.setNeedCustomsDeclaration(1); + } + //是否需要运输(默认:0=否) + if (stockInOrderDO.getNeedTransport() == null) { + stockInOrderDO.setNeedTransport(0); + } + } + + /** + * @description 复制特定字段从入库单明细到收货明细 + * 包括:生产日期、过期日期、存货日期、批次参考号、单据参考号、箱号/卡板号、扩展属性1-4 + * @author gen + * @date 2026/1/29 + * @param source 源对象(InMaterialDetailPO) + * @param target 目标对象(ReceiptMaterialDetailDO) + */ + private void copySpecialFields(InMaterialDetailPO source, ReceiptMaterialDetailDO target) { + if (source == null || target == null) { + return; + } + + try { + // 字段映射:源字段名 -> 目标字段名(支持驼峰和下划线两种命名方式) + Map fieldMappings = new HashMap<>(); + fieldMappings.put("productionDate", "productionDate"); + fieldMappings.put("production_date", "productionDate"); + fieldMappings.put("expiryDate", "expiryDate"); + fieldMappings.put("expiry_date", "expiryDate"); + fieldMappings.put("inventoryDate", "inventoryDate"); + fieldMappings.put("inventory_date", "inventoryDate"); + fieldMappings.put("batchRefNo", "batchRefNo"); + fieldMappings.put("batch_ref_no", "batchRefNo"); + fieldMappings.put("sheetRefNo", "sheetRefNo"); + fieldMappings.put("sheet_ref_no", "sheetRefNo"); + fieldMappings.put("boxPalletNo", "boxPalletNo"); + fieldMappings.put("box_pallet_no", "boxPalletNo"); + fieldMappings.put("extAttr1", "extAttr1"); + fieldMappings.put("ext_attr_1", "extAttr1"); + fieldMappings.put("extAttr2", "extAttr2"); + fieldMappings.put("ext_attr_2", "extAttr2"); + fieldMappings.put("extAttr3", "extAttr3"); + fieldMappings.put("ext_attr_3", "extAttr3"); + fieldMappings.put("extAttr4", "extAttr4"); + fieldMappings.put("ext_attr_4", "extAttr4"); + + // 使用反射复制字段值 + for (Map.Entry entry : fieldMappings.entrySet()) { + String sourceFieldName = entry.getKey(); + String targetFieldName = entry.getValue(); + + // 尝试从源对象获取字段值(支持驼峰和下划线命名) + Object value = getFieldValue(source, sourceFieldName); + if (value != null) { + // 设置到目标对象(使用驼峰命名) + setFieldValue(target, targetFieldName, value); + log.info("复制字段成功:{} -> {},值:{}", sourceFieldName, targetFieldName, value); + } else { + log.debug("源对象字段 {} 的值为 null,跳过复制", sourceFieldName); + } + } + } catch (Exception e) { + log.warn("复制特定字段时发生异常,源对象:{},目标对象:{},错误:{}", + source.getClass().getSimpleName(), target.getClass().getSimpleName(), e.getMessage()); + } + } + + /** + * @description 使用反射获取字段值(支持驼峰和下划线命名) + */ + private Object getFieldValue(Object obj, String fieldName) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return null; + } + + try { + Class clazz = obj.getClass(); + Field field = null; + + // 先尝试直接获取字段(驼峰命名) + try { + field = clazz.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + // 如果失败,尝试转换为驼峰命名(如果是下划线命名) + if (fieldName.contains("_")) { + String camelCaseName = snakeToCamel(fieldName); + try { + field = clazz.getDeclaredField(camelCaseName); + } catch (NoSuchFieldException ex) { + // 继续查找父类 + } + } + } + + // 如果当前类找不到,查找父类 + if (field == null) { + Class currentClass = clazz.getSuperclass(); + while (currentClass != null && field == null) { + try { + field = currentClass.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + if (fieldName.contains("_")) { + String camelCaseName = snakeToCamel(fieldName); + try { + field = currentClass.getDeclaredField(camelCaseName); + } catch (NoSuchFieldException ex) { + // 继续查找父类 + } + } + } + currentClass = currentClass.getSuperclass(); + } + } + + if (field != null) { + field.setAccessible(true); + return field.get(obj); + } + } catch (Exception e) { + log.debug("获取字段值失败,对象:{},字段名:{},错误:{}", + obj.getClass().getSimpleName(), fieldName, e.getMessage()); + } + + return null; + } + + /** + * @description 使用反射设置字段值 + */ + private void setFieldValue(Object obj, String fieldName, Object value) { + if (obj == null || StringUtils.isBlank(fieldName)) { + return; + } + + try { + Class clazz = obj.getClass(); + Field field = null; + + // 先尝试直接获取字段(驼峰命名) + try { + field = clazz.getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + // 如果失败,查找父类 + Class currentClass = clazz.getSuperclass(); + while (currentClass != null && field == null) { + try { + field = currentClass.getDeclaredField(fieldName); + } catch (NoSuchFieldException ex) { + // 继续查找父类 + } + currentClass = currentClass.getSuperclass(); + } + } + + if (field != null) { + field.setAccessible(true); + // 类型转换:如果值类型不匹配,尝试转换 + Class fieldType = field.getType(); + if (value != null && !fieldType.isAssignableFrom(value.getClass())) { + // 尝试类型转换 + if (fieldType == Date.class && value instanceof String) { + // 字符串转日期(简单处理,实际可能需要更复杂的解析) + value = null; // 暂时不转换,避免解析错误 + } else if (fieldType == String.class) { + value = String.valueOf(value); + } + } + if (value != null && fieldType.isAssignableFrom(value.getClass())) { + field.set(obj, value); + } + } + } catch (Exception e) { + log.debug("设置字段值失败,对象:{},字段名:{},值:{},错误:{}", + obj.getClass().getSimpleName(), fieldName, value, e.getMessage()); + } + } + + /** + * @description 下划线命名转驼峰命名 + */ + private String snakeToCamel(String snakeCase) { + if (StringUtils.isBlank(snakeCase)) { + return snakeCase; + } + + String[] parts = snakeCase.split("_"); + if (parts.length == 0) { + return snakeCase; + } + + StringBuilder camelCase = new StringBuilder(parts[0].toLowerCase()); + for (int i = 1; i < parts.length; i++) { + if (parts[i].length() > 0) { + camelCase.append(parts[i].substring(0, 1).toUpperCase()) + .append(parts[i].substring(1).toLowerCase()); + } + } + + return camelCase.toString(); + } + +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/entity/StockOutOrder.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/entity/StockOutOrder.java index fc2649773..218bf2031 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/entity/StockOutOrder.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/entity/StockOutOrder.java @@ -1,6 +1,7 @@ package com.mhd.wms.domain.stockOutOrder.entity; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.fasterxml.jackson.annotation.JsonFormat; import com.mhd.common.core.annotation.Excel; @@ -262,4 +263,110 @@ public class StockOutOrder extends BaseVOEntity { @ApiModelProperty("越库类型:1-直接越库 2-分拨越库") @Excel(name = "越库类型:1-直接越库 2-分拨越库") private Long overStockType; -} + + @ApiModelProperty("to") + @Excel(name = "to") + @TableField(value = "\"TO\"") + private String to; + + @ApiModelProperty("联系人") + @Excel(name = "联系人") + private String contactPerson; + + @ApiModelProperty("车型及车牌") + @Excel(name = "车型及车牌") + private String vehicleModelPlate; + + @ApiModelProperty("委托编号") + @Excel(name = "委托编号") + private String entrustNo; + + @ApiModelProperty("Tel") + @Excel(name = "Tel") + private String tel; + + @ApiModelProperty("司机签名") + @Excel(name = "司机签名") + private String driverSign; + + @ApiModelProperty("Fax") + @Excel(name = "Fax") + private String fax; + + @ApiModelProperty("申报地关区") + @Excel(name = "申报地关区") + private String declareCustoms; + + @ApiModelProperty("生产商") + @Excel(name = "生产商") + private String manufacturer; + + @ApiModelProperty("报关员姓名及联系方式") + @Excel(name = "报关员姓名及联系方式") + private String customsDeclarerInfo; + + @ApiModelProperty("送货地址") + @Excel(name = "送货地址") + private String deliveryAddr; + + @ApiModelProperty("进出境关别") + @Excel(name = "进出境关别") + private String entryExitCustoms; + + @ApiModelProperty("起运/运抵国(地区)") + @Excel(name = "起运/运抵国(地区)") + private String departureArrivalCountry; + + @ApiModelProperty("承运商") + @Excel(name = "承运商") + private String carrier; + + @ApiModelProperty("柜号") + @Excel(name = "柜号") + private String containerNo; + + @ApiModelProperty("柜") + @Excel(name = "柜") + private String containerNoName; + + @ApiModelProperty("出仓日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "出仓日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date outboundDate; + @ApiModelProperty("完成时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date completeTime; + @ApiModelProperty("orderDate") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "orderDate", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date orderDate; + + @ApiModelProperty("运输方式") + @Excel(name = "运输方式") + private String transportModeCode; + @ApiModelProperty("运输方式") + @Excel(name = "运输方式") + private String transportModeName; + @ApiModelProperty("监管方式") + @Excel(name = "监管方式") + private String supervisionModeCode; + @ApiModelProperty("监管方式") + @Excel(name = "监管方式") + private String supervisionModeName; + @ApiModelProperty("海关是否查验货物") + @Excel(name = "海关是否查验货物") + private String customsInspectionFlag; + @ApiModelProperty("是否需要报关") + @Excel(name = "是否需要报关") + private String needDeclareFlag; + @ApiModelProperty("是否需要运输") + @Excel(name = "是否需要运输") + private String needTransportFlag; + @ApiModelProperty("app上传的图片") + private String pictureApp; + +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/ExcelParseService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/ExcelParseService.java new file mode 100644 index 000000000..237ecc575 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/ExcelParseService.java @@ -0,0 +1,420 @@ +package com.mhd.wms.domain.stockOutOrder.repository.listener; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelReader; +import com.alibaba.excel.read.builder.ExcelReaderBuilder; +import com.alibaba.excel.read.metadata.ReadSheet; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.mhd.common.core.domain.po.SysDictDataVo; +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.domain.AjaxResult; +import com.mhd.common.security.utils.SecurityUtils; +import com.mhd.system.api.SystemServiceFeign; +import com.mhd.system.api.UserServiceFeign; +import com.mhd.system.api.model.LoginUser; +import com.mhd.wms.application.service.materialBaseInfo.MaterialBaseInfoApplicationService; +import com.mhd.wms.application.service.stockOutOrder.StockOutOrderApplicationService; +import com.mhd.wms.domain.materialBaseInfo.entity.MaterialBaseInfo; +import com.mhd.wms.domain.materialBaseInfo.repository.mapper.MaterialBaseInfoMapper; +import com.mhd.wms.domain.materialBaseInfo.repository.po.MaterialBaseInfoPO; +import com.mhd.wms.domain.materialBaseInfo.repository.todo.MaterialBaseInfoDO; +import com.mhd.wms.domain.outMaterialDetail.repository.todo.OutMaterialDetailDO; +import com.mhd.wms.domain.stockOutOrder.entity.StockOutOrder; +import com.mhd.wms.domain.stockOutOrder.repository.facade.IStockOutOrderService; +import com.mhd.wms.domain.stockOutOrder.repository.todo.StockOutOrderDO; +import com.mhd.wms.domain.stockOutOrder.service.StockOutOrderDomainService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.io.IOException; +import java.io.InputStream; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * Excel解析服务 + */ +@Service +public class ExcelParseService { + + @Autowired + private StockOutOrderApplicationService stockOutOrderApplicationService; + @Resource + private SystemServiceFeign systemServiceFeign; + @Autowired + private MaterialBaseInfoMapper materialBaseInfoMapper; + @Autowired + private MaterialBaseInfoApplicationService materialBaseInfoService; + @Autowired + private StockOutOrderDomainService stockOutOrderDomainService; + @Resource + private UserServiceFeign userServiceFeign; + /** + * 解析出仓委托单Excel + * @param file 上传的Excel文件 + * @return 解析后的出仓委托单对象 + */ + public StringBuilder parseOutboundOrderExcel(MultipartFile file, String warehouseName,String warehouseCode,Long warehouseId) throws IOException { + + HeaderListener headerListener = new HeaderListener(); + + ReadSheet headerSheet = EasyExcel.readSheet(0) + .headRowNumber(0) + .build(); + + ExcelReader headerReader = EasyExcel.read(file.getInputStream()) + .autoCloseStream(false) + .registerReadListener(headerListener) + .registerConverter(new NoConvertConverter()) + .headRowNumber(0) + .build(); + + // 通过监听器控制只读取前11行 + headerReader.read(headerSheet); + + InputStream itemInputStream = file.getInputStream(); + ItemListener itemListener = new ItemListener(); + + // 商品明细需要跳过前11行,从第12行开始读取 + ExcelReader itemReader = EasyExcel.read(itemInputStream) + .autoCloseStream(false) + .registerReadListener(itemListener) + .registerConverter(new NoConvertConverter()) + .headRowNumber(12) + .build(); + + ReadSheet itemSheet = EasyExcel.readSheet(0).build(); + itemReader.read(itemSheet); + + itemReader.finish(); + List itemList = itemListener.getItemList(); + StockOutOrderDO stockOutOrder = headerListener.getStockOutOrder(); + // 提前获取货主ID,用于查询物料基础信息时过滤 + String customerName = stockOutOrder.getCustomerName(); + Long shipperId = getShipperIdByCustomerName(customerName); + LoginUser loginUser = SecurityUtils.getLoginUser(); + Long topOrganizationId = loginUser != null && loginUser.getUserPo() != null + ? loginUser.getUserPo().getTopOrganizationId() : null; + initList(itemList, warehouseId, warehouseCode, warehouseName, shipperId, topOrganizationId); + stockOutOrder.setMaterialDetailList(itemList); + stockOutOrder.setWarehouseName(warehouseName); + stockOutOrder.setWarehouseCode(warehouseCode); + stockOutOrder.setWarehouseId(warehouseId); + initDict(stockOutOrder); + if (loginUser != null){ + stockOutOrder.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); + stockOutOrder.setOrganizationId(loginUser.getUserPo().getOrganizationId()); + stockOutOrder.setOrganizationName(loginUser.getUserPo().getOrganizationName()); + } + initParam(stockOutOrder); + // 导入出库单时,如果出库单类型为空,默认设置为普通出库 + if (StringUtils.isBlank(stockOutOrder.getOrderTypeCode())) { + stockOutOrder.setOrderTypeCode("pu_tong_chu_ku"); + } + if (StringUtils.isBlank(stockOutOrder.getOrderTypeName())) { + stockOutOrder.setOrderTypeName("普通出库"); + } + //设置创建时间和创建人信息 + if (loginUser != null) { + stockOutOrder.setCreateBy(loginUser.getUserid()); + stockOutOrder.setCreateByName(loginUser.getUsername()); + stockOutOrder.setCreateTime(new Date()); + stockOutOrder.setUpdateBy(loginUser.getUserid()); + stockOutOrder.setUpdateByName(loginUser.getUsername()); + stockOutOrder.setUpdateTime(new Date()); + stockOutOrder.setDelFlag(1); + } + //校验必填字段 + StringBuilder errorMsg = check(stockOutOrder); + if (errorMsg.length() > 0) { + return errorMsg; + } else { + insert(stockOutOrder); + return new StringBuilder(); + } + } + + private void initParam(StockOutOrderDO stockOutOrderDO) { + //设置货主信息 + shipperParam(stockOutOrderDO); + //设置客户信息 + customerParam(stockOutOrderDO); + } + + /** + * 新增出库单 + */ + public Boolean insert(StockOutOrderDO stockOutOrderDO) { + return stockOutOrderDomainService.insert(stockOutOrderDO); + } + + /** + * @description 封装货主信息 + * @author ZhouGY + * @date 2024/5/9 20:43 + * @param stockOutOrderDO + */ + private void shipperParam(StockOutOrderDO stockOutOrderDO){ + String customerName = stockOutOrderDO.getCustomerName(); + if (StringUtils.isEmpty(customerName)) return; + if (!customerName.matches("\\d+")) { + AjaxResult ajaxResult = userServiceFeign.getInfoByName(customerName); + if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ + throw new ServiceException("获取客户信息失败"); + } + UserPo userPo = JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + stockOutOrderDO.setShipperId(userPo.getUserId()); + stockOutOrderDO.setShipperCode(userPo.getUserMemberCode()); + stockOutOrderDO.setShipperName(userPo.getUserName()); + } else { + AjaxResult ajaxResult = userServiceFeign.getInfo(Long.valueOf(customerName)); + if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ + throw new ServiceException("获取货主信息失败"); + } + UserPo userPo = JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + stockOutOrderDO.setShipperId(userPo.getUserId()); + stockOutOrderDO.setShipperCode(userPo.getUserMemberCode()); + stockOutOrderDO.setShipperName(userPo.getUserName()); + } + } + + /** + * @description 封装客户信息 + * @author ZhouGY + * @date 2024/5/9 20:43 + * @param stockOutOrderDO + */ + private void customerParam(StockOutOrderDO stockOutOrderDO){ + String customerName = stockOutOrderDO.getCustomerName(); + if (StringUtils.isEmpty(customerName)) return; + if (!customerName.matches("\\d+")) { + AjaxResult ajaxResult = userServiceFeign.getInfoByName(customerName); + if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ + throw new ServiceException("获取客户信息失败"); + } + UserPo userPo = JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + stockOutOrderDO.setCustomerId(userPo.getUserId()); + stockOutOrderDO.setCustomerCode(userPo.getUserMemberCode()); + stockOutOrderDO.setCustomerName(userPo.getUserName()); + } else { + AjaxResult ajaxResult = userServiceFeign.getInfo(Long.valueOf(customerName)); + if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ + throw new ServiceException("获取客户信息失败"); + } + UserPo userPo = JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + stockOutOrderDO.setCustomerId(userPo.getUserId()); + stockOutOrderDO.setCustomerCode(userPo.getUserMemberCode()); + stockOutOrderDO.setCustomerName(userPo.getUserName()); + } + } + + private StringBuilder check(StockOutOrderDO stockOutOrder) { + StringBuilder errorMsg = new StringBuilder(); + if (stockOutOrder.getMaterialDetailList() == null || stockOutOrder.getMaterialDetailList().isEmpty()) errorMsg.append("物料明细列表不能为空或匹配不上物料信息; "); + if (StringUtils.isEmpty(stockOutOrder.getTo())) errorMsg.append("To不能为空; "); + if (StringUtils.isEmpty(stockOutOrder.getEntrustNo())) errorMsg.append("委托单号不能为空; "); + if (StringUtils.isEmpty(stockOutOrder.getCarrier())) errorMsg.append("承运商不能为空; "); + if (StringUtils.isEmpty(stockOutOrder.getTransportModeCode())) errorMsg.append("运输方式不能为空; "); + if (StringUtils.isEmpty(stockOutOrder.getSupervisionModeCode())) errorMsg.append("监督方式不能为空; "); +// if (StringUtils.isEmpty(stockOutOrder.getContainerNo())) errorMsg.append("柜号不能为空; "); + if (StringUtils.isEmpty(stockOutOrder.getDepartureArrivalCountry())) errorMsg.append("出发/到达国家不能为空; "); + if (StringUtils.isEmpty(stockOutOrder.getManufacturer())) errorMsg.append("制造商不能为空; "); +// if (ObjectUtil.isEmpty(stockOutOrder.getOutboundDate())) errorMsg.append("出仓日期不能为空; "); + if (StringUtils.isEmpty(stockOutOrder.getContactPerson())) errorMsg.append("联系人不能为空; "); + if (StringUtils.isEmpty(stockOutOrder.getTel())) errorMsg.append("Tel不能为空; "); + if (StringUtils.isEmpty(stockOutOrder.getFax())) errorMsg.append("Fax不能为空; "); + if (ObjectUtil.isEmpty(stockOutOrder.getShipperId())) errorMsg.append("客户名称不能为空或匹配不上客户信息; "); + //if (StringUtils.isEmpty(stockOutOrder.getNeedDeclareFlag())) errorMsg.append("是否需要申报不能为空; "); + if (StringUtils.isEmpty(stockOutOrder.getDeclareCustoms())) errorMsg.append("申报地关区不能为空; "); + if (StringUtils.isEmpty(stockOutOrder.getEntryExitCustoms())) errorMsg.append("进出境关别不能为空; "); + //if (StringUtils.isEmpty(stockOutOrder.getNeedTransportFlag())) errorMsg.append("是否需要运输不能为空; "); + return errorMsg; + } + + /** + * @description 根据客户名称获取货主ID(用于导入时提前获取货主ID) + * @param customerName 客户名称(在出库单中,客户名称就是货主名称) + * @return 货主ID,如果找不到则返回null + */ + private Long getShipperIdByCustomerName(String customerName) { + if (StringUtils.isEmpty(customerName)) { + return null; + } + + try { + if (!customerName.matches("\\d+")) { + // 按名称查询 + AjaxResult ajaxResult = userServiceFeign.getInfoByName(customerName); + if ("200".equals(String.valueOf(ajaxResult.get("code")))) { + UserPo userPo = JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + if (userPo != null) { + return userPo.getUserId(); + } + } + } else { + // 按ID查询 + AjaxResult ajaxResult = userServiceFeign.getInfo(Long.valueOf(customerName)); + if ("200".equals(String.valueOf(ajaxResult.get("code")))) { + UserPo userPo = JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); + if (userPo != null) { + return userPo.getUserId(); + } + } + } + } catch (Exception e) { + // 如果查询失败,返回null,后续在shipperParam方法中会再次尝试 + } + + return null; + } + + /** + * @description 初始化物料明细列表,查询物料基础信息并设置物料基础信息ID(改为与入库单相同的逻辑) + * @param outMaterialDetailDOList 出库物料明细列表 + * @param warehouseId 仓库ID + * @param warehouseCode 仓库编码 + * @param warehouseName 仓库名称 + * @param shipperId 货主ID(用于过滤物料基础信息,确保查询到的是该货主绑定的物料) + * @param topOrganizationId 一级组织ID(用于过滤物料基础信息) + */ + private void initList(List outMaterialDetailDOList, Long warehouseId, String warehouseCode, String warehouseName, Long shipperId, Long topOrganizationId) { + for (OutMaterialDetailDO outMaterialDetailDO : outMaterialDetailDOList) { + outMaterialDetailDO.setWarehouseId(warehouseId); + outMaterialDetailDO.setWarehouseCode(warehouseCode); + outMaterialDetailDO.setWarehouseName(warehouseName); + + // 根据明细表中的字段查询物料基础信息(优先:料号 > 商品SKU码 > 商品名称) + // 注意:查询时必须加上货主ID条件,确保查询到的是该货主绑定的物料 + Long materialBaseInfoId = null; + + MaterialBaseInfoPO materialBaseInfoPO = null; + + // 优先使用料号查询(materialNo对应materialCode) + String materialNo = outMaterialDetailDO.getMaterialNo(); + if (StringUtils.isNotBlank(materialNo)) { + MaterialBaseInfoDO queryDO = new MaterialBaseInfoDO(); + queryDO.setMaterialCode(materialNo); + if (topOrganizationId != null) { + queryDO.setTopOrganizationId(topOrganizationId); + } + // 加上货主ID条件,确保查询到的是该货主绑定的物料 + if (shipperId != null) { + queryDO.setShipperId(shipperId); + } + List materialList = materialBaseInfoService.queryList(queryDO); + if (materialList != null && !materialList.isEmpty()) { + materialBaseInfoPO = materialList.get(0); + materialBaseInfoId = materialBaseInfoPO.getMaterialBaseInfoId(); + } + } + + // 如果料号查询不到,使用商品SKU码查询(skucode对应barCode) + if (materialBaseInfoId == null && StringUtils.isNotBlank(outMaterialDetailDO.getSkucode())) { + MaterialBaseInfoDO queryDO = new MaterialBaseInfoDO(); + queryDO.setBarCode(outMaterialDetailDO.getSkucode()); + if (topOrganizationId != null) { + queryDO.setTopOrganizationId(topOrganizationId); + } + // 加上货主ID条件,确保查询到的是该货主绑定的物料 + if (shipperId != null) { + queryDO.setShipperId(shipperId); + } + List materialList = materialBaseInfoService.queryList(queryDO); + if (materialList != null && !materialList.isEmpty()) { + materialBaseInfoPO = materialList.get(0); + materialBaseInfoId = materialBaseInfoPO.getMaterialBaseInfoId(); + } + } + + // 如果料号和SKU码都查询不到,使用商品名称查询(commodityName对应materialName) + if (materialBaseInfoId == null && StringUtils.isNotBlank(outMaterialDetailDO.getCommodityName())) { + MaterialBaseInfoDO queryDO = new MaterialBaseInfoDO(); + queryDO.setMaterialName(outMaterialDetailDO.getCommodityName()); + if (topOrganizationId != null) { + queryDO.setTopOrganizationId(topOrganizationId); + } + // 加上货主ID条件,确保查询到的是该货主绑定的物料 + if (shipperId != null) { + queryDO.setShipperId(shipperId); + } + List materialList = materialBaseInfoService.queryList(queryDO); + if (materialList != null && !materialList.isEmpty()) { + materialBaseInfoPO = materialList.get(0); + materialBaseInfoId = materialBaseInfoPO.getMaterialBaseInfoId(); + } + } + + // 设置物料基础信息ID,并从物料基础信息中回填料号、物料编码、物料名称等信息 + if (materialBaseInfoId != null && materialBaseInfoPO != null) { + outMaterialDetailDO.setMaterialBaseInfoId(materialBaseInfoId); + // 如果Excel中没有料号,从物料基础信息中回填 + if (StringUtils.isBlank(outMaterialDetailDO.getMaterialNo())) { + outMaterialDetailDO.setMaterialNo(materialBaseInfoPO.getMaterialCode()); + } + // 回填物料编码 + if (StringUtils.isBlank(outMaterialDetailDO.getMaterialCode())) { + outMaterialDetailDO.setMaterialCode(materialBaseInfoPO.getMaterialCode()); + } + // 回填物料名称(如果Excel中的商品名称为空,使用物料基础信息中的名称) + if (StringUtils.isBlank(outMaterialDetailDO.getCommodityName())) { + outMaterialDetailDO.setCommodityName(materialBaseInfoPO.getMaterialName()); + } + // 回填物料名称到materialName字段 + outMaterialDetailDO.setMaterialName(materialBaseInfoPO.getMaterialName()); + // 如果Excel中没有SKU码,从物料基础信息中回填 + if (StringUtils.isBlank(outMaterialDetailDO.getSkucode())) { + outMaterialDetailDO.setSkucode(materialBaseInfoPO.getBarCode()); + } + } + } + } + + private void initDict(StockOutOrderDO stockOutOrder) { + if (ObjectUtil.isNotNull(stockOutOrder.getContainerNoName())) { + AjaxResult transportMode = systemServiceFeign.selectListByDictType("cabinetNo"); + if (ObjectUtil.isNotNull(transportMode) && "200".equals(String.valueOf(transportMode.get("code")))) { + List transportModeList = JSON.parseArray(JSONObject.toJSONString(transportMode.get("data")), SysDictDataVo.class); + for (SysDictDataVo sysDictDataVo : transportModeList) { + if (stockOutOrder.getContainerNoName().equals(sysDictDataVo.getDictLabel())) { + stockOutOrder.setContainerNo(sysDictDataVo.getDictValue()); + break; + } + } + } + } + + if (ObjectUtil.isNotNull(stockOutOrder.getTransportModeName())) { + AjaxResult transportMode = systemServiceFeign.selectListByDictType("transportMode"); + if (ObjectUtil.isNotNull(transportMode) && "200".equals(String.valueOf(transportMode.get("code")))) { + List transportModeList = JSON.parseArray(com.alibaba.fastjson2.JSONObject.toJSONString(transportMode.get("data")), SysDictDataVo.class); + for (SysDictDataVo sysDictDataVo : transportModeList) { + if (stockOutOrder.getTransportModeName().equals(sysDictDataVo.getDictLabel())) { + stockOutOrder.setTransportModeCode(sysDictDataVo.getDictValue()); + break; + } + } + } + } + + if (ObjectUtil.isNotNull(stockOutOrder.getSupervisionModeName())) { + AjaxResult transportMode = systemServiceFeign.selectListByDictType("controlType"); + if (ObjectUtil.isNotNull(transportMode) && "200".equals(String.valueOf(transportMode.get("code")))) { + List transportModeList = JSON.parseArray(com.alibaba.fastjson2.JSONObject.toJSONString(transportMode.get("data")), SysDictDataVo.class); + for (SysDictDataVo sysDictDataVo : transportModeList) { + if (stockOutOrder.getSupervisionModeName().equals(sysDictDataVo.getDictLabel())) { + stockOutOrder.setSupervisionModeCode(sysDictDataVo.getDictValue()); + break; + } + } + } + } + } +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/HeaderListener.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/HeaderListener.java new file mode 100644 index 000000000..010d2e757 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/HeaderListener.java @@ -0,0 +1,173 @@ +package com.mhd.wms.domain.stockOutOrder.repository.listener; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.mhd.system.api.SystemServiceFeign; +import com.mhd.system.api.UserServiceFeign; +import com.mhd.wms.domain.stockOutOrder.repository.todo.StockOutOrderDO; +import lombok.Getter; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Collections; +import java.util.ArrayList; + +/** + * 解析表头信息的监听器(处理前11行) + */ +@Getter +public class HeaderListener extends AnalysisEventListener> { + private final StockOutOrderDO stockOutOrder = new StockOutOrderDO(); + private int rowNum = 0; + private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + @Override + public void invoke(Map data, AnalysisContext context) { + // 将Map转换为Map + Map stringData = convertToStringMap(data); + // 将Map转换为List再转为数组 + List dataList = mapToList(stringData); + Object[] rowData = listToArray(dataList); + + // 根据行号提取对应信息 + switch (rowNum) { + case 4: // 第5行:to、仓库联系人、车型及车牌、委托编码 + stockOutOrder.setTo(getStringValue(rowData[2])); + stockOutOrder.setContactPerson(getStringValue(rowData[5])); + stockOutOrder.setVehicleModelPlate(getStringValue(rowData[12])); + stockOutOrder.setEntrustNo(getStringValue(rowData[16])); + break; + case 5: // 第6行:承运方、tel、柜号、司机签名 + stockOutOrder.setCarrier(getStringValue(rowData[2])); + stockOutOrder.setTel(getStringValue(rowData[5])); + stockOutOrder.setContainerNoName(getStringValue(rowData[12])); + stockOutOrder.setDriverSign(getStringValue(rowData[16])); + break; + case 6: // 第7行:出仓日期、fax、运输方式、申报地关区 + LocalDate localDate = parseDate(getStringValue(rowData[2])); + if (localDate != null) { + Date date = Date.from(localDate.atStartOfDay(ZoneId.of("UTC")).toInstant()); + stockOutOrder.setOutboundDate(date); + } + stockOutOrder.setFax(getStringValue(rowData[5])); + stockOutOrder.setTransportModeName(getStringValue(rowData[12])); + stockOutOrder.setDeclareCustoms(getStringValue(rowData[16])); + break; + case 7: // 第8行:生产商、客户名称、报关姓名及联系方式、完成时间 + stockOutOrder.setManufacturer(getStringValue(rowData[2])); + stockOutOrder.setCustomerName(getStringValue(rowData[5])); + stockOutOrder.setCustomsDeclarerInfo(getStringValue(rowData[12])); + LocalDate CompleteTime = parseDate(getStringValue(rowData[16])); + if (CompleteTime != null) { + Date date = Date.from(CompleteTime.atStartOfDay(ZoneId.of("UTC")).toInstant()); + stockOutOrder.setCompleteTime(date); + } + break; + case 8: // 第9行:监管方式、送货地址、海关是否查验货物、进出境关别 + stockOutOrder.setSupervisionModeName(getStringValue(rowData[2])); + stockOutOrder.setDeliveryAddr(getStringValue(rowData[5])); + String stringValue = getStringValue(rowData[12]); + stockOutOrder.setCustomsInspectionFlag(stringValue); + stockOutOrder.setEntryExitCustoms(getStringValue(rowData[16])); + break; + case 9: // 第10行:下单日期、起运国 + LocalDate orderDate = parseDate(getStringValue(rowData[2])); + if (orderDate != null) { + Date date = Date.from(orderDate.atStartOfDay(ZoneId.of("UTC")).toInstant()); + stockOutOrder.setOrderDate(date); + } + stockOutOrder.setDepartureArrivalCountry(getStringValue(rowData[5])); + break; + } + rowNum++; + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + // 解析完成后的处理 + } + + /** + * 将List转换为数组 + */ + private Object[] listToArray(List list) { + // 创建一个足够大的数组来容纳最多30列数据 + Object[] array = new Object[30]; + for (int i = 0; i < 30 && i < list.size(); i++) { + array[i] = list.get(i); + } + return array; + } + + /** + * 将Object的Map转换为String的Map + */ + private Map convertToStringMap(Map dataMap) { + if (dataMap == null) { + return new java.util.HashMap<>(); + } + + Map stringMap = new java.util.HashMap<>(); + for (Map.Entry entry : dataMap.entrySet()) { + Object value = entry.getValue(); + String stringValue = value != null ? value.toString() : ""; + stringMap.put(entry.getKey(), stringValue); + } + + return stringMap; + } + + /** + * 将Map转换为List + */ + private List mapToList(Map map) { + if (map == null) { + return new ArrayList<>(); + } + + // 找到最大索引以确定列表大小 + int maxSize = map.keySet().stream().mapToInt(Integer::intValue).max().orElse(-1) + 1; + maxSize = Math.max(maxSize, 30); // 至少30个位置 + + List list = new ArrayList<>(Collections.nCopies(maxSize, "")); + + for (Map.Entry entry : map.entrySet()) { + if (entry.getKey() >= 0 && entry.getKey() < maxSize) { + String value = entry.getValue(); + list.set(entry.getKey(), value != null ? value : ""); + } + } + + return list; + } + + /** + * 转换为字符串,处理null值 + */ + private String getStringValue(Object value) { + return value == null ? "" : value.toString().trim(); + } + + /** + * 解析日期 + */ + private LocalDate parseDate(String dateStr) { + if (dateStr == null || dateStr.isEmpty()) { + return null; + } + try { + if (dateStr.contains(" ")) { + dateStr = dateStr.split(" ")[0]; + } + return LocalDate.parse(dateStr, dateFormatter); + } catch (Exception e) { + return null; + } + } +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/ItemListener.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/ItemListener.java new file mode 100644 index 000000000..8a800bcb4 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/ItemListener.java @@ -0,0 +1,297 @@ +package com.mhd.wms.domain.stockOutOrder.repository.listener; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.mhd.wms.domain.materialBaseInfo.entity.MaterialBaseInfo; +import com.mhd.wms.domain.materialBaseInfo.repository.mapper.MaterialBaseInfoMapper; +import com.mhd.wms.domain.outMaterialDetail.repository.todo.OutMaterialDetailDO; +import lombok.Getter; +import org.springframework.beans.factory.annotation.Autowired; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Collections; + +/** + * 解析商品明细的监听器(从第12行开始) + */ +@Getter +public class ItemListener extends AnalysisEventListener> { + private final List itemList = new ArrayList<>(); + + + @Override + public void invoke(Map data, AnalysisContext context) { + // 将Map转换为Map + Map stringData = convertToStringMap(data); + // 将Map转换为List再转为数组 + List dataList = mapToList(stringData); + Object[] rowData = listToArray(dataList); + + // 提取序号(第一列),过滤空行和标题行 + String serialNoStr = getStringValue(rowData[0]); + String commodityName = getStringValue(rowData[1]); + String specificationModel = getStringValue(rowData[2]); + + if (commodityName.isEmpty() && specificationModel.isEmpty()) { + return; + } + if (serialNoStr.isEmpty() || "序号".equals(serialNoStr) || !isSequenceNumber(serialNoStr)) { + return; + } + + OutMaterialDetailDO item = new OutMaterialDetailDO(); + + + // 填充商品明细数据 + //商品名称 料号 规格型号/ITEM 商品SKU码 Invoice No. 申报数量 申报单位 升 箱数 件数 尺寸 仓库数量 "总净重 + //(KG)" 总毛重 (KG) "总体积 + //(CBM)" 总面积(SQM) Batch Ref NO's Sheet Ref NO's 原产国 箱号/卡板号 总价 币制 备注 + item.setCommodityName(getStringValue(rowData[1])); + item.setMaterialNo(getStringValue(rowData[2])); + item.setSpecificationModel(getStringValue(rowData[3])); + item.setSkucode(getStringValue(rowData[4])); + item.setInvoiceNo(getStringValue(rowData[5])); + item.setDeclareQuantity(parseBigDecimal(rowData[6])); + item.setDeclareUnit(getStringValue(rowData[7])); + item.setLiter(getStringValue(rowData[8])); + item.setCaseCount(parseBigDecimal(rowData[9])); + item.setPieceCount(parseBigDecimal(rowData[10])); + item.setSize(getStringValue(rowData[11])); + //仓库数量 出库数量? + item.setOutboundQuantity(parseBigDecimal(rowData[12])); + item.setTotalNetWeight(parseBigDecimal(rowData[13])); + item.setTotalGrossWeight(parseBigDecimal(rowData[14])); + item.setTotalVolume(parseBigDecimal(rowData[15])); + item.setTotalArea(parseBigDecimal(rowData[16])); + item.setBatchRefNo(getStringValue(rowData[17])); + item.setSheetRefNo(getStringValue(rowData[18])); + item.setCountryOfOrigin(getStringValue(rowData[19])); + + item.setBoxPalletNo(getStringValue(rowData[20])); + item.setTotalAmount(parseBigDecimal(rowData[21])); + item.setCurrency(getStringValue(rowData[22])); + item.setRemark(getStringValue(rowData[23])); + + itemList.add(item); + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + // 解析完成后的处理 + } + + /** + * 将List转换为数组 + */ + private Object[] listToArray(List list) { + // 创建一个足够大的数组来容纳最多30列数据 + Object[] array = new Object[30]; + for (int i = 0; i < 30 && i < list.size(); i++) { + array[i] = list.get(i); + } + return array; + } + + /** + * 将Object的Map转换为String的Map + */ + private Map convertToStringMap(Map dataMap) { + if (dataMap == null) { + return new java.util.HashMap<>(); + } + + Map stringMap = new java.util.HashMap<>(); + for (Map.Entry entry : dataMap.entrySet()) { + Object value = entry.getValue(); + String stringValue = convertToString(value); + stringMap.put(entry.getKey(), stringValue); + } + + return stringMap; + } + + /** + * 将Object转换为String,处理BigDecimal等数字类型,去除小数点后的零 + */ + private String convertToString(Object value) { + if (value == null) { + return ""; + } + + // 如果是BigDecimal类型,需要特殊处理,去除小数点后的零 + if (value instanceof BigDecimal) { + BigDecimal bd = (BigDecimal) value; + // 如果小数部分为0,转换为整数形式 + if (bd.scale() > 0 && bd.stripTrailingZeros().scale() <= 0) { + return String.valueOf(bd.longValue()); + } + // 否则去除尾部零 + return bd.stripTrailingZeros().toPlainString(); + } + + // 如果是Double或Float类型,也需要处理 + if (value instanceof Double) { + Double d = (Double) value; + if (d == d.longValue()) { + return String.valueOf(d.longValue()); + } + return d.toString(); + } + + if (value instanceof Float) { + Float f = (Float) value; + if (f == f.longValue()) { + return String.valueOf(f.longValue()); + } + return f.toString(); + } + + // 如果是String类型,检查是否是数字字符串(如 "123.0"),去除小数点后的零 + if (value instanceof String) { + String str = value.toString().trim(); + if (str.isEmpty()) { + return ""; + } + // 尝试解析为数字,如果是整数形式的小数(如 "123.0"),转换为整数 + try { + BigDecimal bd = new BigDecimal(str); + // 如果小数部分为0,转换为整数形式 + if (bd.scale() > 0 && bd.stripTrailingZeros().scale() <= 0) { + return String.valueOf(bd.longValue()); + } + // 否则去除尾部零 + return bd.stripTrailingZeros().toPlainString(); + } catch (NumberFormatException e) { + // 不是数字字符串,直接返回 + return str; + } + } + + return value.toString().trim(); + } + + /** + * 将Map转换为List + */ + private List mapToList(Map map) { + if (map == null) { + return new ArrayList<>(); + } + + // 找到最大索引以确定列表大小 + int maxSize = map.keySet().stream().mapToInt(Integer::intValue).max().orElse(-1) + 1; + maxSize = Math.max(maxSize, 30); // 至少30个位置 + + List list = new ArrayList<>(Collections.nCopies(maxSize, "")); + + for (Map.Entry entry : map.entrySet()) { + if (entry.getKey() >= 0 && entry.getKey() < maxSize) { + String value = entry.getValue(); + list.set(entry.getKey(), value != null ? value : ""); + } + } + + return list; + } + + private String getStringValue(Object value) { + if (value == null) { + return ""; + } + + // 如果是BigDecimal类型,需要特殊处理,去除小数点后的零 + if (value instanceof BigDecimal) { + BigDecimal bd = (BigDecimal) value; + // 如果小数部分为0,转换为整数形式 + if (bd.scale() > 0 && bd.stripTrailingZeros().scale() <= 0) { + return String.valueOf(bd.longValue()); + } + // 否则去除尾部零 + return bd.stripTrailingZeros().toPlainString(); + } + + // 如果是Double或Float类型,也需要处理 + if (value instanceof Double) { + Double d = (Double) value; + if (d == d.longValue()) { + return String.valueOf(d.longValue()); + } + return d.toString(); + } + + if (value instanceof Float) { + Float f = (Float) value; + if (f == f.longValue()) { + return String.valueOf(f.longValue()); + } + return f.toString(); + } + + // 如果是String类型,检查是否是数字字符串(如 "123.0"),去除小数点后的零 + if (value instanceof String) { + String str = value.toString().trim(); + if (str.isEmpty()) { + return ""; + } + // 尝试解析为数字,如果是整数形式的小数(如 "123.0"),转换为整数 + try { + BigDecimal bd = new BigDecimal(str); + // 如果小数部分为0,转换为整数形式 + if (bd.scale() > 0 && bd.stripTrailingZeros().scale() <= 0) { + return String.valueOf(bd.longValue()); + } + // 否则去除尾部零 + return bd.stripTrailingZeros().toPlainString(); + } catch (NumberFormatException e) { + // 不是数字字符串,直接返回 + return str; + } + } + + return value.toString().trim(); + } + + /** + * 解析整数,失败返回0 + */ + private Integer parseInteger(Object value) { + try { + String strValue = getStringValue(value); + if (strValue.isEmpty()) { + return 0; + } + return Integer.parseInt(strValue); + } catch (Exception e) { + return 0; + } + } + + /** + * 解析BigDecimal,失败返回0 + */ + private BigDecimal parseBigDecimal(Object value) { + try { + String strValue = getStringValue(value); + if (strValue.isEmpty()) { + return BigDecimal.ZERO; + } + return new BigDecimal(strValue); + } catch (Exception e) { + return BigDecimal.ZERO; + } + } + + + public static boolean isSequenceNumber(String str) { + if (str == null || str.trim().isEmpty()) { + return false; + } + str = str.trim(); + + return str.matches("^[1-9]\\d*$") || str.matches("^[1-9]\\d*\\.\\d+$") || str.matches("^0\\.\\d+$"); + } +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/NoConvertConverter.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/NoConvertConverter.java new file mode 100644 index 000000000..dc4ebe15c --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/listener/NoConvertConverter.java @@ -0,0 +1,55 @@ +package com.mhd.wms.domain.stockOutOrder.repository.listener; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; + +/** + * 自定义转换器,不进行任何类型转换,直接返回原始值 + * 覆盖EasyExcel默认的StringNumberConverter,避免数字格式化错误 + */ +public class NoConvertConverter implements Converter { + + @Override + public Class supportJavaTypeKey() { + return String.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + // 关键:返回NUMBER类型,覆盖StringNumberConverter + return CellDataTypeEnum.NUMBER; + } + + @Override + public String convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) { + // 不进行任何格式化,直接返回原始值的字符串表示 + if (cellData == null) { + return ""; + } + + // 根据单元格类型获取原始值 + try { + CellDataTypeEnum type = cellData.getType(); + if (type == CellDataTypeEnum.STRING) { + return cellData.getStringValue() != null ? cellData.getStringValue() : ""; + } else if (type == CellDataTypeEnum.NUMBER) { + // 直接转换数字为字符串,不进行格式化 + return cellData.getNumberValue() != null ? cellData.getNumberValue().toString() : ""; + } else if (type == CellDataTypeEnum.BOOLEAN) { + return cellData.getBooleanValue() != null ? cellData.getBooleanValue().toString() : ""; + } else if (type == CellDataTypeEnum.EMPTY) { + return ""; + } else { + // 其他类型尝试获取字符串值 + return cellData.getStringValue() != null ? cellData.getStringValue() : ""; + } + } catch (Exception e) { + // 如果获取失败,返回空字符串 + return ""; + } + } +} diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/po/StockOutOrderPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/po/StockOutOrderPO.java index 9e7532e92..61c9ab403 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/po/StockOutOrderPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/po/StockOutOrderPO.java @@ -271,4 +271,110 @@ public class StockOutOrderPO extends BaseVOEntity { @Excel(name = "越库类型:1-直接越库 2-分拨越库") private Long overStockType; -} + + @ApiModelProperty("to") + @Excel(name = "to") + private String to; + + @ApiModelProperty("联系人") + @Excel(name = "联系人") + private String contactPerson; + + @ApiModelProperty("车型及车牌") + @Excel(name = "车型及车牌") + private String vehicleModelPlate; + + @ApiModelProperty("委托编号") + @Excel(name = "委托编号") + private String entrustNo; + + @ApiModelProperty("Tel") + @Excel(name = "Tel") + private String tel; + + @ApiModelProperty("司机签名") + @Excel(name = "司机签名") + private String driverSign; + + @ApiModelProperty("Fax") + @Excel(name = "Fax") + private String fax; + + @ApiModelProperty("申报地关区") + @Excel(name = "申报地关区") + private String declareCustoms; + + @ApiModelProperty("生产商") + @Excel(name = "生产商") + private String manufacturer; + + @ApiModelProperty("报关员姓名及联系方式") + @Excel(name = "报关员姓名及联系方式") + private String customsDeclarerInfo; + + @ApiModelProperty("送货地址") + @Excel(name = "送货地址") + private String deliveryAddr; + + @ApiModelProperty("进出境关别") + @Excel(name = "进出境关别") + private String entryExitCustoms; + + @ApiModelProperty("起运/运抵国(地区)") + @Excel(name = "起运/运抵国(地区)") + private String departureArrivalCountry; + + @ApiModelProperty("承运商") + @Excel(name = "承运商") + private String carrier; + + @ApiModelProperty("柜号") + @Excel(name = "柜号") + private String containerNo; + + @ApiModelProperty("柜") + @Excel(name = "柜") + private String containerNoName; + + @ApiModelProperty("出仓日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "出仓日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date outboundDate; + @ApiModelProperty("完成时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date completeTime; + @ApiModelProperty("orderDate") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "orderDate", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date orderDate; + + @ApiModelProperty("运输方式") + @Excel(name = "运输方式") + private String transportModeCode; + @ApiModelProperty("运输方式") + @Excel(name = "运输方式") + private String transportModeName; + @ApiModelProperty("监管方式") + @Excel(name = "监管方式") + private String supervisionModeCode; + @ApiModelProperty("监管方式") + @Excel(name = "监管方式") + private String supervisionModeName; + @ApiModelProperty("海关是否查验货物") + @Excel(name = "海关是否查验货物") + private String customsInspectionFlag; + @ApiModelProperty("是否需要报关") + @Excel(name = "是否需要报关") + private String needDeclareFlag; + @ApiModelProperty("是否需要运输") + @Excel(name = "是否需要运输") + private String needTransportFlag; + + @ApiModelProperty("app上传的图片") + private String pictureApp; + +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/todo/StockOutOrderDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/todo/StockOutOrderDO.java index 3f825d042..09645246c 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/todo/StockOutOrderDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/repository/todo/StockOutOrderDO.java @@ -290,4 +290,118 @@ public class StockOutOrderDO extends BaseVOEntity { @ApiModelProperty("小于复核状态: 1-未复核 2-复核中 3-已复核") private Integer ltCheckStatus; -} + + @ApiModelProperty("to") + @Excel(name = "to") + private String to; + + @ApiModelProperty("联系人") + @Excel(name = "联系人") + private String contactPerson; + + @ApiModelProperty("车型及车牌") + @Excel(name = "车型及车牌") + private String vehicleModelPlate; + + @ApiModelProperty("委托编号") + @Excel(name = "委托编号") + private String entrustNo; + + @ApiModelProperty("Tel") + @Excel(name = "Tel") + private String tel; + + @ApiModelProperty("司机签名") + @Excel(name = "司机签名") + private String driverSign; + + @ApiModelProperty("Fax") + @Excel(name = "Fax") + private String fax; + + @ApiModelProperty("申报地关区") + @Excel(name = "申报地关区") + private String declareCustoms; + + @ApiModelProperty("生产商") + @Excel(name = "生产商") + private String manufacturer; + + @ApiModelProperty("报关员姓名及联系方式") + @Excel(name = "报关员姓名及联系方式") + private String customsDeclarerInfo; + + @ApiModelProperty("送货地址") + @Excel(name = "送货地址") + private String deliveryAddr; + + @ApiModelProperty("进出境关别") + @Excel(name = "进出境关别") + private String entryExitCustoms; + + @ApiModelProperty("起运/运抵国(地区)") + @Excel(name = "起运/运抵国(地区)") + private String departureArrivalCountry; + + @ApiModelProperty("承运商") + @Excel(name = "承运商") + private String carrier; + + @ApiModelProperty("柜号") + @Excel(name = "柜号") + private String containerNo; + + @ApiModelProperty("柜") + @Excel(name = "柜") + private String containerNoName; + + @ApiModelProperty("出仓日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "出仓日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date outboundDate; + @ApiModelProperty("完成时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date completeTime; + @ApiModelProperty("orderDate") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "orderDate", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date orderDate; + + @ApiModelProperty("运输方式") + @Excel(name = "运输方式") + private String transportModeCode; + @ApiModelProperty("运输方式") + @Excel(name = "运输方式") + private String transportModeName; + @ApiModelProperty("监管方式") + @Excel(name = "监管方式") + private String supervisionModeCode; + @ApiModelProperty("监管方式") + @Excel(name = "监管方式") + private String supervisionModeName; + @ApiModelProperty("海关是否查验货物") + @Excel(name = "海关是否查验货物") + private String customsInspectionFlag; + @ApiModelProperty("是否需要报关") + @Excel(name = "是否需要报关") + private String needDeclareFlag; + @ApiModelProperty("是否需要运输") + @Excel(name = "是否需要运输") + private String needTransportFlag; + + @ApiModelProperty(name = "创建时间查询条件开始日期") + private String createTimeStart; + + @ApiModelProperty(name = "创建时间查询条件结束日期") + private String createTimeEnd; + + @ApiModelProperty(name = "审核时间查询条件开始日期") + private String auditTimeStart; + + @ApiModelProperty(name = "审核时间查询条件结束日期") + private String auditTimeEnd; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/service/StockOutOrderDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/service/StockOutOrderDomainService.java index 8bab73d5d..b4b3bd9d1 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/service/StockOutOrderDomainService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutOrder/service/StockOutOrderDomainService.java @@ -22,7 +22,9 @@ import com.mhd.wms.domain.handoverTaskOrder.repository.todo.HandoverTaskOrderDO; import com.mhd.wms.domain.inMaterialDetail.repository.todo.InMaterialDetailDO; import com.mhd.wms.domain.inventoryStandingDetail.repository.facade.IInventoryStandingDetailService; import com.mhd.wms.domain.inventoryStandingDetail.repository.todo.InventoryStandingDetailDO; +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.wms.domain.materialInventory.repository.facade.IMaterialInventoryService; import com.mhd.wms.domain.materialWarehouseControl.repository.facade.IMaterialWarehouseControlService; @@ -61,6 +63,7 @@ import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -107,6 +110,8 @@ public class StockOutOrderDomainService { private SystemServiceFeign systemServiceFeign; @Autowired private PushSyncBmsDomainService pushSyncBmsDomainService; + @Autowired + private MaterialBaseInfoMapper materialBaseInfoMapper; /** @@ -124,18 +129,18 @@ public class StockOutOrderDomainService { public Boolean insert(StockOutOrderDO stockOutOrderDO) { stockOutOrderDO.setOutOrderNumber(OrderSequence.getOrderCode("CK")); //设置物料信息 - setMaterialDetailInfo(stockOutOrderDO); + //setMaterialDetailInfo(stockOutOrderDO); //统计种类 - stockOutOrderDO.setMaterialQuantity(stockOutOrderDO.getMaterialDetailList().size()); + //stockOutOrderDO.setMaterialQuantity(stockOutOrderDO.getMaterialDetailList().size()); //统计总数量 - BigDecimal quantity = stockOutOrderDO.getMaterialDetailList().stream().map(OutMaterialDetailDO::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal quantity = stockOutOrderDO.getMaterialDetailList().stream().map(OutMaterialDetailDO::getOutboundQuantity).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); stockOutOrderDO.setQuantity(quantity); //统计总重量 - BigDecimal weightLimit = stockOutOrderDO.getMaterialDetailList().stream().map(OutMaterialDetailDO::getWeightLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); - stockOutOrderDO.setWeightLimit(weightLimit); + // BigDecimal weightLimit = stockOutOrderDO.getMaterialDetailList().stream().map(OutMaterialDetailDO::getWeightLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); + // stockOutOrderDO.setWeightLimit(weightLimit); //统计总体积 - BigDecimal volumeLimit = stockOutOrderDO.getMaterialDetailList().stream().map(OutMaterialDetailDO::getVolumeLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); - stockOutOrderDO.setVolumeLimit(volumeLimit); + //BigDecimal volumeLimit = stockOutOrderDO.getMaterialDetailList().stream().map(OutMaterialDetailDO::getVolumeLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); + //stockOutOrderDO.setVolumeLimit(volumeLimit); stockOutOrderService.insert(stockOutOrderDO); return outMaterialDetailService.batchInsert(stockOutOrderDO.getOutOrderNumber(), stockOutOrderDO.getMaterialDetailList()); } @@ -154,7 +159,7 @@ public class StockOutOrderDomainService { //统计种类 stockOutOrderDO.setMaterialQuantity(stockOutOrderDO.getMaterialDetailList().size()); //统计总数量 - BigDecimal quantity = stockOutOrderDO.getMaterialDetailList().stream().map(OutMaterialDetailDO::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal quantity = stockOutOrderDO.getMaterialDetailList().stream().map(OutMaterialDetailDO::getQuantity).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); stockOutOrderDO.setQuantity(quantity); //统计总重量 BigDecimal weightLimit = stockOutOrderDO.getMaterialDetailList().stream().map(OutMaterialDetailDO::getWeightLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); @@ -181,7 +186,7 @@ public class StockOutOrderDomainService { //统计种类 stockOutOrderDO.setMaterialQuantity(stockOutOrderDO.getMaterialDetailList().size()); //统计总数量 - BigDecimal quantity = stockOutOrderDO.getMaterialDetailList().stream().map(OutMaterialDetailDO::getQuantity).reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal quantity = stockOutOrderDO.getMaterialDetailList().stream().map(OutMaterialDetailDO::getQuantity).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); stockOutOrderDO.setQuantity(quantity); //统计总重量 BigDecimal weightLimit = stockOutOrderDO.getMaterialDetailList().stream().map(OutMaterialDetailDO::getWeightLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); @@ -257,6 +262,85 @@ public class StockOutOrderDomainService { return updateStockOutOrderByAllocation(stockOutOrderDb, stockOutOrderPO, 1); } + /** + * @description 手动取消分配(点击确认后直接取消分配) + * @author ZhouGY + * @date 2024/5/22 16:20 + * @param stockOutOrderDO + * @return Boolean + */ + @Transactional(rollbackFor = Exception.class) + public Boolean manualCancelAssign(StockOutOrderDO stockOutOrderDO){ + StockOutOrder stockOutOrderDb = stockOutOrderService.getById(stockOutOrderDO.getOutOrderId()); + if (stockOutOrderDb == null){ + throw new ServiceException("出库单不存在"); + } + if (stockOutOrderDb.getStatus() > 4){ + throw new ServiceException("出库单已拣货,不允许取消分配!"); + } + + // 如果没有传递物料明细列表,直接返回 + if (stockOutOrderDO.getMaterialDetailList() == null || stockOutOrderDO.getMaterialDetailList().isEmpty()) { + throw new ServiceException("物料明细不能为空"); + } + + // 查询物料明细的当前分配情况,构建取消分配参数 + // 如果传递的明细中没有指定取消数量,则取消该明细的所有已分配数量 + List cancelDetailList = new ArrayList<>(); + OutMaterialDetailDO queryDO = new OutMaterialDetailDO(); + queryDO.setOutOrderNumber(stockOutOrderDb.getOutOrderNumber()); + List detailPOList = outMaterialDetailService.queryList(queryDO); + Map detailPOMap = detailPOList.stream() + .collect(Collectors.toMap(OutMaterialDetailPO::getMaterialDetailId, Function.identity())); + + for (OutMaterialDetailDO detailDO : stockOutOrderDO.getMaterialDetailList()) { + OutMaterialDetailPO detailPO = detailPOMap.get(detailDO.getMaterialDetailId()); + if (detailPO == null) { + throw new ServiceException("物料明细不存在,ID:" + detailDO.getMaterialDetailId()); + } + + // 取消分配:直接使用数据库中的已分配数量作为取消数量 + // 如果前端传递了allocationQuantity,需要验证它不能大于已分配数量 + BigDecimal dbAlreadyAllocationQuantity = detailPO.getAlreadyAllocationQuantity() != null + ? detailPO.getAlreadyAllocationQuantity() + : BigDecimal.ZERO; + + // 如果已分配数量为0,跳过该明细(不执行取消分配操作) + if (dbAlreadyAllocationQuantity.compareTo(BigDecimal.ZERO) <= 0) { + continue; // 跳过该明细,继续处理下一个 + } + + // 如果前端传递了取消数量,验证它不能大于已分配数量;否则取消所有已分配数量 + BigDecimal cancelQuantity = detailDO.getAllocationQuantity(); + if (cancelQuantity != null && cancelQuantity.compareTo(BigDecimal.ZERO) > 0) { + // 前端传递了取消数量,验证它不能大于已分配数量 + if (cancelQuantity.compareTo(dbAlreadyAllocationQuantity) > 0) { + String materialName = detailPO.getMaterialName() != null ? detailPO.getMaterialName() : "未知物料"; + throw new ServiceException("物料【" + materialName + "】取消分配数量(" + cancelQuantity + ")不能大于已分配数量(" + dbAlreadyAllocationQuantity + ")"); + } + } else { + // 没有传递取消数量,取消所有已分配数量 + cancelQuantity = dbAlreadyAllocationQuantity; + } + + OutMaterialDetailDO cancelDetail = new OutMaterialDetailDO(); + cancelDetail.setMaterialDetailId(detailDO.getMaterialDetailId()); + cancelDetail.setActualQuantity(cancelQuantity); // 使用actualQuantity字段传递取消数量 + cancelDetail.setAlreadyAllocationQuantity(cancelQuantity); + cancelDetailList.add(cancelDetail); + } + + // 如果所有明细的已分配数量都为0,直接返回成功(没有需要取消的分配) + if (cancelDetailList.isEmpty()) { + return true; + } + + //修改物料明细信息(取消分配) + StockOutOrderPO stockOutOrderPO = outMaterialDetailService.batchCancelAssignUpdate(stockOutOrderDb.getOutOrderNumber(), cancelDetailList); + //修改出库单 + return updateStockOutOrderByAllocation(stockOutOrderDb, stockOutOrderPO, 2); + } + /** * @description 取消分配 @@ -292,20 +376,42 @@ public class StockOutOrderDomainService { LoginUser loginUser = SecurityUtils.getLoginUser(); int status = judgeAllocationQuantityByManualAssign(stockOutOrderPO.getAllocationQuantity(), stockOutOrderDb.getQuantity(),type); BigDecimal allocationQuantity = stockOutOrderDb.getAllocationQuantity(); + BigDecimal alreadyAllocationQuantity = stockOutOrderDb.getAlreadyAllocationQuantity() != null + ? stockOutOrderDb.getAlreadyAllocationQuantity() + : BigDecimal.ZERO; if (type == 2){ - //取消分配需要比较作业数量与已分配数量 - if(stockOutOrderPO.getAllocationQuantity().compareTo(allocationQuantity) > 0){ - throw new ServiceException("取消分配数量不能大于已分配数量"); + //取消分配:stockOutOrderPO.getAllocationQuantity() 和 stockOutOrderPO.getAlreadyAllocationQuantity() 都是要取消的数量 + //物料明细层面的验证已经在 batchCancelAssignUpdate 中完成,这里直接使用即可 + BigDecimal cancelQuantity = stockOutOrderPO.getAllocationQuantity(); + BigDecimal cancelAlreadyAllocationQuantity = stockOutOrderPO.getAlreadyAllocationQuantity() != null + ? stockOutOrderPO.getAlreadyAllocationQuantity() + : BigDecimal.ZERO; + + // 取消分配:减少已分配数量 + // 注意:如果出库单的 alreadyAllocationQuantity 数据不一致(可能为0),使用 cancelAlreadyAllocationQuantity 作为参考 + // 但为了数据一致性,我们仍然从当前值中减去取消的数量 + if (alreadyAllocationQuantity.compareTo(cancelAlreadyAllocationQuantity) < 0) { + // 如果出库单的已分配数量小于要取消的数量,说明数据不一致,使用要取消的数量作为基准 + alreadyAllocationQuantity = cancelAlreadyAllocationQuantity; } - allocationQuantity = allocationQuantity.subtract(stockOutOrderPO.getAllocationQuantity()); + alreadyAllocationQuantity = alreadyAllocationQuantity.subtract(cancelAlreadyAllocationQuantity); + // 确保不会变成负数 + if (alreadyAllocationQuantity.compareTo(BigDecimal.ZERO) < 0) { + alreadyAllocationQuantity = BigDecimal.ZERO; + } + status = judgeAllocationQuantityByManualAssign(stockOutOrderPO.getAllocationQuantity(), stockOutOrderPO.getAlreadyAllocationQuantity(),type); }else { allocationQuantity = allocationQuantity.add(stockOutOrderPO.getAllocationQuantity()); + alreadyAllocationQuantity = alreadyAllocationQuantity.add(stockOutOrderPO.getAlreadyAllocationQuantity() != null + ? stockOutOrderPO.getAlreadyAllocationQuantity() + : BigDecimal.ZERO); } return stockOutOrderService.update(null, new UpdateWrapper().lambda() .set(StockOutOrder::getStatus, status) .set(StockOutOrder::getAllocationQuantity, allocationQuantity) + .set(StockOutOrder::getAlreadyAllocationQuantity, alreadyAllocationQuantity) .set(StockOutOrder::getUpdateBy, loginUser.getUserid()) .set(StockOutOrder::getUpdateByName, loginUser.getUsername()) .set(StockOutOrder::getUpdateTime, new Date()) @@ -335,6 +441,15 @@ public class StockOutOrderDomainService { OutMaterialDetailDO outMaterialDetailDO = new OutMaterialDetailDO(); outMaterialDetailDO.setOutOrderNumber(stockOutOrderPO.getOutOrderNumber()); List materialDetailPOList = outMaterialDetailService.queryListChildren(outMaterialDetailDO); + for (OutMaterialDetailPO outMaterialDetailPO : materialDetailPOList) { + String materialNo = outMaterialDetailPO.getMaterialNo(); + List materialBaseInfos = materialBaseInfoMapper.selectList(new QueryWrapper().lambda().eq(MaterialBaseInfo::getMaterialCode, materialNo)); + if (!CollectionUtils.isEmpty(materialBaseInfos) && materialBaseInfos.size() > 0) { + outMaterialDetailPO.setCommodityName(materialBaseInfos.get(0).getMaterialName()); + outMaterialDetailPO.setMaterialCode(materialBaseInfos.get(0).getMaterialCode()); + outMaterialDetailPO.setMaterialName(materialBaseInfos.get(0).getMaterialName()); + } + } stockOutOrderPO.setMaterialDetailList(materialDetailPOList); return stockOutOrderPO; } @@ -426,25 +541,56 @@ public class StockOutOrderDomainService { List pickingMaterialDetailList = new ArrayList<>(); if (!CollectionUtils.isEmpty(outMaterialDetailPOS)){ outMaterialDetailPOS.forEach(outMaterialDetailPO -> { - PickingMaterialDetailDO pickingMaterialDetailDO = new PickingMaterialDetailDO(); - BeanUtils.copyProperties(outMaterialDetailPO, pickingMaterialDetailDO); - pickingMaterialDetailDO.setPickingOrderNumber(pickingOrderDO.getPickingOrderNumber()); - pickingMaterialDetailDO.setQuantity(outMaterialDetailPO.getAllocationQuantity()); - //设置出库明细关联id - pickingMaterialDetailDO.setOutUniqueId(outMaterialDetailPO.getUniqueId()); - pickingMaterialDetailList.add(pickingMaterialDetailDO); - List outMaterialDetailPOListChildren = outMaterialDetailPO.getChildren(); - if (!CollectionUtils.isEmpty(outMaterialDetailPOListChildren)){ - outMaterialDetailPOListChildren.forEach(outMaterialDetailPOChildren -> { - PickingMaterialDetailDO pickingMaterialDetailDOChildren = new PickingMaterialDetailDO(); - BeanUtils.copyProperties(pickingMaterialDetailDO, pickingMaterialDetailDOChildren); - BeanUtils.copyProperties(outMaterialDetailPOChildren, pickingMaterialDetailDOChildren); - pickingMaterialDetailDOChildren.setPickingOrderNumber(pickingOrderDO.getPickingOrderNumber()); - pickingMaterialDetailDOChildren.setQuantity(outMaterialDetailPOChildren.getAllocationQuantity()); - //设置出库明细关联id - pickingMaterialDetailDOChildren.setOutUniqueId(outMaterialDetailPOChildren.getUniqueId()); - pickingMaterialDetailList.add(pickingMaterialDetailDO); - }); + BigDecimal allocationQuantity = outMaterialDetailPO.getAllocationQuantity(); + if (allocationQuantity != null && allocationQuantity.compareTo(BigDecimal.ZERO) > 0) { + PickingMaterialDetailDO pickingMaterialDetailDO = new PickingMaterialDetailDO(); + BeanUtils.copyProperties(outMaterialDetailPO, pickingMaterialDetailDO); + pickingMaterialDetailDO.setPickingOrderNumber(pickingOrderDO.getPickingOrderNumber()); + pickingMaterialDetailDO.setQuantity(outMaterialDetailPO.getAllocationQuantity()); + //设置出库明细关联id + pickingMaterialDetailDO.setOutUniqueId(outMaterialDetailPO.getUniqueId()); + pickingMaterialDetailDO.setMaterialCode(outMaterialDetailPO.getMaterialNo()); + pickingMaterialDetailDO.setMaterialName(outMaterialDetailPO.getCommodityName()); + pickingMaterialDetailDO.setBarCode(outMaterialDetailPO.getBarCode()); + //设置批次属性字段(从出库单明细中获取) + pickingMaterialDetailDO.setBatchRefNo(outMaterialDetailPO.getBatchRefNo()); + pickingMaterialDetailDO.setSheetRefNo(outMaterialDetailPO.getSheetRefNo()); + pickingMaterialDetailDO.setBoxPalletNo(outMaterialDetailPO.getBoxPalletNo()); + pickingMaterialDetailDO.setExtAttr1(outMaterialDetailPO.getExtAttr1()); + pickingMaterialDetailDO.setExtAttr2(outMaterialDetailPO.getExtAttr2()); + pickingMaterialDetailDO.setProductionDate(outMaterialDetailPO.getProductionDate()); + pickingMaterialDetailDO.setExpiryDate(outMaterialDetailPO.getExpiryDate()); + pickingMaterialDetailDO.setInventoryDate(outMaterialDetailPO.getInventoryDate()); + pickingMaterialDetailDO.setExtAttr3(outMaterialDetailPO.getExtAttr3()); + pickingMaterialDetailDO.setExtAttr4(outMaterialDetailPO.getExtAttr4()); + pickingMaterialDetailList.add(pickingMaterialDetailDO); + List outMaterialDetailPOListChildren = outMaterialDetailPO.getChildren(); + if (!CollectionUtils.isEmpty(outMaterialDetailPOListChildren)){ + outMaterialDetailPOListChildren.forEach(outMaterialDetailPOChildren -> { + PickingMaterialDetailDO pickingMaterialDetailDOChildren = new PickingMaterialDetailDO(); + BeanUtils.copyProperties(pickingMaterialDetailDO, pickingMaterialDetailDOChildren); + BeanUtils.copyProperties(outMaterialDetailPOChildren, pickingMaterialDetailDOChildren); + pickingMaterialDetailDOChildren.setPickingOrderNumber(pickingOrderDO.getPickingOrderNumber()); + pickingMaterialDetailDOChildren.setQuantity(outMaterialDetailPOChildren.getAllocationQuantity()); + //设置出库明细关联id + pickingMaterialDetailDOChildren.setOutUniqueId(outMaterialDetailPOChildren.getUniqueId()); + pickingMaterialDetailDOChildren.setMaterialCode(outMaterialDetailPOChildren.getMaterialNo()); + pickingMaterialDetailDOChildren.setMaterialName(outMaterialDetailPOChildren.getCommodityName()); + pickingMaterialDetailDOChildren.setBarCode(outMaterialDetailPOChildren.getBarCode()); + //设置批次属性字段(从出库单明细中获取) + pickingMaterialDetailDOChildren.setBatchRefNo(outMaterialDetailPOChildren.getBatchRefNo()); + pickingMaterialDetailDOChildren.setSheetRefNo(outMaterialDetailPOChildren.getSheetRefNo()); + pickingMaterialDetailDOChildren.setBoxPalletNo(outMaterialDetailPOChildren.getBoxPalletNo()); + pickingMaterialDetailDOChildren.setExtAttr1(outMaterialDetailPOChildren.getExtAttr1()); + pickingMaterialDetailDOChildren.setExtAttr2(outMaterialDetailPOChildren.getExtAttr2()); + pickingMaterialDetailDOChildren.setProductionDate(outMaterialDetailPOChildren.getProductionDate()); + pickingMaterialDetailDOChildren.setExpiryDate(outMaterialDetailPOChildren.getExpiryDate()); + pickingMaterialDetailDOChildren.setInventoryDate(outMaterialDetailPOChildren.getInventoryDate()); + pickingMaterialDetailDOChildren.setExtAttr3(outMaterialDetailPOChildren.getExtAttr3()); + pickingMaterialDetailDOChildren.setExtAttr4(outMaterialDetailPOChildren.getExtAttr4()); + pickingMaterialDetailList.add(pickingMaterialDetailDOChildren); + }); + } } }); pickingOrderDO.setMaterialDetailList(pickingMaterialDetailList); @@ -535,6 +681,10 @@ public class StockOutOrderDomainService { OutMaterialDetailDO outMaterialDetailDO = new OutMaterialDetailDO(); outMaterialDetailDO.setOutOrderNumber(stockOutOrderPO.getOutOrderNumber()); List outMaterialDetailPOList = outMaterialDetailService.queryListChildren(outMaterialDetailDO); + for (OutMaterialDetailPO outMaterialDetailPO : outMaterialDetailPOList) { + outMaterialDetailPO.setMaterialCode(outMaterialDetailPO.getMaterialNo()); + outMaterialDetailPO.setMaterialName(outMaterialDetailPO.getCommodityName()); + } stockOutOrderPO.setMaterialDetailList(outMaterialDetailPOList); BigDecimal weightLimit = BigDecimal.ZERO; BigDecimal volumeLimit = BigDecimal.ZERO; @@ -953,7 +1103,7 @@ public class StockOutOrderDomainService { outMaterialDetailDO.setPackName(materialBaseInfoPO.getPackName()); //获取包装详情 - AjaxResult packDetailResult = systemServiceFeign.getInfoByPackIdAndUnitCode(materialBaseInfoPO.getPackId(), "EA"); + /*AjaxResult packDetailResult = systemServiceFeign.getInfoByPackIdAndUnitCode(materialBaseInfoPO.getPackId(), "EA"); if(!"200".equals(String.valueOf(packDetailResult.get("code")))){ throw new ServiceException("获取物料单位EA信息失败"); } @@ -971,7 +1121,7 @@ public class StockOutOrderDomainService { throw new ServiceException("物料仓库控制信息不存在"); } outMaterialDetailDO.setMaterialWarehouseControlId(materialWarehouseControlPO.getMaterialWarehouseControlId()); - outMaterialDetailDO.setSerialNumberManage(materialWarehouseControlPO.getSerialNumberManage()); + outMaterialDetailDO.setSerialNumberManage(materialWarehouseControlPO.getSerialNumberManage());*/ }); } @@ -998,4 +1148,5 @@ public class StockOutOrderDomainService { return 3; } } -} + +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutTaskOrder/repository/todo/StockOutTaskOrderDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutTaskOrder/repository/todo/StockOutTaskOrderDO.java index 39a4a417c..b369862af 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutTaskOrder/repository/todo/StockOutTaskOrderDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockOutTaskOrder/repository/todo/StockOutTaskOrderDO.java @@ -165,4 +165,19 @@ public class StockOutTaskOrderDO extends BaseVOEntity { @ApiModelProperty("大于指定状态值:1-待收货 2-部分收货 3-已收货 4-已关闭") private Integer gtStatus; + + @ApiModelProperty("集货库位ID集合") + private List storageLocationList; + + @ApiModelProperty(name = "创建时间查询条件开始日期") + private String createTimeStart; + + @ApiModelProperty(name = "创建时间查询条件结束日期") + private String createTimeEnd; + + @ApiModelProperty(name = "作业完成时间查询条件开始日期") + private String operatorsEndTimeStart; + + @ApiModelProperty(name = "作业完成时间查询条件结束日期") + private String operatorsEndTimeEnd; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/repository/todo/StockReceiptOrderDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/repository/todo/StockReceiptOrderDO.java index a2c23e31c..83d22c3e3 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/repository/todo/StockReceiptOrderDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/repository/todo/StockReceiptOrderDO.java @@ -158,4 +158,12 @@ public class StockReceiptOrderDO extends StockInOrderBaseDO { @ApiModelProperty("物料明细") private List materialDetailList; + @ApiModelProperty("仓库绑定的用户ID列表(用于任务下发时筛选操作人员)") + private List warehouseUserIds; + + @ApiModelProperty(name = "创建时间查询条件开始日期") + private String createTimeStart; + + @ApiModelProperty(name = "创建时间查询条件结束日期") + private String createTimeEnd; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java index 97f3a1d0b..d9e0dfb9b 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java @@ -24,6 +24,7 @@ import com.mhd.wms.domain.containerUsageRecord.repository.todo.ContainerUsageRec import com.mhd.wms.domain.deliveTask.repository.facade.IDeliveTaskService; import com.mhd.wms.domain.deliveTask.repository.todo.DeliveTaskDO; 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; import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.po.InMaterialDetailSerialNumberPO; import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.todo.InMaterialDetailSerialNumberDO; @@ -31,6 +32,8 @@ import com.mhd.wms.domain.inOrderAbnormal.repository.facade.IInOrderAbnormalServ import com.mhd.wms.domain.inOrderAbnormal.repository.todo.InOrderAbnormalBaseDO; import com.mhd.wms.domain.inventoryStandingDetail.repository.facade.IInventoryStandingDetailService; import com.mhd.wms.domain.inventoryStandingDetail.repository.todo.InventoryStandingDetailDO; +import com.mhd.wms.domain.inventoryStandingReport.repository.facade.IInventoryStandingReportService; +import com.mhd.wms.domain.inventoryStandingReport.repository.todo.InventoryStandingReportDO; import com.mhd.wms.domain.materialGoodsRule.entity.MaterialGoodsRule; import com.mhd.wms.domain.materialGoodsRule.repository.facade.IMaterialGoodsRuleService; import com.mhd.wms.domain.materialMoreDetail.repository.facade.IMaterialMoreDetailService; @@ -53,6 +56,9 @@ import com.mhd.wms.domain.stockReceiptOrder.repository.facade.IStockReceiptOrder import com.mhd.wms.domain.stockReceiptOrder.repository.po.StockReceiptOrderPO; import com.mhd.wms.domain.stockReceiptOrder.repository.todo.NoReceiptOrderDO; import com.mhd.wms.domain.stockReceiptOrder.repository.todo.StockReceiptOrderDO; +import com.mhd.wms.domain.stockShelfOrder.entity.StockShelfOrder; +import com.mhd.wms.domain.stockShelfOrder.repository.facade.IStockShelfOrderService; +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 com.mhd.wms.domain.taskReceiptMaterialDetail.repository.todo.TaskReceiptMaterialDetailDO; @@ -88,6 +94,8 @@ public class StockReceiptOrderDomainService { @Autowired private StockShelfOrderDomainService stockShelfOrderDomainService; @Autowired + private IStockShelfOrderService stockShelfOrderService; + @Autowired private IQualityInspectionService qualityInspectionService; @Autowired private IInMaterialDetailSerialNumberService inMaterialDetailSerialNumberService; @@ -104,6 +112,8 @@ public class StockReceiptOrderDomainService { @Autowired private IInventoryStandingDetailService inventoryStandingDetailService; @Autowired + private IInventoryStandingReportService inventoryStandingReportService; + @Autowired private IdGenerator idGenerator; @Autowired private IContainerUsageRecordService containerUsageRecordService; @@ -145,6 +155,7 @@ public class StockReceiptOrderDomainService { receiptMaterialDetail.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId()); receiptMaterialDetail.setUniqueId(idGenerator.snowflakeId(SnowFlakeConstants.wmsId)); receiptMaterialDetail.setReceiptOrderNumber(stockReceiptOrder.getReceiptOrderNumber()); + receiptMaterialDetail.setGenStockShelf(2); // 设置需要生成上架单 receiptMaterialDetail.setCreateBy(loginUser.getUserid()); receiptMaterialDetail.setCreateByName(loginUser.getUsername()); receiptMaterialDetail.setCreateTime(new Date()); @@ -325,8 +336,11 @@ public class StockReceiptOrderDomainService { if (CollectionUtils.isEmpty(stockReceiptOrderPOList)) { throw new ServiceException("收货单不存在或已下发,请重新选择"); } - //是否任务合并下发 + //是否任务合并下发:如果前端没有传递或为null,默认设置为2(否) Integer taskDistributionMerge = stockReceiptOrderDO.getTaskDistributionMerge(); + if (taskDistributionMerge == null) { + taskDistributionMerge = 2; // 默认不合并下发 + } //收货生成任务下发 genDeliveTask(stockReceiptOrderPOList, stockReceiptOrderDO); //标记收货单任务已下发 @@ -369,6 +383,8 @@ public class StockReceiptOrderDomainService { } //保存容器使用记录 genContainerUsageRecord(stockReceiptOrderDO); + //生成库存台账报表记录(收货虚拟库存)- 需要在batchReceiptUpdate之前调用,因为batchReceiptUpdate会将状态更新为3 + genInventoryStandingReport(stockReceiptOrderPO, stockReceiptOrderDO); //修改物料明细信息 receiptMaterialDetailService.batchReceiptUpdate(stockReceiptOrderDO); //生成 收货作业单 @@ -455,8 +471,44 @@ public class StockReceiptOrderDomainService { //根据收货数量生成上架 genStockShelfOrder(stockReceiptOrderPO); + //收货完成后自动生成上架任务 + try { + //查询刚生成的上架单 + StockShelfOrderDO stockShelfOrderDOQuery = new StockShelfOrderDO(); + stockShelfOrderDOQuery.setReceiptOrderNumber(stockReceiptOrderPO.getReceiptOrderNumber()); + stockShelfOrderDOQuery.setTaskDistribution(2); // 查询未下发的上架单 + List stockShelfOrderPOList = stockShelfOrderService.queryList(stockShelfOrderDOQuery); + if (!CollectionUtils.isEmpty(stockShelfOrderPOList)) { + //创建上架任务参数 + StockShelfOrderDO stockShelfOrderDO = new StockShelfOrderDO(); + stockShelfOrderDO.setShelfOrderIds(stockShelfOrderPOList.stream() + .map(StockShelfOrderPO::getShelfOrderId) + .collect(Collectors.toList())); + //如果没有指定操作人员,使用当前登录用户 + if (stockShelfOrderDO.getOperatorsBy() == null) { + stockShelfOrderDO.setOperatorsBy(loginUser.getUserid()); + stockShelfOrderDO.setOperatorsName(loginUser.getUsername()); + } + //生成上架任务 + stockShelfOrderDomainService.genDeliveTask(stockShelfOrderPOList, stockShelfOrderDO); + //标记上架单任务已下发 + stockShelfOrderService.update(null, new UpdateWrapper().lambda() + .set(StockShelfOrder::getTaskDistribution, 1) + .set(StockShelfOrder::getTaskDistributionTime, new Date()) + .set(StockShelfOrder::getUpdateBy, loginUser.getUserid()) + .set(StockShelfOrder::getUpdateByName, loginUser.getUsername()) + .set(StockShelfOrder::getUpdateTime, new Date()) + .in(StockShelfOrder::getShelfOrderId, stockShelfOrderDO.getShelfOrderIds())); + } + } catch (Exception e) { + //如果生成上架任务失败,记录日志但不影响收货完成流程 + log.error("收货完成后生成上架任务失败,收货单号:{}", stockReceiptOrderPO.getReceiptOrderNumber(), e); + } + //生成收货追溯记录 genInventoryStandingDetail(stockReceiptOrderPO); + //生成库存台账报表记录(收货虚拟库存) + genInventoryStandingReport(stockReceiptOrderPO); //存在异常 生成记录 if (abnormal == 1){ genInOrderAbnormal(stockReceiptOrderPO); @@ -619,19 +671,95 @@ public class StockReceiptOrderDomainService { stockShelfOrderDO.setStatus(1); List shelfMaterialDetailDOList = new ArrayList<>(); stockReceiptOrderDO.getMaterialDetailList().forEach(receiptMaterialDetailDO -> { + // 如果已收货数量为0,跳过该明细,不生成上架单明细任务 + if (receiptMaterialDetailDO.getReceiptQuantity() == null || + receiptMaterialDetailDO.getReceiptQuantity().compareTo(BigDecimal.ZERO) <= 0) { + return; + } + ShelfMaterialDetailDO shelfMaterialDetailDO = new ShelfMaterialDetailDO(); BeanUtils.copyProperties(receiptMaterialDetailDO, shelfMaterialDetailDO); shelfMaterialDetailDO.setQuantity(receiptMaterialDetailDO.getReceiptQuantity()); shelfMaterialDetailDO.setInUniqueId(receiptMaterialDetailDO.getInUniqueId()); shelfMaterialDetailDO.setReceiptUniqueId(receiptMaterialDetailDO.getUniqueId()); - receiptMaterialDetailDO.getChildren().forEach(receiptMaterialDetailDOChildren -> { - ShelfMaterialDetailDO shelfMaterialDetailDOChildren = new ShelfMaterialDetailDO(); - BeanUtils.copyProperties(receiptMaterialDetailDOChildren, shelfMaterialDetailDOChildren); - shelfMaterialDetailDOChildren.setQuantity(receiptMaterialDetailDOChildren.getReceiptQuantity()); - shelfMaterialDetailDOChildren.setInUniqueId(receiptMaterialDetailDO.getInUniqueId()); - shelfMaterialDetailDOChildren.setReceiptUniqueId(receiptMaterialDetailDO.getUniqueId()); - shelfMaterialDetailDOList.add(shelfMaterialDetailDOChildren); - }); + // 传递生产日期、过期日期、存货日期、Batch Ref NO's、Sheet Ref NO's、箱号/卡板号、扩展属性1-4 + shelfMaterialDetailDO.setProductionDate(receiptMaterialDetailDO.getProductionDate()); + shelfMaterialDetailDO.setTotalArea(receiptMaterialDetailDO.getTotalArea()); + shelfMaterialDetailDO.setTotalVolume(receiptMaterialDetailDO.getTotalVolume()); + shelfMaterialDetailDO.setTotalNetWeight(receiptMaterialDetailDO.getTotalNetWeight()); + shelfMaterialDetailDO.setTotalGrossWeight(receiptMaterialDetailDO.getTotalGrossWeight()); + shelfMaterialDetailDO.setExpiryDate(receiptMaterialDetailDO.getExpiryDate()); + shelfMaterialDetailDO.setInventoryDate(receiptMaterialDetailDO.getInventoryDate()); + shelfMaterialDetailDO.setBatchRefNo(receiptMaterialDetailDO.getBatchRefNo()); + shelfMaterialDetailDO.setSheetRefNo(receiptMaterialDetailDO.getSheetRefNo()); + shelfMaterialDetailDO.setBoxPalletNo(receiptMaterialDetailDO.getBoxPalletNo()); + shelfMaterialDetailDO.setExtAttr1(receiptMaterialDetailDO.getExtAttr1()); + shelfMaterialDetailDO.setExtAttr2(receiptMaterialDetailDO.getExtAttr2()); + // extAttr3和extAttr4在ReceiptMaterialDetailDO中是String类型,在ShelfMaterialDetailDO中是Date类型,需要转换 + if (receiptMaterialDetailDO.getExtAttr3() != null && !receiptMaterialDetailDO.getExtAttr3().isEmpty()) { + try { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + shelfMaterialDetailDO.setExtAttr3(sdf.parse(receiptMaterialDetailDO.getExtAttr3())); + } catch (Exception e) { + // 如果转换失败,不设置该字段 + } + } + if (receiptMaterialDetailDO.getExtAttr4() != null && !receiptMaterialDetailDO.getExtAttr4().isEmpty()) { + try { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + shelfMaterialDetailDO.setExtAttr4(sdf.parse(receiptMaterialDetailDO.getExtAttr4())); + } catch (Exception e) { + // 如果转换失败,不设置该字段 + } + } + + // 处理子项:如果子项的已收货数量为0,跳过该子项 + if (receiptMaterialDetailDO.getChildren() != null && !receiptMaterialDetailDO.getChildren().isEmpty()) { + receiptMaterialDetailDO.getChildren().forEach(receiptMaterialDetailDOChildren -> { + // 如果子项的已收货数量为0,跳过该子项,不生成上架单明细任务 + if (receiptMaterialDetailDOChildren.getReceiptQuantity() == null || + receiptMaterialDetailDOChildren.getReceiptQuantity().compareTo(BigDecimal.ZERO) <= 0) { + return; + } + + ShelfMaterialDetailDO shelfMaterialDetailDOChildren = new ShelfMaterialDetailDO(); + BeanUtils.copyProperties(receiptMaterialDetailDOChildren, shelfMaterialDetailDOChildren); + shelfMaterialDetailDOChildren.setQuantity(receiptMaterialDetailDOChildren.getReceiptQuantity()); + shelfMaterialDetailDOChildren.setInUniqueId(receiptMaterialDetailDO.getInUniqueId()); + shelfMaterialDetailDOChildren.setReceiptUniqueId(receiptMaterialDetailDO.getUniqueId()); + shelfMaterialDetailDOChildren.setTotalArea(receiptMaterialDetailDOChildren.getTotalArea()); + shelfMaterialDetailDOChildren.setTotalVolume(receiptMaterialDetailDOChildren.getTotalVolume()); + shelfMaterialDetailDOChildren.setTotalNetWeight(receiptMaterialDetailDOChildren.getTotalNetWeight()); + shelfMaterialDetailDOChildren.setTotalGrossWeight(receiptMaterialDetailDOChildren.getTotalGrossWeight()); + // 传递生产日期、过期日期、存货日期、Batch Ref NO's、Sheet Ref NO's、箱号/卡板号、扩展属性1-4 + shelfMaterialDetailDOChildren.setProductionDate(receiptMaterialDetailDOChildren.getProductionDate()); + shelfMaterialDetailDOChildren.setExpiryDate(receiptMaterialDetailDOChildren.getExpiryDate()); + shelfMaterialDetailDOChildren.setInventoryDate(receiptMaterialDetailDOChildren.getInventoryDate()); + shelfMaterialDetailDOChildren.setBatchRefNo(receiptMaterialDetailDOChildren.getBatchRefNo()); + shelfMaterialDetailDOChildren.setSheetRefNo(receiptMaterialDetailDOChildren.getSheetRefNo()); + shelfMaterialDetailDOChildren.setBoxPalletNo(receiptMaterialDetailDOChildren.getBoxPalletNo()); + shelfMaterialDetailDOChildren.setExtAttr1(receiptMaterialDetailDOChildren.getExtAttr1()); + shelfMaterialDetailDOChildren.setExtAttr2(receiptMaterialDetailDOChildren.getExtAttr2()); + // extAttr3和extAttr4在ReceiptMaterialDetailDO中是String类型,在ShelfMaterialDetailDO中是Date类型,需要转换 + if (receiptMaterialDetailDOChildren.getExtAttr3() != null && !receiptMaterialDetailDOChildren.getExtAttr3().isEmpty()) { + try { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + shelfMaterialDetailDOChildren.setExtAttr3(sdf.parse(receiptMaterialDetailDOChildren.getExtAttr3())); + } catch (Exception e) { + // 如果转换失败,不设置该字段 + } + } + if (receiptMaterialDetailDOChildren.getExtAttr4() != null && !receiptMaterialDetailDOChildren.getExtAttr4().isEmpty()) { + try { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + shelfMaterialDetailDOChildren.setExtAttr4(sdf.parse(receiptMaterialDetailDOChildren.getExtAttr4())); + } catch (Exception e) { + // 如果转换失败,不设置该字段 + } + } + shelfMaterialDetailDOList.add(shelfMaterialDetailDOChildren); + }); + } shelfMaterialDetailDOList.add(shelfMaterialDetailDO); }); stockShelfOrderDO.setMaterialDetailList(shelfMaterialDetailDOList); @@ -663,13 +791,69 @@ public class StockReceiptOrderDomainService { List receiptMaterialDetailPOS = receiptMaterialDetailService.queryList(receiptMaterialDetailDO); //上架单明细集合 List shelfMaterialDetailDOList = new ArrayList<>(); + // 批量查询入库单明细,用于获取净重、毛重、体积、面积等字段 + List inUniqueIds = receiptMaterialDetailPOS.stream() + .filter(r -> 2 == r.getGenStockShelf() && r.getInUniqueId() != null) + .map(ReceiptMaterialDetailPO::getInUniqueId) + .distinct() + .collect(Collectors.toList()); + Map inMaterialDetailMap = new HashMap<>(); + if (!CollectionUtils.isEmpty(inUniqueIds)) { + // 使用 MyBatis-Plus 的 QueryWrapper 批量查询入库单明细 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("unique_id", inUniqueIds); + queryWrapper.eq("del_flag", 1); + List inMaterialDetailList = iInMaterialDetailService.list(queryWrapper); + // 转换为 PO 对象 + for (com.mhd.wms.domain.inMaterialDetail.entity.InMaterialDetail inMaterialDetail : inMaterialDetailList) { + InMaterialDetailPO inMaterialDetailPO = new InMaterialDetailPO(); + BeanUtils.copyProperties(inMaterialDetail, inMaterialDetailPO); + inMaterialDetailMap.put(inMaterialDetail.getUniqueId(), inMaterialDetailPO); + } + } for (ReceiptMaterialDetailPO receiptMaterialDetailPO : receiptMaterialDetailPOS) { if (2 == receiptMaterialDetailPO.getGenStockShelf()) { + // 如果已收货数量为0,跳过该明细,不生成上架单明细任务 + if (receiptMaterialDetailPO.getReceiptQuantity() == null || + receiptMaterialDetailPO.getReceiptQuantity().compareTo(BigDecimal.ZERO) <= 0) { + continue; + } + ShelfMaterialDetailDO shelfMaterialDetailDO = new ShelfMaterialDetailDO(); BeanUtils.copyProperties(receiptMaterialDetailPO, shelfMaterialDetailDO); shelfMaterialDetailDO.setQuantity(receiptMaterialDetailPO.getReceiptQuantity()); shelfMaterialDetailDO.setInUniqueId(receiptMaterialDetailPO.getInUniqueId()); shelfMaterialDetailDO.setReceiptUniqueId(receiptMaterialDetailPO.getUniqueId()); + shelfMaterialDetailDO.setTotalArea(receiptMaterialDetailPO.getTotalArea()); + shelfMaterialDetailDO.setTotalVolume(receiptMaterialDetailPO.getTotalVolume()); + shelfMaterialDetailDO.setTotalNetWeight(receiptMaterialDetailPO.getTotalNetWeight()); + shelfMaterialDetailDO.setTotalGrossWeight(receiptMaterialDetailPO.getTotalGrossWeight()); + // 传递生产日期、过期日期、存货日期、Batch Ref NO's、Sheet Ref NO's、箱号/卡板号、扩展属性1-4 + shelfMaterialDetailDO.setProductionDate(receiptMaterialDetailPO.getProductionDate()); + shelfMaterialDetailDO.setExpiryDate(receiptMaterialDetailPO.getExpiryDate()); + shelfMaterialDetailDO.setInventoryDate(receiptMaterialDetailPO.getInventoryDate()); + shelfMaterialDetailDO.setBatchRefNo(receiptMaterialDetailPO.getBatchRefNo()); + shelfMaterialDetailDO.setSheetRefNo(receiptMaterialDetailPO.getSheetRefNo()); + shelfMaterialDetailDO.setBoxPalletNo(receiptMaterialDetailPO.getBoxPalletNo()); + shelfMaterialDetailDO.setExtAttr1(receiptMaterialDetailPO.getExtAttr1()); + shelfMaterialDetailDO.setExtAttr2(receiptMaterialDetailPO.getExtAttr2()); + // extAttr3和extAttr4在ReceiptMaterialDetailPO中是String类型,在ShelfMaterialDetailDO中是Date类型,需要转换 + if (receiptMaterialDetailPO.getExtAttr3() != null && !receiptMaterialDetailPO.getExtAttr3().isEmpty()) { + try { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + shelfMaterialDetailDO.setExtAttr3(sdf.parse(receiptMaterialDetailPO.getExtAttr3())); + } catch (Exception e) { + // 如果转换失败,不设置该字段 + } + } + if (receiptMaterialDetailPO.getExtAttr4() != null && !receiptMaterialDetailPO.getExtAttr4().isEmpty()) { + try { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + shelfMaterialDetailDO.setExtAttr4(sdf.parse(receiptMaterialDetailPO.getExtAttr4())); + } catch (Exception e) { + // 如果转换失败,不设置该字段 + } + } shelfMaterialDetailDOList.add(shelfMaterialDetailDO); receiptQuantity = receiptQuantity.add(receiptMaterialDetailPO.getReceiptQuantity()); } @@ -722,19 +906,86 @@ public class StockReceiptOrderDomainService { List receiptMaterialDetailPODbs = receiptMaterialDetailPOListMap.get(p.getReceiptOrderNumber()); List shelfMaterialDetailDOList = new ArrayList<>(); receiptMaterialDetailPODbs.forEach(receiptMaterialDetailPO -> { + // 如果已收货数量为0,跳过该明细,不生成上架单明细任务 + if (receiptMaterialDetailPO.getReceiptQuantity() == null || + receiptMaterialDetailPO.getReceiptQuantity().compareTo(BigDecimal.ZERO) <= 0) { + return; + } + ShelfMaterialDetailDO shelfMaterialDetailDO = new ShelfMaterialDetailDO(); BeanUtils.copyProperties(receiptMaterialDetailPO, shelfMaterialDetailDO); shelfMaterialDetailDO.setQuantity(receiptMaterialDetailPO.getReceiptQuantity()); shelfMaterialDetailDO.setInUniqueId(receiptMaterialDetailPO.getInUniqueId()); shelfMaterialDetailDO.setReceiptUniqueId(receiptMaterialDetailPO.getUniqueId()); - receiptMaterialDetailPO.getChildren().forEach(receiptMaterialDetailDOChildren -> { - ShelfMaterialDetailDO shelfMaterialDetailDOChildren = new ShelfMaterialDetailDO(); - BeanUtils.copyProperties(receiptMaterialDetailDOChildren, shelfMaterialDetailDOChildren); - shelfMaterialDetailDOChildren.setQuantity(receiptMaterialDetailDOChildren.getReceiptQuantity()); - shelfMaterialDetailDOChildren.setInUniqueId(receiptMaterialDetailPO.getInUniqueId()); - shelfMaterialDetailDOChildren.setReceiptUniqueId(receiptMaterialDetailPO.getUniqueId()); - shelfMaterialDetailDOList.add(shelfMaterialDetailDOChildren); - }); + // 传递生产日期、过期日期、存货日期、Batch Ref NO's、Sheet Ref NO's、箱号/卡板号、扩展属性1-4 + shelfMaterialDetailDO.setProductionDate(receiptMaterialDetailPO.getProductionDate()); + shelfMaterialDetailDO.setExpiryDate(receiptMaterialDetailPO.getExpiryDate()); + shelfMaterialDetailDO.setInventoryDate(receiptMaterialDetailPO.getInventoryDate()); + shelfMaterialDetailDO.setBatchRefNo(receiptMaterialDetailPO.getBatchRefNo()); + shelfMaterialDetailDO.setSheetRefNo(receiptMaterialDetailPO.getSheetRefNo()); + shelfMaterialDetailDO.setBoxPalletNo(receiptMaterialDetailPO.getBoxPalletNo()); + shelfMaterialDetailDO.setExtAttr1(receiptMaterialDetailPO.getExtAttr1()); + shelfMaterialDetailDO.setExtAttr2(receiptMaterialDetailPO.getExtAttr2()); + // extAttr3和extAttr4在ReceiptMaterialDetailPO中是String类型,在ShelfMaterialDetailDO中是Date类型,需要转换 + if (receiptMaterialDetailPO.getExtAttr3() != null && !receiptMaterialDetailPO.getExtAttr3().isEmpty()) { + try { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + shelfMaterialDetailDO.setExtAttr3(sdf.parse(receiptMaterialDetailPO.getExtAttr3())); + } catch (Exception e) { + // 如果转换失败,不设置该字段 + } + } + if (receiptMaterialDetailPO.getExtAttr4() != null && !receiptMaterialDetailPO.getExtAttr4().isEmpty()) { + try { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + shelfMaterialDetailDO.setExtAttr4(sdf.parse(receiptMaterialDetailPO.getExtAttr4())); + } catch (Exception e) { + // 如果转换失败,不设置该字段 + } + } + // 处理子项:如果子项的已收货数量为0,跳过该子项 + if (receiptMaterialDetailPO.getChildren() != null && !receiptMaterialDetailPO.getChildren().isEmpty()) { + receiptMaterialDetailPO.getChildren().forEach(receiptMaterialDetailDOChildren -> { + // 如果子项的已收货数量为0,跳过该子项,不生成上架单明细任务 + if (receiptMaterialDetailDOChildren.getReceiptQuantity() == null || + receiptMaterialDetailDOChildren.getReceiptQuantity().compareTo(BigDecimal.ZERO) <= 0) { + return; + } + + ShelfMaterialDetailDO shelfMaterialDetailDOChildren = new ShelfMaterialDetailDO(); + BeanUtils.copyProperties(receiptMaterialDetailDOChildren, shelfMaterialDetailDOChildren); + shelfMaterialDetailDOChildren.setQuantity(receiptMaterialDetailDOChildren.getReceiptQuantity()); + shelfMaterialDetailDOChildren.setInUniqueId(receiptMaterialDetailPO.getInUniqueId()); + shelfMaterialDetailDOChildren.setReceiptUniqueId(receiptMaterialDetailPO.getUniqueId()); + // 传递生产日期、过期日期、存货日期、Batch Ref NO's、Sheet Ref NO's、箱号/卡板号、扩展属性1-4 + shelfMaterialDetailDOChildren.setProductionDate(receiptMaterialDetailDOChildren.getProductionDate()); + shelfMaterialDetailDOChildren.setExpiryDate(receiptMaterialDetailDOChildren.getExpiryDate()); + shelfMaterialDetailDOChildren.setInventoryDate(receiptMaterialDetailDOChildren.getInventoryDate()); + shelfMaterialDetailDOChildren.setBatchRefNo(receiptMaterialDetailDOChildren.getBatchRefNo()); + shelfMaterialDetailDOChildren.setSheetRefNo(receiptMaterialDetailDOChildren.getSheetRefNo()); + shelfMaterialDetailDOChildren.setBoxPalletNo(receiptMaterialDetailDOChildren.getBoxPalletNo()); + shelfMaterialDetailDOChildren.setExtAttr1(receiptMaterialDetailDOChildren.getExtAttr1()); + shelfMaterialDetailDOChildren.setExtAttr2(receiptMaterialDetailDOChildren.getExtAttr2()); + // extAttr3和extAttr4在ReceiptMaterialDetailPO中是String类型,在ShelfMaterialDetailDO中是Date类型,需要转换 + if (receiptMaterialDetailDOChildren.getExtAttr3() != null && !receiptMaterialDetailDOChildren.getExtAttr3().isEmpty()) { + try { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + shelfMaterialDetailDOChildren.setExtAttr3(sdf.parse(receiptMaterialDetailDOChildren.getExtAttr3())); + } catch (Exception e) { + // 如果转换失败,不设置该字段 + } + } + if (receiptMaterialDetailDOChildren.getExtAttr4() != null && !receiptMaterialDetailDOChildren.getExtAttr4().isEmpty()) { + try { + java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + shelfMaterialDetailDOChildren.setExtAttr4(sdf.parse(receiptMaterialDetailDOChildren.getExtAttr4())); + } catch (Exception e) { + // 如果转换失败,不设置该字段 + } + } + shelfMaterialDetailDOList.add(shelfMaterialDetailDOChildren); + }); + } shelfMaterialDetailDOList.add(shelfMaterialDetailDO); }); stockShelfOrderDO.setMaterialDetailList(shelfMaterialDetailDOList); @@ -917,6 +1168,177 @@ public class StockReceiptOrderDomainService { inventoryStandingDetailService.batchInsert(inventoryStandingDetailDOList); } + /** + * @description 生成库存台账报表记录(收货虚拟库存) + * @author Auto + * @date 2026/1/24 + * @param stockReceiptOrderPO + */ + public void genInventoryStandingReport(StockReceiptOrderPO stockReceiptOrderPO){ + genInventoryStandingReport(stockReceiptOrderPO, null); + } + + /** + * @description 生成库存台账报表记录(收货虚拟库存)- 重载方法,支持从stockReceiptOrderDO获取数据 + * @author Auto + * @date 2026/1/24 + * @param stockReceiptOrderPO + * @param stockReceiptOrderDO 如果提供,则从该对象中获取receipt_quantity,否则从数据库查询 + */ + public void genInventoryStandingReport(StockReceiptOrderPO stockReceiptOrderPO, StockReceiptOrderDO stockReceiptOrderDO){ + try { + // 重新查询最新的收货单信息,确保获取到最新的数据 + StockReceiptOrderPO latestStockReceiptOrderPO = stockReceiptOrderService.getInfo(stockReceiptOrderPO.getReceiptOrderId()); + if (latestStockReceiptOrderPO == null) { + log.warn("生成库存台账报表记录失败,收货单不存在,收货单ID:{}", stockReceiptOrderPO.getReceiptOrderId()); + return; + } + + // 如果提供了stockReceiptOrderDO,则从该对象中获取数据,否则从数据库查询 + List receiptMaterialDetailPOList; + if (stockReceiptOrderDO != null && !CollectionUtils.isEmpty(stockReceiptOrderDO.getMaterialDetailList())) { + // 从stockReceiptOrderDO中获取数据,转换为ReceiptMaterialDetailPO + receiptMaterialDetailPOList = new ArrayList<>(); + log.info("从stockReceiptOrderDO获取收货明细,收货单号:{},明细数量:{}", + latestStockReceiptOrderPO.getReceiptOrderNumber(), + stockReceiptOrderDO.getMaterialDetailList().size()); + for (ReceiptMaterialDetailDO receiptMaterialDetailDO : stockReceiptOrderDO.getMaterialDetailList()) { + // 记录原始数据 + log.debug("处理收货明细DO,物料编码:{},物料名称:{},收货数量:{},收货状态:{}", + receiptMaterialDetailDO.getMaterialCode(), + receiptMaterialDetailDO.getMaterialName(), + receiptMaterialDetailDO.getReceiptQuantity(), + receiptMaterialDetailDO.getReceiptStatus()); + + // 优先使用receiptMaterialDetailDO.getReceiptQuantity()的值(本次收货数量) + // 如果receiptQuantity为null或<=0,跳过该记录 + if (receiptMaterialDetailDO.getReceiptQuantity() == null || + receiptMaterialDetailDO.getReceiptQuantity().compareTo(BigDecimal.ZERO) <= 0) { + log.debug("跳过收货明细(收货数量为空或<=0),物料编码:{},收货数量:{}", + receiptMaterialDetailDO.getMaterialCode(), + receiptMaterialDetailDO.getReceiptQuantity()); + continue; + } + + ReceiptMaterialDetailPO receiptMaterialDetailPO = new ReceiptMaterialDetailPO(); + BeanUtils.copyProperties(receiptMaterialDetailDO, receiptMaterialDetailPO); + // 设置收货单号 + receiptMaterialDetailPO.setReceiptOrderNumber(latestStockReceiptOrderPO.getReceiptOrderNumber()); + // 确保receiptQuantity字段被正确设置(使用DO中的值,因为已经验证过不为null且>0) + receiptMaterialDetailPO.setReceiptQuantity(receiptMaterialDetailDO.getReceiptQuantity()); + // 如果receipt_status为空,则设置为2(收货中),因为这是在batchReceiptUpdate之前调用的 + if (receiptMaterialDetailPO.getReceiptStatus() == null) { + receiptMaterialDetailPO.setReceiptStatus(2); + } + receiptMaterialDetailPOList.add(receiptMaterialDetailPO); + log.debug("添加收货明细PO到列表,物料编码:{},收货数量:{}", + receiptMaterialDetailPO.getMaterialCode(), + receiptMaterialDetailPO.getReceiptQuantity()); + } + log.info("从stockReceiptOrderDO转换后的收货明细数量:{}", receiptMaterialDetailPOList.size()); + } else { + // 从数据库查询 + log.info("从数据库查询收货明细,收货单号:{}", latestStockReceiptOrderPO.getReceiptOrderNumber()); + ReceiptMaterialDetailDO receiptMaterialDetailDO = new ReceiptMaterialDetailDO(); + receiptMaterialDetailDO.setReceiptOrderNumber(latestStockReceiptOrderPO.getReceiptOrderNumber()); + receiptMaterialDetailPOList = receiptMaterialDetailService.queryList(receiptMaterialDetailDO); + log.info("从数据库查询到的收货明细数量:{}", receiptMaterialDetailPOList != null ? receiptMaterialDetailPOList.size() : 0); + } + + if (CollectionUtils.isEmpty(receiptMaterialDetailPOList)) { + log.warn("生成库存台账报表记录失败,收货明细为空,收货单号:{}", latestStockReceiptOrderPO.getReceiptOrderNumber()); + return; + } + + // 按物料、货主、仓库分组统计收货数量 + Map reportMap = new HashMap<>(); + log.info("开始生成库存台账报表记录,收货单号:{},收货明细数量:{}", + latestStockReceiptOrderPO.getReceiptOrderNumber(), receiptMaterialDetailPOList.size()); + for (ReceiptMaterialDetailPO receiptMaterialDetailPO : receiptMaterialDetailPOList){ + // 记录每个明细的详细信息 + log.debug("处理收货明细,物料编码:{},物料名称:{},收货数量:{},收货状态:{}", + receiptMaterialDetailPO.getMaterialCode(), + receiptMaterialDetailPO.getMaterialName(), + receiptMaterialDetailPO.getReceiptQuantity(), + receiptMaterialDetailPO.getReceiptStatus()); + + // 只统计有收货数量的记录 + if (receiptMaterialDetailPO.getReceiptQuantity() == null || + receiptMaterialDetailPO.getReceiptQuantity().compareTo(BigDecimal.ZERO) <= 0) { + log.debug("跳过收货明细(收货数量为空或<=0),物料编码:{},收货数量:{}", + receiptMaterialDetailPO.getMaterialCode(), + receiptMaterialDetailPO.getReceiptQuantity()); + continue; + } + // 只统计收货状态为1(待收货)或2(收货中)的记录 + // 注意:在receivingGoods调用时,我们从stockReceiptOrderDO中获取数据,状态设置为2 + if (receiptMaterialDetailPO.getReceiptStatus() == null || + receiptMaterialDetailPO.getReceiptStatus() < 1 || + receiptMaterialDetailPO.getReceiptStatus() > 2) { + log.debug("跳过收货明细(收货状态不符合要求),物料编码:{},收货状态:{}(需要1或2)", + receiptMaterialDetailPO.getMaterialCode(), + receiptMaterialDetailPO.getReceiptStatus()); + continue; + } + + // 生成唯一key:物料编码_货主ID_仓库ID + String key = receiptMaterialDetailPO.getMaterialCode() + "_" + + latestStockReceiptOrderPO.getShipperId() + "_" + + latestStockReceiptOrderPO.getWarehouseId(); + + InventoryStandingReportDO reportDO = reportMap.get(key); + if (reportDO == null) { + reportDO = new InventoryStandingReportDO(); + reportDO.setOrganizationId(latestStockReceiptOrderPO.getOrganizationId()); + reportDO.setOrganizationName(latestStockReceiptOrderPO.getOrganizationName()); + reportDO.setTopOrganizationId(latestStockReceiptOrderPO.getTopOrganizationId()); + reportDO.setMaterialCode(receiptMaterialDetailPO.getMaterialCode()); + reportDO.setMaterialName(receiptMaterialDetailPO.getMaterialName()); + reportDO.setBarCode(receiptMaterialDetailPO.getBarCode()); + reportDO.setShipperId(latestStockReceiptOrderPO.getShipperId()); + reportDO.setShipperCode(latestStockReceiptOrderPO.getShipperCode()); + reportDO.setShipperName(latestStockReceiptOrderPO.getShipperName()); + reportDO.setWarehouseId(latestStockReceiptOrderPO.getWarehouseId()); + reportDO.setWarehouseCode(latestStockReceiptOrderPO.getWarehouseCode()); + reportDO.setWarehouseName(latestStockReceiptOrderPO.getWarehouseName()); + reportDO.setNodeStatus(1); // 1-收货 + reportDO.setMaterialQuantity(BigDecimal.ZERO); + reportMap.put(key, reportDO); + } + // 累加收货数量 + reportDO.setMaterialQuantity(reportDO.getMaterialQuantity().add(receiptMaterialDetailPO.getReceiptQuantity())); + } + + // 批量插入或更新库存台账报表记录 + int successCount = 0; + for (InventoryStandingReportDO reportDO : reportMap.values()) { + try { + Boolean result = inventoryStandingReportService.insert(reportDO); + if (result) { + successCount++; + log.info("生成库存台账报表记录成功,收货单号:{},物料编码:{},物料名称:{},数量:{}", + latestStockReceiptOrderPO.getReceiptOrderNumber(), + reportDO.getMaterialCode(), + reportDO.getMaterialName(), + reportDO.getMaterialQuantity()); + } else { + log.warn("生成库存台账报表记录失败,返回false,收货单号:{},物料编码:{}", + latestStockReceiptOrderPO.getReceiptOrderNumber(), reportDO.getMaterialCode()); + } + } catch (Exception e) { + log.error("生成库存台账报表记录异常,收货单号:{},物料编码:{},物料名称:{}", + latestStockReceiptOrderPO.getReceiptOrderNumber(), + reportDO.getMaterialCode(), + reportDO.getMaterialName(), e); + } + } + log.info("生成库存台账报表记录完成,收货单号:{},成功:{},总计:{}", + latestStockReceiptOrderPO.getReceiptOrderNumber(), successCount, reportMap.size()); + } catch (Exception e) { + log.error("生成库存台账报表记录异常,收货单号:{}", stockReceiptOrderPO.getReceiptOrderNumber(), e); + } + } + /** * @description 收货生成任务下发 * @author ZhouGY @@ -1025,4 +1447,4 @@ public class StockReceiptOrderDomainService { } } -} +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/repository/todo/StockShelfOrderDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/repository/todo/StockShelfOrderDO.java index 8eb433f1f..26470b410 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/repository/todo/StockShelfOrderDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/repository/todo/StockShelfOrderDO.java @@ -125,4 +125,10 @@ public class StockShelfOrderDO extends StockInOrderBaseDO { @ApiModelProperty("物料明细") private List materialDetailList; + + @ApiModelProperty(name = "创建时间查询条件开始日期") + private String createTimeStart; + + @ApiModelProperty(name = "创建时间查询条件结束日期") + private String createTimeEnd; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/service/StockShelfOrderDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/service/StockShelfOrderDomainService.java index a7c613f01..16d33a87b 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/service/StockShelfOrderDomainService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/service/StockShelfOrderDomainService.java @@ -27,10 +27,21 @@ import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.po.InMaterialD import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.todo.InMaterialDetailSerialNumberDO; import com.mhd.wms.domain.inOrderAbnormal.repository.facade.IInOrderAbnormalService; import com.mhd.wms.domain.inOrderAbnormal.repository.todo.InOrderAbnormalBaseDO; +import com.mhd.wms.domain.inventoryAdjustmentRecord.entity.InventoryAdjustmentRecord; +import com.mhd.wms.domain.inventoryAdjustmentRecord.repository.mapper.InventoryAdjustmentRecordMapper; import com.mhd.wms.domain.inventoryStandingDetail.repository.facade.IInventoryStandingDetailService; import com.mhd.wms.domain.inventoryStandingDetail.repository.todo.InventoryStandingDetailDO; +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.materialGoodsRule.repository.facade.IMaterialGoodsRuleService; +import com.mhd.wms.domain.materialGoodsRule.repository.po.BatchDetailPO; +import com.mhd.wms.domain.materialGoodsRule.repository.po.BatchPO; +import com.mhd.wms.domain.materialGoodsRule.repository.po.MaterialGoodsRulePO; import com.mhd.wms.domain.materialInventory.entity.MaterialInventory; import com.mhd.wms.domain.materialInventory.repository.facade.IMaterialInventoryService; +import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper; +import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO; import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryDO; import com.mhd.wms.domain.materialMoreDetail.repository.todo.MaterialMoreDetailDO; import com.mhd.wms.domain.serialNumber.entity.SerialNumber; @@ -55,6 +66,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; +import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; @@ -79,6 +91,8 @@ public class StockShelfOrderDomainService { @Autowired private IMaterialInventoryService materialInventoryService; @Autowired + private IMaterialBaseInfoService materialBaseInfoService; + @Autowired private IInMaterialDetailSerialNumberService inMaterialDetailSerialNumberService; @Autowired private IStockInTaskOrderService stockInTaskOrderService; @@ -94,6 +108,14 @@ public class StockShelfOrderDomainService { private ISerialNumberService iSerialNumberService; @Resource private SystemServiceFeign systemServiceFeign; + @Autowired + private MaterialInventoryMapper materialInventoryMapper; + @Autowired + private IMaterialGoodsRuleService materialGoodsRuleService; + @Autowired + private InventoryAdjustmentRecordMapper inventoryAdjustmentRecordMapper; + @Autowired + private MaterialBaseInfoMapper materialBaseInfoMapper; /** * 分页查询上架单列表 @@ -300,14 +322,17 @@ public class StockShelfOrderDomainService { StockShelfOrder stockShelfOrder = new StockShelfOrder(); stockShelfOrder.setShelfOrderId(stockShelfOrderDO.getShelfOrderId()); stockShelfOrder.setStatus(2); - stockShelfOrder.setShelvesQuantity(stockShelfOrderPO.getShelvesQuantity().add(stockShelfOrderDO.getActualQuantity())); + BigDecimal currentShelvesQuantity = stockShelfOrderPO.getShelvesQuantity() != null ? stockShelfOrderPO.getShelvesQuantity() : BigDecimal.ZERO; + BigDecimal actualQuantity = stockShelfOrderDO.getActualQuantity() != null ? stockShelfOrderDO.getActualQuantity() : BigDecimal.ZERO; + stockShelfOrder.setShelvesQuantity(currentShelvesQuantity.add(actualQuantity)); stockShelfOrder.setShelvesMaterialQuantity(stockShelfOrderPO.getShelvesMaterialQuantity() + stockShelfOrderDO.getActualReceiptMaterialQuantity()); stockShelfOrder.setUpdateBy(loginUser.getUserid()); stockShelfOrder.setUpdateByName(loginUser.getUsername()); stockShelfOrder.setUpdateTime(new Date()); stockShelfOrderService.updateById(stockShelfOrder); //上架数量大于等于计划数量 直接完成上架 - if (stockShelfOrder.getShelvesQuantity().compareTo(stockShelfOrderPO.getReceiptQuantity()) >= 0){ + BigDecimal receiptQuantity = stockShelfOrderPO.getReceiptQuantity() != null ? stockShelfOrderPO.getReceiptQuantity() : BigDecimal.ZERO; + if (stockShelfOrder.getShelvesQuantity().compareTo(receiptQuantity) >= 0){ completeUpShelf(stockShelfOrderPO.getShelfOrderId()); } return true; @@ -351,7 +376,9 @@ public class StockShelfOrderDomainService { throw new ServiceException("上架单【" + stockShelfOrderPO.getReceiptOrderNumber() + "】已完成上架,请重新选择"); } int abnormal = 2; - if (stockShelfOrderPO.getShelvesQuantity().compareTo(stockShelfOrderPO.getQuantity()) != 0){ + BigDecimal shelvesQuantity = stockShelfOrderPO.getShelvesQuantity() != null ? stockShelfOrderPO.getShelvesQuantity() : BigDecimal.ZERO; + BigDecimal quantity = stockShelfOrderPO.getReceiptQuantity() != null ? stockShelfOrderPO.getReceiptQuantity() : BigDecimal.ZERO; + if (shelvesQuantity.compareTo(quantity) != 0){ abnormal = 1; } LoginUser loginUser = SecurityUtils.getLoginUser(); @@ -366,8 +393,11 @@ public class StockShelfOrderDomainService { updateStockInOrder(stockShelfOrderPO, 5); //上架修改物料库存 List shelfMaterialDetailList = shelfMaterialDetailService.list(new QueryWrapper().lambda().eq(ShelfMaterialDetail::getShelfOrderNumber, stockShelfOrderPO.getShelfOrderNumber())); - //组装上架修改库存参数 - shelfAddMaterialInventory(shelfMaterialDetailList); + //修改库存 + StockShelfOrderDO stockShelfOrderDO = new StockShelfOrderDO(); + BeanUtils.copyProperties(stockShelfOrderPO, stockShelfOrderDO); + stockIn(shelfMaterialDetailList, stockShelfOrderDO); + //shelfAddMaterialInventory(shelfMaterialDetailList, stockShelfOrderPO); //修改上架对应的序列号的库存信息 updateSerialNumberforInventory(shelfMaterialDetailList); //生成上架追溯记录 @@ -381,6 +411,265 @@ public class StockShelfOrderDomainService { return true; } + private synchronized void stockIn(List shelfMaterialDetailDOList, StockShelfOrderDO stockReceiptOrderDO) { + for (ShelfMaterialDetail shelfMaterialDetail : shelfMaterialDetailDOList) { + Long materialBaseInfoId = shelfMaterialDetail.getMaterialBaseInfoId(); + MaterialGoodsRulePO materialGoodsRulePO = materialGoodsRuleService.getInfoByMaterialBaseInfoIds(materialBaseInfoId); + Long batchId = materialGoodsRulePO.getBatchId(); + List fieldNames = new ArrayList<>(); + AjaxResult batchInfo = systemServiceFeign.getBatchInfoByBatchId(batchId); + if("200".equals(String.valueOf(batchInfo.get("code")))){ + BatchPO batch = com.alibaba.fastjson2.JSONObject.parseObject(JSONObject.toJSONString(batchInfo.get("data")), BatchPO.class); + List batchDetailList = batch.getBatchDetailList(); + fieldNames = batchDetailList.stream() + .filter(detail -> "1".equals(String.valueOf(detail.getIsDisplay()))) + .map(BatchDetailPO::getFieldName) + .collect(Collectors.toList()); + } + if (fieldNames.size() == 0) { + throw new ServiceException("批次信息不存在"); + } + Long shipperId = stockReceiptOrderDO.getShipperId(); + MaterialInventory param = getParam(shelfMaterialDetail, fieldNames, shipperId); + List materialInventoryPOS = materialInventoryMapper.selectListByWhere(param); + MaterialBaseInfo materialBaseInfo = materialBaseInfoMapper.selectById(materialBaseInfoId); + LoginUser loginUser = SecurityUtils.getLoginUser(); + if (materialInventoryPOS.size() == 0) { + MaterialInventory materialInventory = new MaterialInventory(); + //仓库信息 + materialInventory.setWarehouseId(stockReceiptOrderDO.getWarehouseId()); + materialInventory.setWarehouseCode(stockReceiptOrderDO.getWarehouseCode()); + materialInventory.setWarehouseName(stockReceiptOrderDO.getWarehouseName()); + + //组织信息 + materialInventory.setOrganizationId(stockReceiptOrderDO.getOrganizationId()); + materialInventory.setTopOrganizationId(stockReceiptOrderDO.getTopOrganizationId()); + materialInventory.setOrganizationName(stockReceiptOrderDO.getOrganizationName()); + + //货主信息 + materialInventory.setShipperId(stockReceiptOrderDO.getShipperId()); + materialInventory.setShipperName(stockReceiptOrderDO.getShipperName()); + materialInventory.setShipperCode(stockReceiptOrderDO.getShipperCode()); + + //物料信息/库位库区 + materialInventory.setMaterialBaseInfoId(shelfMaterialDetail.getMaterialBaseInfoId()); + materialInventory.setStorageSectionId(shelfMaterialDetail.getStorageSectionId()); + materialInventory.setStorageCode(shelfMaterialDetail.getStorageCode()); + materialInventory.setStorageName(shelfMaterialDetail.getStorageName()); + materialInventory.setStorageLocationId(shelfMaterialDetail.getStorageLocationId()); + materialInventory.setStorageLocationCode(shelfMaterialDetail.getStorageLocationCode()); + materialInventory.setStorageLocationName(shelfMaterialDetail.getStorageLocationName()); + + //批次属性信息 + materialInventory.setExtAttr1(shelfMaterialDetail.getExtAttr1()); + materialInventory.setExtAttr2(shelfMaterialDetail.getExtAttr2()); + materialInventory.setExtAttr3(shelfMaterialDetail.getExtAttr3()); + materialInventory.setExtAttr4(shelfMaterialDetail.getExtAttr4()); + materialInventory.setInventoryDate(shelfMaterialDetail.getInventoryDate()); + materialInventory.setExpiryDate(shelfMaterialDetail.getExpiryDate()); + materialInventory.setProductionDate(shelfMaterialDetail.getProductionDate()); + materialInventory.setBoxPalletNo(shelfMaterialDetail.getBoxPalletNo()); + materialInventory.setSheetRefNo(shelfMaterialDetail.getSheetRefNo()); + materialInventory.setBatchRefNo(shelfMaterialDetail.getBatchRefNo()); + materialInventory.setBatchNumber(shelfMaterialDetail.getBatchNumber()); + + //库存数量信息 + materialInventory.setInventoryQuantity(shelfMaterialDetail.getShelvesQuantity()); + materialInventory.setAllocationQuantity(shelfMaterialDetail.getShelvesQuantity()); + materialInventory.setFreezeQuantity(BigDecimal.ZERO); + + //创建人信息 + materialInventory.setCreateBy(loginUser.getUserid()); + materialInventory.setCreateByName(loginUser.getUsername()); + materialInventory.setCreateTime(new Date()); + + //体积 重量等 + materialInventory.setVolume(shelfMaterialDetail.getTotalVolume()); + materialInventory.setArea(shelfMaterialDetail.getTotalArea()); + materialInventory.setGrossWeight(shelfMaterialDetail.getTotalGrossWeight()); + materialInventory.setNetWeight(shelfMaterialDetail.getTotalNetWeight()); + materialInventory.setUnit(materialBaseInfo.getUnitCode()); + materialInventory.setUnitName(materialBaseInfo.getUnitName()); + + materialInventoryMapper.insert(materialInventory); + + + //库存调整记录 + InventoryAdjustmentRecord inventoryAdjustmentRecord = new InventoryAdjustmentRecord(); + inventoryAdjustmentRecord.setAdjustAfterStatusCode("he_ge"); +// inventoryAdjustmentRecord.setAdjustBeforeStatusCode("he_ge"); + inventoryAdjustmentRecord.setAdjustAfterStatusName("合格"); +// inventoryAdjustmentRecord.setAdjustBeforeStatusName("合格"); + inventoryAdjustmentRecord.setAdjustType(1L); + inventoryAdjustmentRecord.setMaterialBaseInfoId(materialInventory.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setMaterialCode(shelfMaterialDetail.getMaterialCode()); + inventoryAdjustmentRecord.setMaterialName(shelfMaterialDetail.getMaterialName()); + inventoryAdjustmentRecord.setBarCode(shelfMaterialDetail.getBarCode()); + inventoryAdjustmentRecord.setMaterialBaseInfoId(shelfMaterialDetail.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setOrganizationId(stockReceiptOrderDO.getOrganizationId()); + inventoryAdjustmentRecord.setOrganizationName(stockReceiptOrderDO.getOrganizationName()); + inventoryAdjustmentRecord.setTopOrganizationId(stockReceiptOrderDO.getTopOrganizationId()); + inventoryAdjustmentRecord.setWarehouseCode(stockReceiptOrderDO.getWarehouseCode()); + inventoryAdjustmentRecord.setWarehouseName(stockReceiptOrderDO.getWarehouseName()); + inventoryAdjustmentRecord.setWarehouseId(stockReceiptOrderDO.getWarehouseId()); + inventoryAdjustmentRecord.setStorageCode(materialInventory.getStorageCode()); + inventoryAdjustmentRecord.setStorageName(materialInventory.getStorageName()); + inventoryAdjustmentRecord.setStorageLocationId(materialInventory.getStorageLocationId()); + inventoryAdjustmentRecord.setStorageLocationCode(materialInventory.getStorageLocationCode()); + inventoryAdjustmentRecord.setStorageLocationName(materialInventory.getStorageLocationName()); + inventoryAdjustmentRecord.setMaterialInventoryId(materialInventory.getMaterialInventoryId()); + inventoryAdjustmentRecord.setMaterialBaseInfoId(materialInventory.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setShipperId(stockReceiptOrderDO.getShipperId()); + inventoryAdjustmentRecord.setShipperName(stockReceiptOrderDO.getShipperName()); + inventoryAdjustmentRecord.setStorageSectionId(materialInventory.getStorageSectionId()); + inventoryAdjustmentRecord.setStorageLocationId(materialInventory.getStorageLocationId()); + inventoryAdjustmentRecord.setCreateBy(loginUser.getUserid()); + inventoryAdjustmentRecord.setCreateByName(loginUser.getUsername()); + inventoryAdjustmentRecord.setCreateTime(new Date()); + inventoryAdjustmentRecord.setAllocationAfterQuantity(materialInventory.getAllocationQuantity()); + inventoryAdjustmentRecord.setAllocationBeforeQuantity(BigDecimal.ZERO); + inventoryAdjustmentRecord.setFreezeBeforeQuantity(BigDecimal.ZERO); + inventoryAdjustmentRecord.setFreezeAfterQuantity(BigDecimal.ZERO); + inventoryAdjustmentRecord.setInventoryBeforeQuantity(BigDecimal.ZERO); + inventoryAdjustmentRecord.setInventoryAfterQuantity(materialInventory.getInventoryQuantity()); + inventoryAdjustmentRecord.setCreateBy(loginUser.getUserid()); + inventoryAdjustmentRecord.setCreateByName(loginUser.getUsername()); + inventoryAdjustmentRecord.setCreateTime(new Date()); + inventoryAdjustmentRecordMapper.insert(inventoryAdjustmentRecord); + } else if (materialInventoryPOS.size() == 1) { + MaterialInventory materialInventory = new MaterialInventory(); + 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); + BigDecimal oldAllocationQuantity = materialInventoryPO.getAllocationQuantity(); + + BigDecimal oldArea = materialInventoryPO.getArea(); + oldArea = oldArea != null ? oldArea : BigDecimal.ZERO; + BigDecimal totalArea = shelfMaterialDetail.getTotalArea(); + totalArea = totalArea != null ? totalArea : BigDecimal.ZERO; + BigDecimal newArea = oldArea.add(totalArea); + BigDecimal oldVolume = materialInventoryPO.getVolume(); + oldVolume = oldVolume != null ? oldVolume : BigDecimal.ZERO; + BigDecimal totalVolume = shelfMaterialDetail.getTotalVolume(); + totalVolume = totalVolume != null ? totalVolume : BigDecimal.ZERO; + BigDecimal newVolume = oldVolume.add(totalVolume); + BigDecimal oldGrossWeight = materialInventoryPO.getGrossWeight(); + oldGrossWeight = oldGrossWeight != null ? oldGrossWeight : BigDecimal.ZERO; + BigDecimal totalGrossWeight = shelfMaterialDetail.getTotalGrossWeight(); + totalGrossWeight = totalGrossWeight != null ? totalGrossWeight : BigDecimal.ZERO; + BigDecimal newGrossWeight = oldGrossWeight.add(totalGrossWeight); + BigDecimal oldNetWeight = materialInventoryPO.getNetWeight(); + oldNetWeight = oldNetWeight != null ? oldNetWeight : BigDecimal.ZERO; + BigDecimal totalNetWeight = shelfMaterialDetail.getTotalNetWeight(); + totalNetWeight = totalNetWeight != null ? totalNetWeight : BigDecimal.ZERO; + BigDecimal newNetWeight = oldNetWeight.add(totalNetWeight); + + materialInventoryPO.setInventoryQuantity(newInventoryQuantity); + materialInventoryPO.setAllocationQuantity(newAllocationQuantity); + materialInventoryPO.setArea(newArea); + materialInventoryPO.setVolume(newVolume); + materialInventoryPO.setGrossWeight(newGrossWeight); + materialInventoryPO.setNetWeight(newNetWeight); + BeanUtils.copyProperties(materialInventoryPO, materialInventory); + materialInventory.setUpdateBy(loginUser.getUserid()); + materialInventory.setUpdateByName(loginUser.getUsername()); + materialInventory.setUpdateTime(new Date()); + materialInventoryMapper.updateById(materialInventory); + + + InventoryAdjustmentRecord inventoryAdjustmentRecord = new InventoryAdjustmentRecord(); + inventoryAdjustmentRecord.setAdjustAfterStatusCode("he_ge"); + inventoryAdjustmentRecord.setAdjustBeforeStatusCode("he_ge"); + inventoryAdjustmentRecord.setAdjustAfterStatusName("合格"); + inventoryAdjustmentRecord.setAdjustBeforeStatusName("合格"); + inventoryAdjustmentRecord.setAdjustType(1L); + inventoryAdjustmentRecord.setMaterialBaseInfoId(materialInventory.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setMaterialCode(shelfMaterialDetail.getMaterialCode()); + inventoryAdjustmentRecord.setMaterialName(shelfMaterialDetail.getMaterialName()); + inventoryAdjustmentRecord.setBarCode(shelfMaterialDetail.getBarCode()); + inventoryAdjustmentRecord.setMaterialBaseInfoId(shelfMaterialDetail.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setOrganizationId(stockReceiptOrderDO.getOrganizationId()); + inventoryAdjustmentRecord.setOrganizationName(stockReceiptOrderDO.getOrganizationName()); + inventoryAdjustmentRecord.setTopOrganizationId(stockReceiptOrderDO.getTopOrganizationId()); + inventoryAdjustmentRecord.setWarehouseCode(stockReceiptOrderDO.getWarehouseCode()); + inventoryAdjustmentRecord.setWarehouseName(stockReceiptOrderDO.getWarehouseName()); + inventoryAdjustmentRecord.setWarehouseId(stockReceiptOrderDO.getWarehouseId()); + inventoryAdjustmentRecord.setStorageCode(materialInventory.getStorageCode()); + inventoryAdjustmentRecord.setStorageName(materialInventory.getStorageName()); + inventoryAdjustmentRecord.setStorageLocationId(materialInventory.getStorageLocationId()); + inventoryAdjustmentRecord.setStorageLocationCode(materialInventory.getStorageLocationCode()); + inventoryAdjustmentRecord.setStorageLocationName(materialInventory.getStorageLocationName()); + inventoryAdjustmentRecord.setMaterialInventoryId(materialInventory.getMaterialInventoryId()); + inventoryAdjustmentRecord.setMaterialBaseInfoId(materialInventory.getMaterialBaseInfoId()); + inventoryAdjustmentRecord.setShipperId(stockReceiptOrderDO.getShipperId()); + inventoryAdjustmentRecord.setShipperName(stockReceiptOrderDO.getShipperName()); + inventoryAdjustmentRecord.setStorageSectionId(materialInventory.getStorageSectionId()); + inventoryAdjustmentRecord.setStorageLocationId(materialInventory.getStorageLocationId()); + inventoryAdjustmentRecord.setCreateBy(loginUser.getUserid()); + inventoryAdjustmentRecord.setCreateByName(loginUser.getUsername()); + inventoryAdjustmentRecord.setCreateTime(new Date()); + inventoryAdjustmentRecord.setAllocationAfterQuantity(newAllocationQuantity); + inventoryAdjustmentRecord.setAllocationBeforeQuantity(oldAllocationQuantity); + inventoryAdjustmentRecord.setFreezeBeforeQuantity(materialInventory.getFreezeQuantity()); + inventoryAdjustmentRecord.setFreezeAfterQuantity(materialInventory.getFreezeQuantity()); + inventoryAdjustmentRecord.setInventoryBeforeQuantity(oldInventoryQuantity); + inventoryAdjustmentRecord.setInventoryAfterQuantity(newInventoryQuantity); + inventoryAdjustmentRecord.setCreateBy(loginUser.getUserid()); + inventoryAdjustmentRecord.setCreateByName(loginUser.getUsername()); + inventoryAdjustmentRecord.setCreateTime(new Date()); + inventoryAdjustmentRecordMapper.insert(inventoryAdjustmentRecord); + } + } + } + + private MaterialInventory getParam(ShelfMaterialDetail shelfMaterialDetail, List fieldNames,Long shipperId){ + MaterialInventory param = new MaterialInventory(); + param.setShipperId(shipperId); + param.setWarehouseId(shelfMaterialDetail.getWarehouseId()); + param.setMaterialBaseInfoId(shelfMaterialDetail.getMaterialBaseInfoId()); + param.setStorageSectionId(shelfMaterialDetail.getStorageSectionId()); + param.setStorageLocationId(shelfMaterialDetail.getStorageLocationId()); + param.setOrganizationId(shelfMaterialDetail.getOrganizationId()); + for (String fieldName : fieldNames) { + switch (fieldName) { + case "ext_attr_4": + param.setExtAttr4(shelfMaterialDetail.getExtAttr4()); + break; + case "ext_attr_3": + param.setExtAttr3(shelfMaterialDetail.getExtAttr3()); + break; + case "ext_attr_2": + param.setExtAttr2(shelfMaterialDetail.getExtAttr2()); + break; + case "ext_attr_1": + param.setExtAttr1(shelfMaterialDetail.getExtAttr1()); + break; + case "box_pallet_no": + param.setBoxPalletNo(shelfMaterialDetail.getBoxPalletNo()); + break; + case "sheet_ref_no": + param.setSheetRefNo(shelfMaterialDetail.getSheetRefNo()); + break; + case "batch_ref_no": + param.setBatchRefNo(shelfMaterialDetail.getBatchRefNo()); + break; + case "inventory_date": + param.setInventoryDate(shelfMaterialDetail.getInventoryDate()); + break; + case "expiry_date": + param.setExpiryDate(shelfMaterialDetail.getExpiryDate()); + break; + case "production_date": + param.setProductionDate(shelfMaterialDetail.getProductionDate()); + break; + } + } + return param; + } + /** * @description 生成异常记录 * @author ZhouGY @@ -402,23 +691,116 @@ public class StockShelfOrderDomainService { * @author ZhouGY * @date 2024/6/19 10:07 * @param shelfMaterialDetailList + * @param stockShelfOrderPO 上架单信息,用于获取货主信息 * @return Boolean */ - public void shelfAddMaterialInventory(List shelfMaterialDetailList){ + public void shelfAddMaterialInventory(List shelfMaterialDetailList, StockShelfOrderPO stockShelfOrderPO){ + // 根据入库单号获取入库单信息,以获取货主信息 + Long shipperId = null; + String shipperCode = null; + String shipperName = null; + + if (stockShelfOrderPO != null && StringUtils.isNotBlank(stockShelfOrderPO.getInOrderNumber())) { + try { + // 根据入库单号查询入库单 + com.mhd.wms.domain.stockInOrder.repository.todo.StockInOrderDO stockInOrderDO = new com.mhd.wms.domain.stockInOrder.repository.todo.StockInOrderDO(); + stockInOrderDO.setInOrderNumber(stockShelfOrderPO.getInOrderNumber()); + List stockInOrderList = stockInOrderService.queryList(stockInOrderDO); + if (!CollectionUtils.isEmpty(stockInOrderList)) { + com.mhd.wms.domain.stockInOrder.repository.po.StockInOrderPO stockInOrderPO = stockInOrderList.get(0); + shipperId = stockInOrderPO.getShipperId(); + shipperCode = stockInOrderPO.getShipperCode(); + shipperName = stockInOrderPO.getShipperName(); + } + } catch (Exception e) { + log.warn("根据入库单号获取货主信息失败,入库单号:{},错误:{}", stockShelfOrderPO.getInOrderNumber(), e.getMessage()); + } + } + + // 如果从入库单获取不到货主信息,尝试从物料基础信息获取 + if (shipperId == null && !CollectionUtils.isEmpty(shelfMaterialDetailList)) { + ShelfMaterialDetail firstDetail = shelfMaterialDetailList.get(0); + if (firstDetail.getMaterialBaseInfoId() != null) { + try { + com.mhd.wms.domain.materialBaseInfo.repository.todo.MaterialBaseInfoDO materialBaseInfoDO = new com.mhd.wms.domain.materialBaseInfo.repository.todo.MaterialBaseInfoDO(); + materialBaseInfoDO.setMaterialBaseInfoId(firstDetail.getMaterialBaseInfoId()); + List materialBaseInfoList = materialBaseInfoService.queryList(materialBaseInfoDO); + if (!CollectionUtils.isEmpty(materialBaseInfoList)) { + com.mhd.wms.domain.materialBaseInfo.repository.po.MaterialBaseInfoPO materialBaseInfoPO = materialBaseInfoList.get(0); + shipperId = materialBaseInfoPO.getShipperId(); + shipperCode = materialBaseInfoPO.getShipperCode(); + shipperName = materialBaseInfoPO.getShipperName(); + } + } catch (Exception e) { + log.warn("根据物料基础信息获取货主信息失败,物料基础信息ID:{},错误:{}", firstDetail.getMaterialBaseInfoId(), e.getMessage()); + } + } + } + + if (shipperId == null) { + log.warn("上架时无法获取货主信息,上架单号:{},入库单号:{},将跳过货主信息设置", + stockShelfOrderPO != null ? stockShelfOrderPO.getShelfOrderNumber() : null, + stockShelfOrderPO != null ? stockShelfOrderPO.getInOrderNumber() : null); + } + List materialInventoryDOList = new ArrayList<>(); for (ShelfMaterialDetail shelfMaterialDetail : shelfMaterialDetailList){ + // 注意:库存是在「完成上架」时一次性写入的, + // 此时部分明细可能已经多次上架,字段含义通常为: + // - alreadyShelvesQuantity:累计已上架数量 + // - shelvesQuantity:本次上架数量(本次操作结束后,大多数明细会被置为0) + // + // 之前的逻辑优先使用 shelvesQuantity,当其为 0 且 alreadyShelvesQuantity > 0 时, + // 会导致该明细在完成上架时不更新库存,只更新了最后一次上架涉及的那条明细。 + // + // 修复方式:优先使用累计已上架数量 alreadyShelvesQuantity, + // 若没有累计数量,再回退到本次上架数量 shelvesQuantity。 + BigDecimal shelvesQuantity = shelfMaterialDetail.getAlreadyShelvesQuantity() != null + ? shelfMaterialDetail.getAlreadyShelvesQuantity() + : (shelfMaterialDetail.getShelvesQuantity() != null + ? shelfMaterialDetail.getShelvesQuantity() + : BigDecimal.ZERO); + + // 如果数量为0或空,跳过该记录 + if (shelvesQuantity.compareTo(BigDecimal.ZERO) <= 0) { + continue; + } + MaterialInventoryDO materialInventoryDO = new MaterialInventoryDO(); BeanUtils.copyProperties(shelfMaterialDetail, materialInventoryDO); - materialInventoryDO.setInventoryQuantity(shelfMaterialDetail.getShelvesQuantity()); - materialInventoryDO.setAllocationQuantity(shelfMaterialDetail.getShelvesQuantity()); + materialInventoryDO.setInventoryQuantity(shelvesQuantity); + materialInventoryDO.setAllocationQuantity(shelvesQuantity); + + // 设置货主信息(从入库单或物料基础信息获取) + if (shipperId != null) { + materialInventoryDO.setShipperId(shipperId); + if (StringUtils.isNotBlank(shipperCode)) { + materialInventoryDO.setShipperCode(shipperCode); + } + if (StringUtils.isNotBlank(shipperName)) { + materialInventoryDO.setShipperName(shipperName); + } + } + materialInventoryDOList.add(materialInventoryDO); } - materialInventoryService.updateMaterialInventoryInfo(materialInventoryDOList, 1); + if (!CollectionUtils.isEmpty(materialInventoryDOList)) { + materialInventoryService.updateMaterialInventoryInfo(materialInventoryDOList, 1); + } } public void updateSerialNumberforInventory(List shelfMaterialDetailList){ for (ShelfMaterialDetail shelfMaterialDetail : shelfMaterialDetailList){ + if (shelfMaterialDetail.getMaterialDetailId() == null) { + continue; + } MaterialInventory one = materialInventoryService.getOne(new QueryWrapper().lambda().eq(MaterialInventory::getMaterialDetailId, shelfMaterialDetail.getMaterialDetailId())); + if (one == null) { + continue; + } + if (one.getMaterialInventoryId() == null) { + continue; + } iSerialNumberService.update(new UpdateWrapper().lambda().eq(SerialNumber::getMaterialDetailId, one.getMaterialDetailId()).set(SerialNumber::getMaterialInventoryId, one.getMaterialInventoryId())); } } @@ -653,4 +1035,4 @@ public class StockShelfOrderDomainService { } } } -} +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/statementStatistics/ImmediateInventoryAssembler.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/statementStatistics/ImmediateInventoryAssembler.java index 635c9fa3f..2108374f5 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/statementStatistics/ImmediateInventoryAssembler.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/statementStatistics/ImmediateInventoryAssembler.java @@ -31,6 +31,10 @@ public class ImmediateInventoryAssembler { if (ObjectUtil.isNull(loginUser)) { throw new DigitalLogisticsException(UserError.TIMEOUT); } + immediateInventoryDO.setAllocationQuantityStart(immediateInventoryDTO.getAllocationQuantityBegin()); + immediateInventoryDO.setFreezeQuantityStart(immediateInventoryDTO.getFreezeQuantityBegin()); + immediateInventoryDO.setPickQuantityStart(immediateInventoryDTO.getPickQuantityBegin()); + immediateInventoryDO.setReceivedQuantityStart(immediateInventoryDTO.getReceivedQuantityBegin()); return immediateInventoryDO; } @@ -48,4 +52,4 @@ public class ImmediateInventoryAssembler { return immediateInventoryDO; } -} +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockInOrder/StockInOrderAssembler.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockInOrder/StockInOrderAssembler.java index b0b23d62c..2c741d1cf 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockInOrder/StockInOrderAssembler.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockInOrder/StockInOrderAssembler.java @@ -11,7 +11,9 @@ import com.mhd.system.api.model.LoginUser; import com.mhd.wms.domain.stockInOrder.repository.todo.StockInOrderDO; import com.mhd.wms.interfaces.dto.stockInOrder.StockInOrderDTO; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import java.math.BigDecimal; import java.util.Date; /** @@ -30,6 +32,9 @@ public class StockInOrderAssembler { StockInOrderDO stockInOrderDO = new StockInOrderDO(); // 拷贝 BeanUtils.copyProperties(stockInOrderDTO, stockInOrderDO, IgnoreNullUtil.getNullPropertyNames(stockInOrderDTO)); + // 确保查询条件字段被正确传递(查询条件字段需要明确传递,避免被IgnoreNullUtil忽略) + stockInOrderDO.setCreateTimeStart(stockInOrderDTO.getCreateTimeStart()); + stockInOrderDO.setCreateTimeEnd(stockInOrderDTO.getCreateTimeEnd()); return stockInOrderDO; } @@ -37,6 +42,15 @@ public class StockInOrderAssembler { * 转换实体 */ public StockInOrderDO toDOByEdit(StockInOrderDTO stockInOrderDTO) { + // 兼容前端传 userName 作为货主名称字段的情况: + // 如果 shipperName 为空但 userName 有值,则优先回填到 shipperName, + // 以保证后续 shipperParam 能根据名称正确找到货主ID。 + if (ObjectUtil.isNull(stockInOrderDTO.getShipperId()) + && (stockInOrderDTO.getShipperName() == null || stockInOrderDTO.getShipperName().trim().length() == 0) + && stockInOrderDTO.getUserName() != null && stockInOrderDTO.getUserName().trim().length() > 0) { + stockInOrderDTO.setShipperName(stockInOrderDTO.getUserName().trim()); + } + StockInOrderDO stockInOrderDO = JSONUtil.toBean(JSONUtil.toJsonStr(stockInOrderDTO), StockInOrderDO.class); LoginUser loginUser = SecurityUtils.getLoginUser(); if (ObjectUtil.isNull(loginUser)) { @@ -57,6 +71,22 @@ public class StockInOrderAssembler { stockInOrderDO.setCreateByName(userName); stockInOrderDO.setCreateTime(new Date()); stockInOrderDO.setDelFlag(1); + // 新增入库单时,如果入库单类型为空,默认设置为普通入库 + String orderTypeCode = stockInOrderDO.getOrderTypeCode(); + if (orderTypeCode == null || orderTypeCode.trim().length() == 0) { + stockInOrderDO.setOrderTypeCode("pu_tong_ru_ku"); + } + String orderTypeName = stockInOrderDO.getOrderTypeName(); + if (orderTypeName == null || orderTypeName.trim().length() == 0) { + stockInOrderDO.setOrderTypeName("普通入库单"); + } + // 新增入库单时,计划数量取所有明细行的入库数量之和 + if (!CollectionUtils.isEmpty(stockInOrderDO.getMaterialDetailList())) { + BigDecimal totalInboundQuantity = stockInOrderDO.getMaterialDetailList().stream() + .map(detail -> detail.getInboundQuantity() != null ? detail.getInboundQuantity() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + stockInOrderDO.setQuantity(totalInboundQuantity); + } } return stockInOrderDO; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockOutOrder/StockOutOrderAssembler.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockOutOrder/StockOutOrderAssembler.java index 9e3da5558..d7eee2642 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockOutOrder/StockOutOrderAssembler.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockOutOrder/StockOutOrderAssembler.java @@ -30,6 +30,11 @@ public class StockOutOrderAssembler { StockOutOrderDO stockOutOrderDO = new StockOutOrderDO(); // 拷贝 BeanUtils.copyProperties(stockOutOrderDTO, stockOutOrderDO, IgnoreNullUtil.getNullPropertyNames(stockOutOrderDTO)); + // 确保查询条件字段被正确传递(查询条件字段需要明确传递,避免被IgnoreNullUtil忽略) + stockOutOrderDO.setCreateTimeStart(stockOutOrderDTO.getCreateTimeStart()); + stockOutOrderDO.setCreateTimeEnd(stockOutOrderDTO.getCreateTimeEnd()); + stockOutOrderDO.setAuditTimeStart(stockOutOrderDTO.getAuditTimeStart()); + stockOutOrderDO.setAuditTimeEnd(stockOutOrderDTO.getAuditTimeEnd()); return stockOutOrderDO; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockOutTaskOrder/StockOutTaskOrderAssembler.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockOutTaskOrder/StockOutTaskOrderAssembler.java index c69cb9121..12c8abe44 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockOutTaskOrder/StockOutTaskOrderAssembler.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockOutTaskOrder/StockOutTaskOrderAssembler.java @@ -32,6 +32,12 @@ public class StockOutTaskOrderAssembler { StockOutTaskOrderDO stockOutTaskOrderDO = new StockOutTaskOrderDO(); // 拷贝 BeanUtils.copyProperties(stockOutTaskOrderDTO, stockOutTaskOrderDO, IgnoreNullUtil.getNullPropertyNames(stockOutTaskOrderDTO)); + // 确保查询条件字段被正确传递(查询条件字段需要明确传递,避免被IgnoreNullUtil忽略) + stockOutTaskOrderDO.setStorageLocationList(stockOutTaskOrderDTO.getStorageLocationList()); + stockOutTaskOrderDO.setCreateTimeStart(stockOutTaskOrderDTO.getCreateTimeStart()); + stockOutTaskOrderDO.setCreateTimeEnd(stockOutTaskOrderDTO.getCreateTimeEnd()); + stockOutTaskOrderDO.setOperatorsEndTimeStart(stockOutTaskOrderDTO.getOperatorsEndTimeStart()); + stockOutTaskOrderDO.setOperatorsEndTimeEnd(stockOutTaskOrderDTO.getOperatorsEndTimeEnd()); return stockOutTaskOrderDO; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockReceiptOrder/StockReceiptOrderAssembler.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockReceiptOrder/StockReceiptOrderAssembler.java index f6bff9c04..c97f85378 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockReceiptOrder/StockReceiptOrderAssembler.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockReceiptOrder/StockReceiptOrderAssembler.java @@ -23,6 +23,9 @@ public class StockReceiptOrderAssembler { StockReceiptOrderDO stockReceiptOrderDO = new StockReceiptOrderDO(); // 拷贝 BeanUtils.copyProperties(stockReceiptOrderDTO, stockReceiptOrderDO, IgnoreNullUtil.getNullPropertyNames(stockReceiptOrderDTO)); + // 确保查询条件字段被正确传递(查询条件字段需要明确传递,避免被IgnoreNullUtil忽略) + stockReceiptOrderDO.setCreateTimeStart(stockReceiptOrderDTO.getCreateTimeStart()); + stockReceiptOrderDO.setCreateTimeEnd(stockReceiptOrderDTO.getCreateTimeEnd()); return stockReceiptOrderDO; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockShelfOrder/StockShelfOrderAssembler.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockShelfOrder/StockShelfOrderAssembler.java index a91efa3e3..d20f62484 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockShelfOrder/StockShelfOrderAssembler.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/assember/stockShelfOrder/StockShelfOrderAssembler.java @@ -23,6 +23,9 @@ public class StockShelfOrderAssembler { StockShelfOrderDO stockShelfOrderDO = JSONUtil.toBean(JSONUtil.toJsonStr(stockShelfOrderDTO), StockShelfOrderDO.class); // 拷贝 BeanUtils.copyProperties(stockShelfOrderDTO, stockShelfOrderDO, IgnoreNullUtil.getNullPropertyNames(stockShelfOrderDTO)); + // 确保查询条件字段被正确传递(查询条件字段需要明确传递,避免被IgnoreNullUtil忽略) + stockShelfOrderDO.setCreateTimeStart(stockShelfOrderDTO.getCreateTimeStart()); + stockShelfOrderDO.setCreateTimeEnd(stockShelfOrderDTO.getCreateTimeEnd()); return stockShelfOrderDO; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/handoverTaskOrder/HandoverTaskOrderDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/handoverTaskOrder/HandoverTaskOrderDTO.java index 0306317da..0a9f4c95b 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/handoverTaskOrder/HandoverTaskOrderDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/handoverTaskOrder/HandoverTaskOrderDTO.java @@ -131,4 +131,15 @@ public class HandoverTaskOrderDTO extends BaseVOEntity { @ApiModelProperty("交接作业单id") private List handoverTaskOrderIds; + + @ApiModelProperty("作业人用户ID") + @Excel(name = "作业人用户ID") + private Long operatorsBy; + + @ApiModelProperty("作业人姓名") + @Excel(name = "作业人姓名") + private String operatorsName; + + @ApiModelProperty("app上传的图片") + private String pictureApp; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/inMaterialDetail/InMaterialDetailDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/inMaterialDetail/InMaterialDetailDTO.java index 8a9198aed..48f5bfd56 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/inMaterialDetail/InMaterialDetailDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/inMaterialDetail/InMaterialDetailDTO.java @@ -263,4 +263,93 @@ public class InMaterialDetailDTO extends BaseVOEntity { @ApiModelProperty("是否是差异单") private Integer isDifferentType; + // ========== 报关相关明细字段 ========== + @ApiModelProperty("规格型号(选择物料后自动带出,不可编辑)") + @Excel(name = "规格型号/ITEM") + private String specificationModel; + + @ApiModelProperty("SKU码(选择物料后自动带出,不可编辑)") + @Excel(name = "SKU码") + private String skuCode; + + @ApiModelProperty("Invoice No.") + @Excel(name = "Invoice No.") + private String invoiceNo; + + @ApiModelProperty("升(输入大于等于0的数字,可以为小数)") + @Excel(name = "升") + private BigDecimal liter; + + @ApiModelProperty("尺寸") + @Excel(name = "尺寸") + private String dimensions; + + @ApiModelProperty("申报单位") + @Excel(name = "申报单位") + private String declarationUnit; + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("原产国") + @Excel(name = "原产国") + private String originCountry; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("币制") + @Excel(name = "币制") + private String currency; + + @ApiModelProperty("单位(数据字典下拉选择框)") + @Excel(name = "单位") + private String unit; + + @ApiModelProperty("申报数量(输入大于等于0的数字,可以为小数)") + @Excel(name = "申报数量") + private BigDecimal declaredQuantity; + + @ApiModelProperty("箱数(输入大于等于0的数字,可以为小数)") + @Excel(name = "箱数") + private BigDecimal boxCount; + + @ApiModelProperty("件数(输入大于等于0的数字,可以为小数)") + @Excel(name = "件数") + private BigDecimal pieceCount; + + @ApiModelProperty("入库数量(输入大于等于0的数字,可以为小数)") + @Excel(name = "入库数量") + private BigDecimal inboundQuantity; + + @ApiModelProperty("出库数量(输入大于等于0的数字,可以为小数)") + @Excel(name = "出库数量") + private BigDecimal outboundQuantity; + + @ApiModelProperty("总净重(KG)(输入大于等于0的数字,可以为小数)") + @Excel(name = "总净重(KG)") + private BigDecimal totalNetWeight; + + @ApiModelProperty("总毛重(KG)(输入大于等于0的数字,可以为小数)") + @Excel(name = "总毛重(KG)") + private BigDecimal totalGrossWeight; + + @ApiModelProperty("总体积(CBM)(输入大于等于0的数字,可以为小数)") + @Excel(name = "总体积(CBM)") + private BigDecimal totalVolume; + + @ApiModelProperty("总面积(SQM)(输入大于等于0的数字,可以为小数)") + @Excel(name = "总面积(SQM)") + private BigDecimal totalArea; + + @ApiModelProperty("总价(输入大于等于0的数字,可以为小数)") + @Excel(name = "总价") + private BigDecimal totalPrice; + } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/materialBaseInfo/MaterialBaseInfoDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/materialBaseInfo/MaterialBaseInfoDTO.java index 0f40a6c79..ede7dbf6c 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/materialBaseInfo/MaterialBaseInfoDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/materialBaseInfo/MaterialBaseInfoDTO.java @@ -190,4 +190,31 @@ public class MaterialBaseInfoDTO extends BaseVOEntity { @ApiModelProperty("是否公用: 1-是 2-否") @Excel(name = "是否公用: 1-是 2-否") private Integer common; + + @ApiModelProperty("SKU码") + private String skuCode; + + @ApiModelProperty("单价") + private BigDecimal unitPrice; + + @ApiModelProperty("币制") + private String currency; + + @ApiModelProperty("原产国") + private String originCountry; + + @ApiModelProperty("HS码") + private String hsCode; + + @ApiModelProperty("申报单位") + private String declarationUnit; + + @ApiModelProperty("法定单位") + private String statutoryUnit; + + @ApiModelProperty("法定第二单位") + private String statutorySecondUnit; + + @ApiModelProperty("规格型号") + private String specificationModel; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/materialInventory/MaterialInventoryDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/materialInventory/MaterialInventoryDTO.java index 3eaff01ac..3505e386a 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/materialInventory/MaterialInventoryDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/materialInventory/MaterialInventoryDTO.java @@ -144,4 +144,21 @@ public class MaterialInventoryDTO extends MaterialBaseDTO { @ApiModelProperty("物料/库位信息") @Excel(name = "物料/库位信息") private String storageInfo; -} + + @ApiModelProperty("货主id") + private Long shipperId; + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + //查询规则 hz:货主,wl:物料,kw:库位,wlkw:物料库位,all:全部 + private String queryRule; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/materialInventory/MaterialInventoryQueryListDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/materialInventory/MaterialInventoryQueryListDTO.java index e91222bed..a1c0a8fa0 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/materialInventory/MaterialInventoryQueryListDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/materialInventory/MaterialInventoryQueryListDTO.java @@ -168,4 +168,16 @@ public class MaterialInventoryQueryListDTO extends MaterialBaseDTO { @ApiModelProperty("物料/库位信息") @Excel(name = "物料/库位信息") private String storageInfo; + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/outMaterialDetail/OutMaterialDetailDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/outMaterialDetail/OutMaterialDetailDTO.java index ef8e166e0..448d3d71a 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/outMaterialDetail/OutMaterialDetailDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/outMaterialDetail/OutMaterialDetailDTO.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.mhd.common.core.annotation.Excel; import com.mhd.common.core.web.domain.BaseVOEntity; +import com.mhd.wms.domain.outMaterialDetail.repository.todo.OutMaterialDetailDO; import com.mhd.wms.interfaces.dto.outMaterialDetailSerialNumber.OutMaterialDetailSerialNumberDTO; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -83,8 +84,8 @@ public class OutMaterialDetailDTO extends BaseVOEntity { @Excel(name = "复核数量") private BigDecimal checkQuantity; - @ApiModelProperty("作业数量(例如:分配数量 拣货数量 复核数量)") - @Excel(name = "作业数量(例如:分配数量 拣货数量 复核数量)") + @ApiModelProperty("作业数量(例如:分配数量 拣货数量 复核数量 取消数量)") + @Excel(name = "作业数量(例如:分配数量 拣货数量 复核数量 取消数量)") private BigDecimal actualQuantity; @ApiModelProperty("净重 单位:千克") @@ -147,6 +148,9 @@ public class OutMaterialDetailDTO extends BaseVOEntity { @Excel(name = "物料状态名称") private String materialStatusName; + @ApiModelProperty("物料明细子集") + private List children; + @ApiModelProperty("容器id") @Excel(name = "容器id") private Long containerId; @@ -163,6 +167,9 @@ public class OutMaterialDetailDTO extends BaseVOEntity { @Excel(name = "容器类型名称 数据字典") private String containerTypeName; + @ApiModelProperty("库存数量(仅展示)") + private BigDecimal inventoryQuantity; + @ApiModelProperty("分配仓库id") private Long warehouseId; @@ -236,4 +243,183 @@ public class OutMaterialDetailDTO extends BaseVOEntity { @ApiModelProperty("取消分配数量") @Excel(name = "取消分配数量") private BigDecimal cancelAllocationQuantity; -} + + + /** + * 商品名称 + */ + @ApiModelProperty("商品名称") + @Excel(name = "商品名称") + private String commodityName; + /** + * 商品编码 + */ + @ApiModelProperty("商品编码") + @Excel(name = "商品编码") + private String commodityNo; + /** + * 料号 + */ + @ApiModelProperty("料号") + @Excel(name = "料号") + private String materialNo; + /** + * 规格型号 + */ + @ApiModelProperty("规格型号") + @Excel(name = "规格型号") + private String specificationModel; + /** + * 商品SKU码 + */ + @ApiModelProperty("商品SKU码") + @Excel(name = "商品SKU码") + private String skucode; + /** + * Invoice No + */ + @ApiModelProperty("Invoice No") + @Excel(name = "Invoice No") + private String invoiceNo; + /** + * 升 + */ + @ApiModelProperty("升") + @Excel(name = "升") + private String liter; + + /** + * 尺寸 + */ + @ApiModelProperty("尺寸") + @Excel(name = "尺寸") + private String size; + + /** + * 申报单位 + */ + @ApiModelProperty("申报单位") + @Excel(name = "申报单位") + private String declareUnit; + + /** + * Batch Ref NO’s + */ + @ApiModelProperty("Batch Ref NO’s") + @Excel(name = "Batch Ref NO’s") + private String batchRefNo; + + /** + * Sheet Ref NO’s + */ + @ApiModelProperty("Sheet Ref NO’s") + @Excel(name = "Sheet Ref NO’s") + private String sheetRefNo; + + /** + * 原产国 + */ + @ApiModelProperty("原产国") + @Excel(name = "原产国") + private String countryOfOrigin; + + /** + * 箱号/卡板号 + */ + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + /** + * 币制 + */ + @ApiModelProperty("币制") + @Excel(name = "币制") + private String currency; + + /** + * 申报数量 + */ + @ApiModelProperty("申报数量") + @Excel(name = "申报数量") + private BigDecimal declareQuantity; + + /** + * 箱数 + */ + @ApiModelProperty("箱数") + @Excel(name = "箱数") + private BigDecimal caseCount; + + /** + * 件数 + */ + @ApiModelProperty("件数") + @Excel(name = "件数") + private BigDecimal pieceCount; + + /** + * 出库数量 + */ + @ApiModelProperty("出库数量") + @Excel(name = "出库数量") + private BigDecimal outboundQuantity; + + /** + * 总净重(KG) + */ + @ApiModelProperty("总净重(KG)") + @Excel(name = "总净重(KG)") + private BigDecimal totalNetWeight; + + /** + * 总毛重(KG) + */ + @ApiModelProperty("总毛重(KG)") + @Excel(name = "总毛重(KG)") + private BigDecimal totalGrossWeight; + + /** + * 总体积(CBM) + */ + @ApiModelProperty("总体积(CBM)") + @Excel(name = "总体积(CBM)") + private BigDecimal totalVolume; + + /** + * 总面积(SQM) + */ + @ApiModelProperty("总面积(SQM)") + @Excel(name = "总面积(SQM)") + private BigDecimal totalArea; + /** + * 总价 + */ + @ApiModelProperty("总价") + @Excel(name = "总价") + private BigDecimal totalAmount; + + /** + * 单位 + */ + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unit; + + + @ApiModelProperty("复核总净重(KG)") + @Excel(name = "复核总净重(KG)") + private BigDecimal checkNetWeight; + + @ApiModelProperty("复核总毛重(KG)") + @Excel(name = "复核总毛重(KG)") + private BigDecimal checkGrossWeight; + + @ApiModelProperty("复核总体积(CBM)") + @Excel(name = "复核总体积(CBM)") + private BigDecimal checkVolume; + + @ApiModelProperty("复核总面积(SQM)") + @Excel(name = "复核总面积(SQM)") + private BigDecimal checkArea; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/pickingMaterialDetail/PickingMaterialDetailDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/pickingMaterialDetail/PickingMaterialDetailDTO.java index 226ce2e99..9fa542910 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/pickingMaterialDetail/PickingMaterialDetailDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/pickingMaterialDetail/PickingMaterialDetailDTO.java @@ -204,4 +204,20 @@ public class PickingMaterialDetailDTO extends BaseVOEntity { @ApiModelProperty("作业数量:拣货数量") @Excel(name = "作业数量:拣货数量") private BigDecimal actualQuantity; -} + + @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; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/receiptMaterialDetail/ReceiptMaterialDetailDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/receiptMaterialDetail/ReceiptMaterialDetailDTO.java index bf3b952a9..639ba47f1 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/receiptMaterialDetail/ReceiptMaterialDetailDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/receiptMaterialDetail/ReceiptMaterialDetailDTO.java @@ -227,4 +227,25 @@ public class ReceiptMaterialDetailDTO extends BaseVOEntity { @ApiModelProperty("复合条件查询 物料名称 物料编码 物料条码") private String compoundOrQuery; -} + + + @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; + + @ApiModelProperty("单位") + @Excel(name = "单位") + private String unit; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/shelfMaterialDetail/ShelfMaterialDetailDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/shelfMaterialDetail/ShelfMaterialDetailDTO.java index 9b8ea0b25..7c3d7b986 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/shelfMaterialDetail/ShelfMaterialDetailDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/shelfMaterialDetail/ShelfMaterialDetailDTO.java @@ -1,5 +1,6 @@ package com.mhd.wms.interfaces.dto.shelfMaterialDetail; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.mhd.common.core.annotation.Excel; @@ -8,8 +9,10 @@ import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.todo.InMateria import com.mhd.wms.domain.shelfMaterialDetail.repository.todo.ShelfMaterialDetailDO; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; +import java.util.Date; import java.util.List; /** @@ -260,4 +263,54 @@ public class ShelfMaterialDetailDTO extends BaseVOEntity { @ApiModelProperty("序列号") private List materialDetailSerialNumberList; -} + + @ApiModelProperty("Batch Ref NO's") + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @ApiModelProperty("Sheet Ref NO's") + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @ApiModelProperty("箱号/卡板号") + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @ApiModelProperty("扩展字段1") + @Excel(name = "扩展字段1") + private String extAttr1; + + @ApiModelProperty("扩展字段2") + @Excel(name = "扩展字段2") + private String extAttr2; + + @ApiModelProperty("生产日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date productionDate; + + @ApiModelProperty("过期日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date expiryDate; + + @ApiModelProperty("存货日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date inventoryDate; + + @ApiModelProperty("ExtAttr3") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr3", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date extAttr3; + + @ApiModelProperty("ExtAttr4") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "ExtAttr4", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date extAttr4; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/statementStatistics/ImmediateInventoryDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/statementStatistics/ImmediateInventoryDTO.java index 80f94e8ee..a43e1113f 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/statementStatistics/ImmediateInventoryDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/statementStatistics/ImmediateInventoryDTO.java @@ -144,4 +144,10 @@ public class ImmediateInventoryDTO { @ApiModelProperty("拣货数量结束") @Excel(name = "拣货数量结束") private BigDecimal pickQuantityEnd; -} + + private BigDecimal pickQuantityBegin; + private BigDecimal receivedQuantityBegin; + private BigDecimal freezeQuantityBegin; + private BigDecimal allocationQuantityBegin; + private BigDecimal checkQuantity; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderBaseDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderBaseDTO.java index 189f2fe9d..848a1c5b8 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderBaseDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderBaseDTO.java @@ -51,6 +51,13 @@ public class StockInOrderBaseDTO extends BaseVOEntity { @Excel(name = "货主名称") private String shipperName; + /** + * 兼容前端使用 userName 作为货主名称字段: + * 如果请求体中只传了 userName,将在组装器中自动回填到 shipperName。 + */ + @ApiModelProperty("货主名称(兼容字段:userName)") + private String userName; + @ApiModelProperty("入库单类型编码") @Excel(name = "入库单类型编码") private String orderTypeCode; diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderDTO.java index 3002d1e36..90ba0999f 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderDTO.java @@ -237,4 +237,110 @@ public class StockInOrderDTO extends StockInOrderBaseDTO { @ApiModelProperty("小于入库单审核状态: 1-未审核 2-审核不通过 3-审核通过") @Excel(name = "小于入库单审核状态: 1-未审核 2-审核不通过 3-审核通过") private Integer gtAuditStatus; + + // ========== 报关相关字段 ========== + @ApiModelProperty("To") + @Excel(name = "To") + private String to; + + @ApiModelProperty("联系人") + @Excel(name = "联系人") + private String contactPerson; + + @ApiModelProperty("车型及车牌") + @Excel(name = "车型及车牌") + private String vehicleInfo; + + @ApiModelProperty("委托编号NO") + @Excel(name = "委托编号NO") + private String consignmentNo; + + @ApiModelProperty("Tel") + @Excel(name = "Tel") + private String tel; + + @ApiModelProperty("司机签名") + @Excel(name = "司机签名") + private String driverSignature; + + @ApiModelProperty("Fax") + @Excel(name = "Fax") + private String fax; + + @ApiModelProperty("申报地关区") + @Excel(name = "申报地关区") + private String declarationArea; + + + @ApiModelProperty("生产商") + @Excel(name = "生产商") + private String manufacturer; + + @ApiModelProperty("报关员姓名及联系方式") + @Excel(name = "报关员姓名及联系方式") + private String customsBrokerInfo; + + @ApiModelProperty("送货地址") + @Excel(name = "送货地址") + private String deliveryAddress; + + @ApiModelProperty("进出境关别") + @Excel(name = "进出境关别") + private String entryExitCustoms; + + @ApiModelProperty("起运/运抵国(地区)") + @Excel(name = "起运/运抵国(地区)") + private String originDestinationCountry; + + @ApiModelProperty("承运商(先做成输入框,待定)") + @Excel(name = "承运商") + private String carrier; + + @ApiModelProperty("柜号(数据字典:20尺/40尺)") + @Excel(name = "柜号") + private String containerNo; + + @ApiModelProperty("运输方式(数据字典:公路运输/其他运输)") + @Excel(name = "运输方式") + private String transportMethod; + + @ApiModelProperty("监管方式(数据字典:一般贸易)") + @Excel(name = "监管方式") + private String supervisionMethod; + + @ApiModelProperty("海关是否查验货物(默认:否)") + @Excel(name = "海关是否查验货物") + private Integer customsInspection; + + @ApiModelProperty("是否需要报关(默认:是)") + @Excel(name = "是否需要报关") + private Integer needCustomsDeclaration; + + @ApiModelProperty("是否需要运输(默认:否)") + @Excel(name = "是否需要运输") + private Integer needTransport; + + @ApiModelProperty("入仓日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Excel(name = "入仓日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date warehouseDate; + + @ApiModelProperty("完成时间") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date completionTime; + + @ApiModelProperty("下单日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @Excel(name = "下单日期", width = 30, dateFormat = "yyyy-MM-dd") + private Date orderDate; + + @ApiModelProperty(name = "创建时间查询条件开始日期") + private String createTimeStart; + + @ApiModelProperty(name = "创建时间查询条件结束日期") + private String createTimeEnd; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderImportRowDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderImportRowDTO.java new file mode 100644 index 000000000..c11526919 --- /dev/null +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderImportRowDTO.java @@ -0,0 +1,213 @@ +package com.mhd.wms.interfaces.dto.stockInOrder; + +import com.mhd.common.core.annotation.Excel; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 入库单导入行DTO(一个Excel行=一个明细行;表头字段可重复) + * + * 约定:以【委托编号NO】作为同一张入库单的分组键(同一个委托编号可导入多条物料明细) + */ +@Data +public class StockInOrderImportRowDTO { + + // ====== 分组/表头基础字段(建议在Excel中每行重复填写) ====== + // @Excel(name = "仓库ID") + // private Long warehouseId; + + // @Excel(name = "货主ID") + // private Long shipperId; + + @Excel(name = "货主编号") + private String shipperCode; + + // @Excel(name = "供应商ID") + // private Long supplierId; + + // @Excel(name = "入库单据类型") + // private String orderTypeCode; + + @Excel(name = "委托编号NO") + private String consignmentNo; + + // ====== 表头报关字段(与页面一致) ====== + @Excel(name = "To") + private String to; + + @Excel(name = "联系人") + private String contactPerson; + + @Excel(name = "车型及车牌") + private String vehicleInfo; + + @Excel(name = "Tel") + private String tel; + + @Excel(name = "司机签名") + private String driverSignature; + + @Excel(name = "Fax") + private String fax; + + @Excel(name = "申报地关区") + private String declarationArea; + + @Excel(name = "生产商") + private String manufacturer; + + @Excel(name = "报关员姓名及联系方式") + private String customsBrokerInfo; + + @Excel(name = "送货地址") + private String deliveryAddress; + + @Excel(name = "进出境关别") + private String entryExitCustoms; + + @Excel(name = "起运/运抵国(地区)") + private String originDestinationCountry; + + // 客户名称只在表头中,明细行不需要此字段(代码会从表头读取并应用到此字段) + @Excel(name = "客户名称") + private String shipperName; + + @Excel(name = "承运商") + private String carrier; + + @Excel(name = "柜号") + private String containerNo; + + @Excel(name = "运输方式") + private String transportMethod; + + @Excel(name = "监管方式") + private String supervisionMethod; + + @Excel(name = "海关是否查验货物") + private Integer customsInspection; + + @Excel(name = "是否需要报关") + private Integer needCustomsDeclaration; + + @Excel(name = "是否需要运输") + private Integer needTransport; + + @Excel(name = "入仓日期") + private String warehouseDate; // 导入先按字符串,后端可根据需要转Date(当前入库单服务未强制使用) + + @Excel(name = "完成时间") + private String completionTime; + + @Excel(name = "下单日期") + private String orderDate; + + @Excel(name = "备注") + private String remark; + + // ====== 明细字段(一个Excel行=一个明细) ====== + @Excel(name = "序号") + private Integer serialNumber; + + @Excel(name = "商品名称") + private String materialName; + + @Excel(name = "料号") + private String materialCode; + + // @Excel(name = "物料基础信息ID") + // private Long materialBaseInfoId; + + // 模板中没有此字段,注释掉 + // @Excel(name = "计划数量") + private BigDecimal quantity; + + @Excel(name = "仓库数量") + private BigDecimal warehouseQuantity; + + // 支持"入库数量"列名(与"仓库数量"映射到同一个字段) + @Excel(name = "入库数量") + private BigDecimal inboundQuantity; + + @Excel(name = "规格型号/ITEM") + private String specificationModel; + + @Excel(name = "商品SKU码") + private String skuCode; + + @Excel(name = "Invoice No.") + private String invoiceNo; + + @Excel(name = "申报数量") + private BigDecimal declaredQuantity; + + @Excel(name = "申报单位") + private String declarationUnit; + + @Excel(name = "升") + private BigDecimal liter; + + @Excel(name = "箱数") + private BigDecimal boxCount; + + @Excel(name = "件数") + private BigDecimal pieceCount; + + @Excel(name = "尺寸") + private String dimensions; + + // @Excel(name = "出库数量") + private BigDecimal outboundQuantity; + + @Excel(name = "单位") + private String unit; + + // 支持多种列名格式(处理换行符、空格、括号等) + @Excel(name = "总净重(KG)") + private BigDecimal totalNetWeight; + + @Excel(name = "总净重\n(KG)") + private BigDecimal totalNetWeight2; + + @Excel(name = "总毛重(KG)") + private BigDecimal totalGrossWeight; + + @Excel(name = "总毛重 (KG)") + private BigDecimal totalGrossWeight2; + + @Excel(name = "总体积(CBM)") + private BigDecimal totalVolume; + + @Excel(name = "总体积\n(CBM)") + private BigDecimal totalVolume2; + + @Excel(name = "总面积(SQM)") + private BigDecimal totalArea; + + @Excel(name = "总面积(SQM)") + private BigDecimal totalArea2; + + @Excel(name = "Batch Ref NO's") + private String batchRefNo; + + @Excel(name = "Sheet Ref NO's") + private String sheetRefNo; + + @Excel(name = "原产国") + private String originCountry; + + @Excel(name = "箱号/卡板号") + private String boxPalletNo; + + @Excel(name = "总价") + private BigDecimal totalPrice; + + @Excel(name = "币制") + private String currency; + + @Excel(name = "备注") + private String detailRemark; +} + + diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockOutOrder/StockOutOrderDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockOutOrder/StockOutOrderDTO.java index e8f3c636d..76de1ab1a 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockOutOrder/StockOutOrderDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockOutOrder/StockOutOrderDTO.java @@ -277,4 +277,119 @@ public class StockOutOrderDTO extends StockOutOrderBaseDTO { @ApiModelProperty("小于复核状态: 1-未复核 2-复核中 3-已复核") private Integer ltCheckStatus; -} + + + @ApiModelProperty("to") + @Excel(name = "to") + private String to; + + @ApiModelProperty("联系人") + @Excel(name = "联系人") + private String contactPerson; + + @ApiModelProperty("车型及车牌") + @Excel(name = "车型及车牌") + private String vehicleModelPlate; + + @ApiModelProperty("委托编号") + @Excel(name = "委托编号") + private String entrustNo; + + @ApiModelProperty("Tel") + @Excel(name = "Tel") + private String tel; + + @ApiModelProperty("司机签名") + @Excel(name = "司机签名") + private String driverSign; + + @ApiModelProperty("Fax") + @Excel(name = "Fax") + private String fax; + + @ApiModelProperty("申报地关区") + @Excel(name = "申报地关区") + private String declareCustoms; + + @ApiModelProperty("生产商") + @Excel(name = "生产商") + private String manufacturer; + + @ApiModelProperty("报关员姓名及联系方式") + @Excel(name = "报关员姓名及联系方式") + private String customsDeclarerInfo; + + @ApiModelProperty("送货地址") + @Excel(name = "送货地址") + private String deliveryAddr; + + @ApiModelProperty("进出境关别") + @Excel(name = "进出境关别") + private String entryExitCustoms; + + @ApiModelProperty("起运/运抵国(地区)") + @Excel(name = "起运/运抵国(地区)") + private String departureArrivalCountry; + + @ApiModelProperty("承运商") + @Excel(name = "承运商") + private String carrier; + + @ApiModelProperty("柜号") + @Excel(name = "柜号") + private String containerNo; + + @ApiModelProperty("柜") + @Excel(name = "柜") + private String containerNoName; + + @ApiModelProperty("出仓日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "出仓日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date outboundDate; + @ApiModelProperty("完成时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date completeTime; + @ApiModelProperty("orderDate") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "orderDate", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date orderDate; + + @ApiModelProperty("运输方式") + @Excel(name = "运输方式") + private String transportModeCode; + @ApiModelProperty("运输方式") + @Excel(name = "运输方式") + private String transportModeName; + @ApiModelProperty("监管方式") + @Excel(name = "监管方式") + private String supervisionModeCode; + @ApiModelProperty("监管方式") + @Excel(name = "监管方式") + private String supervisionModeName; + @ApiModelProperty("海关是否查验货物") + @Excel(name = "海关是否查验货物") + private String customsInspectionFlag; + @ApiModelProperty("是否需要报关") + @Excel(name = "是否需要报关") + private String needDeclareFlag; + @ApiModelProperty("是否需要运输") + @Excel(name = "是否需要运输") + private String needTransportFlag; + + @ApiModelProperty(name = "创建时间查询条件开始日期") + private String createTimeStart; + + @ApiModelProperty(name = "创建时间查询条件结束日期") + private String createTimeEnd; + + @ApiModelProperty(name = "审核时间查询条件开始日期") + private String auditTimeStart; + + @ApiModelProperty(name = "审核时间查询条件结束日期") + private String auditTimeEnd; +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockOutTaskOrder/StockOutTaskOrderDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockOutTaskOrder/StockOutTaskOrderDTO.java index 6619730f1..a8489540f 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockOutTaskOrder/StockOutTaskOrderDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockOutTaskOrder/StockOutTaskOrderDTO.java @@ -159,4 +159,19 @@ public class StockOutTaskOrderDTO extends BaseVOEntity { @ApiModelProperty("大于指定状态值:1-待收货 2-部分收货 3-已收货 4-已关闭") private Integer gtStatus; + + @ApiModelProperty("集货库位ID集合") + private List storageLocationList; + + @ApiModelProperty(name = "创建时间查询条件开始日期") + private String createTimeStart; + + @ApiModelProperty(name = "创建时间查询条件结束日期") + private String createTimeEnd; + + @ApiModelProperty(name = "作业完成时间查询条件开始日期") + private String operatorsEndTimeStart; + + @ApiModelProperty(name = "作业完成时间查询条件结束日期") + private String operatorsEndTimeEnd; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockReceiptOrder/StockReceiptOrderDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockReceiptOrder/StockReceiptOrderDTO.java index bd92bfe91..0aa13cf00 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockReceiptOrder/StockReceiptOrderDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockReceiptOrder/StockReceiptOrderDTO.java @@ -146,4 +146,10 @@ public class StockReceiptOrderDTO extends StockInOrderBaseDTO { @ApiModelProperty("物料明细") private List materialDetailList; + + @ApiModelProperty(name = "创建时间查询条件开始日期") + private String createTimeStart; + + @ApiModelProperty(name = "创建时间查询条件结束日期") + private String createTimeEnd; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockShelfOrder/StockShelfOrderDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockShelfOrder/StockShelfOrderDTO.java index 25d31b343..c86f5821f 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockShelfOrder/StockShelfOrderDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockShelfOrder/StockShelfOrderDTO.java @@ -117,4 +117,10 @@ public class StockShelfOrderDTO extends StockInOrderBaseDTO { @ApiModelProperty("物料明细") private List materialDetailList; + + @ApiModelProperty(name = "创建时间查询条件开始日期") + private String createTimeStart; + + @ApiModelProperty(name = "创建时间查询条件结束日期") + private String createTimeEnd; } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/handoverTaskOrder/HandoverTaskOrderApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/handoverTaskOrder/HandoverTaskOrderApi.java index b6cbe83c1..1f4aee591 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/handoverTaskOrder/HandoverTaskOrderApi.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/handoverTaskOrder/HandoverTaskOrderApi.java @@ -6,8 +6,10 @@ import com.mhd.common.core.web.page.TableDataInfo; import com.mhd.wms.application.service.handoverTaskOrder.HandoverTaskOrderApplicationService; import com.mhd.wms.domain.handoverTaskOrder.repository.po.HandoverTaskOrderPO; import com.mhd.wms.domain.handoverTaskOrder.repository.todo.HandoverTaskOrderDO; +import com.mhd.wms.domain.shiftManage.repository.todo.ShiftManageDO; import com.mhd.wms.interfaces.assember.handoverTaskOrder.HandoverTaskOrderAssembler; import com.mhd.wms.interfaces.dto.handoverTaskOrder.HandoverTaskOrderDTO; +import com.mhd.wms.interfaces.dto.shiftManage.ShiftManageDTO; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -70,6 +72,16 @@ public class HandoverTaskOrderApi extends BaseController { return toAjax(handoverTaskOrderApplicationService.delete(outTaskOrderIds)); } + /** + * 任务下发 + */ + @ApiOperation("任务下发") + @PostMapping(value = "/taskDistribution") + public AjaxResult taskDistribution(@RequestBody HandoverTaskOrderDTO handoverTaskOrderDTO) { + HandoverTaskOrderDO handoverTaskOrderDO = handoverTaskOrderAssembler.toDO(handoverTaskOrderDTO); + return AjaxResult.success(handoverTaskOrderApplicationService.taskDistribution(handoverTaskOrderDO)); + } + /** * 获取交接作业单详细信息 */ @@ -103,7 +115,13 @@ public class HandoverTaskOrderApi extends BaseController { return toAjax(handoverTaskOrderApplicationService.completeHandover(handoverTaskOrderDO)); } - + @ApiOperation("交接作业单APP上传图片并出库") + @PostMapping("/pictureApp") + public AjaxResult pictureApp(@RequestBody HandoverTaskOrderDTO handoverTaskOrderDTO) { + HandoverTaskOrderDO handoverTaskOrderDO = handoverTaskOrderAssembler.toDO(handoverTaskOrderDTO); + handoverTaskOrderApplicationService.pictureApp(handoverTaskOrderDO); + return AjaxResult.success(); + } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/materialInventory/MaterialInventoryApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/materialInventory/MaterialInventoryApi.java index b1ce90493..5ed1a840f 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/materialInventory/MaterialInventoryApi.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/materialInventory/MaterialInventoryApi.java @@ -43,6 +43,17 @@ public class MaterialInventoryApi extends BaseController { //转换实体 MaterialInventoryDO materialInventoryDO = materialInventoryAssembler.toDO(materialInventoryDTO); startPage(); + // 使用带批次属性的查询方法,批次属性值从库存表中获取 + List list = materialInventoryApplicationService.queryListWithBatchAttributes(materialInventoryDO); + return getDataTable(list); + } + + @ApiOperation("查询物料库存列表不分页") + @GetMapping("/listAll") + public TableDataInfo listAll(MaterialInventoryDTO materialInventoryDTO) + { + //转换实体 + MaterialInventoryDO materialInventoryDO = materialInventoryAssembler.toDO(materialInventoryDTO); List list = materialInventoryApplicationService.queryList(materialInventoryDO); return getDataTable(list); } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/pickingOrder/PickingOrderApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/pickingOrder/PickingOrderApi.java index 9c5b014cc..a0bc87498 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/pickingOrder/PickingOrderApi.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/pickingOrder/PickingOrderApi.java @@ -116,4 +116,4 @@ public class PickingOrderApi extends BaseController { PickingOrderDO pickingOrderDO = pickingOrderAssembler.toDO(pickingOrderDTO); return toAjax(pickingOrderApplicationService.completePicking(pickingOrderDO)); } -} +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/shiftMaterialDetail/ShiftMaterialDetailApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/shiftMaterialDetail/ShiftMaterialDetailApi.java index a582d40da..1e83eaeed 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/shiftMaterialDetail/ShiftMaterialDetailApi.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/shiftMaterialDetail/ShiftMaterialDetailApi.java @@ -92,7 +92,8 @@ public class ShiftMaterialDetailApi extends BaseController { throw new ServiceException("请输入移位单号"); } startPage(); - List list = shiftMaterialDetailApplicationService.queryList(shiftMaterialDetailDO); + // 使用带批次属性的查询方法,批次属性值从库存表中获取 + List list = shiftMaterialDetailApplicationService.queryListWithBatchAttributes(shiftMaterialDetailDO); return getDataTable(list); } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/stockInOrder/StockInOrderApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/stockInOrder/StockInOrderApi.java index cc727bdf6..8b9d7f666 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/stockInOrder/StockInOrderApi.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/stockInOrder/StockInOrderApi.java @@ -3,6 +3,8 @@ package com.mhd.wms.interfaces.facadeApi.stockInOrder; 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.common.core.exception.ServiceException; +import com.mhd.common.core.utils.StringUtils; import com.mhd.wms.application.service.stockInOrder.StockInOrderApplicationService; import com.mhd.wms.domain.stockInOrder.repository.po.StockInOrderPO; import com.mhd.wms.domain.stockInOrder.repository.todo.StockInOrderDO; @@ -11,6 +13,7 @@ import com.mhd.wms.interfaces.dto.stockInOrder.StockInOrderDTO; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.util.List; @@ -80,6 +83,15 @@ public class StockInOrderApi extends BaseController { return AjaxResult.success(stockInOrderApplicationService.getInfo(inOrderId)); } + /** + * 导入入库单 + */ + @ApiOperation("导入入库单") + @PostMapping(value = "/importData") + public AjaxResult importData(MultipartFile file) + { + return AjaxResult.success(stockInOrderApplicationService.importData(file)); + } /** * 审核入库单 diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/stockOutOrder/StockOutOrderApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/stockOutOrder/StockOutOrderApi.java index 41925939c..7d4fa5081 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/stockOutOrder/StockOutOrderApi.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/stockOutOrder/StockOutOrderApi.java @@ -1,19 +1,34 @@ package com.mhd.wms.interfaces.facadeApi.stockOutOrder; import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; 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.wms.application.service.handoverTaskOrder.HandoverTaskOrderApplicationService; import com.mhd.wms.application.service.stockOutOrder.StockOutOrderApplicationService; +import com.mhd.wms.domain.handoverTaskOrder.entity.HandoverTaskOrder; +import com.mhd.wms.domain.handoverTaskOrder.repository.facade.IHandoverTaskOrderService; +import com.mhd.wms.domain.outMaterialDetail.repository.todo.OutMaterialDetailDO; +import com.mhd.wms.domain.stockOutOrder.repository.listener.ExcelParseService; import com.mhd.wms.domain.stockOutOrder.repository.po.StockOutOrderPO; import com.mhd.wms.domain.stockOutOrder.repository.todo.StockOutOrderDO; import com.mhd.wms.interfaces.assember.stockOutOrder.StockOutOrderAssembler; +import com.mhd.wms.interfaces.dto.outMaterialDetail.OutMaterialDetailDTO; import com.mhd.wms.interfaces.dto.stockOutOrder.StockOutOrderDTO; import io.swagger.annotations.ApiOperation; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpRequest; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.ArrayList; import java.util.List; /** @@ -31,6 +46,9 @@ public class StockOutOrderApi extends BaseController { @Resource private StockOutOrderAssembler stockOutOrderAssembler; + @Autowired + private IHandoverTaskOrderService handoverTaskOrderService; + /** * 分页查询出库单列表 */ @@ -45,6 +63,44 @@ public class StockOutOrderApi extends BaseController { return getDataTable(list); } + @Autowired + private ExcelParseService excelParseService; + + /** + * 上传并解析出仓委托单Excel + */ + @PostMapping("/import") + public AjaxResult parseOutboundOrder( + @RequestParam("file") MultipartFile file, + HttpServletRequest request, + @RequestParam("warehouseId") Long warehouseId, + @RequestParam("warehouseCode") String warehouseCode, + @RequestParam("warehouseName") String warehouseName) { + + // 验证文件 + if (file.isEmpty()) { + return error("文件为空"); + } + + // 验证文件类型 + String fileName = file.getOriginalFilename(); + if (fileName == null || !fileName.endsWith(".xls") && !fileName.endsWith(".xlsx")) { + return error("文件类型错误"); + } + + try { + // 解析Excel并返回结果 + StringBuilder result = excelParseService.parseOutboundOrderExcel(file, warehouseName, warehouseCode, warehouseId); + if (result.length() > 0) { + return AjaxResult.error(result.toString()); + } else { + return AjaxResult.success(result); + } + } catch (IOException e) { + return error("解析失败"); + } + } + /** * 编辑出库单 */ @@ -80,6 +136,17 @@ public class StockOutOrderApi extends BaseController { { return AjaxResult.success(stockOutOrderApplicationService.getInfoChildren(outOrderId)); } + /** + * 根据出库单号获取出库单详细信息 + */ + @ApiOperation("获取出库单") + @GetMapping(value = "/getInfoOutOrderNumber") + public AjaxResult getInfoOutOrderNumber(String outOrderNumber) + { + HandoverTaskOrder handoverTaskOrder = handoverTaskOrderService.getOne(new LambdaQueryWrapper() + .eq(HandoverTaskOrder::getTaskNumber, outOrderNumber)); + return AjaxResult.success(stockOutOrderApplicationService.getInfoChildren(handoverTaskOrder.getHandoverTaskOrderId())); + } /** * 审核出库单 @@ -97,7 +164,11 @@ public class StockOutOrderApi extends BaseController { @ApiOperation("手动分配") @PostMapping("/manualAssign") public AjaxResult manualAssign(@RequestBody StockOutOrderDTO stockOutOrderDTO) { - StockOutOrderDO stockOutOrderDO = JSONUtil.toBean(JSONUtil.toJsonStr(stockOutOrderDTO), StockOutOrderDO.class); + //StockOutOrderDO stockOutOrderDO = JSONUtil.toBean(JSONUtil.toJsonStr(stockOutOrderDTO), StockOutOrderDO.class); + StockOutOrderDO stockOutOrderDO = new StockOutOrderDO(); + BeanUtils.copyProperties(stockOutOrderDTO, stockOutOrderDO); + List materialDetailList = cn.hutool.core.bean.BeanUtil.copyToList(stockOutOrderDTO.getMaterialDetailList(), OutMaterialDetailDO.class); + stockOutOrderDO.setMaterialDetailList(materialDetailList); return toAjax(stockOutOrderApplicationService.manualAssign(stockOutOrderDO)); } @@ -112,7 +183,48 @@ public class StockOutOrderApi extends BaseController { return toAjax(stockOutOrderApplicationService.cancelAssign(stockOutOrderDO)); } + /** + * 手动取消分配(点击确认后直接取消分配) + * 前端点击取消分配按钮时弹出确认对话框,点击确认后调用此接口 + * 只需要传递出库单ID和物料明细ID,会自动取消该明细的所有已分配数量 + */ + @ApiOperation("手动取消分配") + @PostMapping("/manualCancelAssign") + public AjaxResult manualCancelAssign(@RequestBody StockOutOrderDTO stockOutOrderDTO) { + // 检查参数 + if (stockOutOrderDTO.getOutOrderId() == null) { + return error("出库单ID不能为空"); + } + if (stockOutOrderDTO.getMaterialDetailList() == null || stockOutOrderDTO.getMaterialDetailList().isEmpty()) { + return error("物料明细不能为空,请选择要取消分配的物料明细"); + } + StockOutOrderDO stockOutOrderDO = new StockOutOrderDO(); + BeanUtils.copyProperties(stockOutOrderDTO, stockOutOrderDO); + // 转换物料明细列表,手动转换确保materialDetailId字段正确传递 + List materialDetailList = new ArrayList<>(); + for (OutMaterialDetailDTO detailDTO : stockOutOrderDTO.getMaterialDetailList()) { + OutMaterialDetailDO detailDO = new OutMaterialDetailDO(); + // 只复制必要的字段,确保materialDetailId被正确传递 + detailDO.setMaterialDetailId(detailDTO.getMaterialDetailId()); + detailDO.setUniqueId(detailDTO.getUniqueId()); + detailDO.setAllocationQuantity(detailDTO.getAllocationQuantity()); + // 如果有子明细,也转换 + if (detailDTO.getMaterialDetailList() != null && !detailDTO.getMaterialDetailList().isEmpty()) { + List children = new ArrayList<>(); + for (OutMaterialDetailDTO childDTO : detailDTO.getMaterialDetailList()) { + OutMaterialDetailDO childDO = new OutMaterialDetailDO(); + childDO.setMaterialDetailId(childDTO.getMaterialDetailId()); + childDO.setAllocationQuantity(childDTO.getAllocationQuantity()); + children.add(childDO); + } + detailDO.setChildren(children); + } + materialDetailList.add(detailDO); + } + stockOutOrderDO.setMaterialDetailList(materialDetailList); + return toAjax(stockOutOrderApplicationService.manualCancelAssign(stockOutOrderDO)); + } /** * 生成拣货单 @@ -230,4 +342,4 @@ public class StockOutOrderApi extends BaseController { return toAjax(stockOutOrderApplicationService.close(stockOutOrderDO)); } -} +} \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApp/deliveTask/DeliveTaskAppApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApp/deliveTask/DeliveTaskAppApi.java index bf778a6cf..d9a1a244b 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApp/deliveTask/DeliveTaskAppApi.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApp/deliveTask/DeliveTaskAppApi.java @@ -55,6 +55,17 @@ public class DeliveTaskAppApi extends BaseController { return AjaxResult.success(deliveTaskApplicationService.getInfo(deliverTaskId)); } + /** + * 转交用户 + */ + @ApiOperation("转交用户") + @PostMapping(value = "/forward") + public AjaxResult forward(DeliveTaskDTO deliveTaskDTO) + { + DeliveTaskDO deliveTaskDO = deliveTaskAssembler.toDO(deliveTaskDTO); + return AjaxResult.success(deliveTaskApplicationService.forward(deliveTaskDO)); + } + /** * 工作台查询 diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApp/stockReceiptOrder/StockReceiptOrderAppApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApp/stockReceiptOrder/StockReceiptOrderAppApi.java index de3cbc38b..93df045d9 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApp/stockReceiptOrder/StockReceiptOrderAppApi.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApp/stockReceiptOrder/StockReceiptOrderAppApi.java @@ -52,7 +52,7 @@ public class StockReceiptOrderAppApi extends BaseController { @ApiOperation("获取收货单") @GetMapping(value = "/getInfoByApp") public AjaxResult getInfoByApp(Long receiptOrderId) { - return AjaxResult.success(stockReceiptOrderApplicationService.getInfoByApp(receiptOrderId)); + return AjaxResult.success(stockReceiptOrderApplicationService.getInfo(receiptOrderId)); } /** diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApp/stockShelfOrder/StockShelfOrderAppApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApp/stockShelfOrder/StockShelfOrderAppApi.java index 00773c1e1..9099cd451 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApp/stockShelfOrder/StockShelfOrderAppApi.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApp/stockShelfOrder/StockShelfOrderAppApi.java @@ -53,7 +53,7 @@ public class StockShelfOrderAppApi extends BaseController { @GetMapping(value = "/getInfo") public AjaxResult getInfo(Long shelfOrderId) { - return AjaxResult.success(stockShelfOrderApplicationService.getInfoByApp(shelfOrderId)); + return AjaxResult.success(stockShelfOrderApplicationService.getInfo(shelfOrderId)); } diff --git a/mhd_wms/src/main/resources/bootstrap.yml b/mhd_wms/src/main/resources/bootstrap.yml index 9a099ecf8..daa9ac6db 100644 --- a/mhd_wms/src/main/resources/bootstrap.yml +++ b/mhd_wms/src/main/resources/bootstrap.yml @@ -14,7 +14,9 @@ spring: nacos: discovery: # 服务注册地址 - #server-addr: 127.0.0.1:8848 + server-addr: 127.0.0.1:8848 + username: nacos + password: manhuoda@2023 # 演示环境 # server-addr: 47.92.229.169:8848 # 测试开发环境 @@ -24,10 +26,12 @@ spring: # 大运通泰生产环境 # server-addr: 39.107.137.158:8848 # 线上测试环境 - server-addr: 116.204.23.92:8848 +# server-addr: 116.204.23.92:8848 config: # 配置中心地址 - #server-addr: 127.0.0.1:8848 + server-addr: 127.0.0.1:8848 + username: nacos + password: manhuoda@2023 # 演示环境 # server-addr: 47.92.229.169:8848 # 测试开发环境 @@ -37,7 +41,7 @@ spring: # 大运通泰生产环境 # server-addr: 39.107.137.158:8848 # 线上测试环境 - server-addr: 116.204.23.92:8848 +# server-addr: 116.204.23.92:8848 # 配置文件格式 file-extension: yml # 共享配置 diff --git a/mhd_wms/src/main/resources/mapper/OutMaterialDetail/OutMaterialDetailMapper.xml b/mhd_wms/src/main/resources/mapper/OutMaterialDetail/OutMaterialDetailMapper.xml index ab40e2b22..fcbf40168 100644 --- a/mhd_wms/src/main/resources/mapper/OutMaterialDetail/OutMaterialDetailMapper.xml +++ b/mhd_wms/src/main/resources/mapper/OutMaterialDetail/OutMaterialDetailMapper.xml @@ -51,7 +51,37 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -62,7 +92,38 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.warehouse_id, a.warehouse_code, a.warehouse_name, a.storage_section_id, a.storage_code, a.storage_name, a.storage_location_id, a.storage_location_code, a.storage_location_name, a.level, a.parent_unique_id, a.allow_modify, a.material_inventory_id, a.batch_number, a.container_id, a.container_code, a.container_type, a.container_type_name, a.material_status_code, a.material_status_name, a.remark, a.create_time, a.create_by,gen_picking_order, - a.create_by_name, a.update_time, a.update_by, a.update_by_name, a.del_flag, a.over_stock_id, a.over_stock_status, a.over_stock_type + a.create_by_name, a.update_time, a.update_by, a.update_by_name, a.del_flag, a.over_stock_id, a.over_stock_status, a.over_stock_type, + a.COMMODITY_NAME, + a.COMMODITY_NO, + a.MATERIAL_NO , + a.SPECIFICATION_MODEL, + a.SKUCODE , + a.INVOICE_NO, + a.LITER, + a.SIZE, + a.DECLARE_UNIT, + a.BATCH_REF_NO, + a.SHEET_REF_NO, + a.COUNTRY_OF_ORIGIN, + a.BOX_PALLET_NO, + a.CURRENCY, + a.DECLARE_QUANTITY, + a.CASE_COUNT, + a.PIECE_COUNT, + a.OUTBOUND_QUANTITY, + a.TOTAL_NET_WEIGHT, + a.TOTAL_GROSS_WEIGHT, + a.TOTAL_VOLUME, + a.TOTAL_AREA, + a.TOTAL_AMOUNT, + a.UNIT, + a.EXT_ATTR_1, + a.EXT_ATTR_2, + a.PRODUCTION_DATE, + a.EXPIRY_DATE, + a.INVENTORY_DATE, + a.EXT_ATTR_3, + a.EXT_ATTR_4 diff --git a/mhd_wms/src/main/resources/mapper/handoverTaskOrder/HandoverTaskOrderMapper.xml b/mhd_wms/src/main/resources/mapper/handoverTaskOrder/HandoverTaskOrderMapper.xml index fb1141cb0..b6e60a45e 100644 --- a/mhd_wms/src/main/resources/mapper/handoverTaskOrder/HandoverTaskOrderMapper.xml +++ b/mhd_wms/src/main/resources/mapper/handoverTaskOrder/HandoverTaskOrderMapper.xml @@ -37,6 +37,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -45,7 +46,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.platform_code, a.platform_name, a.platform_use_time_id, a.platform_use_start_time, a.platform_use_end_time, a.platform_use_status, a.order_type_code, a.order_type_name, a.expect_time, a.warehouse_id, a.warehouse_code, a.warehouse_name, a.shipper_id, a.shipper_name, a.order_number, a.picking_order_number, 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 + a.update_by, a.update_by_name, a.del_flag, a.picture_app diff --git a/mhd_wms/src/main/resources/mapper/inMaterialDetail/InMaterialDetailMapper.xml b/mhd_wms/src/main/resources/mapper/inMaterialDetail/InMaterialDetailMapper.xml index 07553eb42..bf31d0b9a 100644 --- a/mhd_wms/src/main/resources/mapper/inMaterialDetail/InMaterialDetailMapper.xml +++ b/mhd_wms/src/main/resources/mapper/inMaterialDetail/InMaterialDetailMapper.xml @@ -19,7 +19,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + @@ -52,6 +52,34 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -59,12 +87,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.material_detail_id, a.organization_id, a.organization_name, a.top_organization_id, a.unique_id, a.in_order_number, a.material_base_info_id, a.material_code, a.material_name, a.bar_code, a.quantity, a.receipt_quantity, a.shelves_quantity, a.receipt_status, a.shelves_status, a.pack_id, a.pack_code, a.pack_name, - a.pack_detail_id, a.unit_code, a.unit_name, a.material_warehouse_control_id, a.serial_number_manage, a.quality_inspection_manage, + CASE + WHEN a.pack_detail_id IS NULL OR TRIM(a.pack_detail_id) = '' THEN NULL + ELSE CAST(a.pack_detail_id AS BIGINT) + END as pack_detail_id, a.unit_code, a.unit_name, a.material_warehouse_control_id, a.serial_number_manage, a.quality_inspection_manage, a.quality_inspection_stage, a.quality_inspection_rule, a.quality_inspection_ratio, a.quality_inspection_term, a.quality_inspection_results, a.allow_overcharge, a.overcharge_ratio, a.batch_number, a.material_status_code, a.material_status_name, a.distribute_rule_id, a.distribute_rule_code, a.distribute_rule_name, a.container_id, a.container_code, a.container_type, a.container_type_name, a.warehouse_id, a.warehouse_code, a.warehouse_name, a.storage_section_id, a.storage_code, a.storage_name, a.storage_location_id, a.storage_location_code, a.storage_location_name, - a.level, a.parent_unique_id, 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, a.over_stock_id, a.over_stock_status, a.over_stock_type + a.level, a.parent_unique_id, 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, a.over_stock_id, a.over_stock_status, a.over_stock_type, + a.SPECIFICATION_MODEL, a.SKU_CODE, a.INVOICE_NO, a.LITER, a.DIMENSIONS, a.DECLARATION_UNIT, a.BATCH_REF_NO, a.SHEET_REF_NO, + a.ORIGIN_COUNTRY, a.BOX_PALLET_NO, a.CURRENCY, a.UNIT, a.DECLARED_QUANTITY, a.BOX_COUNT, a.PIECE_COUNT, a.INBOUND_QUANTITY, + a.TOTAL_NET_WEIGHT, a.TOTAL_GROSS_WEIGHT, a.TOTAL_VOLUME, a.TOTAL_AREA, a.TOTAL_PRICE, + a.PRODUCTION_DATE, a.EXPIRY_DATE, a.INVENTORY_DATE, a.EXT_ATTR_1, a.EXT_ATTR_2, a.EXT_ATTR_3, a.EXT_ATTR_4 ,CASE WHEN (a.quantity - a.receipt_quantity) < 0 THEN 0 ELSE (a.quantity - a.receipt_quantity) @@ -118,7 +153,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and a.pack_name like concat('%', #{packName}, '%') - + and a.pack_detail_id = #{packDetailId} diff --git a/mhd_wms/src/main/resources/mapper/inventoryAdjustmentRecord/InventoryAdjustmentRecordMapper.xml b/mhd_wms/src/main/resources/mapper/inventoryAdjustmentRecord/InventoryAdjustmentRecordMapper.xml index 1f1a1ee7f..1ba2d8ec9 100644 --- a/mhd_wms/src/main/resources/mapper/inventoryAdjustmentRecord/InventoryAdjustmentRecordMapper.xml +++ b/mhd_wms/src/main/resources/mapper/inventoryAdjustmentRecord/InventoryAdjustmentRecordMapper.xml @@ -44,114 +44,135 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + + + + + + - select inventory_adjustment_id, organization_id, organization_name, top_organization_id, material_inventory_id, material_base_info_id, material_code, material_name, bar_code, shipper_id, shipper_name, warehouse_id, warehouse_code, warehouse_name, storage_section_id, storage_code, storage_name, storage_location_id, storage_location_code, storage_location_name, adjust_type, adjust_direction, adjust_before_status_code, adjust_before_status_name, adjust_after_status_code, adjust_after_status_name, inventory_before_quantity, allocation_before_quantity, freeze_before_quantity, inventory_after_quantity, allocation_after_quantity, freeze_after_quantity, create_time, create_by, create_by_name, update_time, update_by, update_by_name, del_flag from inventory_adjustment_record - where del_flag = 1 + select a.inventory_adjustment_id, a.organization_id, a.organization_name, a.top_organization_id, a.material_inventory_id, + a.material_base_info_id, a.material_code, a.material_name, a.bar_code, a.shipper_id, a.shipper_name, a.warehouse_id, + a.warehouse_code, a.warehouse_name, a.storage_section_id, a.storage_code, a.storage_name, a.storage_location_id, + a.storage_location_code, a.storage_location_name, a.adjust_type, a.adjust_direction, a.adjust_before_status_code, + a.adjust_before_status_name, a.adjust_after_status_code, a.adjust_after_status_name, a.inventory_before_quantity, + a.allocation_before_quantity, a.freeze_before_quantity, a.inventory_after_quantity, a.allocation_after_quantity, + a.freeze_after_quantity, a.create_time, a.create_by, a.create_by_name, a.update_time, a.update_by, a.update_by_name, + a.del_flag,b.ext_attr_1, b.ext_attr_2, b.ext_attr_3, b.ext_attr_4, + b.production_date, b.expiry_date, b.inventory_date, + b.batch_ref_no, b.sheet_ref_no, b.box_pallet_no + from inventory_adjustment_record a left join material_inventory b on a.material_inventory_id = b.material_inventory_id + where a.del_flag = 1 - and organization_id = #{organizationId} + and a.organization_id = #{organizationId} - and organization_name like concat('%', #{organizationName}, '%') + and a.organization_name like concat('%', #{organizationName}, '%') - and top_organization_id = #{topOrganizationId} + and a.top_organization_id = #{topOrganizationId} - and material_base_info_id = #{materialBaseInfoId} + and a.material_base_info_id = #{materialBaseInfoId} - and material_inventory_id = #{materialInventoryId} + and a.material_inventory_id = #{materialInventoryId} - and material_code = #{materialCode} + and a.material_code = #{materialCode} - and material_name like concat('%', #{materialName}, '%') + and a.material_name like concat('%', #{materialName}, '%') - and bar_code = #{barCode} + and a.bar_code = #{barCode} - and shipper_id = #{shipperId} + and a.shipper_id = #{shipperId} - and shipper_name like concat('%', #{shipperName}, '%') + and a.shipper_name like concat('%', #{shipperName}, '%') - and warehouse_id = #{warehouseId} + and a.warehouse_id = #{warehouseId} - and warehouse_code = #{warehouseCode} + and a.warehouse_code = #{warehouseCode} - and warehouse_name like concat('%', #{warehouseName}, '%') + and a.warehouse_name like concat('%', #{warehouseName}, '%') - and storage_section_id = #{storageSectionId} + and a.storage_section_id = #{storageSectionId} - and storage_code = #{storageCode} + and a.storage_code = #{storageCode} - and storage_name like concat('%', #{storageName}, '%') + and a.storage_name like concat('%', #{storageName}, '%') - and storage_location_id = #{storageLocationId} + and a.storage_location_id = #{storageLocationId} - and storage_location_code = #{storageLocationCode} + and a.storage_location_code = #{storageLocationCode} - and storage_location_name like concat('%', #{storageLocationName}, '%') + and a.storage_location_name like concat('%', #{storageLocationName}, '%') - and adjust_type = #{adjustType} + and a.adjust_type = #{adjustType} - and adjust_direction = #{adjustDirection} + and a.adjust_direction = #{adjustDirection} - and adjust_before_status_code = #{adjustBeforeStatusCode} + and a.adjust_before_status_code = #{adjustBeforeStatusCode} - and adjust_before_status_name = #{adjustBeforeStatusName} + and a.adjust_before_status_name = #{adjustBeforeStatusName} - and adjust_after_status_code = #{adjustAfterStatusCode} + and a.adjust_after_status_code = #{adjustAfterStatusCode} - and adjust_after_status_name = #{adjustAfterStatusName} + and a.adjust_after_status_name = #{adjustAfterStatusName} - and inventory_before_quantity = #{inventoryBeforeQuantity} + and a.inventory_before_quantity = #{inventoryBeforeQuantity} - and allocation_before_quantity = #{allocationBeforeQuantity} + and a.allocation_before_quantity = #{allocationBeforeQuantity} - and freeze_before_quantity = #{freezeBeforeQuantity} + and a.freeze_before_quantity = #{freezeBeforeQuantity} - and inventory_after_quantity = #{inventoryAfterQuantity} + and a.inventory_after_quantity = #{inventoryAfterQuantity} - and allocation_after_quantity = #{allocationAfterQuantity} + and a.allocation_after_quantity = #{allocationAfterQuantity} - and freeze_after_quantity = #{freezeAfterQuantity} + and a.freeze_after_quantity = #{freezeAfterQuantity} - and create_by_name like concat('%', #{createByName}, '%') + and a.create_by_name like concat('%', #{createByName}, '%') - and update_by_name like concat('%', #{updateByName}, '%') + and a.update_by_name like concat('%', #{updateByName}, '%') + order by a.create_time desc + order by create_time desc @@ -151,6 +195,59 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + group by a.MATERIAL_INVENTORY_ID + + + + + + + + + @@ -323,19 +420,35 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + + + + + + + + + + SELECT * FROM + material_inventory a + LEFT JOIN material_base_info b on a.material_base_info_id = b.material_base_info_id + WHERE + a.del_flag = 1 AND b.shipper_id = #{shipperId} AND a.organization_id = #{organizationId} + + AND a.material_base_info_id = #{materialBaseInfoId} + + + AND a.warehouse_id = #{warehouseId} + + + AND a.storage_section_id = #{storageSectionId} + + + AND a.storage_location_id = #{storageLocationId} + + + AND TRUNC(a.EXT_ATTR_4) = TRUNC(#{extAttr4}) + + + AND TRUNC(a.EXT_ATTR_3) = TRUNC(#{extAttr3}) + + + AND TRUNC(a.inventory_date) = TRUNC(#{inventoryDate}) + + + AND TRUNC(a.EXPIRY_DATE) = TRUNC(#{expiryDate}) + + + AND TRUNC(a.PRODUCTION_DATE) = TRUNC(#{productionDate}) + + + AND a.EXT_ATTR_2 = #{extAttr2} + + + AND a.EXT_ATTR_1 = #{extAttr1} + + + AND a.BOX_PALLET_NO = #{boxPalletNo} + + + AND a.SHEET_REF_NO = #{sheetRefNo} + + + AND a.BATCH_REF_NO = #{batchRefNo} + + + + AND TRUNC(a.EXT_ATTR_4) is null + + + AND TRUNC(a.EXT_ATTR_3) is null + + + AND TRUNC(a.inventory_date) is null + + + AND TRUNC(a.EXPIRY_DATE) is null + + + AND a.PRODUCTION_DATE is null + + + AND a.EXT_ATTR_2 = #{extAttr2} + + + AND a.EXT_ATTR_1 = #{extAttr1} + + + + + + + AND a.EXT_ATTR_2 is null + + + AND a.EXT_ATTR_1 is null + + + + + \ No newline at end of file diff --git a/mhd_wms/src/main/resources/mapper/materialInventoryWarning/MaterialInventoryWarningMapper.xml b/mhd_wms/src/main/resources/mapper/materialInventoryWarning/MaterialInventoryWarningMapper.xml index 3c9b27fb1..900c4f27e 100644 --- a/mhd_wms/src/main/resources/mapper/materialInventoryWarning/MaterialInventoryWarningMapper.xml +++ b/mhd_wms/src/main/resources/mapper/materialInventoryWarning/MaterialInventoryWarningMapper.xml @@ -121,7 +121,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.max_temperature, a.pack_detail_id, a.unit_code, - a.`name`, + a.name, a.top_organization_id, b.shipper_id FROM diff --git a/mhd_wms/src/main/resources/mapper/outOrderAbnormal/OutOrderAbnormalMapper.xml b/mhd_wms/src/main/resources/mapper/outOrderAbnormal/OutOrderAbnormalMapper.xml index 9f200dcc3..d4e95901d 100644 --- a/mhd_wms/src/main/resources/mapper/outOrderAbnormal/OutOrderAbnormalMapper.xml +++ b/mhd_wms/src/main/resources/mapper/outOrderAbnormal/OutOrderAbnormalMapper.xml @@ -33,6 +33,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.out_order_abnormal_id, a.organization_id, a.organization_name, a.top_organization_id, a.abnormal_number, a.out_order_number, a.picking_order_number, a.out_task_order_number, a.type, a.quantity, a.actual_quantity, a.abnormal_actual_quantity, a.abnormal_type, a.abnormal_reason, 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 + + a.out_order_abnormal_id, a.organization_id, a.organization_name, a.top_organization_id, a.abnormal_number, a.picking_order_number, a.out_task_order_number, a.type, a.actual_quantity, a.abnormal_actual_quantity, a.abnormal_type, a.abnormal_reason, 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 + and a.organization_id = #{organizationId} @@ -103,7 +106,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" \ No newline at end of file diff --git a/mhd_wms/src/main/resources/mapper/stockOutOrder/StockOutOrderMapper.xml b/mhd_wms/src/main/resources/mapper/stockOutOrder/StockOutOrderMapper.xml index d22386b3e..6f57d603e 100644 --- a/mhd_wms/src/main/resources/mapper/stockOutOrder/StockOutOrderMapper.xml +++ b/mhd_wms/src/main/resources/mapper/stockOutOrder/StockOutOrderMapper.xml @@ -55,6 +55,33 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -66,7 +93,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.cancel_time, a.close_order, a.close_remark, a.close_by, a.close_by_name, a.close_time, a.check_status, a.check_task_distribution, a.check_task_distribution_time, a.check_operators_by, a.check_operators_name, a.mobilize_code, 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.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_MODEL_PLATE,a.ENTRUST_NO,a.TEL,a.DRIVER_SIGN,a.FAX,a.DECLARE_CUSTOMS,a.MANUFACTURER, + a.CUSTOMS_DECLARER_INFO,a.DELIVERY_ADDR,a.ENTRY_EXIT_CUSTOMS,a.DEPARTURE_ARRIVAL_COUNTRY,a.CARRIER,a.CONTAINER_NO,a.CONTAINER_NO_NAME,a.OUTBOUND_DATE, + a.COMPLETE_TIME,a.ORDER_DATE,a.TRANSPORT_MODE_CODE,a.TRANSPORT_MODE_NAME,a.SUPERVISION_MODE_CODE,a.SUPERVISION_MODE_NAME, + a.CUSTOMS_INSPECTION_FLAG,a.NEED_DECLARE_FLAG,a.NEED_TRANSPORT_FLAG,a.picture_app @@ -93,7 +124,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and a.notice_number = #{noticeNumber} - and a.out_order_number = #{outOrderNumber} + and a.out_order_number like concat('%', #{outOrderNumber}, '%') @@ -120,6 +151,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and a.audit_remark = #{auditRemark} + + and a.check_task_distribution = #{checkTaskDistribution} + and a.audit_by = #{auditBy} @@ -234,6 +268,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{item} + + and date_format(a.create_time,'%Y-%m-%d') >= #{createTimeStart} + + + and date_format(a.create_time,'%Y-%m-%d') <= #{createTimeEnd} + + + and date_format(a.audit_time,'%Y-%m-%d') >= #{auditTimeStart} + + + and date_format(a.audit_time,'%Y-%m-%d') <= #{auditTimeEnd} + and a.del_flag = #{delFlag} and a.del_flag = 1 @@ -247,6 +293,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - order by a.create_time desc + order by a.create_time desc nulls last \ No newline at end of file diff --git a/mhd_wms/src/main/resources/mapper/stockOutTaskOrder/StockOutTaskOrderMapper.xml b/mhd_wms/src/main/resources/mapper/stockOutTaskOrder/StockOutTaskOrderMapper.xml index 6a52b9462..fee22ad63 100644 --- a/mhd_wms/src/main/resources/mapper/stockOutTaskOrder/StockOutTaskOrderMapper.xml +++ b/mhd_wms/src/main/resources/mapper/stockOutTaskOrder/StockOutTaskOrderMapper.xml @@ -56,7 +56,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and a.serial_number = #{serialNumber} - and a.task_number = #{taskNumber} + and a.task_number like concat('%', #{taskNumber}, '%') and a.status = #{status} @@ -86,10 +86,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and a.shipper_name like concat('%', #{shipperName}, '%') - and a.order_number = #{orderNumber} + and a.order_number like concat('%', #{orderNumber}, '%') - and a.picking_order_number = #{pickingOrderNumber} + and a.picking_order_number like concat('%', #{pickingOrderNumber}, '%') and a.abnormal = #{abnormal} @@ -100,6 +100,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and a.operators_name like concat('%', #{operatorsName}, '%') + + and a.picking_quantity = #{pickingQuantity} + and a.operators_end_time = #{operatorsEndTime} @@ -109,6 +112,27 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and a.update_by_name like concat('%', #{updateByName}, '%') + + and a.storage_location_id = #{storageLocationId} + + + and a.storage_location_id in + + #{item} + + + + and date_format(a.create_time,'%Y-%m-%d') >= #{createTimeStart} + + + and date_format(a.create_time,'%Y-%m-%d') <= #{createTimeEnd} + + + and date_format(a.operators_end_time,'%Y-%m-%d') >= #{operatorsEndTimeStart} + + + and date_format(a.operators_end_time,'%Y-%m-%d') <= #{operatorsEndTimeEnd} + and a.del_flag = #{delFlag} and a.del_flag = 1 diff --git a/mhd_wms/src/main/resources/mapper/stockReceiptOrder/StockReceiptOrderMapper.xml b/mhd_wms/src/main/resources/mapper/stockReceiptOrder/StockReceiptOrderMapper.xml index 70cb024b7..6994de923 100644 --- a/mhd_wms/src/main/resources/mapper/stockReceiptOrder/StockReceiptOrderMapper.xml +++ b/mhd_wms/src/main/resources/mapper/stockReceiptOrder/StockReceiptOrderMapper.xml @@ -18,9 +18,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + + @@ -41,6 +47,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + 1=1 and a.receipt_order_id = #{receiptOrderId} @@ -54,11 +61,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and a.top_organization_id = #{topOrganizationId} - and a.in_order_number = #{inOrderNumber} + and a.in_order_number like concat('%', #{inOrderNumber}, '%') and a.receipt_order_number like concat('%', #{receiptOrderNumber}, '%') + + and a.task_distribution_merge = #{taskDistributionMerge} + and a.status = #{status} @@ -113,6 +123,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{item} + + and date_format(a.create_time,'%Y-%m-%d') >= #{createTimeStart} + + + and date_format(a.create_time,'%Y-%m-%d') <= #{createTimeEnd} + and a.del_flag = #{delFlag} and a.del_flag = 1 diff --git a/mhd_wms/src/main/resources/mapper/stockShelfOrder/StockShelfOrderMapper.xml b/mhd_wms/src/main/resources/mapper/stockShelfOrder/StockShelfOrderMapper.xml index 15dc61202..5a608fbb0 100644 --- a/mhd_wms/src/main/resources/mapper/stockShelfOrder/StockShelfOrderMapper.xml +++ b/mhd_wms/src/main/resources/mapper/stockShelfOrder/StockShelfOrderMapper.xml @@ -51,14 +51,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and a.in_order_number = #{inOrderNumber} - - and a.receipt_order_number = #{receiptOrderNumber} + + and a.receipt_order_number like concat('%', #{receiptOrderNumber}, '%') and a.receipt_task_number = #{receiptTaskNumber} - and a.shelf_order_number = #{shelfOrderNumber} + and a.shelf_order_number like concat('%', #{shelfOrderNumber}, '%') and a.status = #{status} @@ -93,6 +93,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{item} + + and date_format(a.create_time,'%Y-%m-%d') >= #{createTimeStart} + + + and date_format(a.create_time,'%Y-%m-%d') <= #{createTimeEnd} + and a.del_flag = #{delFlag} and a.del_flag = 1 @@ -101,7 +107,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - and c.receipt_order_number = #{receiptOrderNumber} + and c.receipt_order_number like concat('%', #{receiptOrderNumber}, '%')