package com.ruoyi.web.controller.task; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.BaseModel; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.http.HttpUtils; import com.ruoyi.system.mapper.TErpSupplierOutboundGoodsMapper; import com.ruoyi.system.mapper.TErpSupplierOutboundMapper; import com.ruoyi.system.mapper.TErpSupplierWarehousingBatchMapper; import com.ruoyi.system.mapper.TErpSupplierWarehousingMapper; import com.ruoyi.system.model.*; import com.ruoyi.system.service.*; import com.ruoyi.system.utils.util.AIUtil; import com.ruoyi.system.vo.TCrmClinicVO; import com.ruoyi.web.controller.yuncang.api.trade.LogisticsSyncAck; import com.ruoyi.web.controller.yuncang.api.trade.LogisticsSyncQuery; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; /** * @author xiaochen * @date 2023/7/11 8:39 */ @Slf4j @Component public class TaskUtil { @Autowired private RedisCache redisCache; @Autowired private AIUtil aiUtil; @Autowired private TCrmClinicService crmClinicService; @Autowired private TErpProcurementService erpProcurementService; @Autowired private TCrmSupplierService crmSupplierService; @Autowired private TCrmSupplierVerifyService crmSupplierVerifyService; @Autowired private TSysOtherConfigService sysOtherConfigService; @Autowired private TSysCloudConfigService sysCloudConfigService; @Autowired private TErpProcurementGoodsService erpProcurementGoodsService; @Resource private TErpSupplierOutboundMapper erpSupplierOutboundMapper; @Resource private TErpSupplierOutboundGoodsMapper erpSupplierOutboundGoodsMapper; @Resource private TErpSupplierWarehousingMapper erpSupplierWarehousingMapper; @Resource private TErpSupplierWarehousingBatchMapper erpSupplierWarehousingBatchMapper; // @Scheduled(fixedRate = 86460000) // @Scheduled(cron = "10 0 0 * * ?") public void dayOfProportionBill() { try { // 查询跳转检测的用户 Set cacheSet = redisCache.getCacheSet(Constants.AI_USER_INSPECTION); // 获取前一天时间 LocalDate lastDay = LocalDate.now().minusDays(1); for (String phone : cacheSet) { R result = aiUtil.reportQuery(phone, lastDay.toString(), lastDay.toString()); JSONObject data = result.getData(); System.err.println(data); } } catch (Exception e) { e.printStackTrace(); } } @Scheduled(cron = "0 0 0 L * ?") public void monthUpdateClinicPerformance() { try { // 判断哪些诊所本月没有业绩达标 List clinics = crmClinicService.list(); String monthDate = new SimpleDateFormat("yyyy-MM").format(new Date()); List procurements = erpProcurementService.list(Wrappers.lambdaQuery(TErpProcurement.class) .in(TErpProcurement::getStatus, Arrays.asList(3,4,5)) .likeRight(TErpProcurement::getCreateTime, monthDate)); for (TCrmClinic clinic : clinics) { List procurementList = procurements.stream().filter(procurement -> procurement.getClinicId().equals(clinic.getId())).collect(Collectors.toList()); if(!CollectionUtils.isEmpty(procurementList)){ BigDecimal monthPurchaseAmount = procurementList.stream().map(TErpProcurement::getPayMoney).reduce(BigDecimal.ZERO, BigDecimal::add); // 未达标 if(monthPurchaseAmount.compareTo(clinic.getLowProcurementMoney())<0){ clinic.setPerformanceCount(clinic.getPerformanceCount()+1); } } } crmClinicService.updateBatchById(clinics); } catch (Exception e) { e.printStackTrace(); } } @Scheduled(cron = "0 0 0 * * ?") public void dayUpdateClinicMessageCount() { try { // 判断哪些诊所本月没有业绩达标 List clinics = crmClinicService.list(); for (TCrmClinic clinic : clinics) { clinic.setSendMessageCount(0); } crmClinicService.updateBatchById(clinics); } catch (Exception e) { e.printStackTrace(); } } // @Scheduled(cron = "0 0 1 * * ?") public void dayUpdateSupplierVerify() { try { // 每天1点生成供应商周期性的核查 List crmSuppliers = crmSupplierService.list(); if(!CollectionUtils.isEmpty(crmSuppliers)){ // 查询核查周期配置 TSysOtherConfig sysOtherConfig = sysOtherConfigService.getById(1); List supplierIds = crmSuppliers.stream().map(TCrmSupplier::getId).collect(Collectors.toList()); // 查询审核列表 List crmSupplierVerifies = crmSupplierVerifyService.list(Wrappers.lambdaQuery(TCrmSupplierVerify.class) .in(TCrmSupplierVerify::getSupplierId, supplierIds) .orderByDesc(TCrmSupplierVerify::getGenerateTime)); for (TCrmSupplier crmSupplier : crmSuppliers) { List supplierVerifies = crmSupplierVerifies.stream().filter(crmSupplierVerify -> crmSupplier.getId().equals(crmSupplierVerify.getSupplierId())).collect(Collectors.toList()); Integer verifyUnit = sysOtherConfig.getVerifyUnit(); Integer verifyValue = sysOtherConfig.getVerifyValue(); if (!CollectionUtils.isEmpty(supplierVerifies)) { // 根据最新的核查进行比较核查周期 TCrmSupplierVerify tCrmSupplierVerify = supplierVerifies.get(0); LocalDate generateTime = tCrmSupplierVerify.getGenerateTime(); LocalDate nextVerifyDate = calculateNextVerifyDate(generateTime, verifyUnit, verifyValue); if (nextVerifyDate != null && nextVerifyDate.isEqual(LocalDate.now())) { createSupplierVerify(crmSupplier); } } else { // 根据供应商添加时间进行比较核查周期 LocalDate createTime = crmSupplier.getCreateTime().toLocalDate(); LocalDate nextVerifyDate = calculateNextVerifyDate(createTime, verifyUnit, verifyValue); if (nextVerifyDate != null && nextVerifyDate.isEqual(LocalDate.now())) { createSupplierVerify(crmSupplier); } } } } } catch (Exception e) { e.printStackTrace(); } } /** * 计算下一次供应商核查时间 * @param baseDate * @param verifyUnit * @param verifyValue * @return */ private LocalDate calculateNextVerifyDate(LocalDate baseDate, Integer verifyUnit, Integer verifyValue) { switch (verifyUnit) { case 1: return baseDate.plusDays(verifyValue); case 2: return baseDate.plusMonths(verifyValue); case 3: return baseDate.plusYears(verifyValue); default: return null; } } /** * 每小时更新订单云物流状态 */ // @Scheduled(fixedRate = 86460000) @Scheduled(cron = "0 0 * * * ?") public void hourUpdateOrderCloudLogisticsStatus() { try { TSysCloudConfig sysCloudConfig = sysCloudConfigService.getOne(Wrappers.lambdaQuery(TSysCloudConfig.class) .eq(TSysCloudConfig::getCloudWarehouse, 1) .last("LIMIT 1")); JSONObject jsonObject = LogisticsSyncQuery.logisticsSyncQuery(sysCloudConfig.getSid(), sysCloudConfig.getAppKey(), sysCloudConfig.getAppSecret(), sysCloudConfig.getUrl(), ""); if(Objects.nonNull(jsonObject)){ JSONArray trades = jsonObject.getJSONArray("trades"); Map map = new HashMap<>(); List tidList = new ArrayList<>(); List> logistics_list = new ArrayList<>(); for (int i = 0; i < trades.size(); i++) { JSONObject trade_order = JSONObject.parseObject(JSONObject.toJSONString(trades.get(i))); String rec_id = trade_order.getString("rec_id"); // 主键,用于logistics_sync_ack回写状态 String tid = trade_order.getString("tid"); // 原始单号 String logistics_no = trade_order.getString("logistics_no"); // 物流单号 String logistics_name = trade_order.getString("logistics_name"); // 物流名称 map.put(tid, logistics_no); tidList.add(tid); Map logistics_1 = new HashMap<>(); logistics_1.put("rec_id", rec_id); logistics_1.put("status", 0); logistics_1.put("message", "同步成功"); logistics_list.add(logistics_1); } List procurements = erpProcurementService.list(Wrappers.lambdaQuery(TErpProcurement.class) .in(TErpProcurement::getProcurementCode, tidList)); if(!CollectionUtils.isEmpty(procurements)){ for (TErpProcurement procurement : procurements) { procurement.setLogisticsNo(map.get(procurement.getProcurementCode())); procurement.setStatus(4); procurement.setSendTime(LocalDateTime.now()); } erpProcurementService.updateBatchById(procurements); } // 物流同步回写 JSONObject logisticsSyncAck = LogisticsSyncAck.logisticsSyncAck(sysCloudConfig.getSid(), sysCloudConfig.getAppKey(), sysCloudConfig.getAppSecret(), sysCloudConfig.getUrl(), logistics_list); log.info("物流同步成功"); if(!CollectionUtils.isEmpty(procurements)){ List supplierIds = procurements.stream().map(TErpProcurement::getSupplierId).collect(Collectors.toList()); List ids = procurements.stream().map(TErpProcurement::getId).collect(Collectors.toList()); // 处理发货流程 detailProcurementSend(supplierIds,ids); } } } catch (Exception e) { e.printStackTrace(); } } public void detailProcurementSend(List clinicSupplierId, List ids) { // 查出这个采购的下级商品 List list = erpProcurementGoodsService.list(Wrappers.lambdaQuery(TErpProcurementGoods.class) .in(TErpProcurementGoods::getProcurementId, ids)); List tErpSupplierWarehousings = erpSupplierWarehousingMapper.selectList(new LambdaQueryWrapper() .in(TErpSupplierWarehousing::getSupplierId, clinicSupplierId).in(TErpSupplierWarehousing::getGoodsId, list.stream().map(TErpProcurementGoods::getGoodsId).collect(Collectors.toList())) .orderByAsc(BaseModel::getCreateTime)); if(tErpSupplierWarehousings.isEmpty()){ throw new RuntimeException("商品供应商未入库,请先入库"); } List tErpSupplierWarehousingBatches = erpSupplierWarehousingBatchMapper.selectList(new LambdaQueryWrapper().in(TErpSupplierWarehousingBatch::getWarehousingId, tErpSupplierWarehousings.stream().map(TErpSupplierWarehousing::getId).collect(Collectors.toList()))); // 获取所有的出库记录 List tErpSupplierOutboundGoodsLists = erpSupplierOutboundGoodsMapper.selectList(new LambdaQueryWrapper().in(TErpSupplierOutboundGoods::getWarehousingBatchId, tErpSupplierWarehousingBatches.stream().map(TErpSupplierWarehousingBatch::getId).collect(Collectors.toList()))); outer:for (TErpProcurementGoods tErpProcurementGoods : list) { // 分别入库 String goodsId = tErpProcurementGoods.getGoodsId(); // 查询这个供应商的 该商品是否入过库 未入库提示 出库判断库存 先找先入库的 List collect = tErpSupplierWarehousings.stream().filter(e -> e.getGoodsId().equals(goodsId)).collect(Collectors.toList()); if(collect.isEmpty()){ throw new RuntimeException("商品供应商未入库,请先入库"); } // 需要出库的数量 Integer purchaseCount = tErpProcurementGoods.getPurchaseCount(); if(purchaseCount==0){ continue; } for (TErpSupplierWarehousing tErpSupplierWarehousing : collect) { List warehousingBatches = tErpSupplierWarehousingBatches.stream().filter(e -> e.getWarehousingId().equals(tErpSupplierWarehousing.getId())).collect(Collectors.toList()); for (TErpSupplierWarehousingBatch warehousingBatch : warehousingBatches) { // 已出库数量 int sum = tErpSupplierOutboundGoodsLists.stream().filter(e -> e.getWarehousingBatchId().equals(warehousingBatch.getId())).mapToInt(TErpSupplierOutboundGoods::getOutboundCount).sum(); // 该批次剩余的数量 int count = warehousingBatch.getWarehousingNumber() - sum; // 该批次没有数量 找下个批次 if(count==0 ){ continue; } // 如果大于这个数量 则使用这个批次 if(count>=purchaseCount){ // 添加出库记录 TErpSupplierOutbound tErpSupplierOutbound= new TErpSupplierOutbound(); tErpSupplierOutbound.setGoodsId(tErpSupplierWarehousing.getGoodsId()); tErpSupplierOutbound.setSupplierId(tErpSupplierWarehousing.getSupplierId()); tErpSupplierOutbound.setWarehouseId(tErpSupplierWarehousing.getWarehouseId()); tErpSupplierOutbound.setOutboundType(7); //TODO 确定这个是采购价还是销售价格 tErpSupplierOutbound.setTotalMoney(tErpProcurementGoods.getPurchasePrice().multiply(new BigDecimal(purchaseCount))); TErpSupplierOutbound last = erpSupplierOutboundMapper.selectOne(new LambdaQueryWrapper().orderByDesc(BaseModel::getCreateTime).orderByDesc(TErpSupplierOutbound::getOutboundNumber).last("limit 1")); if(last==null){ tErpSupplierOutbound.setOutboundNumber("G" + DateUtils.dateTimeNow()+"00001"); }else { String lastProcurementCode = last.getOutboundNumber(); String datePart = "G" + DateUtils.dateTimeNow(); // 直接获取后五位数字并+1,不考虑是否同一天 try { String numberPart = lastProcurementCode.substring(Math.max(0, lastProcurementCode.length() - 5)); int number = Integer.parseInt(numberPart); if (number < 99999) { number++; } else { number = 2; // 达到99999后重置为00002 } tErpSupplierOutbound.setOutboundNumber(datePart + String.format("%05d", number)); } catch (NumberFormatException e) { // 如果解析失败,默认从00001开始 tErpSupplierOutbound.setOutboundNumber(datePart + "00001"); } } try { erpSupplierOutboundMapper.insert(tErpSupplierOutbound); }catch (Exception e){ throw new RuntimeException("网络繁忙,请重试"); } TErpSupplierOutboundGoods tErpSupplierOutboundGoods = new TErpSupplierOutboundGoods(); tErpSupplierOutboundGoods.setOutboundId(tErpSupplierOutbound.getId()); tErpSupplierOutboundGoods.setWarehousingId(tErpSupplierWarehousing.getId()); tErpSupplierOutboundGoods.setWarehousingBatchId(warehousingBatch.getId()); tErpSupplierOutboundGoods.setOutboundCount(purchaseCount); tErpSupplierOutboundGoods.setTotalPrice(tErpProcurementGoods.getPurchasePrice().multiply(new BigDecimal(purchaseCount))); tErpSupplierOutboundGoods.setProcurementGoodsId(tErpProcurementGoods.getId()); erpSupplierOutboundGoodsMapper.insert(tErpSupplierOutboundGoods); continue outer; } if(count().orderByDesc(BaseModel::getCreateTime).orderByDesc(TErpSupplierOutbound::getOutboundNumber).last("limit 1")); if(last==null){ tErpSupplierOutbound.setOutboundNumber("G" + DateUtils.dateTimeNow()+"00001"); }else { String lastProcurementCode = last.getOutboundNumber(); String datePart = "G" + DateUtils.dateTimeNow(); // 直接获取后五位数字并+1,不考虑是否同一天 try { String numberPart = lastProcurementCode.substring(Math.max(0, lastProcurementCode.length() - 5)); int number = Integer.parseInt(numberPart); if (number < 99999) { number++; } else { number = 2; // 达到99999后重置为00002 } tErpSupplierOutbound.setOutboundNumber(datePart + String.format("%05d", number)); } catch (NumberFormatException e) { // 如果解析失败,默认从00001开始 tErpSupplierOutbound.setOutboundNumber(datePart + "00001"); } } try { erpSupplierOutboundMapper.insert(tErpSupplierOutbound); }catch (Exception e){ throw new RuntimeException("网络繁忙,请重试"); } TErpSupplierOutboundGoods tErpSupplierOutboundGoods = new TErpSupplierOutboundGoods(); tErpSupplierOutboundGoods.setOutboundId(tErpSupplierOutbound.getId()); tErpSupplierOutboundGoods.setWarehousingId(tErpSupplierWarehousing.getId()); tErpSupplierOutboundGoods.setWarehousingBatchId(warehousingBatch.getId()); tErpSupplierOutboundGoods.setOutboundCount(purchaseCount); tErpSupplierOutboundGoods.setTotalPrice(tErpProcurementGoods.getPurchasePrice().multiply(new BigDecimal(purchaseCount))); tErpSupplierOutboundGoods.setProcurementGoodsId(tErpProcurementGoods.getId()); erpSupplierOutboundGoodsMapper.insert(tErpSupplierOutboundGoods); } } } if(purchaseCount>0){ throw new RuntimeException("商品供应商库存不足,请先入库"); } } } /** * 供应商周期核查 * @param crmSupplier */ private void createSupplierVerify(TCrmSupplier crmSupplier) { TCrmSupplierVerify crmSupplierVerify = new TCrmSupplierVerify(); crmSupplierVerify.setSupplierId(crmSupplier.getId()); crmSupplierVerify.setGenerateTime(LocalDate.now()); crmSupplierVerify.setStatus(1); crmSupplierVerifyService.save(crmSupplierVerify); } }