fix:修改产品出入库单据相关接口

main
HuangHuiKang 5 days ago
parent 0124acdf5c
commit 234c17c809

@ -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;

@ -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, "其它入库单不存在");

@ -8,6 +8,7 @@ import lombok.RequiredArgsConstructor;
public enum ErpStockCheckApproveActionEnum {
SUBMIT("SUBMIT"),
AUTO_APPROVE("AUTO_APPROVE"),
APPROVE("APPROVE"),
REJECT("REJECT");

@ -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;
}
}

@ -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<ErpPalletRespVO> 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<PageResult<ErpPalletRespVO>> getPalletPage(@Valid ErpPalletPageReqVO pageReqVO) {
PageResult<ErpPalletDO> pageResult = palletService.getPalletPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ErpPalletRespVO.class));
Map<Long, String> qrcodeMap = qrcodeService.selectQrcodeUrlMapByBizTypeAndIds(QrcodeBizTypeEnum.PALLET.getCode(),
convertList(pageResult.getList(), ErpPalletDO::getId));
List<ErpPalletRespVO> 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<ErpPalletDO> pageResult = palletService.getPalletPage(pageReqVO);
Map<Long, String> qrcodeMap = qrcodeService.selectQrcodeUrlMapByBizTypeAndIds(QrcodeBizTypeEnum.PALLET.getCode(),
convertList(pageResult.getList(), ErpPalletDO::getId));
List<ErpPalletRespVO> 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<List<ErpPalletRespVO>> getPalletSimpleList(@RequestParam(value = "status", required = false) Integer status) {
List<ErpPalletDO> list = palletService.getPalletListByStatus(status);
return success(convertList(list, item -> BeanUtils.toBean(item, ErpPalletRespVO.class)));
Map<Long, String> qrcodeMap = qrcodeService.selectQrcodeUrlMapByBizTypeAndIds(QrcodeBizTypeEnum.PALLET.getCode(),
convertList(list, ErpPalletDO::getId));
return success(convertList(list, item -> buildPalletRespVO(item, qrcodeMap)));
}
@PostMapping("/regenerate-code")
public CommonResult<Boolean> 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<Long, String> qrcodeMap) {
ErpPalletRespVO respVO = BeanUtils.toBean(pallet, ErpPalletRespVO.class);
String qrcode = qrcodeMap.get(pallet.getId());
if (qrcode != null) {
respVO.setQrcode(qrcode);
}
return respVO;
}
}

