Compare commits
2 Commits
67f404a10f
...
08715a54fc
| Author | SHA1 | Date |
|---|---|---|
|
|
08715a54fc | |
|
|
84afc4c0e2 |
|
|
@ -3,6 +3,8 @@ package com.njzscloud.dispose.mfg.bom.controller;
|
||||||
import com.njzscloud.common.core.utils.R;
|
import com.njzscloud.common.core.utils.R;
|
||||||
import com.njzscloud.common.mp.support.PageParam;
|
import com.njzscloud.common.mp.support.PageParam;
|
||||||
import com.njzscloud.common.mp.support.PageResult;
|
import com.njzscloud.common.mp.support.PageResult;
|
||||||
|
import com.njzscloud.dispose.mfg.bom.pojo.dto.BomAddDto;
|
||||||
|
import com.njzscloud.dispose.mfg.bom.pojo.dto.BomQueryDto;
|
||||||
import com.njzscloud.dispose.mfg.bom.pojo.entity.BomEntity;
|
import com.njzscloud.dispose.mfg.bom.pojo.entity.BomEntity;
|
||||||
import com.njzscloud.dispose.mfg.bom.service.BomService;
|
import com.njzscloud.dispose.mfg.bom.service.BomService;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
@ -13,6 +15,8 @@ import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 物料清单
|
* 物料清单
|
||||||
|
*
|
||||||
|
* @author ljw
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
|
|
@ -25,8 +29,8 @@ public class BomController {
|
||||||
* 新增
|
* 新增
|
||||||
*/
|
*/
|
||||||
@PostMapping("/add")
|
@PostMapping("/add")
|
||||||
public R<?> add(@RequestBody BomEntity bomEntity) {
|
public R<?> add(@RequestBody BomAddDto bomAddDTO) {
|
||||||
bomService.add(bomEntity);
|
bomService.add(bomAddDTO);
|
||||||
return R.success();
|
return R.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -60,7 +64,7 @@ public class BomController {
|
||||||
* 分页查询
|
* 分页查询
|
||||||
*/
|
*/
|
||||||
@GetMapping("/paging")
|
@GetMapping("/paging")
|
||||||
public R<PageResult<BomEntity>> paging(PageParam pageParam, BomEntity bomEntity) {
|
public R<PageResult<BomEntity>> paging(PageParam pageParam, BomQueryDto queryDto) {
|
||||||
return R.success(bomService.paging(pageParam, bomEntity));
|
return R.success(bomService.paging(pageParam, queryDto));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.njzscloud.dispose.mfg.bom.pojo.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BOM新增DTO
|
||||||
|
* 包含BOM主表信息和明细列表
|
||||||
|
* @author ljw
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
public class BomAddDto {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主产品 Id;gds_goods.id
|
||||||
|
*/
|
||||||
|
private Long goodId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物料清单版本号
|
||||||
|
*/
|
||||||
|
private String bomVer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否可用;0-->否、1-->是
|
||||||
|
*/
|
||||||
|
private Boolean canuse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 备注
|
||||||
|
*/
|
||||||
|
private String memo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BOM明细列表
|
||||||
|
*/
|
||||||
|
private List<BomDetailAddDto> details;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.njzscloud.dispose.mfg.bom.pojo.dto;
|
||||||
|
|
||||||
|
import com.njzscloud.dispose.mfg.bom.constant.MtlType;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物料清单明细
|
||||||
|
* @author ljw
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class BomDetailAddDto {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 产品 Id;gds_goods.id
|
||||||
|
*/
|
||||||
|
private Long goodsId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物料类型,YuanLiao-->原料、FuChanPin-->副产品、ZhuChanPin-->主产品
|
||||||
|
*/
|
||||||
|
private MtlType mtlType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为产出;0-->否、1-->是
|
||||||
|
*/
|
||||||
|
private Boolean chu;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消耗/产出量;如果为产出,则此值为 1
|
||||||
|
*/
|
||||||
|
private BigDecimal quantity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否必需;0-->否、1-->是
|
||||||
|
*/
|
||||||
|
private Boolean mandatory;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.njzscloud.dispose.mfg.bom.pojo.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BOM查询DTO
|
||||||
|
* 用于分页查询的查询条件
|
||||||
|
* @author ljw
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
public class BomQueryDto {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编码(模糊查询)
|
||||||
|
*/
|
||||||
|
private String sn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主产品 Id;gds_goods.id
|
||||||
|
*/
|
||||||
|
private Long goodId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否可用;0-->否、1-->是
|
||||||
|
*/
|
||||||
|
private Boolean canuse;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,32 +1,65 @@
|
||||||
package com.njzscloud.dispose.mfg.bom.service;
|
package com.njzscloud.dispose.mfg.bom.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.njzscloud.common.core.ex.Exceptions;
|
||||||
import com.njzscloud.common.mp.support.PageParam;
|
import com.njzscloud.common.mp.support.PageParam;
|
||||||
import com.njzscloud.common.mp.support.PageResult;
|
import com.njzscloud.common.mp.support.PageResult;
|
||||||
|
import com.njzscloud.common.sn.support.SnUtil;
|
||||||
|
import com.njzscloud.dispose.mfg.bom.constant.MtlType;
|
||||||
import com.njzscloud.dispose.mfg.bom.mapper.BomMapper;
|
import com.njzscloud.dispose.mfg.bom.mapper.BomMapper;
|
||||||
|
import com.njzscloud.dispose.mfg.bom.pojo.dto.BomAddDto;
|
||||||
|
import com.njzscloud.dispose.mfg.bom.pojo.dto.BomDetailAddDto;
|
||||||
|
import com.njzscloud.dispose.mfg.bom.pojo.dto.BomQueryDto;
|
||||||
|
import com.njzscloud.dispose.mfg.bom.pojo.entity.BomDetailEntity;
|
||||||
import com.njzscloud.dispose.mfg.bom.pojo.entity.BomEntity;
|
import com.njzscloud.dispose.mfg.bom.pojo.entity.BomEntity;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 物料清单
|
* 物料清单
|
||||||
|
*
|
||||||
|
* @author ljw
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class BomService extends ServiceImpl<BomMapper, BomEntity> implements IService<BomEntity> {
|
public class BomService extends ServiceImpl<BomMapper, BomEntity> implements IService<BomEntity> {
|
||||||
|
|
||||||
|
private final BomDetailService bomDetailService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增
|
* 新增
|
||||||
*/
|
*/
|
||||||
public void add(BomEntity bomEntity) {
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void add(BomAddDto bomAddDTO) {
|
||||||
|
BomEntity bomEntity = BeanUtil.copyProperties(bomAddDTO, BomEntity.class).setSn(this.generateSn());
|
||||||
|
|
||||||
|
// 校验版本号唯一性
|
||||||
|
validateBomVersionUniqueness(bomEntity.getGoodId(), bomEntity.getBomVer(), null);
|
||||||
|
// 校验可用性(同一主产品ID只能有一个可用的BOM)
|
||||||
|
validateBomAvailability(bomEntity.getGoodId(), null);
|
||||||
|
|
||||||
|
// 预校验明细数据
|
||||||
|
validateBomDetails(bomAddDTO.getDetails(), bomEntity.getGoodId());
|
||||||
|
|
||||||
|
// 保存BOM主表
|
||||||
this.save(bomEntity);
|
this.save(bomEntity);
|
||||||
|
|
||||||
|
// 保存BOM明细
|
||||||
|
for (BomDetailAddDto detail : bomAddDTO.getDetails()) {
|
||||||
|
// 直接保存,不使用BomDetailService的add方法(避免重复校验)
|
||||||
|
BomDetailEntity detailEntity = BeanUtil.copyProperties(detail, BomDetailEntity.class).setBomId(bomEntity.getId());
|
||||||
|
bomDetailService.save(detailEntity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -54,7 +87,94 @@ public class BomService extends ServiceImpl<BomMapper, BomEntity> implements ISe
|
||||||
/**
|
/**
|
||||||
* 分页查询
|
* 分页查询
|
||||||
*/
|
*/
|
||||||
public PageResult<BomEntity> paging(PageParam pageParam, BomEntity bomEntity) {
|
public PageResult<BomEntity> paging(PageParam pageParam, BomQueryDto queryDto) {
|
||||||
return PageResult.of(this.page(pageParam.toPage(), Wrappers.<BomEntity>query(bomEntity)));
|
return PageResult.of(this.page(pageParam.toPage(), Wrappers.<BomEntity>lambdaQuery()
|
||||||
|
.like(StrUtil.isNotBlank(queryDto.getSn()), BomEntity::getSn, queryDto.getSn())
|
||||||
|
.eq(queryDto.getGoodId() != null, BomEntity::getGoodId, queryDto.getGoodId())
|
||||||
|
.eq(queryDto.getCanuse() != null, BomEntity::getCanuse, queryDto.getCanuse())));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验BOM版本号唯一性
|
||||||
|
*
|
||||||
|
* @param goodId 主产品ID
|
||||||
|
* @param bomVer 版本号
|
||||||
|
* @param excludeId 排除的ID(用于修改时排除自身)
|
||||||
|
*/
|
||||||
|
private void validateBomVersionUniqueness(Long goodId, String bomVer, Long excludeId) {
|
||||||
|
|
||||||
|
long count = this.count(Wrappers.<BomEntity>lambdaQuery()
|
||||||
|
.eq(BomEntity::getGoodId, goodId)
|
||||||
|
.eq(BomEntity::getBomVer, bomVer)
|
||||||
|
.ne(excludeId != null, BomEntity::getId, excludeId));
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
throw Exceptions.clierr("同一主产品的BOM版本号必须唯一");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验BOM可用性(同一主产品ID只能有一个可用的BOM)
|
||||||
|
*
|
||||||
|
* @param goodId 主产品ID
|
||||||
|
* @param excludeId 排除的ID(用于修改时排除自身)
|
||||||
|
*/
|
||||||
|
private void validateBomAvailability(Long goodId, Long excludeId) {
|
||||||
|
long count = this.count(Wrappers.<BomEntity>lambdaQuery()
|
||||||
|
.eq(BomEntity::getGoodId, goodId)
|
||||||
|
.eq(BomEntity::getCanuse, Boolean.TRUE)
|
||||||
|
.ne(excludeId != null, BomEntity::getId, excludeId));
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
|
throw Exceptions.clierr("同一主产品只能有一个可用的BOM");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预校验BOM明细数据
|
||||||
|
*
|
||||||
|
* @param details 明细列表
|
||||||
|
* @param mainProductId 主产品ID
|
||||||
|
*/
|
||||||
|
private void validateBomDetails(List<BomDetailAddDto> details, Long mainProductId) {
|
||||||
|
if (details == null || details.isEmpty()) {
|
||||||
|
throw Exceptions.clierr("必须包含至少一个明细");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasMainProduct = false;
|
||||||
|
|
||||||
|
for (BomDetailAddDto detail : details) {
|
||||||
|
// 校验产出物料数量必须为1
|
||||||
|
if (Boolean.TRUE.equals(detail.getChu()) && (detail.getQuantity() == null || detail.getQuantity().compareTo(BigDecimal.ONE) != 0)) {
|
||||||
|
throw Exceptions.clierr("产出物料的数量必须为1");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否包含主产品明细
|
||||||
|
if (detail.getGoodsId() != null && detail.getGoodsId().equals(mainProductId)) {
|
||||||
|
if (detail.getMtlType() == MtlType.ZhuChanPin) {
|
||||||
|
hasMainProduct = true;
|
||||||
|
} else {
|
||||||
|
throw Exceptions.clierr("与主产品ID相同的产品必须是主产品类型");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasMainProduct) {
|
||||||
|
throw Exceptions.clierr("明细中必须包含与主产品ID相同且类型为主产品的记录");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成编码
|
||||||
|
*
|
||||||
|
* @return sn 编码
|
||||||
|
*/
|
||||||
|
public String generateSn() {
|
||||||
|
String sn = SnUtil.next("Bom-SN");
|
||||||
|
if (this.exists(Wrappers.<BomEntity>lambdaQuery().eq(BomEntity::getSn, sn).eq(BomEntity::getDeleted, Boolean.FALSE))) {
|
||||||
|
this.generateSn();
|
||||||
|
}
|
||||||
|
return sn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue