|
|
|
|
@ -5,21 +5,27 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInItemDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInItemMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.mysql.stock.ErpStockInMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.enums.stock.ErpStockRecordBizTypeEnum;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
|
|
|
|
|
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.stock.bo.ErpStockRecordCreateReqBO;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.controller.admin.plan.vo.PlanStatusEnum;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.dataobject.plan.PlanDO;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.dataobject.stockindetail.StockInDetailDO;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.mysql.stockindetail.StockInDetailMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.service.plan.PlanService;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.service.stockindetail.StockInDetailService;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
|
|
|
|
|
@ -40,21 +46,20 @@ public class MesStockInServiceImpl implements MesStockInService {
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockInItemMapper stockInItemMapper;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpNoRedisDAO noRedisDAO;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpProductService productService;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpWarehouseService warehouseService;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpSupplierService supplierService;
|
|
|
|
|
private StockInDetailMapper stockInDetailMapper;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockRecordService stockRecordService;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private StockInDetailService stockInDetailService;
|
|
|
|
|
@Resource
|
|
|
|
|
private PlanService planService;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public void updateStockInStatus(Long id, Integer status) {
|
|
|
|
|
boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status);
|
|
|
|
|
// 1.1 校验存在
|
|
|
|
|
@ -64,6 +69,42 @@ public class MesStockInServiceImpl implements MesStockInService {
|
|
|
|
|
throw exception(approve ? STOCK_IN_APPROVE_FAIL : STOCK_IN_PROCESS_FAIL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 3. 变更库存
|
|
|
|
|
List<ErpStockInItemDO> stockInItems = stockInItemMapper.selectListByInId(id);
|
|
|
|
|
|
|
|
|
|
//生产入库分配给计划
|
|
|
|
|
//完工的计划列表
|
|
|
|
|
List<Integer> statusList = new ArrayList<>();
|
|
|
|
|
statusList.add(PlanStatusEnum.完工.getValue());
|
|
|
|
|
List<PlanDO> finishedPlans = planService.getPlanByStatus(statusList);
|
|
|
|
|
planService.buildProgress(finishedPlans);
|
|
|
|
|
|
|
|
|
|
//开工的计划列表
|
|
|
|
|
statusList = new ArrayList<>();
|
|
|
|
|
statusList.add(PlanStatusEnum.开工.getValue());
|
|
|
|
|
List<PlanDO> startPlans = planService.getPlanByStatus(statusList);
|
|
|
|
|
planService.buildProgress(startPlans);
|
|
|
|
|
//合并同产品
|
|
|
|
|
Map<Long, ErpStockInItemDO> stockInItemDOMap = new HashMap<>();
|
|
|
|
|
stockInItems.forEach(itemDO -> {
|
|
|
|
|
if(stockInItemDOMap.containsKey(itemDO.getProductId())){
|
|
|
|
|
BigDecimal old = stockInItemDOMap.get(itemDO.getProductId()).getCount();
|
|
|
|
|
stockInItemDOMap.get(itemDO.getProductId()).setCount(old.add(itemDO.getCount()));
|
|
|
|
|
}
|
|
|
|
|
else stockInItemDOMap.put(itemDO.getProductId(), itemDO);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//分配
|
|
|
|
|
Map<Long, StockInDetailDO> stockInDetailDOMap = get(stockIn,finishedPlans,startPlans,stockInItemDOMap);
|
|
|
|
|
updateStatus( id, status, approve, stockIn,stockInItems
|
|
|
|
|
,finishedPlans, startPlans, stockInItemDOMap, stockInDetailDOMap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public void updateStatus(Long id, Integer status, boolean approve, ErpStockInDO stockIn,List<ErpStockInItemDO> stockInItems
|
|
|
|
|
,List<PlanDO> finishedPlans, List<PlanDO> startPlans, Map<Long, ErpStockInItemDO> stockInItemDOMap,
|
|
|
|
|
Map<Long, StockInDetailDO> stockInDetailDOMap){
|
|
|
|
|
// 2. 更新状态
|
|
|
|
|
int updateCount = stockInMapper.updateByIdAndStatus(id, stockIn.getStatus(),
|
|
|
|
|
new ErpStockInDO().setStatus(status));
|
|
|
|
|
@ -71,8 +112,6 @@ public class MesStockInServiceImpl implements MesStockInService {
|
|
|
|
|
throw exception(approve ? STOCK_IN_APPROVE_FAIL : STOCK_IN_PROCESS_FAIL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 3. 变更库存
|
|
|
|
|
List<ErpStockInItemDO> stockInItems = stockInItemMapper.selectListByInId(id);
|
|
|
|
|
Integer bizType = approve ? ErpStockRecordBizTypeEnum.OTHER_IN.getType()
|
|
|
|
|
: ErpStockRecordBizTypeEnum.OTHER_IN_CANCEL.getType();
|
|
|
|
|
stockInItems.forEach(stockInItem -> {
|
|
|
|
|
@ -83,11 +122,16 @@ public class MesStockInServiceImpl implements MesStockInService {
|
|
|
|
|
bizType, stockInItem.getInId(), stockInItem.getId(), stockIn.getNo()));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//生产入库分配给计划
|
|
|
|
|
|
|
|
|
|
//保存分配明细
|
|
|
|
|
if(stockInDetailDOMap.size()>0)
|
|
|
|
|
stockInDetailMapper.insertBatch( stockInDetailDOMap.values());
|
|
|
|
|
//将完成数大于计划数的完工计划状态改为 入库状态
|
|
|
|
|
for (PlanDO plan : finishedPlans) {
|
|
|
|
|
if(plan.getFinishNumber()>= plan.getPlanNumber()){
|
|
|
|
|
planService.updateStatus(plan.getId(), PlanStatusEnum.入库.getValue());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private ErpStockInDO validateStockInExists(Long id) {
|
|
|
|
|
ErpStockInDO stockIn = stockInMapper.selectById(id);
|
|
|
|
|
if (stockIn == null) {
|
|
|
|
|
@ -96,5 +140,78 @@ public class MesStockInServiceImpl implements MesStockInService {
|
|
|
|
|
return stockIn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Map<Long, StockInDetailDO> get( ErpStockInDO stockIn, List<PlanDO> finishedPlans, List<PlanDO> startPlans,
|
|
|
|
|
Map<Long, ErpStockInItemDO> stockInItemDOMap){
|
|
|
|
|
//分配入库数量
|
|
|
|
|
Map<Long, StockInDetailDO> stockInDetailDOMap = new HashMap<>();
|
|
|
|
|
//先分配给完工的计划
|
|
|
|
|
for (PlanDO plan : finishedPlans) {
|
|
|
|
|
//计划待分配
|
|
|
|
|
long needNumber = plan.getPlanNumber() - plan.getFinishNumber() ;
|
|
|
|
|
if(needNumber > 0 && stockInItemDOMap.containsKey(plan.getProductId())){
|
|
|
|
|
ErpStockInItemDO itemDO = stockInItemDOMap.get(plan.getProductId());
|
|
|
|
|
//入库待分配
|
|
|
|
|
if(itemDO.getCount().compareTo(BigDecimal.ZERO) > 0){
|
|
|
|
|
StockInDetailDO detailDO = new StockInDetailDO()
|
|
|
|
|
.setStockInItemId(itemDO.getId())
|
|
|
|
|
.setStockInId(stockIn.getId()).setStockInNo(stockIn.getNo())
|
|
|
|
|
.setPlanId(plan.getId()).setProductId(plan.getProductId());
|
|
|
|
|
|
|
|
|
|
if(itemDO.getCount().compareTo(BigDecimal.valueOf(needNumber)) > 0){
|
|
|
|
|
detailDO.setNumber(BigDecimal.valueOf(needNumber));
|
|
|
|
|
}
|
|
|
|
|
else detailDO.setNumber(itemDO.getCount());
|
|
|
|
|
//入库数量减去分配给计划的数量
|
|
|
|
|
itemDO.setCount(itemDO.getCount().add(detailDO.getNumber().negate()));
|
|
|
|
|
plan.setFinishNumber(plan.getFinishNumber()+detailDO.getNumber().longValue());
|
|
|
|
|
stockInDetailDOMap.put(itemDO.getId(), detailDO);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//分配给开工的计划
|
|
|
|
|
for (PlanDO plan : startPlans) {
|
|
|
|
|
//计划待分配
|
|
|
|
|
long needNumber = plan.getPlanNumber() - plan.getFinishNumber() ;
|
|
|
|
|
if(needNumber > 0 && stockInItemDOMap.containsKey(plan.getProductId())){
|
|
|
|
|
ErpStockInItemDO itemDO = stockInItemDOMap.get(plan.getProductId());
|
|
|
|
|
//入库待分配
|
|
|
|
|
if(itemDO.getCount().compareTo(BigDecimal.ZERO) > 0){
|
|
|
|
|
StockInDetailDO detailDO = new StockInDetailDO()
|
|
|
|
|
.setStockInItemId(itemDO.getId())
|
|
|
|
|
.setStockInId(stockIn.getId()).setStockInNo(stockIn.getNo())
|
|
|
|
|
.setPlanId(plan.getId()).setProductId(plan.getProductId());
|
|
|
|
|
|
|
|
|
|
if(itemDO.getCount().compareTo(BigDecimal.valueOf(needNumber)) > 0){
|
|
|
|
|
detailDO.setNumber(BigDecimal.valueOf(needNumber));
|
|
|
|
|
}
|
|
|
|
|
else detailDO.setNumber(itemDO.getCount());
|
|
|
|
|
//入库数量减去分配给计划的数量
|
|
|
|
|
itemDO.setCount(itemDO.getCount().add(detailDO.getNumber().negate()));
|
|
|
|
|
plan.setFinishNumber(plan.getFinishNumber()+detailDO.getNumber().longValue());
|
|
|
|
|
stockInDetailDOMap.put(itemDO.getId(), detailDO);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//处理剩下的
|
|
|
|
|
for (Long productId : stockInItemDOMap.keySet()) {
|
|
|
|
|
ErpStockInItemDO itemDO = stockInItemDOMap.get(productId);
|
|
|
|
|
//有剩余未分配
|
|
|
|
|
if(itemDO.getCount().compareTo(BigDecimal.ZERO)>0){
|
|
|
|
|
if(stockInDetailDOMap.containsKey(itemDO.getId())){
|
|
|
|
|
BigDecimal old = stockInDetailDOMap.get(itemDO.getId()).getNumber();
|
|
|
|
|
stockInDetailDOMap.get(itemDO.getId()).setNumber(old.add(itemDO.getCount()));
|
|
|
|
|
}else{
|
|
|
|
|
StockInDetailDO detailDO = new StockInDetailDO()
|
|
|
|
|
.setStockInItemId(itemDO.getId())
|
|
|
|
|
.setStockInId(stockIn.getId()).setStockInNo(stockIn.getNo())
|
|
|
|
|
.setPlanId(null).setProductId(itemDO.getProductId());
|
|
|
|
|
detailDO.setNumber(itemDO.getCount());
|
|
|
|
|
stockInDetailDOMap.put(itemDO.getId(), detailDO);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return stockInDetailDOMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|