fix:添加托盘管理页面及修改盘点执行相关接口

main
HuangHuiKang 1 day ago
parent e3d1dac817
commit 5850be1a11

@ -101,6 +101,8 @@ public interface ErrorCodeConstants {
ErrorCode WAREHOUSE_LOCATION_CODE_EXISTS = new ErrorCode(1_030_400_005, "库位编码不存在"); ErrorCode WAREHOUSE_LOCATION_CODE_EXISTS = new ErrorCode(1_030_400_005, "库位编码不存在");
ErrorCode WAREHOUSE_LOCATION_NOT_EXISTS = new ErrorCode(1_030_400_006, "库位不存在"); ErrorCode WAREHOUSE_LOCATION_NOT_EXISTS = new ErrorCode(1_030_400_006, "库位不存在");
ErrorCode WAREHOUSE_LOCATION_WAREHOUSE_AREA_NOT_MATCH = new ErrorCode(1_030_400_007, "暂无匹配库位信息"); 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, "托盘编码已存在");
// ========== ERP 其它入库单 1-030-401-000 ========== // ========== ERP 其它入库单 1-030-401-000 ==========
ErrorCode STOCK_IN_NOT_EXISTS = new ErrorCode(1_030_401_000, "其它入库单不存在"); ErrorCode STOCK_IN_NOT_EXISTS = new ErrorCode(1_030_401_000, "其它入库单不存在");
@ -161,6 +163,8 @@ public interface ErrorCodeConstants {
ErrorCode STOCK_CHECK_AUDIT_FAIL_USER = new ErrorCode(1_030_403_012, "审核失败,当前用户不是指定审核人"); ErrorCode STOCK_CHECK_AUDIT_FAIL_USER = new ErrorCode(1_030_403_012, "审核失败,当前用户不是指定审核人");
ErrorCode STOCK_CHECK_AUDIT_FAIL_RESULT = new ErrorCode(1_030_403_013, "审核失败,审核结果只支持通过或驳回"); ErrorCode STOCK_CHECK_AUDIT_FAIL_RESULT = new ErrorCode(1_030_403_013, "审核失败,审核结果只支持通过或驳回");
ErrorCode STOCK_CHECK_SOURCE_TYPE_NOT_EXISTS = new ErrorCode(1_030_403_014, "盘点单生成来源类型不存在"); ErrorCode STOCK_CHECK_SOURCE_TYPE_NOT_EXISTS = new ErrorCode(1_030_403_014, "盘点单生成来源类型不存在");
ErrorCode STOCK_CODE_EXISTS = new ErrorCode(1_030_403_014, "盘点单编码已存在");
// ========== ERP 产品库存 1-030-404-000 ========== // ========== ERP 产品库存 1-030-404-000 ==========
ErrorCode STOCK_COUNT_NEGATIVE = new ErrorCode(1_030_404_000, "操作失败,产品({})所在仓库({})的库存:{},小于变更数量:{}"); ErrorCode STOCK_COUNT_NEGATIVE = new ErrorCode(1_030_404_000, "操作失败,产品({})所在仓库({})的库存:{},小于变更数量:{}");

@ -0,0 +1,82 @@
package cn.iocoder.yudao.module.erp.controller.admin.pallet;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.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;
import cn.iocoder.yudao.module.erp.dal.dataobject.pallet.ErpPalletDO;
import cn.iocoder.yudao.module.erp.service.pallet.ErpPalletService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@Tag(name = "管理后台 - ERP 托盘")
@RestController
@RequestMapping("/erp/pallet")
@Validated
public class ErpPalletController {
@Resource
private ErpPalletService palletService;
@PostMapping("/create")
@Operation(summary = "创建托盘")
@PreAuthorize("@ss.hasPermission('erp:pallet:create')")
public CommonResult<Long> createPallet(@Valid @RequestBody ErpPalletSaveReqVO createReqVO) {
return success(palletService.createPallet(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新托盘")
@PreAuthorize("@ss.hasPermission('erp:pallet:update')")
public CommonResult<Boolean> updatePallet(@Valid @RequestBody ErpPalletSaveReqVO updateReqVO) {
palletService.updatePallet(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除托盘")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('erp:pallet:delete')")
public CommonResult<Boolean> deletePallet(@RequestParam("id") Long id) {
palletService.deletePallet(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得托盘")
@Parameter(name = "id", description = "编号", required = true, example = "1")
@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));
}
@GetMapping("/page")
@Operation(summary = "获得托盘分页")
@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));
}
@GetMapping("/simple-list")
@Operation(summary = "获得托盘精简列表")
@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)));
}
}

@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.erp.controller.admin.pallet.enums;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
@Getter
@AllArgsConstructor
public enum ErpPalletStatusEnum implements IntArrayValuable {
IDLE(1, "空闲"),
OCCUPIED(2, "占用"),
SCRAPPED(3, "报废");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpPalletStatusEnum::getStatus).toArray();
private final Integer status;
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
}

