Compare commits

...

4 Commits

@ -22,9 +22,25 @@ import java.util.stream.Collectors;
public interface MoldBrandMapper extends BaseMapperX<MoldBrandDO> {
default LambdaQueryWrapperX<MoldBrandDO> buildQueryWrapper(MoldBrandPageReqVO reqVO) {
LambdaQueryWrapperX<MoldBrandDO> queryWrapper = new LambdaQueryWrapperX<MoldBrandDO>()
.likeIfPresent(MoldBrandDO::getCode, reqVO.getCode())
.likeIfPresent(MoldBrandDO::getName, reqVO.getName())
LambdaQueryWrapperX<MoldBrandDO> queryWrapper = new LambdaQueryWrapperX<>();
if(StringUtils.isNotBlank(reqVO.getCode())&&StringUtils.isNotBlank(reqVO.getName())&&reqVO.getCode().equals(reqVO.getName())){
if(reqVO.getCode().contains("MOLD-")){
queryWrapper.eq(MoldBrandDO::getId, reqVO.getCode().replace("MOLD-",""));
}else{
queryWrapper.and(w -> w
.like(MoldBrandDO::getCode, reqVO.getCode())
.or()
.like(MoldBrandDO::getName, reqVO.getName())
);
}
}else{
queryWrapper.likeIfPresent(MoldBrandDO::getCode, reqVO.getCode())
.likeIfPresent(MoldBrandDO::getName, reqVO.getName());
}
queryWrapper
/* .likeIfPresent(MoldBrandDO::getCode, reqVO.getCode())
.likeIfPresent(MoldBrandDO::getName, reqVO.getName())*/
.eqIfPresent(MoldBrandDO::getMoldType, reqVO.getMoldType())
.eqIfPresent(MoldBrandDO::getProductId, reqVO.getProductId())
.likeIfPresent(MoldBrandDO::getProductName, reqVO.getProductName())

@ -179,6 +179,8 @@ public interface ErrorCodeConstants {
ErrorCode PRODUCT_UNIT_NOT_EXISTS = new ErrorCode(1_030_502_000, "产品单位不存在");
ErrorCode PRODUCT_UNIT_NAME_DUPLICATE = new ErrorCode(1_030_502_001, "已存在该名字的产品单位");
ErrorCode PRODUCT_UNIT_EXITS_PRODUCT = new ErrorCode(1_030_502_002, "存在产品使用该单位,无法删除");
ErrorCode PRODUCT_UNIT_CONVERT_SELF_NOT_ALLOWED = new ErrorCode(1_030_502_003, "不能设置自己的单位换算自己的单位");
ErrorCode PRODUCT_PURCHASE_UNIT_CONVERT_QUANTITY_INVALID = new ErrorCode(1_030_502_004, "采购单位换算数量必须大于0");
// ========== ERP 结算账户 1-030-600-000 ==========
ErrorCode ACCOUNT_NOT_EXISTS = new ErrorCode(1_030_600_000, "结算账户不存在");

@ -124,6 +124,8 @@ public class ErpProductController {
.setName(product.getName()).setBarCode(product.getBarCode())
.setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName())
.setUnitId(product.getUnitId()).setUnitName(product.getUnitName())
.setPurchaseUnitId(product.getPurchaseUnitId()).setPurchaseUnitName(product.getPurchaseUnitName())
.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice())
.setMinPrice(product.getMinPrice()).setImages(product.getImages())));
}
@ -138,6 +140,8 @@ public class ErpProductController {
.setName(product.getName()).setBarCode(product.getBarCode())
.setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName())
.setUnitId(product.getUnitId()).setUnitName(product.getUnitName())
.setPurchaseUnitId(product.getPurchaseUnitId()).setPurchaseUnitName(product.getPurchaseUnitName())
.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice())
.setMinPrice(product.getMinPrice()).setImages(product.getImages())));
}
@ -149,6 +153,8 @@ public class ErpProductController {
.setName(product.getName()).setBarCode(product.getBarCode())
.setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName())
.setUnitId(product.getUnitId()).setUnitName(product.getUnitName())
.setPurchaseUnitId(product.getPurchaseUnitId()).setPurchaseUnitName(product.getPurchaseUnitName())
.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice())
.setMinPrice(product.getMinPrice()).setImages(product.getImages())));
}
@ -172,6 +178,8 @@ public class ErpProductController {
.setName(product.getName()).setBarCode(product.getBarCode())
.setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName())
.setUnitId(product.getUnitId()).setUnitName(product.getUnitName())
.setPurchaseUnitId(product.getPurchaseUnitId()).setPurchaseUnitName(product.getPurchaseUnitName())
.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice())
.setMinPrice(product.getMinPrice()).setImages(product.getImages())));
}
@ -183,6 +191,8 @@ public class ErpProductController {
.setName(product.getName()).setBarCode(product.getBarCode())
.setCategoryId(product.getCategoryId()).setCategoryName(product.getCategoryName())
.setUnitId(product.getUnitId()).setUnitName(product.getUnitName())
.setPurchaseUnitId(product.getPurchaseUnitId()).setPurchaseUnitName(product.getPurchaseUnitName())
.setPurchaseUnitConvertQuantity(product.getPurchaseUnitConvertQuantity())
.setPurchasePrice(product.getPurchasePrice()).setSalePrice(product.getSalePrice())
.setMinPrice(product.getMinPrice()).setImages(product.getImages())));
}

@ -62,7 +62,16 @@ public class ErpProductImportExcelVO {
@ExcelIgnore
private Long unitId; // 单位ID
@ExcelIgnore
private Long purchaseUnitId; // 采购单位ID
@ExcelIgnore
private String purchaseUnitName; // 采购单位名称
@ExcelIgnore
private BigDecimal purchaseUnitConvertQuantity; // 采购单位换算数量
@ExcelIgnore
private LocalDateTime createTime;
}
}

