From 234c17c809f691ed850aa027c600b9c56f5ebb21 Mon Sep 17 00:00:00 2001 From: HuangHuiKang Date: Thu, 18 Jun 2026 18:45:11 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E4=BF=AE=E6=94=B9=E4=BA=A7=E5=93=81?= =?UTF-8?q?=E5=87=BA=E5=85=A5=E5=BA=93=E5=8D=95=E6=8D=AE=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/enums/QrcodeBizTypeEnum.java | 1 + .../module/erp/enums/ErrorCodeConstants.java | 1 + .../stock/ErpStockCheckApproveActionEnum.java | 1 + .../erp/enums/stock/ErpStockOutModeEnum.java | 25 +++ .../admin/pallet/ErpPalletController.java | 65 +++++++- .../admin/stock/ErpStockCheckController.java | 6 +- .../admin/stock/ErpStockController.java | 40 ++++- .../admin/stock/ErpStockInController.java | 48 +++++- .../admin/stock/ErpStockOutController.java | 47 +++++- .../ErpStockCheckGenerateByLocationReqVO.java | 3 + .../ErpStockCheckGenerateByProductReqVO.java | 3 + .../vo/check/ErpStockCheckPageReqVO.java | 8 +- .../stock/vo/check/ErpStockCheckRespVO.java | 12 ++ .../vo/check/ErpStockCheckSaveReqVO.java | 6 + .../admin/stock/vo/in/ErpStockInRespVO.java | 43 +++++ .../stock/vo/in/ErpStockInSaveReqVO.java | 42 +++++ .../admin/stock/vo/out/ErpStockOutRespVO.java | 49 ++++++ .../vo/out/ErpStockOutSaveReqVOItem.java | 55 ++++++- .../admin/stock/vo/stock/ErpStockRespVO.java | 3 + .../dal/dataobject/stock/ErpStockCheckDO.java | 12 ++ .../dataobject/stock/ErpStockInItemDO.java | 30 ++++ .../stock/ErpStockInItemPalletDO.java | 32 ++++ .../dataobject/stock/ErpStockOutItemDO.java | 41 +++++ .../stock/ErpStockOutItemPalletDO.java | 32 ++++ .../erp/dal/mysql/pallet/ErpPalletMapper.java | 12 ++ .../dal/mysql/stock/ErpStockCheckMapper.java | 2 + .../stock/ErpStockInItemPalletMapper.java | 24 +++ .../erp/dal/mysql/stock/ErpStockMapper.java | 15 +- .../stock/ErpStockOutItemPalletMapper.java | 24 +++ .../erp/handler/PalletQrcodeBizHandler.java | 35 ++++ .../erp/service/pallet/ErpPalletService.java | 11 ++ .../service/pallet/ErpPalletServiceImpl.java | 61 +++++++ .../stock/ErpStockCheckServiceImpl.java | 48 ++++-- .../erp/service/stock/ErpStockInService.java | 5 + .../service/stock/ErpStockInServiceImpl.java | 155 +++++++++++++++--- .../erp/service/stock/ErpStockOutService.java | 5 + .../service/stock/ErpStockOutServiceImpl.java | 152 ++++++++++++++--- .../controller/admin/task/TaskController.java | 12 +- .../task/vo/TaskPackagingSchemeRespVO.java | 21 +++ .../vo/TaskProductPackagingSchemeRespVO.java | 28 ++++ .../module/mes/service/task/TaskService.java | 1 + .../mes/service/task/TaskServiceImpl.java | 41 +++++ 42 files changed, 1175 insertions(+), 82 deletions(-) create mode 100644 yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockOutModeEnum.java create mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockInItemPalletDO.java create mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockOutItemPalletDO.java create mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockInItemPalletMapper.java create mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockOutItemPalletMapper.java create mode 100644 yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/handler/PalletQrcodeBizHandler.java create mode 100644 yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskPackagingSchemeRespVO.java create mode 100644 yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskProductPackagingSchemeRespVO.java 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 51aff4a27..2a87cb0a0 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 @@ -12,6 +12,7 @@ public enum QrcodeBizTypeEnum { DEVICE_LINE("DEVICE_LINE", "设备产线"), KEY_PART("KEY_PART", "关键件"), MOLD("MOLD", "模具"), + PALLET("PALLET", "托盘"), SPARE("SPARE", "备件"); private final String code; 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 e09a78361..a8f30708b 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 @@ -103,6 +103,7 @@ public interface ErrorCodeConstants { ErrorCode WAREHOUSE_LOCATION_WAREHOUSE_AREA_NOT_MATCH = new ErrorCode(1_030_400_007, "暂无匹配库位信息"); ErrorCode PALLET_NOT_EXISTS = new ErrorCode(1_030_400_008, "托盘不存在"); ErrorCode PALLET_CODE_EXISTS = new ErrorCode(1_030_400_009, "托盘编码已存在"); + ErrorCode PALLET_CODE_EMPTY = new ErrorCode(1_030_400_010, "托盘编码不能为空"); // ========== ERP 其它入库单 1-030-401-000 ========== ErrorCode STOCK_IN_NOT_EXISTS = new ErrorCode(1_030_401_000, "其它入库单不存在"); diff --git a/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockCheckApproveActionEnum.java b/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockCheckApproveActionEnum.java index b9b3392b4..f72c31705 100644 --- a/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockCheckApproveActionEnum.java +++ b/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockCheckApproveActionEnum.java @@ -8,6 +8,7 @@ import lombok.RequiredArgsConstructor; public enum ErpStockCheckApproveActionEnum { SUBMIT("SUBMIT"), + AUTO_APPROVE("AUTO_APPROVE"), APPROVE("APPROVE"), REJECT("REJECT"); diff --git a/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockOutModeEnum.java b/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockOutModeEnum.java new file mode 100644 index 000000000..62629f077 --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/enums/stock/ErpStockOutModeEnum.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.erp.enums.stock; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum ErpStockOutModeEnum implements IntArrayValuable { + + BY_PALLET(1, "按托出库"), + SPLIT_PALLET(2, "拆托出库"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpStockOutModeEnum::getMode).toArray(); + + private final Integer mode; + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/pallet/ErpPalletController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/pallet/ErpPalletController.java index cbf0d2bc6..3fc4d7966 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/pallet/ErpPalletController.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/pallet/ErpPalletController.java @@ -1,8 +1,13 @@ package cn.iocoder.yudao.module.erp.controller.admin.pallet; +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; 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.object.BeanUtils; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +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.pallet.vo.ErpPalletPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.pallet.vo.ErpPalletRespVO; import cn.iocoder.yudao.module.erp.controller.admin.pallet.vo.ErpPalletSaveReqVO; @@ -16,9 +21,14 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; +import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.util.List; +import java.util.Map; +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.convertList; @@ -30,6 +40,8 @@ public class ErpPalletController { @Resource private ErpPalletService palletService; + @Resource + private QrcodeRecordService qrcodeService; @PostMapping("/create") @Operation(summary = "创建托盘") @@ -61,7 +73,7 @@ public class ErpPalletController { @PreAuthorize("@ss.hasPermission('erp:pallet:query')") public CommonResult getPallet(@RequestParam("id") Long id) { ErpPalletDO pallet = palletService.getPallet(id); - return success(BeanUtils.toBean(pallet, ErpPalletRespVO.class)); + return success(buildPalletRespVO(pallet)); } @GetMapping("/page") @@ -69,7 +81,24 @@ public class ErpPalletController { @PreAuthorize("@ss.hasPermission('erp:pallet:query')") public CommonResult> getPalletPage(@Valid ErpPalletPageReqVO pageReqVO) { PageResult pageResult = palletService.getPalletPage(pageReqVO); - return success(BeanUtils.toBean(pageResult, ErpPalletRespVO.class)); + Map qrcodeMap = qrcodeService.selectQrcodeUrlMapByBizTypeAndIds(QrcodeBizTypeEnum.PALLET.getCode(), + convertList(pageResult.getList(), ErpPalletDO::getId)); + List list = convertList(pageResult.getList(), pallet -> buildPalletRespVO(pallet, qrcodeMap)); + return success(new PageResult<>(list, pageResult.getTotal())); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出托盘 Excel") + @PreAuthorize("@ss.hasPermission('erp:pallet:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportPalletExcel(@Valid ErpPalletPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + PageResult pageResult = palletService.getPalletPage(pageReqVO); + Map qrcodeMap = qrcodeService.selectQrcodeUrlMapByBizTypeAndIds(QrcodeBizTypeEnum.PALLET.getCode(), + convertList(pageResult.getList(), ErpPalletDO::getId)); + List list = convertList(pageResult.getList(), pallet -> buildPalletRespVO(pallet, qrcodeMap)); + ExcelUtils.write(response, "托盘.xls", "数据", ErpPalletRespVO.class, list); } @GetMapping("/simple-list") @@ -77,6 +106,36 @@ public class ErpPalletController { @Parameter(name = "status", description = "托盘状态", example = "1") public CommonResult> getPalletSimpleList(@RequestParam(value = "status", required = false) Integer status) { List list = palletService.getPalletListByStatus(status); - return success(convertList(list, item -> BeanUtils.toBean(item, ErpPalletRespVO.class))); + Map qrcodeMap = qrcodeService.selectQrcodeUrlMapByBizTypeAndIds(QrcodeBizTypeEnum.PALLET.getCode(), + convertList(list, ErpPalletDO::getId)); + return success(convertList(list, item -> buildPalletRespVO(item, qrcodeMap))); + } + + @PostMapping("/regenerate-code") + public CommonResult regenerateCode(@RequestParam("id") Long id, + @RequestParam("code") String code) throws UnsupportedEncodingException { + palletService.regenerateCode(id, code); + return success(true); + } + + private ErpPalletRespVO buildPalletRespVO(ErpPalletDO pallet) { + if (pallet == null) { + return null; + } + ErpPalletRespVO respVO = BeanUtils.toBean(pallet, ErpPalletRespVO.class); + String qrcode = qrcodeService.selectQrcodeUrlByIdAndCode(QrcodeBizTypeEnum.PALLET.getCode(), pallet.getId(), pallet.getCode()); + if (qrcode != null) { + respVO.setQrcode(qrcode); + } + return respVO; + } + + private ErpPalletRespVO buildPalletRespVO(ErpPalletDO pallet, Map qrcodeMap) { + ErpPalletRespVO respVO = BeanUtils.toBean(pallet, ErpPalletRespVO.class); + String qrcode = qrcodeMap.get(pallet.getId()); + if (qrcode != null) { + respVO.setQrcode(qrcode); + } + return respVO; } } 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 ac138d679..f14d657af 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 @@ -98,7 +98,7 @@ public class ErpStockCheckController { @PutMapping("/update-status") @Operation(summary = "更新库存盘点单状态") - @PreAuthorize("@ss.hasPermission('erp:stock-check:update-status')") + @PreAuthorize("@ss.hasPermission('erp:stock-check:update')") @RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS) public CommonResult updateStockCheckStatus(@RequestParam("id") Long id, @RequestParam("status") Integer status) { @@ -108,7 +108,7 @@ public class ErpStockCheckController { @PutMapping("/submit") @Operation(summary = "提交库存盘点单审核") - @PreAuthorize("@ss.hasPermission('erp:stock-check:update')") + @PreAuthorize("@ss.hasPermission('erp:stock-check:submit')") @RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS) public CommonResult submitStockCheckAudit(@Valid @RequestBody ErpStockCheckSubmitReqVO submitReqVO) { stockCheckService.submitStockCheckAudit(submitReqVO); @@ -117,7 +117,7 @@ public class ErpStockCheckController { @PutMapping("/audit") @Operation(summary = "审核库存盘点单") - @PreAuthorize("@ss.hasPermission('erp:stock-check:update-status')") + @PreAuthorize("@ss.hasPermission('erp:stock-check:audit')") @RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS) public CommonResult auditStockCheck(@Valid @RequestBody ErpStockCheckAuditReqVO auditReqVO) { stockCheckService.auditStockCheck(auditReqVO); 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 eb47ffc3f..0139d80a9 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 @@ -12,9 +12,11 @@ import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProduc import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductPackagingSchemeRespVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockRespVO; +import cn.iocoder.yudao.module.erp.dal.dataobject.pallet.ErpPalletDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; 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.service.pallet.ErpPalletService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockRecordService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockService; @@ -36,8 +38,12 @@ 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.List; import java.util.Map; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -59,6 +65,8 @@ public class ErpStockController { private WarehouseAreaService warehouseAreaService; @Resource private ErpStockRecordService stockRecordService; + @Resource + private ErpPalletService palletService; @GetMapping("/get") @Operation(summary = "获得产品库存") @@ -112,6 +120,7 @@ public class ErpStockController { convertSet(pageResult.getList(), ErpStockDO::getWarehouseId)); Map areaMap = warehouseAreaService.getWarehouseAreaMap( convertSet(pageResult.getList(), ErpStockDO::getAreaId)); + Map palletCountMap = buildPalletCountMap(pageResult.getList()); return BeanUtils.toBean(pageResult, ErpStockRespVO.class, stock -> { MapUtils.findAndThen(productMap, stock.getProductId(), product -> { stock.setProductName(product.getName()).setBarCode(product.getBarCode()) @@ -120,6 +129,7 @@ public class ErpStockController { fillProductExtraInfo(stock, product); fillPackagingSnapshot(stock, product); }); + stock.setPalletCount(palletCountMap.getOrDefault(buildStockKey(stock.getProductId(), stock.getWarehouseId(), stock.getAreaId()), 0L)); stock.setPackagingRule(buildPackagingRule(stock)); stock.setStockDisplay(buildStockDisplay(stock)); MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> stock.setWarehouseName(warehouse.getName())); @@ -150,6 +160,7 @@ public class ErpStockController { fillPackagingSnapshot(respVO, product); } fillDerivedFields(respVO); + respVO.setPalletCount(getPalletCount(respVO)); respVO.setPackagingRule(buildPackagingRule(respVO)); respVO.setStockDisplay(buildStockDisplay(respVO)); ErpWarehouseDO warehouse = warehouseService.getWarehouse(stock.getWarehouseId()); @@ -259,11 +270,12 @@ public class ErpStockController { return null; } if (isProductType(stock.getCategoryType())) { - if (stock.getPalletTotalQuantity() == null || stock.getPalletTotalQuantity().compareTo(BigDecimal.ZERO) <= 0) { + if (stock.getPackageQuantity() == null || stock.getPackageQuantity().compareTo(BigDecimal.ZERO) <= 0) { return formatNumber(stock.getCount()) + stock.getUnitName(); } - BigDecimal palletCount = stock.getCount().divideToIntegralValue(stock.getPalletTotalQuantity()); - return formatNumber(palletCount) + "托,0包,0个"; + BigDecimal packageCount = stock.getCount().divide(stock.getPackageQuantity(), 0, RoundingMode.CEILING); + return formatNumber(BigDecimal.valueOf(stock.getPalletCount() != null ? stock.getPalletCount() : 0L)) + "\u6258" + + formatNumber(packageCount) + "\u5305" + formatNumber(stock.getCount()) + stock.getUnitName(); } if (stock.getPurchaseUnitConvertQuantity() == null || stock.getPurchaseUnitConvertQuantity().compareTo(BigDecimal.ZERO) <= 0 || stock.getPurchaseUnitName() == null || stock.getUnitName() == null) { @@ -298,6 +310,28 @@ public class ErpStockController { return Integer.valueOf(1).equals(categoryType); } + private Map buildPalletCountMap(List stockList) { + if (CollUtil.isEmpty(stockList)) { + return new HashMap<>(); + } + return palletService.getOccupiedPalletList(convertSet(stockList, ErpStockDO::getProductId), + convertSet(stockList, ErpStockDO::getWarehouseId), convertSet(stockList, ErpStockDO::getAreaId)).stream() + .collect(Collectors.groupingBy(pallet -> buildStockKey(pallet.getProductId(), pallet.getWarehouseId(), pallet.getAreaId()), + Collectors.counting())); + } + + private Long getPalletCount(ErpStockRespVO stock) { + return palletService.getOccupiedPalletList(Collections.singleton(stock.getProductId()), + Collections.singleton(stock.getWarehouseId()), Collections.singleton(stock.getAreaId())).stream() + .filter(pallet -> buildStockKey(stock.getProductId(), stock.getWarehouseId(), stock.getAreaId()) + .equals(buildStockKey(pallet.getProductId(), pallet.getWarehouseId(), pallet.getAreaId()))) + .count(); + } + + private String buildStockKey(Long productId, Long warehouseId, Long areaId) { + return String.valueOf(productId) + "_" + String.valueOf(warehouseId) + "_" + String.valueOf(areaId); + } + 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 2120c9b96..02b9e4296 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 @@ -19,16 +19,19 @@ import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInRespVO import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInSubmitReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.StockInTypeEnum; +import cn.iocoder.yudao.module.erp.dal.dataobject.pallet.ErpPalletDO; import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; 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; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemPalletDO; 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.ErpStockInStatusEnum; import cn.iocoder.yudao.module.erp.service.mold.MoldBrandService; import cn.iocoder.yudao.module.erp.service.mold.MoldService; +import cn.iocoder.yudao.module.erp.service.pallet.ErpPalletService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockInService; @@ -92,6 +95,8 @@ public class ErpStockInController { @Resource private MoldService moldService; @Resource + private ErpPalletService palletService; + @Resource private AdminUserApi adminUserApi; @PostMapping("/create") @@ -121,8 +126,8 @@ public class ErpStockInController { } @PutMapping("/submit") - @Operation(summary = "提交其它入库单审核") - @PreAuthorize("@ss.hasPermission('erp:stock-in:update')") + @Operation(summary = "提交入库单审核") + @PreAuthorize("@ss.hasPermission('erp:stock-in:submit')") @RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS) public CommonResult submitStockInAudit(@Valid @RequestBody ErpStockInSubmitReqVO submitReqVO) { stockInService.submitStockInAudit(submitReqVO); @@ -130,8 +135,8 @@ public class ErpStockInController { } @PutMapping("/audit") - @Operation(summary = "审核其它入库单") - @PreAuthorize("@ss.hasPermission('erp:stock-in:update-status')") + @Operation(summary = "审核入库单") + @PreAuthorize("@ss.hasPermission('erp:stock-in:audit')") @RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS) public CommonResult auditStockIn(@Valid @RequestBody ErpStockInAuditReqVO auditReqVO) { stockInService.auditStockIn(auditReqVO); @@ -246,17 +251,23 @@ public class ErpStockInController { convertSet(allItems, ErpStockInItemDO::getMoldSetId)); Map> moldListMap = moldService.getMoldListMapByBrandIds( convertSet(allItems, ErpStockInItemDO::getMoldSetId)); + Map> itemPalletMap = stockInService.getStockInItemPalletListByInIds( + convertSet(stockIns, ErpStockInDO::getId)).stream() + .collect(Collectors.groupingBy(ErpStockInItemPalletDO::getInItemId)); + Map palletMap = palletService.getPalletMap( + convertSet(convertListByFlatMap(itemPalletMap.values(), Collection::stream), ErpStockInItemPalletDO::getPalletId)); Map stockMap = buildStockMap(allItems); List list = convertList(stockIns, stockIn -> buildStockInRespVO( stockIn, itemMap.getOrDefault(stockIn.getId(), Collections.emptyList()), Collections.emptyList(), - userMap, supplierMap, stockMap, warehouseMap, areaMap, productMap, moldMap, moldListMap)); + userMap, supplierMap, stockMap, warehouseMap, areaMap, productMap, moldMap, moldListMap, + itemPalletMap, palletMap)); return new PageResult<>(list, pageResult.getTotal()); } private ErpStockInRespVO buildStockInRespVO(ErpStockInDO stockIn, List stockInItemList, List approveRecords) { return buildStockInRespVO(stockIn, stockInItemList, approveRecords, - null, null, null, null, null, null, null, null); + null, null, null, null, null, null, null, null, null, null); } private ErpStockInRespVO buildStockInRespVO(ErpStockInDO stockIn, List stockInItemList, @@ -268,7 +279,9 @@ public class ErpStockInController { Map pageAreaMap, Map pageProductMap, Map pageMoldMap, - Map> pageMoldListMap) { + Map> pageMoldListMap, + Map> pageItemPalletMap, + Map pagePalletMap) { ErpStockInRespVO stockInVO = BeanUtils.toBean(stockIn, ErpStockInRespVO.class); stockInVO.setStatusName(getStockInStatusName(stockIn.getStatus())); Map warehouseMap = pageWarehouseMap != null ? pageWarehouseMap : warehouseService.getWarehouseMap( @@ -278,6 +291,11 @@ public class ErpStockInController { Map userMap = pageUserMap != null ? pageUserMap : adminUserApi.getUserMap(convertListByFlatMap( Collections.singletonList(stockIn), item -> Stream.of(NumberUtils.parseLong(item.getCreator()), item.getStockUserId(), item.getAuditUserId()))); + Map> itemPalletMap = pageItemPalletMap != null ? pageItemPalletMap + : stockInService.getStockInItemPalletListByInId(stockIn.getId()).stream() + .collect(Collectors.groupingBy(ErpStockInItemPalletDO::getInItemId)); + Map palletMap = pagePalletMap != null ? pagePalletMap : palletService.getPalletMap( + convertSet(convertListByFlatMap(itemPalletMap.values(), Collection::stream), ErpStockInItemPalletDO::getPalletId)); MapUtils.findAndThen(userMap, NumberUtils.parseLong(stockIn.getCreator()), user -> stockInVO.setCreatorName(user.getNickname())); MapUtils.findAndThen(userMap, stockIn.getStockUserId(), user -> stockInVO.setStockUserName(user.getNickname())); MapUtils.findAndThen(userMap, stockIn.getAuditUserId(), user -> stockInVO.setAuditUserName(user.getNickname())); @@ -294,6 +312,7 @@ public class ErpStockInController { item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO); item.setMoldList(moldListMap.getOrDefault(source.getMoldSetId(), new ArrayList<>())); fillWarehouseInfo(item, source, warehouseMap, areaMap); + item.setPallets(buildStockInPalletRespList(itemPalletMap.get(source.getId()), palletMap)); MapUtils.findAndThen(moldMap, source.getMoldSetId(), mold -> { item.setMoldSetName(mold.getName()); item.setProductName(mold.getName()); @@ -316,6 +335,7 @@ public class ErpStockInController { if (StringUtils.isBlank(item.getAreaName())) { MapUtils.findAndThen(areaMap, item.getAreaId(), area -> item.setAreaName(area.getAreaName())); } + item.setPallets(buildStockInPalletRespList(itemPalletMap.get(item.getId()), palletMap)); MapUtils.findAndThen(productMap, item.getProductId(), product -> { item.setProductName(product.getName()); item.setProductBarCode(product.getBarCode()); @@ -359,6 +379,20 @@ public class ErpStockInController { return String.valueOf(productId) + "_" + String.valueOf(warehouseId) + "_" + String.valueOf(areaId); } + private List buildStockInPalletRespList(List itemPallets, + Map palletMap) { + if (CollUtil.isEmpty(itemPallets)) { + return Collections.emptyList(); + } + return convertList(itemPallets, itemPallet -> { + ErpStockInRespVO.Item.PalletItem palletItem = new ErpStockInRespVO.Item.PalletItem(); + palletItem.setPalletId(itemPallet.getPalletId()); + palletItem.setPackageCount(itemPallet.getPackageCount()); + MapUtils.findAndThen(palletMap, itemPallet.getPalletId(), pallet -> palletItem.setPalletCode(pallet.getCode())); + return palletItem; + }); + } + private List buildApproveRecordRespList(List records) { if (CollUtil.isEmpty(records)) { return new ArrayList<>(); diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java index 07ae4baad..191df5a74 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/ErpStockOutController.java @@ -19,14 +19,17 @@ import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutResp import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSubmitReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.StockOutTypeEnum; +import cn.iocoder.yudao.module.erp.dal.dataobject.pallet.ErpPalletDO; import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutApproveRecordDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemPalletDO; import cn.iocoder.yudao.module.erp.enums.ErpStockOutStatusEnum; import cn.iocoder.yudao.module.erp.service.mold.MoldBrandService; import cn.iocoder.yudao.module.erp.service.mold.MoldService; +import cn.iocoder.yudao.module.erp.service.pallet.ErpPalletService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockOutService; @@ -90,6 +93,8 @@ public class ErpStockOutController { @Resource private MoldService moldService; @Resource + private ErpPalletService palletService; + @Resource private AdminUserApi adminUserApi; @PostMapping("/create") @@ -119,8 +124,8 @@ public class ErpStockOutController { } @PutMapping("/submit") - @Operation(summary = "提交其它出库单审核") - @PreAuthorize("@ss.hasPermission('erp:stock-out:update')") + @Operation(summary = "提交出库单审核") + @PreAuthorize("@ss.hasPermission('erp:stock-out:submit')") @RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS) public CommonResult submitStockOutAudit(@Valid @RequestBody ErpStockOutSubmitReqVO submitReqVO) { stockOutService.submitStockOutAudit(submitReqVO); @@ -128,8 +133,8 @@ public class ErpStockOutController { } @PutMapping("/audit") - @Operation(summary = "审核其它出库单") - @PreAuthorize("@ss.hasPermission('erp:stock-out:update-status')") + @Operation(summary = "审核出库单") + @PreAuthorize("@ss.hasPermission('erp:stock-out:audit')") @RateLimiter(count = 1, timeUnit = TimeUnit.SECONDS) public CommonResult auditStockOut(@Valid @RequestBody ErpStockOutAuditReqVO auditReqVO) { stockOutService.auditStockOut(auditReqVO); @@ -250,17 +255,22 @@ public class ErpStockOutController { convertSet(allItems, ErpStockOutItemDO::getMoldSetId)); Map> moldListMap = moldService.getMoldListMapByBrandIds( convertSet(allItems, ErpStockOutItemDO::getMoldSetId)); + Map> itemPalletMap = stockOutService.getStockOutItemPalletListByOutIds( + convertSet(stockOuts, ErpStockOutDO::getId)).stream() + .collect(Collectors.groupingBy(ErpStockOutItemPalletDO::getOutItemId)); + Map palletMap = palletService.getPalletMap( + convertSet(convertListByFlatMap(itemPalletMap.values(), Collection::stream), ErpStockOutItemPalletDO::getPalletId)); Map stockMap = buildStockMap(allItems); List list = convertList(stockOuts, stockOut -> buildStockOutRespVO( stockOut, itemMap.getOrDefault(stockOut.getId(), Collections.emptyList()), Collections.emptyList(), - userMap, customerMap, stockMap, productMap, moldMap, moldListMap)); + userMap, customerMap, stockMap, productMap, moldMap, moldListMap, itemPalletMap, palletMap)); return new PageResult<>(list, pageResult.getTotal()); } private ErpStockOutRespVO buildStockOutRespVO(ErpStockOutDO stockOut, List stockOutItemList, List approveRecords) { return buildStockOutRespVO(stockOut, stockOutItemList, approveRecords, - null, null, null, null, null, null); + null, null, null, null, null, null, null, null); } private ErpStockOutRespVO buildStockOutRespVO(ErpStockOutDO stockOut, List stockOutItemList, @@ -270,12 +280,19 @@ public class ErpStockOutController { Map pageStockMap, Map pageProductMap, Map pageMoldMap, - Map> pageMoldListMap) { + Map> pageMoldListMap, + Map> pageItemPalletMap, + Map pagePalletMap) { ErpStockOutRespVO stockOutVO = BeanUtils.toBean(stockOut, ErpStockOutRespVO.class); stockOutVO.setStatusName(getStockOutStatusName(stockOut.getStatus())); Map userMap = pageUserMap != null ? pageUserMap : adminUserApi.getUserMap(convertListByFlatMap( Collections.singletonList(stockOut), item -> Stream.of(NumberUtils.parseLong(item.getCreator()), item.getResponserId(), item.getAuditUserId()))); + Map> itemPalletMap = pageItemPalletMap != null ? pageItemPalletMap + : stockOutService.getStockOutItemPalletListByOutId(stockOut.getId()).stream() + .collect(Collectors.groupingBy(ErpStockOutItemPalletDO::getOutItemId)); + Map palletMap = pagePalletMap != null ? pagePalletMap : palletService.getPalletMap( + convertSet(convertListByFlatMap(itemPalletMap.values(), Collection::stream), ErpStockOutItemPalletDO::getPalletId)); MapUtils.findAndThen(userMap, NumberUtils.parseLong(stockOut.getCreator()), user -> stockOutVO.setCreatorName(user.getNickname())); MapUtils.findAndThen(userMap, stockOut.getResponserId(), user -> stockOutVO.setResponserName(user.getNickname())); MapUtils.findAndThen(userMap, stockOut.getAuditUserId(), user -> stockOutVO.setAuditUserName(user.getNickname())); @@ -291,6 +308,7 @@ public class ErpStockOutController { : stockService.getStock(source.getMoldSetId(), source.getWarehouseId(), source.getAreaId()); item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO); item.setMoldList(moldListMap.getOrDefault(source.getMoldSetId(), new ArrayList<>())); + item.setPallets(buildStockOutPalletRespList(itemPalletMap.get(source.getId()), palletMap)); MapUtils.findAndThen(moldMap, source.getMoldSetId(), mold -> { item.setMoldSetName(mold.getName()); item.setProductName(mold.getName()); @@ -307,6 +325,7 @@ public class ErpStockOutController { ErpStockDO stock = pageStockMap != null ? pageStockMap.get(buildStockKey(item.getProductId(), item.getWarehouseId(), item.getAreaId())) : stockService.getStock(item.getProductId(), item.getWarehouseId(), item.getAreaId()); item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO); + item.setPallets(buildStockOutPalletRespList(itemPalletMap.get(item.getId()), palletMap)); MapUtils.findAndThen(productMap, item.getProductId(), product -> { item.setProductName(product.getName()); item.setProductBarCode(product.getBarCode()); @@ -369,6 +388,20 @@ public class ErpStockOutController { return String.valueOf(productId) + "_" + String.valueOf(warehouseId) + "_" + String.valueOf(areaId); } + private List buildStockOutPalletRespList(List itemPallets, + Map palletMap) { + if (CollUtil.isEmpty(itemPallets)) { + return Collections.emptyList(); + } + return convertList(itemPallets, itemPallet -> { + ErpStockOutRespVO.Item.PalletItem palletItem = new ErpStockOutRespVO.Item.PalletItem(); + palletItem.setPalletId(itemPallet.getPalletId()); + palletItem.setPackageCount(itemPallet.getPackageCount()); + MapUtils.findAndThen(palletMap, itemPallet.getPalletId(), pallet -> palletItem.setPalletCode(pallet.getCode())); + return palletItem; + }); + } + private List buildApproveRecordRespList(List records) { if (CollUtil.isEmpty(records)) { return new ArrayList<>(); diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckGenerateByLocationReqVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckGenerateByLocationReqVO.java index a01758ad0..35c83946e 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckGenerateByLocationReqVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckGenerateByLocationReqVO.java @@ -18,6 +18,9 @@ public class ErpStockCheckGenerateByLocationReqVO { @Schema(description = "是否允许为空库存,默认 true", example = "true") private Boolean allowEmpty = Boolean.TRUE; + @Schema(description = "选择分类", example = "1") + private Integer categoryType; + public boolean validSelection() { return (warehouseIds != null && !warehouseIds.isEmpty()) || (areaIds != null && !areaIds.isEmpty()); } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckGenerateByProductReqVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckGenerateByProductReqVO.java index 5ead9c285..420a7a385 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckGenerateByProductReqVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckGenerateByProductReqVO.java @@ -17,4 +17,7 @@ public class ErpStockCheckGenerateByProductReqVO { @Schema(description = "是否允许为空库存,默认 true", example = "true") private Boolean allowEmpty = Boolean.TRUE; + @Schema(description = "选择分类", example = "1") + private Integer categoryType; + } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckPageReqVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckPageReqVO.java index 41c23bc9d..5a072e4cd 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckPageReqVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckPageReqVO.java @@ -42,6 +42,12 @@ public class ErpStockCheckPageReqVO extends PageParam { @Schema(description = "产品编号", example = "1") private Long productId; + @Schema(description = "选择分类", example = "1") + private Integer categoryType; + + @Schema(description = "盘点状态:0-未盘点,1-已盘点", example = "1") + private Integer checkStatus; + @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/check/ErpStockCheckRespVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckRespVO.java index 339471138..f55779fd9 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckRespVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckRespVO.java @@ -45,6 +45,18 @@ public class ErpStockCheckRespVO { @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 = "true") + private Boolean needAudit; + @Schema(description = "合计数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15663") @ExcelProperty("合计数量") private BigDecimal totalCount; diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckSaveReqVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckSaveReqVO.java index 48125b098..301f94917 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckSaveReqVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/check/ErpStockCheckSaveReqVO.java @@ -39,6 +39,12 @@ public class ErpStockCheckSaveReqVO { @InEnum(ErpStockCheckSourceTypeEnum.class) private Integer sourceType; + @Schema(description = "选择分类", example = "1") + private Integer categoryType; + + @Schema(description = "盘点状态:0-未盘点,1-已盘点", example = "1") + private Integer checkStatus; + @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/in/ErpStockInRespVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/in/ErpStockInRespVO.java index 57551db70..4f4578fd9 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/in/ErpStockInRespVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/in/ErpStockInRespVO.java @@ -141,9 +141,36 @@ public class ErpStockInRespVO { @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") private BigDecimal count; + @Schema(description = "是否关联任务单", example = "true") + private Boolean relateTask; + + @Schema(description = "任务单 ID", example = "10001") + private Long taskId; + @Schema(description = "包装方案 ID", example = "1") private Long packagingSchemeId; + @Schema(description = "包装方案名称", example = "标准包装") + private String packagingSchemeName; + + @Schema(description = "每包数量", example = "10.00") + private BigDecimal packageQuantity; + + @Schema(description = "每托包数", example = "20.00") + private BigDecimal palletPackageQuantity; + + @Schema(description = "每托总数量", example = "200.00") + private BigDecimal palletTotalQuantity; + + @Schema(description = "托数", example = "2.00") + private BigDecimal palletCount; + + @Schema(description = "包数", example = "40.00") + private BigDecimal packageCount; + + @Schema(description = "个数", example = "400.00") + private BigDecimal pieceCount; + @Schema(description = "单位输入方式", example = "包") private String inputUnitType; @@ -177,7 +204,23 @@ public class ErpStockInRespVO { @Schema(description = "库存数量", example = "100.00") private BigDecimal stockCount; + @Schema(description = "托盘列表") + private List pallets; + @Schema(description = "子模具详情") private List moldList; + + @Data + public static class PalletItem { + + @Schema(description = "托盘 ID", example = "1") + private Long palletId; + + @Schema(description = "托盘编码", example = "TP20240601001") + private String palletCode; + + @Schema(description = "包数", example = "10") + private BigDecimal packageCount; + } } } 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 6bd847d09..72b155291 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 @@ -76,16 +76,58 @@ public class ErpStockInSaveReqVO { @Schema(description = "包装方案 ID", example = "1") private Long packagingSchemeId; + @Schema(description = "包装方案名称", example = "标准包装") + private String packagingSchemeName; + + @Schema(description = "每包数量", example = "10") + private BigDecimal packageQuantity; + + @Schema(description = "每托包数", example = "20") + private BigDecimal palletPackageQuantity; + + @Schema(description = "每托总数量", example = "200") + private BigDecimal palletTotalQuantity; + + @Schema(description = "托数", example = "1") + private BigDecimal palletCount; + + @Schema(description = "包数", example = "10") + private BigDecimal packageCount; + + @Schema(description = "个数", example = "100") + private BigDecimal pieceCount; + @Schema(description = "单位输入方式", example = "包") private String inputUnitType; @Schema(description = "录入数量", example = "10.00") private BigDecimal inputCount; + @Schema(description = "是否关联任务单", example = "true") + private Boolean relateTask; + + @Schema(description = "任务单ID", example = "10001") + private Long taskId; + + @Schema(description = "托盘列表") + @Valid + private List pallets; + @Schema(description = "备注", example = "随便") private String remark; @Schema(description = "设备 id", example = "100") private Long deviceId; + + @Data + public static class PalletItem { + + @Schema(description = "托盘ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "托盘ID不能为空") + private Long palletId; + + @Schema(description = "包数", example = "10") + private BigDecimal packageCount; + } } } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutRespVO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutRespVO.java index 84a95cd8b..00d7ad76b 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutRespVO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutRespVO.java @@ -181,6 +181,39 @@ public class ErpStockOutRespVO { @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") private BigDecimal count; + @Schema(description = "包装方案 ID", example = "1") + private Long packagingSchemeId; + + @Schema(description = "包装方案名称", example = "标准包装") + private String packagingSchemeName; + + @Schema(description = "每包数量", example = "10.00") + private BigDecimal packageQuantity; + + @Schema(description = "每托包数", example = "20.00") + private BigDecimal palletPackageQuantity; + + @Schema(description = "每托总数量", example = "200.00") + private BigDecimal palletTotalQuantity; + + @Schema(description = "托数", example = "2.00") + private BigDecimal palletCount; + + @Schema(description = "包数", example = "40.00") + private BigDecimal packageCount; + + @Schema(description = "个数", example = "400.00") + private BigDecimal pieceCount; + + @Schema(description = "单位输入方式", example = "包") + private String inputUnitType; + + @Schema(description = "录入数量", example = "10.00") + private BigDecimal inputCount; + + @Schema(description = "出库方式:1-按托出库 2-拆托出库", example = "1") + private Integer outMode; + @Schema(description = "出库用途", example = "1") private Integer outUsageType; @@ -226,8 +259,24 @@ public class ErpStockOutRespVO { @Schema(description = "库存数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") private BigDecimal stockCount; + @Schema(description = "托盘列表") + private List pallets; + @Schema(description = "子模具列表") private List moldList; + + @Data + public static class PalletItem { + + @Schema(description = "托盘 ID", example = "1") + private Long palletId; + + @Schema(description = "托盘编码", example = "TP20240601001") + private String palletCode; + + @Schema(description = "包数", example = "10") + private BigDecimal packageCount; + } } } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutSaveReqVOItem.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutSaveReqVOItem.java index eb83335ad..28f8122cc 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutSaveReqVOItem.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/stock/vo/out/ErpStockOutSaveReqVOItem.java @@ -5,8 +5,12 @@ import cn.iocoder.yudao.module.erp.enums.ErpStockOutUsageTypeEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import javax.validation.Valid; import javax.validation.constraints.NotNull; import java.math.BigDecimal; +import java.util.List; + +import cn.iocoder.yudao.module.erp.enums.stock.ErpStockOutModeEnum; @Schema(description = "ERP 其它出库单明细项") @Data @@ -33,9 +37,43 @@ public class ErpStockOutSaveReqVOItem { @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") private BigDecimal count; + @Schema(description = "包装方案 ID", example = "1") + private Long packagingSchemeId; + + @Schema(description = "包装方案名称", example = "标准包装") + private String packagingSchemeName; + + @Schema(description = "每包数量", example = "10.00") + private BigDecimal packageQuantity; + + @Schema(description = "每托包数", example = "20.00") + private BigDecimal palletPackageQuantity; + + @Schema(description = "每托总数量", example = "200.00") + private BigDecimal palletTotalQuantity; + + @Schema(description = "托数", example = "2.00") + private BigDecimal palletCount; + + @Schema(description = "包数", example = "40.00") + private BigDecimal packageCount; + + @Schema(description = "个数", example = "400.00") + private BigDecimal pieceCount; + + @Schema(description = "单位输入方式", example = "包") + private String inputUnitType; + + @Schema(description = "录入数量", example = "10.00") + private BigDecimal inputCount; + + @Schema(description = "出库方式:1-按托出库 2-拆托出库", example = "1") + @InEnum(ErpStockOutModeEnum.class) + private Integer outMode; + @Schema(description = "出库用途", example = "1") @InEnum(ErpStockOutUsageTypeEnum.class) - @NotNull(message = "出库用途不能为空") +// @NotNull(message = "出库用途不能为空") private Integer outUsageType; @Schema(description = "维修单编号", example = "1001") @@ -49,4 +87,19 @@ public class ErpStockOutSaveReqVOItem { @Schema(description = "备注", example = "备注信息") private String remark; + + @Schema(description = "托盘列表") + @Valid + private List pallets; + + @Data + public static class PalletItem { + + @Schema(description = "托盘ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "托盘ID不能为空") + private Long palletId; + + @Schema(description = "包数", example = "10") + private BigDecimal packageCount; + } } 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 ffb58ab76..723135e6f 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 @@ -95,6 +95,9 @@ public class ErpStockRespVO { @ExcelProperty("库存展示") private String stockDisplay; + @Schema(description = "托盘数量", example = "2") + private Long palletCount; + // ========== 仓库信息 ========== @Schema(description = "仓库名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockCheckDO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockCheckDO.java index 2986a7b76..ce7c82229 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockCheckDO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockCheckDO.java @@ -41,6 +41,18 @@ public class ErpStockCheckDO extends BaseDO { * 生成来源类型:1-按库存,2-按产品 */ private Integer sourceType; + /** + * 产品分类类型 + */ + private Integer categoryType; + /** + * 盘点状态:0-未盘点,1-已盘点 + */ + private Integer checkStatus; + /** + * 是否需要审核 + */ + private Boolean needAudit; /** * 合计数量 */ 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 b1f859d48..54bacfa42 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 @@ -70,6 +70,34 @@ public class ErpStockInItemDO extends BaseDO { * 包装方案 ID */ private Long packagingSchemeId; + /** + * 包装方案名称 + */ + private String packagingSchemeName; + /** + * 每包数量 + */ + private BigDecimal packageQuantity; + /** + * 每托包数 + */ + private BigDecimal palletPackageQuantity; + /** + * 每托总数量 + */ + private BigDecimal palletTotalQuantity; + /** + * 托数 + */ + private BigDecimal palletCount; + /** + * 包数 + */ + private BigDecimal packageCount; + /** + * 个数 + */ + private BigDecimal pieceCount; /** * 单位输入方式(托/包/个) */ @@ -78,6 +106,8 @@ public class ErpStockInItemDO extends BaseDO { * 录入数量 */ private BigDecimal inputCount; + private Boolean relateTask; + private Long taskId; /** * 合计金额,单位:元 */ diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockInItemPalletDO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockInItemPalletDO.java new file mode 100644 index 000000000..9e5b07401 --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockInItemPalletDO.java @@ -0,0 +1,32 @@ +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; + +import java.math.BigDecimal; + +@TableName("erp_stock_in_item_pallet") +@KeySequence("erp_stock_in_item_pallet_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ErpStockInItemPalletDO extends BaseDO { + + @TableId + private Long id; + private Long inId; + private Long inItemId; + private Long palletId; + private BigDecimal packageCount; +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockOutItemDO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockOutItemDO.java index 472c16901..6cadaf609 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockOutItemDO.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockOutItemDO.java @@ -105,6 +105,47 @@ public class ErpStockOutItemDO extends BaseDO { * 产品数量 */ private BigDecimal count; + /** + * 包装方案 ID + */ + private Long packagingSchemeId; + /** + * 包装方案名称 + */ + private String packagingSchemeName; + /** + * 每包数量 + */ + private BigDecimal packageQuantity; + /** + * 每托包数 + */ + private BigDecimal palletPackageQuantity; + /** + * 每托总数量 + */ + private BigDecimal palletTotalQuantity; + /** + * 托数 + */ + private BigDecimal palletCount; + /** + * 包数 + */ + private BigDecimal packageCount; + /** + * 个数 + */ + private BigDecimal pieceCount; + /** + * 单位输入方式(托/包/个) + */ + private String inputUnitType; + /** + * 录入数量 + */ + private BigDecimal inputCount; + private Integer outMode; /** * 合计金额,单位:元 */ diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockOutItemPalletDO.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockOutItemPalletDO.java new file mode 100644 index 000000000..953de013d --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/stock/ErpStockOutItemPalletDO.java @@ -0,0 +1,32 @@ +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; + +import java.math.BigDecimal; + +@TableName("erp_stock_out_item_pallet") +@KeySequence("erp_stock_out_item_pallet_seq") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ErpStockOutItemPalletDO extends BaseDO { + + @TableId + private Long id; + private Long outId; + private Long outItemId; + private Long palletId; + private BigDecimal packageCount; +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/pallet/ErpPalletMapper.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/pallet/ErpPalletMapper.java index f353dc732..86f8d573d 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/pallet/ErpPalletMapper.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/pallet/ErpPalletMapper.java @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.erp.controller.admin.pallet.vo.ErpPalletPageReqVO import cn.iocoder.yudao.module.erp.dal.dataobject.pallet.ErpPalletDO; import org.apache.ibatis.annotations.Mapper; +import java.math.BigDecimal; +import java.util.Collection; import java.util.List; @Mapper @@ -37,4 +39,14 @@ public interface ErpPalletMapper extends BaseMapperX { } return selectList(ErpPalletDO::getStatus, status); } + + default List selectOccupiedList(Collection productIds, Collection warehouseIds, + Collection areaIds) { + boolean containsNullArea = areaIds != null && areaIds.stream().anyMatch(java.util.Objects::isNull); + return selectList(new LambdaQueryWrapperX() + .inIfPresent(ErpPalletDO::getProductId, productIds) + .inIfPresent(ErpPalletDO::getWarehouseId, warehouseIds) + .inIfPresent(ErpPalletDO::getAreaId, containsNullArea ? null : areaIds) + .gt(ErpPalletDO::getProductCount, BigDecimal.ZERO)); + } } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockCheckMapper.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockCheckMapper.java index e57f430e0..3c0fb5ec2 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockCheckMapper.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockCheckMapper.java @@ -25,6 +25,8 @@ public interface ErpStockCheckMapper extends BaseMapperX { MPJLambdaWrapperX query = new MPJLambdaWrapperX() .likeIfPresent(ErpStockCheckDO::getNo, reqVO.getNo()) .betweenIfPresent(ErpStockCheckDO::getCheckTime, reqVO.getCheckTime()) + .eqIfPresent(ErpStockCheckDO::getCategoryType, reqVO.getCategoryType()) + .eqIfPresent(ErpStockCheckDO::getCheckStatus, reqVO.getCheckStatus()) .eqIfPresent(ErpStockCheckDO::getStatus, reqVO.getStatus()) .likeIfPresent(ErpStockCheckDO::getRemark, reqVO.getRemark()) .eqIfPresent(ErpStockCheckDO::getCreator, reqVO.getCreator()) diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockInItemPalletMapper.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockInItemPalletMapper.java new file mode 100644 index 000000000..ce7243223 --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockInItemPalletMapper.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.erp.dal.mysql.stock; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemPalletDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; + +@Mapper +public interface ErpStockInItemPalletMapper extends BaseMapperX { + + default List selectListByInId(Long inId) { + return selectList(ErpStockInItemPalletDO::getInId, inId); + } + + default List selectListByInIds(Collection inIds) { + return selectList(ErpStockInItemPalletDO::getInId, inIds); + } + + default int deleteByInId(Long inId) { + return delete(ErpStockInItemPalletDO::getInId, inId); + } +} 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 d30d61f4c..b353be054 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 @@ -85,9 +85,15 @@ public interface ErpStockMapper extends BaseMapperX { default List selectListByWarehouseIdsAndAreaIds(List warehouseIds, List areaIds, boolean nonZeroOnly) { + return selectListByWarehouseIdsAndAreaIds(warehouseIds, areaIds, nonZeroOnly, null); + } + + default List selectListByWarehouseIdsAndAreaIds(List warehouseIds, List areaIds, + boolean nonZeroOnly, Integer categoryType) { LambdaQueryWrapperX query = new LambdaQueryWrapperX() .inIfPresent(ErpStockDO::getWarehouseId, warehouseIds) - .inIfPresent(ErpStockDO::getAreaId, areaIds); + .inIfPresent(ErpStockDO::getAreaId, areaIds) + .eqIfPresent(ErpStockDO::getCategoryType, categoryType); if (nonZeroOnly) { query.ne(ErpStockDO::getCount, BigDecimal.ZERO); } @@ -100,8 +106,13 @@ public interface ErpStockMapper extends BaseMapperX { } default List selectListByProductIds(List productIds, boolean nonZeroOnly) { + return selectListByProductIds(productIds, nonZeroOnly, null); + } + + default List selectListByProductIds(List productIds, boolean nonZeroOnly, Integer categoryType) { LambdaQueryWrapperX query = new LambdaQueryWrapperX() - .inIfPresent(ErpStockDO::getProductId, productIds); + .inIfPresent(ErpStockDO::getProductId, productIds) + .eqIfPresent(ErpStockDO::getCategoryType, categoryType); if (nonZeroOnly) { query.ne(ErpStockDO::getCount, BigDecimal.ZERO); } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockOutItemPalletMapper.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockOutItemPalletMapper.java new file mode 100644 index 000000000..a87bd9e26 --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/stock/ErpStockOutItemPalletMapper.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.erp.dal.mysql.stock; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemPalletDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; + +@Mapper +public interface ErpStockOutItemPalletMapper extends BaseMapperX { + + default List selectListByOutId(Long outId) { + return selectList(ErpStockOutItemPalletDO::getOutId, outId); + } + + default List selectListByOutIds(Collection outIds) { + return selectList(ErpStockOutItemPalletDO::getOutId, outIds); + } + + default int deleteByOutId(Long outId) { + return delete(ErpStockOutItemPalletDO::getOutId, outId); + } +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/handler/PalletQrcodeBizHandler.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/handler/PalletQrcodeBizHandler.java new file mode 100644 index 000000000..2079a2d7c --- /dev/null +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/handler/PalletQrcodeBizHandler.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.erp.handler; + +import cn.iocoder.yudao.module.common.enums.QrcodeBizTypeEnum; +import cn.iocoder.yudao.module.common.handler.QrcodeBizHandler; +import cn.iocoder.yudao.module.erp.dal.mysql.pallet.ErpPalletMapper; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +@Component +public class PalletQrcodeBizHandler implements QrcodeBizHandler { + + @Resource + private ErpPalletMapper palletMapper; + + @Override + public String getBizType() { + return QrcodeBizTypeEnum.PALLET.getCode(); + } + + @Override + public boolean exists(Long id) { + return palletMapper.selectById(id) != null; + } + + @Override + public String buildDeepLink(Long id) { + return "https://www.baidu.com"; + } + + @Override + public String buildH5Path(Long id) { + return "https://baike.baidu.com/item/%E6%98%9F%E5%BA%A7/8072715?fr=aladdin"; + } +} diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/pallet/ErpPalletService.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/pallet/ErpPalletService.java index 6d13decd8..39cf20904 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/pallet/ErpPalletService.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/pallet/ErpPalletService.java @@ -6,7 +6,10 @@ import cn.iocoder.yudao.module.erp.controller.admin.pallet.vo.ErpPalletSaveReqVO import cn.iocoder.yudao.module.erp.dal.dataobject.pallet.ErpPalletDO; import javax.validation.Valid; +import java.io.UnsupportedEncodingException; +import java.util.Collection; import java.util.List; +import java.util.Map; public interface ErpPalletService { @@ -18,7 +21,15 @@ public interface ErpPalletService { ErpPalletDO getPallet(Long id); + List getPalletList(Collection ids); + + Map getPalletMap(Collection ids); + PageResult getPalletPage(ErpPalletPageReqVO pageReqVO); List getPalletListByStatus(Integer status); + + List getOccupiedPalletList(Collection productIds, Collection warehouseIds, Collection areaIds); + + 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/pallet/ErpPalletServiceImpl.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/pallet/ErpPalletServiceImpl.java index 296a77c35..0137928b9 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/pallet/ErpPalletServiceImpl.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/pallet/ErpPalletServiceImpl.java @@ -2,6 +2,9 @@ package cn.iocoder.yudao.module.erp.service.pallet; 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.pallet.vo.ErpPalletPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.pallet.vo.ErpPalletSaveReqVO; @@ -16,10 +19,15 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.io.UnsupportedEncodingException; +import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.PALLET_CODE_EMPTY; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.PALLET_CODE_EXISTS; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.PALLET_NOT_EXISTS; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.PRODUCT_NOT_EXISTS; @@ -40,6 +48,8 @@ public class ErpPalletServiceImpl implements ErpPalletService { private WarehouseAreaService warehouseAreaService; @Resource private ErpProductService productService; + @Resource + private QrcodeRecordService qrcodeService; @Override public Long createPallet(ErpPalletSaveReqVO createReqVO) { @@ -55,6 +65,7 @@ public class ErpPalletServiceImpl implements ErpPalletService { pallet.setQrcode(pallet.getCode()); } palletMapper.insert(pallet); + generatePalletQrcode(pallet.getId(), pallet.getCode()); return pallet.getId(); } @@ -86,6 +97,16 @@ public class ErpPalletServiceImpl implements ErpPalletService { return palletMapper.selectById(id); } + @Override + public List getPalletList(Collection ids) { + return ids == null || ids.isEmpty() ? Collections.emptyList() : palletMapper.selectBatchIds(ids); + } + + @Override + public Map getPalletMap(Collection ids) { + return convertMap(getPalletList(ids), ErpPalletDO::getId); + } + @Override public PageResult getPalletPage(ErpPalletPageReqVO pageReqVO) { return palletMapper.selectPage(pageReqVO); @@ -96,6 +117,28 @@ public class ErpPalletServiceImpl implements ErpPalletService { return palletMapper.selectListByStatus(status); } + @Override + public List getOccupiedPalletList(Collection productIds, Collection warehouseIds, + Collection areaIds) { + return palletMapper.selectOccupiedList(productIds, warehouseIds, areaIds); + } + + @Override + public void regenerateCode(Long id, String code) throws UnsupportedEncodingException { + validatePalletExists(id); + if (StringUtils.isBlank(code)) { + throw exception(PALLET_CODE_EMPTY); + } + CodeTypeEnum codeType = autoCodeUtil.queryCodeType("PALLET_CODE_GENERATE"); + qrcodeService.regenerateByCodeType( + QrcodeBizTypeEnum.PALLET, + id, + code, + "DETAIL", + codeType.getCode() + ); + } + private ErpPalletDO validatePalletExists(Long id) { ErpPalletDO pallet = palletMapper.selectById(id); if (pallet == null) { @@ -141,4 +184,22 @@ public class ErpPalletServiceImpl implements ErpPalletService { throw exception(PRODUCT_NOT_EXISTS); } } + + private void generatePalletQrcode(Long id, String code) { + CodeTypeEnum codeType = autoCodeUtil.queryCodeType("PALLET_CODE_GENERATE"); + if (codeType == null) { + return; + } + try { + qrcodeService.generateOrRefresh( + QrcodeBizTypeEnum.PALLET, + id, + code, + "DETAIL", + codeType + ); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } } 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 22339826a..4d70b6ba6 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 @@ -34,6 +34,7 @@ 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; @@ -89,6 +90,8 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { private PermissionApi permissionApi; @Autowired private AutoCodeUtil autoCodeUtil; + @Resource + private ConfigApi configApi; @Override @Transactional(rollbackFor = Exception.class) @@ -115,6 +118,7 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { ErpStockCheckDO stockCheck = BeanUtils.toBean(createReqVO, ErpStockCheckDO.class, in -> in .setNo(finalCode) + .setNeedAudit(needAudit()) .setStatus(ErpAuditStatus.DRAFT.getStatus()) .setTotalCount(getSumValue(stockCheckItems, ErpStockCheckItemDO::getCount, BigDecimal::add, BigDecimal.ZERO)) .setTotalPrice(getSumValue(stockCheckItems, ErpStockCheckItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO))); @@ -138,6 +142,7 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { validateSourceType(updateReqVO.getSourceType()); List stockCheckItems = validateStockCheckItems(updateReqVO.getItems()); ErpStockCheckDO updateObj = BeanUtils.toBean(updateReqVO, ErpStockCheckDO.class, in -> in + .setNeedAudit(needAudit()) .setTotalCount(getSumValue(stockCheckItems, ErpStockCheckItemDO::getCount, BigDecimal::add, BigDecimal.ZERO)) .setTotalPrice(getSumValue(stockCheckItems, ErpStockCheckItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO))); stockCheckMapper.updateById(updateObj); @@ -185,15 +190,16 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { throw exception(STOCK_CHECK_SUBMIT_FAIL_STATUS); } + Integer fromStatus = stockCheck.getStatus(); Long auditUserId = submitReqVO.getAuditUserId() != null ? submitReqVO.getAuditUserId() : stockCheck.getAuditUserId(); - if (auditUserId == null) { - throw exception(STOCK_CHECK_SUBMIT_FAIL_AUDIT_USER_EMPTY); + if (auditUserId != null) { + adminUserApi.validateUser(auditUserId); } - adminUserApi.validateUser(auditUserId); - Integer fromStatus = stockCheck.getStatus(); - int updateCount = stockCheckMapper.updateByIdAndStatus(stockCheck.getId(), fromStatus, - new ErpStockCheckDO().setAuditUserId(auditUserId).setStatus(ErpAuditStatus.PROCESS.getStatus())); + ErpStockCheckDO updateObj = new ErpStockCheckDO() + .setAuditUserId(auditUserId) + .setStatus(ErpAuditStatus.PROCESS.getStatus()); + int updateCount = stockCheckMapper.updateByIdAndStatus(stockCheck.getId(), fromStatus, updateObj); if (updateCount == 0) { throw exception(STOCK_CHECK_SUBMIT_FAIL_STATUS); } @@ -206,8 +212,23 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { @Transactional(rollbackFor = Exception.class) public void auditStockCheck(ErpStockCheckAuditReqVO auditReqVO) { ErpStockCheckDO stockCheck = validateStockCheckExists(auditReqVO.getId()); - if (!ErpAuditStatus.PROCESS.getStatus().equals(stockCheck.getStatus())) { - throw exception(STOCK_CHECK_AUDIT_FAIL_STATUS); +// if (!ErpAuditStatus.PROCESS.getStatus().equals(stockCheck.getStatus())) { +// throw exception(STOCK_CHECK_AUDIT_FAIL_STATUS); +// } + + Integer fromStatus = stockCheck.getStatus(); + if (!needAudit()) { + int updateCount = stockCheckMapper.updateByIdAndStatus(stockCheck.getId(), fromStatus, + new ErpStockCheckDO().setNeedAudit(false).setStatus(ErpAuditStatus.APPROVE.getStatus())); + if (updateCount == 0) { + throw exception(STOCK_CHECK_AUDIT_FAIL_STATUS); + } + List stockCheckItems = stockCheckItemMapper.selectListByCheckId(stockCheck.getId()); + applyStockCheckEffect(stockCheck, stockCheckItems); + createApproveRecord(stockCheck.getId(), ErpStockCheckApproveActionEnum.AUTO_APPROVE, + fromStatus, ErpAuditStatus.APPROVE.getStatus(), NumberUtils.parseLong(stockCheck.getCreator()), + auditReqVO.getRemark() != null ? auditReqVO.getRemark() : "无需审核,审核时自动盘点"); + return; } Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); @@ -220,9 +241,8 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { throw exception(STOCK_CHECK_AUDIT_FAIL_RESULT); } - Integer fromStatus = stockCheck.getStatus(); int updateCount = stockCheckMapper.updateByIdAndStatus(stockCheck.getId(), fromStatus, - new ErpStockCheckDO().setStatus(auditReqVO.getStatus())); + new ErpStockCheckDO().setNeedAudit(true).setStatus(auditReqVO.getStatus())); if (updateCount == 0) { throw exception(STOCK_CHECK_AUDIT_FAIL_STATUS); } @@ -296,7 +316,7 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { } boolean nonZeroOnly = Boolean.FALSE.equals(reqVO.getAllowEmpty()); List stockList = stockMapper.selectListByWarehouseIdsAndAreaIds( - reqVO.getWarehouseIds(), reqVO.getAreaIds(), nonZeroOnly); + reqVO.getWarehouseIds(), reqVO.getAreaIds(), nonZeroOnly, reqVO.getCategoryType()); return buildPreviewItems(stockList); } @@ -306,7 +326,7 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { return Collections.emptyList(); } boolean nonZeroOnly = Boolean.FALSE.equals(reqVO.getAllowEmpty()); - List stockList = stockMapper.selectListByProductIds(reqVO.getProductIds(), nonZeroOnly); + List stockList = stockMapper.selectListByProductIds(reqVO.getProductIds(), nonZeroOnly, reqVO.getCategoryType()); return buildPreviewItems(stockList); } @@ -481,6 +501,10 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService { .build()); } + private boolean needAudit() { + return !"0".equals(configApi.getConfigValueByCategoryAndKey("biz", "inventoryAudit")); + } + private ErpStockCheckDO validateStockCheckExists(Long id) { ErpStockCheckDO stockCheck = stockCheckMapper.selectById(id); if (stockCheck == null) { diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockInService.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockInService.java index b040af898..2f57ce7bd 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockInService.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockInService.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInSubmit 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; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemPalletDO; import javax.validation.Valid; import java.util.Collection; @@ -37,6 +38,10 @@ public interface ErpStockInService { List getStockInItemListByInIds(Collection inIds); + List getStockInItemPalletListByInId(Long inId); + + List getStockInItemPalletListByInIds(Collection inIds); + List getStockInApproveRecordList(Long stockInId); void updateMoldStatus(Long id, Integer status); 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 f17cec123..34f8feb6c 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 @@ -10,19 +10,24 @@ import cn.iocoder.yudao.module.common.controller.admin.mold.vo.MoldBrandSaveReqV import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldBrandDO; import cn.iocoder.yudao.module.common.dal.mysql.mold.MoldBrandMapper; import cn.iocoder.yudao.module.common.enums.MoldBrandStatusEnum; +import cn.iocoder.yudao.module.erp.controller.admin.pallet.enums.ErpPalletStatusEnum; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInAuditReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInSubmitReqVO; 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.stock.ErpStockInApproveRecordDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemPalletDO; 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.dal.mysql.pallet.ErpPalletMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInApproveRecordMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInItemMapper; +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInItemPalletMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMapper; import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; @@ -49,9 +54,11 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList; @@ -71,6 +78,7 @@ import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_SUBM import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_SUBMIT_FAIL_USER; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_UPDATE_FAIL_APPROVE; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_UPDATE_FAIL_PROCESS; +import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.PALLET_NOT_EXISTS; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_AREA_NOT_EXISTS; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_LOCATION_WAREHOUSE_AREA_NOT_MATCH; @@ -85,10 +93,14 @@ public class ErpStockInServiceImpl implements ErpStockInService { @Resource private ErpStockInItemMapper stockInItemMapper; @Resource + private ErpStockInItemPalletMapper stockInItemPalletMapper; + @Resource private ErpStockInApproveRecordMapper stockInApproveRecordMapper; @Resource private ErpStockMapper erpStockMapper; @Resource + private ErpPalletMapper palletMapper; + @Resource private ErpNoRedisDAO noRedisDAO; @Resource private ErpProductService productService; @@ -135,6 +147,7 @@ public class ErpStockInServiceImpl implements ErpStockInService { stockInMapper.insert(stockIn); stockInItems.forEach(item -> item.setInId(stockIn.getId())); stockInItemMapper.insertBatch(stockInItems); + saveStockInItemPallets(stockIn.getId(), stockInItems, createReqVO.getItems()); if (createReqVO.getInType().equals("模具入库")){ //修改模具组状态 @@ -174,6 +187,7 @@ public class ErpStockInServiceImpl implements ErpStockInService { .setTotalPrice(getSumValue(stockInItems, ErpStockInItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO))); stockInMapper.updateById(updateObj); updateStockInItemList(updateReqVO.getId(), stockInItems); + saveStockInItemPallets(updateReqVO.getId(), stockInItems, updateReqVO.getItems()); } @Override @@ -215,27 +229,12 @@ public class ErpStockInServiceImpl implements ErpStockInService { throw exception(STOCK_IN_SUBMIT_FAIL_STATUS); } Integer fromStatus = stockIn.getStatus(); - if (!Boolean.TRUE.equals(stockIn.getNeedAudit())) { - int updateCount = stockInMapper.updateByIdAndStatus(stockIn.getId(), fromStatus, - new ErpStockInDO().setStatus(ErpAuditStatus.APPROVE.getStatus())); - if (updateCount == 0) { - throw exception(STOCK_IN_SUBMIT_FAIL_STATUS); - } - List stockInItems = stockInItemMapper.selectListByInId(stockIn.getId()); - applyStockInEffect(stockIn, stockInItems, null); - createApproveRecord(stockIn.getId(), ErpStockInApproveActionEnum.AUTO_APPROVE, fromStatus, - ErpAuditStatus.APPROVE.getStatus(), null, - submitReqVO.getRemark() != null ? submitReqVO.getRemark() : "无需审核,提交后自动入库"); - return; - } Long auditUserId = submitReqVO.getAuditUserId() != null ? submitReqVO.getAuditUserId() : stockIn.getAuditUserId(); - if (auditUserId == null) { - throw exception(STOCK_IN_SUBMIT_FAIL_AUDIT_USER_EMPTY); + if (auditUserId != null) { + adminUserApi.validateUser(auditUserId); } - adminUserApi.validateUser(auditUserId); ErpStockInDO updateObj = new ErpStockInDO() .setAuditUserId(auditUserId) - .setNeedAudit(true) .setStatus(ErpAuditStatus.PROCESS.getStatus()); int updateCount = stockInMapper.updateByIdAndStatus(stockIn.getId(), fromStatus, updateObj); if (updateCount == 0) { @@ -249,8 +248,23 @@ public class ErpStockInServiceImpl implements ErpStockInService { @Transactional(rollbackFor = Exception.class) public void auditStockIn(ErpStockInAuditReqVO auditReqVO) { ErpStockInDO stockIn = validateStockInExists(auditReqVO.getId()); - if (!ErpAuditStatus.PROCESS.getStatus().equals(stockIn.getStatus())) { - throw exception(STOCK_IN_AUDIT_FAIL_STATUS); +// if (!ErpAuditStatus.PROCESS.getStatus().equals(stockIn.getStatus())) { +// throw exception(STOCK_IN_AUDIT_FAIL_STATUS); +// } + + Integer fromStatus = stockIn.getStatus(); + if (!needAudit()) { + int updateCount = stockInMapper.updateByIdAndStatus(stockIn.getId(), fromStatus, + new ErpStockInDO().setNeedAudit(false).setStatus(ErpAuditStatus.APPROVE.getStatus())); + if (updateCount == 0) { + throw exception(STOCK_IN_AUDIT_FAIL_STATUS); + } + List stockInItems = stockInItemMapper.selectListByInId(stockIn.getId()); + applyStockInEffect(stockIn, stockInItems, null); + createApproveRecord(stockIn.getId(), ErpStockInApproveActionEnum.AUTO_APPROVE, fromStatus, + ErpAuditStatus.APPROVE.getStatus(), NumberUtils.parseLong(stockIn.getCreator()), + auditReqVO.getRemark() != null ? auditReqVO.getRemark() : "无需审核,审核时自动入库"); + return; } Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); boolean adminCanAudit = permissionApi.hasAnyRoles(loginUserId, RoleCodeEnum.SUPER_ADMIN.getCode()); @@ -262,9 +276,8 @@ public class ErpStockInServiceImpl implements ErpStockInService { throw exception(STOCK_IN_AUDIT_FAIL_RESULT); } - Integer fromStatus = stockIn.getStatus(); int updateCount = stockInMapper.updateByIdAndStatus(stockIn.getId(), fromStatus, - new ErpStockInDO().setStatus(auditReqVO.getStatus())); + new ErpStockInDO().setNeedAudit(true).setStatus(auditReqVO.getStatus())); if (updateCount == 0) { throw exception(STOCK_IN_AUDIT_FAIL_STATUS); } @@ -297,6 +310,7 @@ public class ErpStockInServiceImpl implements ErpStockInService { stockIns.forEach(stockIn -> { stockInMapper.deleteById(stockIn.getId()); stockInItemMapper.deleteByInId(stockIn.getId()); + stockInItemPalletMapper.deleteByInId(stockIn.getId()); stockInApproveRecordMapper.deleteByStockInId(stockIn.getId()); }); } @@ -340,6 +354,19 @@ public class ErpStockInServiceImpl implements ErpStockInService { return stockInItemMapper.selectListByInIds(inIds); } + @Override + public List getStockInItemPalletListByInId(Long inId) { + return stockInItemPalletMapper.selectListByInId(inId); + } + + @Override + public List getStockInItemPalletListByInIds(Collection inIds) { + if (CollUtil.isEmpty(inIds)) { + return Collections.emptyList(); + } + return stockInItemPalletMapper.selectListByInIds(inIds); + } + @Override public List getStockInApproveRecordList(Long stockInId) { return stockInApproveRecordMapper.selectListByStockInId(stockInId); @@ -386,6 +413,7 @@ public class ErpStockInServiceImpl implements ErpStockInService { recordBizType, stockInItem.getInId(), stockInItem.getId(), stockIn.getNo(), stockIn.getInTime())); } }); + operateStockInPalletEffect(stockIn.getId(), stockInItems, approve); } private Integer resolveRecordBizType(String inType, boolean approve, Integer bizType) { @@ -445,6 +473,8 @@ public class ErpStockInServiceImpl implements ErpStockInService { .packagingSchemeId(item.getPackagingSchemeId()) .inputUnitType(item.getInputUnitType()) .inputCount(item.getInputCount()) + .relateTask(item.getRelateTask()) + .taskId(item.getTaskId()) .totalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount())) .remark(item.getRemark()) .deviceId(item.getDeviceId()) @@ -452,6 +482,7 @@ public class ErpStockInServiceImpl implements ErpStockInService { }); } validateWarehouseAreas(list); + validatePallets(list); List productList = productService.validProductList(convertSet(list, ErpStockInSaveReqVO.Item::getProductId)); @@ -468,6 +499,20 @@ public class ErpStockInServiceImpl implements ErpStockInService { .setTotalPrice(MoneyUtils.priceMultiply(target.getProductPrice(), target.getCount())))); } + 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)); + if (CollUtil.isEmpty(palletIds)) { + return; + } + Map palletMap = convertMap(palletMapper.selectBatchIds(palletIds), ErpPalletDO::getId); + palletIds.forEach(palletId -> { + if (!palletMap.containsKey(palletId)) { + throw exception(PALLET_NOT_EXISTS); + } + }); + } + private void validateWarehouseAreas(List list) { Map warehouseMap = convertMap( warehouseService.validWarehouseList(convertSet(list, ErpStockInSaveReqVO.Item::getWarehouseId)), @@ -513,4 +558,72 @@ public class ErpStockInServiceImpl implements ErpStockInService { stockInItemMapper.deleteBatchIds(convertList(diffList.get(2), ErpStockInItemDO::getId)); } } + + private void saveStockInItemPallets(Long inId, List stockInItems, + List reqItems) { + stockInItemPalletMapper.deleteByInId(inId); + if (CollUtil.isEmpty(stockInItems) || CollUtil.isEmpty(reqItems)) { + return; + } + List palletRelations = CollUtil.newArrayList(); + for (int i = 0; i < Math.min(stockInItems.size(), reqItems.size()); i++) { + ErpStockInItemDO stockInItem = stockInItems.get(i); + ErpStockInSaveReqVO.Item reqItem = reqItems.get(i); + if (stockInItem.getId() == null || CollUtil.isEmpty(reqItem.getPallets())) { + continue; + } + reqItem.getPallets().forEach(pallet -> palletRelations.add(ErpStockInItemPalletDO.builder() + .inId(inId) + .inItemId(stockInItem.getId()) + .palletId(pallet.getPalletId()) + .packageCount(defaultPackageCount(pallet.getPackageCount(), stockInItem.getCount())) + .build())); + } + if (CollUtil.isNotEmpty(palletRelations)) { + stockInItemPalletMapper.insertBatch(palletRelations); + } + } + + private void operateStockInPalletEffect(Long inId, List stockInItems, boolean approve) { + List palletRelations = stockInItemPalletMapper.selectListByInId(inId); + if (CollUtil.isEmpty(palletRelations)) { + return; + } + Map itemMap = convertMap(stockInItems, ErpStockInItemDO::getId); + Map palletMap = convertMap(palletMapper.selectBatchIds( + convertSet(palletRelations, ErpStockInItemPalletDO::getPalletId)), ErpPalletDO::getId); + palletRelations.forEach(relation -> { + ErpStockInItemDO item = itemMap.get(relation.getInItemId()); + ErpPalletDO pallet = palletMap.get(relation.getPalletId()); + if (item == null || pallet == null) { + return; + } + BigDecimal packageCount = defaultZero(relation.getPackageCount()); + if (approve) { + pallet.setStatus(ErpPalletStatusEnum.OCCUPIED.getStatus()); + pallet.setProductId(item.getProductId()); + pallet.setProductCount(defaultZero(pallet.getProductCount()).add(packageCount)); + pallet.setWarehouseId(item.getWarehouseId()); + pallet.setAreaId(item.getAreaId()); + } else { + BigDecimal remainCount = defaultZero(pallet.getProductCount()).subtract(packageCount); + if (remainCount.compareTo(BigDecimal.ZERO) <= 0) { + pallet.setStatus(ErpPalletStatusEnum.IDLE.getStatus()); + pallet.setProductId(null); + pallet.setProductCount(BigDecimal.ZERO); + } else { + pallet.setProductCount(remainCount); + } + } + palletMapper.updateById(pallet); + }); + } + + private BigDecimal defaultPackageCount(BigDecimal packageCount, BigDecimal itemCount) { + return packageCount != null ? packageCount : defaultZero(itemCount); + } + + private BigDecimal defaultZero(BigDecimal value) { + return value != null ? value : BigDecimal.ZERO; + } } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutService.java b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutService.java index da07fd9ad..4aba89c84 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutService.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/main/java/cn/iocoder/yudao/module/erp/service/stock/ErpStockOutService.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSave import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutApproveRecordDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemPalletDO; import javax.validation.Valid; import java.util.Collection; @@ -90,6 +91,10 @@ public interface ErpStockOutService { */ List getStockOutItemListByOutIds(Collection outIds); + List getStockOutItemPalletListByOutId(Long outId); + + List getStockOutItemPalletListByOutIds(Collection outIds); + List getStockOutApproveRecordList(Long stockOutId); List selectByOutType(List outTypes); 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 415b7d583..2b097c11d 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 @@ -10,20 +10,25 @@ import cn.iocoder.yudao.module.common.controller.admin.mold.vo.MoldBrandSaveReqV import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldBrandDO; import cn.iocoder.yudao.module.common.dal.mysql.mold.MoldBrandMapper; import cn.iocoder.yudao.module.common.enums.MoldBrandStatusEnum; +import cn.iocoder.yudao.module.erp.controller.admin.pallet.enums.ErpPalletStatusEnum; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutAuditReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSaveReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSaveReqVOItem; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSubmitReqVO; +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.stock.ErpStockOutApproveRecordDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO; +import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemPalletDO; 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.dal.mysql.pallet.ErpPalletMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutApproveRecordMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutItemMapper; +import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutItemPalletMapper; import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockOutMapper; import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO; import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus; @@ -58,6 +63,7 @@ import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList; @@ -79,8 +85,12 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { @Resource private ErpStockOutItemMapper stockOutItemMapper; @Resource + private ErpStockOutItemPalletMapper stockOutItemPalletMapper; + @Resource private ErpStockOutApproveRecordMapper stockOutApproveRecordMapper; @Resource + private ErpPalletMapper palletMapper; + @Resource private ErpNoRedisDAO noRedisDAO; @Resource private ErpProductService productService; @@ -137,6 +147,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { stockOutMapper.insert(stockOut); stockOutItems.forEach(item -> item.setOutId(stockOut.getId())); stockOutItemMapper.insertBatch(stockOutItems); + saveStockOutItemPallets(stockOut.getId(), stockOutItems, createReqVO.getItems()); if (createReqVO.getOutType().equals("模具出库")) { //修改模具组状态 @@ -179,6 +190,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { fillUsageSnapshot(stockOutItems, updateReqVO.getItems()); stockOutMapper.updateById(updateObj); updateStockOutItemList(updateReqVO.getId(), stockOutItems); + saveStockOutItemPallets(updateReqVO.getId(), stockOutItems, updateReqVO.getItems()); } @Override @@ -220,27 +232,12 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { throw exception(STOCK_OUT_SUBMIT_FAIL_STATUS); } Integer fromStatus = stockOut.getStatus(); - if (!Boolean.TRUE.equals(stockOut.getNeedAudit())) { - int updateCount = stockOutMapper.updateByIdAndStatus(stockOut.getId(), fromStatus, - new ErpStockOutDO().setStatus(ErpAuditStatus.APPROVE.getStatus())); - if (updateCount == 0) { - throw exception(STOCK_OUT_SUBMIT_FAIL_STATUS); - } - List stockOutItems = stockOutItemMapper.selectListByOutId(stockOut.getId()); - applyStockOutEffect(stockOut, stockOutItems, null); - createApproveRecord(stockOut.getId(), ErpStockOutApproveActionEnum.AUTO_APPROVE, fromStatus, - ErpAuditStatus.APPROVE.getStatus(), null, - submitReqVO.getRemark() != null ? submitReqVO.getRemark() : "无需审核,提交后自动出库"); - return; - } Long auditUserId = submitReqVO.getAuditUserId() != null ? submitReqVO.getAuditUserId() : stockOut.getAuditUserId(); - if (auditUserId == null) { - throw exception(STOCK_OUT_SUBMIT_FAIL_AUDIT_USER_EMPTY); + if (auditUserId != null) { + adminUserApi.validateUser(auditUserId); } - adminUserApi.validateUser(auditUserId); ErpStockOutDO updateObj = new ErpStockOutDO() .setAuditUserId(auditUserId) - .setNeedAudit(true) .setStatus(ErpAuditStatus.PROCESS.getStatus()); int updateCount = stockOutMapper.updateByIdAndStatus(stockOut.getId(), fromStatus, updateObj); if (updateCount == 0) { @@ -254,8 +251,23 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { @Transactional(rollbackFor = Exception.class) public void auditStockOut(ErpStockOutAuditReqVO auditReqVO) { ErpStockOutDO stockOut = validateStockOutExists(auditReqVO.getId()); - if (!ErpAuditStatus.PROCESS.getStatus().equals(stockOut.getStatus())) { - throw exception(STOCK_OUT_AUDIT_FAIL_STATUS); +// if (!ErpAuditStatus.PROCESS.getStatus().equals(stockOut.getStatus())) { +// throw exception(STOCK_OUT_AUDIT_FAIL_STATUS); +// } + + Integer fromStatus = stockOut.getStatus(); + if (!needAudit()) { + int updateCount = stockOutMapper.updateByIdAndStatus(stockOut.getId(), fromStatus, + new ErpStockOutDO().setNeedAudit(false).setStatus(ErpAuditStatus.APPROVE.getStatus())); + if (updateCount == 0) { + throw exception(STOCK_OUT_AUDIT_FAIL_STATUS); + } + List stockOutItems = stockOutItemMapper.selectListByOutId(stockOut.getId()); + applyStockOutEffect(stockOut, stockOutItems, null); + createApproveRecord(stockOut.getId(), ErpStockOutApproveActionEnum.AUTO_APPROVE, fromStatus, + ErpAuditStatus.APPROVE.getStatus(), NumberUtils.parseLong(stockOut.getCreator()), + auditReqVO.getRemark() != null ? auditReqVO.getRemark() : "无需审核,审核时自动出库"); + return; } Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); @@ -270,9 +282,8 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { throw exception(STOCK_OUT_AUDIT_FAIL_RESULT); } - Integer fromStatus = stockOut.getStatus(); int updateCount = stockOutMapper.updateByIdAndStatus(stockOut.getId(), fromStatus, - new ErpStockOutDO().setStatus(auditReqVO.getStatus())); + new ErpStockOutDO().setNeedAudit(true).setStatus(auditReqVO.getStatus())); if (updateCount == 0) { throw exception(STOCK_OUT_AUDIT_FAIL_STATUS); } @@ -305,6 +316,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { stockOuts.forEach(stockOut -> { stockOutMapper.deleteById(stockOut.getId()); stockOutItemMapper.deleteByOutId(stockOut.getId()); + stockOutItemPalletMapper.deleteByOutId(stockOut.getId()); stockOutApproveRecordMapper.deleteByStockOutId(stockOut.getId()); }); } @@ -340,6 +352,19 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { return stockOutItemMapper.selectListByOutIds(outIds); } + @Override + public List getStockOutItemPalletListByOutId(Long outId) { + return stockOutItemPalletMapper.selectListByOutId(outId); + } + + @Override + public List getStockOutItemPalletListByOutIds(Collection outIds) { + if (CollUtil.isEmpty(outIds)) { + return Collections.emptyList(); + } + return stockOutItemPalletMapper.selectListByOutIds(outIds); + } + @Override public List getStockOutApproveRecordList(Long stockOutId) { return stockOutApproveRecordMapper.selectListByStockOutId(stockOutId); @@ -401,6 +426,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { recordBizType, stockOutItem.getOutId(), stockOutItem.getId(), stockOut.getNo(), stockOut.getOutTime())); } }); + operateStockOutPalletEffect(stockOut.getId(), stockOutItems, approve); } private boolean itemNeedUpdateMoldStatus(MoldBrandDO moldDO) { @@ -477,6 +503,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { .productUnitId(null) .productPrice(item.getProductPrice()) .count(item.getCount()) + .outMode(item.getOutMode()) .totalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount())) .outUsageType(item.getOutUsageType()) .outUsageTypeName(ErpStockOutUsageTypeEnum.getNameByType(item.getOutUsageType())) @@ -487,6 +514,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { .build(); }); } + validatePallets(list); List productList = productService.validProductList(convertSet(list, ErpStockOutSaveReqVOItem::getProductId)); Map productMap = convertMap(productList, ErpProductDO::getId); Map areaMap = warehouseAreaService.getWarehouseAreaMap( @@ -505,6 +533,20 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { .setMaintenanceName(null))); } + private void validatePallets(List list) { + List palletIds = convertListByFlatMap(list, item -> item.getPallets() == null ? java.util.stream.Stream.empty() + : item.getPallets().stream().map(ErpStockOutSaveReqVOItem.PalletItem::getPalletId)); + if (CollUtil.isEmpty(palletIds)) { + return; + } + Map palletMap = convertMap(palletMapper.selectBatchIds(palletIds), ErpPalletDO::getId); + palletIds.forEach(palletId -> { + if (!palletMap.containsKey(palletId)) { + throw exception(PALLET_NOT_EXISTS); + } + }); + } + private void validateWarehouseAreas(List list) { Map warehouseMap = convertMap( warehouseService.validWarehouseList(convertSet(list, ErpStockOutSaveReqVOItem::getWarehouseId)), @@ -553,4 +595,72 @@ public class ErpStockOutServiceImpl implements ErpStockOutService { } } + private void saveStockOutItemPallets(Long outId, List stockOutItems, + List reqItems) { + stockOutItemPalletMapper.deleteByOutId(outId); + if (CollUtil.isEmpty(stockOutItems) || CollUtil.isEmpty(reqItems)) { + return; + } + List palletRelations = CollUtil.newArrayList(); + for (int i = 0; i < Math.min(stockOutItems.size(), reqItems.size()); i++) { + ErpStockOutItemDO stockOutItem = stockOutItems.get(i); + ErpStockOutSaveReqVOItem reqItem = reqItems.get(i); + if (stockOutItem.getId() == null || CollUtil.isEmpty(reqItem.getPallets())) { + continue; + } + reqItem.getPallets().forEach(pallet -> palletRelations.add(ErpStockOutItemPalletDO.builder() + .outId(outId) + .outItemId(stockOutItem.getId()) + .palletId(pallet.getPalletId()) + .packageCount(defaultPackageCount(pallet.getPackageCount(), stockOutItem.getCount())) + .build())); + } + if (CollUtil.isNotEmpty(palletRelations)) { + stockOutItemPalletMapper.insertBatch(palletRelations); + } + } + + private void operateStockOutPalletEffect(Long outId, List stockOutItems, boolean approve) { + List palletRelations = stockOutItemPalletMapper.selectListByOutId(outId); + if (CollUtil.isEmpty(palletRelations)) { + return; + } + Map itemMap = convertMap(stockOutItems, ErpStockOutItemDO::getId); + Map palletMap = convertMap(palletMapper.selectBatchIds( + convertSet(palletRelations, ErpStockOutItemPalletDO::getPalletId)), ErpPalletDO::getId); + palletRelations.forEach(relation -> { + ErpStockOutItemDO item = itemMap.get(relation.getOutItemId()); + ErpPalletDO pallet = palletMap.get(relation.getPalletId()); + if (item == null || pallet == null) { + return; + } + BigDecimal packageCount = defaultZero(relation.getPackageCount()); + if (approve) { + BigDecimal remainCount = defaultZero(pallet.getProductCount()).subtract(packageCount); + if (remainCount.compareTo(BigDecimal.ZERO) <= 0) { + pallet.setStatus(ErpPalletStatusEnum.IDLE.getStatus()); + pallet.setProductId(null); + pallet.setProductCount(BigDecimal.ZERO); + } else { + pallet.setProductCount(remainCount); + } + } else { + pallet.setStatus(ErpPalletStatusEnum.OCCUPIED.getStatus()); + pallet.setProductId(item.getProductId()); + pallet.setProductCount(defaultZero(pallet.getProductCount()).add(packageCount)); + pallet.setWarehouseId(item.getWarehouseId()); + pallet.setAreaId(item.getAreaId()); + } + palletMapper.updateById(pallet); + }); + } + + private BigDecimal defaultPackageCount(BigDecimal packageCount, BigDecimal itemCount) { + return packageCount != null ? packageCount : defaultZero(itemCount); + } + + private BigDecimal defaultZero(BigDecimal value) { + return value != null ? value : BigDecimal.ZERO; + } + } diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/TaskController.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/TaskController.java index 3a305589a..cf9674a11 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/TaskController.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/TaskController.java @@ -216,6 +216,16 @@ public class TaskController { public CommonResult> getTaskDetailListByTaskId(@RequestParam("taskId") Long taskId) { return success(taskService.buildDetailVOList(taskService.getTaskDetailListByTaskId(taskId))); } + + @GetMapping("/task-detail/default-packaging-schemes") + @Operation(summary = "获得生产任务单明细产品默认包装方案列表") + @Parameter(name = "taskId", description = "task ID", required = true) + @PreAuthorize("@ss.hasPermission('mes:task:query')") + public CommonResult getTaskProductDefaultPackagingSchemes( + @RequestParam("taskId") Long taskId) { + return success(taskService.getTaskProductDefaultPackagingSchemes(taskId)); + } + // ==================== 子表(生产任务单明细) ==================== @GetMapping("/task-detail/page") @@ -266,4 +276,4 @@ public class TaskController { public CommonResult> getTaskDetailSummary(@RequestParam("taskId") Long taskId) { return success(taskService.getTaskProductSummaryList(taskId)); } -} \ No newline at end of file +} diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskPackagingSchemeRespVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskPackagingSchemeRespVO.java new file mode 100644 index 000000000..16b2346bf --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskPackagingSchemeRespVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.mes.controller.admin.task.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Schema(description = "管理后台 - 生产任务单默认包装方案 Response VO") +@Data +public class TaskPackagingSchemeRespVO { + + @Schema(description = "任务单 ID", example = "1") + private Long taskId; + + @Schema(description = "任务单名称", example = "RW20240618001") + private String taskName; + + @Schema(description = "产品默认包装方案列表") + private List products; + +} diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskProductPackagingSchemeRespVO.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskProductPackagingSchemeRespVO.java new file mode 100644 index 000000000..da5647607 --- /dev/null +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/task/vo/TaskProductPackagingSchemeRespVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.mes.controller.admin.task.vo; + +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductPackagingSchemeRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Schema(description = "管理后台 - 生产任务单产品默认包装方案 Response VO") +@Data +public class TaskProductPackagingSchemeRespVO { + + @Schema(description = "产品 ID", example = "1") + private Long productId; + + @Schema(description = "产品编码", example = "CP001") + private String productCode; + + @Schema(description = "产品名称", example = "产品A") + private String productName; + + @Schema(description = "任务明细 ID 列表") + private List taskDetailIds; + + @Schema(description = "默认包装方案列表") + private List packagingSchemes; + +} diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskService.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskService.java index a13f4e298..40b39d2c0 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskService.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskService.java @@ -96,6 +96,7 @@ public interface TaskService { */ List getTaskDetailListByTaskId(Long taskId); List buildDetailVOList(List list); + TaskPackagingSchemeRespVO getTaskProductDefaultPackagingSchemes(Long taskId); /** * 获得生产任务单明细分页 * diff --git a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskServiceImpl.java b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskServiceImpl.java index 83c66d602..713bf103e 100644 --- a/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskServiceImpl.java +++ b/yudao-module-mes/yudao-module-mes-biz/src/main/java/cn/iocoder/yudao/module/mes/service/task/TaskServiceImpl.java @@ -6,12 +6,15 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil; +import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductPackagingSchemeRespVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductRelationRespVO; 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.dal.dataobject.productdevicerel.ProductDeviceRelDO; +import cn.iocoder.yudao.module.erp.dal.dataobject.productpackagingschemerel.ProductPackagingSchemeRelDO; import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper; import cn.iocoder.yudao.module.erp.dal.mysql.productdevicerel.ProductDeviceRelMapper; +import cn.iocoder.yudao.module.erp.dal.mysql.productpackagingschemerel.ProductPackagingSchemeRelMapper; import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService; import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; @@ -97,6 +100,8 @@ public class TaskServiceImpl implements TaskService { @Resource private ProductDeviceRelMapper productDeviceRelMapper; + @Resource + private ProductPackagingSchemeRelMapper productPackagingSchemeRelMapper; @Resource private DeviceLedgerService deviceLedgerService; @@ -258,6 +263,42 @@ public class TaskServiceImpl implements TaskService { return taskDetailMapper.selectListByTaskId(taskId); } + @Override + public TaskPackagingSchemeRespVO getTaskProductDefaultPackagingSchemes(Long taskId) { + TaskDO task = getTask(taskId); + TaskPackagingSchemeRespVO result = new TaskPackagingSchemeRespVO(); + result.setTaskId(taskId); + result.setTaskName(task == null ? null : task.getCode()); + List details = getTaskDetailListByTaskId(taskId); + if (CollUtil.isEmpty(details)) { + result.setProducts(Collections.emptyList()); + return result; + } + Set productIds = convertSet(details, TaskDetailDO::getProductId); + Map productMap = productService.getProductMap(productIds); + Map> taskDetailIdMap = details.stream() + .filter(item -> item.getProductId() != null) + .collect(Collectors.groupingBy(TaskDetailDO::getProductId, + Collectors.mapping(TaskDetailDO::getId, Collectors.toList()))); + Map> packagingSchemeMap = productPackagingSchemeRelMapper + .selectListByProductIds(productIds).stream() + .filter(item -> Integer.valueOf(1).equals(item.getDefaultStatus())) + .collect(Collectors.groupingBy(ProductPackagingSchemeRelDO::getProductId, + Collectors.mapping(item -> BeanUtils.toBean(item, ProductPackagingSchemeRespVO.class), + Collectors.toList()))); + result.setProducts(productIds.stream().map(productId -> { + ErpProductDO product = productMap.get(productId); + TaskProductPackagingSchemeRespVO respVO = new TaskProductPackagingSchemeRespVO(); + respVO.setProductId(productId); + respVO.setProductCode(product == null ? null : product.getBarCode()); + respVO.setProductName(product == null ? null : product.getName()); + respVO.setTaskDetailIds(taskDetailIdMap.getOrDefault(productId, Collections.emptyList())); + respVO.setPackagingSchemes(packagingSchemeMap.getOrDefault(productId, Collections.emptyList())); + return respVO; + }).collect(Collectors.toList())); + return result; + } + private void createTaskDetailList(Long taskId, List list) { list.forEach(o -> o.setTaskId(taskId)); taskDetailMapper.insertBatch(list);