|
|
|
|
@ -3,19 +3,23 @@ package cn.iocoder.yudao.module.erp.service.stock;
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
|
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
|
|
|
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
|
|
|
|
|
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
|
|
|
|
import cn.iocoder.yudao.framework.common.util.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.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.out.ErpStockOutSaveReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInSubmitReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.ErpStockInApproveRecordDO;
|
|
|
|
|
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.dataobject.stock.ErpStockOutDO;
|
|
|
|
|
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.ErpStockInApproveRecordMapper;
|
|
|
|
|
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.mysql.stock.ErpStockMapper;
|
|
|
|
|
@ -27,40 +31,62 @@ 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.bo.ErpStockRecordCreateReqBO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.service.warehousearea.WarehouseAreaService;
|
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|
|
|
|
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.*;
|
|
|
|
|
import java.util.Collection;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Objects;
|
|
|
|
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
|
|
|
|
|
|
|
|
|
|
// TODO 芋艿:记录操作日志
|
|
|
|
|
/**
|
|
|
|
|
* ERP 其它入库单 Service 实现类
|
|
|
|
|
*
|
|
|
|
|
* @author 芋道源码
|
|
|
|
|
*/
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList;
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_ALERADY_IN;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_APPROVE_FAIL;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_AUDIT_FAIL_RESULT;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_AUDIT_FAIL_STATUS;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_AUDIT_FAIL_USER;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_DELETE_FAIL_APPROVE;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_DELETE_FAIL_PROCESS;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_NOT_EXISTS;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_NO_EXISTS;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_PROCESS_FAIL;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_SUBMIT_FAIL_AUDIT_USER_EMPTY;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_SUBMIT_FAIL_STATUS;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_SUBMIT_FAIL_USER;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_UPDATE_FAIL_APPROVE;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_IN_UPDATE_FAIL_PROCESS;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_AREA_NOT_EXISTS;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_LOCATION_WAREHOUSE_AREA_NOT_MATCH;
|
|
|
|
|
|
|
|
|
|
@Service
|
|
|
|
|
@Validated
|
|
|
|
|
public class ErpStockInServiceImpl implements ErpStockInService {
|
|
|
|
|
|
|
|
|
|
private static final String ACTION_SUBMIT = "SUBMIT";
|
|
|
|
|
private static final String ACTION_APPROVE = "APPROVE";
|
|
|
|
|
private static final String ACTION_REJECT = "REJECT";
|
|
|
|
|
private static final String ACTION_AUTO_APPROVE = "AUTO_APPROVE";
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockInMapper stockInMapper;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockInItemMapper stockInItemMapper;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockInApproveRecordMapper stockInApproveRecordMapper;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockMapper erpStockMapper;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpNoRedisDAO noRedisDAO;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpProductService productService;
|
|
|
|
|
@Resource
|
|
|
|
|
@ -73,154 +99,325 @@ public class ErpStockInServiceImpl implements ErpStockInService {
|
|
|
|
|
private MoldBrandService moldBrandService;
|
|
|
|
|
@Resource
|
|
|
|
|
private WarehouseAreaService warehouseAreaService;
|
|
|
|
|
@Resource
|
|
|
|
|
private AdminUserApi adminUserApi;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public Long createStockIn(ErpStockInSaveReqVO createReqVO) {
|
|
|
|
|
// 1.1 校验入库项的有效性
|
|
|
|
|
List<ErpStockInItemDO> stockInItems = validateStockInItems(createReqVO.getItems(),createReqVO.getInType());
|
|
|
|
|
// 1.2 校验供应商
|
|
|
|
|
//supplierService.validateSupplier(createReqVO.getSupplierId());
|
|
|
|
|
// 1.3 生成入库单号,并校验唯一性
|
|
|
|
|
List<ErpStockInItemDO> stockInItems = validateStockInItems(createReqVO.getItems(), createReqVO.getInType());
|
|
|
|
|
if (createReqVO.getStockUserId() != null) {
|
|
|
|
|
adminUserApi.validateUser(createReqVO.getStockUserId());
|
|
|
|
|
}
|
|
|
|
|
if (createReqVO.getAuditUserId() != null) {
|
|
|
|
|
adminUserApi.validateUser(createReqVO.getAuditUserId());
|
|
|
|
|
}
|
|
|
|
|
String no = noRedisDAO.generate(ErpNoRedisDAO.STOCK_IN_NO_PREFIX);
|
|
|
|
|
if (stockInMapper.selectByNo(no) != null) {
|
|
|
|
|
throw exception(STOCK_IN_NO_EXISTS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2.1 插入入库单
|
|
|
|
|
boolean needAudit = !Boolean.FALSE.equals(createReqVO.getNeedAudit());
|
|
|
|
|
Integer status = needAudit ? ErpAuditStatus.DRAFT.getStatus() : ErpAuditStatus.APPROVE.getStatus();
|
|
|
|
|
ErpStockInDO stockIn = BeanUtils.toBean(createReqVO, ErpStockInDO.class, in -> in
|
|
|
|
|
.setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus())
|
|
|
|
|
.setNo(no)
|
|
|
|
|
.setNeedAudit(needAudit)
|
|
|
|
|
.setStatus(status)
|
|
|
|
|
.setTotalCount(getSumValue(stockInItems, ErpStockInItemDO::getCount, BigDecimal::add))
|
|
|
|
|
.setTotalPrice(getSumValue(stockInItems, ErpStockInItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)));
|
|
|
|
|
stockInMapper.insert(stockIn);
|
|
|
|
|
// 2.2 插入入库单项
|
|
|
|
|
stockInItems.forEach(o -> {
|
|
|
|
|
o.setInId(stockIn.getId());
|
|
|
|
|
o.setCount(o.getCount());
|
|
|
|
|
});
|
|
|
|
|
stockInItems.forEach(item -> item.setInId(stockIn.getId()));
|
|
|
|
|
stockInItemMapper.insertBatch(stockInItems);
|
|
|
|
|
// for (ErpStockInItemDO item : stockInItems) {
|
|
|
|
|
// MoldDO moldDO = moldService.getMold(item.getProductId());
|
|
|
|
|
// moldDO.setStatus(ErpAuditStatus.PROCESS.getStatus()); // 未审核
|
|
|
|
|
// moldService.updateMold(BeanUtils.toBean(moldDO, MoldSaveReqVO.class));
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
if (!needAudit) {
|
|
|
|
|
applyStockInEffect(stockIn, stockInItems, null);
|
|
|
|
|
createApproveRecord(stockIn.getId(), ACTION_AUTO_APPROVE, null,
|
|
|
|
|
ErpAuditStatus.APPROVE.getStatus(), null, "无需审核,系统自动入库");
|
|
|
|
|
}
|
|
|
|
|
return stockIn.getId();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public void updateStockIn(ErpStockInSaveReqVO updateReqVO) {
|
|
|
|
|
// 1.1 校验存在
|
|
|
|
|
ErpStockInDO stockIn = validateStockInExists(updateReqVO.getId());
|
|
|
|
|
if (ErpAuditStatus.APPROVE.getStatus().equals(stockIn.getStatus())) {
|
|
|
|
|
throw exception(STOCK_IN_UPDATE_FAIL_APPROVE, stockIn.getNo());
|
|
|
|
|
}
|
|
|
|
|
// 1.2 校验供应商
|
|
|
|
|
//supplierService.validateSupplier(updateReqVO.getSupplierId());
|
|
|
|
|
// 1.3 校验入库项的有效性
|
|
|
|
|
List<ErpStockInItemDO> stockInItems = validateStockInItems(updateReqVO.getItems(),updateReqVO.getInType());
|
|
|
|
|
|
|
|
|
|
// 2.1 更新入库单
|
|
|
|
|
if (ErpAuditStatus.PROCESS.getStatus().equals(stockIn.getStatus())) {
|
|
|
|
|
throw exception(STOCK_IN_UPDATE_FAIL_PROCESS, stockIn.getNo());
|
|
|
|
|
}
|
|
|
|
|
if (updateReqVO.getStockUserId() != null) {
|
|
|
|
|
adminUserApi.validateUser(updateReqVO.getStockUserId());
|
|
|
|
|
}
|
|
|
|
|
if (updateReqVO.getAuditUserId() != null) {
|
|
|
|
|
adminUserApi.validateUser(updateReqVO.getAuditUserId());
|
|
|
|
|
}
|
|
|
|
|
List<ErpStockInItemDO> stockInItems = validateStockInItems(updateReqVO.getItems(), updateReqVO.getInType());
|
|
|
|
|
boolean needAudit = !Boolean.FALSE.equals(updateReqVO.getNeedAudit());
|
|
|
|
|
ErpStockInDO updateObj = BeanUtils.toBean(updateReqVO, ErpStockInDO.class, in -> in
|
|
|
|
|
.setNeedAudit(needAudit)
|
|
|
|
|
.setTotalCount(getSumValue(stockInItems, ErpStockInItemDO::getCount, BigDecimal::add))
|
|
|
|
|
.setTotalPrice(getSumValue(stockInItems, ErpStockInItemDO::getTotalPrice, BigDecimal::add)));
|
|
|
|
|
.setTotalPrice(getSumValue(stockInItems, ErpStockInItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)));
|
|
|
|
|
stockInMapper.updateById(updateObj);
|
|
|
|
|
// 2.2 更新入库单项
|
|
|
|
|
updateStockInItemList(updateReqVO.getId(), stockInItems);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public void updateStockInStatus(Long id, Integer status,Integer bizType) {
|
|
|
|
|
boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status);
|
|
|
|
|
public void updateStockInStatus(Long id, Integer status, Integer bizType) {
|
|
|
|
|
ErpStockInDO stockIn = validateStockInExists(id);
|
|
|
|
|
if (stockIn.getStatus().equals(status)) {
|
|
|
|
|
boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status);
|
|
|
|
|
if (approve) {
|
|
|
|
|
if (!ErpAuditStatus.PROCESS.getStatus().equals(stockIn.getStatus())) {
|
|
|
|
|
throw exception(STOCK_IN_APPROVE_FAIL);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (!ErpAuditStatus.APPROVE.getStatus().equals(stockIn.getStatus())) {
|
|
|
|
|
throw exception(STOCK_IN_PROCESS_FAIL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
int updateCount = stockInMapper.updateByIdAndStatus(id, stockIn.getStatus(), new ErpStockInDO().setStatus(status));
|
|
|
|
|
if (updateCount == 0) {
|
|
|
|
|
throw exception(approve ? STOCK_IN_APPROVE_FAIL : STOCK_IN_PROCESS_FAIL);
|
|
|
|
|
}
|
|
|
|
|
List<ErpStockInItemDO> stockInItems = stockInItemMapper.selectListByInId(id);
|
|
|
|
|
if (approve) {
|
|
|
|
|
applyStockInEffect(stockIn, stockInItems, bizType);
|
|
|
|
|
} else {
|
|
|
|
|
cancelStockInEffect(stockIn, stockInItems, bizType);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int updateCount = stockInMapper.updateByIdAndStatus(id, stockIn.getStatus(),
|
|
|
|
|
new ErpStockInDO().setStatus(status));
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public void submitStockInAudit(ErpStockInSubmitReqVO submitReqVO) {
|
|
|
|
|
ErpStockInDO stockIn = validateStockInExists(submitReqVO.getId());
|
|
|
|
|
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
|
|
|
|
|
if (!Objects.equals(NumberUtils.parseLong(stockIn.getCreator()), loginUserId)) {
|
|
|
|
|
throw exception(STOCK_IN_SUBMIT_FAIL_USER);
|
|
|
|
|
}
|
|
|
|
|
if (!ErpAuditStatus.DRAFT.getStatus().equals(stockIn.getStatus())
|
|
|
|
|
&& !ErpAuditStatus.UN_APPROVE.getStatus().equals(stockIn.getStatus())) {
|
|
|
|
|
throw exception(STOCK_IN_SUBMIT_FAIL_STATUS);
|
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
.setStatus(ErpAuditStatus.PROCESS.getStatus());
|
|
|
|
|
int updateCount = stockInMapper.updateByIdAndStatus(stockIn.getId(), fromStatus, updateObj);
|
|
|
|
|
if (updateCount == 0) {
|
|
|
|
|
throw exception(approve ? STOCK_IN_APPROVE_FAIL : STOCK_IN_PROCESS_FAIL);
|
|
|
|
|
throw exception(STOCK_IN_SUBMIT_FAIL_STATUS);
|
|
|
|
|
}
|
|
|
|
|
createApproveRecord(stockIn.getId(), ACTION_SUBMIT, fromStatus,
|
|
|
|
|
ErpAuditStatus.PROCESS.getStatus(), auditUserId, submitReqVO.getRemark());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public void auditStockIn(ErpStockInAuditReqVO auditReqVO) {
|
|
|
|
|
ErpStockInDO stockIn = validateStockInExists(auditReqVO.getId());
|
|
|
|
|
if (!ErpAuditStatus.PROCESS.getStatus().equals(stockIn.getStatus())) {
|
|
|
|
|
throw exception(STOCK_IN_AUDIT_FAIL_STATUS);
|
|
|
|
|
}
|
|
|
|
|
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
|
|
|
|
|
if (!Objects.equals(stockIn.getAuditUserId(), loginUserId)) {
|
|
|
|
|
throw exception(STOCK_IN_AUDIT_FAIL_USER);
|
|
|
|
|
}
|
|
|
|
|
if (!ErpAuditStatus.APPROVE.getStatus().equals(auditReqVO.getStatus())
|
|
|
|
|
&& !ErpAuditStatus.UN_APPROVE.getStatus().equals(auditReqVO.getStatus())) {
|
|
|
|
|
throw exception(STOCK_IN_AUDIT_FAIL_RESULT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<ErpStockInItemDO> stockInItems = stockInItemMapper.selectListByInId(id);
|
|
|
|
|
Integer fromStatus = stockIn.getStatus();
|
|
|
|
|
int updateCount = stockInMapper.updateByIdAndStatus(stockIn.getId(), fromStatus,
|
|
|
|
|
new ErpStockInDO().setStatus(auditReqVO.getStatus()));
|
|
|
|
|
if (updateCount == 0) {
|
|
|
|
|
throw exception(STOCK_IN_AUDIT_FAIL_STATUS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<ErpStockInItemDO> stockInItems = stockInItemMapper.selectListByInId(stockIn.getId());
|
|
|
|
|
if (ErpAuditStatus.APPROVE.getStatus().equals(auditReqVO.getStatus())) {
|
|
|
|
|
applyStockInEffect(stockIn, stockInItems, null);
|
|
|
|
|
}
|
|
|
|
|
Long targetUserId = NumberUtils.parseLong(stockIn.getCreator());
|
|
|
|
|
createApproveRecord(stockIn.getId(), ErpAuditStatus.APPROVE.getStatus().equals(auditReqVO.getStatus())
|
|
|
|
|
? ACTION_APPROVE : ACTION_REJECT,
|
|
|
|
|
fromStatus, auditReqVO.getStatus(), targetUserId, auditReqVO.getRemark());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public void deleteStockIn(List<Long> ids) {
|
|
|
|
|
List<ErpStockInDO> stockIns = stockInMapper.selectBatchIds(ids);
|
|
|
|
|
if (CollUtil.isEmpty(stockIns)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
stockIns.forEach(stockIn -> {
|
|
|
|
|
if (ErpAuditStatus.APPROVE.getStatus().equals(stockIn.getStatus())) {
|
|
|
|
|
throw exception(STOCK_IN_DELETE_FAIL_APPROVE, stockIn.getNo());
|
|
|
|
|
}
|
|
|
|
|
if (ErpAuditStatus.PROCESS.getStatus().equals(stockIn.getStatus())) {
|
|
|
|
|
throw exception(STOCK_IN_DELETE_FAIL_PROCESS, stockIn.getNo());
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
stockIns.forEach(stockIn -> {
|
|
|
|
|
stockInMapper.deleteById(stockIn.getId());
|
|
|
|
|
stockInItemMapper.deleteByInId(stockIn.getId());
|
|
|
|
|
stockInApproveRecordMapper.deleteByStockInId(stockIn.getId());
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ErpStockInDO validateStockInExists(Long id) {
|
|
|
|
|
ErpStockInDO stockIn = stockInMapper.selectById(id);
|
|
|
|
|
if (stockIn == null) {
|
|
|
|
|
throw exception(STOCK_IN_NOT_EXISTS);
|
|
|
|
|
}
|
|
|
|
|
return stockIn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public ErpStockInDO getStockIn(Long id) {
|
|
|
|
|
return stockInMapper.selectById(id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public PageResult<ErpStockInDO> getStockInPage(ErpStockInPageReqVO pageReqVO) {
|
|
|
|
|
return stockInMapper.selectPage(pageReqVO);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<ErpStockInItemDO> getStockInItemListByInId(Long inId) {
|
|
|
|
|
return stockInItemMapper.selectListByInId(inId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<ErpStockInItemDO> getStockInItemListByInIds(Collection<Long> inIds) {
|
|
|
|
|
if (CollUtil.isEmpty(inIds)) {
|
|
|
|
|
return Collections.emptyList();
|
|
|
|
|
}
|
|
|
|
|
return stockInItemMapper.selectListByInIds(inIds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<ErpStockInApproveRecordDO> getStockInApproveRecordList(Long stockInId) {
|
|
|
|
|
return stockInApproveRecordMapper.selectListByStockInId(stockInId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void updateMoldStatus(Long id, Integer status) {
|
|
|
|
|
ErpStockInDO stockIn = validateStockInExists(id);
|
|
|
|
|
stockIn.setStatus(status);
|
|
|
|
|
stockInMapper.updateById(stockIn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void applyStockInEffect(ErpStockInDO stockIn, List<ErpStockInItemDO> stockInItems, Integer bizType) {
|
|
|
|
|
operateStockInEffect(stockIn, stockInItems, true, bizType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void cancelStockInEffect(ErpStockInDO stockIn, List<ErpStockInItemDO> stockInItems, Integer bizType) {
|
|
|
|
|
operateStockInEffect(stockIn, stockInItems, false, bizType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void operateStockInEffect(ErpStockInDO stockIn, List<ErpStockInItemDO> stockInItems,
|
|
|
|
|
boolean approve, Integer bizType) {
|
|
|
|
|
stockInItems.forEach(stockInItem -> {
|
|
|
|
|
BigDecimal count = approve ? stockInItem.getCount() : stockInItem.getCount().negate();
|
|
|
|
|
if (Objects.equals(stockIn.getInType(), "模具入库")) {
|
|
|
|
|
if (Objects.equals(stockIn.getInType(), "妯″叿鍏ュ簱")) {
|
|
|
|
|
MoldBrandDO moldDO = moldBrandService.getMoldBrand(stockInItem.getMoldSetId());
|
|
|
|
|
Integer recordBizType = bizType != null ? bizType
|
|
|
|
|
: (approve ? ErpStockRecordBizTypeEnum.OTHER_IN.getType()
|
|
|
|
|
: ErpStockRecordBizTypeEnum.OTHER_IN_CANCEL.getType());
|
|
|
|
|
stockRecordService.createStockRecord(new ErpStockRecordCreateReqBO(
|
|
|
|
|
stockInItem.getProductId(), moldDO.getId(), stockInItem.getWarehouseId(), count,
|
|
|
|
|
ErpStockRecordBizTypeEnum.OTHER_IN.getType(), stockInItem.getInId(), stockInItem.getId(), stockIn.getNo(), stockIn.getInTime()));
|
|
|
|
|
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());
|
|
|
|
|
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,
|
|
|
|
|
ErpStockRecordBizTypeEnum.getTypeByName(stockIn.getInType(), status), stockInItem.getInId(), stockInItem.getId(), stockIn.getNo(), stockIn.getInTime()));
|
|
|
|
|
recordBizType, stockInItem.getInId(), stockInItem.getId(), stockIn.getNo(), stockIn.getInTime()));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Objects.equals(stockIn.getInType(), "模具入库")) {
|
|
|
|
|
for (ErpStockInItemDO item : stockInItems) {
|
|
|
|
|
if (item.getMoldSetId() != null) {
|
|
|
|
|
MoldBrandDO moldDO = moldBrandService.getMoldBrand(item.getMoldSetId());
|
|
|
|
|
if (Objects.equals(moldDO.getStatus(), 1)) {
|
|
|
|
|
throw exception(STOCK_ALERADY_IN, moldDO.getCode() + "-" + moldDO.getName());
|
|
|
|
|
}
|
|
|
|
|
moldDO.setStatus(1);
|
|
|
|
|
moldBrandService.updateMoldBrand(BeanUtils.toBean(moldDO, MoldBrandSaveReqVO.class));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private boolean itemNeedUpdateMoldStatus(MoldBrandDO moldDO) {
|
|
|
|
|
if (Objects.equals(moldDO.getStatus(), MoldBrandStatusEnum.STANDBY.getStatus())) {
|
|
|
|
|
throw exception(STOCK_ALERADY_IN, moldDO.getCode() + "-" + moldDO.getName());
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void createApproveRecord(Long stockInId, String actionType, Integer fromStatus,
|
|
|
|
|
Integer toStatus, Long targetUserId, String remark) {
|
|
|
|
|
stockInApproveRecordMapper.insert(ErpStockInApproveRecordDO.builder()
|
|
|
|
|
.stockInId(stockInId)
|
|
|
|
|
.actionType(actionType)
|
|
|
|
|
.fromStatus(fromStatus)
|
|
|
|
|
.toStatus(toStatus)
|
|
|
|
|
.targetUserId(targetUserId)
|
|
|
|
|
.remark(remark)
|
|
|
|
|
.build());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<ErpStockInItemDO> validateStockInItems(List<ErpStockInSaveReqVO.Item> list,String outType) {
|
|
|
|
|
private List<ErpStockInItemDO> validateStockInItems(List<ErpStockInSaveReqVO.Item> list, String inType) {
|
|
|
|
|
validateWarehouseAreas(list);
|
|
|
|
|
if (Objects.equals(outType, "模具入库")) {
|
|
|
|
|
List<MoldBrandDO> moldList = moldBrandService.validMoldList(
|
|
|
|
|
convertSet(list, ErpStockInSaveReqVO.Item::getMoldSetId));
|
|
|
|
|
if (Objects.equals(inType, "妯″叿鍏ュ簱")) {
|
|
|
|
|
List<MoldBrandDO> moldList = moldBrandService.validMoldList(convertSet(list, ErpStockInSaveReqVO.Item::getMoldSetId));
|
|
|
|
|
Map<Long, MoldBrandDO> moldMap = convertMap(moldList, MoldBrandDO::getId);
|
|
|
|
|
Map<Long, ErpWarehouseDO> warehouseMap = convertMap(
|
|
|
|
|
warehouseService.getWarehouseList(convertSet(list, ErpStockInSaveReqVO.Item::getWarehouseId)),
|
|
|
|
|
ErpWarehouseDO::getId);
|
|
|
|
|
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(
|
|
|
|
|
convertSet(list, ErpStockInSaveReqVO.Item::getAreaId));
|
|
|
|
|
return convertList(list, o -> {
|
|
|
|
|
MoldBrandDO moldBrand = moldMap.get(o.getMoldSetId());
|
|
|
|
|
return convertList(list, item -> {
|
|
|
|
|
MoldBrandDO moldBrand = moldMap.get(item.getMoldSetId());
|
|
|
|
|
return ErpStockInItemDO.builder()
|
|
|
|
|
.id(null)
|
|
|
|
|
.id(item.getId())
|
|
|
|
|
.moldSetId(moldBrand.getId())
|
|
|
|
|
.moldSetName(moldBrand.getName())
|
|
|
|
|
.warehouseId(o.getWarehouseId())
|
|
|
|
|
.warehouseName(warehouseMap.containsKey(o.getWarehouseId()) ? warehouseMap.get(o.getWarehouseId()).getName() : null)
|
|
|
|
|
.areaId(o.getAreaId())
|
|
|
|
|
.areaName(areaMap.containsKey(o.getAreaId()) ? areaMap.get(o.getAreaId()).getAreaName() : null)
|
|
|
|
|
.warehouseId(item.getWarehouseId())
|
|
|
|
|
.warehouseName(warehouseMap.containsKey(item.getWarehouseId()) ? warehouseMap.get(item.getWarehouseId()).getName() : null)
|
|
|
|
|
.areaId(item.getAreaId())
|
|
|
|
|
.areaName(areaMap.containsKey(item.getAreaId()) ? areaMap.get(item.getAreaId()).getAreaName() : null)
|
|
|
|
|
.productId(moldBrand.getId())
|
|
|
|
|
.productUnitId(null)
|
|
|
|
|
.productPrice(o.getProductPrice())
|
|
|
|
|
.count(o.getCount())
|
|
|
|
|
.totalPrice(MoneyUtils.priceMultiply(o.getProductPrice(), o.getCount()))
|
|
|
|
|
.remark(o.getRemark())
|
|
|
|
|
.deviceId(o.getDeviceId())
|
|
|
|
|
.productPrice(item.getProductPrice())
|
|
|
|
|
.count(item.getCount())
|
|
|
|
|
.packagingSchemeId(item.getPackagingSchemeId())
|
|
|
|
|
.inputUnitType(item.getInputUnitType())
|
|
|
|
|
.inputCount(item.getInputCount())
|
|
|
|
|
.totalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount()))
|
|
|
|
|
.remark(item.getRemark())
|
|
|
|
|
.deviceId(item.getDeviceId())
|
|
|
|
|
.build();
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
List<ErpProductDO> productList = productService.validProductList(
|
|
|
|
|
convertSet(list, ErpStockInSaveReqVO.Item::getProductId));
|
|
|
|
|
Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);
|
|
|
|
|
Map<Long, ErpWarehouseDO> warehouseMap = convertMap(
|
|
|
|
|
warehouseService.getWarehouseList(convertSet(list, ErpStockInSaveReqVO.Item::getWarehouseId)),
|
|
|
|
|
ErpWarehouseDO::getId);
|
|
|
|
|
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(
|
|
|
|
|
convertSet(list, ErpStockInSaveReqVO.Item::getAreaId));
|
|
|
|
|
return convertList(list, o -> BeanUtils.toBean(o, ErpStockInItemDO.class, item -> item
|
|
|
|
|
.setWarehouseName(warehouseMap.containsKey(item.getWarehouseId()) ? warehouseMap.get(item.getWarehouseId()).getName() : null)
|
|
|
|
|
.setAreaName(areaMap.containsKey(item.getAreaId()) ? areaMap.get(item.getAreaId()).getAreaName() : null)
|
|
|
|
|
.setProductUnitId(productMap.get(item.getProductId()).getUnitId())
|
|
|
|
|
.setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount()))));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<ErpProductDO> productList = productService.validProductList(convertSet(list, ErpStockInSaveReqVO.Item::getProductId));
|
|
|
|
|
Map<Long, ErpProductDO> productMap = convertMap(productList, ErpProductDO::getId);
|
|
|
|
|
Map<Long, ErpWarehouseDO> warehouseMap = convertMap(
|
|
|
|
|
warehouseService.getWarehouseList(convertSet(list, ErpStockInSaveReqVO.Item::getWarehouseId)),
|
|
|
|
|
ErpWarehouseDO::getId);
|
|
|
|
|
Map<Long, WarehouseAreaDO> areaMap = warehouseAreaService.getWarehouseAreaMap(
|
|
|
|
|
convertSet(list, ErpStockInSaveReqVO.Item::getAreaId));
|
|
|
|
|
return convertList(list, item -> BeanUtils.toBean(item, ErpStockInItemDO.class, target -> target
|
|
|
|
|
.setWarehouseName(warehouseMap.containsKey(target.getWarehouseId()) ? warehouseMap.get(target.getWarehouseId()).getName() : null)
|
|
|
|
|
.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<ErpStockInSaveReqVO.Item> list) {
|
|
|
|
|
@ -246,9 +443,9 @@ public class ErpStockInServiceImpl implements ErpStockInService {
|
|
|
|
|
&& newList.stream().anyMatch(item -> item.getMoldSetId() != null);
|
|
|
|
|
if (moldStockIn) {
|
|
|
|
|
stockInItemMapper.deleteByInId(id);
|
|
|
|
|
newList.forEach(o -> {
|
|
|
|
|
o.setId(null);
|
|
|
|
|
o.setInId(id);
|
|
|
|
|
newList.forEach(item -> {
|
|
|
|
|
item.setId(null);
|
|
|
|
|
item.setInId(id);
|
|
|
|
|
});
|
|
|
|
|
stockInItemMapper.insertBatch(newList);
|
|
|
|
|
return;
|
|
|
|
|
@ -256,9 +453,9 @@ public class ErpStockInServiceImpl implements ErpStockInService {
|
|
|
|
|
|
|
|
|
|
List<ErpStockInItemDO> oldList = stockInItemMapper.selectListByInId(id);
|
|
|
|
|
List<List<ErpStockInItemDO>> diffList = diffList(oldList, newList,
|
|
|
|
|
(oldVal, newVal) -> oldVal.getId().equals(newVal.getId()));
|
|
|
|
|
(oldVal, newVal) -> Objects.equals(oldVal.getId(), newVal.getId()));
|
|
|
|
|
if (CollUtil.isNotEmpty(diffList.get(0))) {
|
|
|
|
|
diffList.get(0).forEach(o -> o.setInId(id));
|
|
|
|
|
diffList.get(0).forEach(item -> item.setInId(id));
|
|
|
|
|
stockInItemMapper.insertBatch(diffList.get(0));
|
|
|
|
|
}
|
|
|
|
|
if (CollUtil.isNotEmpty(diffList.get(1))) {
|
|
|
|
|
@ -268,68 +465,5 @@ public class ErpStockInServiceImpl implements ErpStockInService {
|
|
|
|
|
stockInItemMapper.deleteBatchIds(convertList(diffList.get(2), ErpStockInItemDO::getId));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public void deleteStockIn(List<Long> ids) {
|
|
|
|
|
// 1. 校验不处于已审批
|
|
|
|
|
List<ErpStockInDO> stockIns = stockInMapper.selectBatchIds(ids);
|
|
|
|
|
if (CollUtil.isEmpty(stockIns)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
stockIns.forEach(stockIn -> {
|
|
|
|
|
if (ErpAuditStatus.APPROVE.getStatus().equals(stockIn.getStatus())) {
|
|
|
|
|
throw exception(STOCK_IN_DELETE_FAIL_APPROVE, stockIn.getNo());
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 2. 遍历删除,并记录操作日志
|
|
|
|
|
stockIns.forEach(stockIn -> {
|
|
|
|
|
// 2.1 删除入库单
|
|
|
|
|
stockInMapper.deleteById(stockIn.getId());
|
|
|
|
|
// 2.2 删除入库单项
|
|
|
|
|
stockInItemMapper.deleteByInId(stockIn.getId());
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ErpStockInDO validateStockInExists(Long id) {
|
|
|
|
|
ErpStockInDO stockIn = stockInMapper.selectById(id);
|
|
|
|
|
if (stockIn == null) {
|
|
|
|
|
throw exception(STOCK_IN_NOT_EXISTS);
|
|
|
|
|
}
|
|
|
|
|
return stockIn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public ErpStockInDO getStockIn(Long id) {
|
|
|
|
|
return stockInMapper.selectById(id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public PageResult<ErpStockInDO> getStockInPage(ErpStockInPageReqVO pageReqVO) {
|
|
|
|
|
return stockInMapper.selectPage(pageReqVO);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ==================== 入库项 ====================
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<ErpStockInItemDO> getStockInItemListByInId(Long inId) {
|
|
|
|
|
return stockInItemMapper.selectListByInId(inId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<ErpStockInItemDO> getStockInItemListByInIds(Collection<Long> inIds) {
|
|
|
|
|
if (CollUtil.isEmpty(inIds)) {
|
|
|
|
|
return Collections.emptyList();
|
|
|
|
|
}
|
|
|
|
|
return stockInItemMapper.selectListByInIds(inIds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void updateMoldStatus(Long id, Integer status) {
|
|
|
|
|
ErpStockInDO stockIn = validateStockInExists(id);
|
|
|
|
|
stockIn.setStatus(status);
|
|
|
|
|
stockInMapper.updateById(stockIn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|