@ -53,6 +53,18 @@ public class ErpProductRespVO extends ErpProductDO {
@ExcelProperty("单位")
private String unitName;
@Schema(description = "采购单位编号", example = "8890")
@ExcelProperty("采购单位编号")
private Long purchaseUnitId;
@Schema(description = "采购单位", example = "包")
@ExcelProperty("采购单位")
private String purchaseUnitName;
@Schema(description = "采购单位换算数量", example = "100")
@ExcelProperty("采购单位换算数量")
private BigDecimal purchaseUnitConvertQuantity;
@Schema(description = "产品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("产品状态")
private Integer status;

@ -36,6 +36,15 @@ public class ProductSaveReqVO {
@NotNull(message = "单位编号不能为空")
private Long unitId;
@Schema(description = "采购单位编号", example = "8890")
private Long purchaseUnitId;
@Schema(description = "采购单位名称", example = "包")
private String purchaseUnitName;
@Schema(description = "采购单位换算数量", example = "100")
private BigDecimal purchaseUnitConvertQuantity;
@Schema(description = "产品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotNull(message = "产品状态不能为空")
private Integer status;

@ -13,9 +13,11 @@ import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageR
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockRespVO;
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.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService;
import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
@ -51,6 +53,8 @@ public class ErpStockController {
private ErpProductService productService;
@Resource
private ErpWarehouseService warehouseService;
@Resource
private WarehouseAreaService warehouseAreaService;
@GetMapping("/get")
@Operation(summary = "获得产品库存")
@ -62,9 +66,10 @@ public class ErpStockController {
@PreAuthorize("@ss.hasPermission('erp:stock:query')")
public CommonResult<ErpStockRespVO> getStock(@RequestParam(value = "id", required = false) Long id,
@RequestParam(value = "productId", required = false) Long productId,
@RequestParam(value = "warehouseId", required = false) Long warehouseId) {
ErpStockDO stock = id != null ? stockService.getStock(id) : stockService.getStock(productId, warehouseId);
return success(BeanUtils.toBean(stock, ErpStockRespVO.class));
@RequestParam(value = "warehouseId", required = false) Long warehouseId,
@RequestParam(value = "areaId", required = false) Long areaId) {
ErpStockDO stock = id != null ? stockService.getStock(id) : stockService.getStock(productId, warehouseId, areaId);
return success(buildStockRespVO(stock));
}
@GetMapping("/get-count")
@ -102,11 +107,43 @@ public class ErpStockController {
convertSet(pageResult.getList(), ErpStockDO::getProductId));
Map<Long, ErpWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
convertSet(pageResult.getList(), ErpStockDO::getWarehouseId));
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(
convertSet(pageResult.getList(), ErpStockDO::getAreaId));
return BeanUtils.toBean(pageResult, ErpStockRespVO.class, stock -> {
MapUtils.findAndThen(productMap, stock.getProductId(), product -> stock.setProductName(product.getName()).setBarCode(product.getBarCode())
.setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName()));
.setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName())
.setCategoryType(product.getCategoryType()));
MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> stock.setWarehouseName(warehouse.getName()));
if (stock.getAreaName() == null) {
MapUtils.findAndThen(areaMap, stock.getAreaId(), area -> stock.setAreaName(area.getAreaName()));
}
});
}
}
private ErpStockRespVO buildStockRespVO(ErpStockDO stock) {
if (stock == null) {
return null;
}
ErpStockRespVO respVO = BeanUtils.toBean(stock, ErpStockRespVO.class);
ErpProductRespVO product = productService.getProduct(stock.getProductId());
if (product != null) {
respVO.setProductName(product.getName());
respVO.setBarCode(product.getBarCode());
respVO.setCategoryName(product.getCategoryName());
respVO.setUnitName(product.getUnitName());
respVO.setCategoryType(product.getCategoryType());
}
ErpWarehouseDO warehouse = warehouseService.getWarehouse(stock.getWarehouseId());
if (warehouse != null) {
respVO.setWarehouseName(warehouse.getName());
}
if (respVO.getAreaName() == null && respVO.getAreaId() != null) {
WarehouseAreaDO area = warehouseAreaService.getWarehouseArea(respVO.getAreaId());
if (area != null) {
respVO.setAreaName(area.getAreaName());
}
}
return respVO;
}
}

