# MonthlyReportWeeklySalesPlanServiceImpl.java

    package cloud.wconnect.workperformance.service.monthlyreport.impl;

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.ApproveStatusEnum;
    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.pojo.dto.UserDTO;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.workperformance.entity.monthlyreport.*;
    import cloud.wconnect.workperformance.mapper.monthlyreport.MonthlyReportWeeklySalesPlanMapper;
    import cloud.wconnect.workperformance.mapper.monthlyreport.MonthlyReportWeeklySalesPlanStatisticsTimeMapper;
    import cloud.wconnect.workperformance.pojo.dto.monthlyreport.weeklysalesplan.WeeklySalesPlanDTO;
    import cloud.wconnect.workperformance.pojo.dto.monthlyreport.weeklysalesplan.WeeklySalesPlanStatisticsDTO;
    import cloud.wconnect.workperformance.service.monthlyreport.IHandlePropertySettingChange;
    import cloud.wconnect.workperformance.service.monthlyreport.IMonthlyReportWeeklySalesPlanDetailService;
    import cloud.wconnect.workperformance.service.monthlyreport.IMonthlyReportWeeklySalesPlanService;
    import cloud.wconnect.workperformance.service.monthlyreport.IMonthlyReportWeeklySalesPlanStatisticsTimeService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.google.common.collect.Lists;
    import org.apache.commons.collections.CollectionUtils;
    import org.apache.commons.collections.MapUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.math.BigDecimal;
    import java.time.LocalDate;
    import java.util.*;
    import java.util.function.Function;
    import java.util.stream.Collectors;

    /**
     * <p>
     * 月报Weekly Sales Plan表 服务实现类
     * </p>
     *
     * @author lichen
     * @since 2024-12-09
     */
    @Service
    @DS("monthly_report")
    public class MonthlyReportWeeklySalesPlanServiceImpl extends ServiceImpl<MonthlyReportWeeklySalesPlanMapper, MonthlyReportWeeklySalesPlan> implements IMonthlyReportWeeklySalesPlanService, IHandlePropertySettingChange {

        @Autowired
        private IMonthlyReportWeeklySalesPlanDetailService monthlyReportWeeklySalesPlanDetailService;
        @Autowired
        private MonthlyReportWeeklySalesPlanStatisticsTimeMapper monthlyReportWeeklySalesPlanStatisticsTimeMapper;
        @Autowired
        private IMonthlyReportWeeklySalesPlanStatisticsTimeService monthlyReportWeeklySalesPlanStatisticsTimeService;
        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        private BeanMapper beanMapper;

        /**
         * 删除区域数据
         *
         * @param propertyDTO    资产DTO
         * @param monthlyReports 月报集合
         * @return void
         * @author lichen
         * @date 2024/12/9
         */
        @Override
        public void delete(PropertyDTO propertyDTO, List<MonthlyReport> monthlyReports) {
            List<Long> reportIds = monthlyReports.stream().map(MonthlyReport::getId).toList();
            if (CollectionUtils.isEmpty(reportIds)) return;
            remove(new LambdaQueryWrapper<MonthlyReportWeeklySalesPlan>()
                    .eq(MonthlyReportWeeklySalesPlan::getPropertyId, propertyDTO.getId())
                    .in(MonthlyReportWeeklySalesPlan::getReportId, reportIds));
        }

        /**
         * 初始化区域数据
         * 备注：按照先删后增的逻辑处理
         *
         * @param propertyDTO            资产DTO
         * @param monthlyReports         月报集合
         * @param areaId2AreaTypeConfigs 区域分类集合
         * @return void
         * @author lichen
         * @date 2024/12/9
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void init(PropertyDTO propertyDTO, List<MonthlyReport> monthlyReports, Map<Integer, List<AreaTypeConfig>> areaId2AreaTypeConfigs) {
            //删除月报的Weekly Sales Plan区域的数据
            delete(propertyDTO, monthlyReports);

            Map<String, MonthlyReport> yearMonth2MonthlyReport = monthlyReports.stream().collect(Collectors.toMap(monthlyReport -> {
                LocalDate localDate = LocalDate.of(monthlyReport.getYear(), monthlyReport.getMonth(), 1);
                return DateTimeUtils.localDateToStr(localDate, BaseConstant.DATE_FORMAT_YYYY_MM);
            }, Function.identity()));
            //获取月报时间的集合
            Set<String> yearMonthList = yearMonth2MonthlyReport.keySet();
            //查询Weekly Sales Plan明细
            Map<String, List<MonthlyReportWeeklySalesPlanDetail>> yearMonth2WeeklySalesPlanDetails = monthlyReportWeeklySalesPlanDetailService.listByYearMonth(propertyDTO.getId(), yearMonthList)
                    .stream().collect(Collectors.groupingBy(MonthlyReportWeeklySalesPlanDetail::getYearMonth));
            if (MapUtils.isNotEmpty(yearMonth2WeeklySalesPlanDetails)) {
                //审批中的状态集合
                ArrayList<Integer> approvingStatusList = Lists.newArrayList(ApproveStatusEnum.PENDING.getStatus(), ApproveStatusEnum.APPROVEING.getStatus());

                ArrayList<MonthlyReportWeeklySalesPlan> batchInsert = Lists.newArrayListWithExpectedSize(yearMonthList.size());
                for (Map.Entry<String, MonthlyReport> entry : yearMonth2MonthlyReport.entrySet()) {
                    String yearMonth = entry.getKey();
                    MonthlyReport monthlyReport = entry.getValue();

                    //获取指定月份的Weekly Sales Plan明细(按照指标itemName分组)
                    Map<String, List<MonthlyReportWeeklySalesPlanDetail>> itemName2WeeklySalesPlanDetails = yearMonth2WeeklySalesPlanDetails.getOrDefault(yearMonth, Collections.emptyList())
                            .stream().collect(Collectors.groupingBy(MonthlyReportWeeklySalesPlanDetail::getItemName));
                    itemName2WeeklySalesPlanDetails.forEach((itemName, weeklySalesPlanDetails) -> {
                        ArrayList<BigDecimal> monthlyGoalList = Lists.newArrayListWithCapacity(weeklySalesPlanDetails.size());
                        ArrayList<BigDecimal> approvingMtdActualList = Lists.newArrayListWithCapacity(weeklySalesPlanDetails.size());
                        ArrayList<BigDecimal> approvedMtdActualList = Lists.newArrayListWithCapacity(weeklySalesPlanDetails.size());

                        for (MonthlyReportWeeklySalesPlanDetail weeklySalesPlanDetail : weeklySalesPlanDetails) {
                            //收集目标值
                            if (Objects.nonNull(weeklySalesPlanDetail.getMonthlyGoal())) {
                                monthlyGoalList.add(weeklySalesPlanDetail.getMonthlyGoal());
                            }

                            if (Objects.nonNull(weeklySalesPlanDetail.getWeekOne())) {
                                //收集第一周审批中的MTD Actual
                                if (approvingStatusList.contains(weeklySalesPlanDetail.getWeekOneApproveStatus())) {
                                    approvingMtdActualList.add(weeklySalesPlanDetail.getWeekOne());
                                }
                                //收集第一周审批通过的MTD Actual
                                if (ApproveStatusEnum.APPROVED.getStatus() == weeklySalesPlanDetail.getWeekOneApproveStatus()) {
                                    approvedMtdActualList.add(weeklySalesPlanDetail.getWeekOne());
                                }
                            }

                            if (Objects.nonNull(weeklySalesPlanDetail.getWeekTwo())) {
                                //收集第二周审批中的MTD Actual
                                if (approvingStatusList.contains(weeklySalesPlanDetail.getWeekTwoApproveStatus())) {
                                    approvingMtdActualList.add(weeklySalesPlanDetail.getWeekTwo());
                                }
                                //收集第二周审批通过的MTD Actual
                                if (ApproveStatusEnum.APPROVED.getStatus() == weeklySalesPlanDetail.getWeekTwoApproveStatus()) {
                                    approvedMtdActualList.add(weeklySalesPlanDetail.getWeekTwo());
                                }
                            }

                            if (Objects.nonNull(weeklySalesPlanDetail.getWeekThree())) {
                                //收集第三周审批中的MTD Actual
                                if (approvingStatusList.contains(weeklySalesPlanDetail.getWeekThreeApproveStatus())) {
                                    approvingMtdActualList.add(weeklySalesPlanDetail.getWeekThree());
                                }
                                //收集第三周审批通过的MTD Actual
                                if (ApproveStatusEnum.APPROVED.getStatus() == weeklySalesPlanDetail.getWeekThreeApproveStatus()) {
                                    approvedMtdActualList.add(weeklySalesPlanDetail.getWeekThree());
                                }
                            }

                            if (Objects.nonNull(weeklySalesPlanDetail.getWeekFour())) {
                                //收集第四周审批中的MTD Actual
                                if (approvingStatusList.contains(weeklySalesPlanDetail.getWeekFourApproveStatus())) {
                                    approvingMtdActualList.add(weeklySalesPlanDetail.getWeekFour());
                                }
                                //累计第四周审批通过的MTD Actual
                                if (ApproveStatusEnum.APPROVED.getStatus() == weeklySalesPlanDetail.getWeekFourApproveStatus()) {
                                    approvedMtdActualList.add(weeklySalesPlanDetail.getWeekFour());
                                }
                            }

                            if (Objects.nonNull(weeklySalesPlanDetail.getWeekFive())) {
                                //收集第五周审批中的MTD Actual
                                if (approvingStatusList.contains(weeklySalesPlanDetail.getWeekFiveApproveStatus())) {
                                    approvingMtdActualList.add(weeklySalesPlanDetail.getWeekFive());
                                }
                                //收集第五周审批通过的MTD Actual
                                if (ApproveStatusEnum.APPROVED.getStatus() == weeklySalesPlanDetail.getWeekFiveApproveStatus()) {
                                    approvedMtdActualList.add(weeklySalesPlanDetail.getWeekFive());
                                }
                            }
                        }

                        //构建Weekly Sales Plan汇总的对象
                        MonthlyReportWeeklySalesPlan monthlyReportWeeklySalesPlan = new MonthlyReportWeeklySalesPlan();
                        monthlyReportWeeklySalesPlan.setTenantId(propertyDTO.getTenantId());
                        monthlyReportWeeklySalesPlan.setPropertyId(propertyDTO.getId());
                        monthlyReportWeeklySalesPlan.setReportId(monthlyReport.getId());
                        monthlyReportWeeklySalesPlan.setItemName(itemName);
                        monthlyReportWeeklySalesPlan.setMonthlyGoalSum(monthlyGoalList.stream().reduce(BigDecimal::add).orElse(null));
                        monthlyReportWeeklySalesPlan.setApprovingMtdActualSum(approvingMtdActualList.stream().reduce(BigDecimal::add).orElse(null));
                        monthlyReportWeeklySalesPlan.setApprovedMtdActualSum(approvedMtdActualList.stream().reduce(BigDecimal::add).orElse(null));
                        batchInsert.add(monthlyReportWeeklySalesPlan);
                    });
                }
                //批量新增
                saveBatch(batchInsert);
            }

            //月报id集合
            List<Long> reportIds = monthlyReports.stream().map(MonthlyReport::getId).toList();
            //当前时间
            long updateTime = DateTimeUtils.nowTimestamp();
            //更新指标统计时间
            monthlyReportWeeklySalesPlanStatisticsTimeMapper.saveOrUpdateByUnique(propertyDTO, reportIds, 0, updateTime);
        }

        /**
         * 查询Weekly Sales Plan区域数据
         *
         * @param propertyDTO 资产DTO
         * @param reportId    报告ID
         * @return cloud.wconnect.workperformance.pojo.dto.monthlyreport.weeklysalesplan.WeeklySalesPlanStatisticsDTO
         * @author lichen
         * @date 2024/12/9
         */
        @Override
        public WeeklySalesPlanStatisticsDTO listByReportId(PropertyDTO propertyDTO, Long reportId) {
            //查询Weekly Sales Plan指标统计时间
            MonthlyReportWeeklySalesPlanStatisticsTime monthlyReportWeeklySalesPlanStatisticsTime = monthlyReportWeeklySalesPlanStatisticsTimeService.getOne(
                    new LambdaQueryWrapper<MonthlyReportWeeklySalesPlanStatisticsTime>()
                            .eq(MonthlyReportWeeklySalesPlanStatisticsTime::getPropertyId, propertyDTO.getId())
                            .eq(MonthlyReportWeeklySalesPlanStatisticsTime::getReportId, reportId));

            Integer updateId = monthlyReportWeeklySalesPlanStatisticsTime.getUpdateId();
            String username = "";
            if (updateId > 0) {
                //更新人
                UserDTO userDTO = userInternalService.getOne(propertyDTO.getTenantId(), updateId);
                username = userDTO.getName();
            }

            //Weekly Sales Plan 指标数据集合
            List<MonthlyReportWeeklySalesPlan> monthlyReportWeeklySalesPlans = list(new LambdaQueryWrapper<MonthlyReportWeeklySalesPlan>()
                    .eq(MonthlyReportWeeklySalesPlan::getPropertyId, propertyDTO.getId())
                    .eq(MonthlyReportWeeklySalesPlan::getReportId, reportId));
            return new WeeklySalesPlanStatisticsDTO(monthlyReportWeeklySalesPlanStatisticsTime.getUpdateId(), monthlyReportWeeklySalesPlanStatisticsTime.getUpdateTime(),
                    username, beanMapper.mapList(monthlyReportWeeklySalesPlans, WeeklySalesPlanDTO.class));
        }
    }