|
|
|
|
@ -0,0 +1,236 @@
|
|
|
|
|
package cn.iocoder.yudao.module.erp.service.bitwms;
|
|
|
|
|
|
|
|
|
|
import cn.iocoder.yudao.module.common.enums.QrcodeBizTypeEnum;
|
|
|
|
|
import cn.iocoder.yudao.module.common.service.qrcordrecord.QrcodeRecordService;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.bitwms.vo.BitWmsInboundReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.bitwms.vo.BitWmsLabelRespVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.bitwms.vo.BitWmsMoveReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.bitwms.vo.BitWmsOutboundReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.bitwms.vo.BitWmsScanRespVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.in.ErpStockInSaveReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.move.ErpStockMoveSaveReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSaveReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.stock.vo.out.ErpStockOutSaveReqVOItem;
|
|
|
|
|
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.warehouselocation.WarehouseLocationDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.mysql.warehouselocation.WarehouseLocationMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.service.stock.ErpStockInService;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.service.stock.ErpStockMoveService;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.service.stock.ErpStockOutService;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.service.stock.ErpStockService;
|
|
|
|
|
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.time.LocalDateTime;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.LinkedHashMap;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.PRODUCT_CODE_NOT_EXISTS;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.PRODUCT_NOT_EXISTS;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.STOCK_COUNT_NEGATIVE2;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.WAREHOUSE_LOCATION_NOT_EXISTS;
|
|
|
|
|
|
|
|
|
|
@Service
|
|
|
|
|
@Validated
|
|
|
|
|
public class BitWmsServiceImpl implements BitWmsService {
|
|
|
|
|
|
|
|
|
|
private static final String BIT_BIZ_UNIT = "BIT";
|
|
|
|
|
private static final String SAMPLE_TYPE = "SAMPLE";
|
|
|
|
|
private static final String LOCATION_TYPE = "LOCATION";
|
|
|
|
|
private static final String SAMPLE_IN_TYPE = "样品入库";
|
|
|
|
|
private static final String SAMPLE_OUT_TYPE = "样品出库";
|
|
|
|
|
private static final String SAMPLE_MOVE_TYPE = "样品移库";
|
|
|
|
|
private static final int SAMPLE_PRINT_TEMPLATE_TYPE = 6;
|
|
|
|
|
private static final int LOCATION_PRINT_TEMPLATE_TYPE = 7;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpProductService productService;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpProductMapper productMapper;
|
|
|
|
|
@Resource
|
|
|
|
|
private WarehouseLocationMapper warehouseLocationMapper;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockInService stockInService;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockOutService stockOutService;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockMoveService stockMoveService;
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpStockService stockService;
|
|
|
|
|
@Resource
|
|
|
|
|
private QrcodeRecordService qrcodeRecordService;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public Long inbound(BitWmsInboundReqVO reqVO) {
|
|
|
|
|
ErpProductRespVO product = validateBitSample(reqVO.getProductId());
|
|
|
|
|
ErpStockInSaveReqVO stockIn = new ErpStockInSaveReqVO();
|
|
|
|
|
stockIn.setSupplierId(reqVO.getSupplierId());
|
|
|
|
|
stockIn.setInTime(LocalDateTime.now());
|
|
|
|
|
stockIn.setInType(SAMPLE_IN_TYPE);
|
|
|
|
|
stockIn.setRemark(reqVO.getRemark());
|
|
|
|
|
stockIn.setWarehouseId(reqVO.getWarehouseId());
|
|
|
|
|
|
|
|
|
|
ErpStockInSaveReqVO.Item item = new ErpStockInSaveReqVO.Item();
|
|
|
|
|
item.setProductId(reqVO.getProductId());
|
|
|
|
|
item.setWarehouseId(reqVO.getWarehouseId());
|
|
|
|
|
item.setAreaId(reqVO.getAreaId());
|
|
|
|
|
item.setCount(reqVO.getCount());
|
|
|
|
|
item.setProductPrice(product.getPurchasePrice() != null ? product.getPurchasePrice() : BigDecimal.ZERO);
|
|
|
|
|
item.setRemark(reqVO.getRemark());
|
|
|
|
|
stockIn.setItems(Collections.singletonList(item));
|
|
|
|
|
return stockInService.createStockIn(stockIn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public Long outbound(BitWmsOutboundReqVO reqVO) {
|
|
|
|
|
ErpProductRespVO product = validateBitSample(reqVO.getProductId());
|
|
|
|
|
validateStockEnough(reqVO.getProductId(), reqVO.getWarehouseId(), reqVO.getAreaId(), reqVO.getCount());
|
|
|
|
|
|
|
|
|
|
ErpStockOutSaveReqVO stockOut = new ErpStockOutSaveReqVO();
|
|
|
|
|
stockOut.setOutType(SAMPLE_OUT_TYPE);
|
|
|
|
|
stockOut.setOutTime(LocalDateTime.now());
|
|
|
|
|
stockOut.setRemark(buildOutboundRemark(reqVO.getOutReason(), reqVO.getRemark()));
|
|
|
|
|
|
|
|
|
|
ErpStockOutSaveReqVOItem item = new ErpStockOutSaveReqVOItem();
|
|
|
|
|
item.setProductId(reqVO.getProductId());
|
|
|
|
|
item.setWarehouseId(reqVO.getWarehouseId());
|
|
|
|
|
item.setAreaId(reqVO.getAreaId());
|
|
|
|
|
item.setCount(reqVO.getCount());
|
|
|
|
|
item.setProductPrice(product.getPurchasePrice() != null ? product.getPurchasePrice() : BigDecimal.ZERO);
|
|
|
|
|
item.setRemark(reqVO.getRemark());
|
|
|
|
|
stockOut.setItems(Collections.singletonList(item));
|
|
|
|
|
return stockOutService.createStockOut(stockOut);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public Long move(BitWmsMoveReqVO reqVO) {
|
|
|
|
|
ErpProductRespVO product = validateBitSample(reqVO.getProductId());
|
|
|
|
|
validateStockEnough(reqVO.getProductId(), reqVO.getFromWarehouseId(), reqVO.getFromAreaId(), reqVO.getCount());
|
|
|
|
|
|
|
|
|
|
ErpStockMoveSaveReqVO stockMove = new ErpStockMoveSaveReqVO();
|
|
|
|
|
stockMove.setMoveTime(LocalDateTime.now());
|
|
|
|
|
stockMove.setRemark(reqVO.getRemark() != null ? reqVO.getRemark() : SAMPLE_MOVE_TYPE);
|
|
|
|
|
|
|
|
|
|
ErpStockMoveSaveReqVO.Item item = new ErpStockMoveSaveReqVO.Item();
|
|
|
|
|
item.setProductId(reqVO.getProductId());
|
|
|
|
|
item.setFromWarehouseId(reqVO.getFromWarehouseId());
|
|
|
|
|
item.setFromAreaId(reqVO.getFromAreaId());
|
|
|
|
|
item.setToWarehouseId(reqVO.getToWarehouseId());
|
|
|
|
|
item.setToAreaId(reqVO.getToAreaId());
|
|
|
|
|
item.setCount(reqVO.getCount());
|
|
|
|
|
item.setProductPrice(product.getPurchasePrice() != null ? product.getPurchasePrice() : BigDecimal.ZERO);
|
|
|
|
|
item.setRemark(reqVO.getRemark());
|
|
|
|
|
stockMove.setItems(Collections.singletonList(item));
|
|
|
|
|
|
|
|
|
|
Long id = stockMoveService.createStockMove(stockMove);
|
|
|
|
|
stockMoveService.updateStockMoveStatus(id, ErpAuditStatus.APPROVE.getStatus());
|
|
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public BitWmsScanRespVO scan(String code) {
|
|
|
|
|
ErpProductDO product = productMapper.selectOne(ErpProductDO::getBarCode, code);
|
|
|
|
|
if (product != null && Boolean.TRUE.equals(product.getIsSample()) && BIT_BIZ_UNIT.equals(product.getBizUnit())) {
|
|
|
|
|
BitWmsScanRespVO respVO = new BitWmsScanRespVO();
|
|
|
|
|
respVO.setType(SAMPLE_TYPE);
|
|
|
|
|
respVO.setId(product.getId());
|
|
|
|
|
respVO.setCode(product.getBarCode());
|
|
|
|
|
respVO.setName(product.getName());
|
|
|
|
|
return respVO;
|
|
|
|
|
}
|
|
|
|
|
WarehouseLocationDO location = warehouseLocationMapper.selectByNo(code);
|
|
|
|
|
if (location != null) {
|
|
|
|
|
BitWmsScanRespVO respVO = new BitWmsScanRespVO();
|
|
|
|
|
respVO.setType(LOCATION_TYPE);
|
|
|
|
|
respVO.setId(location.getId());
|
|
|
|
|
respVO.setCode(location.getCode());
|
|
|
|
|
respVO.setName(location.getName());
|
|
|
|
|
return respVO;
|
|
|
|
|
}
|
|
|
|
|
throw exception(PRODUCT_CODE_NOT_EXISTS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public BitWmsLabelRespVO getSampleLabel(Long productId) {
|
|
|
|
|
ErpProductRespVO product = validateBitSample(productId);
|
|
|
|
|
String qrcodeUrl = qrcodeRecordService.selectQrcodeUrlByIdAndCode(
|
|
|
|
|
QrcodeBizTypeEnum.PRODUCT.getCode(), product.getId(), product.getBarCode());
|
|
|
|
|
Map<String, Object> printData = new LinkedHashMap<>();
|
|
|
|
|
printData.put("id", product.getId());
|
|
|
|
|
printData.put("code", product.getBarCode());
|
|
|
|
|
printData.put("name", product.getName());
|
|
|
|
|
printData.put("customerName", product.getCustomerName());
|
|
|
|
|
printData.put("sampleCategory", product.getSampleCategory());
|
|
|
|
|
printData.put("qrcodeUrl", qrcodeUrl);
|
|
|
|
|
return buildLabel(SAMPLE_TYPE, product.getId(), product.getBarCode(), product.getName(), qrcodeUrl,
|
|
|
|
|
productMapper.selectPrintTemplate(SAMPLE_PRINT_TEMPLATE_TYPE), printData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public BitWmsLabelRespVO getLocationLabel(Long locationId) {
|
|
|
|
|
WarehouseLocationDO location = warehouseLocationMapper.selectById(locationId);
|
|
|
|
|
if (location == null) {
|
|
|
|
|
throw exception(WAREHOUSE_LOCATION_NOT_EXISTS);
|
|
|
|
|
}
|
|
|
|
|
String qrcodeUrl = qrcodeRecordService.selectQrcodeUrlByIdAndCode(
|
|
|
|
|
QrcodeBizTypeEnum.WAREHOUSE_LOCATION.getCode(), location.getId(), location.getCode());
|
|
|
|
|
Map<String, Object> printData = new LinkedHashMap<>();
|
|
|
|
|
printData.put("id", location.getId());
|
|
|
|
|
printData.put("code", location.getCode());
|
|
|
|
|
printData.put("name", location.getName());
|
|
|
|
|
printData.put("warehouseId", location.getWarehouseId());
|
|
|
|
|
printData.put("areaId", location.getAreaId());
|
|
|
|
|
printData.put("qrcodeUrl", qrcodeUrl);
|
|
|
|
|
return buildLabel(LOCATION_TYPE, location.getId(), location.getCode(), location.getName(), qrcodeUrl,
|
|
|
|
|
warehouseLocationMapper.selectPrintTemplate(LOCATION_PRINT_TEMPLATE_TYPE), printData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ErpProductRespVO validateBitSample(Long productId) {
|
|
|
|
|
ErpProductRespVO product = productService.getProduct(productId);
|
|
|
|
|
if (product == null || !Boolean.TRUE.equals(product.getIsSample()) || !BIT_BIZ_UNIT.equals(product.getBizUnit())) {
|
|
|
|
|
throw exception(PRODUCT_NOT_EXISTS);
|
|
|
|
|
}
|
|
|
|
|
return product;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void validateStockEnough(Long productId, Long warehouseId, Long areaId, BigDecimal count) {
|
|
|
|
|
ErpStockDO stock = stockService.getStock(productId, warehouseId, areaId);
|
|
|
|
|
BigDecimal currentCount = stock != null && stock.getCount() != null ? stock.getCount() : BigDecimal.ZERO;
|
|
|
|
|
if (currentCount.compareTo(count) < 0) {
|
|
|
|
|
throw exception(STOCK_COUNT_NEGATIVE2, productId, warehouseId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String buildOutboundRemark(String outReason, String remark) {
|
|
|
|
|
if (remark == null || remark.isEmpty()) {
|
|
|
|
|
return "出库原因:" + outReason;
|
|
|
|
|
}
|
|
|
|
|
return "出库原因:" + outReason + ";" + remark;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private BitWmsLabelRespVO buildLabel(String type, Long id, String code, String name, String qrcodeUrl,
|
|
|
|
|
String templateJson, Map<String, Object> printData) {
|
|
|
|
|
BitWmsLabelRespVO respVO = new BitWmsLabelRespVO();
|
|
|
|
|
respVO.setType(type);
|
|
|
|
|
respVO.setId(id);
|
|
|
|
|
respVO.setCode(code);
|
|
|
|
|
respVO.setName(name);
|
|
|
|
|
respVO.setQrcodeUrl(qrcodeUrl);
|
|
|
|
|
respVO.setTemplateJson(templateJson);
|
|
|
|
|
respVO.setPrintData(printData);
|
|
|
|
|
return respVO;
|
|
|
|
|
}
|
|
|
|
|
}
|