package com.ningdatech.carapi.report.manage;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.NdDateUtils;
import com.ningdatech.basic.util.StrPool;
import com.ningdatech.carapi.car.vehicle.contants.VehicleContant;
import com.ningdatech.carapi.common.constant.UserRoleTypeEnum;
import com.ningdatech.carapi.common.contants.DefValConstants;
import com.ningdatech.carapi.report.constant.DataUploadAuditStatusEnum;
import com.ningdatech.carapi.report.constant.DataUploadAuditTypeEnum;
import com.ningdatech.carapi.report.constant.UploadDataTypeEnum;
import com.ningdatech.carapi.report.model.entity.*;
import com.ningdatech.carapi.report.model.po.ReqConcreteSupplyDataUploadPO;
import com.ningdatech.carapi.report.model.po.ReqDataUploadListPO;
import com.ningdatech.carapi.report.model.vo.ResConcreteSupplyDataUploadDetailVO;
import com.ningdatech.carapi.report.model.vo.ResConcreteSupplyRelatedDataVO;
import com.ningdatech.carapi.report.model.vo.ResDataUploadListVO;
import com.ningdatech.carapi.report.service.*;
import com.ningdatech.carapi.sys.entity.dto.CompanyDTO;
import com.ningdatech.carapi.sys.entity.dto.RegionDTO;
import com.ningdatech.carapi.sys.helper.CompaniesCacheHelper;
import com.ningdatech.carapi.sys.helper.RegionsCacheHelper;
import com.ningdatech.carapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.carapi.user.util.LoginUserUtil;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author CMM
 * @since 2023/09/28 11:15
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class ConcreteSupplyBulletinManage {

    private final IBulkCementDirectReportSystemAuditRecordService auditRecordService;
    private final IBulkCementDirectReportSystemAuditInfoService auditInfoService;
    private final RegionsCacheHelper regionsCacheHelper;
    private final IBulkCementDirectReportSystemDataRelevanceService dataRelevanceService;
    private final IConcreteSupplyBulletinService concreteSupplyBulletinService;
    private final IBulkCementDirectReportSystemUniversalIndexService universalIndexService;
    private final CompaniesCacheHelper companiesCacheHelper;

    public PageVo<ResDataUploadListVO> dataUploadList(ReqDataUploadListPO req) {

        UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
        Long regionId = userDetail.getRegionId();

        Page<ConcreteSupplyBulletin> page = req.page();
        // 根据所属区域查出对应的散装水泥供应量数据上报记录
        LambdaQueryWrapper<ConcreteSupplyBulletin> wrapper = Wrappers.lambdaQuery(ConcreteSupplyBulletin.class);
        // 获取入参
        LocalDateTime reportStartMonth = req.getReportStartMonth();
        LocalDateTime reportEndMonth = req.getReportEndMonth();
        Integer auditStatus = req.getAuditStatus();
        wrapper.ge(Objects.nonNull(reportStartMonth), ConcreteSupplyBulletin::getReportMonth, reportStartMonth)
                .le(Objects.nonNull(reportEndMonth), ConcreteSupplyBulletin::getReportMonth, reportEndMonth)
                .eq(Objects.nonNull(auditStatus),ConcreteSupplyBulletin::getAuditStatus,auditStatus)
                .eq(ConcreteSupplyBulletin::getRegionId,regionId)
                .orderByDesc(ConcreteSupplyBulletin::getReportMonth);
                //.isNotNull(ConcreteSupplyBulletin::getAuditInfoId);
        concreteSupplyBulletinService.page(page,wrapper);
        List<ConcreteSupplyBulletin> records = page.getRecords();
        if (CollUtil.isEmpty(records)){
            return PageVo.empty();
        }
        // 获取审核信息
        List<Long> auditInfoIdList = records.stream().map(ConcreteSupplyBulletin::getAuditInfoId).collect(Collectors.toList());
        Map<Long, BulkCementDirectReportSystemAuditInfo> auditInfoMap = auditInfoService.list(Wrappers.lambdaQuery(BulkCementDirectReportSystemAuditInfo.class).in(BulkCementDirectReportSystemAuditInfo::getId, auditInfoIdList))
                .stream().collect(Collectors.toMap(BulkCementDirectReportSystemAuditInfo::getId, v -> v));
        List<ResDataUploadListVO> resVos = records.stream().map(r -> {
            ResDataUploadListVO vo = new ResDataUploadListVO();
            LocalDateTime month = r.getReportMonth();
            String reportMonthStr = NdDateUtils.format(month, NdDateUtils.DEFAULT_MONTH_FORMAT);
            LocalDateTime reportMonth = LocalDateTimeUtil.parse(reportMonthStr, DateTimeFormatter.ofPattern(DatePattern.NORM_MONTH_PATTERN));
            vo.setRegionId(r.getRegionId());
            vo.setReportMonth(reportMonth);
            vo.setAuditDataId(r.getId());
            BulkCementDirectReportSystemAuditInfo auditInfo = auditInfoMap.get(r.getAuditInfoId());
            if (Objects.nonNull(auditInfo)) {
                vo.setAuditOpinion(auditInfo.getAuditOpinion());
            }
            vo.setAuditStatus(r.getAuditStatus());
            String desc = DataUploadAuditStatusEnum.getDescByCode(r.getAuditStatus());
            vo.setAuditStatusName(desc);
            vo.setCreateOn(r.getCreateOn());
            return vo;
        }).collect(Collectors.toList());
        return PageVo.of(resVos, page.getTotal());
    }

    @Transactional(rollbackFor = Exception.class)
    public String concreteSupplyDataUpload(ReqConcreteSupplyDataUploadPO req) {
        // 获取登录用户信息
        UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
        LocalDateTime reportMonth = req.getReportMonth();
        Long regionId = userDetail.getRegionId();

        // 如果登录用户为区县散办
        if (UserRoleTypeEnum.REGION_ADMIN_ROLE_ID.getId().equals(userDetail.getRoleId())) {

            VUtils.isTrue(Objects.isNull(reportMonth)).throwMessage("请选择上报月份!");

            // 提交市级审核申请
            BulkCementDirectReportSystemAuditInfo cityAuditInfo = new BulkCementDirectReportSystemAuditInfo();
            assemblyAuditInfo(cityAuditInfo, DataUploadAuditStatusEnum.UNDER_AUDIT, userDetail);
            cityAuditInfo.setAuditType(DataUploadAuditTypeEnum.CITY_AUDIT.getCode());
            auditInfoService.save(cityAuditInfo);

            // 保存上报数据信息
            ConcreteSupplyBulletin concreteSupplyBulletin = new ConcreteSupplyBulletin();
            // 区县的区域ID
            Long countryRegionId = userDetail.getRegionId();
            // 获取所在市的区域ID
            RegionDTO regionDto = regionsCacheHelper.getByRegionId(countryRegionId);
            Long parentId = regionDto.getParentId();
            // 判断上报月份所在市的关联数据不存在
            RegionDTO cityRegionDto = regionsCacheHelper.getByRegionId(parentId);
            BulkCementDirectReportSystemDataRelevance cityData = dataRelevanceService.getOne(Wrappers.lambdaQuery(BulkCementDirectReportSystemDataRelevance.class)
                    .eq(BulkCementDirectReportSystemDataRelevance::getRegionId, parentId)
                    .eq(BulkCementDirectReportSystemDataRelevance::getAuditType,DataUploadAuditTypeEnum.CITY_AUDIT.getCode())
                    .eq(BulkCementDirectReportSystemDataRelevance::getReportMonth, reportMonth)
                    .eq(BulkCementDirectReportSystemDataRelevance::getAuditDataType, UploadDataTypeEnum.CONCRETE_SUPPLY_BULLETIN.getCode()));
            // 判断当前地区当前上报月份数据是否已经存在,如果已经存在，删除原数据并更新市、省关联数据列表
            checkUploadData(reportMonth, regionId, cityData);
            Long dataId = req.getId();
            // 上报数据不为空，说明为重新提交
            if (Objects.nonNull(dataId)) {
                ConcreteSupplyBulletin oldData = concreteSupplyBulletinService.getById(dataId);
                VUtils.isTrue(Objects.isNull(oldData)).throwMessage("重新提交数据不存在!");
                // 更新市级关联数据
                updateCityData(cityData,oldData);
                // 删除被退回的数据
                concreteSupplyBulletinService.removeById(oldData);
            }

            assemblyData(req, userDetail, concreteSupplyBulletin);
            concreteSupplyBulletin.setAuditInfoId(cityAuditInfo.getId());
            concreteSupplyBulletin.setAuditStatus(DataUploadAuditStatusEnum.UNDER_AUDIT.getCode());
            concreteSupplyBulletinService.saveOrUpdate(concreteSupplyBulletin);

            // 补充数据审核表信息
            BulkCementDirectReportSystemAuditRecord auditRecord = new BulkCementDirectReportSystemAuditRecord();
            assemblyAuditRecord(userDetail, concreteSupplyBulletin.getId(), cityAuditInfo.getId(), auditRecord);
            auditRecord.setReportMonth(reportMonth);
            auditRecord.setAuditType(DataUploadAuditTypeEnum.CITY_AUDIT.getCode());
            auditRecordService.save(auditRecord);

            // 补充所在市的关联数据信息
            if (Objects.isNull(cityData)) {
                BulkCementDirectReportSystemDataRelevance cityRelevanceData = new BulkCementDirectReportSystemDataRelevance();
                assemblyRelevanceData(userDetail, reportMonth, cityRelevanceData);
                cityRelevanceData.setRegionId(parentId);
                // 获取所在市散装中心所属的管理企业ID
                CompanyDTO companyDto = companiesCacheHelper.getByName(cityRegionDto.getRegionName() + VehicleContant.ADMIN_COMPANY_NAME);
                if (Objects.nonNull(companyDto)) {
                    cityRelevanceData.setCompanyId(companyDto.getId());
                }
                cityRelevanceData.setAuditType(DataUploadAuditTypeEnum.CITY_AUDIT.getCode());
                cityRelevanceData.setAuditDataType(UploadDataTypeEnum.CONCRETE_SUPPLY_BULLETIN.getCode());
                // 有新上报的数据，就更新关联数据状态为未上报
                cityRelevanceData.setAuditStatus(DataUploadAuditStatusEnum.NOT_REPORT.getCode());
                dataRelevanceService.saveOrUpdate(cityRelevanceData);
            }

        }
        // 如果登录用户是市级散办,更新审核状态(未上报、被退回)为审核中，并提交省级审核信息和审核记录
        else if (UserRoleTypeEnum.BULK_CEMENT_ADMIN_ROLE_ID.getId().equals(userDetail.getRoleId())) {

            Long relevanceDataId = req.getId();
            VUtils.isTrue(Objects.isNull(relevanceDataId)).throwMessage("请传入关联数据ID!");

            // 提交省级审核申请
            BulkCementDirectReportSystemAuditInfo provinceAuditInfo = new BulkCementDirectReportSystemAuditInfo();
            assemblyAuditInfo(provinceAuditInfo, DataUploadAuditStatusEnum.UNDER_AUDIT, userDetail);
            provinceAuditInfo.setAuditType(DataUploadAuditTypeEnum.PROVINCE_AUDIT.getCode());
            auditInfoService.save(provinceAuditInfo);

            // 更新市级关联数据审核状态为审核中
            BulkCementDirectReportSystemDataRelevance cityRelevanceData = dataRelevanceService.getById(relevanceDataId);
            VUtils.isTrue(Objects.isNull(cityRelevanceData)).throwMessage("数据不存在!");
            // 关联审核信息ID
            cityRelevanceData.setUnitResponsiblePerson(req.getUnitResponsiblePerson());
            cityRelevanceData.setPreparer(req.getPreparer());
            cityRelevanceData.setReviewer(req.getReviewer());
            cityRelevanceData.setSubmissionDate(req.getSubmissionDate());
            cityRelevanceData.setAuditInfoId(provinceAuditInfo.getId());
            cityRelevanceData.setAuditStatus(DataUploadAuditStatusEnum.UNDER_AUDIT.getCode());
            cityRelevanceData.setUpdateOn(LocalDateTime.now());
            cityRelevanceData.setUpdateBy(userDetail.getUserId());
            cityRelevanceData.setUnitResponsiblePerson(req.getUnitResponsiblePerson());
            cityRelevanceData.setPreparer(req.getPreparer());
            cityRelevanceData.setReviewer(req.getReviewer());
            cityRelevanceData.setSubmissionDate(req.getSubmissionDate());
            dataRelevanceService.updateById(cityRelevanceData);

            // 判断上报月份省关联数据是否存在
            BulkCementDirectReportSystemDataRelevance provinceData = dataRelevanceService.getOne(Wrappers.lambdaQuery(BulkCementDirectReportSystemDataRelevance.class)
                    .eq(BulkCementDirectReportSystemDataRelevance::getRegionId, DefValConstants.ZJREGION_ID)
                    .eq(BulkCementDirectReportSystemDataRelevance::getAuditType,DataUploadAuditTypeEnum.PROVINCE_AUDIT.getCode())
                    .eq(BulkCementDirectReportSystemDataRelevance::getReportMonth, reportMonth)
                    .eq(BulkCementDirectReportSystemDataRelevance::getAuditDataType, UploadDataTypeEnum.CONCRETE_SUPPLY_BULLETIN.getCode()));
            // 如果上报月份省级关联数据不存在
            // 补充省散办关联数据信息
            if (Objects.isNull(provinceData)) {
                BulkCementDirectReportSystemDataRelevance provinceRelevanceData = new BulkCementDirectReportSystemDataRelevance();
                assemblyRelevanceData(userDetail, reportMonth, provinceRelevanceData);
                provinceRelevanceData.setAuditInfoId(provinceAuditInfo.getId());
                provinceRelevanceData.setRegionId(DefValConstants.ZJREGION_ID);
                provinceRelevanceData.setAuditType(DataUploadAuditTypeEnum.PROVINCE_AUDIT.getCode());
                // 获取省散装中心所属的管理企业ID
                CompanyDTO companyDto = companiesCacheHelper.getByName(DefValConstants.PROVINCE + VehicleContant.ADMIN_COMPANY_NAME);
                if (Objects.nonNull(companyDto)) {
                    provinceRelevanceData.setCompanyId(companyDto.getId());
                }
                provinceRelevanceData.setAuditDataType(UploadDataTypeEnum.CONCRETE_SUPPLY_BULLETIN.getCode());
                provinceRelevanceData.setAuditStatus(DataUploadAuditStatusEnum.UNDER_AUDIT.getCode());
                dataRelevanceService.save(provinceRelevanceData);
            }

            // 创建省级审核记录
            BulkCementDirectReportSystemAuditRecord provinceAuditRecord = new BulkCementDirectReportSystemAuditRecord();
            assemblyAuditRecord(userDetail, cityRelevanceData.getId(), provinceAuditInfo.getId(), provinceAuditRecord);
            provinceAuditRecord.setReportMonth(cityRelevanceData.getReportMonth());
            provinceAuditRecord.setAuditType(DataUploadAuditTypeEnum.PROVINCE_AUDIT.getCode());
            auditRecordService.save(provinceAuditRecord);
        }

        return "上报成功!";
    }

    private void assemblyRelevanceData(UserInfoDetails userDetail, LocalDateTime reportMonth, BulkCementDirectReportSystemDataRelevance relevanceData) {
        relevanceData.setReportMonth(reportMonth);
        relevanceData.setCreateOn(LocalDateTime.now());
        relevanceData.setCreateBy(userDetail.getUserId());
        relevanceData.setUpdateOn(LocalDateTime.now());
        relevanceData.setUpdateBy(userDetail.getUserId());
        relevanceData.setLastUpdateTime(LocalDateTime.now());
    }
    private void assemblyAuditRecord(UserInfoDetails userDetail, Long auditDataId, Long auditInfoId, BulkCementDirectReportSystemAuditRecord auditRecord) {
        auditRecord.setAuditDataId(auditDataId);
        auditRecord.setAuditInfoId(auditInfoId);
        auditRecord.setAuditStatus(DataUploadAuditStatusEnum.UNDER_AUDIT.getCode());
        auditRecord.setAuditDataType(UploadDataTypeEnum.CONCRETE_SUPPLY_BULLETIN.getCode());
        auditRecord.setCompanyId(userDetail.getCompanyId());
        auditRecord.setRegionId(userDetail.getRegionId());
        auditRecord.setCreateOn(LocalDateTime.now());
        auditRecord.setCreateBy(userDetail.getUserId());
        auditRecord.setUpdateOn(LocalDateTime.now());
        auditRecord.setUpdateBy(userDetail.getUserId());
    }

    private void assemblyAuditInfo(BulkCementDirectReportSystemAuditInfo auditInfo, DataUploadAuditStatusEnum underAudit, UserInfoDetails userDetail) {
        auditInfo.setAuditStatus(underAudit.getCode());
        auditInfo.setAuditDataType(UploadDataTypeEnum.CONCRETE_SUPPLY_BULLETIN.getCode());
        auditInfo.setCreateOn(LocalDateTime.now());
        auditInfo.setCreateBy(userDetail.getUserId());
        auditInfo.setUpdateOn(LocalDateTime.now());
        auditInfo.setUpdateBy(userDetail.getUserId());
    }

    private void assemblyData(ReqConcreteSupplyDataUploadPO req, UserInfoDetails userDetail, ConcreteSupplyBulletin concreteSupplyBulletin) {
        RegionDTO regionDto = regionsCacheHelper.getByRegionId(userDetail.getRegionId());
        String regionName = regionDto.getRegionName();
        // 单位名称改成了地区
        concreteSupplyBulletin.setUnitName(regionName);
        concreteSupplyBulletin.setThreeCategoryGuidGoal(req.getThreeCategoryGuidGoal());
        concreteSupplyBulletin.setProductionCompanyNums(req.getProductionCompanyNums());
        concreteSupplyBulletin.setAnnualDesignProductionCapacity(req.getAnnualDesignProductionCapacity());
        concreteSupplyBulletin.setThisMonthOutput(req.getThisMonthOutput());
        concreteSupplyBulletin.setAccumulativeOutput(req.getAccumulativeOutput());
        concreteSupplyBulletin.setThisMonthCementUsage(req.getThisMonthCementUsage());
        concreteSupplyBulletin.setCementAccumulativeUsage(req.getCementAccumulativeUsage());
        concreteSupplyBulletin.setThisMonthWasteUtilization(req.getThisMonthWasteUtilization());
        concreteSupplyBulletin.setAccumulativeWasteUtilization(req.getAccumulativeWasteUtilization());
        concreteSupplyBulletin.setReportMonth(req.getReportMonth());
        concreteSupplyBulletin.setCompanyId(userDetail.getCompanyId());
        concreteSupplyBulletin.setUnitResponsiblePerson(req.getUnitResponsiblePerson());
        concreteSupplyBulletin.setPreparer(req.getPreparer());
        concreteSupplyBulletin.setReviewer(req.getReviewer());
        concreteSupplyBulletin.setSubmissionDate(req.getSubmissionDate());
        concreteSupplyBulletin.setRegionId(userDetail.getRegionId());
        concreteSupplyBulletin.setCreateOn(LocalDateTime.now());
        concreteSupplyBulletin.setCreateBy(userDetail.getUserId());
        concreteSupplyBulletin.setUpdateOn(LocalDateTime.now());
        concreteSupplyBulletin.setUpdateBy(userDetail.getUserId());
        concreteSupplyBulletin.setRemark(req.getRemark());
    }

    private void checkUploadData(LocalDateTime reportMonth, Long regionId, BulkCementDirectReportSystemDataRelevance cityData) {
        ConcreteSupplyBulletin concreteSupplyBulletin = concreteSupplyBulletinService.getOne(Wrappers.lambdaQuery(ConcreteSupplyBulletin.class)
                .eq(ConcreteSupplyBulletin::getRegionId, regionId)
                .eq(ConcreteSupplyBulletin::getReportMonth, reportMonth));
        // 判断审核状态，如果审核通过，更新审核通过的数据
        if (Objects.nonNull(concreteSupplyBulletin) &&
                DataUploadAuditStatusEnum.AUDIT_PASS.getCode().equals(concreteSupplyBulletin.getAuditStatus())){
            updateCityData(cityData,concreteSupplyBulletin);
            concreteSupplyBulletinService.removeById(concreteSupplyBulletin);
        }
    }

    private void updateCityData(BulkCementDirectReportSystemDataRelevance cityData, ConcreteSupplyBulletin concreteSupplyBulletin) {
        if (Objects.nonNull(cityData)) {
            String auditDataIdList = cityData.getAuditDataIdList();
            if (StringUtils.isNotBlank(auditDataIdList)){
                List<Long> idList = Arrays.stream(auditDataIdList.split(StrPool.COMMA)).map(Long::valueOf).collect(Collectors.toList());
                // 将已经存在的该地区该上报月份的数据数据从关联表中删除
                idList.remove(concreteSupplyBulletin.getId());
            }
        }
    }

    public ResConcreteSupplyDataUploadDetailVO getConcreteSupplyUploadData(ReqConcreteSupplyDataUploadPO req) {

        // 获取登录用户信息
        UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
        // 获取填报的数据
        BigDecimal threeCategoryGuidGoal = req.getThreeCategoryGuidGoal();
        Integer productionCompanyNums = req.getProductionCompanyNums();
        BigDecimal annualDesignProductionCapacity = req.getAnnualDesignProductionCapacity();

        BigDecimal thisMonthOutput = req.getThisMonthOutput();
        BigDecimal thisMonthCementUsage = req.getThisMonthCementUsage();
        BigDecimal thisMonthWasteUtilization = req.getThisMonthWasteUtilization();
        String remark = req.getRemark();

        LocalDateTime reportMonth = req.getReportMonth();
        Long regionId = userDetail.getRegionId();

        // 计算实际产量(立方米)、使用散装水泥量(吨)、废弃物综合利用量(吨)
        // 获取上个月该地区的混凝土供应量数据
        LocalDateTime preReportMonth = reportMonth.minusMonths(1L);
        ConcreteSupplyBulletin preConcreteSupplyBulletin = concreteSupplyBulletinService.getOne(Wrappers.lambdaQuery(ConcreteSupplyBulletin.class)
                .eq(ConcreteSupplyBulletin::getRegionId, regionId)
                .eq(ConcreteSupplyBulletin::getReportMonth, preReportMonth));
        VUtils.isTrue(Objects.isNull(preConcreteSupplyBulletin)).throwMessage("系统上个月数据不存在!");

        ResConcreteSupplyDataUploadDetailVO vo = new ResConcreteSupplyDataUploadDetailVO();
        vo.setThreeCategoryGuidGoal(threeCategoryGuidGoal);
        vo.setProductionCompanyNums(productionCompanyNums);
        vo.setAnnualDesignProductionCapacity(annualDesignProductionCapacity);
        vo.setRemark(remark);

        if (Objects.nonNull(thisMonthOutput)) {
            // 累计产量：本月实际产量 + 上个月累计产量
            BigDecimal preMonthAccumulativeOutput = preConcreteSupplyBulletin.getAccumulativeOutput();
            BigDecimal preMonthAccOutput = Objects.isNull(preMonthAccumulativeOutput) ? BigDecimal.ZERO : preMonthAccumulativeOutput;
            BigDecimal accumulativeOutput = thisMonthOutput.add(preMonthAccOutput);
            vo.setAccumulativeOutput(accumulativeOutput);
        }

        if (Objects.nonNull(thisMonthCementUsage)) {
            // 累计使用散装水泥量: 本月使用散装水泥量 + 上个月累计使用散装水泥量
            BigDecimal preMonthCementAccumulativeUsage = preConcreteSupplyBulletin.getCementAccumulativeUsage();
            BigDecimal preMonthCementAccUsage = Objects.isNull(preMonthCementAccumulativeUsage) ? BigDecimal.ZERO : preMonthCementAccumulativeUsage;
            BigDecimal cementAccumulativeUsage = thisMonthCementUsage.add(preMonthCementAccUsage);
            vo.setCementAccumulativeUsage(cementAccumulativeUsage);
        }

        if (Objects.nonNull(thisMonthWasteUtilization)) {
            // 累计废弃物综合利用量: 本月废弃物综合利用量 + 上个月累计废弃物综合利用量
            BigDecimal preMonthAccumulativeWasteUtilization = preConcreteSupplyBulletin.getAccumulativeWasteUtilization();
            BigDecimal preMonthAccWasteUtilization = Objects.isNull(preMonthAccumulativeWasteUtilization) ? BigDecimal.ZERO : preMonthAccumulativeWasteUtilization;
            BigDecimal accumulativeWasteUtilization = thisMonthWasteUtilization.add(preMonthAccWasteUtilization);
            vo.setAccumulativeWasteUtilization(accumulativeWasteUtilization);
        }
        return vo;
    }

    public ResConcreteSupplyRelatedDataVO getConcreteSupplyRelatedData(ReqConcreteSupplyDataUploadPO po) {
        LocalDateTime reportMonth = po.getReportMonth();
        VUtils.isTrue(Objects.isNull(reportMonth)).throwMessage("请传入上报月份!");
        Long regionId = po.getRegionId();
        VUtils.isTrue(Objects.isNull(regionId)).throwMessage("请传入区域ID!");
        LocalDateTime preReportMonth = reportMonth.minusMonths(1);
        ConcreteSupplyBulletin preMonthConcreteSupplyBulletin = concreteSupplyBulletinService.getOne(Wrappers.lambdaQuery(ConcreteSupplyBulletin.class)
                .eq(ConcreteSupplyBulletin::getReportMonth, preReportMonth)
                .eq(ConcreteSupplyBulletin::getRegionId, regionId));
        int year = reportMonth.getYear();
        BulkCementDirectReportSystemUniversalIndex universalIndex = universalIndexService.getOne(Wrappers.lambdaQuery(BulkCementDirectReportSystemUniversalIndex.class)
                .eq(BulkCementDirectReportSystemUniversalIndex::getRegionId, regionId)
                .eq(BulkCementDirectReportSystemUniversalIndex::getYear, year));
        ResConcreteSupplyRelatedDataVO vo = new ResConcreteSupplyRelatedDataVO();
        if (Objects.nonNull(preMonthConcreteSupplyBulletin)) {
            vo.setProductionCompanyNums(preMonthConcreteSupplyBulletin.getProductionCompanyNums());
            vo.setAnnualDesignProductionCapacity(preMonthConcreteSupplyBulletin.getAnnualDesignProductionCapacity());
        }
        if (Objects.nonNull(universalIndex)) {
            vo.setThreeCategoryGuidGoal(universalIndex.getConcreteSupplyThreeCategoryGuidGoal());
        }else {
            vo.setThreeCategoryGuidGoal(BigDecimal.ZERO);
        }
        return vo;
    }
}
