|
|
|
|
@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.common.dal.mysql.mold.MoldBrandMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.common.enums.MoldBrandStatusEnum;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.pallet.enums.ErpPalletStatusEnum;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductPackagingSchemeRespVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutAuditReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutPageReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSaveReqVO;
|
|
|
|
|
@ -21,6 +22,7 @@ import cn.iocoder.yudao.module.erp.dal.dataobject.pallet.ErpPalletDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutApproveRecordDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockOutItemPalletDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpWarehouseDO;
|
|
|
|
|
@ -55,8 +57,10 @@ import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Collection;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.LinkedHashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Objects;
|
|
|
|
|
@ -105,6 +109,8 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockRecordService stockRecordService;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockService stockService;
|
|
|
|
|
@Resource
|
|
|
|
|
private WarehouseAreaService warehouseAreaService;
|
|
|
|
|
@Resource
|
|
|
|
|
private AdminUserApi adminUserApi;
|
|
|
|
|
@ -120,12 +126,14 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public Long createStockOut(ErpStockOutSaveReqVO createReqVO) {
|
|
|
|
|
BigDecimal totalCount = getOriginalProductStockOutTotalCount(createReqVO);
|
|
|
|
|
normalizeProductStockOutItems(createReqVO);
|
|
|
|
|
List<ErpStockOutItemDO> stockOutItems = validateStockOutItems(createReqVO.getItems(), createReqVO.getOutType());
|
|
|
|
|
if (createReqVO.getCustomerId() != null) {
|
|
|
|
|
customerService.validateCustomer(createReqVO.getCustomerId());
|
|
|
|
|
}
|
|
|
|
|
if (createReqVO.getResponserId() != null) {
|
|
|
|
|
adminUserApi.validateUser(createReqVO.getResponserId());
|
|
|
|
|
if (createReqVO.getStockUserId() != null) {
|
|
|
|
|
adminUserApi.validateUser(createReqVO.getStockUserId());
|
|
|
|
|
}
|
|
|
|
|
if (createReqVO.getAuditUserId() != null) {
|
|
|
|
|
adminUserApi.validateUser(createReqVO.getAuditUserId());
|
|
|
|
|
@ -141,7 +149,8 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
|
|
|
|
|
.setNo(no)
|
|
|
|
|
.setNeedAudit(needAudit)
|
|
|
|
|
.setStatus(status)
|
|
|
|
|
.setTotalCount(getSumValue(stockOutItems, ErpStockOutItemDO::getCount, BigDecimal::add))
|
|
|
|
|
.setTotalCount(totalCount != null ? totalCount
|
|
|
|
|
: getSumValue(stockOutItems, ErpStockOutItemDO::getCount, BigDecimal::add))
|
|
|
|
|
.setTotalPrice(getSumValue(stockOutItems, ErpStockOutItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)));
|
|
|
|
|
fillUsageSnapshot(stockOutItems, createReqVO.getItems());
|
|
|
|
|
stockOutMapper.insert(stockOut);
|
|
|
|
|
@ -165,6 +174,8 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public void updateStockOut(ErpStockOutSaveReqVO updateReqVO) {
|
|
|
|
|
BigDecimal totalCount = getOriginalProductStockOutTotalCount(updateReqVO);
|
|
|
|
|
normalizeProductStockOutItems(updateReqVO);
|
|
|
|
|
ErpStockOutDO stockOut = validateStockOutExists(updateReqVO.getId());
|
|
|
|
|
if (ErpAuditStatus.APPROVE.getStatus().equals(stockOut.getStatus())) {
|
|
|
|
|
throw exception(STOCK_OUT_UPDATE_FAIL_APPROVE, stockOut.getNo());
|
|
|
|
|
@ -175,8 +186,8 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
|
|
|
|
|
if (updateReqVO.getCustomerId() != null) {
|
|
|
|
|
customerService.validateCustomer(updateReqVO.getCustomerId());
|
|
|
|
|
}
|
|
|
|
|
if (updateReqVO.getResponserId() != null) {
|
|
|
|
|
adminUserApi.validateUser(updateReqVO.getResponserId());
|
|
|
|
|
if (updateReqVO.getStockUserId() != null) {
|
|
|
|
|
adminUserApi.validateUser(updateReqVO.getStockUserId());
|
|
|
|
|
}
|
|
|
|
|
if (updateReqVO.getAuditUserId() != null) {
|
|
|
|
|
adminUserApi.validateUser(updateReqVO.getAuditUserId());
|
|
|
|
|
@ -185,11 +196,13 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
|
|
|
|
|
boolean needAudit = needAudit();
|
|
|
|
|
ErpStockOutDO updateObj = BeanUtils.toBean(updateReqVO, ErpStockOutDO.class, out -> out
|
|
|
|
|
.setNeedAudit(needAudit)
|
|
|
|
|
.setTotalCount(getSumValue(stockOutItems, ErpStockOutItemDO::getCount, BigDecimal::add))
|
|
|
|
|
.setTotalCount(totalCount != null ? totalCount
|
|
|
|
|
: getSumValue(stockOutItems, ErpStockOutItemDO::getCount, BigDecimal::add))
|
|
|
|
|
.setTotalPrice(getSumValue(stockOutItems, ErpStockOutItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)));
|
|
|
|
|
fillUsageSnapshot(stockOutItems, updateReqVO.getItems());
|
|
|
|
|
stockOutMapper.updateById(updateObj);
|
|
|
|
|
updateStockOutItemList(updateReqVO.getId(), stockOutItems);
|
|
|
|
|
updateStockOutItemList(updateReqVO.getId(), stockOutItems,
|
|
|
|
|
Objects.equals(updateReqVO.getOutType(), "产品出库"));
|
|
|
|
|
saveStockOutItemPallets(updateReqVO.getId(), stockOutItems, updateReqVO.getItems());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -375,6 +388,88 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
|
|
|
|
|
return stockOutMapper.selectByOutType(outTypes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private BigDecimal getOriginalProductStockOutTotalCount(ErpStockOutSaveReqVO reqVO) {
|
|
|
|
|
if (reqVO == null || !Objects.equals(reqVO.getOutType(), "产品出库")
|
|
|
|
|
|| CollUtil.isEmpty(reqVO.getItems())) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
return getSumValue(reqVO.getItems(), ErpStockOutSaveReqVOItem::getCount, BigDecimal::add, BigDecimal.ZERO);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void normalizeProductStockOutItems(ErpStockOutSaveReqVO reqVO) {
|
|
|
|
|
if (reqVO == null || !Objects.equals(reqVO.getOutType(), "产品出库")
|
|
|
|
|
|| CollUtil.isEmpty(reqVO.getItems())) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
List<ErpStockOutSaveReqVOItem> normalizedItems = new ArrayList<>();
|
|
|
|
|
for (ErpStockOutSaveReqVOItem sourceItem : reqVO.getItems()) {
|
|
|
|
|
if (CollUtil.isEmpty(sourceItem.getPallets())) {
|
|
|
|
|
normalizedItems.add(sourceItem);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
Map<StockOutPalletGroupKey, ErpStockOutSaveReqVOItem> itemMap = new LinkedHashMap<>();
|
|
|
|
|
Map<StockOutPalletGroupKey, List<ErpStockOutSaveReqVOItem.PalletItem>> palletMap = new LinkedHashMap<>();
|
|
|
|
|
for (ErpStockOutSaveReqVOItem.PalletItem pallet : sourceItem.getPallets()) {
|
|
|
|
|
Long warehouseId = pallet.getWarehouseId() != null ? pallet.getWarehouseId() : sourceItem.getWarehouseId();
|
|
|
|
|
Long areaId = pallet.getAreaId() != null ? pallet.getAreaId() : sourceItem.getAreaId();
|
|
|
|
|
StockOutPalletGroupKey key = new StockOutPalletGroupKey(warehouseId, areaId);
|
|
|
|
|
ErpStockOutSaveReqVOItem targetItem = itemMap.computeIfAbsent(key,
|
|
|
|
|
item -> copyStockOutItem(sourceItem, warehouseId, areaId));
|
|
|
|
|
targetItem.setCount(defaultZero(targetItem.getCount()).add(resolvePalletCount(pallet)));
|
|
|
|
|
targetItem.setPackageCount(defaultZero(targetItem.getPackageCount()).add(defaultZero(pallet.getPackageCount())));
|
|
|
|
|
palletMap.computeIfAbsent(key, item -> new ArrayList<>()).add(pallet);
|
|
|
|
|
}
|
|
|
|
|
itemMap.forEach((key, item) -> {
|
|
|
|
|
item.setPallets(palletMap.getOrDefault(key, Collections.emptyList()));
|
|
|
|
|
normalizedItems.add(item);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
reqVO.setItems(normalizedItems);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ErpStockOutSaveReqVOItem copyStockOutItem(ErpStockOutSaveReqVOItem sourceItem, Long warehouseId, Long areaId) {
|
|
|
|
|
ErpStockOutSaveReqVOItem targetItem = BeanUtils.toBean(sourceItem, ErpStockOutSaveReqVOItem.class);
|
|
|
|
|
targetItem.setId(null);
|
|
|
|
|
targetItem.setWarehouseId(warehouseId);
|
|
|
|
|
targetItem.setAreaId(areaId);
|
|
|
|
|
targetItem.setCount(BigDecimal.ZERO);
|
|
|
|
|
targetItem.setPackageCount(BigDecimal.ZERO);
|
|
|
|
|
targetItem.setPallets(new ArrayList<>());
|
|
|
|
|
return targetItem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private BigDecimal resolvePalletCount(ErpStockOutSaveReqVOItem.PalletItem pallet) {
|
|
|
|
|
return defaultZero(pallet.getCount());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static class StockOutPalletGroupKey {
|
|
|
|
|
|
|
|
|
|
private final Long warehouseId;
|
|
|
|
|
private final Long areaId;
|
|
|
|
|
|
|
|
|
|
private StockOutPalletGroupKey(Long warehouseId, Long areaId) {
|
|
|
|
|
this.warehouseId = warehouseId;
|
|
|
|
|
this.areaId = areaId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean equals(Object obj) {
|
|
|
|
|
if (this == obj) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (!(obj instanceof StockOutPalletGroupKey)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
StockOutPalletGroupKey that = (StockOutPalletGroupKey) obj;
|
|
|
|
|
return Objects.equals(warehouseId, that.warehouseId) && Objects.equals(areaId, that.areaId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int hashCode() {
|
|
|
|
|
return Objects.hash(warehouseId, areaId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void updateMoldStatus(Long id, Integer status) {
|
|
|
|
|
ErpStockOutDO stockOut = validateStockOutExists(id);
|
|
|
|
|
@ -568,10 +663,11 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void updateStockOutItemList(Long id, List<ErpStockOutItemDO> newList) {
|
|
|
|
|
private void updateStockOutItemList(Long id, List<ErpStockOutItemDO> newList, boolean recreateItems) {
|
|
|
|
|
boolean moldStockOut = CollUtil.isNotEmpty(newList)
|
|
|
|
|
&& newList.stream().anyMatch(item -> item.getMoldSetId() != null);
|
|
|
|
|
if (moldStockOut) {
|
|
|
|
|
if (moldStockOut || recreateItems) {
|
|
|
|
|
stockOutItemPalletMapper.deleteByOutId(id);
|
|
|
|
|
stockOutItemMapper.deleteByOutId(id);
|
|
|
|
|
newList.forEach(item -> {
|
|
|
|
|
item.setId(null);
|
|
|
|
|
@ -612,7 +708,10 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
|
|
|
|
|
.outId(outId)
|
|
|
|
|
.outItemId(stockOutItem.getId())
|
|
|
|
|
.palletId(pallet.getPalletId())
|
|
|
|
|
.packageCount(defaultPackageCount(pallet.getPackageCount(), stockOutItem.getCount()))
|
|
|
|
|
.warehouseId(pallet.getWarehouseId() != null ? pallet.getWarehouseId() : stockOutItem.getWarehouseId())
|
|
|
|
|
.areaId(pallet.getAreaId() != null ? pallet.getAreaId() : stockOutItem.getAreaId())
|
|
|
|
|
.count(resolvePalletCount(pallet))
|
|
|
|
|
.packageCount(defaultZero(pallet.getPackageCount()))
|
|
|
|
|
.build()));
|
|
|
|
|
}
|
|
|
|
|
if (CollUtil.isNotEmpty(palletRelations)) {
|
|
|
|
|
@ -626,6 +725,7 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Map<Long, ErpStockOutItemDO> itemMap = convertMap(stockOutItems, ErpStockOutItemDO::getId);
|
|
|
|
|
Map<Long, ErpProductDO> productMap = productService.getProductMap(convertSet(stockOutItems, ErpStockOutItemDO::getProductId));
|
|
|
|
|
Map<Long, ErpPalletDO> palletMap = convertMap(palletMapper.selectBatchIds(
|
|
|
|
|
convertSet(palletRelations, ErpStockOutItemPalletDO::getPalletId)), ErpPalletDO::getId);
|
|
|
|
|
palletRelations.forEach(relation -> {
|
|
|
|
|
@ -640,13 +740,18 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
|
|
|
|
|
if (remainCount.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
|
|
pallet.setStatus(ErpPalletStatusEnum.IDLE.getStatus());
|
|
|
|
|
pallet.setProductId(null);
|
|
|
|
|
pallet.setProductName(null);
|
|
|
|
|
pallet.setProductCount(BigDecimal.ZERO);
|
|
|
|
|
pallet.setWarehouseId(null);
|
|
|
|
|
pallet.setAreaId(null);
|
|
|
|
|
} else {
|
|
|
|
|
pallet.setProductCount(remainCount);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
pallet.setStatus(ErpPalletStatusEnum.OCCUPIED.getStatus());
|
|
|
|
|
pallet.setProductId(item.getProductId());
|
|
|
|
|
ErpProductDO product = productMap.get(item.getProductId());
|
|
|
|
|
pallet.setProductName(product != null ? product.getName() : null);
|
|
|
|
|
pallet.setProductCount(defaultZero(pallet.getProductCount()).add(packageCount));
|
|
|
|
|
pallet.setWarehouseId(item.getWarehouseId());
|
|
|
|
|
pallet.setAreaId(item.getAreaId());
|
|
|
|
|
@ -655,10 +760,6 @@ public class ErpStockOutServiceImpl implements ErpStockOutService {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private BigDecimal defaultPackageCount(BigDecimal packageCount, BigDecimal itemCount) {
|
|
|
|
|
return packageCount != null ? packageCount : defaultZero(itemCount);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private BigDecimal defaultZero(BigDecimal value) {
|
|
|
|
|
return value != null ? value : BigDecimal.ZERO;
|
|
|
|
|
}
|
|
|
|
|
|