@ -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<Boolean> 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<Boolean> 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<Boolean> auditStockCheck(@Valid @RequestBody ErpStockCheckAuditReqVO auditReqVO) {
stockCheckService.auditStockCheck(auditReqVO);

@ -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<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(
convertSet(pageResult.getList(), ErpStockDO::getAreaId));
Map<String, Long> 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<String, Long> buildPalletCountMap(List<ErpStockDO> 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();
}

@ -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<Boolean> 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<Boolean> auditStockIn(@Valid @RequestBody ErpStockInAuditReqVO auditReqVO) {
stockInService.auditStockIn(auditReqVO);
@ -246,17 +251,23 @@ public class ErpStockInController {
convertSet(allItems, ErpStockInItemDO::getMoldSetId));
Map<Long, List<cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO>> moldListMap = moldService.getMoldListMapByBrandIds(
convertSet(allItems, ErpStockInItemDO::getMoldSetId));
Map<Long, List<ErpStockInItemPalletDO>> itemPalletMap = stockInService.getStockInItemPalletListByInIds(
convertSet(stockIns, ErpStockInDO::getId)).stream()
.collect(Collectors.groupingBy(ErpStockInItemPalletDO::getInItemId));
Map<Long, ErpPalletDO> palletMap = palletService.getPalletMap(
convertSet(convertListByFlatMap(itemPalletMap.values(), Collection::stream), ErpStockInItemPalletDO::getPalletId));
Map<String, ErpStockDO> stockMap = buildStockMap(allItems);
List<ErpStockInRespVO> 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<ErpStockInItemDO> stockInItemList,
List<ErpStockInApproveRecordDO> 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<ErpStockInItemDO> stockInItemList,
@ -268,7 +279,9 @@ public class ErpStockInController {
Map<Long, WarehouseAreaDO> pageAreaMap,
Map<Long, ErpProductRespVO> pageProductMap,
Map<Long, MoldBrandDO> pageMoldMap,
Map<Long, List<cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO>> pageMoldListMap) {
Map<Long, List<cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO>> pageMoldListMap,
Map<Long, List<ErpStockInItemPalletDO>> pageItemPalletMap,
Map<Long, ErpPalletDO> pagePalletMap) {
ErpStockInRespVO stockInVO = BeanUtils.toBean(stockIn, ErpStockInRespVO.class);
stockInVO.setStatusName(getStockInStatusName(stockIn.getStatus()));
Map<Long, ErpWarehouseDO> warehouseMap = pageWarehouseMap != null ? pageWarehouseMap : warehouseService.getWarehouseMap(
@ -278,6 +291,11 @@ public class ErpStockInController {
Map<Long, AdminUserRespDTO> userMap = pageUserMap != null ? pageUserMap : adminUserApi.getUserMap(convertListByFlatMap(
Collections.singletonList(stockIn), item -> Stream.of(NumberUtils.parseLong(item.getCreator()),
item.getStockUserId(), item.getAuditUserId())));
Map<Long, List<ErpStockInItemPalletDO>> itemPalletMap = pageItemPalletMap != null ? pageItemPalletMap
: stockInService.getStockInItemPalletListByInId(stockIn.getId()).stream()
.collect(Collectors.groupingBy(ErpStockInItemPalletDO::getInItemId));
Map<Long, ErpPalletDO> 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<ErpStockInRespVO.Item.PalletItem> buildStockInPalletRespList(List<ErpStockInItemPalletDO> itemPallets,
Map<Long, ErpPalletDO> 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<ErpStockInApproveRecordRespVO> buildApproveRecordRespList(List<ErpStockInApproveRecordDO> records) {
if (CollUtil.isEmpty(records)) {
return new ArrayList<>();

@ -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<Boolean> 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<Boolean> auditStockOut(@Valid @RequestBody ErpStockOutAuditReqVO auditReqVO) {
stockOutService.auditStockOut(auditReqVO);
@ -250,17 +255,22 @@ public class ErpStockOutController {
convertSet(allItems, ErpStockOutItemDO::getMoldSetId));
Map<Long, List<cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO>> moldListMap = moldService.getMoldListMapByBrandIds(
convertSet(allItems, ErpStockOutItemDO::getMoldSetId));
Map<Long, List<ErpStockOutItemPalletDO>> itemPalletMap = stockOutService.getStockOutItemPalletListByOutIds(
convertSet(stockOuts, ErpStockOutDO::getId)).stream()
.collect(Collectors.groupingBy(ErpStockOutItemPalletDO::getOutItemId));
Map<Long, ErpPalletDO> palletMap = palletService.getPalletMap(
convertSet(convertListByFlatMap(itemPalletMap.values(), Collection::stream), ErpStockOutItemPalletDO::getPalletId));
Map<String, ErpStockDO> stockMap = buildStockMap(allItems);
List<ErpStockOutRespVO> 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<ErpStockOutItemDO> stockOutItemList,
List<ErpStockOutApproveRecordDO> 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<ErpStockOutItemDO> stockOutItemList,
@ -270,12 +280,19 @@ public class ErpStockOutController {
Map<String, ErpStockDO> pageStockMap,
Map<Long, ErpProductRespVO> pageProductMap,
Map<Long, MoldBrandDO> pageMoldMap,
Map<Long, List<cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO>> pageMoldListMap) {
Map<Long, List<cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO>> pageMoldListMap,
Map<Long, List<ErpStockOutItemPalletDO>> pageItemPalletMap,
Map<Long, ErpPalletDO> pagePalletMap) {
ErpStockOutRespVO stockOutVO = BeanUtils.toBean(stockOut, ErpStockOutRespVO.class);
stockOutVO.setStatusName(getStockOutStatusName(stockOut.getStatus()));
Map<Long, AdminUserRespDTO> userMap = pageUserMap != null ? pageUserMap : adminUserApi.getUserMap(convertListByFlatMap(
Collections.singletonList(stockOut), item -> Stream.of(NumberUtils.parseLong(item.getCreator()),
item.getResponserId(), item.getAuditUserId())));
Map<Long, List<ErpStockOutItemPalletDO>> itemPalletMap = pageItemPalletMap != null ? pageItemPalletMap
: stockOutService.getStockOutItemPalletListByOutId(stockOut.getId()).stream()
.collect(Collectors.groupingBy(ErpStockOutItemPalletDO::getOutItemId));
Map<Long, ErpPalletDO> 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<ErpStockOutRespVO.Item.PalletItem> buildStockOutPalletRespList(List<ErpStockOutItemPalletDO> itemPallets,
Map<Long, ErpPalletDO> 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<ErpStockOutApproveRecordRespVO> buildApproveRecordRespList(List<ErpStockOutApproveRecordDO> records) {
if (CollUtil.isEmpty(records)) {
return new ArrayList<>();

@ -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());
}

@ -17,4 +17,7 @@ public class ErpStockCheckGenerateByProductReqVO {
@Schema(description = "是否允许为空库存,默认 true", example = "true")
private Boolean allowEmpty = Boolean.TRUE;
@Schema(description = "选择分类", example = "1")
private Integer categoryType;
}

@ -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;
}
}

@ -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;

@ -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;

@ -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<PalletItem> pallets;
@Schema(description = "子模具详情")
private List<MoldDO> 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;
}
}
}

@ -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<PalletItem> 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;
}
}
}

@ -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<PalletItem> pallets;
@Schema(description = "子模具列表")
private List<MoldDO> 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;
}
}
}

@ -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<PalletItem> 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;
}
}

@ -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 = "李四")

@ -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;
/**
*
*/

@ -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;
/**
*
*/

@ -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;
}

@ -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;
/**
*
*/

@ -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;
}

@ -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<ErpPalletDO> {
}
return selectList(ErpPalletDO::getStatus, status);
}
default List<ErpPalletDO> selectOccupiedList(Collection<Long> productIds, Collection<Long> warehouseIds,
Collection<Long> areaIds) {
boolean containsNullArea = areaIds != null && areaIds.stream().anyMatch(java.util.Objects::isNull);
return selectList(new LambdaQueryWrapperX<ErpPalletDO>()
.inIfPresent(ErpPalletDO::getProductId, productIds)
.inIfPresent(ErpPalletDO::getWarehouseId, warehouseIds)
.inIfPresent(ErpPalletDO::getAreaId, containsNullArea ? null : areaIds)
.gt(ErpPalletDO::getProductCount, BigDecimal.ZERO));
}
}

@ -25,6 +25,8 @@ public interface ErpStockCheckMapper extends BaseMapperX<ErpStockCheckDO> {
MPJLambdaWrapperX<ErpStockCheckDO> query = new MPJLambdaWrapperX<ErpStockCheckDO>()
.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())

@ -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<ErpStockInItemPalletDO> {
default List<ErpStockInItemPalletDO> selectListByInId(Long inId) {
return selectList(ErpStockInItemPalletDO::getInId, inId);
}
default List<ErpStockInItemPalletDO> selectListByInIds(Collection<Long> inIds) {
return selectList(ErpStockInItemPalletDO::getInId, inIds);
}
default int deleteByInId(Long inId) {
return delete(ErpStockInItemPalletDO::getInId, inId);
}
}

@ -85,9 +85,15 @@ public interface ErpStockMapper extends BaseMapperX<ErpStockDO> {
default List<ErpStockDO> selectListByWarehouseIdsAndAreaIds(List<Long> warehouseIds, List<Long> areaIds,
boolean nonZeroOnly) {
return selectListByWarehouseIdsAndAreaIds(warehouseIds, areaIds, nonZeroOnly, null);
}
default List<ErpStockDO> selectListByWarehouseIdsAndAreaIds(List<Long> warehouseIds, List<Long> areaIds,
boolean nonZeroOnly, Integer categoryType) {
LambdaQueryWrapperX<ErpStockDO> query = new LambdaQueryWrapperX<ErpStockDO>()
.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<ErpStockDO> {
}
default List<ErpStockDO> selectListByProductIds(List<Long> productIds, boolean nonZeroOnly) {
return selectListByProductIds(productIds, nonZeroOnly, null);
}
default List<ErpStockDO> selectListByProductIds(List<Long> productIds, boolean nonZeroOnly, Integer categoryType) {
LambdaQueryWrapperX<ErpStockDO> query = new LambdaQueryWrapperX<ErpStockDO>()
.inIfPresent(ErpStockDO::getProductId, productIds);
.inIfPresent(ErpStockDO::getProductId, productIds)
.eqIfPresent(ErpStockDO::getCategoryType, categoryType);
if (nonZeroOnly) {
query.ne(ErpStockDO::getCount, BigDecimal.ZERO);
}

@ -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<ErpStockOutItemPalletDO> {
default List<ErpStockOutItemPalletDO> selectListByOutId(Long outId) {
return selectList(ErpStockOutItemPalletDO::getOutId, outId);
}
default List<ErpStockOutItemPalletDO> selectListByOutIds(Collection<Long> outIds) {
return selectList(ErpStockOutItemPalletDO::getOutId, outIds);
}
default int deleteByOutId(Long outId) {
return delete(ErpStockOutItemPalletDO::getOutId, outId);
}
}

@ -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";
}
}

@ -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<ErpPalletDO> getPalletList(Collection<Long> ids);
Map<Long, ErpPalletDO> getPalletMap(Collection<Long> ids);
PageResult<ErpPalletDO> getPalletPage(ErpPalletPageReqVO pageReqVO);
List<ErpPalletDO> getPalletListByStatus(Integer status);
List<ErpPalletDO> getOccupiedPalletList(Collection<Long> productIds, Collection<Long> warehouseIds, Collection<Long> areaIds);
void regenerateCode(Long id, String code) throws UnsupportedEncodingException;
}

