diff --git a/yudao-module-common/yudao-module-common-biz/src/main/java/cn/iocoder/yudao/module/common/controller/admin/mold/vo/MoldBrandPageReqVO.java b/yudao-module-common/yudao-module-common-biz/src/main/java/cn/iocoder/yudao/module/common/controller/admin/mold/vo/MoldBrandPageReqVO.java index a2e2c28ff..684ada1b1 100644 --- a/yudao-module-common/yudao-module-common-biz/src/main/java/cn/iocoder/yudao/module/common/controller/admin/mold/vo/MoldBrandPageReqVO.java +++ b/yudao-module-common/yudao-module-common-biz/src/main/java/cn/iocoder/yudao/module/common/controller/admin/mold/vo/MoldBrandPageReqVO.java @@ -50,6 +50,9 @@ public class MoldBrandPageReqVO extends PageParam { @Schema(description = "设备名称", example = "注塑机") private String deviceName; + @Schema(description = "当前设备,模糊匹配设备名称", example = "注塑机") + private String currentDevice; + @Schema(description = "预期寿命(小时)") private BigDecimal useTime; diff --git a/yudao-module-common/yudao-module-common-biz/src/main/java/cn/iocoder/yudao/module/common/enums/QrcodeBizTypeEnum.java b/yudao-module-common/yudao-module-common-biz/src/main/java/cn/iocoder/yudao/module/common/enums/QrcodeBizTypeEnum.java index 2a87cb0a0..b16f2c0f1 100644 --- a/yudao-module-common/yudao-module-common-biz/src/main/java/cn/iocoder/yudao/module/common/enums/QrcodeBizTypeEnum.java +++ b/yudao-module-common/yudao-module-common-biz/src/main/java/cn/iocoder/yudao/module/common/enums/QrcodeBizTypeEnum.java @@ -13,7 +13,8 @@ public enum QrcodeBizTypeEnum { KEY_PART("KEY_PART", "关键件"), MOLD("MOLD", "模具"), PALLET("PALLET", "托盘"), - SPARE("SPARE", "备件"); + SPARE("SPARE", "备件"), + WAREHOUSE_AREA("WAREHOUSE_AREA", "库区"); private final String code; private final String name; diff --git a/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java b/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java index fece8bd8f..4ae100ad6 100644 --- a/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java +++ b/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/ErrorCodeConstants.java @@ -153,6 +153,13 @@ public interface ErrorCodeConstants { ErrorCode STOCK_MOVE_APPROVE_FAIL = new ErrorCode(1_030_402_003, "审核失败,只有未审核的调拨单才能审核"); ErrorCode STOCK_MOVE_NO_EXISTS = new ErrorCode(1_030_402_004, "生成调拨号失败,请重新提交"); ErrorCode STOCK_MOVE_UPDATE_FAIL_APPROVE = new ErrorCode(1_030_402_005, "库存调拨单({})已审核,无法修改"); + ErrorCode STOCK_MOVE_UPDATE_FAIL_PROCESS = new ErrorCode(1_030_402_006, "库存调拨单({})审核中,无法修改"); + ErrorCode STOCK_MOVE_DELETE_FAIL_PROCESS = new ErrorCode(1_030_402_007, "库存调拨单({})审核中,无法删除"); + ErrorCode STOCK_MOVE_SUBMIT_FAIL_STATUS = new ErrorCode(1_030_402_008, "提交审核失败,只有待提交或已驳回的调拨单才能提交"); + ErrorCode STOCK_MOVE_SUBMIT_FAIL_USER = new ErrorCode(1_030_402_009, "提交审核失败,只有创建人才能提交审核"); + ErrorCode STOCK_MOVE_AUDIT_FAIL_STATUS = new ErrorCode(1_030_402_010, "审核失败,只有审核中的调拨单才能审核"); + ErrorCode STOCK_MOVE_AUDIT_FAIL_USER = new ErrorCode(1_030_402_011, "审核失败,当前用户不是指定审核人"); + ErrorCode STOCK_MOVE_AUDIT_FAIL_RESULT = new ErrorCode(1_030_402_012, "审核失败,审核结果只支持通过或驳回"); // ========== ERP 库存盘点单 1-030-403-000 ========== ErrorCode STOCK_CHECK_NOT_EXISTS = new ErrorCode(1_030_403_000, "库存盘点单不存在"); diff --git a/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockMoveApproveActionEnum.java b/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockMoveApproveActionEnum.java new file mode 100644 index 000000000..ebdd73ea3 --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockMoveApproveActionEnum.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.erp.enums.stock; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Getter +public enum ErpStockMoveApproveActionEnum { + + SUBMIT("SUBMIT"), + APPROVE("APPROVE"), + REJECT("REJECT"), + AUTO_APPROVE("AUTO_APPROVE"); + + private final String actionType; + +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductController.java index 7b0931318..3531d5b7b 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductController.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/product/ErpProductController.java @@ -118,8 +118,9 @@ public class ErpProductController { } @GetMapping("/simple-list-all") @Operation(summary = "获得所有精简列表", description = "只包含被开启的产品,主要用于前端的下拉选项") - public CommonResult> getAllSimpleList(@RequestParam(name = "categoryId", required = false) Integer categoryId) { - List list = productService.getProductVOListByStatus(CommonStatusEnum.ENABLE.getStatus(),categoryId); + public CommonResult> getAllSimpleList(@RequestParam(name = "categoryId", required = false) Integer categoryId, + @RequestParam(name = "categoryType", required = false) Integer categoryType) { + List list = productService.getProductVOListByStatus(CommonStatusEnum.ENABLE.getStatus(), categoryId, categoryType); return success(convertList(list, product -> new ErpProductRespVO().setId(product.getId()) .setName(product.getName()).setBarCode(product.getBarCode()) .setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName()) diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockCheckController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockCheckController.java index f14d657af..41ca08aab 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockCheckController.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockCheckController.java @@ -10,16 +10,10 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter; +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckApproveRecordRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckAuditReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckGenerateByLocationReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckGenerateByProductReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckPageReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckRespVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckSaveReqVO; -import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckSubmitReqVO; +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.*; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckApproveRecordDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckItemDO; @@ -186,6 +180,64 @@ public class ErpStockCheckController { ExcelUtils.write(response, "库存盘点单.xls", "数据", ErpStockCheckRespVO.class, list); } + @GetMapping("/record-page") + @Operation(summary = "获得库存盘点记录分页") + @PreAuthorize("@ss.hasPermission('erp:stock-check:query')") + public CommonResult> getStockCheckRecordPage( + @Valid ErpStockCheckRecordPageReqVO pageReqVO) { + return success(buildStockCheckRecordVOPageResult(stockCheckService.getStockCheckRecordPage(pageReqVO))); + } + + @GetMapping("/record-export-excel") + @Operation(summary = "导出库存盘点记录 Excel") + @PreAuthorize("@ss.hasPermission('erp:stock-check:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportStockCheckRecordExcel(@Valid ErpStockCheckRecordPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = buildStockCheckRecordVOPageResult( + stockCheckService.getStockCheckRecordPage(pageReqVO)).getList(); + ExcelUtils.write(response, "库存盘点记录.xls", "数据", ErpStockCheckRecordRespVO.class, list); + } + + private PageResult buildStockCheckRecordVOPageResult(PageResult pageResult) { + if (CollUtil.isEmpty(pageResult.getList())) { + return PageResult.empty(pageResult.getTotal()); + } + Map stockCheckMap = stockCheckService.getStockCheckMap( + convertSet(pageResult.getList(), ErpStockCheckItemDO::getCheckId)); + Map productMap = productService.getProductVOMap( + convertSet(pageResult.getList(), ErpStockCheckItemDO::getProductId)); + Map unitMap = productUnitService.getProductUnitMap(convertSet(productMap.values(), ErpProductRespVO::getUnitId)); + Map warehouseMap = warehouseService.getWarehouseMap( + convertSet(pageResult.getList(), ErpStockCheckItemDO::getWarehouseId)); + Map areaMap = warehouseAreaService.getWarehouseAreaMap( + convertSet(pageResult.getList(), ErpStockCheckItemDO::getAreaId)); + Map userMap = adminUserApi.getUserMap(convertListByFlatMap(stockCheckMap.values(), + stockCheck -> Stream.of(NumberUtils.parseLong(stockCheck.getCreator())))); + return BeanUtils.toBean(pageResult, ErpStockCheckRecordRespVO.class, record -> { + MapUtils.findAndThen(stockCheckMap, record.getCheckId(), stockCheck -> { + record.setNo(stockCheck.getNo()) + .setCheckTime(stockCheck.getCheckTime()) + .setSourceType(stockCheck.getSourceType()) + .setCategoryType(stockCheck.getCategoryType()) + .setCheckStatus(stockCheck.getCheckStatus()) + .setStatus(stockCheck.getStatus()) + .setCreator(stockCheck.getCreator()) + .setCreateTime(stockCheck.getCreateTime()); + MapUtils.findAndThen(userMap, NumberUtils.parseLong(stockCheck.getCreator()), user -> record.setCreatorName(user.getNickname())); + }); + MapUtils.findAndThen(productMap, record.getProductId(), product -> record.setProductName(product.getName()) + .setProductBarCode(product.getBarCode()).setCategoryName(product.getCategoryName())); + MapUtils.findAndThen(productMap, record.getProductId(), product -> + MapUtils.findAndThen(unitMap, product.getUnitId(), unit -> record.setProductUnitName(unit.getName()))); + MapUtils.findAndThen(warehouseMap, record.getWarehouseId(), warehouse -> record.setWarehouseName(warehouse.getName())); + if (record.getAreaName() == null) { + MapUtils.findAndThen(areaMap, record.getAreaId(), area -> record.setAreaName(area.getAreaName())); + } + }); + } + private PageResult buildStockCheckVOPageResult(PageResult pageResult) { if (CollUtil.isEmpty(pageResult.getList())) { return PageResult.empty(pageResult.getTotal()); diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockController.java index 0139d80a9..a7b17f868 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockController.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockController.java @@ -38,11 +38,13 @@ import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; import java.math.BigDecimal; -import java.math.RoundingMode; import java.util.Collections; import java.util.HashMap; +import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; @@ -95,8 +97,10 @@ public class ErpStockController { @Operation(summary = "获得产品库存分页") @PreAuthorize("@ss.hasPermission('erp:stock:query')") public CommonResult> getStockPage(@Valid ErpStockPageReqVO pageReqVO) { - PageResult pageResult = stockService.getStockPage(pageReqVO); - return success(buildStockVOPageResult(pageResult)); + ErpStockPageReqVO queryReqVO = BeanUtils.toBean(pageReqVO, ErpStockPageReqVO.class); + queryReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + PageResult groupedResult = buildStockVOPageResult(stockService.getStockPage(queryReqVO)); + return success(new PageResult<>(paginateStockList(groupedResult.getList(), pageReqVO), groupedResult.getTotal())); } @GetMapping("/export-excel") @@ -121,7 +125,7 @@ public class ErpStockController { Map areaMap = warehouseAreaService.getWarehouseAreaMap( convertSet(pageResult.getList(), ErpStockDO::getAreaId)); Map palletCountMap = buildPalletCountMap(pageResult.getList()); - return BeanUtils.toBean(pageResult, ErpStockRespVO.class, stock -> { + PageResult respPageResult = BeanUtils.toBean(pageResult, ErpStockRespVO.class, stock -> { MapUtils.findAndThen(productMap, stock.getProductId(), product -> { stock.setProductName(product.getName()).setBarCode(product.getBarCode()) .setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName()) @@ -138,6 +142,8 @@ public class ErpStockController { } fillRecentRecordTime(stock); }); + List mergedList = mergeStockByProductAndWarehouse(respPageResult.getList()); + return new PageResult<>(mergedList, (long) mergedList.size()); } private ErpStockRespVO buildStockRespVO(ErpStockDO stock) { @@ -177,6 +183,79 @@ public class ErpStockController { return respVO; } + private List mergeStockByProductAndWarehouse(List stockList) { + if (CollUtil.isEmpty(stockList)) { + return Collections.emptyList(); + } + Map mergedMap = new LinkedHashMap<>(); + stockList.forEach(stock -> { + String key = buildStockGroupKey(stock.getProductId(), stock.getWarehouseId()); + ErpStockRespVO merged = mergedMap.computeIfAbsent(key, item -> { + ErpStockRespVO target = BeanUtils.toBean(stock, ErpStockRespVO.class); + target.setId(null); + target.setAreaId(null); + target.setAreaName(null); + target.setCount(BigDecimal.ZERO); + target.setPalletCount(0L); + target.setAreaStocks(new ArrayList<>()); + return target; + }); + merged.setCount(defaultZero(merged.getCount()).add(defaultZero(stock.getCount()))); + merged.setPalletCount((merged.getPalletCount() == null ? 0L : merged.getPalletCount()) + + (stock.getPalletCount() == null ? 0L : stock.getPalletCount())); + merged.getAreaStocks().add(buildAreaStock(stock)); + if (merged.getRecentInTime() == null || stock.getRecentInTime() != null + && stock.getRecentInTime().isAfter(merged.getRecentInTime())) { + merged.setRecentInTime(stock.getRecentInTime()); + } + if (merged.getRecentOutTime() == null || stock.getRecentOutTime() != null + && stock.getRecentOutTime().isAfter(merged.getRecentOutTime())) { + merged.setRecentOutTime(stock.getRecentOutTime()); + } + }); + mergedMap.values().forEach(stock -> { + stock.setTotalBaseCount(stock.getCount()); + stock.setTotalPackageCount(calculatePackageCount(stock, stock.getCount())); + stock.setPackagingRule(buildPackagingRule(stock)); + stock.setStockDisplay(buildStockDisplay(stock)); + }); + return new ArrayList<>(mergedMap.values()); + } + + private List paginateStockList(List list, PageParam pageReqVO) { + if (CollUtil.isEmpty(list) || Objects.equals(pageReqVO.getPageSize(), PageParam.PAGE_SIZE_NONE)) { + return list; + } + int fromIndex = (pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize(); + if (fromIndex >= list.size()) { + return Collections.emptyList(); + } + int toIndex = Math.min(fromIndex + pageReqVO.getPageSize(), list.size()); + return list.subList(fromIndex, toIndex); + } + + private ErpStockRespVO.AreaStock buildAreaStock(ErpStockRespVO stock) { + ErpStockRespVO.AreaStock areaStock = new ErpStockRespVO.AreaStock(); + areaStock.setAreaId(stock.getAreaId()); + areaStock.setAreaName(stock.getAreaName()); + areaStock.setCount(defaultZero(stock.getCount())); + areaStock.setPackageCount(calculatePackageCount(stock, stock.getCount())); + areaStock.setBaseCount(calculateBaseCount(stock, stock.getCount())); + areaStock.setStockDisplay(buildAreaStockDisplay(stock, areaStock)); + return areaStock; + } + + private String buildAreaStockDisplay(ErpStockRespVO stock, ErpStockRespVO.AreaStock areaStock) { + String prefix = areaStock.getAreaName() != null ? areaStock.getAreaName() + ":" : ""; + String countDisplay = "(" + formatNumber(areaStock.getCount()) + nullToEmpty(stock.getUnitName()) + ")"; + if (isProductType(stock.getCategoryType())) { + return prefix + formatNumber(areaStock.getPackageCount()) + "包" + + formatNumber(areaStock.getBaseCount()) + stock.getUnitName() + countDisplay; + } + return prefix + formatNumber(areaStock.getPackageCount()) + nullToEmpty(stock.getPurchaseUnitName()) + + formatNumber(areaStock.getBaseCount()) + nullToEmpty(stock.getUnitName()) + countDisplay; + } + private void fillRecentRecordTime(ErpStockRespVO stock) { stock.setRecentInTime(stockRecordService.getLatestRecordTime( stock.getProductId(), stock.getWarehouseId(), stock.getAreaId(), true)); @@ -188,24 +267,32 @@ public class ErpStockController { if (stock.getUnitId() == null) { stock.setUnitId(product.getUnitId()); } + stock.setUnitName(product.getUnitName()); if (stock.getPurchaseUnitId() == null) { stock.setPurchaseUnitId(product.getPurchaseUnitId()); } - if (stock.getPurchaseUnitName() == null) { - stock.setPurchaseUnitName(product.getPurchaseUnitName()); - } - if (stock.getPurchaseUnitConvertQuantity() == null) { - stock.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity()); - } - if (stock.getDefaultPackagingSchemeId() == null) { - stock.setDefaultPackagingSchemeId(product.getDefaultPackagingSchemeId()); - } + stock.setPurchaseUnitName(product.getPurchaseUnitName()); + stock.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity()); + stock.setDefaultPackagingSchemeId(product.getDefaultPackagingSchemeId()); if (stock.getDefaultPackagingScheme() == null) { stock.setDefaultPackagingScheme(findDefaultPackagingScheme(product)); } } private void fillPackagingSnapshot(ErpStockRespVO stock, ErpProductRespVO product) { + if (isProductType(stock.getCategoryType())) { + ProductPackagingSchemeRespVO defaultScheme = findDefaultPackagingScheme(product); + if (defaultScheme == null) { + return; + } + stock.setDefaultPackagingSchemeId(defaultScheme.getPackagingSchemeId()); + stock.setDefaultPackagingScheme(defaultScheme); + stock.setDefaultPackagingSchemeName(defaultScheme.getPackagingSchemeName()); + stock.setPackageQuantity(defaultScheme.getPackageQuantity()); + stock.setPalletPackageQuantity(defaultScheme.getPalletPackageQuantity()); + stock.setPalletTotalQuantity(defaultScheme.getPalletTotalQuantity()); + return; + } if (stock.getDefaultPackagingSchemeName() != null && stock.getPackageQuantity() != null && stock.getPalletPackageQuantity() != null @@ -273,9 +360,10 @@ public class ErpStockController { if (stock.getPackageQuantity() == null || stock.getPackageQuantity().compareTo(BigDecimal.ZERO) <= 0) { return formatNumber(stock.getCount()) + stock.getUnitName(); } - BigDecimal packageCount = stock.getCount().divide(stock.getPackageQuantity(), 0, RoundingMode.CEILING); + BigDecimal packageCount = calculatePackageCount(stock, stock.getCount()); + BigDecimal baseCount = calculateBaseCount(stock, stock.getCount()); return formatNumber(BigDecimal.valueOf(stock.getPalletCount() != null ? stock.getPalletCount() : 0L)) + "\u6258" - + formatNumber(packageCount) + "\u5305" + formatNumber(stock.getCount()) + stock.getUnitName(); + + formatNumber(packageCount) + "\u5305" + formatNumber(baseCount) + stock.getUnitName(); } if (stock.getPurchaseUnitConvertQuantity() == null || stock.getPurchaseUnitConvertQuantity().compareTo(BigDecimal.ZERO) <= 0 || stock.getPurchaseUnitName() == null || stock.getUnitName() == null) { @@ -306,6 +394,37 @@ public class ErpStockController { display.append(formatNumber(quantity)).append(unitName); } + private BigDecimal calculatePackageCount(ErpStockRespVO stock, BigDecimal count) { + BigDecimal convertQuantity = getDisplayConvertQuantity(stock); + if (convertQuantity == null || convertQuantity.compareTo(BigDecimal.ZERO) <= 0) { + return BigDecimal.ZERO; + } + return defaultZero(count).divideToIntegralValue(convertQuantity); + } + + private BigDecimal calculateBaseCount(ErpStockRespVO stock, BigDecimal count) { + BigDecimal convertQuantity = getDisplayConvertQuantity(stock); + if (convertQuantity == null || convertQuantity.compareTo(BigDecimal.ZERO) <= 0) { + return defaultZero(count); + } + return defaultZero(count).remainder(convertQuantity); + } + + private BigDecimal getDisplayConvertQuantity(ErpStockRespVO stock) { + if (isProductType(stock.getCategoryType())) { + return stock.getPackageQuantity(); + } + return stock.getPurchaseUnitConvertQuantity(); + } + + private BigDecimal defaultZero(BigDecimal value) { + return value != null ? value : BigDecimal.ZERO; + } + + private String nullToEmpty(String value) { + return value != null ? value : ""; + } + private boolean isProductType(Integer categoryType) { return Integer.valueOf(1).equals(categoryType); } @@ -332,6 +451,10 @@ public class ErpStockController { return String.valueOf(productId) + "_" + String.valueOf(warehouseId) + "_" + String.valueOf(areaId); } + private String buildStockGroupKey(Long productId, Long warehouseId) { + return String.valueOf(productId) + "_" + String.valueOf(warehouseId); + } + private String formatNumber(BigDecimal value) { return value == null ? "0" : value.stripTrailingZeros().toPlainString(); } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockInController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockInController.java index 78be661fc..789bac398 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockInController.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockInController.java @@ -179,7 +179,6 @@ public class ErpStockInController { @PreAuthorize("@ss.hasPermission('erp:stock-in:query')") public CommonResult> getStockInPage(@Valid ErpStockInPageReqVO pageReqVO) { fillPageReqDefault(pageReqVO); - applyItemFilter(pageReqVO); return success(buildStockInVOPageResult(stockInService.getStockInPage(pageReqVO))); } @@ -190,34 +189,11 @@ public class ErpStockInController { public void exportStockInExcel(@Valid ErpStockInPageReqVO pageReqVO, HttpServletResponse response) throws IOException { fillPageReqDefault(pageReqVO); - applyItemFilter(pageReqVO); pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); List list = buildStockInVOPageResult(stockInService.getStockInPage(pageReqVO)).getList(); ExcelUtils.write(response, "其它入库单.xls", "数据", ErpStockInRespVO.class, list); } - private void applyItemFilter(ErpStockInPageReqVO pageReqVO) { - if (pageReqVO.getProductId() == null && pageReqVO.getWarehouseId() == null) { - return; - } - List ids = stockInService.getStockInIdsByItemFilter(pageReqVO.getProductId(), pageReqVO.getWarehouseId()); - if (StringUtils.isNotBlank(pageReqVO.getIds())) { - List reqIds = Stream.of(pageReqVO.getIds().split(",")) - .map(String::trim) - .filter(StringUtils::isNotBlank) - .map(Long::valueOf) - .collect(Collectors.toList()); - ids = ids.stream().filter(reqIds::contains).collect(Collectors.toList()); - } - if (CollUtil.isEmpty(ids)) { - pageReqVO.setIds("-1"); - return; - } - pageReqVO.setIds(CollUtil.join(ids, ",")); - pageReqVO.setProductId(null); - pageReqVO.setWarehouseId(null); - } - private void fillPageReqDefault(ErpStockInPageReqVO pageReqVO) { if (StringUtils.isEmpty(pageReqVO.getInType())) { List list = new ArrayList<>(); @@ -341,8 +317,11 @@ public class ErpStockInController { item.setProductBarCode(product.getBarCode()); item.setProductUnitName(product.getUnitName()); item.setCategoryType(product.getCategoryType()); - item.setSupplierId(product.getDefaultSupplierId()); - if (product.getDefaultSupplierId() != null && CollUtil.isNotEmpty(product.getSuppliers())) { + if (item.getSupplierId() == null) { + item.setSupplierId(product.getDefaultSupplierId()); + } + if (StringUtils.isBlank(item.getSupplierName()) + && product.getDefaultSupplierId() != null && CollUtil.isNotEmpty(product.getSuppliers())) { product.getSuppliers().stream() .filter(supplier -> Objects.equals(supplier.getSupplierId(), product.getDefaultSupplierId())) .findFirst() diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockMoveController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockMoveController.java index 72d67d210..e69706e1e 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockMoveController.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockMoveController.java @@ -6,18 +6,30 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveApproveRecordRespVO; +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveAuditReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMovePageReqVO; +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveProductStockRespVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveRespVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveSaveReqVO; +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveSubmitReqVO; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveApproveRecordDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveItemDO; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO; +import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO; +import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockMoveService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; +import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService; +import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import io.swagger.v3.oas.annotations.Operation; @@ -32,11 +44,19 @@ import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.concurrent.TimeUnit; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @@ -52,6 +72,10 @@ public class ErpStockMoveController { private ErpStockService stockService; @Resource private ErpProductService productService; + @Resource + private ErpWarehouseService warehouseService; + @Resource + private WarehouseAreaService warehouseAreaService; @Resource private AdminUserApi adminUserApi; @@ -80,6 +104,42 @@ public class ErpStockMoveController { return success(true); } + @PutMapping("/submit") + @Operation(summary = "提交库存调拨单审核") + @PreAuthorize("@ss.hasPermission('erp:stock-move:submit')") + @RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS) + public CommonResult submitStockMoveAudit(@Valid @RequestBody ErpStockMoveSubmitReqVO submitReqVO) { + stockMoveService.submitStockMoveAudit(submitReqVO); + return success(true); + } + + @PutMapping("/audit") + @Operation(summary = "审核库存调拨单") + @PreAuthorize("@ss.hasPermission('erp:stock-move:audit')") + @RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS) + public CommonResult auditStockMove(@Valid @RequestBody ErpStockMoveAuditReqVO auditReqVO) { + stockMoveService.auditStockMove(auditReqVO); + return success(true); + } + + @GetMapping("/approve-record-list") + @Operation(summary = "获得库存调拨单审核记录") + @PreAuthorize("@ss.hasPermission('erp:stock-move:query')") + public CommonResult> getApproveRecordList(@RequestParam("id") Long id) { + return success(buildApproveRecordRespList(stockMoveService.getStockMoveApproveRecordList(id))); + } + + @GetMapping("/product-stock-list") + @Operation(summary = "获得产品仓库库区库存列表") + @PreAuthorize("@ss.hasPermission('erp:stock-move:query')") + public CommonResult> getProductStockList( + @RequestParam("productId") Long productId, + @RequestParam(value = "warehouseId", required = false) Long warehouseId) { + List stockList = stockService.getStockList(Collections.singleton(productId), + warehouseId == null ? Collections.emptySet() : Collections.singleton(warehouseId), Collections.emptySet()); + return success(buildProductStockRespList(stockList)); + } + @DeleteMapping("/delete") @Operation(summary = "删除库存调拨单") @Parameter(name = "ids", description = "编号数组", required = true) @@ -98,16 +158,9 @@ public class ErpStockMoveController { if (stockMove == null) { return success(null); } - List stockMoveItemList = stockMoveService.getStockMoveItemListByMoveId(id); - Map productMap = productService.getProductVOMap( - convertSet(stockMoveItemList, ErpStockMoveItemDO::getProductId)); - return success(BeanUtils.toBean(stockMove, ErpStockMoveRespVO.class, stockMoveVO -> - stockMoveVO.setItems(BeanUtils.toBean(stockMoveItemList, ErpStockMoveRespVO.Item.class, item -> { - ErpStockDO stock = stockService.getStock(item.getProductId(), item.getFromWarehouseId()); - item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO); - MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())); - })))); + return success(buildStockMoveRespVO(stockMove, + stockMoveService.getStockMoveItemListByMoveId(id), + stockMoveService.getStockMoveApproveRecordList(id))); } @GetMapping("/page") @@ -134,27 +187,135 @@ public class ErpStockMoveController { if (CollUtil.isEmpty(pageResult.getList())) { return PageResult.empty(pageResult.getTotal()); } - // 1.1 调拨项 + List stockMoves = pageResult.getList(); List stockMoveItemList = stockMoveService.getStockMoveItemListByMoveIds( - convertSet(pageResult.getList(), ErpStockMoveDO::getId)); + convertSet(stockMoves, ErpStockMoveDO::getId)); Map> stockMoveItemMap = convertMultiMap(stockMoveItemList, ErpStockMoveItemDO::getMoveId); - // 1.2 产品信息 Map productMap = productService.getProductVOMap( convertSet(stockMoveItemList, ErpStockMoveItemDO::getProductId)); - // 1.3 TODO 芋艿:搞仓库信息 - // 1.4 管理员信息 - Map userMap = adminUserApi.getUserMap( - convertSet(pageResult.getList(), stockMove -> Long.parseLong(stockMove.getCreator()))); - // 2. 开始拼接 + Map warehouseMap = warehouseService.getWarehouseMap(convertListByFlatMap(stockMoveItemList, + item -> Stream.of(item.getFromWarehouseId(), item.getToWarehouseId()))); + Map areaMap = warehouseAreaService.getWarehouseAreaMap(convertListByFlatMap(stockMoveItemList, + item -> Stream.of(item.getFromAreaId(), item.getToAreaId()))); + Map stockMap = buildStockMap(stockMoveItemList); + Map userMap = adminUserApi.getUserMap(convertListByFlatMap(stockMoves, + stockMove -> Stream.of(NumberUtils.parseLong(stockMove.getCreator()), stockMove.getAuditUserId()))); return BeanUtils.toBean(pageResult, ErpStockMoveRespVO.class, stockMove -> { stockMove.setItems(BeanUtils.toBean(stockMoveItemMap.get(stockMove.getId()), ErpStockMoveRespVO.Item.class, - item -> MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) - .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())))); + item -> fillStockMoveItem(item, productMap, warehouseMap, areaMap, stockMap))); stockMove.setProductNames(CollUtil.join(stockMove.getItems(), ",", ErpStockMoveRespVO.Item::getProductName)); - // TODO 芋艿: -// MapUtils.findAndThen(customerMap, stockMove.getCustomerId(), supplier -> stockMove.setCustomerName(supplier.getName())); - MapUtils.findAndThen(userMap, Long.parseLong(stockMove.getCreator()), user -> stockMove.setCreatorName(user.getNickname())); + stockMove.setStatusName(getAuditStatusName(stockMove.getStatus())); + MapUtils.findAndThen(userMap, NumberUtils.parseLong(stockMove.getCreator()), user -> stockMove.setCreatorName(user.getNickname())); + MapUtils.findAndThen(userMap, stockMove.getAuditUserId(), user -> stockMove.setAuditUserName(user.getNickname())); + }); + } + + private List buildProductStockRespList(List stockList) { + if (CollUtil.isEmpty(stockList)) { + return Collections.emptyList(); + } + Map productMap = productService.getProductVOMap(convertSet(stockList, ErpStockDO::getProductId)); + Map warehouseMap = warehouseService.getWarehouseMap(convertSet(stockList, ErpStockDO::getWarehouseId)); + Map areaMap = warehouseAreaService.getWarehouseAreaMap(convertSet(stockList, ErpStockDO::getAreaId)); + return stockList.stream() + .sorted(Comparator.comparing(ErpStockDO::getWarehouseId, Comparator.nullsLast(Long::compareTo)) + .thenComparing(ErpStockDO::getAreaId, Comparator.nullsLast(Long::compareTo))) + .map(stock -> BeanUtils.toBean(stock, ErpStockMoveProductStockRespVO.class, respVO -> { + respVO.setStockCount(stock.getCount()); + MapUtils.findAndThen(productMap, stock.getProductId(), product -> respVO.setProductName(product.getName()) + .setProductBarCode(product.getBarCode())); + MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> respVO.setWarehouseName(warehouse.getName())); + if (respVO.getAreaName() == null) { + MapUtils.findAndThen(areaMap, stock.getAreaId(), area -> respVO.setAreaName(area.getAreaName())); + } + })) + .collect(Collectors.toList()); + } + + private ErpStockMoveRespVO buildStockMoveRespVO(ErpStockMoveDO stockMove, List stockMoveItemList, + List approveRecords) { + Map productMap = productService.getProductVOMap( + convertSet(stockMoveItemList, ErpStockMoveItemDO::getProductId)); + Map warehouseMap = warehouseService.getWarehouseMap(convertListByFlatMap(stockMoveItemList, + item -> Stream.of(item.getFromWarehouseId(), item.getToWarehouseId()))); + Map areaMap = warehouseAreaService.getWarehouseAreaMap(convertListByFlatMap(stockMoveItemList, + item -> Stream.of(item.getFromAreaId(), item.getToAreaId()))); + Map stockMap = buildStockMap(stockMoveItemList); + Map userMap = adminUserApi.getUserMap(convertListByFlatMap(approveRecords, + record -> Stream.of(NumberUtils.parseLong(record.getCreator()), record.getTargetUserId()))); + userMap.putAll(adminUserApi.getUserMap(convertListByFlatMap(Collections.singletonList(stockMove), + item -> Stream.of(NumberUtils.parseLong(item.getCreator()), item.getAuditUserId())))); + return BeanUtils.toBean(stockMove, ErpStockMoveRespVO.class, respVO -> { + respVO.setItems(BeanUtils.toBean(stockMoveItemList, ErpStockMoveRespVO.Item.class, + item -> fillStockMoveItem(item, productMap, warehouseMap, areaMap, stockMap))); + respVO.setProductNames(CollUtil.join(respVO.getItems(), ",", ErpStockMoveRespVO.Item::getProductName)); + respVO.setStatusName(getAuditStatusName(respVO.getStatus())); + respVO.setApproveRecords(buildApproveRecordRespList(approveRecords, userMap)); + MapUtils.findAndThen(userMap, NumberUtils.parseLong(respVO.getCreator()), user -> respVO.setCreatorName(user.getNickname())); + MapUtils.findAndThen(userMap, respVO.getAuditUserId(), user -> respVO.setAuditUserName(user.getNickname())); }); } -} \ No newline at end of file + private void fillStockMoveItem(ErpStockMoveRespVO.Item item, Map productMap, + Map warehouseMap, Map areaMap, + Map stockMap) { + MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) + .setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())); + MapUtils.findAndThen(warehouseMap, item.getFromWarehouseId(), warehouse -> item.setFromWarehouseName(warehouse.getName())); + MapUtils.findAndThen(warehouseMap, item.getToWarehouseId(), warehouse -> item.setToWarehouseName(warehouse.getName())); + MapUtils.findAndThen(areaMap, item.getFromAreaId(), area -> item.setFromAreaName(area.getAreaName())); + MapUtils.findAndThen(areaMap, item.getToAreaId(), area -> item.setToAreaName(area.getAreaName())); + ErpStockDO stock = stockMap.get(buildStockKey(item.getProductId(), item.getFromWarehouseId(), item.getFromAreaId())); + item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO); + } + + private Map buildStockMap(List stockMoveItemList) { + if (CollUtil.isEmpty(stockMoveItemList)) { + return Collections.emptyMap(); + } + List stockList = stockService.getStockList(convertSet(stockMoveItemList, ErpStockMoveItemDO::getProductId), + convertSet(stockMoveItemList, ErpStockMoveItemDO::getFromWarehouseId), + convertSet(stockMoveItemList, ErpStockMoveItemDO::getFromAreaId)); + Map stockMap = new java.util.HashMap<>(); + for (ErpStockDO stock : stockList) { + stockMap.put(buildStockKey(stock.getProductId(), stock.getWarehouseId(), stock.getAreaId()), stock); + } + return stockMap; + } + + private String buildStockKey(Long productId, Long warehouseId, Long areaId) { + return String.valueOf(productId) + "_" + String.valueOf(warehouseId) + "_" + String.valueOf(areaId); + } + + private List buildApproveRecordRespList(List records) { + if (CollUtil.isEmpty(records)) { + return new ArrayList<>(); + } + Map userMap = adminUserApi.getUserMap(convertListByFlatMap(records, + record -> Stream.of(NumberUtils.parseLong(record.getCreator()), record.getTargetUserId()))); + return buildApproveRecordRespList(records, userMap); + } + + private List buildApproveRecordRespList(List records, + Map userMap) { + if (CollUtil.isEmpty(records)) { + return new ArrayList<>(); + } + return BeanUtils.toBean(records, ErpStockMoveApproveRecordRespVO.class, record -> { + MapUtils.findAndThen(userMap, NumberUtils.parseLong(record.getCreator()), user -> record.setCreatorName(user.getNickname())); + MapUtils.findAndThen(userMap, record.getTargetUserId(), user -> record.setTargetUserName(user.getNickname())); + record.setFromStatusName(getAuditStatusName(record.getFromStatus())); + record.setToStatusName(getAuditStatusName(record.getToStatus())); + }); + } + + private String getAuditStatusName(Integer status) { + for (ErpAuditStatus item : ErpAuditStatus.values()) { + if (item.getStatus().equals(status)) { + return item.getName(); + } + } + return null; + } + +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckRecordPageReqVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckRecordPageReqVO.java new file mode 100644 index 000000000..f5d2a1fbd --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckRecordPageReqVO.java @@ -0,0 +1,54 @@ +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - ERP 库存盘点记录分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ErpStockCheckRecordPageReqVO extends PageParam { + + @Schema(description = "盘点单号", example = "QCPD20260623001") + private String no; + + @Schema(description = "盘点时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] checkTime; + + @Schema(description = "生成来源类型:1-按库存,2-按产品", example = "1") + private Integer sourceType; + + @Schema(description = "产品分类类型", example = "1") + private Integer categoryType; + + @Schema(description = "盘点状态:0-未盘点,1-已盘点", example = "1") + private Integer checkStatus; + + @Schema(description = "审核状态", example = "20") + private Integer status; + + @Schema(description = "产品编号", example = "1") + private Long productId; + + @Schema(description = "仓库编号", example = "1") + private Long warehouseId; + + @Schema(description = "库区编号", example = "1") + private Long areaId; + + @Schema(description = "创建人") + private String creator; + + @Schema(description = "盘点记录项 id 集合,导出使用") + private String ids; + +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckRecordRespVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckRecordRespVO.java new file mode 100644 index 000000000..870558151 --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckRecordRespVO.java @@ -0,0 +1,124 @@ +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check; + +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; +import cn.iocoder.yudao.module.erp.enums.DictTypeConstants; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.module.erp.enums.DictTypeConstants.AUDIT_STATUS; +import static cn.iocoder.yudao.module.erp.enums.DictTypeConstants.PRODUCT_CATEGORY_TYPE; + +@Schema(description = "管理后台 - ERP 库存盘点记录 Response VO") +@Data +@ExcelIgnoreUnannotated +public class ErpStockCheckRecordRespVO { + + @Schema(description = "盘点记录项编号", example = "11756") + @ExcelProperty("盘点记录项编号") + private Long id; + + @Schema(description = "盘点单编号", example = "11756") + private Long checkId; + + @Schema(description = "盘点单号", example = "QCPD20260623001") + @ExcelProperty("盘点单号") + private String no; + + @Schema(description = "盘点时间") + @ExcelProperty("盘点时间") + private LocalDateTime checkTime; + + @Schema(description = "生成来源类型:1-按库存,2-按产品", example = "1") + @ExcelProperty(value = "生成来源类型", converter = DictConvert.class) + @DictFormat("erp_stock_check_source_type") + private Integer sourceType; + + @Schema(description = "产品分类类型", example = "1") + @ExcelProperty(value = "产品分类类型", converter = DictConvert.class) + @DictFormat(PRODUCT_CATEGORY_TYPE) + private Integer categoryType; + + @Schema(description = "盘点状态:0-未盘点,1-已盘点", example = "1") + @ExcelProperty("盘点状态") + private Integer checkStatus; + + @Schema(description = "审核状态", example = "20") + @ExcelProperty(value = "审核状态", converter = DictConvert.class) + @DictFormat(AUDIT_STATUS) + private Integer status; + + @Schema(description = "产品编号", example = "3113") + private Long productId; + + @Schema(description = "产品名称", example = "苹果") + @ExcelProperty("产品名称") + private String productName; + + @Schema(description = "产品条码", example = "A9985") + @ExcelProperty("产品条码") + private String productBarCode; + + @Schema(description = "产品分类", example = "水果") + @ExcelProperty("产品分类") + private String categoryName; + + @Schema(description = "产品单位名称", example = "个") + @ExcelProperty("单位") + private String productUnitName; + + @Schema(description = "仓库编号", example = "3113") + private Long warehouseId; + + @Schema(description = "仓库名称", example = "成品仓") + @ExcelProperty("仓库名称") + private String warehouseName; + + @Schema(description = "库区编号", example = "1") + private Long areaId; + + @Schema(description = "库区名称", example = "A区") + @ExcelProperty("库区名称") + private String areaName; + + @Schema(description = "产品单价", example = "100.00") + @ExcelProperty("产品单价") + private BigDecimal productPrice; + + @Schema(description = "账面数量", example = "100.00") + @ExcelProperty("账面数量") + private BigDecimal stockCount; + + @Schema(description = "实际数量", example = "95.00") + @ExcelProperty("实际数量") + private BigDecimal actualCount; + + @Schema(description = "盈亏数量", example = "-5.00") + @ExcelProperty("盈亏数量") + private BigDecimal count; + + @Schema(description = "合计金额", example = "500.00") + @ExcelProperty("合计金额") + private BigDecimal totalPrice; + + @Schema(description = "备注", example = "随便") + @ExcelProperty("备注") + private String remark; + + @Schema(description = "创建人", example = "1") + private String creator; + + @Schema(description = "创建人名称", example = "张三") + @ExcelProperty("创建人") + private String creatorName; + + @Schema(description = "创建时间") + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/in/ErpStockInSaveReqVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/in/ErpStockInSaveReqVO.java index 5e7786384..7453543ae 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/in/ErpStockInSaveReqVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/in/ErpStockInSaveReqVO.java @@ -66,6 +66,12 @@ public class ErpStockInSaveReqVO { @Schema(description = "产品编号", example = "3113") private Long productId; + @Schema(description = "供应商编号", example = "3113") + private Long supplierId; + + @Schema(description = "供应商名称", example = "供应商A") + private String supplierName; + @Schema(description = "产品单价", example = "100.00") private BigDecimal productPrice; diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveApproveRecordRespVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveApproveRecordRespVO.java new file mode 100644 index 000000000..87a2e9ef2 --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveApproveRecordRespVO.java @@ -0,0 +1,50 @@ +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - ERP 库存调拨单审核记录 Response VO") +@Data +public class ErpStockMoveApproveRecordRespVO { + + @Schema(description = "编号", example = "1") + private Long id; + + @Schema(description = "调拨单编号", example = "1") + private Long stockMoveId; + + @Schema(description = "操作类型", example = "SUBMIT") + private String actionType; + + @Schema(description = "变更前状态", example = "0") + private Integer fromStatus; + + @Schema(description = "变更前状态名称", example = "待提交") + private String fromStatusName; + + @Schema(description = "变更后状态", example = "10") + private Integer toStatus; + + @Schema(description = "变更后状态名称", example = "审核中") + private String toStatusName; + + @Schema(description = "目标审核人编号", example = "1") + private Long targetUserId; + + @Schema(description = "目标审核人名称", example = "李四") + private String targetUserName; + + @Schema(description = "备注", example = "请审核") + private String remark; + + @Schema(description = "操作人", example = "1") + private String creator; + + @Schema(description = "操作人名称", example = "张三") + private String creatorName; + + @Schema(description = "创建时间") + private LocalDateTime createTime; +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveAuditReqVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveAuditReqVO.java new file mode 100644 index 000000000..1b05bb026 --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveAuditReqVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - ERP 库存调拨单审核 Request VO") +@Data +public class ErpStockMoveAuditReqVO { + + @Schema(description = "调拨单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756") + @NotNull(message = "调拨单编号不能为空") + private Long id; + + @Schema(description = "审核结果 20-通过 1-驳回", requiredMode = Schema.RequiredMode.REQUIRED, example = "20") + @NotNull(message = "审核结果不能为空") + private Integer status; + + @Schema(description = "审核备注", example = "审核通过") + private String remark; +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMovePageReqVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMovePageReqVO.java index 7816e8670..14d4857e6 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMovePageReqVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMovePageReqVO.java @@ -39,11 +39,23 @@ public class ErpStockMovePageReqVO extends PageParam { @Schema(description = "产品编号", example = "1") private Long productId; + @Schema(description = "产品分类类型", example = "1") + private Integer categoryType; + @Schema(description = "调出仓库编号", example = "1") private Long fromWarehouseId; + @Schema(description = "调出库区编号", example = "1") + private Long fromAreaId; + + @Schema(description = "调入仓库编号", example = "1") + private Long toWarehouseId; + + @Schema(description = "调入库区编号", example = "1") + private Long toAreaId; + @Schema(description = "id集合导出用") private String ids; -} \ No newline at end of file +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveProductStockRespVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveProductStockRespVO.java new file mode 100644 index 000000000..e26f36f03 --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveProductStockRespVO.java @@ -0,0 +1,50 @@ +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - ERP 库存调拨产品库区库存 Response VO") +@Data +public class ErpStockMoveProductStockRespVO { + + @Schema(description = "产品编号", example = "1") + private Long productId; + + @Schema(description = "产品名称", example = "产品A") + private String productName; + + @Schema(description = "产品编码", example = "CP001") + private String productBarCode; + + @Schema(description = "仓库编号", example = "10") + private Long warehouseId; + + @Schema(description = "仓库名称", example = "成品仓") + private String warehouseName; + + @Schema(description = "库区编号", example = "100") + private Long areaId; + + @Schema(description = "库区名称", example = "A区") + private String areaName; + + @Schema(description = "当前库存数量", example = "120") + private BigDecimal stockCount; + + @Schema(description = "库存单位编号", example = "1") + private Long unitId; + + @Schema(description = "库存单位名称", example = "个") + private String unitName; + + @Schema(description = "包装单位编号", example = "2") + private Long purchaseUnitId; + + @Schema(description = "包装单位名称", example = "箱") + private String purchaseUnitName; + + @Schema(description = "包装单位与库存单位换算数量", example = "20") + private BigDecimal purchaseUnitConvertQuantity; +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveRespVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveRespVO.java index 799ddc3f1..0ab4984e1 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveRespVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveRespVO.java @@ -43,6 +43,18 @@ public class ErpStockMoveRespVO { @DictFormat(AUDIT_STATUS) private Integer status; + @Schema(description = "状态名称", example = "待提交") + private String statusName; + + @Schema(description = "是否需要审核", example = "true") + private Boolean needAudit; + + @Schema(description = "审核人编号", example = "1888") + private Long auditUserId; + + @Schema(description = "审核人名称", example = "李四") + private String auditUserName; + @Schema(description = "备注", example = "随便") @ExcelProperty("备注") private String remark; @@ -62,6 +74,9 @@ public class ErpStockMoveRespVO { @Schema(description = "调拨项列表", requiredMode = Schema.RequiredMode.REQUIRED) private List items; + @Schema(description = "审核记录") + private List approveRecords; + @Schema(description = "产品信息", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("产品信息") private String productNames; @@ -75,9 +90,27 @@ public class ErpStockMoveRespVO { @Schema(description = "调出仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") private Long fromWarehouseId; + @Schema(description = "调出仓库名称", example = "A仓") + private String fromWarehouseName; + + @Schema(description = "调出库区编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") + private Long fromAreaId; + + @Schema(description = "调出库区名称", example = "A-01") + private String fromAreaName; + @Schema(description = "调入仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888") private Long toWarehouseId; + @Schema(description = "调入仓库名称", example = "B仓") + private String toWarehouseName; + + @Schema(description = "调入库区编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888") + private Long toAreaId; + + @Schema(description = "调入库区名称", example = "B-01") + private String toAreaName; + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") private Long productId; @@ -104,4 +137,4 @@ public class ErpStockMoveRespVO { } -} \ No newline at end of file +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveSaveReqVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveSaveReqVO.java index dc803531b..435b65392 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveSaveReqVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveSaveReqVO.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutApproveRecordRespVO; import com.fasterxml.jackson.annotation.JsonIgnore; +import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -33,7 +35,10 @@ public class ErpStockMoveSaveReqVO { @Schema(description = "附件 URL", example = "https://www.iocoder.cn/1.doc") private String fileUrl; - @Schema(description = "调拨项列表", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "审核人编号", example = "1888") + private Long auditUserId; + + @Schema(description = "调拨项列表", implementation = ErpStockMoveSaveReqVO.Item.class) @NotEmpty(message = "调拨项列表不能为空") @Valid private List items; @@ -48,10 +53,18 @@ public class ErpStockMoveSaveReqVO { @NotNull(message = "调出仓库编号不能为空") private Long fromWarehouseId; + @Schema(description = "调出库区编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") + @NotNull(message = "调出库区编号不能为空") + private Long fromAreaId; + @Schema(description = "调入仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888") @NotNull(message = "调入仓库编号不能为空") private Long toWarehouseId; + @Schema(description = "调入库区编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888") + @NotNull(message = "调入库区编号不能为空") + private Long toAreaId; + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113") @NotNull(message = "产品编号不能为空") private Long productId; @@ -69,9 +82,9 @@ public class ErpStockMoveSaveReqVO { @AssertTrue(message = "调出、调仓仓库不能相同") @JsonIgnore public boolean isWarehouseValid() { - return ObjectUtil.notEqual(fromWarehouseId, toWarehouseId); + return ObjectUtil.notEqual(fromWarehouseId, toWarehouseId) || ObjectUtil.notEqual(fromAreaId, toAreaId); } } -} \ No newline at end of file +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveSubmitReqVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveSubmitReqVO.java new file mode 100644 index 000000000..41feb897a --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/move/ErpStockMoveSubmitReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - ERP 库存调拨单提交审核 Request VO") +@Data +public class ErpStockMoveSubmitReqVO { + + @Schema(description = "调拨单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11756") + @NotNull(message = "调拨单编号不能为空") + private Long id; + + @Schema(description = "审核人编号", example = "1888") + private Long auditUserId; + + @Schema(description = "提交备注", example = "请审核") + private String remark; +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/stock/ErpStockRespVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/stock/ErpStockRespVO.java index 723135e6f..893779d4e 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/stock/ErpStockRespVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/stock/ErpStockRespVO.java @@ -9,6 +9,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.math.BigDecimal; +import java.util.List; import static cn.iocoder.yudao.module.erp.enums.DictTypeConstants.PRODUCT_CATEGORY_TYPE; @@ -95,6 +96,15 @@ public class ErpStockRespVO { @ExcelProperty("库存展示") private String stockDisplay; + @Schema(description = "总包数", example = "10") + private BigDecimal totalPackageCount; + + @Schema(description = "总基本数量", example = "100") + private BigDecimal totalBaseCount; + + @Schema(description = "库区库存明细") + private List areaStocks; + @Schema(description = "托盘数量", example = "2") private Long palletCount; @@ -112,4 +122,26 @@ public class ErpStockRespVO { @ExcelProperty("最近出库时间") private java.time.LocalDateTime recentOutTime; + @Data + public static class AreaStock { + + @Schema(description = "库区编号", example = "1") + private Long areaId; + + @Schema(description = "库区名称", example = "A-01") + private String areaName; + + @Schema(description = "库存数量", example = "100") + private BigDecimal count; + + @Schema(description = "包数", example = "10") + private BigDecimal packageCount; + + @Schema(description = "基本数量", example = "0") + private BigDecimal baseCount; + + @Schema(description = "库存展示", example = "A-01:10包0个") + private String stockDisplay; + } + } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/warehousearea/WarehouseAreaController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/warehousearea/WarehouseAreaController.java index a798cff36..0acf7573b 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/warehousearea/WarehouseAreaController.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/warehousearea/WarehouseAreaController.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.erp.controller.admin.warehousearea; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.module.common.enums.QrcodeBizTypeEnum; +import cn.iocoder.yudao.module.common.service.qrcordrecord.QrcodeRecordService; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.warehouse.ErpWarehouseRespVO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO; import org.springframework.web.bind.annotation.*; @@ -13,6 +15,7 @@ import io.swagger.v3.oas.annotations.Operation; import java.util.*; import java.io.IOException; +import java.io.UnsupportedEncodingException; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -25,6 +28,7 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo.*; import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO; @@ -43,10 +47,13 @@ public class WarehouseAreaController { @Resource private WarehouseAreaService warehouseAreaService; + @Resource + private QrcodeRecordService qrcodeService; + @PostMapping("/create") @Operation(summary = "创建ERP 库区信息") @PreAuthorize("@ss.hasPermission('erp:warehouse-area:create')") - public CommonResult createWarehouseArea(@Valid @RequestBody WarehouseAreaSaveReqVO createReqVO) { + public CommonResult createWarehouseArea(@Valid @RequestBody WarehouseAreaSaveReqVO createReqVO) throws UnsupportedEncodingException { return success(warehouseAreaService.createWarehouseArea(createReqVO)); } @@ -73,7 +80,10 @@ public class WarehouseAreaController { @PreAuthorize("@ss.hasPermission('erp:warehouse-area:query')") public CommonResult getWarehouseArea(@RequestParam("id") Long id) { WarehouseAreaDO warehouseArea = warehouseAreaService.getWarehouseArea(id); - return success(BeanUtils.toBean(warehouseArea, WarehouseAreaRespVO.class)); + WarehouseAreaRespVO respVO = BeanUtils.toBean(warehouseArea, WarehouseAreaRespVO.class); + fillQrcodeUrl(respVO, warehouseArea); + fillTemplateJson(respVO); + return success(respVO); } @GetMapping("/page") @@ -81,7 +91,10 @@ public class WarehouseAreaController { @PreAuthorize("@ss.hasPermission('erp:warehouse-area:query')") public CommonResult> getWarehouseAreaPage(@Valid WarehouseAreaPageReqVO pageReqVO) { PageResult pageResult = warehouseAreaService.getWarehouseAreaPage(pageReqVO); - return success(BeanUtils.toBean(pageResult, WarehouseAreaRespVO.class)); + PageResult result = BeanUtils.toBean(pageResult, WarehouseAreaRespVO.class); + fillQrcodeUrl(result.getList()); + fillTemplateJson(result.getList()); + return success(result); } @@ -89,12 +102,47 @@ public class WarehouseAreaController { @Operation(summary = "获得库区精简列表", description = "只包含被开启的仓库库区,主要用于前端的下拉选项") public CommonResult> getWarehouseSimpleList(@RequestParam(value = "warehouseId", required = false) Long warehouseId) { List list = warehouseAreaService.getWarehouseListByStatusAndWarehouseId(CommonStatusEnum.ENABLE.getStatus(), warehouseId); - return success(convertList(list, area -> new WarehouseAreaRespVO() + List result = convertList(list, area -> new WarehouseAreaRespVO() .setId(area.getId()) .setWarehouseId(area.getWarehouseId()) .setAreaCode(area.getAreaCode()) .setAreaName(area.getAreaName()) - .setStatus(area.getStatus()))); + .setStatus(area.getStatus())); + fillQrcodeUrl(result); + return success(result); + } + + private void fillQrcodeUrl(WarehouseAreaRespVO respVO, WarehouseAreaDO warehouseArea) { + if (respVO == null || warehouseArea == null) { + return; + } + respVO.setQrcodeUrl(qrcodeService.selectQrcodeUrlByIdAndCode( + QrcodeBizTypeEnum.WAREHOUSE_AREA.getCode(), warehouseArea.getId(), warehouseArea.getAreaCode())); + } + + private void fillQrcodeUrl(List list) { + Map qrcodeUrlMap = qrcodeService.selectQrcodeUrlMapByBizTypeAndIds( + QrcodeBizTypeEnum.WAREHOUSE_AREA.getCode(), convertSet(list, WarehouseAreaRespVO::getId)); + for (WarehouseAreaRespVO respVO : list) { + respVO.setQrcodeUrl(qrcodeUrlMap.get(respVO.getId())); + } + } + + private void fillTemplateJson(WarehouseAreaRespVO respVO) { + if (respVO == null) { + return; + } + respVO.setTemplateJson(warehouseAreaService.selectPrintTemplate()); + } + + private void fillTemplateJson(List list) { + if (list == null || list.isEmpty()) { + return; + } + String templateJson = warehouseAreaService.selectPrintTemplate(); + for (WarehouseAreaRespVO respVO : list) { + respVO.setTemplateJson(templateJson); + } } @@ -111,4 +159,11 @@ public class WarehouseAreaController { BeanUtils.toBean(list, WarehouseAreaRespVO.class)); } + @PostMapping("/regenerate-code") + public CommonResult regenerateCode(@RequestParam("id") Long id, + @RequestParam("code") String code) throws UnsupportedEncodingException { + warehouseAreaService.regenerateCode(id, code); + return success(true); + } + } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/warehousearea/vo/WarehouseAreaRespVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/warehousearea/vo/WarehouseAreaRespVO.java index e0278110a..e6eac600b 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/warehousearea/vo/WarehouseAreaRespVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/warehousearea/vo/WarehouseAreaRespVO.java @@ -25,6 +25,12 @@ public class WarehouseAreaRespVO { @ExcelProperty("库区编码") private String areaCode; + @Schema(description = "二维码 URL") + private String qrcodeUrl; + + @Schema(description = "打印模板Json", example = "") + private String templateJson; + @Schema(description = "库区名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") @ExcelProperty("库区名称") private String areaName; @@ -45,4 +51,4 @@ public class WarehouseAreaRespVO { @ExcelProperty("创建时间") private LocalDateTime createTime; -} \ No newline at end of file +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/product/ErpProductDO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/product/ErpProductDO.java index b375b7bf7..0b9e2c4fe 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/product/ErpProductDO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/product/ErpProductDO.java @@ -66,6 +66,11 @@ public class ErpProductDO extends BaseDO { */ private Long unitId; + /** + * 单位名称 + */ + private String unitName; + /** * 采购单位编号 * diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockInItemDO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockInItemDO.java index c068a7e7b..32c59fbf4 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockInItemDO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockInItemDO.java @@ -56,6 +56,14 @@ public class ErpStockInItemDO extends BaseDO { * 产品名称快照 */ private String productName; + /** + * 供应商编号 + */ + private Long supplierId; + /** + * 供应商名称快照 + */ + private String supplierName; /** * 产品单位编号 * diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveApproveRecordDO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveApproveRecordDO.java new file mode 100644 index 000000000..0d6720844 --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveApproveRecordDO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.erp.dal.dataobject.stock; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@TableName("erp_stock_move_approve_record") +@KeySequence("erp_stock_move_approve_record_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ErpStockMoveApproveRecordDO extends BaseDO { + + @TableId + private Long id; + + private Long stockMoveId; + + private String actionType; + + private Integer fromStatus; + + private Integer toStatus; + + private Long targetUserId; + + private String remark; +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveDO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveDO.java index 682b33104..91ed8ed34 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveDO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveDO.java @@ -45,6 +45,8 @@ public class ErpStockMoveDO extends BaseDO { * 合计金额,单位:元 */ private BigDecimal totalPrice; + private Boolean needAudit; + private Long auditUserId; /** * 状态 * @@ -60,4 +62,4 @@ public class ErpStockMoveDO extends BaseDO { */ private String fileUrl; -} \ No newline at end of file +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveItemDO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveItemDO.java index aee203670..5dcbc8f26 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveItemDO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockMoveItemDO.java @@ -41,12 +41,16 @@ public class ErpStockMoveItemDO extends BaseDO { * 关联 {@link ErpWarehouseDO#getId()} */ private Long fromWarehouseId; + private Long fromAreaId; + private String fromAreaName; /** * 调入仓库编号 * * 关联 {@link ErpWarehouseDO#getId()} */ private Long toWarehouseId; + private Long toAreaId; + private String toAreaName; /** * 产品编号 * @@ -76,4 +80,4 @@ public class ErpStockMoveItemDO extends BaseDO { */ private String remark; -} \ No newline at end of file +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/product/ErpProductMapper.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/product/ErpProductMapper.java index f984ecd16..edce89a53 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/product/ErpProductMapper.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/product/ErpProductMapper.java @@ -133,9 +133,13 @@ public interface ErpProductMapper extends BaseMapperX { } /**查询不同类型的产品**/ default List selectByCategorys(List categoryIds) { + return selectByCategorys(categoryIds, CommonStatusEnum.ENABLE.getStatus()); + } + + default List selectByCategorys(List categoryIds, Integer status) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); - wrapper.eq(ErpProductDO::getStatus, 0); + wrapper.eq(status != null, ErpProductDO::getStatus, status); if (categoryIds!=null && !categoryIds.isEmpty() ) { wrapper.in(ErpProductDO::getCategoryId, categoryIds); diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockCheckItemMapper.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockCheckItemMapper.java index ae13f9f96..80c8a72d6 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockCheckItemMapper.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockCheckItemMapper.java @@ -1,11 +1,19 @@ package cn.iocoder.yudao.module.erp.dal.mysql.stock; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckRecordPageReqVO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckItemDO; +import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; +import com.alibaba.excel.util.StringUtils; import org.apache.ibatis.annotations.Mapper; +import java.time.format.DateTimeFormatter; +import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.stream.Collectors; /** * ERP 库存盘点单项 Mapper @@ -15,6 +23,53 @@ import java.util.List; @Mapper public interface ErpStockCheckItemMapper extends BaseMapperX { + DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + Integer STOCK_CHECK_STATUS_CHECKED = 1; + + default PageResult selectRecordPage(ErpStockCheckRecordPageReqVO reqVO) { + LambdaQueryWrapperX query = new LambdaQueryWrapperX() + .eqIfPresent(ErpStockCheckItemDO::getProductId, reqVO.getProductId()) + .eqIfPresent(ErpStockCheckItemDO::getWarehouseId, reqVO.getWarehouseId()) + .eqIfPresent(ErpStockCheckItemDO::getAreaId, reqVO.getAreaId()) + .orderByDesc(ErpStockCheckItemDO::getId); + query.inSql(ErpStockCheckItemDO::getCheckId, buildCheckFilterSql(reqVO)); + if (StringUtils.isNotBlank(reqVO.getIds())) { + List idList = Arrays.stream(reqVO.getIds().split(",")) + .map(String::trim) + .map(Long::valueOf) + .collect(Collectors.toList()); + query.in(ErpStockCheckItemDO::getId, idList); + } + return selectPage(reqVO, query); + } + + default String buildCheckFilterSql(ErpStockCheckRecordPageReqVO reqVO) { + StringBuilder checkFilterSql = new StringBuilder("select id from erp_stock_check where deleted = 0"); + checkFilterSql.append(" and check_status = ").append(STOCK_CHECK_STATUS_CHECKED); + checkFilterSql.append(" and status = ").append(ErpAuditStatus.APPROVE.getStatus()); + if (StringUtils.isNotBlank(reqVO.getNo())) { + checkFilterSql.append(" and no like '%").append(reqVO.getNo().replace("'", "''")).append("%'"); + } + if (reqVO.getCheckTime() != null && reqVO.getCheckTime().length == 2) { + if (reqVO.getCheckTime()[0] != null) { + checkFilterSql.append(" and check_time >= '").append(DATE_TIME_FORMATTER.format(reqVO.getCheckTime()[0])).append("'"); + } + if (reqVO.getCheckTime()[1] != null) { + checkFilterSql.append(" and check_time <= '").append(DATE_TIME_FORMATTER.format(reqVO.getCheckTime()[1])).append("'"); + } + } + if (reqVO.getSourceType() != null) { + checkFilterSql.append(" and source_type = ").append(reqVO.getSourceType()); + } + if (reqVO.getCategoryType() != null) { + checkFilterSql.append(" and category_type = ").append(reqVO.getCategoryType()); + } + if (StringUtils.isNotBlank(reqVO.getCreator())) { + checkFilterSql.append(" and creator = '").append(reqVO.getCreator().replace("'", "''")).append("'"); + } + return checkFilterSql.toString(); + } + default List selectListByCheckId(Long checkId) { return selectList(ErpStockCheckItemDO::getCheckId, checkId); } @@ -27,4 +82,4 @@ public interface ErpStockCheckItemMapper extends BaseMapperX { default PageResult selectPage(ErpStockInPageReqVO reqVO) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); - if(StringUtil.isNotBlank(reqVO.getNo())){ - if(reqVO.getNo().contains("PRODUCTMATERIAL-")){ - query.eq(ErpProductDO::getId, reqVO.getNo().replace("PRODUCTMATERIAL-","")); - }else{ + Long productId = reqVO.getProductId(); + if (StringUtil.isNotBlank(reqVO.getNo())) { + if (reqVO.getNo().contains("PRODUCTMATERIAL-")) { + productId = Long.valueOf(reqVO.getNo().replace("PRODUCTMATERIAL-", "")); + } else { query.likeIfPresent(ErpStockInDO::getNo, reqVO.getNo()); - } } + if (productId != null || reqVO.getWarehouseId() != null) { + query.inSql(ErpStockInDO::getId, buildItemFilterSql(productId, reqVO.getWarehouseId())); + } + query -// .likeIfPresent(ErpStockInDO::getNo, reqVO.getNo()) .eqIfPresent(ErpStockInDO::getSupplierId, reqVO.getSupplierId()) .betweenIfPresent(ErpStockInDO::getInTime, reqVO.getInTime()) .inIfPresent(ErpStockInDO::getStatus, reqVO.getStatusList()) @@ -52,6 +53,17 @@ public interface ErpStockInMapper extends BaseMapperX { return selectJoinPage(reqVO, ErpStockInDO.class, query); } + default String buildItemFilterSql(Long productId, Long warehouseId) { + StringBuilder itemFilterSql = new StringBuilder("select distinct in_id from erp_stock_in_item where deleted = 0"); + if (productId != null) { + itemFilterSql.append(" and product_id = ").append(productId); + } + if (warehouseId != null) { + itemFilterSql.append(" and warehouse_id = ").append(warehouseId); + } + return itemFilterSql.toString(); + } + default int updateByIdAndStatus(Long id, Integer status, ErpStockInDO updateObj) { return update(updateObj, new LambdaUpdateWrapper() .eq(ErpStockInDO::getId, id) diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockMapper.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockMapper.java index b353be054..0231088e8 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockMapper.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockMapper.java @@ -5,6 +5,7 @@ import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldBrandDO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO; @@ -31,8 +32,33 @@ public interface ErpStockMapper extends BaseMapperX { default PageResult selectPage(ErpStockPageReqVO reqVO) { - LambdaQueryWrapperX erpStockDOLambdaQueryWrapperX = new LambdaQueryWrapperX() - .eqIfPresent(ErpStockDO::getProductId, reqVO.getProductId()) + LambdaQueryWrapperX erpStockDOLambdaQueryWrapperX = new LambdaQueryWrapperX(); + +// if(StringUtils.isNotBlank(reqVO.getCode())&&StringUtils.isNotBlank(reqVO.getName())&&reqVO.getCode().equals(reqVO.getName())){ +// if(reqVO.getCode().contains("PRODUCTMATERIAL-")){ +// queryWrapper.eq(MoldBrandDO::getId, reqVO.getCode().replace("PRODUCTMATERIAL-","")); +// }else{ +// queryWrapper.and(w -> w +// .like(MoldBrandDO::getCode, reqVO.getCode()) +// .or() +// .like(MoldBrandDO::getName, reqVO.getName()) +// ); +// } +// }else{ +// queryWrapper.likeIfPresent(MoldBrandDO::getCode, reqVO.getCode()) +// .likeIfPresent(MoldBrandDO::getName, reqVO.getName()); +// } + + + + + + + + + + + erpStockDOLambdaQueryWrapperX.eqIfPresent(ErpStockDO::getProductId, reqVO.getProductId()) .eqIfPresent(ErpStockDO::getWarehouseId, reqVO.getWarehouseId()) .eqIfPresent(ErpStockDO::getAreaId, reqVO.getAreaId()) .eqIfPresent(ErpStockDO::getCategoryId, reqVO.getCategoryId()) diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockMoveApproveRecordMapper.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockMoveApproveRecordMapper.java new file mode 100644 index 000000000..6f371eab7 --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockMoveApproveRecordMapper.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.erp.dal.mysql.stock; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveApproveRecordDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface ErpStockMoveApproveRecordMapper extends BaseMapperX { + + default List selectListByStockMoveId(Long stockMoveId) { + return selectList(new LambdaQueryWrapperX() + .eq(ErpStockMoveApproveRecordDO::getStockMoveId, stockMoveId) + .orderByAsc(ErpStockMoveApproveRecordDO::getId)); + } + + default int deleteByStockMoveId(Long stockMoveId) { + return delete(ErpStockMoveApproveRecordDO::getStockMoveId, stockMoveId); + } +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockMoveMapper.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockMoveMapper.java index d31f1f998..2968b1405 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockMoveMapper.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockMoveMapper.java @@ -4,6 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMovePageReqVO; +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO; +import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveItemDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockRecordDO; @@ -31,11 +33,21 @@ public interface ErpStockMoveMapper extends BaseMapperX { .likeIfPresent(ErpStockMoveDO::getRemark, reqVO.getRemark()) .eqIfPresent(ErpStockMoveDO::getCreator, reqVO.getCreator()) .orderByDesc(ErpStockMoveDO::getId); - if (reqVO.getFromWarehouseId() != null || reqVO.getProductId() != null) { + if (reqVO.getFromWarehouseId() != null || reqVO.getFromAreaId() != null + || reqVO.getToWarehouseId() != null || reqVO.getToAreaId() != null + || reqVO.getProductId() != null || reqVO.getCategoryType() != null) { query.leftJoin(ErpStockMoveItemDO.class, ErpStockMoveItemDO::getMoveId, ErpStockMoveDO::getId) .eq(reqVO.getFromWarehouseId() != null, ErpStockMoveItemDO::getFromWarehouseId, reqVO.getFromWarehouseId()) - .eq(reqVO.getProductId() != null, ErpStockMoveItemDO::getProductId, reqVO.getProductId()) - .groupBy(ErpStockMoveDO::getId); // 避免 1 对多查询,产生相同的 1 + .eq(reqVO.getFromAreaId() != null, ErpStockMoveItemDO::getFromAreaId, reqVO.getFromAreaId()) + .eq(reqVO.getToWarehouseId() != null, ErpStockMoveItemDO::getToWarehouseId, reqVO.getToWarehouseId()) + .eq(reqVO.getToAreaId() != null, ErpStockMoveItemDO::getToAreaId, reqVO.getToAreaId()) + .eq(reqVO.getProductId() != null, ErpStockMoveItemDO::getProductId, reqVO.getProductId()); + if (reqVO.getCategoryType() != null) { + query.leftJoin(ErpProductDO.class, ErpProductDO::getId, ErpStockMoveItemDO::getProductId) + .leftJoin(ErpProductCategoryDO.class, ErpProductCategoryDO::getId, ErpProductDO::getCategoryId) + .eq(ErpProductCategoryDO::getType, reqVO.getCategoryType()); + } + query.groupBy(ErpStockMoveDO::getId); // 避免 1 对多查询,产生相同的 1 } @@ -62,4 +74,4 @@ public interface ErpStockMoveMapper extends BaseMapperX { return selectOne(ErpStockMoveDO::getNo, no); } -} \ No newline at end of file +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockOutMapper.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockOutMapper.java index a3672abf4..1ffce95e0 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockOutMapper.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockOutMapper.java @@ -9,6 +9,7 @@ import com.alibaba.excel.util.StringUtils; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; +import org.apache.poi.util.StringUtil; import java.util.Arrays; import java.util.List; @@ -18,8 +19,22 @@ import java.util.stream.Collectors; public interface ErpStockOutMapper extends BaseMapperX { default PageResult selectPage(ErpStockOutPageReqVO reqVO) { - MPJLambdaWrapperX query = new MPJLambdaWrapperX() - .likeIfPresent(ErpStockOutDO::getNo, reqVO.getNo()) + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + + Long productId = reqVO.getProductId(); + if (StringUtil.isNotBlank(reqVO.getNo())) { + if (reqVO.getNo().contains("PRODUCTMATERIAL-")) { + productId = Long.valueOf(reqVO.getNo().replace("PRODUCTMATERIAL-", "")); + } else { + query.likeIfPresent(ErpStockOutDO::getNo, reqVO.getNo()); + } + } + + if (productId != null || reqVO.getWarehouseId() != null) { + query.inSql(ErpStockOutDO::getId, buildItemFilterSql(productId, reqVO.getWarehouseId())); + } + + query .eqIfPresent(ErpStockOutDO::getCustomerId, reqVO.getCustomerId()) .eqIfPresent(ErpStockOutDO::getStockUserId, reqVO.getStockUserId()) .eqIfPresent(ErpStockOutDO::getOutType, reqVO.getOutType()) @@ -40,6 +55,17 @@ public interface ErpStockOutMapper extends BaseMapperX { return selectJoinPage(reqVO, ErpStockOutDO.class, query); } + default String buildItemFilterSql(Long productId, Long warehouseId) { + StringBuilder itemFilterSql = new StringBuilder("select distinct out_id from erp_stock_out_item where deleted = 0"); + if (productId != null) { + itemFilterSql.append(" and product_id = ").append(productId); + } + if (warehouseId != null) { + itemFilterSql.append(" and warehouse_id = ").append(warehouseId); + } + return itemFilterSql.toString(); + } + default int updateByIdAndStatus(Long id, Integer status, ErpStockOutDO updateObj) { return update(updateObj, new LambdaUpdateWrapper() .eq(ErpStockOutDO::getId, id) diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/warehousearea/WarehouseAreaMapper.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/warehousearea/WarehouseAreaMapper.java index d4a645d5a..80ae8f4f9 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/warehousearea/WarehouseAreaMapper.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/warehousearea/WarehouseAreaMapper.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; import cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo.*; /** @@ -50,4 +51,6 @@ public interface WarehouseAreaMapper extends BaseMapperX { return selectCount(WarehouseAreaDO::getWarehouseId, warehouseId); } + String selectPrintTemplate(@Param("templateType") Integer templateType); + } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/framework/bean/ProductTypeEnum.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/framework/bean/ProductTypeEnum.java index ba02994a7..a029e28ff 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/framework/bean/ProductTypeEnum.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/framework/bean/ProductTypeEnum.java @@ -10,11 +10,11 @@ import java.util.Arrays; @AllArgsConstructor public enum ProductTypeEnum implements IntArrayValuable { - ITEM(1, "原料"), - PRODUCT(2, "产品"), - TOOL(3, "工具"), + ITEM(1, "产品"), + PRODUCT(2, "物料"), + BEIJIAN(3, "备件"), HAOCAI(4, "耗材"), - BEIJIAN(5, "备件"); + TOOL(5, "工具"); public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductTypeEnum::getTypeId).toArray(); /** diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/mold/MoldBrandServiceImpl.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/mold/MoldBrandServiceImpl.java index cbd725a4e..92290552b 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/mold/MoldBrandServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/mold/MoldBrandServiceImpl.java @@ -215,6 +215,7 @@ public class MoldBrandServiceImpl implements MoldBrandService { @Override public PageResult getMoldBrandPage(MoldBrandPageReqVO pageReqVO) { + applyCurrentDeviceFilter(pageReqVO); if (StrUtil.isNotBlank(pageReqVO.getDeviceName())) { List filteredList = selectByDeviceName(pageReqVO); List pageList = paginateList(filteredList, pageReqVO); @@ -241,6 +242,7 @@ public class MoldBrandServiceImpl implements MoldBrandService { @Override public MoldBrandStatusStatisticsRespVO getMoldBrandStatusStatistics(MoldBrandPageReqVO pageReqVO) { MoldBrandPageReqVO statisticsReqVO = BeanUtils.toBean(pageReqVO, MoldBrandPageReqVO.class); + applyCurrentDeviceFilter(statisticsReqVO); statisticsReqVO.setStatus(null); List list = StrUtil.isNotBlank(statisticsReqVO.getDeviceName()) ? selectByDeviceName(statisticsReqVO) @@ -363,6 +365,12 @@ public class MoldBrandServiceImpl implements MoldBrandService { return latestOperateMap; } + private void applyCurrentDeviceFilter(MoldBrandPageReqVO reqVO) { + if (reqVO != null && StrUtil.isBlank(reqVO.getDeviceName()) && StrUtil.isNotBlank(reqVO.getCurrentDevice())) { + reqVO.setDeviceName(reqVO.getCurrentDevice()); + } + } + private void fillCurrentDeviceNameByLatestOperate(MoldBrandRespVO item, MoldOperateSimpleDO latestOperate) { if (latestOperate == null) { item.setDeviceName(null); diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductService.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductService.java index 3c28c7723..39923fa0e 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductService.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductService.java @@ -73,7 +73,7 @@ public interface ErpProductService { * @param status 状态 * @return 产品 VO 列表 */ - List getProductVOListByStatus(Integer status,Integer categoryId); + List getProductVOListByStatus(Integer status, Integer categoryId, Integer categoryType); List getProductVOListByCategory(Integer categoryId); List getProductVOListByCategory(Integer categoryId, Integer categoryType); List buildProductVOList(List list); diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductServiceImpl.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductServiceImpl.java index f8886981b..5c7a9e950 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/product/ErpProductServiceImpl.java @@ -33,6 +33,7 @@ import cn.iocoder.yudao.module.erp.dal.mysql.productpackagingschemerel.ProductPa import cn.iocoder.yudao.module.erp.dal.mysql.productmoldrel.ProductMoldRelMapper; import cn.iocoder.yudao.module.erp.dal.mysql.productsupplierrel.ProductSupplierRelMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMapper; +import cn.iocoder.yudao.module.erp.framework.bean.ProductTypeEnum; import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; @@ -361,15 +362,24 @@ public class ErpProductServiceImpl implements ErpProductService { if (productUnitService.getProductUnit(purchaseUnitId) == null) { throw exception(PRODUCT_UNIT_NOT_EXISTS); } - if (unitId.equals(purchaseUnitId)) { - throw exception(PRODUCT_UNIT_CONVERT_SELF_NOT_ALLOWED); - } +// if (unitId.equals(purchaseUnitId)) { +// throw exception(PRODUCT_UNIT_CONVERT_SELF_NOT_ALLOWED); +// } if (purchaseUnitConvertQuantity == null || purchaseUnitConvertQuantity.compareTo(BigDecimal.ZERO) <= 0) { throw exception(PRODUCT_PURCHASE_UNIT_CONVERT_QUANTITY_INVALID); } } private void fillProductUnitName(ErpProductDO product) { + if (product.getUnitId() == null) { + product.setUnitName(null); + } else { + ErpProductUnitDO unit = productUnitService.getProductUnit(product.getUnitId()); + if (unit == null) { + throw exception(PRODUCT_UNIT_NOT_EXISTS); + } + product.setUnitName(unit.getName()); + } if (product.getPurchaseUnitId() == null) { product.setPurchaseUnitName(null); return; @@ -494,12 +504,7 @@ public class ErpProductServiceImpl implements ErpProductService { if (id != null) { ErpProductRespVO product = getProduct(id); if (product != null) { - Integer templateType = 0; - if (product.getCategoryType() == 1 ) { - templateType = 1; // 打印模板产品值 - } else if(product.getCategoryId() == 5){ - templateType = 5; // 打印模板备件值 - } + Integer templateType = isSpareProductCategory(product) ? 5 : 1; String template = productMapper.selectPrintTemplate(templateType); product.setTemplateJson(template); } @@ -517,17 +522,37 @@ public class ErpProductServiceImpl implements ErpProductService { throw exception(PRODUCT_NOT_EXISTS); } + private boolean isSpareProductCategory(ErpProductRespVO product) { + Long categoryId = product.getSubCategoryId() != null ? product.getSubCategoryId() : product.getCategoryId(); + if (categoryId == null) { + return Objects.equals(product.getCategoryType(), ProductTypeEnum.BEIJIAN.getTypeId()); + } + ErpProductCategoryDO category = productCategoryMapper.selectById(categoryId); + return category != null && Objects.equals(category.getType(), ProductTypeEnum.BEIJIAN.getTypeId()); + } + @Override - public List getProductVOListByStatus(Integer status,Integer categoryId) { + public List getProductVOListByStatus(Integer status, Integer categoryId, Integer categoryType) { List categoryList = new ArrayList<>(); + if (categoryType != null) { + List categoryIds = productMapper.selectCategoryIdListByType(categoryType); + if (CollUtil.isEmpty(categoryIds)) { + return new ArrayList<>(); + } + if (categoryId != null && !categoryIds.contains(categoryId.longValue())) { + return new ArrayList<>(); + } + categoryIds.forEach(item -> categoryList.add(item.intValue())); + } if(categoryId != null ){ + categoryList.clear(); categoryList.add(categoryId); } - List list = productMapper.selectByCategorys(categoryList); + List list = productMapper.selectByCategorys(categoryList, status); return buildProductVOList(list); } @Override @@ -651,10 +676,14 @@ public class ErpProductServiceImpl implements ErpProductService { product.setSubCategoryName(subCategory.getName()); product.setCategoryType(subCategory.getType()); }); - MapUtils.findAndThen(unitMap, product.getUnitId(), - unit -> product.setUnitName(unit.getName())); - MapUtils.findAndThen(purchaseUnitMap, product.getPurchaseUnitId(), - unit -> product.setPurchaseUnitName(unit.getName())); + if (StrUtil.isBlank(product.getUnitName())) { + MapUtils.findAndThen(unitMap, product.getUnitId(), + unit -> product.setUnitName(unit.getName())); + } + if (StrUtil.isBlank(product.getPurchaseUnitName())) { + MapUtils.findAndThen(purchaseUnitMap, product.getPurchaseUnitId(), + unit -> product.setPurchaseUnitName(unit.getName())); + } product.setPackagingSchemes(packagingSchemeMap.getOrDefault(product.getId(), Collections.emptyList())); product.setSuppliers(supplierMap.getOrDefault(product.getId(), Collections.emptyList())); product.setDefaultSupplierId(defaultSupplierMap.get(product.getId())); @@ -825,6 +854,7 @@ public class ErpProductServiceImpl implements ErpProductService { ErpProductUnitDO unitDO = productUnitService.getProductUnitByName(importProduct.getUnitName()); if (unitDO != null) { productDO.setUnitId(unitDO.getId()); + productDO.setUnitName(unitDO.getName()); } } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockCheckService.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockCheckService.java index 952ea5280..b29f9c0fd 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockCheckService.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockCheckService.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheck import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckGenerateByLocationReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckGenerateByProductReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckPageReqVO; +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckRecordPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckRespVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckSubmitReqVO; @@ -15,6 +16,9 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckItemDO; import javax.validation.Valid; import java.util.Collection; import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; /** * ERP 库存盘点单 Service 接口 @@ -65,6 +69,12 @@ public interface ErpStockCheckService { */ ErpStockCheckDO getStockCheck(Long id); + default Map getStockCheckMap(Collection ids) { + return convertMap(getStockCheckList(ids), ErpStockCheckDO::getId); + } + + List getStockCheckList(Collection ids); + /** * 获得库存盘点单分页 * @@ -73,6 +83,8 @@ public interface ErpStockCheckService { */ PageResult getStockCheckPage(ErpStockCheckPageReqVO pageReqVO); + PageResult getStockCheckRecordPage(ErpStockCheckRecordPageReqVO pageReqVO); + // ==================== 盘点项 ==================== /** diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockCheckServiceImpl.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockCheckServiceImpl.java index 4d70b6ba6..2b8ce25ca 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockCheckServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockCheckServiceImpl.java @@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheck import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckGenerateByLocationReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckGenerateByProductReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckPageReqVO; +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckRecordPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckRespVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckSubmitReqVO; @@ -30,9 +31,7 @@ import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; import cn.iocoder.yudao.module.erp.enums.stock.ErpStockCheckApproveActionEnum; import cn.iocoder.yudao.module.erp.enums.stock.ErpStockCheckSourceTypeEnum; -import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum; import cn.iocoder.yudao.module.erp.service.product.ErpProductService; -import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO; import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService; import cn.iocoder.yudao.module.infra.api.config.ConfigApi; import cn.iocoder.yudao.module.system.api.permission.PermissionApi; @@ -83,7 +82,7 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { @Resource private WarehouseAreaService warehouseAreaService; @Resource - private ErpStockRecordService stockRecordService; + private ErpStockService stockService; @Resource private AdminUserApi adminUserApi; @Resource @@ -119,7 +118,7 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { ErpStockCheckDO stockCheck = BeanUtils.toBean(createReqVO, ErpStockCheckDO.class, in -> in .setNo(finalCode) .setNeedAudit(needAudit()) - .setStatus(ErpAuditStatus.DRAFT.getStatus()) + .setStatus(ErpAuditStatus.PROCESS.getStatus()) .setTotalCount(getSumValue(stockCheckItems, ErpStockCheckItemDO::getCount, BigDecimal::add, BigDecimal.ZERO)) .setTotalPrice(getSumValue(stockCheckItems, ErpStockCheckItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO))); stockCheckMapper.insert(stockCheck); @@ -135,9 +134,9 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { if (ErpAuditStatus.APPROVE.getStatus().equals(stockCheck.getStatus())) { throw exception(STOCK_CHECK_UPDATE_FAIL_APPROVE, stockCheck.getNo()); } - if (ErpAuditStatus.PROCESS.getStatus().equals(stockCheck.getStatus())) { - throw exception(STOCK_CHECK_UPDATE_FAIL_PROCESS, stockCheck.getNo()); - } +// if (ErpAuditStatus.PROCESS.getStatus().equals(stockCheck.getStatus())) { +// throw exception(STOCK_CHECK_UPDATE_FAIL_PROCESS, stockCheck.getNo()); +// } validateSourceType(updateReqVO.getSourceType()); List stockCheckItems = validateStockCheckItems(updateReqVO.getItems()); @@ -182,9 +181,9 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { public void submitStockCheckAudit(ErpStockCheckSubmitReqVO submitReqVO) { ErpStockCheckDO stockCheck = validateStockCheckExists(submitReqVO.getId()); Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); - if (!Objects.equals(NumberUtils.parseLong(stockCheck.getCreator()), loginUserId)) { - throw exception(STOCK_CHECK_SUBMIT_FAIL_USER); - } +// if (!Objects.equals(NumberUtils.parseLong(stockCheck.getCreator()), loginUserId)) { +// throw exception(STOCK_CHECK_SUBMIT_FAIL_USER); +// } if (!ErpAuditStatus.DRAFT.getStatus().equals(stockCheck.getStatus()) && !ErpAuditStatus.UN_APPROVE.getStatus().equals(stockCheck.getStatus())) { throw exception(STOCK_CHECK_SUBMIT_FAIL_STATUS); @@ -215,11 +214,12 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { // if (!ErpAuditStatus.PROCESS.getStatus().equals(stockCheck.getStatus())) { // throw exception(STOCK_CHECK_AUDIT_FAIL_STATUS); // } + Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); Integer fromStatus = stockCheck.getStatus(); if (!needAudit()) { int updateCount = stockCheckMapper.updateByIdAndStatus(stockCheck.getId(), fromStatus, - new ErpStockCheckDO().setNeedAudit(false).setStatus(ErpAuditStatus.APPROVE.getStatus())); + new ErpStockCheckDO().setNeedAudit(false).setStatus(ErpAuditStatus.APPROVE.getStatus()).setAuditUserId(loginUserId)); if (updateCount == 0) { throw exception(STOCK_CHECK_AUDIT_FAIL_STATUS); } @@ -231,18 +231,17 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { return; } - Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); boolean adminCanAudit = permissionApi.hasAnyRoles(loginUserId, RoleCodeEnum.SUPER_ADMIN.getCode()); - if (!Objects.equals(stockCheck.getAuditUserId(), loginUserId) && !adminCanAudit) { - throw exception(STOCK_CHECK_AUDIT_FAIL_USER); - } +// if (!Objects.equals(stockCheck.getAuditUserId(), loginUserId) && !adminCanAudit) { +// throw exception(STOCK_CHECK_AUDIT_FAIL_USER); +// } if (!ErpAuditStatus.APPROVE.getStatus().equals(auditReqVO.getStatus()) && !ErpAuditStatus.UN_APPROVE.getStatus().equals(auditReqVO.getStatus())) { throw exception(STOCK_CHECK_AUDIT_FAIL_RESULT); } int updateCount = stockCheckMapper.updateByIdAndStatus(stockCheck.getId(), fromStatus, - new ErpStockCheckDO().setNeedAudit(true).setStatus(auditReqVO.getStatus())); + new ErpStockCheckDO().setNeedAudit(true).setStatus(auditReqVO.getStatus()).setAuditUserId(loginUserId)); if (updateCount == 0) { throw exception(STOCK_CHECK_AUDIT_FAIL_STATUS); } @@ -269,9 +268,9 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { if (ErpAuditStatus.APPROVE.getStatus().equals(stockCheck.getStatus())) { throw exception(STOCK_CHECK_DELETE_FAIL_APPROVE, stockCheck.getNo()); } - if (ErpAuditStatus.PROCESS.getStatus().equals(stockCheck.getStatus())) { - throw exception(STOCK_CHECK_DELETE_FAIL_PROCESS, stockCheck.getNo()); - } +// if (ErpAuditStatus.PROCESS.getStatus().equals(stockCheck.getStatus())) { +// throw exception(STOCK_CHECK_DELETE_FAIL_PROCESS, stockCheck.getNo()); +// } }); stockChecks.forEach(stockCheck -> { @@ -286,11 +285,24 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { return stockCheckMapper.selectById(id); } + @Override + public List getStockCheckList(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return Collections.emptyList(); + } + return stockCheckMapper.selectBatchIds(ids); + } + @Override public PageResult getStockCheckPage(ErpStockCheckPageReqVO pageReqVO) { return stockCheckMapper.selectPage(pageReqVO); } + @Override + public PageResult getStockCheckRecordPage(ErpStockCheckRecordPageReqVO pageReqVO) { + return stockCheckItemMapper.selectRecordPage(pageReqVO); + } + @Override public List getStockCheckItemListByCheckId(Long checkId) { return stockCheckItemMapper.selectListByCheckId(checkId); @@ -404,25 +416,13 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { return; } BigDecimal count = approve ? stockCheckItem.getCount() : stockCheckItem.getCount().negate(); - Integer bizType; - if (approve) { - bizType = stockCheckItem.getCount().compareTo(BigDecimal.ZERO) > 0 - ? ErpStockRecordBizTypeEnum.CHECK_MORE_IN.getType() - : ErpStockRecordBizTypeEnum.CHECK_LESS_OUT.getType(); - } else { - bizType = stockCheckItem.getCount().compareTo(BigDecimal.ZERO) > 0 - ? ErpStockRecordBizTypeEnum.CHECK_MORE_IN_CANCEL.getType() - : ErpStockRecordBizTypeEnum.CHECK_LESS_OUT_CANCEL.getType(); - } ErpProductDO productDO = productService.validProductList(Collections.singleton(stockCheckItem.getProductId())) .stream().findFirst().orElse(null); if (productDO == null) { return; } - stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO( - stockCheckItem.getProductId(), productDO.getCategoryId(), null, - stockCheckItem.getWarehouseId(), stockCheckItem.getAreaId(), stockCheckItem.getAreaName(), - count, bizType, stockCheckItem.getCheckId(), stockCheckItem.getId(), stockCheck.getNo(), stockCheck.getCheckTime())); + stockService.updateStockCountIncrement(productDO.getCategoryId(), stockCheckItem.getProductId(), + stockCheckItem.getWarehouseId(), stockCheckItem.getAreaId(), stockCheckItem.getAreaName(), count); }); } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockInServiceImpl.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockInServiceImpl.java index f70c64c58..8f1bf3710 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockInServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockInServiceImpl.java @@ -19,6 +19,7 @@ import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.StockInTypeEnum; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; import cn.iocoder.yudao.module.erp.dal.dataobject.pallet.ErpPalletDO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO; +import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInApproveRecordDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO; @@ -41,8 +42,6 @@ import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO; import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService; import cn.iocoder.yudao.module.infra.api.config.ConfigApi; -import cn.iocoder.yudao.module.system.api.permission.PermissionApi; -import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -103,8 +102,6 @@ public class ErpStockInServiceImpl implements ErpStockInService { @Resource private AdminUserApi adminUserApi; @Resource - private PermissionApi permissionApi; - @Resource private ConfigApi configApi; @Override @@ -124,7 +121,7 @@ public class ErpStockInServiceImpl implements ErpStockInService { } boolean needAudit = needAudit(); - Integer status = ErpAuditStatus.DRAFT.getStatus(); + Integer status = ErpAuditStatus.PROCESS.getStatus(); ErpStockInDO stockIn = BeanUtils.toBean(createReqVO, ErpStockInDO.class, in -> in .setNo(no) .setNeedAudit(needAudit) @@ -158,9 +155,9 @@ public class ErpStockInServiceImpl implements ErpStockInService { if (ErpAuditStatus.APPROVE.getStatus().equals(stockIn.getStatus())) { throw exception(STOCK_IN_UPDATE_FAIL_APPROVE, stockIn.getNo()); } - if (ErpAuditStatus.PROCESS.getStatus().equals(stockIn.getStatus())) { - throw exception(STOCK_IN_UPDATE_FAIL_PROCESS, stockIn.getNo()); - } +// if (ErpAuditStatus.PROCESS.getStatus().equals(stockIn.getStatus())) { +// throw exception(STOCK_IN_UPDATE_FAIL_PROCESS, stockIn.getNo()); +// } if (updateReqVO.getStockUserId() != null) { adminUserApi.validateUser(updateReqVO.getStockUserId()); } @@ -210,9 +207,9 @@ public class ErpStockInServiceImpl implements ErpStockInService { public void submitStockInAudit(ErpStockInSubmitReqVO submitReqVO) { ErpStockInDO stockIn = validateStockInExists(submitReqVO.getId()); Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); - if (!Objects.equals(NumberUtils.parseLong(stockIn.getCreator()), loginUserId)) { - throw exception(STOCK_IN_SUBMIT_FAIL_USER); - } +// if (!Objects.equals(NumberUtils.parseLong(stockIn.getCreator()), loginUserId)) { +// throw exception(STOCK_IN_SUBMIT_FAIL_USER); +// } if (!ErpAuditStatus.DRAFT.getStatus().equals(stockIn.getStatus()) && !ErpAuditStatus.UN_APPROVE.getStatus().equals(stockIn.getStatus())) { throw exception(STOCK_IN_SUBMIT_FAIL_STATUS); @@ -242,9 +239,11 @@ public class ErpStockInServiceImpl implements ErpStockInService { // } Integer fromStatus = stockIn.getStatus(); + Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); if (!needAudit()) { int updateCount = stockInMapper.updateByIdAndStatus(stockIn.getId(), fromStatus, - new ErpStockInDO().setNeedAudit(false).setStatus(ErpAuditStatus.APPROVE.getStatus())); + new ErpStockInDO().setNeedAudit(false).setAuditUserId(loginUserId) + .setStatus(ErpAuditStatus.APPROVE.getStatus()).setAuditUserId(loginUserId)); if (updateCount == 0) { throw exception(STOCK_IN_AUDIT_FAIL_STATUS); } @@ -255,18 +254,13 @@ public class ErpStockInServiceImpl implements ErpStockInService { auditReqVO.getRemark() != null ? auditReqVO.getRemark() : "无需审核,审核时自动入库"); return; } - Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); - boolean adminCanAudit = permissionApi.hasAnyRoles(loginUserId, RoleCodeEnum.SUPER_ADMIN.getCode()); - if (!Objects.equals(stockIn.getAuditUserId(), loginUserId) && !adminCanAudit) { - throw exception(STOCK_IN_AUDIT_FAIL_USER); - } if (!ErpAuditStatus.APPROVE.getStatus().equals(auditReqVO.getStatus()) && !ErpAuditStatus.UN_APPROVE.getStatus().equals(auditReqVO.getStatus())) { throw exception(STOCK_IN_AUDIT_FAIL_RESULT); } int updateCount = stockInMapper.updateByIdAndStatus(stockIn.getId(), fromStatus, - new ErpStockInDO().setNeedAudit(true).setStatus(auditReqVO.getStatus())); + new ErpStockInDO().setNeedAudit(true).setAuditUserId(loginUserId).setStatus(auditReqVO.getStatus())); if (updateCount == 0) { throw exception(STOCK_IN_AUDIT_FAIL_STATUS); } @@ -292,9 +286,9 @@ public class ErpStockInServiceImpl implements ErpStockInService { if (ErpAuditStatus.APPROVE.getStatus().equals(stockIn.getStatus())) { throw exception(STOCK_IN_DELETE_FAIL_APPROVE, stockIn.getNo()); } - if (ErpAuditStatus.PROCESS.getStatus().equals(stockIn.getStatus())) { - throw exception(STOCK_IN_DELETE_FAIL_PROCESS, stockIn.getNo()); - } +// if (ErpAuditStatus.PROCESS.getStatus().equals(stockIn.getStatus())) { +// throw exception(STOCK_IN_DELETE_FAIL_PROCESS, stockIn.getNo()); +// } }); stockIns.forEach(stockIn -> { stockInMapper.deleteById(stockIn.getId()); @@ -555,14 +549,38 @@ public class ErpStockInServiceImpl implements ErpStockInService { ErpWarehouseDO::getId); Map areaMap = warehouseAreaService.getWarehouseAreaMap( convertSet(list, ErpStockInSaveReqVO.Item::getAreaId)); + Map supplierMap = buildStockInItemSupplierMap(list, inType); return convertList(list, item -> BeanUtils.toBean(item, ErpStockInItemDO.class, target -> target .setWarehouseName(warehouseMap.containsKey(target.getWarehouseId()) ? warehouseMap.get(target.getWarehouseId()).getName() : null) .setAreaName(areaMap.containsKey(target.getAreaId()) ? areaMap.get(target.getAreaId()).getAreaName() : null) .setProductName(productMap.get(target.getProductId()).getName()) + .setSupplierName(resolveStockInItemSupplierName(item, supplierMap, inType)) .setProductUnitId(productMap.get(target.getProductId()).getUnitId()) .setTotalPrice(MoneyUtils.priceMultiply(target.getProductPrice(), target.getCount())))); } + private Map buildStockInItemSupplierMap(List list, String inType) { + if (!isSupplierItemStockIn(inType)) { + return Collections.emptyMap(); + } + return supplierService.getSupplierMap(convertSet(list, ErpStockInSaveReqVO.Item::getSupplierId)); + } + + private String resolveStockInItemSupplierName(ErpStockInSaveReqVO.Item item, Map supplierMap, + String inType) { + if (!isSupplierItemStockIn(inType) || item.getSupplierId() == null) { + return null; + } + ErpSupplierDO supplier = supplierMap.get(item.getSupplierId()); + return supplier != null ? supplier.getName() : item.getSupplierName(); + } + + private boolean isSupplierItemStockIn(String inType) { + return Objects.equals(inType, StockInTypeEnum.原料入库.getValue()) + || Objects.equals(inType, StockInTypeEnum.备件入库.getValue()) + || Objects.equals(inType, "物料入库"); + } + private void validatePallets(List list) { List palletIds = convertListByFlatMap(list, item -> item.getPallets() == null ? java.util.stream.Stream.empty() : item.getPallets().stream().map(ErpStockInSaveReqVO.Item.PalletItem::getPalletId)); diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockMoveService.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockMoveService.java index b7d4ecf86..ef6dcc8e5 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockMoveService.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockMoveService.java @@ -3,6 +3,9 @@ package cn.iocoder.yudao.module.erp.service.stock; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMovePageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveSaveReqVO; +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveAuditReqVO; +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveSubmitReqVO; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveApproveRecordDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveItemDO; @@ -40,6 +43,12 @@ public interface ErpStockMoveService { */ void updateStockMoveStatus(Long id, Integer status); + void submitStockMoveAudit(ErpStockMoveSubmitReqVO submitReqVO); + + void auditStockMove(ErpStockMoveAuditReqVO auditReqVO); + + List getStockMoveApproveRecordList(Long id); + /** * 删除库存调拨单 * @@ -81,4 +90,4 @@ public interface ErpStockMoveService { */ List getStockMoveItemListByMoveIds(Collection moveIds); -} \ No newline at end of file +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockMoveServiceImpl.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockMoveServiceImpl.java index 034741fb8..705428efb 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockMoveServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockMoveServiceImpl.java @@ -3,19 +3,33 @@ package cn.iocoder.yudao.module.erp.service.stock; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveAuditReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMovePageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveSaveReqVO; +import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveSubmitReqVO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveApproveRecordDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockMoveItemDO; +import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO; +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMoveApproveRecordMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMoveItemMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMoveMapper; import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; +import cn.iocoder.yudao.module.erp.enums.stock.ErpStockMoveApproveActionEnum; import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum; import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO; +import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService; +import cn.iocoder.yudao.module.infra.api.config.ConfigApi; +import cn.iocoder.yudao.module.system.api.permission.PermissionApi; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -26,13 +40,14 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Stream; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*; -// TODO 芋艿:记录操作日志 +// TODO 记录操作日志 /** * ERP 库存调拨单 Service 实现类 @@ -43,10 +58,16 @@ import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*; @Validated public class ErpStockMoveServiceImpl implements ErpStockMoveService { + private static final String AUDIT_CONFIG_CATEGORY = "biz"; + private static final String AUDIT_CONFIG_KEY = "transferAduit"; + private static final String AUDIT_CONFIG_DISABLE_VALUE = "0"; + @Resource private ErpStockMoveMapper stockMoveMapper; @Resource private ErpStockMoveItemMapper stockMoveItemMapper; + @Resource + private ErpStockMoveApproveRecordMapper stockMoveApproveRecordMapper; @Resource private ErpNoRedisDAO noRedisDAO; @@ -57,11 +78,19 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { private ErpWarehouseService warehouseService; @Resource private ErpStockRecordService stockRecordService; + @Resource + private WarehouseAreaService warehouseAreaService; + @Resource + private AdminUserApi adminUserApi; + @Resource + private ConfigApi configApi; + @Resource + private PermissionApi permissionApi; @Override @Transactional(rollbackFor = Exception.class) public Long createStockMove(ErpStockMoveSaveReqVO createReqVO) { - // 1.1 校验出库项的有效性 + // 1.1 校验调拨项的有效性 List stockMoveItems = validateStockMoveItems(createReqVO.getItems()); // 1.2 生成调拨单号,并校验唯一性 String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_MOVE_NO_PREFIX); @@ -69,13 +98,18 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { throw exception(STOCK_MOVE_NO_EXISTS); } - // 2.1 插入出库单 + if (createReqVO.getAuditUserId() != null) { + adminUserApi.validateUser(createReqVO.getAuditUserId()); + } + boolean needAudit = needAudit(); ErpStockMoveDO stockMove = BeanUtils.toBean(createReqVO, ErpStockMoveDO.class, in -> in - .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus()) + .setNo(no) + .setNeedAudit(needAudit) + .setStatus(ErpAuditStatus.PROCESS.getStatus()) .setTotalCount(getSumValue(stockMoveItems, ErpStockMoveItemDO::getCount, BigDecimal::add)) .setTotalPrice(getSumValue(stockMoveItems, ErpStockMoveItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO))); stockMoveMapper.insert(stockMove); - // 2.2 插入出库单项 + // 2.2 插入调拨单项 stockMoveItems.forEach(o -> o.setMoveId(stockMove.getId())); stockMoveItemMapper.insertBatch(stockMoveItems); return stockMove.getId(); @@ -89,38 +123,119 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { if (ErpAuditStatus.APPROVE.getStatus().equals(stockMove.getStatus())) { throw exception(STOCK_MOVE_UPDATE_FAIL_APPROVE, stockMove.getNo()); } - // 1.2 校验出库项的有效性 +// if (ErpAuditStatus.PROCESS.getStatus().equals(stockMove.getStatus())) { +// throw exception(STOCK_MOVE_UPDATE_FAIL_PROCESS, stockMove.getNo()); +// } List stockMoveItems = validateStockMoveItems(updateReqVO.getItems()); + if (updateReqVO.getAuditUserId() != null) { + adminUserApi.validateUser(updateReqVO.getAuditUserId()); + } + boolean needAudit = needAudit(); - // 2.1 更新出库单 ErpStockMoveDO updateObj = BeanUtils.toBean(updateReqVO, ErpStockMoveDO.class, in -> in + .setNeedAudit(needAudit) .setTotalCount(getSumValue(stockMoveItems, ErpStockMoveItemDO::getCount, BigDecimal::add)) .setTotalPrice(getSumValue(stockMoveItems, ErpStockMoveItemDO::getTotalPrice, BigDecimal::add))); stockMoveMapper.updateById(updateObj); - // 2.2 更新出库单项 + // 2.2 更新调拨单项 updateStockMoveItemList(updateReqVO.getId(), stockMoveItems); } @Override @Transactional(rollbackFor = Exception.class) public void updateStockMoveStatus(Long id, Integer status) { - boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status); - // 1.1 校验存在 ErpStockMoveDO stockMove = validateStockMoveExists(id); - // 1.2 校验状态 - if (stockMove.getStatus().equals(status)) { - throw exception(approve ? STOCK_MOVE_APPROVE_FAIL : STOCK_MOVE_PROCESS_FAIL); + boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status); + if (approve) { + if (!ErpAuditStatus.PROCESS.getStatus().equals(stockMove.getStatus())) { + throw exception(STOCK_MOVE_APPROVE_FAIL); + } + } else { + if (!ErpAuditStatus.APPROVE.getStatus().equals(stockMove.getStatus())) { + throw exception(STOCK_MOVE_PROCESS_FAIL); + } } - - // 2. 更新状态 int updateCount = stockMoveMapper.updateByIdAndStatus(id, stockMove.getStatus(), new ErpStockMoveDO().setStatus(status)); if (updateCount == 0) { throw exception(approve ? STOCK_MOVE_APPROVE_FAIL : STOCK_MOVE_PROCESS_FAIL); } - - // 3. 变更库存 List stockMoveItems = stockMoveItemMapper.selectListByMoveId(id); + operateStockMoveEffect(stockMove, stockMoveItems, approve); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void submitStockMoveAudit(ErpStockMoveSubmitReqVO submitReqVO) { + ErpStockMoveDO stockMove = validateStockMoveExists(submitReqVO.getId()); + Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); +// if (!Objects.equals(NumberUtils.parseLong(stockMove.getCreator()), loginUserId)) { +// throw exception(STOCK_MOVE_SUBMIT_FAIL_USER); +// } + if (!ErpAuditStatus.DRAFT.getStatus().equals(stockMove.getStatus()) + && !ErpAuditStatus.UN_APPROVE.getStatus().equals(stockMove.getStatus())) { + throw exception(STOCK_MOVE_SUBMIT_FAIL_STATUS); + } + Integer fromStatus = stockMove.getStatus(); + Long auditUserId = submitReqVO.getAuditUserId() != null ? submitReqVO.getAuditUserId() : stockMove.getAuditUserId(); + if (auditUserId != null) { + adminUserApi.validateUser(auditUserId); + } + int updateCount = stockMoveMapper.updateByIdAndStatus(stockMove.getId(), fromStatus, + new ErpStockMoveDO().setAuditUserId(auditUserId).setStatus(ErpAuditStatus.PROCESS.getStatus())); + if (updateCount == 0) { + throw exception(STOCK_MOVE_SUBMIT_FAIL_STATUS); + } + createApproveRecord(stockMove.getId(), ErpStockMoveApproveActionEnum.SUBMIT, fromStatus, + ErpAuditStatus.PROCESS.getStatus(), auditUserId, submitReqVO.getRemark()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void auditStockMove(ErpStockMoveAuditReqVO auditReqVO) { + ErpStockMoveDO stockMove = validateStockMoveExists(auditReqVO.getId()); + Integer fromStatus = stockMove.getStatus(); + Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); + if (!ErpAuditStatus.PROCESS.getStatus().equals(fromStatus) && needAudit()) { + throw exception(STOCK_MOVE_AUDIT_FAIL_STATUS); + } + if (!needAudit()) { + int updateCount = stockMoveMapper.updateByIdAndStatus(stockMove.getId(), fromStatus, + new ErpStockMoveDO().setNeedAudit(false).setStatus(ErpAuditStatus.APPROVE.getStatus()).setAuditUserId(loginUserId)); + if (updateCount == 0) { + throw exception(STOCK_MOVE_AUDIT_FAIL_STATUS); + } + List stockMoveItems = stockMoveItemMapper.selectListByMoveId(stockMove.getId()); + operateStockMoveEffect(stockMove, stockMoveItems, true); + createApproveRecord(stockMove.getId(), ErpStockMoveApproveActionEnum.AUTO_APPROVE, fromStatus, + ErpAuditStatus.APPROVE.getStatus(), NumberUtils.parseLong(stockMove.getCreator()), + auditReqVO.getRemark() != null ? auditReqVO.getRemark() : "无需审核,审核时自动调拨"); + return; + } + boolean adminCanAudit = permissionApi.hasAnyRoles(loginUserId, RoleCodeEnum.SUPER_ADMIN.getCode()); +// if (!Objects.equals(stockMove.getAuditUserId(), loginUserId) && !adminCanAudit) { +// throw exception(STOCK_MOVE_AUDIT_FAIL_USER); +// } + if (!ErpAuditStatus.APPROVE.getStatus().equals(auditReqVO.getStatus()) + && !ErpAuditStatus.UN_APPROVE.getStatus().equals(auditReqVO.getStatus())) { + throw exception(STOCK_MOVE_AUDIT_FAIL_RESULT); + } + + int updateCount = stockMoveMapper.updateByIdAndStatus(stockMove.getId(), fromStatus, + new ErpStockMoveDO().setNeedAudit(true).setStatus(auditReqVO.getStatus()).setAuditUserId(loginUserId)); + if (updateCount == 0) { + throw exception(STOCK_MOVE_AUDIT_FAIL_STATUS); + } + List stockMoveItems = stockMoveItemMapper.selectListByMoveId(stockMove.getId()); + if (ErpAuditStatus.APPROVE.getStatus().equals(auditReqVO.getStatus())) { + operateStockMoveEffect(stockMove, stockMoveItems, true); + } + createApproveRecord(stockMove.getId(), ErpAuditStatus.APPROVE.getStatus().equals(auditReqVO.getStatus()) + ? ErpStockMoveApproveActionEnum.APPROVE : ErpStockMoveApproveActionEnum.REJECT, + fromStatus, auditReqVO.getStatus(), NumberUtils.parseLong(stockMove.getCreator()), auditReqVO.getRemark()); + } + + private void operateStockMoveEffect(ErpStockMoveDO stockMove, List stockMoveItems, boolean approve) { Integer fromBizType = approve ? ErpStockRecordBizTypeEnum.MOVE_OUT.getType() : ErpStockRecordBizTypeEnum.MOVE_OUT_CANCEL.getType(); Integer toBizType = approve ? ErpStockRecordBizTypeEnum.MOVE_IN.getType() @@ -128,13 +243,15 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { stockMoveItems.forEach(stockMoveItem -> { BigDecimal fromCount = approve ? stockMoveItem.getCount().negate() : stockMoveItem.getCount(); BigDecimal toCount = approve ? stockMoveItem.getCount() : stockMoveItem.getCount().negate(); - ErpProductDO productDO = productService.getProduct(stockMoveItem.getProductId()); + ErpProductRespVO productDO = productService.getProduct(stockMoveItem.getProductId()); stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO( - stockMoveItem.getProductId(),productDO.getCategoryId(), stockMoveItem.getFromWarehouseId(), fromCount, + stockMoveItem.getProductId(), productDO.getCategoryId(), productDO.getCategoryType(), + stockMoveItem.getFromWarehouseId(), stockMoveItem.getFromAreaId(), stockMoveItem.getFromAreaName(), fromCount, fromBizType, stockMoveItem.getMoveId(), stockMoveItem.getId(), stockMove.getNo(),stockMove.getMoveTime())); stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO( - stockMoveItem.getProductId(),productDO.getCategoryId(), stockMoveItem.getToWarehouseId(), toCount, + stockMoveItem.getProductId(), productDO.getCategoryId(), productDO.getCategoryType(), + stockMoveItem.getToWarehouseId(), stockMoveItem.getToAreaId(), stockMoveItem.getToAreaName(), toCount, toBizType, stockMoveItem.getMoveId(), stockMoveItem.getId(), stockMove.getNo(),stockMove.getMoveTime())); }); } @@ -147,12 +264,24 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { // 1.2 校验仓库存在 warehouseService.validWarehouseList(convertSetByFlatMap(list, item -> Stream.of(item.getFromWarehouseId(), item.getToWarehouseId()))); + Map areaMap = warehouseAreaService.getWarehouseAreaMap(convertSetByFlatMap(list, + item -> Stream.of(item.getFromAreaId(), item.getToAreaId()))); // 2. 转化为 ErpStockMoveItemDO 列表 return convertList(list, o -> BeanUtils.toBean(o, ErpStockMoveItemDO.class, item -> item .setProductUnitId(productMap.get(item.getProductId()).getUnitId()) + .setFromAreaName(validateMoveArea(item.getFromWarehouseId(), item.getFromAreaId(), areaMap).getAreaName()) + .setToAreaName(validateMoveArea(item.getToWarehouseId(), item.getToAreaId(), areaMap).getAreaName()) .setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount())))); } + private WarehouseAreaDO validateMoveArea(Long warehouseId, Long areaId, Map areaMap) { + WarehouseAreaDO area = areaMap.get(areaId); + if (area == null || !Objects.equals(area.getWarehouseId(), warehouseId)) { + throw exception(WAREHOUSE_AREA_NOT_EXISTS); + } + return area; + } + private void updateStockMoveItemList(Long id, List newList) { // 第一步,对比新老数据,获得添加、修改、删除的列表 List oldList = stockMoveItemMapper.selectListByMoveId(id); @@ -184,17 +313,37 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { if (ErpAuditStatus.APPROVE.getStatus().equals(stockMove.getStatus())) { throw exception(STOCK_MOVE_DELETE_FAIL_APPROVE, stockMove.getNo()); } + // if (ErpAuditStatus.PROCESS.getStatus().equals(stockMove.getStatus())) { + // throw exception(STOCK_MOVE_DELETE_FAIL_PROCESS, stockMove.getNo()); + // } }); // 2. 遍历删除,并记录操作日志 stockMoves.forEach(stockMove -> { - // 2.1 删除出库单 + // 2.1 删除调拨单 stockMoveMapper.deleteById(stockMove.getId()); - // 2.2 删除出库单项 + // 2.2 删除调拨单项 stockMoveItemMapper.deleteByMoveId(stockMove.getId()); + stockMoveApproveRecordMapper.deleteByStockMoveId(stockMove.getId()); }); } + private boolean needAudit() { + return !AUDIT_CONFIG_DISABLE_VALUE.equals(configApi.getConfigValueByCategoryAndKey(AUDIT_CONFIG_CATEGORY, AUDIT_CONFIG_KEY)); + } + + private void createApproveRecord(Long stockMoveId, ErpStockMoveApproveActionEnum action, Integer fromStatus, + Integer toStatus, Long targetUserId, String remark) { + stockMoveApproveRecordMapper.insert(ErpStockMoveApproveRecordDO.builder() + .stockMoveId(stockMoveId) + .actionType(action.getActionType()) + .fromStatus(fromStatus) + .toStatus(toStatus) + .targetUserId(targetUserId) + .remark(remark) + .build()); + } + private ErpStockMoveDO validateStockMoveExists(Long id) { ErpStockMoveDO stockMove = stockMoveMapper.selectById(id); if (stockMove == null) { @@ -213,7 +362,12 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { return stockMoveMapper.selectPage(pageReqVO); } - // ==================== 出库项 ==================== + @Override + public List getStockMoveApproveRecordList(Long id) { + return stockMoveApproveRecordMapper.selectListByStockMoveId(id); + } + + // ==================== 调拨项 ==================== @Override public List getStockMoveItemListByMoveId(Long moveId) { @@ -228,4 +382,4 @@ public class ErpStockMoveServiceImpl implements ErpStockMoveService { return stockMoveItemMapper.selectListByMoveIds(moveIds); } -} \ No newline at end of file +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutServiceImpl.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutServiceImpl.java index 729d19e55..17d80ffca 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutServiceImpl.java @@ -144,7 +144,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { } boolean needAudit = needAudit(); - Integer status = ErpAuditStatus.DRAFT.getStatus(); + Integer status = ErpAuditStatus.PROCESS.getStatus(); ErpStockOutDO stockOut = BeanUtils.toBean(createReqVO, ErpStockOutDO.class, out -> out .setNo(no) .setNeedAudit(needAudit) @@ -180,9 +180,9 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { if (ErpAuditStatus.APPROVE.getStatus().equals(stockOut.getStatus())) { throw exception(STOCK_OUT_UPDATE_FAIL_APPROVE, stockOut.getNo()); } - if (ErpAuditStatus.PROCESS.getStatus().equals(stockOut.getStatus())) { - throw exception(STOCK_OUT_UPDATE_FAIL_PROCESS, stockOut.getNo()); - } +// if (ErpAuditStatus.PROCESS.getStatus().equals(stockOut.getStatus())) { +// throw exception(STOCK_OUT_UPDATE_FAIL_PROCESS, stockOut.getNo()); +// } if (updateReqVO.getCustomerId() != null) { customerService.validateCustomer(updateReqVO.getCustomerId()); } @@ -237,9 +237,9 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { public void submitStockOutAudit(ErpStockOutSubmitReqVO submitReqVO) { ErpStockOutDO stockOut = validateStockOutExists(submitReqVO.getId()); Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); - if (!Objects.equals(NumberUtils.parseLong(stockOut.getCreator()), loginUserId)) { - throw exception(STOCK_OUT_SUBMIT_FAIL_USER); - } +// if (!Objects.equals(NumberUtils.parseLong(stockOut.getCreator()), loginUserId)) { +// throw exception(STOCK_OUT_SUBMIT_FAIL_USER); +// } if (!ErpAuditStatus.DRAFT.getStatus().equals(stockOut.getStatus()) && !ErpAuditStatus.UN_APPROVE.getStatus().equals(stockOut.getStatus())) { throw exception(STOCK_OUT_SUBMIT_FAIL_STATUS); @@ -267,11 +267,12 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { // if (!ErpAuditStatus.PROCESS.getStatus().equals(stockOut.getStatus())) { // throw exception(STOCK_OUT_AUDIT_FAIL_STATUS); // } + Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); Integer fromStatus = stockOut.getStatus(); if (!needAudit()) { int updateCount = stockOutMapper.updateByIdAndStatus(stockOut.getId(), fromStatus, - new ErpStockOutDO().setNeedAudit(false).setStatus(ErpAuditStatus.APPROVE.getStatus())); + new ErpStockOutDO().setNeedAudit(false).setStatus(ErpAuditStatus.APPROVE.getStatus()).setAuditUserId(loginUserId)); if (updateCount == 0) { throw exception(STOCK_OUT_AUDIT_FAIL_STATUS); } @@ -283,12 +284,11 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { return; } - Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); boolean adminCanSubmit = permissionApi.hasAnyRoles(loginUserId, RoleCodeEnum.SUPER_ADMIN.getCode()); - if (!Objects.equals(stockOut.getAuditUserId(), loginUserId) && !adminCanSubmit) { - throw exception(STOCK_OUT_AUDIT_FAIL_USER); - } +// if (!Objects.equals(stockOut.getAuditUserId(), loginUserId) && !adminCanSubmit) { +// throw exception(STOCK_OUT_AUDIT_FAIL_USER); +// } if (!ErpAuditStatus.APPROVE.getStatus().equals(auditReqVO.getStatus()) && !ErpAuditStatus.UN_APPROVE.getStatus().equals(auditReqVO.getStatus())) { @@ -296,7 +296,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { } int updateCount = stockOutMapper.updateByIdAndStatus(stockOut.getId(), fromStatus, - new ErpStockOutDO().setNeedAudit(true).setStatus(auditReqVO.getStatus())); + new ErpStockOutDO().setNeedAudit(true).setStatus(auditReqVO.getStatus()).setAuditUserId(loginUserId)); if (updateCount == 0) { throw exception(STOCK_OUT_AUDIT_FAIL_STATUS); } @@ -322,9 +322,9 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { if (ErpAuditStatus.APPROVE.getStatus().equals(stockOut.getStatus())) { throw exception(STOCK_OUT_DELETE_FAIL_APPROVE, stockOut.getNo()); } - if (ErpAuditStatus.PROCESS.getStatus().equals(stockOut.getStatus())) { - throw exception(STOCK_OUT_DELETE_FAIL_PROCESS, stockOut.getNo()); - } +// if (ErpAuditStatus.PROCESS.getStatus().equals(stockOut.getStatus())) { +// throw exception(STOCK_OUT_DELETE_FAIL_PROCESS, stockOut.getNo()); +// } }); stockOuts.forEach(stockOut -> { stockOutMapper.deleteById(stockOut.getId()); diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/warehousearea/WarehouseAreaService.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/warehousearea/WarehouseAreaService.java index 9a608cc62..71eed8c59 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/warehousearea/WarehouseAreaService.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/warehousearea/WarehouseAreaService.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.erp.service.warehousearea; import java.util.*; +import java.io.UnsupportedEncodingException; import cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo.*; import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -21,7 +22,7 @@ public interface WarehouseAreaService { * @param createReqVO 创建信息 * @return 编号 */ - Long createWarehouseArea(@Valid WarehouseAreaSaveReqVO createReqVO); + Long createWarehouseArea(@Valid WarehouseAreaSaveReqVO createReqVO) throws UnsupportedEncodingException; /** * 更新ERP 库区信息 @@ -66,4 +67,8 @@ public interface WarehouseAreaService { List getWarehouseListByStatus(Integer status); List getWarehouseListByStatusAndWarehouseId(Integer status, Long warehouseId); + + String selectPrintTemplate(); + + void regenerateCode(Long id, String code) throws UnsupportedEncodingException; } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/warehousearea/WarehouseAreaServiceImpl.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/warehousearea/WarehouseAreaServiceImpl.java index 85a319995..ed31a7305 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/warehousearea/WarehouseAreaServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/warehousearea/WarehouseAreaServiceImpl.java @@ -2,17 +2,23 @@ package cn.iocoder.yudao.module.erp.service.warehousearea; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.common.enums.CodeTypeEnum; +import cn.iocoder.yudao.module.common.enums.QrcodeBizTypeEnum; +import cn.iocoder.yudao.module.common.service.qrcordrecord.QrcodeRecordService; import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil; import cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo.WarehouseAreaPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.warehousearea.vo.WarehouseAreaSaveReqVO; import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO; import cn.iocoder.yudao.module.erp.dal.mysql.warehousearea.WarehouseAreaMapper; import cn.iocoder.yudao.module.erp.dal.mysql.warehouselocation.WarehouseLocationMapper; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.io.UnsupportedEncodingException; import java.util.Collection; import java.util.ArrayList; import java.util.List; @@ -24,8 +30,11 @@ import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_ARE @Service @Validated +@Slf4j public class WarehouseAreaServiceImpl implements WarehouseAreaService { + private static final int WAREHOUSE_AREA_PRINT_TEMPLATE_TYPE = 7; + @Resource private WarehouseAreaMapper warehouseAreaMapper; @@ -35,8 +44,12 @@ public class WarehouseAreaServiceImpl implements WarehouseAreaService { @Resource private AutoCodeUtil autoCodeUtil; + @Resource + private QrcodeRecordService qrcodeService; + @Override - public Long createWarehouseArea(WarehouseAreaSaveReqVO createReqVO) { + @Transactional(rollbackFor = Exception.class) + public Long createWarehouseArea(WarehouseAreaSaveReqVO createReqVO) throws UnsupportedEncodingException { WarehouseAreaDO warehouseArea = BeanUtils.toBean(createReqVO, WarehouseAreaDO.class); if (StringUtils.isEmpty(warehouseArea.getAreaCode())) { warehouseArea.setAreaCode(autoCodeUtil.genSerialCode("RESERVOIR_AREA_GENERATE", null)); @@ -44,6 +57,17 @@ public class WarehouseAreaServiceImpl implements WarehouseAreaService { throw exception(WAREHOUSE_AREA_CODE_EXISTS); } warehouseAreaMapper.insert(warehouseArea); + CodeTypeEnum codeType = autoCodeUtil.queryCodeType("RESERVOIR_AREA_GENERATE"); + if (codeType == null) { + log.warn("[创建库区]未配置码类型,跳过生成,ruleCode={}", "RESERVOIR_AREA_GENERATE"); + return warehouseArea.getId(); + } + qrcodeService.generateOrRefresh( + QrcodeBizTypeEnum.WAREHOUSE_AREA, + warehouseArea.getId(), + warehouseArea.getAreaCode(), + "DETAIL", + codeType); return warehouseArea.getId(); } @@ -106,4 +130,30 @@ public class WarehouseAreaServiceImpl implements WarehouseAreaService { return result; } + @Override + public String selectPrintTemplate() { + return warehouseAreaMapper.selectPrintTemplate(WAREHOUSE_AREA_PRINT_TEMPLATE_TYPE); + } + + @Override + public void regenerateCode(Long id, String code) throws UnsupportedEncodingException { + if (warehouseAreaMapper.selectById(id) == null) { + throw exception(WAREHOUSE_AREA_NOT_EXISTS); + } + if (StringUtils.isBlank(code)) { + throw exception(WAREHOUSE_AREA_CODE_EXISTS); + } + CodeTypeEnum codeType = autoCodeUtil.queryCodeType("RESERVOIR_AREA_GENERATE"); + if (codeType == null) { + log.warn("[重生成库区二维码]未配置码类型,跳过生成,ruleCode={}", "RESERVOIR_AREA_GENERATE"); + return; + } + qrcodeService.regenerateByCodeType( + QrcodeBizTypeEnum.WAREHOUSE_AREA, + id, + code, + "DETAIL", + codeType.getCode()); + } + } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/resources/mapper/product/ErpProductMapper.xml b/yudao-module-erp/yudao-module-erp-biz/src/main/resources/mapper/product/ErpProductMapper.xml index 74b3362c4..68d1605cf 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/resources/mapper/product/ErpProductMapper.xml +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/resources/mapper/product/ErpProductMapper.xml @@ -9,7 +9,7 @@ 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ --> + select template_json + from mes_print_template + where deleted = 0 + and template_type = #{templateType} + and template_biz_type = 1 + + + diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/deviceledger/vo/DeviceLedgerPageReqVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/deviceledger/vo/DeviceLedgerPageReqVO.java index cc23a1871..0b23f027b 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/deviceledger/vo/DeviceLedgerPageReqVO.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/deviceledger/vo/DeviceLedgerPageReqVO.java @@ -100,7 +100,8 @@ public class DeviceLedgerPageReqVO extends PageParam { private Long productId; @Schema(description = "出厂日期") - private LocalDateTime outgoingTime; + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) + private LocalDate[] outgoingTime; @Schema(description = "序列号") private String sn; diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dvrepair/vo/DvRepairPageReqVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dvrepair/vo/DvRepairPageReqVO.java index 7cff354a2..f50147393 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dvrepair/vo/DvRepairPageReqVO.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/dvrepair/vo/DvRepairPageReqVO.java @@ -18,6 +18,9 @@ public class DvRepairPageReqVO extends PageParam { @Schema(description = "维修单编号") private String repairCode; + @Schema(description = "关键词,匹配维修单号/设备编号/设备名称") + private String keyword; + @Schema(description = "维修单名称", example = "王五") private String repairName; @@ -66,6 +69,9 @@ public class DvRepairPageReqVO extends PageParam { @Schema(description = "单据状态0-待完成 1-已完成", example = "1") private Integer status; + @Schema(description = "维修状态 0-待完成 1-通过 2-不通过", example = "1") + private Integer repairStatus; + @Schema(description = "备注") private String remark; @@ -80,6 +86,9 @@ public class DvRepairPageReqVO extends PageParam { @Schema(description = "设备ID集合", example = "6979") private List machineryIds; + @Schema(hidden = true) + private List keywordMachineryIds; + @Schema(description = "产线") private String deviceLine; } diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/deviceledger/DeviceLedgerMapper.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/deviceledger/DeviceLedgerMapper.java index 9a78c77c7..2cb512255 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/deviceledger/DeviceLedgerMapper.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/deviceledger/DeviceLedgerMapper.java @@ -56,6 +56,7 @@ public interface DeviceLedgerMapper extends BaseMapperX { .eqIfPresent(DeviceLedgerDO::getSort, reqVO.getSort()) .eqIfPresent(DeviceLedgerDO::getIsScheduled, reqVO.getIsScheduled()) .betweenIfPresent(DeviceLedgerDO::getCreateTime, reqVO.getCreateTime()) + .betweenIfPresent(DeviceLedgerDO::getOutgoingTime, reqVO.getOutgoingTime()) .orderByDesc(DeviceLedgerDO::getCreateTime); if (reqVO.getDeviceLineIds() != null && !reqVO.getDeviceLineIds().isEmpty()) { diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dvrepair/DvRepairMapper.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dvrepair/DvRepairMapper.java index 5d06a60d7..af7eec9d7 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dvrepair/DvRepairMapper.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/dvrepair/DvRepairMapper.java @@ -27,30 +27,22 @@ public interface DvRepairMapper extends BaseMapperX { LambdaQueryWrapperX dvRepairDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>(); - if(StringUtils.isNotBlank(reqVO.getRepairCode())&&StringUtils.isNotBlank(reqVO.getMachineryCode())&&reqVO.getRepairCode().equals(reqVO.getMachineryCode())){ - dvRepairDOLambdaQueryWrapperX.and(w -> w - .like(DvRepairDO::getRepairCode, reqVO.getRepairCode()) - .or() - .like(DvRepairDO::getMachineryCode, reqVO.getMachineryCode()) - .or() - .in(DvRepairDO::getMachineryId,reqVO.getMachineryIds()) - ); - }else if(CollUtil.isNotEmpty(reqVO.getMachineryIds())){ - dvRepairDOLambdaQueryWrapperX.in(DvRepairDO::getMachineryId,reqVO.getMachineryIds()); + if(CollUtil.isNotEmpty(reqVO.getMachineryIds())){ + dvRepairDOLambdaQueryWrapperX.in(DvRepairDO::getMachineryId, reqVO.getMachineryIds()); } - else{ - dvRepairDOLambdaQueryWrapperX.eqIfPresent(DvRepairDO::getRepairCode, reqVO.getRepairCode()) - .eqIfPresent(DvRepairDO::getMachineryCode, reqVO.getMachineryCode()); + if (StringUtils.isNotBlank(reqVO.getKeyword())) { + dvRepairDOLambdaQueryWrapperX.and(w -> { + w.like(DvRepairDO::getRepairCode, reqVO.getKeyword()); + if (CollUtil.isNotEmpty(reqVO.getKeywordMachineryIds())) { + w.or().in(DvRepairDO::getMachineryId, reqVO.getKeywordMachineryIds()); + } + }); } - /* if(CollUtil.isNotEmpty(reqVO.getMachineryIds())){ - dvRepairDOLambdaQueryWrapperX.in(DvRepairDO::getMachineryId,reqVO.getMachineryIds()); - }*/ dvRepairDOLambdaQueryWrapperX - + .likeIfPresent(DvRepairDO::getRepairCode, reqVO.getRepairCode()) .likeIfPresent(DvRepairDO::getRepairName, reqVO.getRepairName()) .eqIfPresent(DvRepairDO::getMachineryId, reqVO.getMachineryId()) - - .likeIfPresent(DvRepairDO::getMachineryName, reqVO.getMachineryName()) + .likeIfPresent(DvRepairDO::getMachineryCode, reqVO.getMachineryCode()) .eqIfPresent(DvRepairDO::getMachineryBrand, reqVO.getMachineryBrand()) .eqIfPresent(DvRepairDO::getMachinerySpec, reqVO.getMachinerySpec()) .eqIfPresent(DvRepairDO::getMachineryTypeId, reqVO.getMachineryTypeId()) @@ -61,6 +53,7 @@ public interface DvRepairMapper extends BaseMapperX { .eqIfPresent(DvRepairDO::getAcceptedBy, reqVO.getAcceptedBy()) .eqIfPresent(DvRepairDO::getConfirmBy, reqVO.getConfirmBy()) .eqIfPresent(DvRepairDO::getStatus, reqVO.getStatus()) + .eqIfPresent(DvRepairDO::getRepairStatus, reqVO.getRepairStatus()) .eqIfPresent(DvRepairDO::getRemark, reqVO.getRemark()) .betweenIfPresent(DvRepairDO::getCreateTime, reqVO.getCreateTime()) .orderByDesc(DvRepairDO::getCreateTime); @@ -78,4 +71,4 @@ public interface DvRepairMapper extends BaseMapperX { } void selectDeviceRepair(EventStatisticsVO eventStatisticsVO); -} \ No newline at end of file +} diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/dvrepair/DvRepairServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/dvrepair/DvRepairServiceImpl.java index b2d48e6f0..bd97d1519 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/dvrepair/DvRepairServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/dvrepair/DvRepairServiceImpl.java @@ -136,15 +136,15 @@ public class DvRepairServiceImpl implements DvRepairService { @Override public PageResult getDvRepairPage(DvRepairPageReqVO pageReqVO) { - if(StringUtils.isNotBlank(pageReqVO.getDeviceLine())|| StringUtils.isNotBlank(pageReqVO.getRepairCode())) { + if(StringUtils.isNotBlank(pageReqVO.getDeviceLine()) || StringUtils.isNotBlank(pageReqVO.getMachineryName())) { LambdaQueryWrapperX deviceLedgerDOLambdaQueryWrapperX = new LambdaQueryWrapperX<>(); if(StringUtils.isNotBlank(pageReqVO.getDeviceLine())) deviceLedgerDOLambdaQueryWrapperX.eqIfPresent(DeviceLedgerDO::getDeviceLine, pageReqVO.getDeviceLine()); - if(StringUtils.isNotBlank(pageReqVO.getRepairCode())){ + if(StringUtils.isNotBlank(pageReqVO.getMachineryName())){ deviceLedgerDOLambdaQueryWrapperX.and(w -> w - .like(DeviceLedgerDO::getDeviceCode, pageReqVO.getRepairCode()) + .like(DeviceLedgerDO::getDeviceCode, pageReqVO.getMachineryName()) .or() - .like(DeviceLedgerDO::getDeviceName, pageReqVO.getRepairCode()) + .like(DeviceLedgerDO::getDeviceName, pageReqVO.getMachineryName()) ); } List deviceLedgerDOS = deviceLedgerMapper.selectList(deviceLedgerDOLambdaQueryWrapperX); @@ -158,6 +158,20 @@ public class DvRepairServiceImpl implements DvRepairService { } } + if (StringUtils.isNotBlank(pageReqVO.getKeyword())) { + LambdaQueryWrapperX keywordDeviceQuery = new LambdaQueryWrapperX<>(); + keywordDeviceQuery.and(w -> w + .like(DeviceLedgerDO::getDeviceCode, pageReqVO.getKeyword()) + .or() + .like(DeviceLedgerDO::getDeviceName, pageReqVO.getKeyword()) + ); + List deviceLedgerDOS = deviceLedgerMapper.selectList(keywordDeviceQuery); + pageReqVO.setKeywordMachineryIds(deviceLedgerDOS.stream() + .map(DeviceLedgerDO::getId) + .distinct() + .collect(Collectors.toList())); + } + return dvRepairMapper.selectPage(pageReqVO); }