src/main/java/com/ruoyi/production/service/impl/SalesLedgerSchedulingServiceImpl.java
@@ -5,20 +5,21 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.procurementrecord.dto.ProcurementRecordOutPageDto;
import com.ruoyi.production.dto.ProcessSchedulingDto;
import com.ruoyi.production.dto.ProductionDispatchAddDto;
import com.ruoyi.production.dto.SalesLedgerSchedulingDto;
import com.ruoyi.production.dto.SalesLedgerSchedulingProcessDto;
import com.ruoyi.production.dto.*;
import com.ruoyi.production.mapper.SalesLedgerSchedulingMapper;
import com.ruoyi.production.mapper.SalesLedgerWorkMapper;
import com.ruoyi.production.mapper.SpeculativeTradingInfoMapper;
import com.ruoyi.production.pojo.SalesLedgerScheduling;
import com.ruoyi.production.pojo.SalesLedgerWork;
import com.ruoyi.production.pojo.SpeculativeTradingInfo;
import com.ruoyi.production.service.SalesLedgerSchedulingService;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@@ -26,8 +27,12 @@
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
/**
@@ -61,6 +66,12 @@
                    .filter(j -> j.getSalesLedgerProductId().equals(i.getSalesLedgerProductId()))
                    .map(SalesLedgerWork::getFinishedNum)
                    .reduce(BigDecimal.ZERO, BigDecimal::add));
            // 状态 = 数量和完工数量比较
            if(i.getSchedulingNum().compareTo(i.getSuccessNum()) == 0){
                i.setStatus("已完成");
            }else{
                i.setStatus("未完成");
            }
        });
        return list;
    }
@@ -90,13 +101,46 @@
    private final SysUserMapper sysUserMapper;
    private final SpeculativeTradingInfoMapper speculativeTradingInfoMapper;
    @Override
    public int productionDispatch(ProductionDispatchAddDto productionDispatchAddDto) {
        SysUser sysUser = sysUserMapper.selectUserById(productionDispatchAddDto.getSchedulingUserId());
        if(sysUser == null) throw new RuntimeException("排产人不存在");
        // 获取空余炒机
        String[] split = productionDispatchAddDto.getSpeculativeTradingName().split(",");
        if(split != null && split.length == 0){
            throw new RuntimeException("生产炒机不能为空");
        }
        List<SpeculativeTradingInfo> speculativeTradingInfos = speculativeTradingInfoMapper.selectList(new LambdaQueryWrapper<SpeculativeTradingInfo>()
                .in(SpeculativeTradingInfo::getName, Arrays.asList(split))
                .orderByAsc(SpeculativeTradingInfo::getSort));
        if(CollectionUtils.isEmpty(speculativeTradingInfos)){
            throw new RuntimeException("无空余炒机,请检查炒机表");
        }
        AtomicReference<String> name = new AtomicReference<>("");  //需要绑定的炒机
        //通过规格型号和排产数量计算本次生产产量
        String[] split1 = productionDispatchAddDto.getSpecificationModel().split("\\*");
        if(split1.length != 2) throw new RuntimeException("规格型号格式错误");
        // 本次生产产量
        BigDecimal productionNum = new BigDecimal(split1[0])
                .multiply(new BigDecimal(split1[1]).multiply(productionDispatchAddDto.getSchedulingNum()));
        // 多个炒机情况
        if(speculativeTradingInfos.size() > 1){
            speculativeTradingInfos.forEach(item ->{
                // 获取该炒机正在排产量
                BigDecimal schedulingNumBySpeculativeTradingName = getSchedulingNumBySpeculativeTradingName(item.getName());
                // 如果该炒机总量 - 正在排产量 >=本次生产产量就分配此炒机
                if(item.getWorkLoad().subtract(schedulingNumBySpeculativeTradingName).compareTo(productionNum) >= 0){
                    name.set(item.getName());
                }
            });
        }
        if(name.get().isEmpty()) throw new RuntimeException("无空余炒机,请检查炒机表");
        SalesLedgerScheduling salesLedgerScheduling = SalesLedgerScheduling.builder()
                .salesLedgerId(productionDispatchAddDto.getSalesLedgerId())
                .salesLedgerProductId(productionDispatchAddDto.getSalesLedgerProductId())
                .speculativeTradingName(name.get())
                .schedulingUserId(productionDispatchAddDto.getSchedulingUserId())
                .schedulingUserName(sysUser.getNickName())
                .schedulingNum(productionDispatchAddDto.getSchedulingNum())
@@ -106,23 +150,92 @@
        return salesLedgerSchedulingMapper.insert(salesLedgerScheduling);
    }
    private final SalesLedgerProductMapper salesLedgerProductMapper;
    /**
     *通过炒机名称获取当天正在排产量
     * @return
     */
    public BigDecimal getSchedulingNumBySpeculativeTradingName(String speculativeTradingName){
        LambdaQueryWrapper<SalesLedgerScheduling> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SalesLedgerScheduling::getSpeculativeTradingName, speculativeTradingName)
                .eq(SalesLedgerScheduling::getSchedulingDate, LocalDate.now());
        List<SalesLedgerScheduling> salesLedgerSchedulings = salesLedgerSchedulingMapper.selectList(queryWrapper);
        if(CollectionUtils.isEmpty(salesLedgerSchedulings)){
            return BigDecimal.ZERO;
        }
        List<Long> collect = salesLedgerSchedulings.stream().map(SalesLedgerScheduling::getSalesLedgerProductId).collect(Collectors.toList());
        List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>()
                .in(SalesLedgerProduct::getId, collect));
        if(CollectionUtils.isEmpty(salesLedgerProducts)) return BigDecimal.ZERO;
        AtomicInteger totalNum = new AtomicInteger(0); //总数
        salesLedgerSchedulings.forEach(item ->{
            List<SalesLedgerProduct> collect1 = salesLedgerProducts.stream()
                    .filter(j -> j.getId().equals(item.getSalesLedgerProductId()))
                    .collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(collect1)){
                SalesLedgerProduct salesLedgerProduct = collect1.get(0);
                // 根据产品规格 * 排产数量 获取本次生产产量并累计
                String[] split = salesLedgerProduct.getSpecificationModel().split("\\*");
                BigDecimal productionNum = new BigDecimal(split[0])
                        .multiply(new BigDecimal(split[1]).multiply(item.getSchedulingNum()));
                totalNum.addAndGet(productionNum.intValue());
            }
        });
        return new BigDecimal(totalNum.get());
    }
    /**
     *通过批量炒机名称获取当天正在排产量
     * @return
     */
    public BigDecimal getSchedulingNumBySpeculativeTradingNameList(List<String> speculativeTradingName){
        LambdaQueryWrapper<SalesLedgerScheduling> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SalesLedgerScheduling::getSpeculativeTradingName, speculativeTradingName)
                .eq(SalesLedgerScheduling::getSchedulingDate, LocalDate.now());
        List<SalesLedgerScheduling> salesLedgerSchedulings = salesLedgerSchedulingMapper.selectList(queryWrapper);
        if(CollectionUtils.isEmpty(salesLedgerSchedulings)){
            return BigDecimal.ZERO;
        }
        List<Long> collect = salesLedgerSchedulings.stream().map(SalesLedgerScheduling::getSalesLedgerProductId).collect(Collectors.toList());
        List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>()
                .in(SalesLedgerProduct::getId, collect));
        if(CollectionUtils.isEmpty(salesLedgerProducts)) return BigDecimal.ZERO;
        AtomicInteger totalNum = new AtomicInteger(0); //总数
        salesLedgerSchedulings.forEach(item ->{
            List<SalesLedgerProduct> collect1 = salesLedgerProducts.stream()
                    .filter(j -> j.getId().equals(item.getSalesLedgerProductId()))
                    .collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(collect1)){
                SalesLedgerProduct salesLedgerProduct = collect1.get(0);
                // 根据产品规格 * 排产数量 获取本次生产产量并累计
                String[] split = salesLedgerProduct.getSpecificationModel().split("\\*");
                BigDecimal productionNum = new BigDecimal(split[0])
                        .multiply(new BigDecimal(split[1]).multiply(item.getSchedulingNum()));
                totalNum.addAndGet(productionNum.intValue());
            }
        });
        return new BigDecimal(totalNum.get());
    }
    @Override
    public IPage<SalesLedgerSchedulingProcessDto> listPageProcess(Page page, SalesLedgerSchedulingProcessDto salesLedgerSchedulingDto) {
        IPage<SalesLedgerSchedulingProcessDto> list = salesLedgerSchedulingMapper.listPageProcess(page, salesLedgerSchedulingDto);
        Set<Long> collect = list.getRecords().stream().map(SalesLedgerSchedulingProcessDto::getSalesLedgerProductId).collect(Collectors.toSet());
        if(CollectionUtils.isEmpty(collect)) return list;
        LambdaQueryWrapper<SalesLedgerWork> salesLedgerWorkLambdaQueryWrapper = new LambdaQueryWrapper<>();
        salesLedgerWorkLambdaQueryWrapper.in(SalesLedgerWork::getSalesLedgerProductId, collect)
                .ne(SalesLedgerWork::getStatus, 1);
        List<SalesLedgerWork> salesLedgerWorks = salesLedgerWorkMapper.selectList(salesLedgerWorkLambdaQueryWrapper);
        list.getRecords().forEach(i -> {
            // 获取完成数量
            i.setSuccessNum(salesLedgerWorks
                    .stream()
                    .filter(j -> j.getSalesLedgerProductId().equals(i.getSalesLedgerProductId()))
                    .map(SalesLedgerWork::getFinishedNum)
                    .reduce(BigDecimal.ZERO, BigDecimal::add));
        });
//        Set<Long> collect = list.getRecords().stream().map(SalesLedgerSchedulingProcessDto::getId).collect(Collectors.toSet());
//        if(CollectionUtils.isEmpty(collect)) return list;
//        LambdaQueryWrapper<SalesLedgerWork> salesLedgerWorkLambdaQueryWrapper = new LambdaQueryWrapper<>();
//        salesLedgerWorkLambdaQueryWrapper.in(SalesLedgerWork::getSalesLedgerSchedulingId, collect)
//                .ne(SalesLedgerWork::getStatus, 1);
//        List<SalesLedgerWork> salesLedgerWorks = salesLedgerWorkMapper.selectList(salesLedgerWorkLambdaQueryWrapper);
//        list.getRecords().forEach(i -> {
//            // 获取完成数量
//            i.setSuccessNum(salesLedgerWorks
//                    .stream()
//                    .filter(j -> j.getSalesLedgerSchedulingId().equals(i.getId()))
//                    .map(SalesLedgerWork::getFinishedNum)
//                    .reduce(BigDecimal.ZERO, BigDecimal::add));
//        });
        return list;
    }