@ -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<ErpPalletDO> getPalletList(Collection<Long> ids) {
return ids == null || ids.isEmpty() ? Collections.emptyList() : palletMapper.selectBatchIds(ids);
}
@Override
public Map<Long, ErpPalletDO> getPalletMap(Collection<Long> ids) {
return convertMap(getPalletList(ids), ErpPalletDO::getId);
}
@Override
public PageResult<ErpPalletDO> getPalletPage(ErpPalletPageReqVO pageReqVO) {
return palletMapper.selectPage(pageReqVO);
@ -96,6 +117,28 @@ public class ErpPalletServiceImpl implements ErpPalletService {
return palletMapper.selectListByStatus(status);
}
@Override
public List<ErpPalletDO> getOccupiedPalletList(Collection<Long> productIds, Collection<Long> warehouseIds,
Collection<Long> 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);
}
}
}

@ -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<ErpStockCheckItemDO> 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<ErpStockCheckItemDO> 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<ErpStockDO> 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<ErpStockDO> stockList = stockMapper.selectListByProductIds(reqVO.getProductIds(), nonZeroOnly);
List<ErpStockDO> 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) {

@ -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<ErpStockInItemDO> getStockInItemListByInIds(Collection<Long> inIds);
List<ErpStockInItemPalletDO> getStockInItemPalletListByInId(Long inId);
List<ErpStockInItemPalletDO> getStockInItemPalletListByInIds(Collection<Long> inIds);
List<ErpStockInApproveRecordDO> getStockInApproveRecordList(Long stockInId);
void updateMoldStatus(Long id, Integer status);

@ -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<ErpStockInItemDO> 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<ErpStockInItemDO> 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<ErpStockInItemPalletDO> getStockInItemPalletListByInId(Long inId) {
return stockInItemPalletMapper.selectListByInId(inId);
}
@Override
public List<ErpStockInItemPalletDO> getStockInItemPalletListByInIds(Collection<Long> inIds) {
if (CollUtil.isEmpty(inIds)) {
return Collections.emptyList();
}
return stockInItemPalletMapper.selectListByInIds(inIds);
}
@Override
public List<ErpStockInApproveRecordDO> 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<ErpProductDO> 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<ErpStockInSaveReqVO.Item> list) {
List<Long> 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<Long, ErpPalletDO> palletMap = convertMap(palletMapper.selectBatchIds(palletIds), ErpPalletDO::getId);
palletIds.forEach(palletId -> {
if (!palletMap.containsKey(palletId)) {
throw exception(PALLET_NOT_EXISTS);
}
});
}
private void validateWarehouseAreas(List<ErpStockInSaveReqVO.Item> list) {
Map<Long, ErpWarehouseDO> 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<ErpStockInItemDO> stockInItems,
List<ErpStockInSaveReqVO.Item> reqItems) {
stockInItemPalletMapper.deleteByInId(inId);
if (CollUtil.isEmpty(stockInItems) || CollUtil.isEmpty(reqItems)) {
return;
}
List<ErpStockInItemPalletDO> 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<ErpStockInItemDO> stockInItems, boolean approve) {
List<ErpStockInItemPalletDO> palletRelations = stockInItemPalletMapper.selectListByInId(inId);
if (CollUtil.isEmpty(palletRelations)) {
return;
}
Map<Long, ErpStockInItemDO> itemMap = convertMap(stockInItems, ErpStockInItemDO::getId);
Map<Long, ErpPalletDO> 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;
}
}

@ -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<ErpStockOutItemDO> getStockOutItemListByOutIds(Collection<Long> outIds);
List<ErpStockOutItemPalletDO> getStockOutItemPalletListByOutId(Long outId);
List<ErpStockOutItemPalletDO> getStockOutItemPalletListByOutIds(Collection<Long> outIds);
List<ErpStockOutApproveRecordDO> getStockOutApproveRecordList(Long stockOutId);
List<ErpStockOutDO> selectByOutType(List<String> outTypes);

