package com.ningdatech.carapi.report.manage;

import java.math.BigDecimal;
import java.math.RoundingMode;
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.BulkCementDirectReportSystemAuditInfo;
import com.ningdatech.carapi.report.model.entity.BulkCementDirectReportSystemAuditRecord;
import com.ningdatech.carapi.report.model.entity.BulkCementDirectReportSystemDataRelevance;
import com.ningdatech.carapi.report.model.entity.BulkCementTransferBulletin;
import com.ningdatech.carapi.report.model.po.ReqBulkCementTransferDataUploadPO;
import com.ningdatech.carapi.report.model.po.ReqDataUploadListPO;
import com.ningdatech.carapi.report.model.vo.ResBulkCementTransferDataUploadDetailVO;
import com.ningdatech.carapi.report.model.vo.ResDataUploadListVO;
import com.ningdatech.carapi.report.service.IBulkCementDirectReportSystemAuditInfoService;
import com.ningdatech.carapi.report.service.IBulkCementDirectReportSystemAuditRecordService;
import com.ningdatech.carapi.report.service.IBulkCementDirectReportSystemDataRelevanceService;
import com.ningdatech.carapi.report.service.IBulkCementTransferBulletinService;
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 BulkCementTransferBulletinManage {

    private final IBulkCementDirectReportSystemAuditRecordService auditRecordService;
    private final IBulkCementDirectReportSystemAuditInfoService auditInfoService;
    private final RegionsCacheHelper regionsCacheHelper;
    private final IBulkCementDirectReportSystemDataRelevanceService dataRelevanceService;
    private final IBulkCementTransferBulletinService bulkCementTransferBulletinService;
    private final CompaniesCacheHelper companiesCacheHelper;
    public PageVo<ResDataUploadListVO> dataUploadList(ReqDataUploadListPO req) {

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

        Page<BulkCementTransferBulletin> page = req.page();
        // 根据所属区域查出对应的中转库进出量数据上报记录
        LambdaQueryWrapper<BulkCementTransferBulletin> wrapper = Wrappers.lambdaQuery(BulkCementTransferBulletin.class);
        // 获取入参
        LocalDateTime reportStartMonth = req.getReportStartMonth();
        LocalDateTime reportEndMonth = req.getReportEndMonth();
        Integer auditStatus = req.getAuditStatus();
        wrapper.ge(Objects.nonNull(reportStartMonth), BulkCementTransferBulletin::getReportMonth, reportStartMonth)
                .le(Objects.nonNull(reportEndMonth), BulkCementTransferBulletin::getReportMonth, reportEndMonth)
                .eq(Objects.nonNull(auditStatus),BulkCementTransferBulletin::getAuditStatus,auditStatus)
                .eq(BulkCementTransferBulletin::getRegionId,regionId)
                .orderByDesc(BulkCementTransferBulletin::getReportMonth);
                //.isNotNull(BulkCementTransferBulletin::getAuditInfoId);
        bulkCementTransferBulletinService.page(page,wrapper);
        List<BulkCementTransferBulletin> records = page.getRecords();
        if (CollUtil.isEmpty(records)){
            return PageVo.empty();
        }
        // 获取审核信息
        List<Long> auditInfoIdList = records.stream().map(BulkCementTransferBulletin::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 bulkCementTransferDataUpload(ReqBulkCementTransferDataUploadPO 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);

            // 保存上报数据信息
            BulkCementTransferBulletin bulkCementTransferBulletin = new BulkCementTransferBulletin();
            // 区县的区域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.BULK_CEMENT_TRANSFER_BULLETIN.getCode()));
            // 判断当前地区当前上报月份数据是否已经存在,如果已经存在，删除原数据并更新市、省关联数据列表
            checkUploadData(reportMonth, regionId, cityData);
            Long dataId = req.getId();
            // 上报数据不为空，说明为重新提交
            if (Objects.nonNull(dataId)) {
                BulkCementTransferBulletin oldData = bulkCementTransferBulletinService.getById(dataId);
                VUtils.isTrue(Objects.isNull(oldData)).throwMessage("重新提交数据不存在!");
                // 更新市级关联数据
                updateCityData(cityData,oldData);
                // 删除被退回的数据
                bulkCementTransferBulletinService.removeById(oldData);
            }

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

            // 补充数据审核表信息
            BulkCementDirectReportSystemAuditRecord auditRecord = new BulkCementDirectReportSystemAuditRecord();
            assemblyAuditRecord(userDetail, bulkCementTransferBulletin.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.BULK_CEMENT_TRANSFER_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.setAuditStatus(DataUploadAuditStatusEnum.UNDER_AUDIT.getCode());
            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.BULK_CEMENT_TRANSFER_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.BULK_CEMENT_TRANSFER_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.BULK_CEMENT_TRANSFER_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.BULK_CEMENT_TRANSFER_BULLETIN.getCode());
        auditInfo.setCreateOn(LocalDateTime.now());
        auditInfo.setCreateBy(userDetail.getUserId());
        auditInfo.setUpdateOn(LocalDateTime.now());
        auditInfo.setUpdateBy(userDetail.getUserId());
    }

    private void assemblyData(ReqBulkCementTransferDataUploadPO req, UserInfoDetails userDetail, BulkCementTransferBulletin bulkCementTransferBulletin) {
        RegionDTO regionDto = regionsCacheHelper.getByRegionId(userDetail.getRegionId());
        String regionName = regionDto.getRegionName();
        // 单位名称改成了地区
        bulkCementTransferBulletin.setUnitName(regionName);
        bulkCementTransferBulletin.setLastMonthEndInventory(req.getLastMonthEndInventory());
        bulkCementTransferBulletin.setThisMonthIncomingStorage(req.getThisMonthIncomingStorage());
        bulkCementTransferBulletin.setCumulativeIncomingStorage(req.getCumulativeIncomingStorage());
        bulkCementTransferBulletin.setThisMonthOutgoingStorage(req.getThisMonthOutgoingStorage());
        bulkCementTransferBulletin.setCumulativeOutgoingStorage(req.getCumulativeOutgoingStorage());
        bulkCementTransferBulletin.setMonthEndInventory(req.getMonthEndInventory());
        bulkCementTransferBulletin.setMonthEndInventoryGrowthRate(req.getMonthEndInventoryGrowthRate());
        bulkCementTransferBulletin.setReportMonth(req.getReportMonth());
        bulkCementTransferBulletin.setCompanyId(userDetail.getCompanyId());
        bulkCementTransferBulletin.setRegionId(userDetail.getRegionId());
        bulkCementTransferBulletin.setCreateOn(LocalDateTime.now());
        bulkCementTransferBulletin.setCreateBy(userDetail.getUserId());
        bulkCementTransferBulletin.setUpdateOn(LocalDateTime.now());
        bulkCementTransferBulletin.setUpdateBy(userDetail.getUserId());
    }

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

    private void updateCityData(BulkCementDirectReportSystemDataRelevance cityData, BulkCementTransferBulletin bulkCementTransferBulletin) {
        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(bulkCementTransferBulletin.getId());
            }
        }
    }

    public ResBulkCementTransferDataUploadDetailVO getBulkCementTransferUploadData(ReqBulkCementTransferDataUploadPO req) {

        // 获取登录用户信息
        UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
        // 上月末库存
        BigDecimal lastMonthEndInventory = req.getLastMonthEndInventory();
        VUtils.isTrue(Objects.isNull(lastMonthEndInventory)).throwMessage("请传入上月末库存!");
        // 获取填报的数据
        // 本月进库量
        BigDecimal thisMonthIncomingStorage = req.getThisMonthIncomingStorage();
        // 本月出库量
        BigDecimal thisMonthOutgoingStorage = req.getThisMonthOutgoingStorage();
        LocalDateTime reportMonth = req.getReportMonth();
        Long regionId = userDetail.getRegionId();

        // 计算累计进库量、累计出库量、月末库存量、同比增长率
        // 获取上个月该地区的累计进库量、累计出库量
        LocalDateTime preReportMonth = reportMonth.minusMonths(1L);
        BulkCementTransferBulletin preBulkCementTransferBulletin = bulkCementTransferBulletinService.getOne(Wrappers.lambdaQuery(BulkCementTransferBulletin.class)
                .eq(BulkCementTransferBulletin::getRegionId, regionId)
                .eq(BulkCementTransferBulletin::getReportMonth, preReportMonth));
        VUtils.isTrue(Objects.isNull(preBulkCementTransferBulletin)).throwMessage("系统上个月数据不存在!");
        // 获取去年当前上报月份该地区的月末库存量
        LocalDateTime preYearReportMonth = preReportMonth.minusYears(1L).plusMonths(1L);
        BulkCementTransferBulletin preYearBulkCementTransferBulletin = bulkCementTransferBulletinService.getOne(Wrappers.lambdaQuery(BulkCementTransferBulletin.class)
                .eq(BulkCementTransferBulletin::getRegionId, regionId)
                .eq(BulkCementTransferBulletin::getReportMonth, preYearReportMonth));
        VUtils.isTrue(Objects.isNull(preYearBulkCementTransferBulletin)).throwMessage("系统去年该月数据不存在!");

        ResBulkCementTransferDataUploadDetailVO vo = new ResBulkCementTransferDataUploadDetailVO();
        vo.setLastMonthEndInventory(lastMonthEndInventory);
        vo.setThisMonthIncomingStorage(thisMonthIncomingStorage);
        vo.setThisMonthOutgoingStorage(thisMonthOutgoingStorage);

        if (Objects.nonNull(thisMonthIncomingStorage)) {
            // 累计进库量：本月进库量 + 上个月累计进库量
            BigDecimal preMonthCumulativeIncomingStorage = preBulkCementTransferBulletin.getCumulativeIncomingStorage();
            BigDecimal preMonCumInStorage = Objects.isNull(preMonthCumulativeIncomingStorage) ? BigDecimal.ZERO : preMonthCumulativeIncomingStorage;
            BigDecimal cumulativeIncomingStorage = thisMonthIncomingStorage.add(preMonCumInStorage);
            vo.setCumulativeIncomingStorage(cumulativeIncomingStorage);
        }

        if (Objects.nonNull(thisMonthOutgoingStorage)) {
            // 累计出库量: 本月出库量 + 上个月的累计出库量
            BigDecimal preMonthCumulativeOutgoingStorage = preBulkCementTransferBulletin.getCumulativeOutgoingStorage();
            BigDecimal preMonCumOutStorage = Objects.isNull(preMonthCumulativeOutgoingStorage) ? BigDecimal.ZERO : preMonthCumulativeOutgoingStorage;
            BigDecimal cumulativeOutgoingStorage = thisMonthOutgoingStorage.add(preMonCumOutStorage);
            vo.setCumulativeOutgoingStorage(cumulativeOutgoingStorage);
        }

        if (Objects.nonNull(thisMonthIncomingStorage) && Objects.nonNull(thisMonthOutgoingStorage)){
            // 月末库存量 = 上月末库存量 + 本月进库量 - 本月出库量
            BigDecimal monthEndInventory = lastMonthEndInventory.add(thisMonthIncomingStorage).subtract(thisMonthOutgoingStorage);
            vo.setMonthEndInventory(monthEndInventory);
            // 同比增长率 = （月末库存量 - 去年月末库存量）/ 去年月末库存量 * 100
            BigDecimal preYearMonthEndInventory = preYearBulkCementTransferBulletin.getMonthEndInventory();
            BigDecimal monthEndInventoryGrowthRate = monthEndInventory.subtract(preYearMonthEndInventory).divide(preYearMonthEndInventory, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
            vo.setMonthEndInventoryGrowthRate(monthEndInventoryGrowthRate);
        }
        return vo;
    }

    public BigDecimal getBulkCementTransferLastMonthData(ReqBulkCementTransferDataUploadPO 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);
        BulkCementTransferBulletin transferBulletin = bulkCementTransferBulletinService.getOne(Wrappers.lambdaQuery(BulkCementTransferBulletin.class)
                .eq(BulkCementTransferBulletin::getReportMonth, preReportMonth)
                .eq(BulkCementTransferBulletin::getRegionId, regionId));
        if (Objects.isNull(transferBulletin)){
            return BigDecimal.ZERO;
        }
        return transferBulletin.getLastMonthEndInventory();
    }
}
