|
@@ -0,0 +1,337 @@
|
|
|
+package com.ruoyi.ams.stock.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollectionUtil;
|
|
|
+import cn.hutool.core.collection.ListUtil;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+import com.ruoyi.ams.box.domain.WmsBoxInfo;
|
|
|
+import com.ruoyi.ams.box.service.IWmsBoxInfoService;
|
|
|
+import com.ruoyi.ams.inv.domain.InvLotAtt;
|
|
|
+import com.ruoyi.ams.inv.domain.InvLotLocId;
|
|
|
+import com.ruoyi.ams.inv.service.IInvLotAttService;
|
|
|
+import com.ruoyi.ams.inv.service.IInvLotLocIdService;
|
|
|
+import com.ruoyi.ams.order.form.CheckOutInfoForm;
|
|
|
+import com.ruoyi.ams.order.service.IWmsDocOrderHeaderService;
|
|
|
+import com.ruoyi.ams.stock.domain.StockTakeRecord;
|
|
|
+import com.ruoyi.ams.stock.dto.PalletInventoryDetailDTO;
|
|
|
+import com.ruoyi.ams.stock.dto.StockTakeRecordDTO;
|
|
|
+import com.ruoyi.ams.stock.mapper.StockTakeRecordMapper;
|
|
|
+import com.ruoyi.ams.stock.service.StockTakeRecordService;
|
|
|
+import com.ruoyi.base.constant.Constant;
|
|
|
+import com.ruoyi.base.domain.BaseSku;
|
|
|
+import com.ruoyi.base.service.IBaseSkuService;
|
|
|
+import com.ruoyi.base.service.ICodeSkuRelationshipService;
|
|
|
+import com.ruoyi.common.constant.Constants;
|
|
|
+import com.ruoyi.common.utils.ConvertUtils;
|
|
|
+import com.ruoyi.common.utils.DateUtils;
|
|
|
+import com.ruoyi.common.utils.StringUtils;
|
|
|
+import com.ruoyi.framework.service.impl.CrudServiceImpl;
|
|
|
+import io.jsonwebtoken.lang.Assert;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+
|
|
|
+ * 托盘匹配记录Service业务层处理
|
|
|
+ *
|
|
|
+ * @author ruoyi
|
|
|
+ * @date 2023-08-23
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class StockTakeRecordServiceImpl extends CrudServiceImpl<StockTakeRecordMapper, StockTakeRecord, StockTakeRecordDTO> implements StockTakeRecordService {
|
|
|
+ @Autowired
|
|
|
+ private IWmsDocOrderHeaderService wmsDocOrderHeaderService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IWmsBoxInfoService wmsBoxInfoService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IInvLotLocIdService invLotLocIdService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IInvLotAttService invLotAttService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IBaseSkuService baseSkuService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ICodeSkuRelationshipService codeSkuRelationshipService;
|
|
|
+
|
|
|
+
|
|
|
+ * 盘点出库
|
|
|
+ *
|
|
|
+ * @param palletNoList
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void palletOutOfWarehouse(List<String> palletNoList) {
|
|
|
+ Assert.isTrue(CollectionUtil.isNotEmpty(palletNoList), "托盘号不能为空!");
|
|
|
+ List<WmsBoxInfo> wmsBoxInfoList = wmsBoxInfoService.queryWmsBoxInfoByPalletNoList(palletNoList);
|
|
|
+ List<CheckOutInfoForm> checkOutInfoFormList = wmsBoxInfoList.stream().filter(item ->
|
|
|
+
|
|
|
+ StringUtils.isNotBlank(item.getBoxNo()) && ObjectUtil.isNotNull(item.getLocationId()))
|
|
|
+ .map(item -> {
|
|
|
+ CheckOutInfoForm checkOutInfoForm = ConvertUtils.sourceToTarget(item, CheckOutInfoForm.class);
|
|
|
+ checkOutInfoForm.setPalletNo(item.getBoxNo());
|
|
|
+ checkOutInfoForm.setLocationNo(item.getLocationId().toString());
|
|
|
+ return checkOutInfoForm;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ Assert.isTrue(CollectionUtil.isNotEmpty(checkOutInfoFormList), "托盘信息丢失!");
|
|
|
+
|
|
|
+ checkOutInfoFormList.forEach(item -> wmsDocOrderHeaderService.doCheckout(item));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * 根据托盘号获取明细
|
|
|
+ *
|
|
|
+ * @param palletNo
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<PalletInventoryDetailDTO> getPalletInventoryDetailList(String palletNo) {
|
|
|
+ List<InvLotAtt> invLotAttList = getInventoryListByPalletNo(palletNo);
|
|
|
+ List<BaseSku> baseSkuList = baseSkuService.queryActiveSkuList(invLotAttList.stream().map(InvLotAtt::getSku).collect(Collectors.toList()));
|
|
|
+ Assert.isTrue(CollectionUtil.isNotEmpty(baseSkuList), "物料信息系统未维护!");
|
|
|
+ Map<String, List<BaseSku>> skuInfoMap = baseSkuList.stream().collect(Collectors.groupingBy(BaseSku::getSku));
|
|
|
+ List<StockTakeRecord> stockTakeRecordByPalletList = getStockTakeRecordByPalletList(palletNo);
|
|
|
+ return invLotAttList.stream().filter(item ->
|
|
|
+ stockTakeRecordByPalletList.stream().noneMatch(stockTakeRecord ->
|
|
|
+ StrUtil.equals(stockTakeRecord.getBarCode(), item.getLotatt02())))
|
|
|
+ .map(item -> {
|
|
|
+ PalletInventoryDetailDTO palletInventoryDetailDTO = new PalletInventoryDetailDTO();
|
|
|
+ palletInventoryDetailDTO.setSku(item.getSku());
|
|
|
+
|
|
|
+ BaseSku baseSku = CollectionUtil.isNotEmpty(skuInfoMap.get(item.getSku())) ?
|
|
|
+ skuInfoMap.get(item.getSku()).stream().findFirst().get() : null;
|
|
|
+ palletInventoryDetailDTO.setDesc(ObjectUtil.isNotNull(baseSku) ? baseSku.getDesc1() : null);
|
|
|
+
|
|
|
+ palletInventoryDetailDTO.setModel(ObjectUtil.isNotNull(baseSku) ? baseSku.getModel() : null);
|
|
|
+
|
|
|
+ palletInventoryDetailDTO.setBarCode(item.getLotatt02());
|
|
|
+ return palletInventoryDetailDTO;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * 盘点记录 (盘点过程中调用)
|
|
|
+ *
|
|
|
+ * @param palletNo
|
|
|
+ * @param barCode
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean stockTakePallet(String palletNo, String barCode) {
|
|
|
+ codeSkuRelationshipService.checkIsProduct(barCode);
|
|
|
+ List<StockTakeRecord> stockTakeRecordByPalletList = getStockTakeRecordByPalletList(palletNo);
|
|
|
+ String stockNo = null;
|
|
|
+ if (CollectionUtil.isNotEmpty(stockTakeRecordByPalletList)){
|
|
|
+ stockNo = stockTakeRecordByPalletList.stream().map(StockTakeRecord::getStockNo).findFirst().get();
|
|
|
+ List<StockTakeRecord> stockTakeRecordFilterByBarCodeList = stockTakeRecordByPalletList.stream().filter(item ->
|
|
|
+ StringUtils.equals(item.getBarCode(), barCode)).collect(Collectors.toList());
|
|
|
+ Assert.isTrue(CollectionUtil.isEmpty(stockTakeRecordFilterByBarCodeList), "该条码已盘点!");
|
|
|
+ }
|
|
|
+ List<InvLotAtt> palletInventoryList = getInventoryListByPalletNo(palletNo);
|
|
|
+ List<InvLotAtt> barCodeList = palletInventoryList.stream().filter(item ->
|
|
|
+ StrUtil.equals(item.getLotatt02(), barCode)).collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (CollectionUtil.isNotEmpty(barCodeList)) {
|
|
|
+ return baseDao.insert(buildStockTakeRecord(Constant.STOCK_TAKE_TYPE.NORMAL.getValue(), palletNo, barCode, stockNo)) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ List<StockTakeRecord> stockTakeRecordByBarCodeList = getStockTakeRecordByBarCodeList(ListUtil.toList(barCode), Constant.STOCK_TAKE_TYPE.LOSS.getValue());
|
|
|
+ String stockType = Constant.STOCK_TAKE_TYPE.SURPLUS.getValue();
|
|
|
+ if (CollectionUtil.isNotEmpty(stockTakeRecordByBarCodeList)) {
|
|
|
+ stockType = Constant.STOCK_TAKE_TYPE.NORMAL.getValue();
|
|
|
+ updateStockTakeRecordType(stockTakeRecordByBarCodeList.stream().findFirst().get().getId(), stockType);
|
|
|
+ } else {
|
|
|
+ operateInventory(barCode, palletNo);
|
|
|
+ }
|
|
|
+ return baseDao.insert(buildStockTakeRecord(stockType, palletNo, barCode, stockNo)) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * 结束盘点 将所有该托盘盘点记录状态更改为盘点完成(盘点完成调用)
|
|
|
+ *
|
|
|
+ * @param palletNo
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean finishStockTakePallet(String palletNo) {
|
|
|
+
|
|
|
+ try {
|
|
|
+
|
|
|
+
|
|
|
+ List<InvLotAtt> palleInventoryList = getInventoryListByPalletNo(palletNo);
|
|
|
+
|
|
|
+ List<StockTakeRecord> stockTakeRecordByBarCodeList = getStockTakeRecordByBarCodeList(palleInventoryList.stream()
|
|
|
+ .map(InvLotAtt::getLotatt02).collect(Collectors.toList()), Constant.STOCK_TAKE_TYPE.SURPLUS.getValue());
|
|
|
+
|
|
|
+ if (CollectionUtil.isNotEmpty(stockTakeRecordByBarCodeList)) {
|
|
|
+ stockTakeRecordByBarCodeList.forEach(item -> item.setStockType(Constant.STOCK_TAKE_TYPE.NORMAL.getValue()));
|
|
|
+
|
|
|
+ palleInventoryList = palleInventoryList.stream().filter(item ->
|
|
|
+ stockTakeRecordByBarCodeList.stream().noneMatch(stockTakeRecord ->
|
|
|
+ StrUtil.equals(item.getLotatt02(), stockTakeRecord.getBarCode()))).collect(Collectors.toList());
|
|
|
+ updateBatchById(stockTakeRecordByBarCodeList);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (CollectionUtil.isNotEmpty(palleInventoryList)) {
|
|
|
+ List<StockTakeRecord> stockTakeLossTypeList = new ArrayList<>();
|
|
|
+ List<StockTakeRecord> stockTakeRecordByPalletList = getStockTakeRecordByPalletList(palletNo);
|
|
|
+ String stockNo = CollectionUtil.isNotEmpty(stockTakeRecordByPalletList) ?
|
|
|
+ stockTakeRecordByPalletList.stream().map(StockTakeRecord::getStockNo).findFirst().get() : null;
|
|
|
+ palleInventoryList.forEach(item ->
|
|
|
+ stockTakeLossTypeList.add(buildStockTakeRecord(Constant.STOCK_TAKE_TYPE.LOSS.getValue(), palletNo, item.getLotatt02(), stockNo)));
|
|
|
+
|
|
|
+ insertBatch(stockTakeLossTypeList);
|
|
|
+ operateInventory(palleInventoryList, palletNo);
|
|
|
+ }
|
|
|
+ } catch (IllegalArgumentException e) {
|
|
|
+ }
|
|
|
+
|
|
|
+ return baseDao.update(new StockTakeRecord(), Wrappers.<StockTakeRecord>lambdaUpdate()
|
|
|
+ .set(StockTakeRecord::getStockStatus, Constant.STOCK_TAKE_STATUS.FINISHED.getValue())
|
|
|
+ .eq(StockTakeRecord::getScanPallet, palletNo)
|
|
|
+ .eq(StockTakeRecord::getDelFlag, Constants.NO)
|
|
|
+ .eq(StockTakeRecord::getStockStatus, Constant.STOCK_TAKE_STATUS.UNFINISHED.getValue())) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void operateInventory(String barCode, String palletNo) {
|
|
|
+
|
|
|
+ List<InvLotAtt> invLotAttList = getInventoryListByBarCode(barCode);
|
|
|
+ operateInventory(invLotAttList, palletNo);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * 修改库存、增加盘点批次
|
|
|
+ *
|
|
|
+ * @param lotAttList
|
|
|
+ * @param palletNo
|
|
|
+ */
|
|
|
+ private void operateInventory(List<InvLotAtt> lotAttList, String palletNo) {
|
|
|
+ List<InvLotAtt> invLotAttInsertList = new ArrayList<>();
|
|
|
+ WmsBoxInfo wmsBoxInfo = wmsBoxInfoService.selectWmsBoxInfoByBoxNo(palletNo);
|
|
|
+ lotAttList.forEach(item -> {
|
|
|
+ String lotNum = IdWorker.getIdStr();
|
|
|
+ invLotAttInsertList.add(buildInvLotAtt(lotNum, palletNo, item));
|
|
|
+
|
|
|
+ invLotLocIdService.updateInvLotLocIdLotNum(item.getLotnum(), lotNum, wmsBoxInfo.getLocationId().toString());
|
|
|
+ });
|
|
|
+ invLotAttService.insertBatch(invLotAttInsertList);
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<InvLotAtt> getInventoryListByBarCode(String barCode) {
|
|
|
+ return getInventoryList(null, barCode);
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<InvLotAtt> getInventoryListByPalletNo(String palletNo) {
|
|
|
+ return getInventoryList(palletNo, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<InvLotAtt> getInventoryList(String palletNo, String barCode) {
|
|
|
+ Assert.isTrue(StringUtils.isNotBlank(palletNo) || StringUtils.isNotBlank(barCode), "托盘和条码不能都为空!");
|
|
|
+ List<InvLotAtt> invLotAttList = StringUtils.isNotBlank(palletNo) ? invLotAttService.queryInvLotAtt(palletNo) :
|
|
|
+ invLotAttService.queryInvLotAttByBarCodeList(barCode);
|
|
|
+ Assert.isTrue(CollectionUtil.isNotEmpty(invLotAttList), "无库存信息!");
|
|
|
+ List<InvLotLocId> invLotLocIdList = invLotLocIdService.queryInvLotLocIdByLotnum(invLotAttList.stream().map(InvLotAtt::getLotnum).collect(Collectors.toList()));
|
|
|
+ Assert.isTrue(CollectionUtil.isNotEmpty(invLotLocIdList), "无库存信息!");
|
|
|
+ return invLotAttList.stream().filter(item ->
|
|
|
+
|
|
|
+ invLotLocIdList.stream().anyMatch(invLotLocId -> StringUtils.equals(invLotLocId.getLotnum(), item.getLotnum()))).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ private StockTakeRecord buildStockTakeRecord(String stockType, String scanPallet, String barCode, String stockNo) {
|
|
|
+
|
|
|
+ boolean flag = StrUtil.equals(Constant.STOCK_TAKE_TYPE.NORMAL.getValue(), stockType);
|
|
|
+ StockTakeRecord stockTakeRecord = new StockTakeRecord();
|
|
|
+ stockTakeRecord.setDelFlag(Constants.NO);
|
|
|
+ stockTakeRecord.setStockType(stockType);
|
|
|
+
|
|
|
+ stockTakeRecord.setStockStatus(Constant.STOCK_TAKE_STATUS.UNFINISHED.getValue());
|
|
|
+
|
|
|
+ stockTakeRecord.setSourcePallet(flag || StrUtil.equals(Constant.STOCK_TAKE_TYPE.LOSS.getValue(), stockType) ?
|
|
|
+ scanPallet : Constant.VIRTUAL_PALLET);
|
|
|
+
|
|
|
+ stockTakeRecord.setStockPallet(flag || StrUtil.equals(Constant.STOCK_TAKE_TYPE.SURPLUS.getValue(), stockType) ?
|
|
|
+ scanPallet : Constant.VIRTUAL_PALLET);
|
|
|
+ stockTakeRecord.setScanPallet(scanPallet);
|
|
|
+ stockTakeRecord.setBarCode(barCode);
|
|
|
+ stockTakeRecord.setId(IdWorker.getIdStr());
|
|
|
+ stockTakeRecord.setStockNo(StringUtils.isNotBlank(stockNo) ? stockNo : Constant.PD.concat(stockTakeRecord.getId()));
|
|
|
+ return stockTakeRecord;
|
|
|
+ }
|
|
|
+
|
|
|
+ private InvLotAtt buildInvLotAtt(String lotNum, String palletNo, InvLotAtt invLotAtt) {
|
|
|
+ InvLotAtt convertInvLotAtt = ConvertUtils.sourceToTarget(invLotAtt, InvLotAtt.class);
|
|
|
+ convertInvLotAtt.setLotnum(lotNum);
|
|
|
+ convertInvLotAtt.setLotatt07(palletNo);
|
|
|
+ convertInvLotAtt.setCreateBy("stock");
|
|
|
+ convertInvLotAtt.setRemark("add inv lot att cause by stock take");
|
|
|
+ return convertInvLotAtt;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<StockTakeRecord> getStockTakeRecordByBarCodeList(List<String> barCodeList, String stockType) {
|
|
|
+ return baseDao.selectList(Wrappers.<StockTakeRecord>lambdaQuery()
|
|
|
+ .in(StockTakeRecord::getBarCode, barCodeList)
|
|
|
+ .eq(StockTakeRecord::getDelFlag, Constants.NO)
|
|
|
+ .eq(StockTakeRecord::getStockType, stockType));
|
|
|
+ }
|
|
|
+
|
|
|
+ private void updateStockTakeRecordType(String id, String stockType) {
|
|
|
+ baseDao.update(new StockTakeRecord(), Wrappers.<StockTakeRecord>lambdaUpdate()
|
|
|
+ .set(StockTakeRecord::getStockType, stockType)
|
|
|
+ .eq(StockTakeRecord::getId, id));
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<StockTakeRecord> getStockTakeRecordByPalletList(String palletNo) {
|
|
|
+ return getStockTakeRecordByPalletList(palletNo, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<StockTakeRecord> getStockTakeRecordByPalletList(String palletNo, String barCode) {
|
|
|
+ return baseDao.selectList(Wrappers.<StockTakeRecord>lambdaQuery()
|
|
|
+ .eq(StockTakeRecord::getScanPallet, palletNo)
|
|
|
+ .eq(StringUtils.isNotBlank(barCode), StockTakeRecord::getBarCode, barCode)
|
|
|
+ .eq(StockTakeRecord::getDelFlag, Constants.NO)
|
|
|
+ .eq(StockTakeRecord::getStockStatus, Constant.STOCK_TAKE_STATUS.UNFINISHED.getValue()));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public QueryWrapper<StockTakeRecord> getWrapper(Map<String, Object> params) {
|
|
|
+ QueryWrapper<StockTakeRecord> queryWrapper = new QueryWrapper<>();
|
|
|
+ String stockNo = (String) params.get("stockNo");
|
|
|
+ String barCode = (String) params.get("barCode");
|
|
|
+ String scanPallet = (String) params.get("scanPallet");
|
|
|
+ String stockPallet = (String) params.get("stockPallet");
|
|
|
+ String sourcePallet = (String) params.get("sourcePallet");
|
|
|
+ String stockType = (String) params.get("stockType");
|
|
|
+
|
|
|
+ Date beginTime = StringUtils.isNotBlank((String) params.get("beginTime")) ?
|
|
|
+ DateUtil.parse((String) params.get("beginTime"), DateUtils.YYYY_MM_DD_HH_MM_SS) : DateUtils.offsetYear(DateUtils.getNowDate(), -1);
|
|
|
+
|
|
|
+ Date endTime = StringUtils.isNotBlank((String) params.get("endTime")) ?
|
|
|
+ DateUtil.parse((String) params.get("endTime"), DateUtils.YYYY_MM_DD_HH_MM_SS) : DateUtils.getNowDate();
|
|
|
+ queryWrapper.lambda()
|
|
|
+ .like(StringUtils.isNotBlank(stockNo), StockTakeRecord::getStockNo, stockNo)
|
|
|
+ .like(StringUtils.isNotBlank(barCode), StockTakeRecord::getBarCode, barCode)
|
|
|
+ .like(StringUtils.isNotBlank(scanPallet), StockTakeRecord::getScanPallet, scanPallet)
|
|
|
+ .like(StringUtils.isNotBlank(stockPallet), StockTakeRecord::getStockPallet, stockPallet)
|
|
|
+ .like(StringUtils.isNotBlank(sourcePallet), StockTakeRecord::getSourcePallet, sourcePallet)
|
|
|
+ .eq(StringUtils.isNotBlank(stockType), StockTakeRecord::getStockType, stockType)
|
|
|
+ .between(StockTakeRecord::getCreateTime, beginTime, endTime);
|
|
|
+ return queryWrapper;
|
|
|
+ }
|
|
|
+}
|