@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.erp.controller.admin.pallet.enums;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
@Getter
@AllArgsConstructor
public enum ErpPalletTypeEnum implements IntArrayValuable {
PLASTIC(1, "塑料"),
STEEL(2, "钢质"),
WOOD(3, "木托盘");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ErpPalletTypeEnum::getType).toArray();
private final Integer type;
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
}

@ -0,0 +1,59 @@
package cn.iocoder.yudao.module.erp.controller.admin.pallet.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.erp.controller.admin.pallet.enums.ErpPalletStatusEnum;
import cn.iocoder.yudao.module.erp.controller.admin.pallet.enums.ErpPalletTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - ERP 托盘分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ErpPalletPageReqVO extends PageParam {
@Schema(description = "托盘编码", example = "TP202506100001")
private String code;
@Schema(description = "托盘类型", example = "1")
@InEnum(ErpPalletTypeEnum.class)
private Integer palletType;
@Schema(description = "托盘状态", example = "1")
@InEnum(ErpPalletStatusEnum.class)
private Integer status;
@Schema(description = "仓库编号", example = "1")
private Long warehouseId;
@Schema(description = "库区编号", example = "11")
private Long areaId;
@Schema(description = "生产任务单号", example = "PLAN20250610001")
private String planCode;
@Schema(description = "产品编号", example = "1001")
private Long productId;
@Schema(description = "采购日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private LocalDate[] purchaseDate;
@Schema(description = "投入使用日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private LocalDate[] useDate;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,84 @@
package cn.iocoder.yudao.module.erp.controller.admin.pallet.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - ERP 托盘 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ErpPalletRespVO {
@Schema(description = "托盘编号", example = "1")
@ExcelProperty("托盘编号")
private Long id;
@Schema(description = "托盘编码", example = "TP202506100001")
@ExcelProperty("托盘编码")
private String code;
@Schema(description = "托盘类型", example = "1")
@ExcelProperty("托盘类型")
private Integer palletType;
@Schema(description = "托盘规格", example = "1200×1000×150")
@ExcelProperty("托盘规格")
private String specification;
@Schema(description = "额定承载重量", example = "1000")
@ExcelProperty("额定承载重量")
private BigDecimal ratedLoadWeight;
@Schema(description = "单位", example = "kg")
@ExcelProperty("单位")
private String unit;
@Schema(description = "托盘状态", example = "1")
@ExcelProperty("托盘状态")
private Integer status;
@Schema(description = "仓库编号", example = "1")
@ExcelProperty("仓库编号")
private Long warehouseId;
@Schema(description = "库区编号", example = "11")
@ExcelProperty("库区编号")
private Long areaId;
@Schema(description = "生产任务单号", example = "PLAN20250610001")
@ExcelProperty("生产任务单号")
private String planCode;
@Schema(description = "产品编号", example = "1001")
@ExcelProperty("产品编号")
private Long productId;
@Schema(description = "产品数量", example = "120")
@ExcelProperty("产品数量")
private BigDecimal productCount;
@Schema(description = "二维码", example = "https://xxx.com/qrcode/pallet/1")
@ExcelProperty("二维码")
private String qrcode;
@Schema(description = "采购日期", example = "2025-06-10")
@ExcelProperty("采购日期")
private LocalDate purchaseDate;
@Schema(description = "投入使用日期", example = "2025-06-11")
@ExcelProperty("投入使用日期")
private LocalDate useDate;
@Schema(description = "备注", example = "用于成品周转")
@ExcelProperty("备注")
private String remark;
@Schema(description = "创建时间")
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

@ -0,0 +1,73 @@
package cn.iocoder.yudao.module.erp.controller.admin.pallet.vo;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.erp.controller.admin.pallet.enums.ErpPalletStatusEnum;
import cn.iocoder.yudao.module.erp.controller.admin.pallet.enums.ErpPalletTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDate;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
@Schema(description = "管理后台 - ERP 托盘新增/修改 Request VO")
@Data
public class ErpPalletSaveReqVO {
@Schema(description = "托盘编号", example = "1")
private Long id;
@Schema(description = "托盘编码", example = "TP202506100001")
private String code;
@Schema(description = "托盘类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "托盘类型不能为空")
@InEnum(ErpPalletTypeEnum.class)
private Integer palletType;
@Schema(description = "托盘规格(长×宽×高)", example = "1200×1000×150")
private String specification;
@Schema(description = "额定承载重量", example = "1000")
private BigDecimal ratedLoadWeight;
@Schema(description = "单位", example = "kg")
private String unit;
@Schema(description = "托盘状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "托盘状态不能为空")
@InEnum(ErpPalletStatusEnum.class)
private Integer status;
@Schema(description = "仓库编号", example = "1")
private Long warehouseId;
@Schema(description = "库区编号", example = "11")
private Long areaId;
@Schema(description = "生产任务单号", example = "PLAN20250610001")
private String planCode;
@Schema(description = "产品编号", example = "1001")
private Long productId;
@Schema(description = "产品数量", example = "120")
private BigDecimal productCount;
@Schema(description = "二维码", example = "https://xxx.com/qrcode/pallet/1")
private String qrcode;
@Schema(description = "采购日期", example = "2025-06-10")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private LocalDate purchaseDate;
@Schema(description = "投入使用日期", example = "2025-06-11")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private LocalDate useDate;
@Schema(description = "备注", example = "用于成品周转")
private String remark;
}

@ -10,7 +10,8 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter; import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckApproveRecordRespVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckApproveRecordRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckAuditReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckAuditReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckGenerateByLocationReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckGenerateByLocationReqVO;
@ -25,6 +26,7 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckItemDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO; 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.dataobject.warehousearea.WarehouseAreaDO;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService; import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockCheckService; import cn.iocoder.yudao.module.erp.service.stock.ErpStockCheckService;
import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService; import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService;
import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService; import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService;
@ -71,6 +73,8 @@ public class ErpStockCheckController {
@Resource @Resource
private ErpProductService productService; private ErpProductService productService;
@Resource @Resource
private ErpProductUnitService productUnitService;
@Resource
private ErpWarehouseService warehouseService; private ErpWarehouseService warehouseService;
@Resource @Resource
private WarehouseAreaService warehouseAreaService; private WarehouseAreaService warehouseAreaService;
@ -189,10 +193,12 @@ public class ErpStockCheckController {
List<ErpStockCheckItemDO> stockCheckItemList = stockCheckService.getStockCheckItemListByCheckIds( List<ErpStockCheckItemDO> stockCheckItemList = stockCheckService.getStockCheckItemListByCheckIds(
convertSet(pageResult.getList(), ErpStockCheckDO::getId)); convertSet(pageResult.getList(), ErpStockCheckDO::getId));
Map<Long, List<ErpStockCheckItemDO>> stockCheckItemMap = convertMultiMap(stockCheckItemList, ErpStockCheckItemDO::getCheckId); Map<Long, List<ErpStockCheckItemDO>> stockCheckItemMap = convertMultiMap(stockCheckItemList, ErpStockCheckItemDO::getCheckId);
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(pageResult.getList(),
stockCheck -> Stream.of(NumberUtils.parseLong(stockCheck.getCreator()), stockCheck.getAuditUserId())));
return BeanUtils.toBean(pageResult, ErpStockCheckRespVO.class, stockCheck -> { return BeanUtils.toBean(pageResult, ErpStockCheckRespVO.class, stockCheck -> {
stockCheck.setItems(buildItemRespList(stockCheckItemMap.get(stockCheck.getId()))); stockCheck.setItems(buildItemRespList(stockCheckItemMap.get(stockCheck.getId())));
stockCheck.setProductNames(CollUtil.join(stockCheck.getItems(), ",", ErpStockCheckRespVO.Item::getProductName)); stockCheck.setProductNames(CollUtil.join(stockCheck.getItems(), ",", ErpStockCheckRespVO.Item::getProductName));
fillUserInfo(stockCheck); fillUserInfo(stockCheck, userMap);
}); });
} }
@ -210,12 +216,18 @@ public class ErpStockCheckController {
if (CollUtil.isEmpty(itemList)) { if (CollUtil.isEmpty(itemList)) {
return new ArrayList<>(); return new ArrayList<>();
} }
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(convertSet(itemList, ErpStockCheckItemDO::getProductId)); Map<Long, ErpProductDO> productMap = productService.getProductMap(convertSet(itemList, ErpStockCheckItemDO::getProductId));
Map<Long, ErpProductUnitDO> unitMap = productUnitService.getProductUnitMap(convertSet(itemList, item -> {
ErpProductDO product = productMap.get(item.getProductId());
return product != null ? product.getUnitId() : null;
}));
Map<Long, ErpWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(convertSet(itemList, ErpStockCheckItemDO::getWarehouseId)); Map<Long, ErpWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(convertSet(itemList, ErpStockCheckItemDO::getWarehouseId));
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(convertSet(itemList, ErpStockCheckItemDO::getAreaId)); Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(convertSet(itemList, ErpStockCheckItemDO::getAreaId));
return BeanUtils.toBean(itemList, ErpStockCheckRespVO.Item.class, item -> { return BeanUtils.toBean(itemList, ErpStockCheckRespVO.Item.class, item -> {
MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName()) MapUtils.findAndThen(productMap, item.getProductId(), product -> item.setProductName(product.getName())
.setProductBarCode(product.getBarCode()).setProductUnitName(product.getUnitName())); .setProductBarCode(product.getBarCode()));
MapUtils.findAndThen(productMap, item.getProductId(), product ->
MapUtils.findAndThen(unitMap, product.getUnitId(), unit -> item.setProductUnitName(unit.getName())));
MapUtils.findAndThen(warehouseMap, item.getWarehouseId(), warehouse -> item.setWarehouseName(warehouse.getName())); MapUtils.findAndThen(warehouseMap, item.getWarehouseId(), warehouse -> item.setWarehouseName(warehouse.getName()));
if (item.getAreaName() == null) { if (item.getAreaName() == null) {
MapUtils.findAndThen(areaMap, item.getAreaId(), area -> item.setAreaName(area.getAreaName())); MapUtils.findAndThen(areaMap, item.getAreaId(), area -> item.setAreaName(area.getAreaName()));
@ -228,6 +240,10 @@ public class ErpStockCheckController {
userIds.add(NumberUtils.parseLong(stockCheck.getCreator())); userIds.add(NumberUtils.parseLong(stockCheck.getCreator()));
userIds.add(stockCheck.getAuditUserId()); userIds.add(stockCheck.getAuditUserId());
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds); Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
fillUserInfo(stockCheck, userMap);
}
private void fillUserInfo(ErpStockCheckRespVO stockCheck, Map<Long, AdminUserRespDTO> userMap) {
MapUtils.findAndThen(userMap, NumberUtils.parseLong(stockCheck.getCreator()), user -> stockCheck.setCreatorName(user.getNickname())); MapUtils.findAndThen(userMap, NumberUtils.parseLong(stockCheck.getCreator()), user -> stockCheck.setCreatorName(user.getNickname()));
MapUtils.findAndThen(userMap, stockCheck.getAuditUserId(), user -> stockCheck.setAuditUserName(user.getNickname())); MapUtils.findAndThen(userMap, stockCheck.getAuditUserId(), user -> stockCheck.setAuditUserName(user.getNickname()));
} }

@ -5,6 +5,11 @@ import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import static cn.iocoder.yudao.module.erp.enums.DictTypeConstants.PRODUCT_CATEGORY_TYPE; import static cn.iocoder.yudao.module.erp.enums.DictTypeConstants.PRODUCT_CATEGORY_TYPE;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
@ -30,6 +35,9 @@ public class ErpStockCheckRespVO {
@Schema(description = "盘点时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "盘点时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("盘点时间") @ExcelProperty("盘点时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime checkTime; private LocalDateTime checkTime;
@Schema(description = "生成来源类型1-按库存2-按产品", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @Schema(description = "生成来源类型1-按库存2-按产品", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ -110,8 +118,7 @@ public class ErpStockCheckRespVO {
@NotNull(message = "账面数量不能为空") @NotNull(message = "账面数量不能为空")
private BigDecimal stockCount; private BigDecimal stockCount;
@Schema(description = "实际数量(实际库存)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") @Schema(description = "实际数量(实际库存)", example = "100.00")
@NotNull(message = "实际数量不能为空")
private BigDecimal actualCount; private BigDecimal actualCount;
@Schema(description = "盈亏数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") @Schema(description = "盈亏数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")

@ -1,5 +1,10 @@
package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check; package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.erp.enums.stock.ErpStockCheckSourceTypeEnum; import cn.iocoder.yudao.module.erp.enums.stock.ErpStockCheckSourceTypeEnum;
@ -19,8 +24,14 @@ public class ErpStockCheckSaveReqVO {
@Schema(description = "盘点编号", example = "11756") @Schema(description = "盘点编号", example = "11756")
private Long id; private Long id;
@Schema(description = "盘点编码", example = "11756")
private String code;
@Schema(description = "盘点时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "盘点时间", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "盘点时间不能为空") @NotNull(message = "盘点时间不能为空")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime checkTime; private LocalDateTime checkTime;
@Schema(description = "生成来源类型1-按库存2-按产品", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @Schema(description = "生成来源类型1-按库存2-按产品", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ -63,8 +74,7 @@ public class ErpStockCheckSaveReqVO {
@NotNull(message = "账面数量不能为空") @NotNull(message = "账面数量不能为空")
private BigDecimal stockCount; private BigDecimal stockCount;
@Schema(description = "实际数量(实际库存)", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") @Schema(description = "实际数量(实际库存)", example = "100.00")
@NotNull(message = "实际数量不能为空")
private BigDecimal actualCount; private BigDecimal actualCount;
@Schema(description = "盈亏数量,服务端自动按 实际数量 - 账面数量 计算", example = "100.00") @Schema(description = "盈亏数量,服务端自动按 实际数量 - 账面数量 计算", example = "100.00")

@ -0,0 +1,44 @@
package cn.iocoder.yudao.module.erp.dal.dataobject.pallet;
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;
import java.time.LocalDate;
@TableName("erp_pallet")
@KeySequence("erp_pallet_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ErpPalletDO extends BaseDO {
@TableId
private Long id;
private String code;
private Integer palletType;
private String specification;
private BigDecimal ratedLoadWeight;
private String unit;
private Integer status;
private Long warehouseId;
private Long areaId;
private String planCode;
private Long productId;
private BigDecimal productCount;
private String qrcode;
private LocalDate purchaseDate;
private LocalDate useDate;
private String remark;
}

@ -0,0 +1,40 @@
package cn.iocoder.yudao.module.erp.dal.mysql.pallet;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.erp.controller.admin.pallet.vo.ErpPalletPageReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.pallet.ErpPalletDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface ErpPalletMapper extends BaseMapperX<ErpPalletDO> {
default PageResult<ErpPalletDO> selectPage(ErpPalletPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ErpPalletDO>()
.likeIfPresent(ErpPalletDO::getCode, reqVO.getCode())
.eqIfPresent(ErpPalletDO::getPalletType, reqVO.getPalletType())
.eqIfPresent(ErpPalletDO::getStatus, reqVO.getStatus())
.eqIfPresent(ErpPalletDO::getWarehouseId, reqVO.getWarehouseId())
.eqIfPresent(ErpPalletDO::getAreaId, reqVO.getAreaId())
.likeIfPresent(ErpPalletDO::getPlanCode, reqVO.getPlanCode())
.eqIfPresent(ErpPalletDO::getProductId, reqVO.getProductId())
.betweenIfPresent(ErpPalletDO::getPurchaseDate, reqVO.getPurchaseDate())
.betweenIfPresent(ErpPalletDO::getUseDate, reqVO.getUseDate())
.betweenIfPresent(ErpPalletDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ErpPalletDO::getId));
}
default ErpPalletDO selectByCode(String code) {
return selectOne(ErpPalletDO::getCode, code);
}
default List<ErpPalletDO> selectListByStatus(Integer status) {
if (status == null) {
return selectList();
}
return selectList(ErpPalletDO::getStatus, status);
}
}

@ -5,8 +5,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckPageReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckDO; import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockCheckItemDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@ -32,10 +30,14 @@ public interface ErpStockCheckMapper extends BaseMapperX<ErpStockCheckDO> {
.eqIfPresent(ErpStockCheckDO::getCreator, reqVO.getCreator()) .eqIfPresent(ErpStockCheckDO::getCreator, reqVO.getCreator())
.orderByDesc(ErpStockCheckDO::getId); .orderByDesc(ErpStockCheckDO::getId);
if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) { if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) {
query.leftJoin(ErpStockCheckItemDO.class, ErpStockCheckItemDO::getCheckId, ErpStockCheckDO::getId) StringBuilder itemFilterSql = new StringBuilder("select distinct check_id from erp_stock_check_item where deleted = 0");
.eq(reqVO.getWarehouseId() != null, ErpStockCheckItemDO::getWarehouseId, reqVO.getWarehouseId()) if (reqVO.getWarehouseId() != null) {
.eq(reqVO.getProductId() != null, ErpStockCheckItemDO::getProductId, reqVO.getProductId()) itemFilterSql.append(" and warehouse_id = ").append(reqVO.getWarehouseId());
.groupBy(ErpStockCheckDO::getId); // 避免 1 对多查询,产生相同的 1 }
if (reqVO.getProductId() != null) {
itemFilterSql.append(" and product_id = ").append(reqVO.getProductId());
}
query.inSql(ErpStockCheckDO::getId, itemFilterSql.toString());
} }

@ -83,11 +83,31 @@ public interface ErpStockMapper extends BaseMapperX<ErpStockDO> {
return selectList(query); return selectList(query);
} }
default List<ErpStockDO> selectListByWarehouseIdsAndAreaIds(List<Long> warehouseIds, List<Long> areaIds,
boolean nonZeroOnly) {
LambdaQueryWrapperX<ErpStockDO> query = new LambdaQueryWrapperX<ErpStockDO>()
.inIfPresent(ErpStockDO::getWarehouseId, warehouseIds)
.inIfPresent(ErpStockDO::getAreaId, areaIds);
if (nonZeroOnly) {
query.ne(ErpStockDO::getCount, BigDecimal.ZERO);
}
return selectList(query);
}
default List<ErpStockDO> selectListByProductIds(List<Long> productIds) { default List<ErpStockDO> selectListByProductIds(List<Long> productIds) {
return selectList(new LambdaQueryWrapperX<ErpStockDO>() return selectList(new LambdaQueryWrapperX<ErpStockDO>()
.inIfPresent(ErpStockDO::getProductId, productIds)); .inIfPresent(ErpStockDO::getProductId, productIds));
} }
default List<ErpStockDO> selectListByProductIds(List<Long> productIds, boolean nonZeroOnly) {
LambdaQueryWrapperX<ErpStockDO> query = new LambdaQueryWrapperX<ErpStockDO>()
.inIfPresent(ErpStockDO::getProductId, productIds);
if (nonZeroOnly) {
query.ne(ErpStockDO::getCount, BigDecimal.ZERO);
}
return selectList(query);
}
default List<ErpStockDO> selectListByProductIdsAndWarehouseIdsAndAreaIds(Collection<Long> productIds, default List<ErpStockDO> selectListByProductIdsAndWarehouseIdsAndAreaIds(Collection<Long> productIds,
Collection<Long> warehouseIds, Collection<Long> warehouseIds,
Collection<Long> areaIds) { Collection<Long> areaIds) {

@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.erp.service.pallet;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.erp.controller.admin.pallet.vo.ErpPalletPageReqVO;
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.util.List;
public interface ErpPalletService {
Long createPallet(@Valid ErpPalletSaveReqVO createReqVO);
void updatePallet(@Valid ErpPalletSaveReqVO updateReqVO);
void deletePallet(Long id);
ErpPalletDO getPallet(Long id);
PageResult<ErpPalletDO> getPalletPage(ErpPalletPageReqVO pageReqVO);
List<ErpPalletDO> getPalletListByStatus(Integer status);
}

@ -0,0 +1,144 @@
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.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;
import cn.iocoder.yudao.module.erp.dal.dataobject.pallet.ErpPalletDO;
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.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService;
import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
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;
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;
@Service
@Validated
public class ErpPalletServiceImpl implements ErpPalletService {
@Resource
private ErpPalletMapper palletMapper;
@Resource
private AutoCodeUtil autoCodeUtil;
@Resource
private ErpWarehouseService warehouseService;
@Resource
private WarehouseAreaService warehouseAreaService;
@Resource
private ErpProductService productService;
@Override
public Long createPallet(ErpPalletSaveReqVO createReqVO) {
validateWarehouseAreaMatch(createReqVO.getWarehouseId(), createReqVO.getAreaId());
validateProductExists(createReqVO.getProductId());
ErpPalletDO pallet = BeanUtils.toBean(createReqVO, ErpPalletDO.class);
if (StringUtils.isBlank(pallet.getCode())) {
pallet.setCode(autoCodeUtil.genSerialCode("PALLET_CODE_GENERATE", null));
} else {
validateCodeUnique(null, pallet.getCode());
}
if (StringUtils.isBlank(pallet.getQrcode())) {
pallet.setQrcode(pallet.getCode());
}
palletMapper.insert(pallet);
return pallet.getId();
}
@Override
public void updatePallet(ErpPalletSaveReqVO updateReqVO) {
ErpPalletDO pallet = validatePalletExists(updateReqVO.getId());
validateWarehouseAreaMatch(updateReqVO.getWarehouseId(), updateReqVO.getAreaId());
validateProductExists(updateReqVO.getProductId());
ErpPalletDO updateObj = BeanUtils.toBean(updateReqVO, ErpPalletDO.class);
if (StringUtils.isBlank(updateObj.getCode())) {
updateObj.setCode(pallet.getCode());
} else {
validateCodeUnique(updateObj.getId(), updateObj.getCode());
}
if (StringUtils.isBlank(updateObj.getQrcode())) {
updateObj.setQrcode(updateObj.getCode());
}
palletMapper.updateById(updateObj);
}
@Override
public void deletePallet(Long id) {
validatePalletExists(id);
palletMapper.deleteById(id);
}
@Override
public ErpPalletDO getPallet(Long id) {
return palletMapper.selectById(id);
}
@Override
public PageResult<ErpPalletDO> getPalletPage(ErpPalletPageReqVO pageReqVO) {
return palletMapper.selectPage(pageReqVO);
}
@Override
public List<ErpPalletDO> getPalletListByStatus(Integer status) {
return palletMapper.selectListByStatus(status);
}
private ErpPalletDO validatePalletExists(Long id) {
ErpPalletDO pallet = palletMapper.selectById(id);
if (pallet == null) {
throw exception(PALLET_NOT_EXISTS);
}
return pallet;
}
private void validateCodeUnique(Long id, String code) {
ErpPalletDO pallet = palletMapper.selectByCode(code);
if (pallet == null) {
return;
}
if (id == null || !pallet.getId().equals(id)) {
throw exception(PALLET_CODE_EXISTS);
}
}
private void validateWarehouseAreaMatch(Long warehouseId, Long areaId) {
if (warehouseId == null && areaId == null) {
return;
}
if (warehouseId != null && warehouseService.validWarehouseList(Collections.singleton(warehouseId)).isEmpty()) {
throw exception(cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_NOT_EXISTS);
}
if (areaId == null) {
return;
}
WarehouseAreaDO area = warehouseAreaService.getWarehouseArea(areaId);
if (area == null) {
throw exception(WAREHOUSE_AREA_NOT_EXISTS);
}
if (warehouseId == null || !warehouseId.equals(area.getWarehouseId())) {
throw exception(WAREHOUSE_LOCATION_WAREHOUSE_AREA_NOT_MATCH);
}
}
private void validateProductExists(Long productId) {
if (productId == null) {
return;
}
if (productService.validProductList(Collections.singleton(productId)).isEmpty()) {
throw exception(PRODUCT_NOT_EXISTS);
}
}
}

@ -7,7 +7,7 @@ import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO; import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckAuditReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckAuditReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckGenerateByLocationReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckGenerateByLocationReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckGenerateByProductReqVO; import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.check.ErpStockCheckGenerateByProductReqVO;
@ -37,6 +37,9 @@ import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService;
import cn.iocoder.yudao.module.system.api.permission.PermissionApi; import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum; import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -56,23 +59,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_APPROVE_FAIL; import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_AUDIT_FAIL_RESULT;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_AUDIT_FAIL_STATUS;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_AUDIT_FAIL_USER;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_DELETE_FAIL_APPROVE;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_DELETE_FAIL_PROCESS;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_NOT_EXISTS;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_NO_EXISTS;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_SOURCE_TYPE_NOT_EXISTS;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_PROCESS_FAIL;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_SUBMIT_FAIL_AUDIT_USER_EMPTY;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_SUBMIT_FAIL_STATUS;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_SUBMIT_FAIL_USER;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_UPDATE_FAIL_APPROVE;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_CHECK_UPDATE_FAIL_PROCESS;
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;
@Service @Service
@Validated @Validated
@ -100,19 +87,34 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService {
private AdminUserApi adminUserApi; private AdminUserApi adminUserApi;
@Resource @Resource
private PermissionApi permissionApi; private PermissionApi permissionApi;
@Autowired
private AutoCodeUtil autoCodeUtil;
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Long createStockCheck(ErpStockCheckSaveReqVO createReqVO) { public Long createStockCheck(ErpStockCheckSaveReqVO createReqVO) {
String code = createReqVO.getCode();
validateSourceType(createReqVO.getSourceType()); validateSourceType(createReqVO.getSourceType());
List<ErpStockCheckItemDO> stockCheckItems = validateStockCheckItems(createReqVO.getItems()); List<ErpStockCheckItemDO> stockCheckItems = validateStockCheckItems(createReqVO.getItems());
String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_CHECK_NO_PREFIX); // String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_CHECK_NO_PREFIX);
if (stockCheckMapper.selectByNo(no) != null) { // if (stockCheckMapper.selectByNo(no) != null) {
throw exception(STOCK_CHECK_NO_EXISTS); // throw exception(STOCK_CHECK_NO_EXISTS);
// }
boolean autoGeneratedCode = StringUtils.isBlank(code);
if (autoGeneratedCode) {
code = autoCodeUtil.genSerialCode("INVENTORY_EXECUTION_CODE", null);
} else {
if (stockCheckMapper.selectOne(Wrappers.<ErpStockCheckDO>lambdaQuery()
.eq(ErpStockCheckDO::getNo, code)) != null) {
throw exception(STOCK_CODE_EXISTS);
}
} }
String finalCode = code;
ErpStockCheckDO stockCheck = BeanUtils.toBean(createReqVO, ErpStockCheckDO.class, in -> in ErpStockCheckDO stockCheck = BeanUtils.toBean(createReqVO, ErpStockCheckDO.class, in -> in
.setNo(no) .setNo(finalCode)
.setStatus(ErpAuditStatus.DRAFT.getStatus()) .setStatus(ErpAuditStatus.DRAFT.getStatus())
.setTotalCount(getSumValue(stockCheckItems, ErpStockCheckItemDO::getCount, BigDecimal::add, BigDecimal.ZERO)) .setTotalCount(getSumValue(stockCheckItems, ErpStockCheckItemDO::getCount, BigDecimal::add, BigDecimal.ZERO))
.setTotalPrice(getSumValue(stockCheckItems, ErpStockCheckItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO))); .setTotalPrice(getSumValue(stockCheckItems, ErpStockCheckItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)));
@ -292,10 +294,9 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService {
if (reqVO == null || !reqVO.validSelection()) { if (reqVO == null || !reqVO.validSelection()) {
return Collections.emptyList(); return Collections.emptyList();
} }
List<ErpStockDO> stockList = stockMapper.selectListByWarehouseIdsAndAreaIds(reqVO.getWarehouseIds(), reqVO.getAreaIds()); boolean nonZeroOnly = Boolean.FALSE.equals(reqVO.getAllowEmpty());
if (Boolean.FALSE.equals(reqVO.getAllowEmpty())) { List<ErpStockDO> stockList = stockMapper.selectListByWarehouseIdsAndAreaIds(
stockList = filterNonZeroStocks(stockList); reqVO.getWarehouseIds(), reqVO.getAreaIds(), nonZeroOnly);
}
return buildPreviewItems(stockList); return buildPreviewItems(stockList);
} }
@ -304,10 +305,8 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService {
if (reqVO == null || CollUtil.isEmpty(reqVO.getProductIds())) { if (reqVO == null || CollUtil.isEmpty(reqVO.getProductIds())) {
return Collections.emptyList(); return Collections.emptyList();
} }
List<ErpStockDO> stockList = stockMapper.selectListByProductIds(reqVO.getProductIds()); boolean nonZeroOnly = Boolean.FALSE.equals(reqVO.getAllowEmpty());
if (Boolean.FALSE.equals(reqVO.getAllowEmpty())) { List<ErpStockDO> stockList = stockMapper.selectListByProductIds(reqVO.getProductIds(), nonZeroOnly);
stockList = filterNonZeroStocks(stockList);
}
return buildPreviewItems(stockList); return buildPreviewItems(stockList);
} }
@ -328,7 +327,8 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService {
if (CollUtil.isEmpty(stockList)) { if (CollUtil.isEmpty(stockList)) {
return Collections.emptyList(); return Collections.emptyList();
} }
Map<Long, ErpProductDO> productMap = productService.getProductMap(convertSet(stockList, ErpStockDO::getProductId)); Collection<Long> productIds = convertSet(stockList, ErpStockDO::getProductId);
Map<Long, ErpProductDO> productMap = productService.getProductMap(productIds);
Map<Long, ErpWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(convertSet(stockList, ErpStockDO::getWarehouseId)); Map<Long, ErpWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(convertSet(stockList, ErpStockDO::getWarehouseId));
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(convertSet(stockList, ErpStockDO::getAreaId)); Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(convertSet(stockList, ErpStockDO::getAreaId));
List<ErpStockCheckRespVO.Item> result = new ArrayList<>(); List<ErpStockCheckRespVO.Item> result = new ArrayList<>();
@ -339,7 +339,7 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService {
item.setAreaName(stock.getAreaName()); item.setAreaName(stock.getAreaName());
item.setProductId(stock.getProductId()); item.setProductId(stock.getProductId());
item.setStockCount(stock.getCount() != null ? stock.getCount() : BigDecimal.ZERO); item.setStockCount(stock.getCount() != null ? stock.getCount() : BigDecimal.ZERO);
item.setActualCount(stock.getCount() != null ? stock.getCount() : BigDecimal.ZERO); item.setActualCount(null);
item.setCount(BigDecimal.ZERO); item.setCount(BigDecimal.ZERO);
MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> item.setWarehouseName(warehouse.getName())); MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> item.setWarehouseName(warehouse.getName()));
if (item.getAreaName() == null) { if (item.getAreaName() == null) {
@ -347,13 +347,10 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService {
} }
ErpProductDO productDO = productMap.get(stock.getProductId()); ErpProductDO productDO = productMap.get(stock.getProductId());
item.setProductPrice(resolveProductPrice(productDO)); item.setProductPrice(resolveProductPrice(productDO));
item.setProductUnitName(stock.getUnitName());
if (productDO != null) { if (productDO != null) {
item.setProductName(productDO.getName()); item.setProductName(productDO.getName());
item.setProductBarCode(productDO.getBarCode()); item.setProductBarCode(productDO.getBarCode());
ErpProductRespVO productVO = productService.getProduct(productDO.getId());
if (productVO != null) {
item.setProductUnitName(productVO.getUnitName());
}
} }
result.add(item); result.add(item);
} }
@ -434,8 +431,8 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService {
ErpProductDO productDO = productMap.get(item.getProductId()); ErpProductDO productDO = productMap.get(item.getProductId());
WarehouseAreaDO area = item.getAreaId() != null ? areaMap.get(item.getAreaId()) : null; WarehouseAreaDO area = item.getAreaId() != null ? areaMap.get(item.getAreaId()) : null;
BigDecimal stockCount = item.getStockCount() != null ? item.getStockCount() : BigDecimal.ZERO; BigDecimal stockCount = item.getStockCount() != null ? item.getStockCount() : BigDecimal.ZERO;
BigDecimal actualCount = item.getActualCount() != null ? item.getActualCount() : BigDecimal.ZERO; BigDecimal actualCount = item.getActualCount();
BigDecimal count = actualCount.subtract(stockCount); BigDecimal count = actualCount != null ? actualCount.subtract(stockCount) : null;
BigDecimal productPrice = item.getProductPrice() != null ? item.getProductPrice() : resolveProductPrice(productDO); BigDecimal productPrice = item.getProductPrice() != null ? item.getProductPrice() : resolveProductPrice(productDO);
return ErpStockCheckItemDO.builder() return ErpStockCheckItemDO.builder()
.id(item.getId()) .id(item.getId())
@ -448,7 +445,7 @@ public class ErpStockCheckServiceImpl implements ErpStockCheckService {
.stockCount(stockCount) .stockCount(stockCount)
.actualCount(actualCount) .actualCount(actualCount)
.count(count) .count(count)
.totalPrice(MoneyUtils.priceMultiply(productPrice, count)) .totalPrice(count != null ? MoneyUtils.priceMultiply(productPrice, count) : null)
.remark(item.getRemark()) .remark(item.getRemark())
.build(); .build();
}); });

Loading…
Cancel
Save