package cn.iocoder.yudao.module.mes.controller.admin.wm.transaction; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.mes.controller.admin.wm.transaction.vo.MesWmTransactionPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.wm.transaction.vo.MesWmTransactionRespVO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO; import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transaction.MesWmTransactionDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeDO; import cn.iocoder.yudao.module.mes.dal.dataobject.pro.pallet.MesProPalletDO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO; import cn.iocoder.yudao.module.mes.dal.mysql.md.item.MesMdItemMapper; import cn.iocoder.yudao.module.mes.dal.mysql.pro.bagcode.MesProBagCodeMapper; import cn.iocoder.yudao.module.mes.dal.mysql.pro.pallet.MesProPalletMapper; import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesDetailMapper; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO; import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO; import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum; import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService; import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService; import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService; import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService; import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService; import cn.iocoder.yudao.module.mdm.api.category.MdmItemCategoryApi; import cn.iocoder.yudao.module.mdm.api.category.dto.MdmItemCategoryRespDTO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; /** * 库存事务流水 Controller */ @Tag(name = "管理后台 - 库存事务流水") @RestController @RequestMapping("/mes/wm/transaction") @Validated public class MesWmTransactionController { @Resource private MesWmTransactionService transactionService; @Resource private MesMdmItemService mdmItemService; @Resource private MdmItemCategoryApi mdmItemCategoryApi; @Resource private MesWmWarehouseService warehouseService; @Resource private MesWmWarehouseLocationService locationService; @Resource private MesWmWarehouseAreaService areaService; @Resource private MesProBagCodeMapper bagCodeMapper; @Resource private MesProPalletMapper palletMapper; @Resource private MesWmProductSalesDetailMapper salesDetailMapper; @Resource private MesMdItemMapper mesMdItemMapper; @Resource private MesMdItemTypeService mesMdItemTypeService; @GetMapping("/page") @Operation(summary = "获取库存事务流水分页") @Parameter(name = "id", description = "编号", required = true, example = "1") @PreAuthorize("@ss.hasPermission('mes:wm-transaction:query')") public CommonResult> getTransactionPage(@Valid MesWmTransactionPageReqVO pageReqVO) { PageResult pageResult = transactionService.getTransactionPage(pageReqVO); if (pageResult.getTotal() == 0) { return success(PageResult.empty(pageResult.getTotal())); } // 关联查询物料信息 Map itemMap = mdmItemService.getItemMap( convertSet(pageResult.getList(), MesWmTransactionDO::getItemId)); // 关联查询物料类别信息 Map itemCategoryMap = mdmItemCategoryApi.getItemCategoryList( convertSet(itemMap.values(), MesMdmItemDO::getCategoryId)).getCheckedData().stream() .collect(Collectors.toMap(MdmItemCategoryRespDTO::getId, c -> c)); // 关联查询 MES 物料(品种同步生成),品种未维护规格/分类时回退使用 Set mdmItemIds = convertSet(itemMap.values(), MesMdmItemDO::getId); Map mesItemMap = mdmItemIds.isEmpty() ? Map.of() : mesMdItemMapper.selectList(MesMdItemDO::getMdmItemId, mdmItemIds).stream() .collect(Collectors.toMap(MesMdItemDO::getMdmItemId, i -> i, (a, b) -> a)); Set mesItemTypeIds = convertSet(mesItemMap.values(), MesMdItemDO::getItemTypeId); mesItemTypeIds.remove(null); Map mesItemTypeMap = mesItemTypeIds.isEmpty() ? Map.of() : mesMdItemTypeService.getItemTypeMap(mesItemTypeIds); // 关联查询仓库信息 Map warehouseMap = warehouseService.getWarehouseMap( convertSet(pageResult.getList(), MesWmTransactionDO::getWarehouseId)); // 关联查询库区信息 Map locationMap = locationService.getWarehouseLocationMap( convertSet(pageResult.getList(), MesWmTransactionDO::getLocationId)); // 关联查询库位信息 Map areaMap = areaService.getWarehouseAreaMap( convertSet(pageResult.getList(), MesWmTransactionDO::getAreaId)); var bagIds = convertSet(pageResult.getList(), MesWmTransactionDO::getBagCodeId); bagIds.remove(null); Map bagMap = bagIds.isEmpty() ? Map.of() : bagCodeMapper.selectBatchIds(bagIds) .stream().collect(Collectors.toMap(MesProBagCodeDO::getId, b -> b)); var salesIds = pageResult.getList().stream().filter(t -> Integer.valueOf(MesBizTypeConstants.WM_PRODUCT_SALES).equals(t.getBizType())) .map(MesWmTransactionDO::getBizId).filter(java.util.Objects::nonNull).collect(Collectors.toSet()); var details = salesDetailMapper.selectBySalesIdsAndBagIds(salesIds, bagIds); var palletIds = convertSet(details, MesWmProductSalesDetailDO::getPalletCodeId); palletIds.remove(null); Map pallets = palletIds.isEmpty() ? Map.of() : palletMapper.selectBatchIds(palletIds) .stream().collect(Collectors.toMap(MesProPalletDO::getId, p -> p)); Map detailMap = details.stream().collect(Collectors.toMap( d -> d.getSalesId() + ":" + d.getBagCodeId() + ":" + d.getShipmentId(), d -> d, (a, b) -> a)); // 转换为 VO List voList = pageResult.getList().stream().map(transaction -> { MesWmTransactionRespVO vo = BeanUtils.toBean(transaction, MesWmTransactionRespVO.class); MesProBagCodeDO bag = transaction.getBagCodeId() == null ? null : bagMap.get(transaction.getBagCodeId()); if ((vo.getBagCode() == null || vo.getBagCode().isBlank()) && bag != null) vo.setBagCode(bag.getCode()); if (Integer.valueOf(MesBizTypeConstants.WM_PRODUCT_SALES).equals(transaction.getBizType())) { MesWmProductSalesDetailDO detail = detailMap.get(transaction.getBizId() + ":" + transaction.getBagCodeId() + ":" + transaction.getShipmentId()); MesProPalletDO pallet = detail == null || detail.getPalletCodeId() == null ? null : pallets.get(detail.getPalletCodeId()); if (pallet != null) vo.setPalletCode(pallet.getCode()); } // 质检、生产入库等流水没有销售明细,托盘码回退取袋码当前绑定的托盘 if (StrUtil.isBlank(vo.getPalletCode()) && bag != null) { vo.setPalletCode(bag.getPalletCode()); } // 事务类型名称 MesWmTransactionTypeEnum typeEnum = MesWmTransactionTypeEnum.valueOf(transaction.getType()); vo.setTypeName(typeEnum != null ? typeEnum.getName() : "未知"); // 业务类型名称 vo.setBizTypeName(getBizTypeName(transaction.getBizType())); // 物料信息 MesMdmItemDO item = itemMap.get(transaction.getItemId()); if (item != null) { MesMdItemDO mesItem = mesItemMap.get(item.getId()); vo.setItemCode(item.getCode()); vo.setItemName(item.getName()); // 规格:品种管理未维护时,回退取 MES 物料规格型号 vo.setSpecification(StrUtil.blankToDefault(item.getSpecification(), mesItem != null ? mesItem.getSpecification() : null)); // 类别:优先品种分类,其次 MES 物料分类 MdmItemCategoryRespDTO category = itemCategoryMap.get(item.getCategoryId()); String itemTypeName = category != null ? category.getName() : null; if (StrUtil.isBlank(itemTypeName) && mesItem != null && mesItem.getItemTypeId() != null) { MesMdItemTypeDO itemType = mesItemTypeMap.get(mesItem.getItemTypeId()); if (itemType != null) { itemTypeName = itemType.getName(); } } vo.setItemTypeName(itemTypeName); } // 仓库信息 MesWmWarehouseDO warehouse = warehouseMap.get(transaction.getWarehouseId()); if (warehouse != null) { vo.setWarehouseName(warehouse.getName()); } // 库区信息 MesWmWarehouseLocationDO location = locationMap.get(transaction.getLocationId()); if (location != null) { vo.setLocationName(location.getName()); } // 库位信息 MesWmWarehouseAreaDO area = areaMap.get(transaction.getAreaId()); if (area != null) { vo.setAreaName(area.getName()); } return vo; }).collect(Collectors.toList()); return success(new PageResult<>(voList, pageResult.getTotal())); } /** * 获取业务类型名称 */ private String getBizTypeName(Integer bizType) { if (bizType == null) { return "未知"; } switch (bizType) { case MesBizTypeConstants.QC_SEED_QUALITY: return "种子质检"; case MesBizTypeConstants.WM_ITEM_RECEIPT_CANCEL: return "采购入库取消"; case MesBizTypeConstants.WM_STOCK_TAKING: return "盘点调整"; case MesBizTypeConstants.WM_STOCK_ADJUST_IN: return "自定义入库"; case MesBizTypeConstants.WM_STOCK_ADJUST_OUT: return "自定义出库"; case MesBizTypeConstants.WM_ITEM_RECEIPT_IN: return "采购入库"; case MesBizTypeConstants.WM_PRODUCT_SALES: return "销售出库"; case MesBizTypeConstants.WM_TRANSFER_IN: return "调拨入库"; case MesBizTypeConstants.WM_TRANSFER_OUT: return "调拨出库"; case MesBizTypeConstants.WM_MISC_RECPT: return "其他入库"; case MesBizTypeConstants.WM_MISC_ISSUE: return "其他出库"; case MesBizTypeConstants.WM_ISSUE: return "生产领料"; case MesBizTypeConstants.WM_RETURN_ISSUE: return "生产退料"; case MesBizTypeConstants.WM_PRODUCT_RECPT: return "生产入库"; case MesBizTypeConstants.WM_ITEM_CONSUME: return "生产消耗"; case MesBizTypeConstants.WM_PRODUCT_PRODUCE: return "产品产出"; case MesBizTypeConstants.WM_RETURN_VENDOR: return "供应商退货"; case MesBizTypeConstants.WM_RETURN_SALES: return "销售退货"; case MesBizTypeConstants.WM_OUTSOURCE_ISSUE: return "外协发料"; case MesBizTypeConstants.WM_OUTSOURCE_RECPT: return "外协入库"; default: return "未知类型(" + bizType + ")"; } } }