package com.doumee.service.business.impl; import com.alibaba.druid.sql.visitor.functions.Concat; import com.doumee.core.constants.ResponseStatus; import com.doumee.core.exception.BusinessException; import com.doumee.core.model.LoginUserInfo; import com.doumee.core.model.PageData; import com.doumee.core.model.PageWrap; import com.doumee.core.utils.Constants; import com.doumee.core.utils.DateUtil; import com.doumee.core.utils.Utils; import com.doumee.core.utils.redis.RedisUtil; import com.doumee.dao.business.*; import com.doumee.dao.business.model.*; import com.doumee.dao.system.model.SystemUser; import com.doumee.service.business.YwOutinboundService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.github.yulichang.wrapper.MPJLambdaWrapper; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** * 运维出入库信息表Service实现 * @author 江蹄蹄 * @date 2025/01/06 11:05 */ @Service public class YwOutinboundServiceImpl implements YwOutinboundService { @Autowired private YwOutinboundMapper ywOutinboundMapper; @Autowired private YwMaterialMapper ywMaterialMapper; @Autowired private YwOutinboundRecordMapper ywOutinboundRecordMapper; @Autowired private YwStockMapper ywStockMapper; @Autowired private YwWarehouseMapper ywWarehouseMapper; @Autowired private YwStocktakingMapper ywStocktakingMapper; @Autowired private RedisTemplate redisTemplate; @Override @Transactional(rollbackFor = {Exception.class, BusinessException.class}) public Integer create(YwOutinbound ywOutinbound) { List recordList = this.verifyData(ywOutinbound); YwWarehouse ywWarehouse = ywWarehouseMapper.selectById(ywOutinbound.getWarehouseId()); if(Objects.isNull(ywWarehouse)){ throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"未查询到仓库信息"); } LoginUserInfo loginUserInfo = ywOutinbound.getLoginUserInfo(); //根据操作类型进行判断是入库/出库 Constants.ywOutInType ywOutInType = Constants.ywOutInType.getYwOutInType(ywOutinbound.getType()); if(Objects.isNull(ywOutInType)){ throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"未匹配到出入库类型"); } //生成出入库单据编号 ywOutinbound.setCode(getNextInOutCode(ywOutInType.getInOut())); ywOutinbound.setCreator(loginUserInfo.getId()); ywOutinbound.setCreateDate(new Date()); ywOutinbound.setOrigin(Constants.ZERO); ywOutinboundMapper.insert(ywOutinbound); for (YwOutinboundRecord ywOutinboundRecord:recordList) { ywOutinboundRecord.setOutInBoundId(ywOutinbound.getId()); ywOutinboundRecord.setCreator(loginUserInfo.getId()); ywOutinboundRecord.setCreateDate(new Date()); ywOutinboundRecord.setIsdeleted(Constants.ZERO); } ywOutinboundRecordMapper.insert(recordList); //更新库存信息 this.dealStockData(ywOutinbound,recordList,ywOutInType.getInOut()); return ywOutinbound.getId(); } public List verifyData(YwOutinbound ywOutinbound){ if(Objects.isNull(ywOutinbound) || Objects.isNull(ywOutinbound.getType()) || ((ywOutinbound.getType() >= 5 && ywOutinbound.getType() <= 9 ) && Objects.isNull(ywOutinbound.getOutUserId()) ) || Objects.isNull(ywOutinbound.getWarehouseId()) || Objects.isNull(ywOutinbound.getDoneDate()) || com.github.xiaoymin.knife4j.core.util.CollectionUtils.isEmpty(ywOutinbound.getRecordList()) ){ throw new BusinessException(ResponseStatus.BAD_REQUEST); } List recordList = ywOutinbound.getRecordList(); for (YwOutinboundRecord ywOutinboundRecord:recordList) { if(Objects.isNull(ywOutinboundRecord) ||Objects.isNull(ywOutinboundRecord.getMaterialId()) ||Objects.isNull(ywOutinboundRecord.getStock()) ||ywOutinboundRecord.getStock().compareTo(BigDecimal.ZERO)<=Constants.ZERO ){ throw new BusinessException(ResponseStatus.BAD_REQUEST); } ywOutinboundRecord.setId(null); } //判断当前是否存在进行中的盘点单 if(ywStocktakingMapper.selectCount(new QueryWrapper().lambda().eq(YwStocktaking::getIsdeleted,Constants.ZERO) .eq(YwStocktaking::getWarehouseId,ywOutinbound.getWarehouseId()) .eq(YwStocktaking::getStatus,Constants.ONE))>Constants.ZERO){ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"存在进行中的盘点单,无法进行出入库操作"); }; //判断是否存在相同数据 Set materialIds = new HashSet(recordList.stream().map(i->i.getMaterialId()).collect(Collectors.toList())); if(materialIds.size() != recordList.size()){ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"存在相同资产信息,请检查数据!"); } if(ywMaterialMapper.selectCount(new QueryWrapper().lambda().in(YwMaterial::getId,materialIds))!=recordList.size()){ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"资产信息存在异常,请检查数据!"); } return recordList; } public void dealStockData(YwOutinbound ywOutinbound,List recordList,Integer inOut){ for (YwOutinboundRecord ywOutinboundRecord:recordList) { YwStock ywStock = ywStockMapper.selectOne(new QueryWrapper().lambda().eq(YwStock::getIsdeleted,Constants.ZERO) .eq(YwStock::getWarehouseId,ywOutinbound.getWarehouseId()).eq(YwStock::getMaterialId,ywOutinboundRecord.getMaterialId())); if(Constants.equalsInteger(inOut,Constants.ZERO)){ //入库 if(Objects.isNull(ywStock)){ ywStock = new YwStock(); ywStock.setIsdeleted(Constants.ZERO); ywStock.setStock(ywOutinboundRecord.getStock()); ywStock.setWarehouseId(ywOutinbound.getWarehouseId()); ywStock.setMaterialId(ywOutinboundRecord.getMaterialId()); ywStock.setCreateDate(new Date()); ywStock.setCreator(ywOutinbound.getCreator()); ywStockMapper.insert(ywStock); }else{ ywStockMapper.update(new UpdateWrapper().lambda() .setSql(" stock = ( stock + "+ywOutinboundRecord.getStock()+") ") .set(YwStock::getEditDate, DateUtil.getCurrDateTime()) .set(YwStock::getEditor, ywOutinbound.getCreator()) .eq(YwStock::getId,ywStock.getId()) ); } }else{ YwMaterial ywMaterial = ywMaterialMapper.selectById(ywOutinboundRecord.getMaterialId()); //出库 if(Objects.isNull(ywStock) || ywStock.getStock().compareTo(ywOutinboundRecord.getStock()) < Constants.ZERO){ throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), ywMaterial.getName() + "库存不足,请刷新重试"); }/*else if(ywStock.getStock().compareTo(ywOutinboundRecord.getStock()) == Constants.ZERO){ ywStockMapper.deleteById(ywStock.getId()); }*/else{ ywStockMapper.update(new UpdateWrapper().lambda() .setSql(" stock = ( stock - "+ywOutinboundRecord.getStock()+") ") .set(YwStock::getEditDate, DateUtil.getCurrDateTime()) .set(YwStock::getEditor, ywOutinbound.getCreator()) .eq(YwStock::getId,ywStock.getId()) ); } } } } @Override public void deleteById(Integer id) { ywOutinboundMapper.deleteById(id); } @Override public void delete(YwOutinbound ywOutinbound) { UpdateWrapper deleteWrapper = new UpdateWrapper<>(ywOutinbound); ywOutinboundMapper.delete(deleteWrapper); } @Override public void deleteByIdInBatch(List ids) { if (CollectionUtils.isEmpty(ids)) { return; } ywOutinboundMapper.deleteBatchIds(ids); } @Override public void updateById(YwOutinbound ywOutinbound) { ywOutinboundMapper.updateById(ywOutinbound); } @Override public void updateByIdInBatch(List ywOutinbounds) { if (CollectionUtils.isEmpty(ywOutinbounds)) { return; } for (YwOutinbound ywOutinbound: ywOutinbounds) { this.updateById(ywOutinbound); } } @Override public YwOutinbound findById(Integer id) { return ywOutinboundMapper.selectById(id); } @Override public YwOutinbound findOne(YwOutinbound ywOutinbound) { QueryWrapper wrapper = new QueryWrapper<>(ywOutinbound); return ywOutinboundMapper.selectOne(wrapper); } @Override public List findList(YwOutinbound ywOutinbound) { QueryWrapper wrapper = new QueryWrapper<>(ywOutinbound); return ywOutinboundMapper.selectList(wrapper); } @Override public YwOutinbound getDetail(Integer id) { MPJLambdaWrapper queryWrapper = new MPJLambdaWrapper(); queryWrapper.selectAll(YwOutinbound.class) .selectAs(SystemUser::getRealname,YwOutinbound::getCreateUserName) .selectAs(YwWarehouse::getName,YwOutinbound::getWarehouseName) .leftJoin(SystemUser.class,SystemUser::getId,YwOutinbound::getCreator) .leftJoin(YwWarehouse.class,YwWarehouse::getId,YwOutinbound::getWarehouseId) .eq(YwOutinbound::getId,id) .last(" limit 1"); YwOutinbound ywOutinbound = ywOutinboundMapper.selectJoinOne(YwOutinbound.class,queryWrapper); List idList = new ArrayList<>(); idList.add(id); ywOutinbound.setRecordList(this.getRecordDetailData(idList)); return ywOutinbound; } @Override public PageData findPage(PageWrap pageWrap) { IPage page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity()); MPJLambdaWrapper queryWrapper = new MPJLambdaWrapper(); Utils.MP.blankToNull(pageWrap.getModel()); YwOutinbound model = pageWrap.getModel(); if(Objects.isNull(model)||Objects.isNull(model.getInOut())){ throw new BusinessException(ResponseStatus.BAD_REQUEST); } List typeList = Constants.ywOutInType.getAllTypeKey(model.getInOut()); queryWrapper.selectAll(YwOutinbound.class) .select(" s1.realname ",YwOutinbound::getCreateUserName) .select(" s2.realname ",YwOutinbound::getOutUserName) .selectAs(YwWarehouse::getName,YwOutinbound::getWarehouseName) .leftJoin(YwWarehouse.class,YwWarehouse::getId,YwOutinbound::getWarehouseId) .leftJoin("system_user s1 on t.creator = s1.id") .leftJoin("system_user s2 on t.out_user_id = s2.id") .like(StringUtils.isNotBlank(model.getCode()),YwOutinbound::getCode,model.getCode()) .eq(Objects.nonNull(model.getType()),YwOutinbound::getType,model.getType()) .eq(Objects.nonNull(model.getWarehouseId()),YwOutinbound::getWarehouseId,model.getWarehouseId()) .in(Objects.nonNull(model.getInOut()),YwOutinbound::getType,typeList) ; if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(pageWrap.getSorts())){ for(PageWrap.SortData sortData: pageWrap.getSorts()) { if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) { queryWrapper.orderByDesc(sortData.getProperty()); } else { queryWrapper.orderByAsc(sortData.getProperty()); } } }else{ queryWrapper.orderByDesc(YwOutinbound::getCode); } IPage iPage = ywOutinboundMapper.selectJoinPage(page,YwOutinbound.class,queryWrapper); if(Objects.nonNull(iPage.getRecords())){ iPage.setRecords(this.getDetailData(iPage.getRecords())); } return PageData.from(iPage); } public List getDetailData(List ywOutinboundList){ List idList = ywOutinboundList.stream().map(i->i.getId()).collect(Collectors.toList()); if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(idList)){ List ywOutinboundRecordList = this.getRecordDetailData(idList); if(CollectionUtils.isEmpty(ywOutinboundRecordList)){ return ywOutinboundList; } for (YwOutinbound ywOutinbound:ywOutinboundList) { ywOutinbound.setRecordList( ywOutinboundRecordList.stream().filter(i->Constants.equalsInteger(i.getOutInBoundId(),ywOutinbound.getId())).collect(Collectors.toList()) ); } } return ywOutinboundList; } public List getRecordDetailData(List outinBoundIdList){ List ywOutinboundRecordList = ywOutinboundRecordMapper.selectJoinList(YwOutinboundRecord.class, new MPJLambdaWrapper() .selectAll(YwOutinboundRecord.class) .selectAs(YwMaterial::getCode,YwOutinboundRecord::getMaterialCode) .selectAs(YwMaterial::getName,YwOutinboundRecord::getMaterialName) .selectAs(YwMaterial::getQrcode,YwOutinboundRecord::getMaterialQrcode) .selectAs(YwMaterial::getBrand,YwOutinboundRecord::getMaterialBrand) .selectAs(YwMaterial::getUnitName,YwOutinboundRecord::getMaterialUnitName) .leftJoin(YwMaterial.class,YwMaterial::getId,YwOutinboundRecord::getMaterialId) .eq(YwOutinboundRecord::getIsdeleted,Constants.ZERO) .in(YwOutinboundRecord::getOutInBoundId,outinBoundIdList) ); return ywOutinboundRecordList; } // @Override // public PageData findPage(PageWrap pageWrap) { // IPage page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity()); // // QueryWrapper queryWrapper = new QueryWrapper<>(); // Utils.MP.blankToNull(pageWrap.getModel()); // if (pageWrap.getModel().getId() != null) { // queryWrapper.lambda().eq(YwOutinbound::getId, pageWrap.getModel().getId()); // } // if (pageWrap.getModel().getCreator() != null) { // queryWrapper.lambda().eq(YwOutinbound::getCreator, pageWrap.getModel().getCreator()); // } // if (pageWrap.getModel().getCreateDate() != null) { // queryWrapper.lambda().ge(YwOutinbound::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate())); // queryWrapper.lambda().le(YwOutinbound::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate())); // } // if (pageWrap.getModel().getEditor() != null) { // queryWrapper.lambda().eq(YwOutinbound::getEditor, pageWrap.getModel().getEditor()); // } // if (pageWrap.getModel().getEditDate() != null) { // queryWrapper.lambda().ge(YwOutinbound::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate())); // queryWrapper.lambda().le(YwOutinbound::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate())); // } // if (pageWrap.getModel().getIsdeleted() != null) { // queryWrapper.lambda().eq(YwOutinbound::getIsdeleted, pageWrap.getModel().getIsdeleted()); // } // if (pageWrap.getModel().getRemark() != null) { // queryWrapper.lambda().eq(YwOutinbound::getRemark, pageWrap.getModel().getRemark()); // } // if (pageWrap.getModel().getWarehouseId() != null) { // queryWrapper.lambda().eq(YwOutinbound::getWarehouseId, pageWrap.getModel().getWarehouseId()); // } // if (pageWrap.getModel().getMaterialId() != null) { // queryWrapper.lambda().eq(YwOutinbound::getMaterialId, pageWrap.getModel().getMaterialId()); // } // if (pageWrap.getModel().getStock() != null) { // queryWrapper.lambda().eq(YwOutinbound::getStock, pageWrap.getModel().getStock()); // } // if (pageWrap.getModel().getType() != null) { // queryWrapper.lambda().eq(YwOutinbound::getType, pageWrap.getModel().getType()); // } // if (pageWrap.getModel().getOrigin() != null) { // queryWrapper.lambda().eq(YwOutinbound::getOrigin, pageWrap.getModel().getOrigin()); // } // if (pageWrap.getModel().getContent() != null) { // queryWrapper.lambda().eq(YwOutinbound::getContent, pageWrap.getModel().getContent()); // } // if (pageWrap.getModel().getDoneDate() != null) { // queryWrapper.lambda().ge(YwOutinbound::getDoneDate, Utils.Date.getStart(pageWrap.getModel().getDoneDate())); // queryWrapper.lambda().le(YwOutinbound::getDoneDate, Utils.Date.getEnd(pageWrap.getModel().getDoneDate())); // } // if (pageWrap.getModel().getStatus() != null) { // queryWrapper.lambda().eq(YwOutinbound::getStatus, pageWrap.getModel().getStatus()); // } // for(PageWrap.SortData sortData: pageWrap.getSorts()) { // if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) { // queryWrapper.orderByDesc(sortData.getProperty()); // } else { // queryWrapper.orderByAsc(sortData.getProperty()); // } // } // return PageData.from(ywOutinboundMapper.selectPage(page, queryWrapper)); // } @Override public long count(YwOutinbound ywOutinbound) { QueryWrapper wrapper = new QueryWrapper<>(ywOutinbound); return ywOutinboundMapper.selectCount(wrapper); } public synchronized String getNextInOutCode(Integer inOut){ String prefix = (Constants.equalsInteger(inOut,0)?"RK-":"CK-") + DateUtil.getDate(new Date(),"yyyyMMdd") +"-"; Integer countNum = RedisUtil.getObject(redisTemplate, Constants.equalsInteger(inOut,0)?Constants.RedisKeys.COM_OUTBOUND_OUT_KEY:Constants.RedisKeys.COM_OUTBOUND_IN_KEY, Integer.class); countNum = Constants.formatIntegerNum(countNum)+1; //更新缓存 RedisUtil.addObject(redisTemplate,Constants.equalsInteger(inOut,0)?Constants.RedisKeys.COM_OUTBOUND_OUT_KEY:Constants.RedisKeys.COM_OUTBOUND_IN_KEY,countNum); String nextIndex =Integer.toString( countNum ); return prefix + StringUtils.leftPad(nextIndex,4,"0"); } }