| | |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockAdjustReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockFreezeReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockMoveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockFreezeReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockListReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockBagPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockBagRespVO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstockbag.MesWmMaterialStockBagMapper; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmStockSummaryRespVO; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO; |
| | | import cn.iocoder.yudao.module.mdm.api.category.MdmItemCategoryApi; |
| | | import cn.iocoder.yudao.module.mdm.api.category.dto.MdmItemCategoryRespDTO; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.vendor.MesMdVendorDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstockbag.MesWmMaterialStockBagDO; |
| | | 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.mdm.api.unit.MdmUnitMeasureApi; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO; |
| | | |
| | | import cn.iocoder.yudao.module.mes.service.md.vendor.MesMdVendorService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService; |
| | |
| | | public class MesWmMaterialStockController { |
| | | |
| | | @Resource |
| | | private cn.iocoder.yudao.module.mes.dal.mysql.wm.transaction.MesWmTransactionMapper transactionMapper; |
| | | |
| | | @Resource |
| | | private MesWmMaterialStockService materialStockService; |
| | | @Resource |
| | | private MdmItemApi mdmItemApi; |
| | | @Resource |
| | | private MdmItemCategoryApi mdmItemCategoryApi; |
| | | @Resource |
| | | private MdmUnitMeasureApi mdmUnitMeasureApi; |
| | | @Resource |
| | |
| | | @Resource |
| | | private MesWmWarehouseAreaService areaService; |
| | | @Resource |
| | | private MesMdVendorService vendorService; |
| | | private SrmSupplierApi srmSupplierApi; |
| | | @Resource |
| | | private MesWmMaterialStockBagMapper materialStockBagMapper; |
| | | @Resource |
| | | private cn.iocoder.yudao.module.mes.service.wm.productsales.MesWmProductSalesLineService productSalesLineService; |
| | | @Resource private cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesDetailMapper salesDetailMapper; |
| | | @Resource private cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesMapper salesMapper; |
| | | @Resource private cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesShipmentMapper shipmentMapper; |
| | | |
| | | @GetMapping("/picking-list") |
| | | @Operation(summary = "按销售出库单行查询合格库存") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-product-sales:stock') and @ss.hasPermission('mes:wm-material-stock:query')") |
| | | public CommonResult<List<MesWmMaterialStockRespVO>> getPickingStocks(@RequestParam("lineId") Long lineId) { |
| | | var line = productSalesLineService.getProductSalesLine(lineId); |
| | | if (line == null) throw new IllegalArgumentException("出库单行不存在"); |
| | | return success(buildRespVOList(materialStockService.getQualifiedMaterialStockListByItemAndBatch(line.getItemId(), line.getBatchId()))); |
| | | } |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "获得库存记录") |
| | |
| | | @Valid MesWmMaterialStockPageReqVO pageReqVO) { |
| | | PageResult<MesWmMaterialStockDO> pageResult = materialStockService.getMaterialStockPage(pageReqVO); |
| | | return success(new PageResult<>(buildRespVOList(pageResult.getList()), pageResult.getTotal())); |
| | | } |
| | | |
| | | @GetMapping("/bag-details") |
| | | @Operation(summary = "查询库存袋码明细") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-material-stock:query')") |
| | | public CommonResult<PageResult<MesWmMaterialStockBagRespVO>> getMaterialStockBagDetails( |
| | | @Valid MesWmMaterialStockBagPageReqVO pageReqVO) { |
| | | PageResult<MesWmMaterialStockBagRespVO> result = new PageResult<>(); |
| | | PageResult<cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstockbag.MesWmMaterialStockBagDO> page = |
| | | materialStockBagMapper.selectPage(pageReqVO); |
| | | var transactionIds = convertSet(page.getList(), cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstockbag.MesWmMaterialStockBagDO::getLastTransactionId); |
| | | Map<Long, cn.iocoder.yudao.module.mes.dal.dataobject.wm.transaction.MesWmTransactionDO> transactions = transactionIds.isEmpty() |
| | | ? Collections.emptyMap() : transactionMapper.selectBatchIds(transactionIds).stream() |
| | | .collect(Collectors.toMap(cn.iocoder.yudao.module.mes.dal.dataobject.wm.transaction.MesWmTransactionDO::getId, tx -> tx)); |
| | | var rows = BeanUtils.toBean(page.getList(), MesWmMaterialStockBagRespVO.class); |
| | | var bagIds = convertSet(page.getList(), cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstockbag.MesWmMaterialStockBagDO::getBagCodeId); |
| | | var pickingDetails = salesDetailMapper.selectByBagIds(bagIds); |
| | | var saleIds = convertSet(pickingDetails, cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO::getSalesId); |
| | | var shipmentIds = convertSet(pickingDetails, cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDetailDO::getShipmentId); |
| | | var saleMap = saleIds.isEmpty() ? Collections.<Long, cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDO>emptyMap() |
| | | : salesMapper.selectBatchIds(saleIds).stream().collect(Collectors.toMap(cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDO::getId, s -> s)); |
| | | var shipmentMap = shipmentIds.isEmpty() ? Collections.<Long, cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesShipmentDO>emptyMap() |
| | | : shipmentMapper.selectBatchIds(shipmentIds).stream().collect(Collectors.toMap(cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesShipmentDO::getId, s -> s)); |
| | | Map<Long, String> pickingByBag = new java.util.HashMap<>(); |
| | | for (var detail : pickingDetails) { |
| | | var sale = saleMap.get(detail.getSalesId()); |
| | | var shipment = detail.getShipmentId() == null ? null : shipmentMap.get(detail.getShipmentId()); |
| | | if (sale == null) continue; |
| | | if (detail.getShipmentId() == null && Integer.valueOf(2).equals(sale.getStatus())) pickingByBag.putIfAbsent(detail.getBagCodeId(), "PICKED"); |
| | | else if ((detail.getShipmentId() == null && (Integer.valueOf(10).equals(sale.getStatus()) || Integer.valueOf(3).equals(sale.getStatus()))) |
| | | || (shipment != null && (Integer.valueOf(10).equals(shipment.getStatus()) || Integer.valueOf(20).equals(shipment.getStatus())))) pickingByBag.put(detail.getBagCodeId(), "RESERVED"); |
| | | } |
| | | for (int i = 0; i < rows.size(); i++) { |
| | | var bag = page.getList().get(i); |
| | | var tx = bag.getLastTransactionId() == null ? null : transactions.get(bag.getLastTransactionId()); |
| | | if (Integer.valueOf(2).equals(bag.getStatus()) && tx != null && Integer.valueOf(2).equals(tx.getType())) { |
| | | rows.get(i).setOutboundBizType(tx.getBizType()); |
| | | } |
| | | if (Integer.valueOf(1).equals(bag.getStatus())) rows.get(i).setPickingStatus(pickingByBag.get(bag.getBagCodeId())); |
| | | } |
| | | return success(new PageResult<>(rows, page.getTotal())); |
| | | } |
| | | |
| | | @PutMapping("/update-frozen") |
| | |
| | | return success(materialStockService.adjustMaterialStockOut(reqVO)); |
| | | } |
| | | |
| | | @PostMapping("/move") |
| | | @Operation(summary = "库存移库") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-material-stock:update')") |
| | | public CommonResult<Boolean> moveMaterialStock(@Valid @RequestBody MesWmMaterialStockMoveReqVO reqVO) { |
| | | materialStockService.moveMaterialStock(reqVO); |
| | | return success(true); |
| | | } |
| | | |
| | | @GetMapping("/summary-by-item") |
| | | @Operation(summary = "按品种汇总库存数量") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-material-stock:query')") |
| | | public CommonResult<List<MesWmStockSummaryRespVO>> getStockSummaryByItem( |
| | | MesWmMaterialStockListReqVO reqVO) { |
| | | return success(materialStockService.getStockSummaryByItem(reqVO)); |
| | | } |
| | | |
| | | @GetMapping("/summary-by-batch") |
| | | @Operation(summary = "按批次汇总库存数量") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-material-stock:query')") |
| | | public CommonResult<List<MesWmStockSummaryRespVO>> getStockSummaryByBatch( |
| | | MesWmMaterialStockListReqVO reqVO) { |
| | | return success(materialStockService.getStockSummaryByBatch(reqVO)); |
| | | } |
| | | |
| | | @GetMapping("/summary-by-warehouse") |
| | | @Operation(summary = "按仓库汇总库存数量") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-material-stock:query')") |
| | | public CommonResult<List<MesWmStockSummaryRespVO>> getStockSummaryByWarehouse( |
| | | MesWmMaterialStockListReqVO reqVO) { |
| | | return success(materialStockService.getStockSummaryByWarehouse(reqVO)); |
| | | } |
| | | |
| | | @GetMapping("/export-excel") |
| | | @Operation(summary = "导出库存台账 Excel") |
| | | @PreAuthorize("@ss.hasPermission('mes:wm-material-stock:export')") |
| | |
| | | // 1. 获得关联数据 |
| | | Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap( |
| | | convertSet(list, MesWmMaterialStockDO::getItemId)); |
| | | Map<Long, MdmItemCategoryRespDTO> itemCategoryMap = mdmItemCategoryApi.getItemCategoryList( |
| | | convertSet(itemMap.values(), MdmItemRespDTO::getCategoryId)).getCheckedData().stream() |
| | | .collect(Collectors.toMap(MdmItemCategoryRespDTO::getId, c -> c)); |
| | | Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList( |
| | | convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData() |
| | | .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e)); |
| | |
| | | convertSet(list, MesWmMaterialStockDO::getLocationId)); |
| | | Map<Long, MesWmWarehouseAreaDO> areaMap = areaService.getWarehouseAreaMap( |
| | | convertSet(list, MesWmMaterialStockDO::getAreaId)); |
| | | Map<Long, MesMdVendorDO> vendorMap = vendorService.getVendorMap( |
| | | convertSet(list, MesWmMaterialStockDO::getVendorId)); |
| | | List<MesWmMaterialStockBagDO> bagHistory = materialStockBagMapper.selectHistoryByMaterialStockIds( |
| | | convertSet(list, MesWmMaterialStockDO::getId)); |
| | | Map<Long, Long> bagCountMap = bagHistory.stream().filter(bag -> Integer.valueOf(1).equals(bag.getStatus())) |
| | | .collect(Collectors.groupingBy(MesWmMaterialStockBagDO::getMaterialStockId, Collectors.counting())); |
| | | var stockIdsWithBagHistory = convertSet(bagHistory, MesWmMaterialStockBagDO::getMaterialStockId); |
| | | Map<Long, SrmSupplierRespDTO> vendorMap = srmSupplierApi.getSupplierList( |
| | | convertSet(list, MesWmMaterialStockDO::getVendorId)).getCheckedData().stream() |
| | | .collect(Collectors.toMap(SrmSupplierRespDTO::getId, s -> s)); |
| | | // 2. 构建结果 |
| | | return BeanUtils.toBean(list, MesWmMaterialStockRespVO.class, vo -> { |
| | | MapUtils.findAndThen(itemMap, vo.getItemId(), item -> { |
| | | vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()); |
| | | MapUtils.findAndThen(itemCategoryMap, item.getCategoryId(), |
| | | category -> vo.setItemTypeName(category.getName())); |
| | | MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(), |
| | | unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName())); |
| | | }); |
| | |
| | | area -> vo.setAreaName(area.getName())); |
| | | MapUtils.findAndThen(vendorMap, vo.getVendorId(), |
| | | vendor -> vo.setVendorName(vendor.getName())); |
| | | vo.setBagCount(bagCountMap.getOrDefault(vo.getId(), 0L)); |
| | | vo.setBagDetailSupported(stockIdsWithBagHistory.contains(vo.getId())); |
| | | // 计算可用量 = 在库数量 - 冻结数量 - 占用量 |
| | | BigDecimal quantity = vo.getQuantity() != null ? vo.getQuantity() : BigDecimal.ZERO; |
| | | BigDecimal frozenQty = vo.getFrozenQuantity() != null ? vo.getFrozenQuantity() : BigDecimal.ZERO; |