Files
scrq-hd/.svn/pristine/aa/aa0bebd0374776f584e44a466b557dcbded3ed94.svn-base
2025-07-03 10:34:04 +08:00

1167 lines
52 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.cmeim.stock.service;
import cn.hutool.core.date.DateUnit;
import com.cmeim.basic.api.RemoteSyDictService;
import com.cmeim.basic.api.dto.MaterialDto;
import com.cmeim.basic.api.dto.SyDictDto;
import com.cmeim.biz.po.MmMaterialBar;
import com.cmeim.biz.repository.MmMaterialBarRepository;
import com.cmeim.biz.service.InputBillService;
import com.cmeim.biz.service.api.CurrencyService;
import com.cmeim.biz.vo.QueryStockVo;
import com.cmeim.common.core.domain.R;
import com.cmeim.common.core.exception.ServiceException;
import com.cmeim.common.core.utils.BeanUtil;
import com.cmeim.common.core.utils.DateUtil;
import com.cmeim.common.core.web.domain.RespondEnum;
import com.cmeim.stock.dto.StockDto;
import com.cmeim.stock.po.MmStock;
import com.cmeim.stock.po.MmStockArea;
import com.cmeim.stock.po.MmStockBiz;
import com.cmeim.stock.po.MmStockCaution;
import com.cmeim.stock.po.MmStockSummary;
import com.cmeim.stock.repository.*;
import com.cmeim.stock.service.api.MaterialBarService;
import com.cmeim.stock.vo.DaysCautionVo;
import com.cmeim.stock.vo.MaterialInfoVo;
import com.cmeim.stock.vo.MaterialParmVo;
import com.cmeim.stock.vo.MmStockBizVo;
import com.cmeim.stock.vo.MmStockHisVo;
import com.cmeim.stock.vo.MmStockVo;
import com.cmeim.stock.vo.QtyCautionVo;
import com.cmeim.stock.vo.StockCautionVo;
import com.cmeim.stock.vo.StockSummarVo;
import com.cmeim.stock.vo.StockVo;
import com.cmeim.system.api.RemoteConfigService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@Transactional(rollbackFor = {ServiceException.class, RuntimeException.class, Exception.class})
@Service
@Slf4j
public class StockService {
@Autowired
private MmStockRepository stockRepository;
@Autowired
private MmStockAreaRepository stockAreaRepository;
@Autowired
private MmStockHisRepository stockHisRepository;
@Autowired
private MmStockBizRepository stockBizRepository;
@Autowired
private RemoteService remoteService;
@Autowired
private EntityManager entityManager;
@Autowired
private MmStockCautionRepository stockCautionRepository;
@Autowired
private RemoteSyDictService remoteSyDictService;
@Autowired
private MmMaterialBarRepository materialBarRepository;
@Autowired
private CurrencyService currencyService;
@Autowired
private MaterialBarService materialBarService;
@Autowired
private RemoteConfigService remoteConfigService;
String bn = "batchNo";
String materialName = "materialName";
String warehouseCode = "warehouseCode";
String materialBar = "materialBar";
String boxBar = "boxBar";
String billNumber = "billNumber";
String supplierName = "supplierName";
String locationCode = "locationCode";
String createdDt = "createdDt";
String materialId = "materialId";
String warehouseId = "warehouseId";
String unitOfMeasure = "unitOfMeasure";
String locationName = "locationName";
String locationId = "locationId";
/**
* 根据库存Id获取库存信息
*
* @param stockId
* @return
*/
public MmStock stockGetById(Long stockId) {
MmStock mmStock = new MmStock();
Optional<MmStock> byId = stockRepository.findById(stockId);
if (byId.isPresent()) {
mmStock = byId.get();
}
return mmStock;
}
/**
* 根据最小包装条码获取库存信息
*
* @param pkgBar
* @return
*/
public MmStock stockGetByPkgBar(String pkgBar) {
MmStock stocks = stockRepository.findByMaterialBar(pkgBar);
return stocks;
}
/**
* 根据箱条码获取库存信息
*
* @param boxBar
* @return
*/
public List<MmStock> stockGetByBoxBar(String boxBar) {
MmStock query = new MmStock();
query.setBoxBar(boxBar);
List<MmStock> stocks = stockRepository.findAll(Example.of(query));
return stocks;
}
/**
* 库存中是否存在该最小包装条码
*
* @param pkgBar
* @return
*/
public boolean existByPkgBar(String pkgBar) {
MmStock query = new MmStock();
query.setMaterialBar(pkgBar);
long cnt = stockRepository.count(Example.of(query));
return cnt > 0;
}
/**
* 库存中是否存在该箱条码
*
* @param boxBar
* @return
*/
public boolean existByBoxBar(String boxBar) {
MmStock query = new MmStock();
query.setBoxBar(boxBar);
long cnt = stockRepository.count(Example.of(query));
return cnt > 0;
}
/**
* 推荐库位
*
* @param materialId
* @return
*/
public MmStock recommend(Long materialId) {
MmStock query = new MmStock();
query.setMaterialId(materialId);
query.setDictFreeze(0);
List<MmStock> stocks = stockRepository.findAll(Example.of(query), Sort.by(Sort.Order.asc(bn)));
if (!stocks.isEmpty()) {
return stocks.get(0);
}
return null;
}
public List<QtyCautionVo> stockQtyCaution(StockCautionVo stockCautionVo, Sort sort) {
List<MmStockCaution> stockCautionList =
stockCautionRepository.findAll(buildCautionSpecification(stockCautionVo), sort);
List<QtyCautionVo> voList = new ArrayList<>();
for (MmStockCaution caution : stockCautionList) {
List<MmStock> stockList = stockRepository.findAllByMaterialIdAndWarehouseId(
caution.getMaterialId(), caution.getWarehouseId());
MaterialDto material = remoteService.FindMaterialById(caution.getMaterialId()).getData();
QtyCautionVo vo = new QtyCautionVo();
vo.setWareHouseCode(caution.getWarehouseCode());
vo.setWareHouseName(caution.getWarehouseName());
vo.setMaterialCode(material.getMaterialCode());
vo.setMaterialName(material.getMaterialName());
vo.setMaterialSpec(material.getMaterialSpec());
BigDecimal sum = new BigDecimal(0);
for (MmStock stock : stockList) {
sum = sum.add(stock.getQty());
}
vo.setQty(sum);
vo.setCautionQty(caution.getCautionQty());
vo.setMaxQty(caution.getMaxQty());
if (caution.getCautionQty() != null) {
int result = sum.compareTo(caution.getCautionQty());
if (result <= 0) {
vo.setCautionStatus(1);
}
}
if (caution.getMaxQty() != null) {
int result1 = sum.compareTo(caution.getMaxQty());
if (result1 >= 0) {
vo.setCautionStatus(2);
}
}
if (vo.getCautionStatus() == null) {
vo.setCautionStatus(0);
}
voList.add(vo);
}
return voList;
}
public List<DaysCautionVo> stockAgeCaution(StockCautionVo stockCautionVo, Sort sort) {
List<MmStockCaution> stockCautionList =
stockCautionRepository.findAll(buildCautionSpecification(stockCautionVo), sort);
List<DaysCautionVo> voList = new ArrayList<>();
for (MmStockCaution caution : stockCautionList) {
MmStockVo stockVo = new MmStockVo();
stockVo.setBoxBar(stockCautionVo.getBoxBar());
stockVo.setMaterialBar(stockCautionVo.getPkgBar());
stockVo.setLocationCodes(stockCautionVo.getLocationCodes());
stockVo.setMaterialId(caution.getMaterialId());
stockVo.setWarehouseId(caution.getWarehouseId());
List<MmStock> stockList = stockRepository.findAll(buildStockSpecification(stockVo));
for (MmStock stock : stockList) {
DaysCautionVo vo = BeanUtil.copyProperties(stock, DaysCautionVo.class);
Date stockDate = DateUtil.string2Date(stock.getCreatedDt(), DateUtil.PATTERN_yyyyMMddHHmmss);
Date nowDate = DateUtil.getCurDate();
int age = (int) ((nowDate.getTime() - stockDate.getTime()) / (1000L * 3600L * 24L));
vo.setAge(Integer.valueOf(age));
vo.setCaution_days(caution.getCautionDays());
if (caution.getCautionDays() != null && age >= caution.getCautionDays()) {
vo.setExpired(true);
}
voList.add(vo);
}
}
return voList;
}
private Specification buildCautionSpecification(StockCautionVo vo) {
Specification<MmStockCaution> specification = (root, criteriaQuery, cb) -> {
List<Predicate> predicates = Lists.newArrayList();
if (vo.getMaterialCode() != null) {
predicates.add(cb.like(root.get("materialCode").as(String.class), "%" + vo.getMaterialCode() + "%"));
}
if (vo.getMaterialName() != null) {
predicates.add(cb.like(root.get(materialName).as(String.class), "%" + vo.getMaterialName() + "%"));
}
if (vo.getWarehouseCodes() != null) {
CriteriaBuilder.In<String> in = cb.in(root.get(warehouseCode).as(String.class));
for (String code : vo.getWarehouseCodes()) {
in.value(code);
}
predicates.add(in);
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
return specification;
}
public Page findStock(MmStockVo query, PageRequest pageRequest) {
return stockRepository.findAll(buildStockSpecification(query), pageRequest);
}
public Specification buildStockSpecification(MmStockVo entity) {
Specification specification = new Specification<MmStockVo>() {
@Override
public Predicate toPredicate(Root<MmStockVo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
List<Predicate> predicates = Lists.newArrayList();
if (StringUtils.isNotBlank(entity.getMaterialBar())) {
predicates.add(cb.like(root.get(materialBar).as(String.class), "%" + entity.getMaterialBar() + "%"));
}
if (StringUtils.isNotBlank(entity.getBoxBar())) {
predicates.add(cb.like(root.get(boxBar).as(String.class), "%" + entity.getBoxBar() + "%"));
}
if (StringUtils.isNotBlank(entity.getBatchNo())) {
predicates.add(cb.like(root.get(bn).as(String.class), "%" + entity.getBatchNo() + "%"));
}
if (StringUtils.isNotBlank(entity.getMaterialCode())) {
predicates.add(cb.like(root.get("materialCode").as(String.class),
"%" + entity.getMaterialCode() + "%"));
}
if (StringUtils.isNotBlank(entity.getMaterialName())) {
predicates.add(cb.like(root.get(materialName).as(String.class),
"%" + entity.getMaterialName() + "%"));
}
if (StringUtils.isNotBlank(entity.getBillNumber())) {
predicates.add(cb.like(root.get(billNumber).as(String.class), "%" + entity.getBillNumber() + "%"));
}
if (StringUtils.isNotBlank(entity.getSupplierName())) {
predicates.add(cb.like(
root.get(supplierName).as(String.class), "%" + entity.getSupplierName() + "%"));
}
if (entity.getWarehouseCodes() != null) {
CriteriaBuilder.In<String> in = cb.in(root.get(warehouseCode).as(String.class));
for (String warehouseCode : entity.getWarehouseCodes()) {
in.value(warehouseCode);
}
predicates.add(in);
}
if (entity.getLocationCodes() != null) {
CriteriaBuilder.In<String> in = cb.in(root.get(locationCode).as(String.class));
for (String locationCode : entity.getLocationCodes()) {
in.value(locationCode);
}
predicates.add(in);
}
if (StringUtils.isNotBlank(entity.getCreatedDt())) {
predicates.add(cb.greaterThanOrEqualTo(root.get(createdDt).as(String.class),
entity.getCreatedDt()));
}
if (StringUtils.isNotBlank(entity.getCreatedDt2())) {
predicates.add(cb.lessThanOrEqualTo(root.get(createdDt).as(String.class),
entity.getCreatedDt2()));
}
if (entity.getMaterialId() != null) {
predicates.add(cb.equal(root.get(materialId).as(Long.class), entity.getMaterialId()));
}
if (entity.getWarehouseId() != null) {
predicates.add(cb.equal(root.get(warehouseId).as(Long.class), entity.getWarehouseId()));
}
if (entity.getDictFreeze() != null) {
predicates.add(cb.equal(root.get("dictFreeze").as(Integer.class), entity.getDictFreeze()));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
}
};
return specification;
}
public Specification buildSpecification2(MmStockVo query) {
Specification<MmStockSummary> specification = (root, criteriaQuery, cb) -> {
List<Predicate> predicates = Lists.newArrayList();
if (query.getMaterialCode() != null) {
predicates.add(cb.like(root.get("materialCode").as(String.class),
"%" + query.getMaterialCode() + "%"));
}
if (query.getMaterialName() != null) {
predicates.add(cb.like(root.get(materialName).as(String.class),
"%" + query.getMaterialName() + "%"));
}
if (query.getBatchNo() != null) {
predicates.add(cb.like(root.get(bn).as(String.class), "%" + query.getBatchNo() + "%"));
}
if (query.getWarehouseCode() != null) {
predicates.add(cb.like(root.get(warehouseCode).as(String.class),
"%" + query.getWarehouseCode() + "%"));
}
if (query.getWarehouseName() != null) {
predicates.add(cb.like(root.get("warehouseName").as(String.class),
"%" + query.getWarehouseName() + "%"));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
return specification;
}
public TypedQuery<StockSummarVo> findStockSummar(MmStockVo query, String[] orders) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<StockSummarVo> criteriaQuery = criteriaBuilder.createQuery(StockSummarVo.class);
Root<MmStock> root = criteriaQuery.from(MmStock.class);
List<Predicate> predicates = Lists.newArrayList();
if (StringUtils.isNotBlank(query.getMaterialBar())) {
predicates.add(criteriaBuilder.like(root.get(materialBar).as(String.class),
"%" + query.getMaterialBar() + "%"));
}
if (StringUtils.isNotBlank(query.getBoxBar())) {
predicates.add(criteriaBuilder.like(root.get(boxBar).as(String.class), "%" + query.getBoxBar() + "%"));
}
if (StringUtils.isNotBlank(query.getBatchNo())) {
predicates.add(criteriaBuilder.like(root.get(bn).as(String.class), "%" + query.getBatchNo() + "%"));
}
if (StringUtils.isNotBlank(query.getMaterialCode())) {
predicates.add(criteriaBuilder.like(root.get("materialCode").as(String.class),
"%" + query.getMaterialCode() + "%"));
}
if (StringUtils.isNotBlank(query.getMaterialName())) {
predicates.add(criteriaBuilder.like(root.get(materialName).as(String.class),
"%" + query.getMaterialName() + "%"));
}
if (StringUtils.isNotBlank(query.getBillNumber())) {
predicates.add(criteriaBuilder.like(root.get(billNumber).as(String.class),
"%" + query.getBillNumber() + "%"));
}
if (StringUtils.isNotBlank(query.getSupplierName())) {
predicates.add(criteriaBuilder.like(root.get(supplierName).as(String.class),
"%" + query.getSupplierName() + "%"));
}
if (query.getWarehouseCodes() != null) {
CriteriaBuilder.In<String> in = criteriaBuilder.in(root.get(warehouseCode).as(String.class));
for (String warehouseCode : query.getWarehouseCodes()) {
in.value(warehouseCode);
}
predicates.add(in);
}
if (query.getLocationCodes() != null) {
CriteriaBuilder.In<String> in = criteriaBuilder.in(root.get(locationCode).as(String.class));
for (String locationCode : query.getLocationCodes()) {
in.value(locationCode);
}
predicates.add(in);
}
if (StringUtils.isNotBlank(query.getCreatedDt())) {
predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get(createdDt).as(String.class),
query.getCreatedDt()));
}
if (StringUtils.isNotBlank(query.getCreatedDt2())) {
predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get(createdDt).as(String.class),
query.getCreatedDt2()));
}
criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
criteriaQuery.multiselect(root.get(materialId), root.get("materialCode"), root.get(materialName),
root.get(unitOfMeasure), root.get(warehouseId), root.get(warehouseCode), root.get(
"warehouseName"), root.get(locationId), root.get(locationCode), root.get(locationName),
criteriaBuilder.sum(root.get("qty")));
criteriaQuery.groupBy(root.get(materialId), root.get("materialCode"), root.get(materialName), root.get(
unitOfMeasure), root.get(warehouseId), root.get(warehouseCode), root.get("warehouseName"),
root.get(locationId), root.get(locationCode), root.get(locationName));
ArrayList<Order> jpaOrders = new ArrayList<>();
if (orders != null && orders.length > 0) {
for (String orderStr : orders) {
String[] order = orderStr.split(" ");
if ("asc".equals(order[1])) {
jpaOrders.add(criteriaBuilder.asc(root.get(order[0])));
} else {
jpaOrders.add(criteriaBuilder.desc(root.get(order[0])));
}
}
} else {
jpaOrders.add(criteriaBuilder.desc(root.get("id")));
}
criteriaQuery.orderBy(jpaOrders);
TypedQuery<StockSummarVo> createQuery = entityManager.createQuery(criteriaQuery);
return createQuery;
}
public Page findStockHis(MmStockHisVo query, PageRequest pageRequest) {
return stockHisRepository.findAll(buildStockHisSpecification(query), pageRequest);
}
private Specification buildStockHisSpecification(MmStockHisVo entity) {
Specification specification = (Specification<MmStockHisVo>) (root, criteriaQuery, cb) -> {
List<Predicate> predicates = Lists.newArrayList();
if (StringUtils.isNotBlank(entity.getMaterialBar())) {
predicates.add(cb.like(root.get(materialBar).as(String.class), "%" + entity.getMaterialBar() +
"%"));
}
if (StringUtils.isNotBlank(entity.getBoxBar())) {
predicates.add(cb.like(root.get(boxBar).as(String.class), "%" + entity.getBoxBar() + "%"));
}
if (StringUtils.isNotBlank(entity.getMaterialCode())) {
predicates.add(cb.like(root.get("materialCode").as(String.class),
"%" + entity.getMaterialCode() + "%"));
}
if (StringUtils.isNotBlank(entity.getMaterialName())) {
predicates.add(cb.like(root.get(materialName).as(String.class),
"%" + entity.getMaterialName() + "%"));
}
if (StringUtils.isNotBlank(entity.getBillNumber())) {
predicates.add(cb.like(root.get(billNumber).as(String.class), "%" + entity.getBillNumber() +
"%"));
}
if (StringUtils.isNotBlank(entity.getSupplierName())) {
predicates.add(cb.like(root.get(supplierName).as(String.class),
"%" + entity.getSupplierName() + "%"));
}
if (entity.getWarehouseCodes() != null) {
CriteriaBuilder.In<String> in = cb.in(root.get(warehouseCode).as(String.class));
for (String warehouseCode : entity.getWarehouseCodes()) {
in.value(warehouseCode);
}
predicates.add(in);
}
if (entity.getLocationCodes() != null) {
CriteriaBuilder.In<String> in = cb.in(root.get(locationCode).as(String.class));
for (String locationCode : entity.getLocationCodes()) {
in.value(locationCode);
}
predicates.add(in);
}
if (StringUtils.isNotBlank(entity.getCreatedDt())) {
predicates.add(cb.greaterThanOrEqualTo(root.get(createdDt).as(String.class),
entity.getCreatedDt()));
}
if (StringUtils.isNotBlank(entity.getCreatedDt2())) {
predicates.add(cb.lessThanOrEqualTo(root.get(createdDt).as(String.class),
entity.getCreatedDt2()));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
return specification;
}
public Page findStockBiz(MmStockBizVo query, PageRequest pageRequest) {
return stockBizRepository.findAll(buildStockBizSpecification(query), pageRequest);
}
private Specification buildStockBizSpecification(MmStockBizVo entity) {
Specification specification = (Specification<MmStockBizVo>) (root, criteriaQuery, cb) -> {
List<Predicate> predicates = Lists.newArrayList();
if (StringUtils.isNotBlank(entity.getMaterialBar())) {
predicates.add(cb.like(root.get(materialBar).as(String.class), "%" + entity.getMaterialBar() +
"%"));
}
if (StringUtils.isNotBlank(entity.getBoxBar())) {
predicates.add(cb.like(root.get(boxBar).as(String.class), "%" + entity.getBoxBar() + "%"));
}
if (StringUtils.isNotBlank(entity.getMaterialCode())) {
predicates.add(cb.like(root.get("materialCode").as(String.class),
"%" + entity.getMaterialCode() + "%"));
}
if (StringUtils.isNotBlank(entity.getMaterialName())) {
predicates.add(cb.like(root.get(materialName).as(String.class),
"%" + entity.getMaterialName() + "%"));
}
if (StringUtils.isNotBlank(entity.getBillNumber())) {
predicates.add(cb.like(root.get(billNumber).as(String.class), "%" + entity.getBillNumber() +
"%"));
}
if (StringUtils.isNotBlank(entity.getSupplierName())) {
predicates.add(cb.like(root.get(supplierName).as(String.class),
"%" + entity.getSupplierName() + "%"));
}
if (entity.getBiztypes() != null) {
CriteriaBuilder.In<Integer> in = cb.in(root.get("dictBiztype").as(Integer.class));
for (Integer biztype : entity.getBiztypes()) {
in.value(biztype);
}
predicates.add(in);
}
if (entity.getWarehouseCodes() != null) {
CriteriaBuilder.In<String> in = cb.in(root.get(warehouseCode).as(String.class));
for (String warehouseCode : entity.getWarehouseCodes()) {
in.value(warehouseCode);
}
predicates.add(in);
}
if (entity.getLocationCodes() != null) {
CriteriaBuilder.In<String> in = cb.in(root.get(locationCode).as(String.class));
for (String locationCode : entity.getLocationCodes()) {
in.value(locationCode);
}
predicates.add(in);
}
if (entity.getTargetWarehouseCodes() != null) {
CriteriaBuilder.In<String> in = cb.in(root.get("targetWarehouseCode").as(String.class));
for (String warehouseCode : entity.getTargetWarehouseCodes()) {
in.value(warehouseCode);
}
predicates.add(in);
}
if (entity.getTargetLocationCodes() != null) {
CriteriaBuilder.In<String> in = cb.in(root.get("targetLocationCode").as(String.class));
for (String locationCode : entity.getTargetLocationCodes()) {
in.value(locationCode);
}
predicates.add(in);
}
if (StringUtils.isNotBlank(entity.getCreatedDt())) {
predicates.add(cb.greaterThanOrEqualTo(root.get(createdDt).as(String.class),
entity.getCreatedDt()));
}
if (StringUtils.isNotBlank(entity.getCreatedDt2())) {
predicates.add(cb.lessThanOrEqualTo(root.get(createdDt).as(String.class),
entity.getCreatedDt2()));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
return specification;
}
/**
* 库存汇总
*
* @param query
* @return
*/
public List<StockDto> findStock(StockDto query) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<MmStock> criteriaQuery = criteriaBuilder.createQuery(MmStock.class);
Root<MmStock> root = criteriaQuery.from(MmStock.class);
List<Predicate> predicates = Lists.newArrayList();
if (query.getMaterialIdArr() != null) {
CriteriaBuilder.In<Long> in = criteriaBuilder.in(root.get(materialId).as(Long.class));
for (Long materialId : query.getMaterialIdArr()) {
in.value(materialId);
}
predicates.add(in);
}
if (query.getWarehouseIdArr() != null) {
CriteriaBuilder.In<Long> in = criteriaBuilder.in(root.get(warehouseId).as(Long.class));
for (Long warehouseId : query.getWarehouseIdArr()) {
in.value(warehouseId);
}
predicates.add(in);
}
if (query.getMaterialId() != null) {
predicates.add(criteriaBuilder.equal(root.get(materialId).as(Long.class), query.getMaterialId()));
}
if (query.getWarehouseId() != null) {
predicates.add(criteriaBuilder.equal(root.get(warehouseId).as(Long.class), query.getWarehouseId()));
}
criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
criteriaQuery.multiselect(root.get(materialId), criteriaBuilder.sum(root.get("qty")));
criteriaQuery.groupBy(root.get(materialId));
List<MmStock> queryList = entityManager.createQuery(criteriaQuery).getResultList();
List<StockDto> result = BeanUtil.copyProperties(queryList, StockDto.class);
return result;
}
public PageImpl<MmStock> queryMaterialByWarehouse(MmStockVo vo, PageRequest pageRequest) {
int pageSize = pageRequest.getPageSize();
int pageNumber = pageRequest.getPageNumber();
PageRequest of = PageRequest.of(pageNumber, pageSize);
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<MmStock> criteriaQuery = criteriaBuilder.createQuery(MmStock.class);
Root<MmStock> root = criteriaQuery.from(MmStock.class);
List<Predicate> predicates = Lists.newArrayList();
if (vo.getWarehouseId() != null) {
predicates.add(criteriaBuilder.equal(root.get(warehouseId).as(Long.class), vo.getWarehouseId()));
}
criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
criteriaQuery.multiselect(root.get(materialId), criteriaBuilder.sum(root.get("qty")), root.get(
"materialCode"), root.get(materialName), root.get("materialSpec"), root.get(bn), root.get(
unitOfMeasure));
criteriaQuery.groupBy(root.get(materialId));
List<MmStock> queryList = entityManager.createQuery(criteriaQuery).getResultList();
TypedQuery<MmStock> createQuery = entityManager.createQuery(criteriaQuery);
createQuery.setFirstResult(pageNumber * pageSize);
createQuery.setMaxResults(pageRequest.getPageSize());
//返回查询的分页结果createQuery.getResultList()为分页查询的结果对象counts.size()为设置分页参数之前查询的总数
return new PageImpl<MmStock>(createQuery.getResultList(), of, queryList.size());
}
public Specification buildSpecification(MmStockVo vo) {
Specification<MmStockVo> specification = (root, criteriaQuery, cb) -> {
List<Predicate> predicates = Lists.newArrayList();
if (vo.getMaterialCode() != null) {
predicates.add(cb.like(root.get("materialCode").as(String.class), "%" + vo.getMaterialCode() +
"%"));
}
if (vo.getMaterialName() != null) {
predicates.add(cb.like(root.get(materialName).as(String.class), "%" + vo.getMaterialName() +
"%"));
}
if (vo.getBatchNo() != null) {
predicates.add(cb.like(root.get(bn).as(String.class), "%" + vo.getBatchNo() + "%"));
}
if (vo.getWarehouseCode() != null) {
predicates.add(cb.like(root.get(warehouseCode).as(String.class), "%" + vo.getWarehouseCode() +
"%"));
}
if (vo.getWarehouseName() != null) {
predicates.add(cb.like(root.get("warehouseName").as(String.class), "%" + vo.getWarehouseName() +
"%"));
}
if (vo.getMaterialBar() != null) {
predicates.add(cb.like(root.get(materialBar).as(String.class), "%" + vo.getMaterialBar() + "%"));
}
if (vo.getBillNumber() != null) {
predicates.add(cb.like(root.get(billNumber).as(String.class), "%" + vo.getBillNumber() + "%"));
}
if (vo.getBillNumber() != null) {
predicates.add(cb.like(root.get(billNumber).as(String.class), "%" + vo.getBillNumber() + "%"));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
return specification;
}
public List<MaterialInfoVo> queryMaterialByCodes(MaterialParmVo vo) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<MaterialInfoVo> criteriaQuery = criteriaBuilder.createQuery(MaterialInfoVo.class);
Root<MmStock> root = criteriaQuery.from(MmStock.class);
List<Predicate> predicates = Lists.newArrayList();
if (vo.getWarehouseId() != null) {
predicates.add(criteriaBuilder.equal(root.get(warehouseId).as(Long.class), vo.getWarehouseId()));
}
if (vo.getWarehouseCode() != null) {
predicates.add(criteriaBuilder.equal(root.get(warehouseCode).as(String.class), vo.getWarehouseCode()));
}
if (vo.getCodes().size() > 0) {
CriteriaBuilder.In<String> in = criteriaBuilder.in(root.get("materialCode").as(String.class));
for (String materialCode : vo.getCodes()) {
in.value(materialCode);
}
predicates.add(in);
}
criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
criteriaQuery.multiselect(root.get(materialId), criteriaBuilder.sum(root.get("qty")), root.get(
"materialCode"), root.get(materialName),
root.get("materialSpec"), root.get(bn), root.get(locationId), root.get(locationCode),
root.get(locationName), root.get(unitOfMeasure));
criteriaQuery.groupBy(root.get(materialId));
List<MaterialInfoVo> queryList = entityManager.createQuery(criteriaQuery).getResultList();
List<MaterialInfoVo> materialInfoVoList = new ArrayList<>();
for (String code : vo.getCodes()) {
List<MaterialInfoVo> collect = queryList.stream().filter(
s -> s.getMaterialCode().equals(code)).collect(Collectors.toList());
if (collect.size() >0) {
materialInfoVoList.add(collect.get(0));
} else {
BigDecimal qtyDecimal = new BigDecimal(0);
MaterialInfoVo materialInfoVo = new MaterialInfoVo(null, qtyDecimal ,code, null,
null,null,null,null, null, null);
materialInfoVoList.add(materialInfoVo);
}
}
return materialInfoVoList;
}
private String getDictValue(List<SyDictDto> dtoList, Integer key) {
for (SyDictDto dto : dtoList) {
if (dto.getGroupKey().equals(key)) {
return dto.getGroupText();
}
}
return "";
}
public List<Object[]> initPrintData(List<MmStock> list, String[] cloumns) {
List<Object[]> datalist = new ArrayList<>();
SyDictDto dto = new SyDictDto();
dto.setGroupCode("mm_stock_status");
// 库存状态
List<SyDictDto> stockStatusList = remoteSyDictService.query(dto).getData();
new SyDictDto();
dto.setGroupCode("mm_stock_freeze");
// 库存冻结
List<SyDictDto> freezeList = remoteSyDictService.query(dto).getData();
new SyDictDto();
dto.setGroupCode("mm_stock_billtype");
// 库存类型
List<SyDictDto> billtypeList = remoteSyDictService.query(dto).getData();
int index = 1;
for (int i = 0; i < list.size(); i++) {
MmStock stock = list.get(i);
Object[] data = new Object[cloumns.length];
data[0] = index;
index++;
data[1] = stock.getMaterialBar();
data[2] = stock.getBoxBar();
data[3] = stock.getMaterialCode();
data[4] = stock.getMaterialName();
data[5] = stock.getBatchNo();
data[6] = stock.getQty();
data[7] = stock.getUnitOfMeasure();
data[8] = stock.getWarehouseCode();
data[9] = stock.getWarehouseName();
data[10] = stock.getLocationCode();
data[11] = stock.getLocationName();
data[12] = getDictValue(stockStatusList, stock.getDictStatus());
data[13] = getDictValue(billtypeList, stock.getDictBilltype());
data[14] = getDictValue(freezeList, stock.getDictFreeze());
data[15] = "1".equals(stock.getIsFil()) ? "是" : "否";
data[16] = stock.getBzyxq();
data[17] = stock.getInspectionNo();
data[18] = stock.getBillNumber();
data[19] = stock.getSupplierCode();
data[20] = stock.getSupplierName();
data[21] = stock.getCreatedBy();
data[22] = stock.getCreatedDt();
data[23] = stock.getUpdatedBy();
data[24] = stock.getUpdatedDt();
datalist.add(data);
}
return datalist;
}
public List<Object[]> initPrintData2(List<MmStockSummary> list, String[] cloumns) {
List<Object[]> datalist = new ArrayList<>();
int index = 1;
for (int i = 0; i < list.size(); i++) {
MmStockSummary stockSummary = list.get(i);
Object[] data = new Object[cloumns.length];
data[0] = index;
index++;
data[1] = stockSummary.getMaterialCode();
data[2] = stockSummary.getMaterialName();
data[3] = stockSummary.getWarehouseCode();
data[4] = stockSummary.getWarehouseName();
data[5] = stockSummary.getBatchNo();
data[6] = stockSummary.getQty();
data[7] = stockSummary.getUnitOfMeasure();
data[8] = stockSummary.getCreatedBy();
data[9] = stockSummary.getCreatedDt();
data[10] = stockSummary.getUpdatedBy();
data[11] = stockSummary.getUpdatedDt();
datalist.add(data);
}
return datalist;
}
public List<Object[]> initPrintData3(List<MmStockBiz> list, String[] cloumns) {
List<Object[]> datalist = new ArrayList<>();
SyDictDto dto = new SyDictDto();
dto.setGroupCode("mm_stock_biz_type");
// 事务类型
List<SyDictDto> stockBizTypeList = remoteSyDictService.query(dto).getData();
new SyDictDto();
dto.setGroupCode("mm_stock_biz_billtype");
// 单据类型
List<SyDictDto> stockBizBillTypeList = remoteSyDictService.query(dto).getData();
new SyDictDto();
dto.setGroupCode("mm_stock_billtype");
// 库存类型
List<SyDictDto> billtypeList = remoteSyDictService.query(dto).getData();
int index = 1;
for (int i = 0; i < list.size(); i++) {
MmStockBiz stockBiz = list.get(i);
Object[] data = new Object[cloumns.length];
data[0] = index;
index++;
data[1] = stockBiz.getMaterialBar();
data[2] = stockBiz.getBoxBar();
data[3] = stockBiz.getMaterialCode();
data[4] = stockBiz.getMaterialName();
data[5] = stockBiz.getBatchNo();
data[6] = getDictValue(stockBizTypeList, stockBiz.getDictBiztype());
data[7] = stockBiz.getBeforeQty();
data[8] = stockBiz.getAfterQty();
data[9] = stockBiz.getQty();
data[10] = stockBiz.getUnitOfMeasure();
data[11] = stockBiz.getWarehouseCode();
data[12] = stockBiz.getWarehouseName();
data[13] = stockBiz.getLocationCode();
data[14] = stockBiz.getLocationName();
data[15] = stockBiz.getTargetWarehouseCode();
data[16] = stockBiz.getTargetWarehouseName();
data[17] = stockBiz.getTargetLocationCode();
data[18] = stockBiz.getTargetLocationName();
data[19] = getDictValue(stockBizBillTypeList, stockBiz.getDictBilltype());
data[20] = stockBiz.getBillNumber();
data[21] = stockBiz.getSupplierCode();
data[22] = stockBiz.getSupplierName();
data[21] = stockBiz.getCreatedBy();
data[22] = stockBiz.getCreatedDt();
data[23] = stockBiz.getUpdatedBy();
data[24] = stockBiz.getUpdatedDt();
datalist.add(data);
}
return datalist;
}
public static String getWeekDays(Integer year,Integer week){
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Calendar cal=Calendar.getInstance();
cal.setFirstDayOfWeek(Calendar.MONDAY);
cal.set(Calendar.YEAR, year);
cal.set(Calendar.WEEK_OF_YEAR, week);
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
/* String beginDate = sdf.format(cal.getTime());*/
cal.add(Calendar.DAY_OF_WEEK, 7);
String endDate = sdf.format(cal.getTime());
return endDate;
}
/**
* 计算物料有效期时间
*/
public void earlyWarningInformationInsert() {
//查询所以库存
List<MmStock> mmStockList = stockRepository.findAll();
//获取所有的物料编码并去重
List<String> collect = mmStockList.stream().distinct().map(
MmStock::getMaterialCode).collect(Collectors.toList());
//获取所有物料信息,得到物料有效月份
R<List<MaterialDto>> byMaterialCodeList = remoteService.findByMaterialCodeList(collect);
if(byMaterialCodeList.getData() == null) {
throw new ServiceException(RespondEnum.FAILURE,"未查询物料信息");
}
List<MaterialDto> data = byMaterialCodeList.getData();
//根据批次(批次是时间生成)进行有效时间获取
for (MmStock stock :mmStockList) {
String date = null;
if (StringUtils.isEmpty(stock.getBatchNo())) {
continue;
}
if (stock.getBatchNo().length() != 8) {
if (stock.getBatchNo().length() == 6){
date = "20" + stock.getBatchNo();
}
if (stock.getBatchNo().length() == 4) {
String year = "20"+stock.getBatchNo().substring(0, 2);
String week = stock.getBatchNo().substring(2, 4);
String weekDays = getWeekDays(Integer.valueOf(year), Integer.valueOf(week));
date = weekDays.replace("-", "");
}
}
if (date == null) {
date = stock.getBatchNo();
}
List<MaterialDto> materialDtoList = data.stream().filter(
s -> s.getMaterialCode().equals(stock.getMaterialCode())).collect(Collectors.toList());
if (materialDtoList.size() > 0) {
if (materialDtoList.get(0).getMaxLife() != null) {
stock.setValidFrequency(materialDtoList.get(0).getMaxLife().intValue());
String s = addDay(date.substring(0,4)+"-"+date.substring(4,6)+"-"+date.substring(6,8),
materialDtoList.get(0).getMaxLife().intValue());
System.out.println(s);
stock.setValideDt(s);
}
}
}
}
//实现日期加一天的方法
public static String addDay(String s, int n) {
if (n == 0) { return null;}
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar cd = Calendar.getInstance();
cd.setTime(sdf.parse(s));
//cd.add(Calendar.DATE, n);//增加一天
cd.add(Calendar.MONTH, n);//增加一个月
System.out.println(cd.getTime());
return sdf.format(cd.getTime());
} catch (Exception e) {
return null;
}
}
public QueryStockVo missPickList(String code) {
log.info("库存查询传参:"+code);
QueryStockVo queryStockVo = new QueryStockVo();
List<StockVo> result = new ArrayList<>();
MmMaterialBar materialBarDto = materialBarRepository.findByMaterialBar(code);
if (materialBarDto == null) {
MmMaterialBar mmMaterialBar = materialBarService.analysisOldBar(code);
materialBarDto = BeanUtil.copyProperties(mmMaterialBar, MmMaterialBar.class);
}
MmStock stock = stockRepository.findByMaterialBar(code);
if (stock != null) {
result.add(BeanUtil.copyProperties(stock, StockVo.class));
result.get(0).setBarQty(materialBarDto.getMaterialQty());
}
if (stock == null) {
List<MmStock> bar = stockRepository.findByMaterialCodeAndBatchNoAndWarehouseTypeAndLocationCodeAndWarehouseCode(
materialBarDto.getMaterialCode(), materialBarDto.getBatchNo(), 10, materialBarDto.getLocationCode(),materialBarDto.getWarehouseCode());
StockVo stocks = null;
if (bar.size() >0) {
stock = bar.get(0);
stocks = BeanUtil.copyProperties(stock, StockVo.class);
stocks.setBarQty(materialBarDto.getMaterialQty());
stocks.setMaterialBar(code);
result.add(stocks);
}
if (stocks == null) {
stock = BeanUtil.copyProperties(materialBarDto, StockVo.class);
stocks = BeanUtil.copyProperties(materialBarDto, StockVo.class);
stocks.setBarQty(materialBarDto.getMaterialQty());
stocks.setMaterialBar(code);
result.add(stocks);
}
}
Integer saveType = null;
if (stock != null) {
saveType = currencyService.selectStockSaveType(
materialBarDto.getMaterialCode(), stock.getCustomerCode(), stock.getWarehouseCode());
if (saveType == 2) {
throw new ServiceException(RespondEnum.FAILURE,String.format(
"物料编码【%s】的存货类型属性未维护", materialBarDto.getMaterialCode()));
}
queryStockVo.setSaveType(saveType);
}
if (stock == null) {
// 视为库位
// 如果是库位,则需要根据物料编码和批次号分组查询
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<MmStock> criteriaQuery = criteriaBuilder.createQuery(MmStock.class);
Root<MmStock> root = criteriaQuery.from(MmStock.class);
List<Predicate> predicates = Lists.newArrayList();
predicates.add(criteriaBuilder.equal(root.get("locationCode").as(String.class), code));
criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
List<MmStock> resultList = entityManager.createQuery(criteriaQuery).getResultList();
result = BeanUtil.copyProperties(resultList, StockVo.class);
result.get(0).setBarQty(materialBarDto.getMaterialQty());
}
queryStockVo.setMmStockList(result);
log.info("库存查询回参:"+queryStockVo);
return queryStockVo;
}
public QueryStockVo missPickAreaList(String code) {
log.info("库存查询传参area:"+code);
// 根据条码查询bar
MmMaterialBar materialBarDto = materialBarRepository.findByMaterialBar(code);
if (materialBarDto == null) {
MmMaterialBar mmMaterialBar = materialBarService.analysisOldBar(code);
materialBarDto = BeanUtil.copyProperties(mmMaterialBar, MmMaterialBar.class);
}
// 根据条码查询mm_stock_area
MmStockArea stockArea = stockAreaRepository.findByMaterialBar(code);
List<StockVo> result = new ArrayList<>();
// 库存不为空
if (stockArea != null) {
result.add(BeanUtil.copyProperties(stockArea, StockVo.class));
result.get(0).setBarQty(materialBarDto.getMaterialQty());
}
// 库存为空
if (stockArea == null) {
List<MmStockArea> bar = stockAreaRepository.findByMaterialCodeAndBatchNoAndLocationCodeAndWarehouseCode(
materialBarDto.getMaterialCode(),
materialBarDto.getBatchNo(),
materialBarDto.getLocationCode(),
materialBarDto.getWarehouseCode());
StockVo stocks = null;
if (bar.size() >0) {
stockArea = bar.get(0);
stocks = BeanUtil.copyProperties(stockArea, StockVo.class);
stocks.setBarQty(materialBarDto.getMaterialQty());
stocks.setMaterialBar(code);
result.add(stocks);
}
if (stocks == null) {
stockArea = BeanUtil.copyProperties(materialBarDto, StockVo.class);
stocks = BeanUtil.copyProperties(materialBarDto, StockVo.class);
stocks.setBarQty(materialBarDto.getMaterialQty());
stocks.setMaterialBar(code);
result.add(stocks);
}
}
Integer saveType = null;
QueryStockVo queryStockVo = new QueryStockVo();
if (stockArea != null) {
saveType = currencyService.selectStockSaveType(
materialBarDto.getMaterialCode(), stockArea.getCustomerCode(), stockArea.getWarehouseCode());
if (saveType == 2) {
throw new ServiceException(RespondEnum.FAILURE,String.format(
"物料编码【%s】的存货类型属性未维护", materialBarDto.getMaterialCode()));
}
queryStockVo.setSaveType(saveType);
}
if (stockArea == null) {
// 视为库位
// 如果是库位,则需要根据物料编码和批次号分组查询
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<MmStockArea> criteriaQuery = criteriaBuilder.createQuery(MmStockArea.class);
Root<MmStockArea> root = criteriaQuery.from(MmStockArea.class);
List<Predicate> predicates = Lists.newArrayList();
predicates.add(criteriaBuilder.equal(root.get("locationCode").as(String.class), code));
criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
List<MmStockArea> resultList = entityManager.createQuery(criteriaQuery).getResultList();
result = BeanUtil.copyProperties(resultList, StockVo.class);
result.get(0).setBarQty(materialBarDto.getMaterialQty());
}
for (StockVo stockVo : result) {
stockVo.setLocationCode("线边仓");
}
queryStockVo.setMmStockList(result);
log.info("库存查询回参:"+queryStockVo);
return queryStockVo;
}
public void slowMoveAlert() {
// 获取呆滞参数
R<String> result = remoteConfigService.findByConfigKey("stock.slowMove.day");
if (result.getCode() != R.SUCCESS || StringUtils.isBlank(result.getMsg())) {
throw new ServiceException(RespondEnum.FAILURE, "请配置呆滞预警参数");
}
String slowMoveDay = result.getMsg();
// 获取全部库存
List<MmStock> stockList = stockRepository.findAll();
for (MmStock stock : stockList) {
// 根据StockSaveType判断如何获取mm_stock_biz
List<MmStockBiz> stockBizList = new ArrayList<>();
if (stock.getStockSaveType() != null && stock.getStockSaveType() == 10) {
// 根据物料、批次、仓库获取mm_stock_biz最新一条数据
stockBizList = stockBizRepository.findByMaterialCodeAndBatchNoAndWarehouseCodeOrderByCreatedDtDesc(
stock.getMaterialCode(), stock.getBatchNo(), stock.getWarehouseCode());
} else if (stock.getStockSaveType() != null && (stock.getStockSaveType() == 20 || stock.getStockSaveType() == 30)) {
// 根据条码获取mm_stock_biz最新一条数据
stockBizList = stockBizRepository.findByMaterialBarOrderByCreatedDtDesc(stock.getMaterialBar());
}
String stockBizDt = new String();
if (stockBizList.size() > 0) {
stockBizDt = stockBizList.get(0).getCreatedDt();
} else {
stockBizDt = stock.getCreatedDt();
}
// 根据biz最新创建时间和当前时间差是否大于预警参数
if (StringUtils.isNotBlank(stockBizDt)) {
long between = cn.hutool.core.date.DateUtil.between(
cn.hutool.core.date.DateUtil.parseDate(stockBizDt), new Date(), DateUnit.DAY);
if (between > Long.valueOf(slowMoveDay)) {
stock.setIsSlowMove(1);
} else {
stock.setIsSlowMove(0);
}
stockRepository.save(stock);
}
}
}
}