@@ -147,7 +260,14 @@
            SysUser sysUser = sysUserMapper.selectUserById(processSchedulingDto.getSchedulingUserId());
            if(sysUser == null) throw new RuntimeException("排产人不存在");
            salesLedgerScheduling.setFinishedNum(salesLedgerScheduling.getFinishedNum().add(processSchedulingDto.getSchedulingNum()));
            if(salesLedgerScheduling.getSchedulingNum().compareTo(salesLedgerScheduling.getFinishedNum()) <= 0){
//            LambdaQueryWrapper<SalesLedgerWork> salesLedgerWorkLambdaQueryWrapper = new LambdaQueryWrapper<>();
//            salesLedgerWorkLambdaQueryWrapper.eq(SalesLedgerWork::getSalesLedgerSchedulingId, salesLedgerScheduling.getId())
//                    .ne(SalesLedgerWork::getStatus, 1);
//            List<SalesLedgerWork> salesLedgerWorks = salesLedgerWorkMapper.selectList(salesLedgerWorkLambdaQueryWrapper);
            if(salesLedgerScheduling.getSchedulingNum().compareTo(salesLedgerScheduling.getFinishedNum()) < 0){
                throw new RuntimeException("当前排产数量大于待排产数量,请仔细核对!");
            }
            if(salesLedgerScheduling.getSchedulingNum().compareTo(salesLedgerScheduling.getFinishedNum()) == 0){
                salesLedgerScheduling.setStatus(3);
            }else{
                salesLedgerScheduling.setStatus(2);
@@ -156,6 +276,10 @@
            SalesLedgerWork.SalesLedgerWorkBuilder salesLedgerWorkBuilder = SalesLedgerWork.builder()
                    .salesLedgerSchedulingId(salesLedgerScheduling.getId())
                    .salesLedgerId(salesLedgerScheduling.getSalesLedgerId())
                    .remark(processSchedulingDto.getRemark())
                    .type(processSchedulingDto.getType())
                    .loss(processSchedulingDto.getLoss())
                    .receive(processSchedulingDto.getReceive())
                    .salesLedgerProductId(salesLedgerScheduling.getSalesLedgerProductId())
                    .schedulingUserId(salesLedgerScheduling.getSchedulingUserId())
                    .schedulingUserName(sysUser.getNickName())
@@ -168,4 +292,22 @@
        }
        return 0;
    }
    @Override
    public void exportOne(HttpServletResponse response) {
        List<SalesLedgerSchedulingDto> list = salesLedgerSchedulingMapper.list();
        if(CollectionUtils.isEmpty(list)){
            throw new RuntimeException("无导出数据");
        }
        List<DaiDto> dais = new ArrayList<>();
        list.forEach(i -> {
            DaiDto daiDto = new DaiDto();
            BeanUtils.copyProperties(i, daiDto);
            // 获取待排产数量
            daiDto.setDaiNum(daiDto.getQuantity().subtract(i.getSchedulingNum()));
            dais.add(daiDto);
        });
        ExcelUtil<DaiDto> util = new ExcelUtil<>(DaiDto.class);
        util.exportExcel(response, dais, "生产派工");
    }
}