package com.vincent.rsf.server.manager.schedules; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.vincent.rsf.framework.common.Cools; import com.vincent.rsf.framework.exception.CoolException; import com.vincent.rsf.server.api.entity.dto.ReceiptDetlsDto; import com.vincent.rsf.server.common.config.SysStockProperties; import com.vincent.rsf.server.common.utils.CommonUtil; import com.vincent.rsf.server.common.utils.DateUtils; import com.vincent.rsf.server.manager.controller.params.WarehouseAreaParam; import com.vincent.rsf.server.manager.entity.*; import com.vincent.rsf.server.manager.enums.AsnExceStatus; import com.vincent.rsf.server.manager.enums.POExceStatus; import com.vincent.rsf.server.manager.enums.PakinIOStatus; import com.vincent.rsf.server.manager.enums.WarehouseAreasType; import com.vincent.rsf.server.manager.service.*; import com.vincent.rsf.server.manager.service.impl.WarehouseAreasItemServiceImpl; import com.vincent.rsf.server.system.constant.GlobalConfigCode; import com.vincent.rsf.server.system.constant.SerialRuleCode; import com.vincent.rsf.server.system.entity.Config; import com.vincent.rsf.server.system.service.ConfigService; import com.vincent.rsf.server.system.utils.SerialRuleUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; /** * @author Ryan * @version 1.0 * @title ScheduleJobs * @description * @create 2025/3/3 15:38 */ @Component public class ScheduleJobs { @Autowired private PurchaseService purchaseService; @Autowired private PurchaseItemService purchaseItemService; @Autowired private AsnOrderService asnOrderService; @Autowired private MatnrService matnrService; @Autowired private AsnOrderItemService asnOrderItemService; @Resource private SysStockProperties flowProperties; @Autowired private WaitPakinService waitPakinService; @Autowired private WaitPakinItemService waitPakinItemService; @Autowired private WaitPakinLogService waitPakinLogService; @Autowired private WaitPakinItemLogService waitPakinItemLogService; @Autowired private ConfigService configService; @Autowired private WarehouseAreasService warehouseAreasService; @Autowired private WarehouseAreasItemServiceImpl warehouseAreasItemService; @Autowired private CompanysService companysService; /** * @author Ryan * @date 2025/5/9 * @description: 直接组托开关为true,将收货单直接加入临时库存 * @version 1.0 */ // @Scheduled(cron = "0 0/05 * * * ? ") @Scheduled(cron = "0/25 * * * * ?") @Transactional(rollbackFor = Exception.class) public synchronized void IgnoreReceipt() { Config config = configService.getOne(new LambdaQueryWrapper().eq(Config::getFlag, GlobalConfigCode.DIRECT_WAIT_PAKIN)); if (Objects.isNull(config)) { return; } if (!Boolean.parseBoolean(config.getVal())) { return; } List orders = asnOrderService.list(new LambdaQueryWrapper().eq(AsnOrder::getExceStatus, AsnExceStatus.ASN_EXCE_STATUS_UN_EXCE.val)); if (!orders.isEmpty()) { for (AsnOrder order : orders) { List orderItems = asnOrderItemService.list(new LambdaQueryWrapper().eq(AsnOrderItem::getAsnId, order.getId())); if (orderItems.isEmpty()) { return; } List items = new ArrayList<>(); for (AsnOrderItem item : orderItems) { WarehouseAreas one = warehouseAreasService.getOne(new LambdaQueryWrapper() .eq(WarehouseAreas::getType, WarehouseAreasType.WAREHOUSE_AREAS_TYPE_RECEIPT.type), false); Long areaId = Objects.isNull(one) ? null : one.getId(); String areaName = Objects.isNull(one) ? null : one.getName(); WarehouseAreasItem param = new WarehouseAreasItem(); BeanUtils.copyProperties(item, param); param.setAreaId(one.getId()) .setAsnCode(order.getCode()) .setAreaId(areaId) .setAreaName(areaName) .setAsnId(order.getId()); items.add(param); Matnr matnr = matnrService.getOne(new LambdaQueryWrapper().eq(Matnr::getId, item.getMatnrId())); if (Objects.isNull(matnr)) { throw new CoolException("物料不存在!!"); } //更新收货区库存 extracted(one, item, order, matnr); if (!asnOrderItemService.update(new LambdaUpdateWrapper().set(AsnOrderItem::getQty, item.getAnfme()).eq(AsnOrderItem::getId, item.getId()))) { throw new CoolException("收货单明细完成数量修改失败!!"); } } // if (!warehouseAreasItemService.saveBatch(items)) { // throw new CoolException("收货单保存至收货区执行失败!!"); // } if (!asnOrderService.update(new LambdaUpdateWrapper() .set(AsnOrder::getQty, order.getAnfme()) .set(AsnOrder::getExceStatus, AsnExceStatus.ASN_EXCE_STATUS_RECEIPT_DONE.val) .eq(AsnOrder::getId, order.getId()))) { throw new CoolException("收货单状态修改失败!!"); } } } } /** * @author Ryan * @date 2025/5/12 * @description: 收货区库存更新 * @version 1.0 */ private void extracted(WarehouseAreas areasItem, AsnOrderItem orderItem, AsnOrder asnOrder, Matnr matnr) { Companys companys = new Companys(); if (StringUtils.isNoneBlank(orderItem.getSplrCode())) { companys = companysService.getOne(new LambdaQueryWrapper().eq(Companys::getCode, orderItem.getSplrCode())); } WarehouseAreasItem item = new WarehouseAreasItem(); item.setTrackCode(orderItem.getBarcode()) .setAreaName(areasItem.getName()) .setAreaId(areasItem.getId()) .setAsnItemId(orderItem.getId()) .setAsnCode(asnOrder.getCode()) .setAsnId(asnOrder.getId()) .setProdTime(orderItem.getProdTime()) .setPlatItemId(orderItem.getPlatItemId()) .setPlatOrderCode(orderItem.getPlatOrderCode()) .setPlatWorkCode(orderItem.getPlatWorkCode()) .setProjectCode(orderItem.getProjectCode()) .setSplrId(companys.getId()) //库存单位为最小单位 .setUnit(orderItem.getStockUnit()) .setStockUnit(orderItem.getStockUnit()) .setMatnrCode(matnr.getCode()) .setAnfme(orderItem.getAnfme()) .setMatnrId(matnr.getId()) .setIsptResult(orderItem.getIsptResult()) .setMaktx(matnr.getName()) .setSplrBatch(orderItem.getSplrBatch()) .setWeight(matnr.getWeight()) .setFieldsIndex(orderItem.getFieldsIndex()) .setShipperId(matnr.getShipperId()); LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() .eq(WarehouseAreasItem::getMatnrCode, orderItem.getMatnrCode()) .eq(!Cools.isEmpty(orderItem.getFieldsIndex()), WarehouseAreasItem::getFieldsIndex, orderItem.getFieldsIndex()) .eq(WarehouseAreasItem::getAsnCode, orderItem.getAsnCode()) .eq(StringUtils.isNotBlank(orderItem.getSplrBatch()), WarehouseAreasItem::getSplrBatch, orderItem.getSplrBatch()); if (Objects.isNull(orderItem.getIsptResult())) { queryWrapper.isNull(WarehouseAreasItem::getIsptResult); } else { queryWrapper.eq(WarehouseAreasItem::getIsptResult, orderItem.getIsptResult()); } WarehouseAreasItem serviceOne = warehouseAreasItemService.getOne(queryWrapper); if (!Objects.isNull(serviceOne)) { item.setId(serviceOne.getId()); item.setAnfme(item.getAnfme() + serviceOne.getAnfme()); } //未质检 if (!warehouseAreasItemService.saveOrUpdate(item)) { throw new CoolException("收货失败!!"); } } /** * @return * @throws * @author Ryan * @description 根据PO单据生成ASN单, 自动生成ASN单为全量生成 * @time 2025/3/3 15:44 */ @Scheduled(cron = "0 0/05 * * * ? ") @Transactional(rollbackFor = Exception.class) public synchronized void genAsnOrder() { //判断是否开启自动生成ASN单据 if (!flowProperties.getFlagAutoAsn()) { return; } //获取未生成ASN单据 List purchases = purchaseService.list(new LambdaQueryWrapper().eq(Purchase::getExceStatus, 0)); //PO单为空,直接跳出当前任务 if (purchases.isEmpty()) { return; } //生成ASN单据 purchases.forEach(purchase -> { if (!Objects.isNull(purchase.getStartTime())) { //判断起始时间是否大于当前时间 if (DateUtils.compareDate(new Date(), purchase.getStartTime())) { return; } } List items = purchaseItemService.list(new LambdaQueryWrapper().eq(PurchaseItem::getPurchaseId, purchase.getId())); if (items.isEmpty()) { throw new CoolException("子列表数据为空,请查询PO单是否正确录入!!"); } AsnOrder order = new AsnOrder(); //根据编码规则生成ASN单号 String code = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_ASN_ORDER, purchase); order.setAnfme(purchase.getAnfme()) .setCode(code) .setArrTime(purchase.getPreArr()) .setQty(purchase.getQty()) .setPoId(purchase.getId()) .setPoCode(purchase.getCode()); if (!asnOrderService.save(order)) { throw new CoolException("ASN单据保存失败!!"); } List orderItems = new ArrayList<>(); items.forEach(item -> { AsnOrderItem orderItem = new AsnOrderItem(); Matnr matnr = matnrService.getOne(new LambdaQueryWrapper().eq(Matnr::getCode, item.getMatnrCode())); if (Objects.isNull(matnr)) { throw new CoolException("数据错误:当前物料不存在!!"); } String trackCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_LABEL_CODE, item); if (StringUtils.isBlank(trackCode)) { throw new CoolException("单据跟踪码生成失败:请检查「sys_asn_mantr_label」是否配置完成!!"); } // String barcode = code + matnr.getCode(); orderItem.setAnfme(item.getAnfme()) .setAsnId(order.getId()) .setQty(item.getQty()) .setSplrName(item.getSplrName()) .setAsnCode(code) .setSplrCode(item.getSplrCode()) .setPoDetlId(item.getId()) .setPlatItemId(item.getPlatItemId()) .setTrackCode(trackCode) .setPoCode(purchase.getCode()) .setPurQty(item.getAnfme()) .setPurUnit(item.getUnit()) .setMatnrCode(matnr.getCode()) .setMaktx(matnr.getName()) .setMatnrId(matnr.getId()); orderItems.add(orderItem); }); if (!asnOrderItemService.saveBatch(orderItems)) { throw new CoolException(("Asn单据明细保存失败!!")); } //任务执行完成,修改已完成数量和PO单执行状态 purchase.setQty(purchase.getAnfme()) .setExceStatus(POExceStatus.PO_EXCE_STATUS_EXCE_ING.val); if (!purchaseService.saveOrUpdate(purchase)) { throw new CoolException("PO单执行完成后,保存失败!!"); } }); } /** * @param * @return * @author Ryan * @description 生成物料标签 * @time 2025/3/29 12:35 */ @Scheduled(cron = "0 0/05 * * * ? ") @Transactional(rollbackFor = Exception.class) public void generateMatnrLabel() { List list = asnOrderItemService.list(new LambdaQueryWrapper() .isNull(AsnOrderItem::getTrackCode) .select(AsnOrderItem::getId)); if (Objects.isNull(list) || list.isEmpty()) { return; } List items = new ArrayList<>(); list.forEach(item -> { String trackCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_LABEL_CODE, item); if (StringUtils.isBlank(trackCode)) { throw new CoolException("单据跟踪码生成失败:请检查「sys_asn_mantr_label」是否配置完成!!"); } // item.setTrackCode(trackCode); item.setBarcode(trackCode); items.add(item); }); if (!asnOrderItemService.updateBatchById(items)) { throw new CoolException("生成编码失败!!"); } } /** * @param * @return * @author Ryan * @description 组拖历史档 * @time 2025/3/29 12:36 */ @Scheduled(cron = "0/25 * * * * ?") @Transactional(rollbackFor = Exception.class) public void pakinLog() { List pakinIds = waitPakinService.list(new LambdaQueryWrapper() .eq(WaitPakin::getIoStatus, Short.valueOf(PakinIOStatus.PAKIN_IO_STATUS_TASK_DONE.val)) .select(WaitPakin::getId)); if (pakinIds.isEmpty()) { return; } List list = pakinIds.stream().map(WaitPakin::getId).collect(Collectors.toList()); List pakins = waitPakinService.list(new LambdaQueryWrapper().in(WaitPakin::getId, list)); if (pakins.isEmpty()) { throw new CoolException("组拖单为空!!"); } List pakinLogs = new ArrayList<>(); pakins.forEach(pakin -> { WaitPakinLog log = new WaitPakinLog(); BeanUtils.copyProperties(pakin, log); log.setPakinId(pakin.getId()).setIoStatus(Short.parseShort("2")); pakinLogs.add(log); }); if (!waitPakinLogService.saveBatch(pakinLogs)) { throw new CoolException("历史档保存失败!!"); } List itemLogs = new ArrayList<>(); List pakinItems = waitPakinItemService.list(new LambdaQueryWrapper().in(WaitPakinItem::getPakinId, list)); if (pakinItems.isEmpty()) { throw new CoolException("组拖明细为空!!"); } pakinItems.forEach(item -> { WaitPakinItemLog itemLog = new WaitPakinItemLog(); BeanUtils.copyProperties(item, itemLog); itemLog.setPakinItemId(item.getId()) .setPakinId(item.getPakinId()); itemLogs.add(itemLog); }); if (!waitPakinItemLogService.saveBatch(itemLogs)) { throw new CoolException("历史明细档保存失败!!"); } if (!waitPakinService.removeByIds(list)) { throw new CoolException("原单据删除失败!!"); } if (!waitPakinItemService.remove(new LambdaQueryWrapper().in(WaitPakinItem::getPakinId, list))) { throw new CoolException("原单据明细删除失败!!"); } } }