@ -10,7 +10,6 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.ratelimiter.core.annotation.RateLimiter;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldBrandDO;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInApproveRecordRespVO;
@ -185,9 +184,6 @@ public class ErpStockInController {
}
private void fillPageReqDefault(ErpStockInPageReqVO pageReqVO) {
if (Boolean.TRUE.equals(pageReqVO.getRelatedToMe())) {
pageReqVO.setCurrentUserId(SecurityFrameworkUtils.getLoginUserId());
}
if (StringUtils.isEmpty(pageReqVO.getInType())) {
List<String> list = new ArrayList<>();
list.add(StockInTypeEnum..getValue());
@ -228,7 +224,7 @@ public class ErpStockInController {
convertSet(stockInItemList, ErpStockInItemDO::getMoldSetId));
stockInVO.setItems(convertList(stockInItemList, source -> {
ErpStockInRespVO.Item item = BeanUtils.toBean(source, ErpStockInRespVO.Item.class);
ErpStockDO stock = stockService.getStock(source.getMoldSetId(), source.getWarehouseId());
ErpStockDO stock = stockService.getStock(source.getMoldSetId(), source.getWarehouseId(), source.getAreaId());
item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
item.setMoldList(moldListMap.getOrDefault(source.getMoldSetId(), new ArrayList<>()));
fillWarehouseInfo(item, source, warehouseMap, areaMap);
@ -245,7 +241,7 @@ public class ErpStockInController {
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(stockInItemList, ErpStockInItemDO::getProductId));
stockInVO.setItems(BeanUtils.toBean(stockInItemList, ErpStockInRespVO.Item.class, item -> {
ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId());
ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId(), item.getAreaId());
item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
if (StringUtils.isBlank(item.getWarehouseName())) {
MapUtils.findAndThen(warehouseMap, item.getWarehouseId(), warehouse -> item.setWarehouseName(warehouse.getName()));
@ -257,6 +253,7 @@ public class ErpStockInController {
item.setProductName(product.getName());
item.setProductBarCode(product.getBarCode());
item.setProductUnitName(product.getUnitName());
item.setCategoryType(product.getCategoryType());
});
}));
stockInVO.setProductNames(CollUtil.join(stockInVO.getItems(), ",", ErpStockInRespVO.Item::getProductName));

@ -228,7 +228,7 @@ public class ErpStockOutController {
convertSet(stockOutItemList, ErpStockOutItemDO::getMoldSetId));
stockOutVO.setItems(convertList(stockOutItemList, source -> {
ErpStockOutRespVO.Item item = BeanUtils.toBean(source, ErpStockOutRespVO.Item.class);
ErpStockDO stock = stockService.getStock(source.getMoldSetId(), source.getWarehouseId());
ErpStockDO stock = stockService.getStock(source.getMoldSetId(), source.getWarehouseId(), source.getAreaId());
item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
item.setMoldList(moldListMap.getOrDefault(source.getMoldSetId(), new ArrayList<>()));
MapUtils.findAndThen(moldMap, source.getMoldSetId(), mold -> {
@ -244,12 +244,13 @@ public class ErpStockOutController {
Map<Long, ErpProductRespVO> productMap = productService.getProductVOMap(
convertSet(stockOutItemList, ErpStockOutItemDO::getProductId));
stockOutVO.setItems(BeanUtils.toBean(stockOutItemList, ErpStockOutRespVO.Item.class, item -> {
ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId());
ErpStockDO stock = stockService.getStock(item.getProductId(), item.getWarehouseId(), item.getAreaId());
item.setStockCount(stock != null ? stock.getCount() : BigDecimal.ZERO);
MapUtils.findAndThen(productMap, item.getProductId(), product -> {
item.setProductName(product.getName());
item.setProductBarCode(product.getBarCode());
item.setProductUnitName(product.getUnitName());
item.setCategoryType(product.getCategoryType());
});
}));
stockOutVO.setProductNames(CollUtil.join(stockOutVO.getItems(), ",", ErpStockOutRespVO.Item::getProductName));

@ -13,9 +13,11 @@ import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockReco
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockRecordRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockRecordDO;
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.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.stock.ErpStockRecordService;
import cn.iocoder.yudao.module.erp.service.stock.ErpWarehouseService;
import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
@ -51,6 +53,8 @@ public class ErpStockRecordController {
private ErpProductService productService;
@Resource
private ErpWarehouseService warehouseService;
@Resource
private WarehouseAreaService warehouseAreaService;
@Resource
private AdminUserApi adminUserApi;
@ -61,7 +65,7 @@ public class ErpStockRecordController {
@PreAuthorize("@ss.hasPermission('erp:stock-record:query')")
public CommonResult<ErpStockRecordRespVO> getStockRecord(@RequestParam("id") Long id) {
ErpStockRecordDO stockRecord = stockRecordService.getStockRecord(id);
return success(BeanUtils.toBean(stockRecord, ErpStockRecordRespVO.class));
return success(buildStockRecordRespVO(stockRecord));
}
@GetMapping("/page")
@ -92,14 +96,51 @@ public class ErpStockRecordController {
convertSet(pageResult.getList(), ErpStockRecordDO::getProductId));
Map<Long, ErpWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
convertSet(pageResult.getList(), ErpStockRecordDO::getWarehouseId));
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(
convertSet(pageResult.getList(), ErpStockRecordDO::getAreaId));
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
convertSet(pageResult.getList(), record -> Long.parseLong(record.getCreator())));
return BeanUtils.toBean(pageResult, ErpStockRecordRespVO.class, stock -> {
MapUtils.findAndThen(productMap, stock.getProductId(), product -> stock.setProductName(product.getName())
.setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName()));
.setCategoryName(product.getCategoryName()).setUnitName(product.getUnitName())
.setCategoryType(product.getCategoryType()));
MapUtils.findAndThen(warehouseMap, stock.getWarehouseId(), warehouse -> stock.setWarehouseName(warehouse.getName()));
if (stock.getAreaName() == null) {
MapUtils.findAndThen(areaMap, stock.getAreaId(), area -> stock.setAreaName(area.getAreaName()));
}
MapUtils.findAndThen(userMap, Long.parseLong(stock.getCreator()), user -> stock.setCreatorName(user.getNickname()));
});
}
}
private ErpStockRecordRespVO buildStockRecordRespVO(ErpStockRecordDO stockRecord) {
if (stockRecord == null) {
return null;
}
ErpStockRecordRespVO respVO = BeanUtils.toBean(stockRecord, ErpStockRecordRespVO.class);
ErpProductRespVO product = productService.getProduct(stockRecord.getProductId());
if (product != null) {
respVO.setProductName(product.getName());
respVO.setCategoryName(product.getCategoryName());
respVO.setUnitName(product.getUnitName());
respVO.setCategoryType(product.getCategoryType());
}
ErpWarehouseDO warehouse = warehouseService.getWarehouse(stockRecord.getWarehouseId());
if (warehouse != null) {
respVO.setWarehouseName(warehouse.getName());
}
if (respVO.getAreaName() == null && respVO.getAreaId() != null) {
WarehouseAreaDO area = warehouseAreaService.getWarehouseArea(respVO.getAreaId());
if (area != null) {
respVO.setAreaName(area.getAreaName());
}
}
if (respVO.getCreator() != null) {
AdminUserRespDTO user = adminUserApi.getUser(Long.parseLong(respVO.getCreator()));
if (user != null) {
respVO.setCreatorName(user.getNickname());
}
}
return respVO;
}
}

@ -121,6 +121,9 @@ public class ErpStockInRespVO {
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
private Long productId;
@Schema(description = "产品分类类型", example = "1")
private Integer categoryType;
@Schema(description = "产品单价", example = "100.00")
private BigDecimal productPrice;

@ -60,7 +60,7 @@ public class ErpStockInSaveReqVO {
private Long warehouseId;
@Schema(description = "库区编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
@NotNull(message = "库区编号不能为空")
// @NotNull(message = "库区编号不能为空")
private Long areaId;
@Schema(description = "产品编号", example = "3113")

@ -117,9 +117,18 @@ public class ErpStockOutRespVO {
@Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
private Long warehouseId;
@Schema(description = "库区编号", example = "1")
private Long areaId;
@Schema(description = "库区名称", example = "A区")
private String areaName;
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
private Long productId;
@Schema(description = "产品分类类型", example = "1")
private Integer categoryType;
@Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
private BigDecimal productPrice;

@ -59,6 +59,9 @@ public class ErpStockOutSaveReqVO {
@Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
private Long warehouseId;
@Schema(description = "库区编号", example = "1")
private Long areaId;
@Schema(description = "产品 id", example = "3113")
private Long productId;

@ -22,8 +22,12 @@ public class ErpStockRecordPageReqVO extends PageParam {
@Schema(description = "仓库编号", example = "32407")
private Long warehouseId;
@Schema(description = "库区编号", example = "1")
private Long areaId;
@Schema(description = "产品分类", example = "32407")
private Long categoryId;
@Schema(description = "产品分类类型", example = "1")
private Integer categoryType;
@Schema(description = "业务类型", example = "10")
private Integer bizType;
@ -40,4 +44,4 @@ public class ErpStockRecordPageReqVO extends PageParam {
@Schema(description = "id集合导出用")
private String ids;
}
}

@ -23,9 +23,21 @@ public class ErpStockRecordRespVO {
@Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10625")
private Long productId;
@Schema(description = "产品分类类型", example = "1")
@ExcelProperty(value = "产品分类类型", converter = DictConvert.class)
@DictFormat(DictTypeConstants.PRODUCT_CATEGORY_TYPE)
private Integer categoryType;
@Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32407")
private Long warehouseId;
@Schema(description = "库区编号", example = "1")
private Long areaId;
@Schema(description = "库区名称", example = "A区")
@ExcelProperty("库区名称")
private String areaName;
@Schema(description = "出入库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "11084")
@ExcelProperty("出入库数量")
private BigDecimal count;
@ -89,4 +101,4 @@ public class ErpStockRecordRespVO {
@Schema(description = "出入库时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("出入库时间")
private LocalDateTime recordTime;
}
}

@ -18,9 +18,15 @@ public class ErpStockPageReqVO extends PageParam {
@Schema(description = "仓库编号", example = "2802")
private Long warehouseId;
@Schema(description = "库区编号", example = "1")
private Long areaId;
@Schema(description = "产品分类", example = "2802")
private Long categoryId;
@Schema(description = "产品分类类型", example = "1")
private Integer categoryType;
@Schema(description = "id集合导出用")
private String ids;
}
}

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
@ -7,6 +9,8 @@ import lombok.Data;
import java.math.BigDecimal;
import static cn.iocoder.yudao.module.erp.enums.DictTypeConstants.PRODUCT_CATEGORY_TYPE;
@Schema(description = "管理后台 - ERP 库存 Response VO")
@Data
@ExcelIgnoreUnannotated
@ -22,12 +26,24 @@ public class ErpStockRespVO {
@Schema(description = "仓库编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2802")
private Long warehouseId;
@Schema(description = "库区编号", example = "1")
private Long areaId;
@Schema(description = "库区名称", example = "A区")
@ExcelProperty("库区名称")
private String areaName;
@Schema(description = "库存数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "21935")
@ExcelProperty("库存数量")
private BigDecimal count;
@Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11161")
private Long categoryId;
@Schema(description = "产品分类类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty(value = "产品分类类型", converter = DictConvert.class)
@DictFormat(PRODUCT_CATEGORY_TYPE)
private Integer categoryType;
// ========== 产品信息 ==========
@Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "苹果")
@ -52,4 +68,4 @@ public class ErpStockRespVO {
@ExcelProperty("仓库名称")
private String warehouseName;
}
}

@ -65,6 +65,23 @@ public class ErpProductDO extends BaseDO {
* {@link ErpProductUnitDO#getId()}
*/
private Long unitId;
/**
*
*
* {@link ErpProductUnitDO#getId()}
*/
private Long purchaseUnitId;
/**
*
*/
private String purchaseUnitName;
/**
*
*/
private BigDecimal purchaseUnitConvertQuantity;
/**
*
*

@ -42,10 +42,27 @@ public class ErpStockDO extends BaseDO {
* {@link ErpWarehouseDO#getId()}
*/
private Long warehouseId;
/**
*
*/
private Long areaId;
/**
*
*/
private String areaName;
/**
*
*/
private BigDecimal count;
//@Schema(description = "产品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11161")
/**
*
*/
private Long categoryId;
}
/**
*
*
* {@link cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductCategoryDO#getType()}
*/
private Integer categoryType;
}

@ -43,6 +43,14 @@ public class ErpStockOutItemDO extends BaseDO {
* {@link ErpWarehouseDO#getId()}
*/
private Long warehouseId;
/**
*
*/
private Long areaId;
/**
*
*/
private String areaName;
/**
*
*
@ -78,4 +86,4 @@ public class ErpStockOutItemDO extends BaseDO {
* {@link ErpProductDO#getId()}
*/
private Long deviceId;
}
}

@ -43,12 +43,24 @@ public class ErpStockRecordDO extends BaseDO {
* {@link ErpProductDO#getId()}
*/
private Long categoryId;
/**
*
*/
private Integer categoryType;
/**
*
*
* {@link ErpWarehouseDO#getId()}
*/
private Long warehouseId;
/**
*
*/
private Long areaId;
/**
*
*/
private String areaName;
/**
*
*
@ -89,4 +101,4 @@ public class ErpStockRecordDO extends BaseDO {
*
*/
private LocalDateTime recordTime;
}
}

@ -101,6 +101,10 @@ public interface ErpProductMapper extends BaseMapperX<ErpProductDO> {
return selectCount(ErpProductDO::getUnitId, unitId);
}
default Long selectCountByPurchaseUnitId(Long purchaseUnitId) {
return selectCount(ErpProductDO::getPurchaseUnitId, purchaseUnitId);
}
default List<ErpProductDO> selectListByStatus(Integer status) {
return selectList(ErpProductDO::getStatus, status);
}

@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.erp.dal.dataobject.productpackagingschemerel.ProductPackagingSchemeRelDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collection;
import java.util.List;
@Mapper
@ -13,4 +14,8 @@ public interface ProductPackagingSchemeRelMapper extends BaseMapperX<ProductPack
return selectList(ProductPackagingSchemeRelDO::getProductId, productId);
}
default List<ProductPackagingSchemeRelDO> selectListByProductIds(Collection<Long> productIds) {
return selectList(ProductPackagingSchemeRelDO::getProductId, productIds);
}
}

@ -29,9 +29,6 @@ public interface ErpStockInMapper extends BaseMapperX<ErpStockInDO> {
.eqIfPresent(ErpStockInDO::getCreator, reqVO.getCreator())
.eqIfPresent(ErpStockInDO::getAuditUserId, reqVO.getAuditUserId())
.orderByDesc(ErpStockInDO::getId);
query.and(Boolean.TRUE.equals(reqVO.getRelatedToMe()) && reqVO.getCurrentUserId() != null,
w -> w.eq(ErpStockInDO::getCreator, String.valueOf(reqVO.getCurrentUserId()))
.or().eq(ErpStockInDO::getAuditUserId, reqVO.getCurrentUserId()));
if (reqVO.getWarehouseId() != null || reqVO.getProductId() != null) {
query.leftJoin(ErpStockInItemDO.class, ErpStockInItemDO::getInId, ErpStockInDO::getId)
.eq(reqVO.getWarehouseId() != null, ErpStockInItemDO::getWarehouseId, reqVO.getWarehouseId())

@ -33,7 +33,9 @@ public interface ErpStockMapper extends BaseMapperX<ErpStockDO> {
LambdaQueryWrapperX<ErpStockDO> erpStockDOLambdaQueryWrapperX = new LambdaQueryWrapperX<ErpStockDO>()
.eqIfPresent(ErpStockDO::getProductId, reqVO.getProductId())
.eqIfPresent(ErpStockDO::getWarehouseId, reqVO.getWarehouseId())
.eqIfPresent(ErpStockDO::getAreaId, reqVO.getAreaId())
.eqIfPresent(ErpStockDO::getCategoryId, reqVO.getCategoryId())
.eqIfPresent(ErpStockDO::getCategoryType, reqVO.getCategoryType())
.orderByDesc(ErpStockDO::getId);
// 单独处理 ids 条件
@ -51,8 +53,21 @@ public interface ErpStockMapper extends BaseMapperX<ErpStockDO> {
}
default ErpStockDO selectByProductIdAndWarehouseId(Long productId, Long warehouseId) {
return selectByProductIdAndWarehouseIdAndAreaId(productId, warehouseId, null);
}
default ErpStockDO selectByProductIdAndWarehouseIdAndAreaId(Long productId, Long warehouseId, Long areaId) {
return selectOne(new LambdaQueryWrapperX<ErpStockDO>()
.eq(ErpStockDO::getProductId, productId)
.eq(ErpStockDO::getWarehouseId, warehouseId)
.eq(areaId != null, ErpStockDO::getAreaId, areaId)
.isNull(areaId == null, ErpStockDO::getAreaId));
}
default ErpStockDO selectByProductIdAndWarehouseIdAndCategoryType(Long productId, Long warehouseId, Integer categoryType) {
return selectOne(ErpStockDO::getProductId, productId,
ErpStockDO::getWarehouseId, warehouseId);
ErpStockDO::getWarehouseId, warehouseId,
ErpStockDO::getCategoryType, categoryType);
}
default List<ErpStockDO> selectByProductId(Long productId) {
@ -95,4 +110,4 @@ public interface ErpStockMapper extends BaseMapperX<ErpStockDO> {
@Param("warehouseId") Long warehouseId,
@Param("num") BigDecimal num);
}
}

@ -26,7 +26,9 @@ public interface ErpStockRecordMapper extends BaseMapperX<ErpStockRecordDO> {
LambdaQueryWrapperX<ErpStockRecordDO> erpStockRecordDOLambdaQueryWrapperX = new LambdaQueryWrapperX<ErpStockRecordDO>()
.eqIfPresent(ErpStockRecordDO::getProductId, reqVO.getProductId())
.eqIfPresent(ErpStockRecordDO::getCategoryId, reqVO.getCategoryId())
.eqIfPresent(ErpStockRecordDO::getCategoryType, reqVO.getCategoryType())
.eqIfPresent(ErpStockRecordDO::getWarehouseId, reqVO.getWarehouseId())
.eqIfPresent(ErpStockRecordDO::getAreaId, reqVO.getAreaId())
.eqIfPresent(ErpStockRecordDO::getBizType, reqVO.getBizType())
.likeIfPresent(ErpStockRecordDO::getBizNo, reqVO.getBizNo())
.betweenIfPresent(ErpStockRecordDO::getCreateTime, reqVO.getCreateTime())
@ -46,4 +48,4 @@ public interface ErpStockRecordMapper extends BaseMapperX<ErpStockRecordDO> {
return selectPage(reqVO,erpStockRecordDOLambdaQueryWrapperX);
}
}
}

@ -368,7 +368,7 @@ public class MoldBrandServiceImpl implements MoldBrandService {
item.setDeviceName(null);
return;
}
if (Objects.equals(latestOperate.getOperateType(), "1")) {
if (Objects.equals(latestOperate.getOperateType(), "1") && item.getStatus().equals(MoldBrandStatusEnum.ON_MACHINE.getStatus())) {
item.setDeviceName(latestOperate.getDeviceName());
return;
}

@ -118,6 +118,8 @@ public interface ErpProductService {
* @return
*/
Long getProductCountByUnitId(Long unitId);
Long getProductCountByPurchaseUnitId(Long purchaseUnitId);
/**
*
*

@ -50,6 +50,7 @@ import javax.annotation.Resource;
import javax.validation.ConstraintViolationException;
import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
@ -125,8 +126,11 @@ public class ErpProductServiceImpl implements ErpProductService {
String code = createReqVO.getBarCode();
boolean autoGeneratedCode = StringUtils.isBlank(code);
validateProductUnitRelation(createReqVO.getUnitId(), createReqVO.getPurchaseUnitId(), createReqVO.getPurchaseUnitConvertQuantity());
ErpProductDO product = BeanUtils.toBean(createReqVO, ErpProductDO.class);
fillProductUnitName(product);
if (productMapper.selectProductExist(product)) {
throw exception(PRODUCT_NAME_AND_STANDARD_EXISTS);
@ -236,8 +240,10 @@ public class ErpProductServiceImpl implements ErpProductService {
// TODO 芋艿:校验分类
// 校验存在
validateProductExists(updateReqVO.getId());
validateProductUnitRelation(updateReqVO.getUnitId(), updateReqVO.getPurchaseUnitId(), updateReqVO.getPurchaseUnitConvertQuantity());
// 更新
ErpProductDO updateObj = BeanUtils.toBean(updateReqVO, ErpProductDO.class);
fillProductUnitName(updateObj);
ErpProductCategoryDO productCategory = productCategoryMapper.selectById(updateObj.getCategoryId());
Long id = productCategory.getParentId();
updateObj.setSubCategoryName(productCategory.getName());
@ -345,6 +351,36 @@ public class ErpProductServiceImpl implements ErpProductService {
}
}
private void validateProductUnitRelation(Long unitId, Long purchaseUnitId, BigDecimal purchaseUnitConvertQuantity) {
if (unitId == null || productUnitService.getProductUnit(unitId) == null) {
throw exception(PRODUCT_UNIT_NOT_EXISTS);
}
if (purchaseUnitId == null) {
return;
}
if (productUnitService.getProductUnit(purchaseUnitId) == null) {
throw exception(PRODUCT_UNIT_NOT_EXISTS);
}
if (unitId.equals(purchaseUnitId)) {
throw exception(PRODUCT_UNIT_CONVERT_SELF_NOT_ALLOWED);
}
if (purchaseUnitConvertQuantity == null || purchaseUnitConvertQuantity.compareTo(BigDecimal.ZERO) <= 0) {
throw exception(PRODUCT_PURCHASE_UNIT_CONVERT_QUANTITY_INVALID);
}
}
private void fillProductUnitName(ErpProductDO product) {
if (product.getPurchaseUnitId() == null) {
product.setPurchaseUnitName(null);
return;
}
ErpProductUnitDO purchaseUnit = productUnitService.getProductUnit(product.getPurchaseUnitId());
if (purchaseUnit == null) {
throw exception(PRODUCT_UNIT_NOT_EXISTS);
}
product.setPurchaseUnitName(purchaseUnit.getName());
}
@Override
public ErpProductRespVO getProduct(Long id) {
ErpProductDO product = productMapper.selectById(id);
@ -372,6 +408,12 @@ public class ErpProductServiceImpl implements ErpProductService {
if (erpProductCategoryDO !=null ){
respVO.setCategoryType(erpProductCategoryDO.getType());
}
if (respVO.getPurchaseUnitId() != null && respVO.getPurchaseUnitName() == null) {
ErpProductUnitDO purchaseUnit = productUnitService.getProductUnit(respVO.getPurchaseUnitId());
if (purchaseUnit != null) {
respVO.setPurchaseUnitName(purchaseUnit.getName());
}
}
//
// respVO.setDeviceIds(respVO.getDevices().stream()
// .map(ProductRelationRespVO::getId)
@ -522,12 +564,20 @@ public class ErpProductServiceImpl implements ErpProductService {
if (CollUtil.isEmpty(list)) {
return Collections.emptyList();
}
Map<Long, List<ProductPackagingSchemeRespVO>> packagingSchemeMap =
productPackagingSchemeRelMapper.selectListByProductIds(convertSet(list, ErpProductDO::getId))
.stream()
.collect(Collectors.groupingBy(ProductPackagingSchemeRelDO::getProductId,
Collectors.mapping(rel -> BeanUtils.toBean(rel, ProductPackagingSchemeRespVO.class),
Collectors.toList())));
Map<Long, ErpProductCategoryDO> categoryMap = productCategoryService.getProductCategoryMap(
convertSet(list, ErpProductDO::getCategoryId));
Map<Long, ErpProductCategoryDO> subCategoryMap = productCategoryService.getProductCategoryMap(
convertSet(list, ErpProductDO::getSubCategoryId));
Map<Long, ErpProductUnitDO> unitMap = productUnitService.getProductUnitMap(
convertSet(list, ErpProductDO::getUnitId));
Map<Long, ErpProductUnitDO> purchaseUnitMap = productUnitService.getProductUnitMap(
convertSet(list, ErpProductDO::getPurchaseUnitId));
return BeanUtils.toBean(list, ErpProductRespVO.class, product -> {
MapUtils.findAndThen(categoryMap, product.getCategoryId(), category -> {
product.setCategoryName(category.getName());
@ -541,6 +591,9 @@ public class ErpProductServiceImpl implements ErpProductService {
});
MapUtils.findAndThen(unitMap, product.getUnitId(),
unit -> product.setUnitName(unit.getName()));
MapUtils.findAndThen(purchaseUnitMap, product.getPurchaseUnitId(),
unit -> product.setPurchaseUnitName(unit.getName()));
product.setPackagingSchemes(packagingSchemeMap.getOrDefault(product.getId(), Collections.emptyList()));
if (Boolean.TRUE.equals(product.getDeleted())) {
product.setName(product.getName() + "(已被删除)");
}
@ -556,6 +609,12 @@ public class ErpProductServiceImpl implements ErpProductService {
public Long getProductCountByUnitId(Long unitId) {
return productMapper.selectCountByUnitId(unitId);
}
@Override
public Long getProductCountByPurchaseUnitId(Long purchaseUnitId) {
return productMapper.selectCountByPurchaseUnitId(purchaseUnitId);
}
@Override
public List<ErpProductDO> getProductList(Collection<Long> ids) {
return productMapper.selectBatchIds(ids);
@ -705,6 +764,16 @@ public class ErpProductServiceImpl implements ErpProductService {
}
}
if (StrUtil.isNotBlank(importProduct.getPurchaseUnitName())) {
ErpProductUnitDO purchaseUnitDO = productUnitService.getProductUnitByName(importProduct.getPurchaseUnitName());
if (purchaseUnitDO != null) {
productDO.setPurchaseUnitId(purchaseUnitDO.getId());
productDO.setPurchaseUnitName(purchaseUnitDO.getName());
}
}
validateProductUnitRelation(productDO.getUnitId(), productDO.getPurchaseUnitId(), productDO.getPurchaseUnitConvertQuantity());
return productDO;
}
}

@ -67,6 +67,7 @@ public class ErpProductUnitServiceImpl implements ErpProductUnitService {
}
// 1.1 校验存在
validateProductUnitExists(updateReqVO.getId());
validatePrimaryUnitNotSelf(updateReqVO.getId(), updateReqVO.getPrimaryId());
// 1.2 校验名字唯一
validateProductUnitNameUnique(updateReqVO.getId(), updateReqVO.getName());
// 2. 更新
@ -98,7 +99,7 @@ public class ErpProductUnitServiceImpl implements ErpProductUnitService {
// 1.1 校验存在
validateProductUnitExists(id);
// 1.2 校验产品是否使用
if (productService.getProductCountByUnitId(id) > 0) {
if (productService.getProductCountByUnitId(id) > 0 || productService.getProductCountByPurchaseUnitId(id) > 0) {
throw exception(PRODUCT_UNIT_EXITS_PRODUCT);
}
// 2. 删除
@ -111,6 +112,12 @@ public class ErpProductUnitServiceImpl implements ErpProductUnitService {
}
}
private void validatePrimaryUnitNotSelf(Long id, Long primaryId) {
if (primaryId != null && primaryId.equals(id)) {
throw exception(PRODUCT_UNIT_CONVERT_SELF_NOT_ALLOWED);
}
}
@Override
public ErpProductUnitDO getProductUnit(Long id) {
return productUnitMapper.selectById(id);
@ -181,4 +188,4 @@ public class ErpProductUnitServiceImpl implements ErpProductUnitService {
});
CollUtil.isNotEmpty(erpProductUnitDOs);productUnitMapper.insertBatch(erpProductUnitDOs);
}
}
}

@ -8,11 +8,13 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.common.controller.admin.mold.vo.MoldBrandSaveReqVO;
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.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.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInApproveRecordDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO;
@ -77,6 +79,8 @@ public class ErpStockInServiceImpl implements ErpStockInService {
@Resource
private ErpStockInMapper stockInMapper;
@Resource
private MoldBrandMapper moldBrandMapper;
@Resource
private ErpStockInItemMapper stockInItemMapper;
@Resource
private ErpStockInApproveRecordMapper stockInApproveRecordMapper;
@ -117,7 +121,7 @@ public class ErpStockInServiceImpl implements ErpStockInService {
}
boolean needAudit = needAudit();
Integer status = needAudit ? ErpAuditStatus.DRAFT.getStatus() : ErpAuditStatus.APPROVE.getStatus();
Integer status = ErpAuditStatus.DRAFT.getStatus();
ErpStockInDO stockIn = BeanUtils.toBean(createReqVO, ErpStockInDO.class, in -> in
.setNo(no)
.setNeedAudit(needAudit)
@ -128,11 +132,17 @@ public class ErpStockInServiceImpl implements ErpStockInService {
stockInItems.forEach(item -> item.setInId(stockIn.getId()));
stockInItemMapper.insertBatch(stockInItems);
if (!needAudit) {
applyStockInEffect(stockIn, stockInItems, null);
createApproveRecord(stockIn.getId(), ErpStockInApproveActionEnum.AUTO_APPROVE, null,
ErpAuditStatus.APPROVE.getStatus(), null, "无需审核,系统自动入库");
if (createReqVO.getInType().equals("模具入库")){
//修改模具组状态
for (ErpStockInSaveReqVO.Item item : createReqVO.getItems()) {
MoldBrandDO moldBrandDO = moldBrandMapper.selectById(item.getMoldSetId());
moldBrandDO.setStatus(MoldBrandStatusEnum.IN_STOCK.getStatus());
moldBrandMapper.updateById(moldBrandDO);
}
}
return stockIn.getId();
}
@ -200,12 +210,25 @@ public class ErpStockInServiceImpl implements ErpStockInService {
&& !ErpAuditStatus.UN_APPROVE.getStatus().equals(stockIn.getStatus())) {
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);
}
adminUserApi.validateUser(auditUserId);
Integer fromStatus = stockIn.getStatus();
ErpStockInDO updateObj = new ErpStockInDO()
.setAuditUserId(auditUserId)
.setNeedAudit(true)
@ -334,19 +357,21 @@ public class ErpStockInServiceImpl implements ErpStockInService {
: (approve ? ErpStockRecordBizTypeEnum.OTHER_IN.getType()
: ErpStockRecordBizTypeEnum.OTHER_IN_CANCEL.getType());
stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
stockInItem.getProductId(), moldDO.getId(), stockInItem.getWarehouseId(), count,
stockInItem.getProductId(), moldDO.getId(), null, stockInItem.getWarehouseId(),
stockInItem.getAreaId(), stockInItem.getAreaName(), count,
recordBizType, stockInItem.getInId(), stockInItem.getId(), stockIn.getNo(), stockIn.getInTime()));
if (approve && itemNeedUpdateMoldStatus(moldDO)) {
moldDO.setStatus(MoldBrandStatusEnum.STANDBY.getStatus());
moldBrandService.updateMoldBrand(BeanUtils.toBean(moldDO, MoldBrandSaveReqVO.class));
}
} else {
ErpProductDO productDO = productService.getProduct(stockInItem.getProductId());
ErpProductRespVO productDO = productService.getProduct(stockInItem.getProductId());
Integer recordBizType = bizType != null ? bizType
: (approve ? ErpStockRecordBizTypeEnum.getTypeByName(stockIn.getInType())
: ErpStockRecordBizTypeEnum.getTypeByName(stockIn.getInType(), 10));
stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
stockInItem.getProductId(), productDO.getCategoryId(), stockInItem.getWarehouseId(), count,
stockInItem.getProductId(), productDO.getCategoryId(), productDO.getCategoryType(), stockInItem.getWarehouseId(),
stockInItem.getAreaId(), stockInItem.getAreaName(), count,
recordBizType, stockInItem.getInId(), stockInItem.getId(), stockIn.getNo(), stockIn.getInTime()));
}
});
@ -376,7 +401,6 @@ public class ErpStockInServiceImpl implements ErpStockInService {
}
private List<ErpStockInItemDO> validateStockInItems(List<ErpStockInSaveReqVO.Item> list, String inType) {
validateWarehouseAreas(list);
if (Objects.equals(inType, "模具入库")) {
List<MoldBrandDO> moldList = moldBrandService.validMoldList(convertSet(list, ErpStockInSaveReqVO.Item::getMoldSetId));
Map<Long, MoldBrandDO> moldMap = convertMap(moldList, MoldBrandDO::getId);
@ -408,6 +432,8 @@ public class ErpStockInServiceImpl implements ErpStockInService {
.build();
});
}
validateWarehouseAreas(list);
List<ErpProductDO> productList = productService.validProductList(convertSet(list, ErpStockInSaveReqVO.Item::getProductId));
Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);

@ -8,6 +8,8 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.common.controller.admin.mold.vo.MoldBrandSaveReqVO;
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.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;
@ -17,6 +19,8 @@ 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.ErpWarehouseDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.warehousearea.WarehouseAreaDO;
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.ErpStockOutMapper;
@ -29,6 +33,7 @@ import cn.iocoder.yudao.module.erp.service.mold.MoldService;
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.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.user.AdminUserApi;
import org.springframework.stereotype.Service;
@ -62,6 +67,8 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
@Resource
private ErpStockOutMapper stockOutMapper;
@Resource
private MoldBrandMapper moldBrandMapper;
@Resource
private ErpStockOutItemMapper stockOutItemMapper;
@Resource
private ErpStockOutApproveRecordMapper stockOutApproveRecordMapper;
@ -80,6 +87,8 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
@Resource
private ErpStockRecordService stockRecordService;
@Resource
private WarehouseAreaService warehouseAreaService;
@Resource
private AdminUserApi adminUserApi;
@Resource
private ConfigApi configApi;
@ -103,7 +112,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
}
boolean needAudit = needAudit();
Integer status = needAudit ? ErpAuditStatus.DRAFT.getStatus() : ErpAuditStatus.APPROVE.getStatus();
Integer status = ErpAuditStatus.DRAFT.getStatus();
ErpStockOutDO stockOut = BeanUtils.toBean(createReqVO, ErpStockOutDO.class, out -> out
.setNo(no)
.setNeedAudit(needAudit)
@ -114,11 +123,16 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
stockOutItems.forEach(item -> item.setOutId(stockOut.getId()));
stockOutItemMapper.insertBatch(stockOutItems);
if (!needAudit) {
applyStockOutEffect(stockOut, stockOutItems, null);
createApproveRecord(stockOut.getId(), ErpStockOutApproveActionEnum.AUTO_APPROVE, null,
ErpAuditStatus.APPROVE.getStatus(), null, "无需审核,系统自动出库");
if (createReqVO.getOutType().equals("模具出库")) {
//修改模具组状态
for (ErpStockOutSaveReqVO.Item item : createReqVO.getItems()) {
MoldBrandDO moldBrandDO = moldBrandMapper.selectById(item.getMoldSetId());
moldBrandDO.setStatus(MoldBrandStatusEnum.STANDBY.getStatus());
moldBrandMapper.updateById(moldBrandDO);
}
}
return stockOut.getId();
}
@ -189,12 +203,25 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
&& !ErpAuditStatus.UN_APPROVE.getStatus().equals(stockOut.getStatus())) {
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);
}
adminUserApi.validateUser(auditUserId);
Integer fromStatus = stockOut.getStatus();
ErpStockOutDO updateObj = new ErpStockOutDO()
.setAuditUserId(auditUserId)
.setNeedAudit(true)
@ -328,7 +355,8 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
: (approve ? ErpStockRecordBizTypeEnum.OTHER_OUT.getType()
: ErpStockRecordBizTypeEnum.OTHER_OUT_CANCEL.getType());
stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
stockOutItem.getProductId(), moldDO.getId(), stockOutItem.getWarehouseId(), count,
stockOutItem.getProductId(), moldDO.getId(), null, stockOutItem.getWarehouseId(),
stockOutItem.getAreaId(), stockOutItem.getAreaName(), count,
recordBizType, stockOutItem.getOutId(), stockOutItem.getId(), stockOut.getNo(), stockOut.getOutTime()));
if (approve && itemNeedUpdateMoldStatus(moldDO)) {
moldDO.setStatus(3);
@ -340,7 +368,8 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
: (approve ? ErpStockRecordBizTypeEnum.getTypeByName(stockOut.getOutType())
: ErpStockRecordBizTypeEnum.getTypeByName(stockOut.getOutType(), 10));
stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
stockOutItem.getProductId(), product.getCategoryId(), stockOutItem.getWarehouseId(), count,
stockOutItem.getProductId(), product.getCategoryId(), product.getCategoryType(), stockOutItem.getWarehouseId(),
stockOutItem.getAreaId(), stockOutItem.getAreaName(), count,
recordBizType, stockOutItem.getOutId(), stockOutItem.getId(), stockOut.getNo(), stockOut.getOutTime()));
}
});
@ -370,9 +399,12 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
}
private List<ErpStockOutItemDO> validateStockOutItems(List<ErpStockOutSaveReqVO.Item> list, String outType) {
validateWarehouseAreas(list);
if (Objects.equals(outType, "模具出库")) {
List<MoldBrandDO> moldList = moldBrandService.validMoldList(convertSet(list, ErpStockOutSaveReqVO.Item::getMoldSetId));
Map<Long, MoldBrandDO> moldMap = convertMap(moldList, MoldBrandDO::getId);
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(
convertSet(list, ErpStockOutSaveReqVO.Item::getAreaId));
return convertList(list, item -> {
MoldBrandDO moldBrand = moldMap.get(item.getMoldSetId());
return ErpStockOutItemDO.builder()
@ -380,6 +412,8 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
.moldSetId(moldBrand.getId())
.moldSetName(moldBrand.getName())
.warehouseId(item.getWarehouseId())
.areaId(item.getAreaId())
.areaName(areaMap.containsKey(item.getAreaId()) ? areaMap.get(item.getAreaId()).getAreaName() : null)
.productId(moldBrand.getId())
.productUnitId(null)
.productPrice(item.getProductPrice())
@ -391,11 +425,35 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
}
List<ErpProductDO> productList = productService.validProductList(convertSet(list, ErpStockOutSaveReqVO.Item::getProductId));
Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(
convertSet(list, ErpStockOutSaveReqVO.Item::getAreaId));
return convertList(list, item -> BeanUtils.toBean(item, ErpStockOutItemDO.class, target -> target
.setAreaName(areaMap.containsKey(target.getAreaId()) ? areaMap.get(target.getAreaId()).getAreaName() : null)
.setProductUnitId(productMap.get(target.getProductId()).getUnitId())
.setTotalPrice(MoneyUtils.priceMultiply(target.getProductPrice(), target.getCount()))));
}
private void validateWarehouseAreas(List<ErpStockOutSaveReqVO.Item> list) {
Map<Long, ErpWarehouseDO> warehouseMap = convertMap(
warehouseService.validWarehouseList(convertSet(list, ErpStockOutSaveReqVO.Item::getWarehouseId)),
ErpWarehouseDO::getId);
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(
convertSet(list, ErpStockOutSaveReqVO.Item::getAreaId));
list.forEach(item -> {
if (item.getAreaId() == null) {
return;
}
WarehouseAreaDO area = areaMap.get(item.getAreaId());
if (area == null) {
throw exception(WAREHOUSE_AREA_NOT_EXISTS);
}
if (!warehouseMap.containsKey(item.getWarehouseId())
|| !Objects.equals(item.getWarehouseId(), area.getWarehouseId())) {
throw exception(WAREHOUSE_LOCATION_WAREHOUSE_AREA_NOT_MATCH);
}
});
}
private void updateStockOutItemList(Long id, List<ErpStockOutItemDO> newList) {
boolean moldStockOut = CollUtil.isNotEmpty(newList)
&& newList.stream().anyMatch(item -> item.getMoldSetId() != null);

@ -2,9 +2,11 @@ package cn.iocoder.yudao.module.erp.service.stock;
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.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.record.ErpStockRecordPageReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockRecordDO;
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockRecordMapper;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.erp.service.stock.bo.ErpStockRecordCreateReqBO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -28,6 +30,9 @@ public class ErpStockRecordServiceImpl implements ErpStockRecordService {
@Resource
private ErpStockService stockService;
@Resource
private ErpProductService productService;
@Override
public ErpStockRecordDO getStockRecord(Long id) {
return stockRecordMapper.selectById(id);
@ -43,12 +48,19 @@ public class ErpStockRecordServiceImpl implements ErpStockRecordService {
public void createStockRecord(ErpStockRecordCreateReqBO createReqBO) {
// 1. 更新库存
BigDecimal totalCount = stockService.updateStockCountIncrement(createReqBO.getCategoryId(),
createReqBO.getProductId(), createReqBO.getWarehouseId(), createReqBO.getCount());
createReqBO.getProductId(), createReqBO.getWarehouseId(), createReqBO.getAreaId(),
createReqBO.getAreaName(), createReqBO.getCount());
Integer categoryType = createReqBO.getCategoryType();
if (categoryType == null) {
ErpProductRespVO product = productService.getProduct(createReqBO.getProductId());
categoryType = product != null ? product.getCategoryType() : null;
}
// 2. 创建库存明细
ErpStockRecordDO stockRecord = BeanUtils.toBean(createReqBO, ErpStockRecordDO.class)
.setCategoryId(createReqBO.getCategoryId())
.setCategoryType(categoryType)
.setTotalCount(totalCount);
stockRecordMapper.insert(stockRecord);
}
}
}

@ -39,6 +39,8 @@ public interface ErpStockService {
*/
ErpStockDO getStock(Long productId, Long warehouseId);
ErpStockDO getStock(Long productId, Long warehouseId, Long areaId);
/**
*
* 0
@ -64,6 +66,7 @@ public interface ErpStockService {
* @param count
* @return
*/
BigDecimal updateStockCountIncrement(Long categoryId, Long productId, Long warehouseId, BigDecimal count);
BigDecimal updateStockCountIncrement(Long categoryId, Long productId, Long warehouseId, Long areaId,
String areaName, BigDecimal count);
}
}

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.erp.service.stock;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.stock.ErpStockPageReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockMapper;
@ -42,12 +43,31 @@ public class ErpStockServiceImpl implements ErpStockService {
@Override
public ErpStockDO getStock(Long id) {
return stockMapper.selectById(id);
ErpStockDO stock = stockMapper.selectById(id);
if (stock != null && stock.getCategoryType() == null) {
ErpProductRespVO product = productService.getProduct(stock.getProductId());
if (product != null) {
stock.setCategoryType(product.getCategoryType());
}
}
return stock;
}
@Override
public ErpStockDO getStock(Long productId, Long warehouseId) {
return stockMapper.selectByProductIdAndWarehouseId(productId, warehouseId);
return getStock(productId, warehouseId, null);
}
@Override
public ErpStockDO getStock(Long productId, Long warehouseId, Long areaId) {
ErpStockDO stock = stockMapper.selectByProductIdAndWarehouseIdAndAreaId(productId, warehouseId, areaId);
if (stock != null && stock.getCategoryType() == null) {
ErpProductRespVO product = productService.getProduct(productId);
if (product != null) {
stock.setCategoryType(product.getCategoryType());
}
}
return stock;
}
@Override
public List<ErpStockDO> getStockByProductId(Long productId) {
@ -66,13 +86,24 @@ public class ErpStockServiceImpl implements ErpStockService {
}
@Override
public BigDecimal updateStockCountIncrement(Long categoryId,Long productId, Long warehouseId, BigDecimal count) {
public BigDecimal updateStockCountIncrement(Long categoryId, Long productId, Long warehouseId, Long areaId,
String areaName, BigDecimal count) {
ErpProductRespVO product = productService.getProduct(productId);
Integer categoryType = product != null ? product.getCategoryType() : null;
// 1.1 查询当前库存
ErpStockDO stock = stockMapper.selectByProductIdAndWarehouseId(productId, warehouseId);
ErpStockDO stock = stockMapper.selectByProductIdAndWarehouseIdAndAreaId(productId, warehouseId, areaId);
if (stock == null) {
stock = new ErpStockDO().setProductId(productId).setWarehouseId(warehouseId).setCount(BigDecimal.ZERO);
stock = new ErpStockDO().setProductId(productId).setWarehouseId(warehouseId).setAreaId(areaId)
.setAreaName(areaName).setCount(BigDecimal.ZERO).setCategoryType(categoryType);
stock.setCategoryId(categoryId);
stockMapper.insert(stock);
} else if (stock.getCategoryType() == null) {
stock.setCategoryType(categoryType);
stockMapper.updateById(new ErpStockDO().setId(stock.getId()).setCategoryType(categoryType));
} else if (stock.getAreaId() != null && (stock.getAreaName() == null || stock.getAreaName().isEmpty())
&& areaName != null && !areaName.isEmpty()) {
stock.setAreaName(areaName);
stockMapper.updateById(new ErpStockDO().setId(stock.getId()).setAreaName(areaName));
}
// 1.2 校验库存是否充足
if (!NEGATIVE_STOCK_COUNT_ENABLE && stock.getCount().add(count).compareTo(BigDecimal.ZERO) < 0) {
@ -92,4 +123,4 @@ public class ErpStockServiceImpl implements ErpStockService {
return stock.getCount().add(count);
}
}
}

@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.erp.service.stock.bo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -15,7 +14,6 @@ import java.time.LocalDateTime;
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ErpStockRecordCreateReqBO {
/**
@ -28,11 +26,23 @@ public class ErpStockRecordCreateReqBO {
*/
@NotNull(message = "产品类型不能为空")
private Long categoryId;
/**
*
*/
private Integer categoryType;
/**
*
*/
@NotNull(message = "仓库编号不能为空")
private Long warehouseId;
/**
*
*/
private Long areaId;
/**
*
*/
private String areaName;
/**
*
*
@ -64,4 +74,33 @@ public class ErpStockRecordCreateReqBO {
@NotNull(message = "出入库时间不能为空")
private LocalDateTime recordTime;
public ErpStockRecordCreateReqBO(Long productId, Long categoryId, Long warehouseId, BigDecimal count,
Integer bizType, Long bizId, Long bizItemId, String bizNo,
LocalDateTime recordTime) {
this(productId, categoryId, null, warehouseId, null, null, count, bizType, bizId, bizItemId, bizNo, recordTime);
}
public ErpStockRecordCreateReqBO(Long productId, Long categoryId, Integer categoryType, Long warehouseId,
BigDecimal count, Integer bizType, Long bizId, Long bizItemId,
String bizNo, LocalDateTime recordTime) {
this(productId, categoryId, categoryType, warehouseId, null, null, count, bizType, bizId, bizItemId, bizNo, recordTime);
}
public ErpStockRecordCreateReqBO(Long productId, Long categoryId, Integer categoryType, Long warehouseId,
Long areaId, String areaName, BigDecimal count, Integer bizType, Long bizId,
Long bizItemId, String bizNo, LocalDateTime recordTime) {
this.productId = productId;
this.categoryId = categoryId;
this.categoryType = categoryType;
this.warehouseId = warehouseId;
this.areaId = areaId;
this.areaName = areaName;
this.count = count;
this.bizType = bizType;
this.bizId = bizId;
this.bizItemId = bizItemId;
this.bizNo = bizNo;
this.recordTime = recordTime;
}
}

@ -10,6 +10,7 @@
-->
<select id="selectListByIdsWithDeleted" resultType="cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO">
SELECT id, name, bar_code, category_id, sub_category_id, sub_category_name, unit_id,
purchase_unit_id, purchase_unit_name, purchase_unit_convert_quantity,
status, standard, remark, expiry_day, weight, purchase_price, sale_price,
min_price, safety_number, create_time, update_time, creator, updater, deleted
FROM erp_product

Loading…
Cancel
Save