@ -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<ErpStockOutItemDO> 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<ErpStockOutItemDO> 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<ErpStockOutItemPalletDO> getStockOutItemPalletListByOutId(Long outId) {
return stockOutItemPalletMapper.selectListByOutId(outId);
}
@Override
public List<ErpStockOutItemPalletDO> getStockOutItemPalletListByOutIds(Collection<Long> outIds) {
if (CollUtil.isEmpty(outIds)) {
return Collections.emptyList();
}
return stockOutItemPalletMapper.selectListByOutIds(outIds);
}
@Override
public List<ErpStockOutApproveRecordDO> 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<ErpProductDO> productList = productService.validProductList(convertSet(list, ErpStockOutSaveReqVOItem::getProductId));
Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(
@ -505,6 +533,20 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
.setMaintenanceName(null)));
}
private void validatePallets(List<ErpStockOutSaveReqVOItem> list) {
List<Long> 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<Long, ErpPalletDO> palletMap = convertMap(palletMapper.selectBatchIds(palletIds), ErpPalletDO::getId);
palletIds.forEach(palletId -> {
if (!palletMap.containsKey(palletId)) {
throw exception(PALLET_NOT_EXISTS);
}
});
}
private void validateWarehouseAreas(List<ErpStockOutSaveReqVOItem> list) {
Map<Long, ErpWarehouseDO> warehouseMap = convertMap(
warehouseService.validWarehouseList(convertSet(list, ErpStockOutSaveReqVOItem::getWarehouseId)),
@ -553,4 +595,72 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
}
}
private void saveStockOutItemPallets(Long outId, List<ErpStockOutItemDO> stockOutItems,
List<ErpStockOutSaveReqVOItem> reqItems) {
stockOutItemPalletMapper.deleteByOutId(outId);
if (CollUtil.isEmpty(stockOutItems) || CollUtil.isEmpty(reqItems)) {
return;
}
List<ErpStockOutItemPalletDO> 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<ErpStockOutItemDO> stockOutItems, boolean approve) {
List<ErpStockOutItemPalletDO> palletRelations = stockOutItemPalletMapper.selectListByOutId(outId);
if (CollUtil.isEmpty(palletRelations)) {
return;
}
Map<Long, ErpStockOutItemDO> itemMap = convertMap(stockOutItems, ErpStockOutItemDO::getId);
Map<Long, ErpPalletDO> 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;
}
}

@ -216,6 +216,16 @@ public class TaskController {
public CommonResult<List<TaskDetailRespVO>> 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<TaskPackagingSchemeRespVO> getTaskProductDefaultPackagingSchemes(
@RequestParam("taskId") Long taskId) {
return success(taskService.getTaskProductDefaultPackagingSchemes(taskId));
}
// ==================== 子表(生产任务单明细) ====================
@GetMapping("/task-detail/page")
@ -266,4 +276,4 @@ public class TaskController {
public CommonResult<List<ViewTaskProductSummary>> getTaskDetailSummary(@RequestParam("taskId") Long taskId) {
return success(taskService.getTaskProductSummaryList(taskId));
}
}
}

@ -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<TaskProductPackagingSchemeRespVO> products;
}

@ -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<Long> taskDetailIds;
@Schema(description = "默认包装方案列表")
private List<ProductPackagingSchemeRespVO> packagingSchemes;
}

@ -96,6 +96,7 @@ public interface TaskService {
*/
List<TaskDetailDO> getTaskDetailListByTaskId(Long taskId);
List<TaskDetailRespVO> buildDetailVOList(List<TaskDetailDO> list);
TaskPackagingSchemeRespVO getTaskProductDefaultPackagingSchemes(Long taskId);
/**
*
*

@ -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<TaskDetailDO> details = getTaskDetailListByTaskId(taskId);
if (CollUtil.isEmpty(details)) {
result.setProducts(Collections.emptyList());
return result;
}
Set<Long> productIds = convertSet(details, TaskDetailDO::getProductId);
Map<Long, ErpProductDO> productMap = productService.getProductMap(productIds);
Map<Long, List<Long>> taskDetailIdMap = details.stream()
.filter(item -> item.getProductId() != null)
.collect(Collectors.groupingBy(TaskDetailDO::getProductId,
Collectors.mapping(TaskDetailDO::getId, Collectors.toList())));
Map<Long, List<ProductPackagingSchemeRespVO>> 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<TaskDetailDO> list) {
list.forEach(o -> o.setTaskId(taskId));
taskDetailMapper.insertBatch(list);

Loading…
Cancel
Save