|
|
@@ -43,6 +43,9 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.ZoneId;
|
|
|
+import java.time.temporal.ChronoUnit;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
|
@@ -1105,17 +1108,137 @@ public class PsiWareHouseBasicService {
|
|
|
return wareHouseDtoIPage;
|
|
|
}
|
|
|
|
|
|
- public IPage<PsiWareHouseDto> nearExpiryList(Page<PsiWareHouseDto> page, PsiWareHouseDto dto) {
|
|
|
- IPage<PsiWareHouseDto> iPage = basicMapper.nearExpiryList(page, dto);
|
|
|
+ /**
|
|
|
+ * 根据库存的保质期和生产日期,进行临期规则筛选
|
|
|
+ * @param page
|
|
|
+ * @param dto
|
|
|
+ */
|
|
|
+ public void nearExpiryList(Page<PsiWareHouseDto> page, PsiWareHouseDto dto) {
|
|
|
+ Page<PsiWareHouseDto> queryPage = new Page<>();
|
|
|
+ queryPage.setCurrent(1);
|
|
|
+ queryPage.setSize(-1);
|
|
|
+ IPage<PsiWareHouseDto> iPage = basicMapper.nearExpiryList(queryPage, dto);
|
|
|
+ List<PsiWareHouseDto> list = new ArrayList<>();
|
|
|
+ LocalDate today = LocalDate.now(ZoneId.systemDefault());
|
|
|
iPage.getRecords().forEach(item -> {
|
|
|
-
|
|
|
+ if (!canCheckNearExpiry(item)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Integer shelfLifeValue = parseShelfLifeValue(item.getShelfLife());
|
|
|
+ if (shelfLifeValue == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ LocalDate produceDate = toLocalDate(item.getProduceDate());
|
|
|
+ LocalDate expiryDate = calculateExpiryDate(produceDate, shelfLifeValue, item.getShelfLifeUnit());
|
|
|
+ if (expiryDate == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ long totalDays = ChronoUnit.DAYS.between(produceDate, expiryDate);
|
|
|
+ long remainingDays = ChronoUnit.DAYS.between(today, expiryDate);
|
|
|
+ if (!shouldIncludeNearExpiry(totalDays, remainingDays)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ item.setExpiryDate(Date.from(expiryDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
|
|
|
+ item.setRemainingDays((int) remainingDays);
|
|
|
+ list.add(item);
|
|
|
});
|
|
|
- return iPage;
|
|
|
+ if(CollectionUtil.isNotEmpty(list)){
|
|
|
+ String warnInfo = list.stream()
|
|
|
+ .map(item -> item.getTradeName())
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.joining("、"));
|
|
|
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
|
|
|
+ String day = format.format(new Date());
|
|
|
+ String title = "管理员发起了 ["+ warnInfo +"] [物资临期提醒]";
|
|
|
+ //向多个用户发起通知
|
|
|
+ List<UserDTO> usersInfo = psiDetailedMapper.getUsersInfo();
|
|
|
+ //获取目前领用流程的taskid,根据procInsId去查taskId
|
|
|
+ String uuid = "";
|
|
|
+ if (null != usersInfo) {
|
|
|
+ for (UserDTO userDTO1 : usersInfo) {
|
|
|
+ uuid = UUID.randomUUID().toString();
|
|
|
+ //发送通知
|
|
|
+ Map<String ,String > map = new HashMap<>();
|
|
|
+ map.put("taskId",uuid);
|
|
|
+ map.put("title",title);
|
|
|
+ map.put("defId",dto.getId());
|
|
|
+ map.put("taskName","物资临期提醒");
|
|
|
+ map.put("createUser","管理员");
|
|
|
+ map.put("createTime",day);
|
|
|
+ map.put("noticeName",userDTO1.getLoginName());
|
|
|
+ map.put("noticeId",userDTO1.getId());
|
|
|
+ map.put("createById","1");
|
|
|
+ flowTaskService.add(map);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 列表查询
|
|
|
*/
|
|
|
+ private boolean canCheckNearExpiry(PsiWareHouseDto item) {
|
|
|
+ return item != null
|
|
|
+ && item.getProduceDate() != null
|
|
|
+ && StringUtils.isNotBlank(item.getShelfLife())
|
|
|
+ && StringUtils.isNotBlank(item.getShelfLifeUnit());
|
|
|
+ }
|
|
|
+
|
|
|
+ private Integer parseShelfLifeValue(String shelfLife) {
|
|
|
+ try {
|
|
|
+ BigDecimal value = new BigDecimal(shelfLife.trim()).stripTrailingZeros();
|
|
|
+ if (value.scale() > 0 || value.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return value.intValueExact();
|
|
|
+ } catch (Exception e) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private LocalDate toLocalDate(Date date) {
|
|
|
+ return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
|
|
+ }
|
|
|
+
|
|
|
+ private LocalDate calculateExpiryDate(LocalDate produceDate, Integer shelfLife, String shelfLifeUnit) {
|
|
|
+ String unit = shelfLifeUnit == null ? "" : shelfLifeUnit.trim();
|
|
|
+ if (unit.contains("年")) {
|
|
|
+ return produceDate.plusYears(shelfLife);
|
|
|
+ }
|
|
|
+ if (unit.contains("月")) {
|
|
|
+ return produceDate.plusMonths(shelfLife);
|
|
|
+ }
|
|
|
+ if (unit.contains("天") || unit.contains("日")) {
|
|
|
+ return produceDate.plusDays(shelfLife);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean shouldIncludeNearExpiry(long totalDays, long remainingDays) {
|
|
|
+ if (totalDays <= 0 || remainingDays < 0) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (totalDays <= 30) {
|
|
|
+ return remainingDays * 3 <= totalDays;
|
|
|
+ }
|
|
|
+ return remainingDays * 4 <= totalDays
|
|
|
+ || remainingDays == 30
|
|
|
+ || remainingDays == 60
|
|
|
+ || remainingDays == 90;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<PsiWareHouseDto> buildNearExpiryPageRecords(List<PsiWareHouseDto> list, long current, long size) {
|
|
|
+ if (size <= 0) {
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+ long start = (current - 1) * size;
|
|
|
+ if (start >= list.size()) {
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+ long end = Math.min(start + size, list.size());
|
|
|
+ return new ArrayList<>(list.subList((int) start, (int) end));
|
|
|
+ }
|
|
|
+
|
|
|
public IPage<PsiWareHouseDto> getByProduceDateNotMerge(Page<PsiWareHouseDto> page , PsiWareHouseDto dto) throws Exception{
|
|
|
QueryWrapper<PsiWareHouseDto> queryWrapper = QueryWrapperGenerator.buildQueryCondition(dto, PsiWareHouseDto.class);
|
|
|
|
|
|
@@ -1181,6 +1304,88 @@ public class PsiWareHouseBasicService {
|
|
|
}
|
|
|
|
|
|
|
|
|
+ public IPage<PsiWareHouseDto> getAllData(Page<PsiWareHouseDto> page , PsiWareHouseDto dto) throws Exception{
|
|
|
+ QueryWrapper<PsiWareHouseDto> queryWrapper = QueryWrapperGenerator.buildQueryCondition(dto, PsiWareHouseDto.class);
|
|
|
+
|
|
|
+ queryWrapper.eq("a.del_flag", "0");
|
|
|
+
|
|
|
+ if (StringUtils.isNotEmpty(dto.getTradeName())) {
|
|
|
+ queryWrapper.like("a.trade_name", dto.getTradeName());
|
|
|
+ }
|
|
|
+ queryWrapper.and(wq ->{
|
|
|
+ wq.eq("bas.`status`","0")
|
|
|
+ .or()
|
|
|
+ .eq("bas.`status`","5");
|
|
|
+ });
|
|
|
+
|
|
|
+ //入库类型
|
|
|
+ if (StringUtils.isNotEmpty(dto.getWareHouseType())) {
|
|
|
+ queryWrapper.eq("c.id", dto.getWareHouseType());
|
|
|
+ }
|
|
|
+
|
|
|
+ //生产日期
|
|
|
+ if (dto.getProduceDate() != null) {
|
|
|
+ queryWrapper.eq("a.produce_date", dto.getProduceDate());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtils.isNotEmpty(dto.getSupplierId())) {
|
|
|
+ List<PsiWareHouseDetailed> wareHouseDetaileds = psiDetailedMapper.selectList(new LambdaQueryWrapper<PsiWareHouseDetailed>().eq(PsiWareHouseDetailed::getSupplierId, dto.getSupplierId()));
|
|
|
+ if (CollectionUtil.isNotEmpty(wareHouseDetaileds)) {
|
|
|
+ List<String> containsIds = wareHouseDetaileds.stream().map(PsiWareHouseDetailed::getId).collect(Collectors.toList());
|
|
|
+ if (CollectionUtil.isNotEmpty(containsIds)) {
|
|
|
+ queryWrapper.in("a.id", containsIds);
|
|
|
+ } else {
|
|
|
+ return new Page<>();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return new Page<>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ LocalDate today = LocalDate.now(ZoneId.systemDefault());
|
|
|
+ IPage<PsiWareHouseDto> wareHouseDtoIPage = basicMapper.getAllData(page, queryWrapper);
|
|
|
+ wareHouseDtoIPage.getRecords().forEach(item -> {
|
|
|
+ // 将小数点后无效的0删除
|
|
|
+ // 总量 格式化
|
|
|
+ if (StringUtils.isNotBlank(item.getAllNumber())) {
|
|
|
+ String s = convertByBigDecimal(item.getAllNumber());
|
|
|
+ item.setAllNumber(s);
|
|
|
+ }
|
|
|
+ //领用量 格式化
|
|
|
+ if (StringUtils.isNotBlank(item.getBorrowNumber())) {
|
|
|
+ String s = convertByBigDecimal(item.getBorrowNumber());
|
|
|
+ item.setBorrowNumber(s);
|
|
|
+ }
|
|
|
+ //剩余量 格式化
|
|
|
+ if (StringUtils.isNotBlank(item.getTradeNumber())) {
|
|
|
+ String s = convertByBigDecimal(item.getTradeNumber());
|
|
|
+ item.setTradeNumber(s);
|
|
|
+ }
|
|
|
+ //提醒数量 格式化
|
|
|
+ if (StringUtils.isNotBlank(item.getWarnNum())) {
|
|
|
+ String s = convertByBigDecimal(item.getWarnNum());
|
|
|
+ item.setWarnNum(s);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!canCheckNearExpiry(item)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Integer shelfLifeValue = parseShelfLifeValue(item.getShelfLife());
|
|
|
+ if (shelfLifeValue == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ LocalDate produceDate = toLocalDate(item.getProduceDate());
|
|
|
+ LocalDate expiryDate = calculateExpiryDate(produceDate, shelfLifeValue, item.getShelfLifeUnit());
|
|
|
+ if (expiryDate == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ long totalDays = ChronoUnit.DAYS.between(produceDate, expiryDate);
|
|
|
+ long remainingDays = ChronoUnit.DAYS.between(today, expiryDate);
|
|
|
+ item.setExpiryDate(Date.from(expiryDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
|
|
|
+ item.setRemainingDays((int) remainingDays);
|
|
|
+ });
|
|
|
+ return wareHouseDtoIPage;
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
// 去除小数点后无效的0
|
|
|
public String convertByBigDecimal(String value) {
|