src/main/java/com/ruoyi/procurementrecord/service/impl/ProcurementRecordServiceImpl.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.security.LoginUser;
@@ -110,6 +111,8 @@
        procurementRecordStorageById.setWarnNum(procurementDto.getWarnNum());
        procurementRecordStorageById.setUpdateUser(SecurityUtils.getLoginUser().getUserId());
        procurementRecordStorageById.setUpdateTime(LocalDateTime.now());
        procurementRecordStorageById.setUnitPrice(procurementDto.getUnitPrice());
        procurementRecordStorageById.setTotalPrice(procurementDto.getTotalPrice());
        return procurementRecordMapper.updateById(procurementRecordStorageById);
    }
@@ -193,15 +196,28 @@
        if(salesLedgerProduct == null){
            throw new RuntimeException("销售台账产品不存在");
        }
        // 根据大类,规格查询所有产品id
        LambdaQueryWrapper<SalesLedgerProduct> salesLedgerProductLambdaQueryWrapper = new LambdaQueryWrapper<>();
        salesLedgerProductLambdaQueryWrapper.eq(SalesLedgerProduct::getProductCategory, salesLedgerProduct.getProductCategory())
                .eq(SalesLedgerProduct::getSpecificationModel, salesLedgerProduct.getSpecificationModel())
                .eq(SalesLedgerProduct::getType, 1);
        List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(salesLedgerProductLambdaQueryWrapper);
        if(CollectionUtils.isEmpty(salesLedgerProducts)){
            throw new RuntimeException("没有找到对应的产品");
        }
        salesLedgerProduct.setMinStock(procurementDto.getMinStock());
        salesLedgerProductMapper.updateById(salesLedgerProduct);
        ProcurementRecordStorage procurementRecordStorageById = getProcurementRecordById(procurementDto.getId());
        procurementRecordStorageById.setCreateBy(sysUser.getNickName());
        procurementRecordStorageById.setCreateUser(sysUser.getUserId());
        procurementRecordStorageById.setUpdateTime(LocalDateTime.parse(entryDateStr,df));
        procurementRecordStorageById.setUpdateUser(loginUser.getUserId());
        procurementRecordStorageById.setCreateTime(LocalDateTime.parse(createTimeStr,df));
        procurementRecordMapper.updateById(procurementRecordStorageById);
        LambdaQueryWrapper<ProcurementRecordStorage> procurementRecordStorageLambdaQueryWrapper = new LambdaQueryWrapper<>();
        procurementRecordStorageLambdaQueryWrapper.in(ProcurementRecordStorage::getSalesLedgerProductId, salesLedgerProducts.stream().map(SalesLedgerProduct::getId).collect(Collectors.toList()));
        ProcurementRecordStorage procurementRecordStorage = ProcurementRecordStorage.builder().build();
        procurementRecordStorage.setUnitPrice(procurementDto.getUnitPrice());
        procurementRecordStorage.setTotalPrice(procurementDto.getTotalPrice());
        procurementRecordStorage.setCreateBy(sysUser.getNickName());
        procurementRecordStorage.setCreateUser(sysUser.getUserId());
        procurementRecordStorage.setUpdateTime(LocalDateTime.parse(entryDateStr,df));
        procurementRecordStorage.setUpdateUser(loginUser.getUserId());
        procurementRecordStorage.setCreateTime(LocalDateTime.parse(createTimeStr,df));
        procurementRecordMapper.update(procurementRecordStorage,procurementRecordStorageLambdaQueryWrapper);
        return 0;
    }
@@ -400,6 +416,68 @@
    }
    @Override
    public InventoryInformationDto getReportList() {
        InventoryInformationDto inventoryInformationDto = new InventoryInformationDto();
        IPage<ProcurementPageDto> procurementPageDtoIPage = this.listPage(new Page<>(1, -1), new ProcurementPageDto());
        if(CollectionUtils.isEmpty(procurementPageDtoIPage.getRecords())){
            return inventoryInformationDto;
        }
        // 计算总库存数量
        inventoryInformationDto.setTotalInventoryCount(procurementPageDtoIPage.getRecords().stream()
                .map(ProcurementPageDto::getInboundNum0)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .intValue());
        // 计算总库存金额-ProcurementPageDto里每个对象的inboundNum0值和taxInclusiveUnitPrice的乘积,之后相加得到总库存金额
        BigDecimal totalInventoryValue = procurementPageDtoIPage.getRecords().stream()
                // 过滤空对象,避免NPE
                .filter(Objects::nonNull)
                // 处理每个对象的空值:null转为0
                .map(dto -> {
                    // 入库数量:null → 0
                    BigDecimal inboundNum0 = Optional.ofNullable(dto.getInboundNum0()).orElse(BigDecimal.ZERO);
                    // 含税单价:null → 0
                    BigDecimal taxInclusiveUnitPrice = Optional.ofNullable(dto.getTaxInclusiveUnitPrice()).orElse(BigDecimal.ZERO);
                    // 计算单个对象的库存金额:数量 × 含税单价
                    return inboundNum0.multiply(taxInclusiveUnitPrice);
                })
                // 所有单个金额求和,初始值为0
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        // 设置总库存金额
        inventoryInformationDto.setTotalInventoryValue(totalInventoryValue);
        // 计算库存变动数量-ProcurementPageDto里每个对象的inboundNum值和inboundNum0值的差值,之后相加得到库存变动数量
        inventoryInformationDto.setInventoryChangeCount(procurementPageDtoIPage.getRecords().stream()
                // 过滤空对象,避免NPE
                .filter(Objects::nonNull)
                // 处理每个对象的空值:null转为0
                .map(dto -> {
                    // 入库数量:null → 0
                    BigDecimal inboundNum = Optional.ofNullable(dto.getInboundNum()).orElse(BigDecimal.ZERO);
                    // 待出库数量:null → 0
                    BigDecimal inboundNum0 = Optional.ofNullable(dto.getInboundNum0()).orElse(BigDecimal.ZERO);
                    // 计算单个对象的库存变动数量:数量 - 待出库数量
                    return inboundNum.subtract(inboundNum0);
                })
                // 所有单个变动数量求和,初始值为0
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .intValue());
        // 计算库存变动金额ProcurementPageDto里每个对象的taxInclusiveTotalPrice值的和
        BigDecimal inventoryChangeValue = procurementPageDtoIPage.getRecords().stream()
                // 过滤空对象,避免NPE
                .filter(Objects::nonNull)
                // 处理每个对象的空值:null转为0
                .map(dto -> {
                    // 含税总价:null → 0
                    BigDecimal taxInclusiveTotalPrice = Optional.ofNullable(dto.getTaxInclusiveTotalPrice()).orElse(BigDecimal.ZERO);
                    // 计算单个对象的入库库存金额:含税总价
                    return taxInclusiveTotalPrice;
                })
                // 所有单个变动金额求和,初始值为0
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        // 设置库存变动金额
        inventoryInformationDto.setInventoryChangeValue(inventoryChangeValue.subtract(totalInventoryValue));
        return inventoryInformationDto;
    }
    @Override
    public IPage<ProcurementPageDto> listPageByProduction(Page page, ProcurementPageDto procurementDto) {
        IPage<ProcurementPageDto> procurementPageDtoIPage = procurementRecordMapper.listPageByProduction(page, procurementDto);
        List<ProcurementPageDto> procurementPageDtos = procurementPageDtoIPage.getRecords();
@@ -452,6 +530,7 @@
            Long aLong = customStorageMapper.selectCount(null);
            item.setInboundBatches(aLong.equals(0L) ? "第1批次(自定义入库)" : "第"+ (aLong + 1) + "批次(自定义入库)" );
            item.setCreateBy(loginUser.getNickName());
            item.setCode(OrderUtils.countTodayByCreateTime(customStorageMapper, ""));
            customStorageMapper.insert(item);
        });
        return AjaxResult.success("自定义入库成功");
@@ -632,6 +711,35 @@
    }
    @Override
    public int updateManagementByCustom(ProcurementManagementUpdateDto procurementDto) {
        CustomStorage customStorage = customStorageMapper.selectById(procurementDto.getId());
        if(customStorage == null){
            throw new RuntimeException("材料库存不存在");
        }
        LambdaQueryWrapper<CustomStorage> customStorageLambdaQueryWrapper = new LambdaQueryWrapper<>();
        customStorageLambdaQueryWrapper.eq(CustomStorage::getProductCategory, customStorage.getProductCategory())
                .eq(CustomStorage::getSpecificationModel, customStorage.getSpecificationModel());
        CustomStorage one = new CustomStorage();
        one.setTaxInclusiveUnitPrice(procurementDto.getTaxInclusiveUnitPrice());
        one.setTaxInclusiveTotalPrice(procurementDto.getTaxInclusiveTotalPrice());
        return customStorageMapper.update(one,customStorageLambdaQueryWrapper);
    }
    @Override
    public BigDecimal getProcurementAmount(Long salesProductId) {
        LambdaQueryWrapper<ProcurementRecordStorage> procurementRecordStorageLambdaQueryWrapper = new LambdaQueryWrapper<>();
        procurementRecordStorageLambdaQueryWrapper.eq(ProcurementRecordStorage::getSalesLedgerProductId, salesProductId)
                .eq(ProcurementRecordStorage::getType, 2);
        List<ProcurementRecordStorage> procurementRecordStorages = procurementRecordMapper.selectList(procurementRecordStorageLambdaQueryWrapper);
        if(CollectionUtils.isEmpty( procurementRecordStorages)){
            return BigDecimal.ZERO;
        }
        return procurementRecordStorages.stream()
                .map(ProcurementRecordStorage::getInboundNum)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    @Override
    public int add(ProcurementAddDto procurementDto) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        // 批量新增