Subversion Repositories SmartDukaan

Rev

Rev 35630 | Rev 35649 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 35630 Rev 35632
Line 27... Line 27...
27
import com.spice.profitmandi.dao.repository.dtr.*;
27
import com.spice.profitmandi.dao.repository.dtr.*;
28
import com.spice.profitmandi.dao.repository.fofo.PartnerDailyInvestmentRepository;
28
import com.spice.profitmandi.dao.repository.fofo.PartnerDailyInvestmentRepository;
29
import com.spice.profitmandi.dao.repository.fofo.PurchaseRepository;
29
import com.spice.profitmandi.dao.repository.fofo.PurchaseRepository;
30
import com.spice.profitmandi.dao.repository.fofo.RbmRatingRepository;
30
import com.spice.profitmandi.dao.repository.fofo.RbmRatingRepository;
31
import com.spice.profitmandi.dao.repository.fofo.SalesRatingRepository;
31
import com.spice.profitmandi.dao.repository.fofo.SalesRatingRepository;
-
 
32
import com.spice.profitmandi.dao.repository.transaction.LoanRepository;
32
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
33
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
33
import com.spice.profitmandi.dao.repository.user.AddressRepository;
34
import com.spice.profitmandi.dao.repository.user.AddressRepository;
34
import com.spice.profitmandi.service.AuthService;
35
import com.spice.profitmandi.service.AuthService;
35
import com.spice.profitmandi.service.NotificationService;
36
import com.spice.profitmandi.service.NotificationService;
36
import com.spice.profitmandi.service.PartnerCollectionService;
37
import com.spice.profitmandi.service.PartnerCollectionService;
Line 183... Line 184...
183
    LeadDetailRepository leadDetailRepository;
184
    LeadDetailRepository leadDetailRepository;
184
 
185
 
185
    @Autowired
186
    @Autowired
186
    PurchaseRepository purchaseRepository;
187
    PurchaseRepository purchaseRepository;
187
 
188
 
-
 
189
    @Autowired
-
 
190
    private LoanRepository loanRepository;
-
 
191
 
188
    @RequestMapping(value = "/lead", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
192
    @RequestMapping(value = "/lead", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
189
    @ApiImplicitParams({
193
    @ApiImplicitParams({
190
            @ApiImplicitParam(name = "Auth-Token", value = "Auth-Token", required = true, dataType = "string", paramType = "header")})
194
            @ApiImplicitParam(name = "Auth-Token", value = "Auth-Token", required = true, dataType = "string", paramType = "header")})
191
 
195
 
192
    public ResponseEntity<?> LeadUser(@RequestBody CreateRefferalRequest createRefferalRequest) throws Exception {
196
    public ResponseEntity<?> LeadUser(@RequestBody CreateRefferalRequest createRefferalRequest) throws Exception {
Line 824... Line 828...
824
    @ApiImplicitParams({@ApiImplicitParam(name = "Auth-Token", value = "Auth-Token", required = true, dataType = "string", paramType = "header")})
828
    @ApiImplicitParams({@ApiImplicitParam(name = "Auth-Token", value = "Auth-Token", required = true, dataType = "string", paramType = "header")})
825
    public ResponseEntity<?> getPartnerTarget(HttpServletRequest request, @RequestParam String
829
    public ResponseEntity<?> getPartnerTarget(HttpServletRequest request, @RequestParam String
826
            gmailId, @RequestParam String dayValue, @RequestParam ActivationType activationType) throws
830
            gmailId, @RequestParam String dayValue, @RequestParam ActivationType activationType) throws
827
            ProfitMandiBusinessException {
831
            ProfitMandiBusinessException {
828
 
832
 
-
 
833
        long startTime = System.currentTimeMillis();
-
 
834
        long lapTime = startTime;
-
 
835
 
829
        AuthUser authUser = authRepository.selectByGmailId(gmailId);
836
        AuthUser authUser = authRepository.selectByGmailId(gmailId);
-
 
837
        LOGGER.info("PERF: selectByGmailId took {} ms", System.currentTimeMillis() - lapTime);
-
 
838
        lapTime = System.currentTimeMillis();
-
 
839
 
830
        Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();
840
        // Optimized: get partner IDs only for this specific user instead of ALL users
831
        Set<Integer> fofoIds = storeGuyMap.get(authUser.getEmailId());
841
        Set<Integer> fofoIds = csService.getPartnerIdsByAuthUserId(authUser.getId());
-
 
842
        LOGGER.info("PERF: getPartnerIdsByAuthUserId took {} ms", System.currentTimeMillis() - lapTime);
-
 
843
        lapTime = System.currentTimeMillis();
832
        List<String> brands = Arrays.asList("Vivo", "Samsung", "Oppo", "Itel", "Almost New", "Others");
844
        List<String> brands = Arrays.asList("Vivo", "Samsung", "Oppo", "Itel", "Almost New", "Others");
833
 
845
 
834
        float totalPartnerTargetSecondary = 0;
846
        float totalPartnerTargetSecondary = 0;
835
        float totalPartnerTargetCollection = 0;
847
        float totalPartnerTargetCollection = 0;
836
        float totalPartnerAchievementSecondary = 0;
848
        float totalPartnerAchievementSecondary = 0;
837
        float totalPartnerAchievementCollection = 0;
849
        float totalPartnerAchievementCollection = 0;
838
        TargetModel tm = new TargetModel();
850
        TargetModel tm = new TargetModel();
839
        Map<Integer, PartnerDailyInvestment> partnerDailyInvestmentMap = new HashMap<>();
851
        Map<Integer, PartnerDailyInvestment> partnerDailyInvestmentMap = new HashMap<>();
840
        Map<Integer, Long> partnerTicketCount = ticketRepository.selectAllOpenTicketsGroupByRetailer();
852
        Map<Integer, Long> partnerTicketCount = new HashMap<>(); // Will be populated after we have fofoIdList
841
 
-
 
842
        LOGGER.info("partnerTicketCount {}", partnerTicketCount);
-
 
843
 
853
 
844
        List<PartnerTargetAchievementModel> ptams = new ArrayList<>();
854
        List<PartnerTargetAchievementModel> ptams = new ArrayList<>();
845
 
855
 
846
        if (fofoIds != null && fofoIds.size() > 0) {
856
        if (fofoIds != null && fofoIds.size() > 0) {
847
            LOGGER.info("fofoIds {}", fofoIds);
857
            LOGGER.info("fofoIds {}", fofoIds);
848
            List<Integer> fofoIdList = fofoStoreRepository.selectByRetailerIds(new ArrayList<>(fofoIds)).stream()
858
            List<Integer> fofoIdList = fofoStoreRepository.selectByRetailerIds(new ArrayList<>(fofoIds)).stream()
849
                    .filter(x -> (!x.isInternal() && (activationType == null || x.getActivationType().equals(activationType))))
859
                    .filter(x -> (!x.isInternal() && (activationType == null || x.getActivationType().equals(activationType))))
850
                    .map(x -> x.getId()).collect(Collectors.toList());
860
                    .map(x -> x.getId()).collect(Collectors.toList());
-
 
861
            LOGGER.info("PERF: selectByRetailerIds took {} ms", System.currentTimeMillis() - lapTime);
-
 
862
            lapTime = System.currentTimeMillis();
851
            LOGGER.info("fofoIdList {}", fofoIdList);
863
            LOGGER.info("fofoIdList size: {}", fofoIdList.size());
-
 
864
 
-
 
865
            // Optimized: fetch ticket counts only for specific fofoIds instead of all retailers
-
 
866
            if (!fofoIdList.isEmpty()) {
-
 
867
                partnerTicketCount = ticketRepository.selectOpenTicketsCountByFofoIds(fofoIdList);
-
 
868
            }
-
 
869
            LOGGER.info("PERF: selectOpenTicketsCountByFofoIds took {} ms", System.currentTimeMillis() - lapTime);
-
 
870
            lapTime = System.currentTimeMillis();
852
            LocalDateTime startDate = LocalDate.now().atStartOfDay();
871
            LocalDateTime startDate = LocalDate.now().atStartOfDay();
853
 
872
 
854
            if (dayValue.equals("previous")) {
873
            if (dayValue.equals("previous")) {
855
                startDate = LocalDate.now().minusDays(1).atStartOfDay();
874
                startDate = LocalDate.now().minusDays(1).atStartOfDay();
856
 
875
 
857
            }
876
            }
858
 
877
 
859
            if (fofoIdList.size() > 0) {
878
            if (fofoIdList.size() > 0) {
860
 
879
 
-
 
880
                // Fetch fofoIds with overdue loans (pending amount > 0 and created > 15 days ago)
-
 
881
                // Optimized: returns only fofoIds, not full Loan objects
-
 
882
                LocalDateTime fifteenDaysAgo = LocalDate.now().minusDays(15).atStartOfDay();
-
 
883
                Set<Integer> fofoIdsWithOverdueLoans = loanRepository.selectFofoIdsWithOverdueLoans(fofoIdList, fifteenDaysAgo);
-
 
884
                LOGGER.info("PERF: selectFofoIdsWithOverdueLoans took {} ms", System.currentTimeMillis() - lapTime);
-
 
885
                lapTime = System.currentTimeMillis();
-
 
886
 
-
 
887
                // Fetch fofoIds with MTD billing above threshold (20000)
-
 
888
                // Optimized: direct query on orders table instead of complex RBM query
-
 
889
                LocalDateTime mtdStartDate = LocalDate.now().withDayOfMonth(1).atStartOfDay();
-
 
890
                LocalDateTime mtdEndDate = LocalDate.now().plusDays(1).atStartOfDay();
-
 
891
                long billingThreshold = 20000L; // Same as RbmWeeklyBillingModel.BILLING_THRESHOLD
-
 
892
                Set<Integer> allMtdBilledFofoIds = orderRepository.selectFofoIdsWithMtdBillingAboveThreshold(
-
 
893
                        fofoIdList, mtdStartDate, mtdEndDate, billingThreshold);
-
 
894
                LOGGER.info("PERF: selectFofoIdsWithMtdBillingAboveThreshold took {} ms", System.currentTimeMillis() - lapTime);
-
 
895
                lapTime = System.currentTimeMillis();
-
 
896
 
861
                List<PartnerDailyInvestment> partnerDailyInvestments = partnerDailyInvestmentRepository.selectAll(fofoIdList, startDate.toLocalDate().minusDays(1));
897
                List<PartnerDailyInvestment> partnerDailyInvestments = partnerDailyInvestmentRepository.selectAll(fofoIdList, startDate.toLocalDate().minusDays(1));
-
 
898
                LOGGER.info("PERF: partnerDailyInvestmentRepository.selectAll took {} ms", System.currentTimeMillis() - lapTime);
-
 
899
                lapTime = System.currentTimeMillis();
862
 
900
 
863
                if (!partnerDailyInvestments.isEmpty()) {
901
                if (!partnerDailyInvestments.isEmpty()) {
864
                    partnerDailyInvestmentMap = partnerDailyInvestments.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
902
                    partnerDailyInvestmentMap = partnerDailyInvestments.stream().collect(Collectors.toMap(x -> x.getFofoId(), x -> x));
865
                }
903
                }
866
 
904
 
867
                Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
905
                // Optimized: fetch only specific fofoIds instead of all retailers
868
 
-
 
869
                Map<Integer, CustomRetailer> customRetailers = fofoIdList.stream().map(x -> customRetailerMap.get(x))
906
                Map<Integer, CustomRetailer> customRetailers = retailerService.getFofoRetailers(fofoIdList);
870
                        .filter(x -> x != null).collect(Collectors.toList()).stream()
907
                LOGGER.info("PERF: getFofoRetailers took {} ms", System.currentTimeMillis() - lapTime);
871
                        .collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
908
                lapTime = System.currentTimeMillis();
872
 
909
 
873
                List<Integer> remarkIds = partnerCollectionRemarkRepository.selectMaxRemarkId(fofoIdList);
910
                List<Integer> remarkIds = partnerCollectionRemarkRepository.selectMaxRemarkId(fofoIdList);
874
 
-
 
-
 
911
                LOGGER.info("PERF: selectMaxRemarkId took {} ms", System.currentTimeMillis() - lapTime);
875
                LOGGER.info("remarkIds {}", remarkIds);
912
                lapTime = System.currentTimeMillis();
876
 
913
 
877
                long todayCollectionCount = 0;
914
                long todayCollectionCount = 0;
878
                if (!remarkIds.isEmpty()) {
915
                if (!remarkIds.isEmpty()) {
879
                    todayCollectionCount = partnerCollectionRemarkRepository
916
                    todayCollectionCount = partnerCollectionRemarkRepository
880
                            .selectByAuthIdAndIds(authUser.getId(), remarkIds).stream()
917
                            .selectByAuthIdAndIds(authUser.getId(), remarkIds).stream()
881
                            .filter(x -> x.getCreateTimestamp().toLocalDate().equals(LocalDate.now()))
918
                            .filter(x -> x.getCreateTimestamp().toLocalDate().equals(LocalDate.now()))
882
                            .collect(Collectors.counting());
919
                            .collect(Collectors.counting());
883
 
920
 
884
                }
921
                }
-
 
922
                LOGGER.info("PERF: selectByAuthIdAndIds took {} ms", System.currentTimeMillis() - lapTime);
-
 
923
                lapTime = System.currentTimeMillis();
885
 
924
 
886
                Map<Integer, PartnerCollectionPlanModel> collectionMap = partnerCollectionService.getCollectionMap(fofoIdList, startDate);
925
                Map<Integer, PartnerCollectionPlanModel> collectionMap = partnerCollectionService.getCollectionMap(fofoIdList, startDate);
-
 
926
                LOGGER.info("PERF: getCollectionMap took {} ms", System.currentTimeMillis() - lapTime);
-
 
927
                lapTime = System.currentTimeMillis();
887
 
928
 
888
                Map<Integer, List<PartnerSecondaryPlanModel>> partnerSecondaryPlans = orderRepository
929
                Map<Integer, List<PartnerSecondaryPlanModel>> partnerSecondaryPlans = orderRepository
889
                        .selectPartnerSecondaryGroupByBrand(fofoIdList, startDate.toLocalDate()).stream()
930
                        .selectPartnerSecondaryGroupByBrand(fofoIdList, startDate.toLocalDate()).stream()
890
                        .collect(Collectors.groupingBy(x -> x.getFofoId()));
931
                        .collect(Collectors.groupingBy(x -> x.getFofoId()));
-
 
932
                LOGGER.info("PERF: selectPartnerSecondaryGroupByBrand took {} ms", System.currentTimeMillis() - lapTime);
-
 
933
                lapTime = System.currentTimeMillis();
891
 
934
 
892
                // Pre-fetch all AuthUsers that might be needed (instead of N+1 queries)
935
                // Pre-fetch all AuthUsers that might be needed (instead of N+1 queries)
893
                Set<Integer> allAuthIds = new HashSet<>();
936
                Set<Integer> allAuthIds = new HashSet<>();
894
                collectionMap.values().stream()
937
                collectionMap.values().stream()
895
                        .map(PartnerCollectionPlanModel::getAuthId)
938
                        .map(PartnerCollectionPlanModel::getAuthId)
Line 927... Line 970...
927
                        PartnerCollectionPlanModel collectionPlan = collectionMap.get(fofoId);
970
                        PartnerCollectionPlanModel collectionPlan = collectionMap.get(fofoId);
928
 
971
 
929
                        ptam.setRemark(collectionPlan.getRemark());
972
                        ptam.setRemark(collectionPlan.getRemark());
930
                        ptam.setMessage(collectionPlan.getMessage());
973
                        ptam.setMessage(collectionPlan.getMessage());
931
                        ptam.setRemarkTimestamp(collectionPlan.getRemarkTimestamp());
974
                        ptam.setRemarkTimestamp(collectionPlan.getRemarkTimestamp());
-
 
975
                        ptam.setRecordingUrl(collectionPlan.getRecordingUrl());
932
                        ptam.setRank(collectionPlan.getRank());
976
                        ptam.setRank(collectionPlan.getRank());
933
                        Integer authId = collectionPlan.getAuthId();
977
                        Integer authId = collectionPlan.getAuthId();
934
 
978
 
935
                        Map<Integer, String> rankColorMap = ProfitMandiConstants.Rank_Color_Map;
979
                        Map<Integer, String> rankColorMap = ProfitMandiConstants.Rank_Color_Map;
936
 
980
 
Line 1076... Line 1120...
1076
                            ptam.setTicketCount(0);
1120
                            ptam.setTicketCount(0);
1077
 
1121
 
1078
                        }
1122
                        }
1079
                    }
1123
                    }
1080
 
1124
 
-
 
1125
                    // Category Assignment Logic (Priority: PLAN_TODAY > CARRY_FORWARD > ZERO_BILLED > UNTOUCHED > NORMAL)
-
 
1126
                    // Check if partner has credit due (loans > 15 days with pending amount) - just a flag, doesn't affect sorting
-
 
1127
                    boolean hasCreditDue = fofoIdsWithOverdueLoans.contains(fofoId);
-
 
1128
                    ptam.setHasOverdue(hasCreditDue);
-
 
1129
 
-
 
1130
                    // Default rank to 5 (Normal) if no collection plan exists
-
 
1131
                    int rank = ptam.getRank() > 0 ? ptam.getRank() : 5;
-
 
1132
                    boolean hasZeroBilling = !allMtdBilledFofoIds.contains(fofoId);
-
 
1133
 
-
 
1134
                    // Assign category based on rank (overdue is just a flag, doesn't affect category)
-
 
1135
                    if (rank == 1) {
-
 
1136
                        ptam.setCategory("PLAN_TODAY");
-
 
1137
                        ptam.setCategoryPriority(1);
-
 
1138
                    } else if (rank == 2) {
-
 
1139
                        ptam.setCategory("CARRY_FORWARD");
-
 
1140
                        ptam.setCategoryPriority(2);
-
 
1141
                    } else if (hasZeroBilling && rank < 5) {
-
 
1142
                        // Zero billed only if NOT in normal category (rank 5+)
-
 
1143
                        // If rank is 1,2,3,4 and has zero billing, include in ZERO_BILLED
-
 
1144
                        ptam.setCategory("ZERO_BILLED");
-
 
1145
                        ptam.setCategoryPriority(3);
-
 
1146
                    } else if (rank == 3) {
-
 
1147
                        ptam.setCategory("UNTOUCHED");
-
 
1148
                        ptam.setCategoryPriority(4);
-
 
1149
                    } else {
-
 
1150
                        // rank 4 (future plan) and rank 5+ (normal) go to NORMAL
-
 
1151
                        // Also, zero billing with rank 5+ goes to NORMAL (not ZERO_BILLED)
-
 
1152
                        ptam.setCategory("NORMAL");
-
 
1153
                        ptam.setCategoryPriority(5);
-
 
1154
                    }
-
 
1155
 
1081
                    ptams.add(ptam);
1156
                    ptams.add(ptam);
1082
 
1157
 
1083
                }
1158
                }
1084
                List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId()).stream().collect(Collectors.toList());
1159
                List<Position> positions = positionRepository.selectPositionByAuthId(authUser.getId()).stream().collect(Collectors.toList());
1085
 
1160
 
Line 1118... Line 1193...
1118
                    filteredPtams = ptams;
1193
                    filteredPtams = ptams;
1119
                }
1194
                }
1120
                tm.setRBMAndL1(isRBMAndL1);
1195
                tm.setRBMAndL1(isRBMAndL1);
1121
                tm.setRBMAndNotL1(isRBMAndNotL1);
1196
                tm.setRBMAndNotL1(isRBMAndNotL1);
1122
                tm.setSales(isSales);
1197
                tm.setSales(isSales);
-
 
1198
 
-
 
1199
                // Calculate category counts
-
 
1200
                Map<String, Long> categoryCounts = filteredPtams.stream()
-
 
1201
                        .collect(Collectors.groupingBy(
-
 
1202
                                p -> p.getCategory() != null ? p.getCategory() : "NORMAL",
-
 
1203
                                Collectors.counting()));
-
 
1204
                // Count parties with overdue flag (independent of category)
1123
                /*tm.setTargetAchievement(filteredPtams.stream().sorted(Comparator.comparing(PartnerTargetAchievementModel::getRank))
1205
                tm.setOverdueCount((int) filteredPtams.stream().filter(PartnerTargetAchievementModel::isHasOverdue).count());
-
 
1206
                tm.setPlanTodayCount(categoryCounts.getOrDefault("PLAN_TODAY", 0L).intValue());
-
 
1207
                tm.setCarryForwardCount(categoryCounts.getOrDefault("CARRY_FORWARD", 0L).intValue());
-
 
1208
                tm.setZeroBilledCount(categoryCounts.getOrDefault("ZERO_BILLED", 0L).intValue());
-
 
1209
                tm.setUntouchedCount(categoryCounts.getOrDefault("UNTOUCHED", 0L).intValue());
-
 
1210
                tm.setNormalCount(categoryCounts.getOrDefault("NORMAL", 0L).intValue());
-
 
1211
 
-
 
1212
                // Sort by: 1) Partners with today's remark go to bottom of entire list
-
 
1213
                //          EXCEPT: NO_ANSWER remark older than 2 hours comes back to original position
-
 
1214
                //          2) Category Priority (PLAN_TODAY=1, CARRY_FORWARD=2, ZERO_BILLED=3, UNTOUCHED=4, NORMAL=5)
1124
                        .collect(Collectors.toList()));*/
1215
                //          3) Then by rank
-
 
1216
                LocalDateTime twoHoursAgo = LocalDateTime.now().minusHours(2);
1125
                tm.setTargetAchievement(filteredPtams.stream()
1217
                tm.setTargetAchievement(filteredPtams.stream()
1126
                        .sorted(Comparator
1218
                        .sorted(Comparator
1127
                                .comparing((PartnerTargetAchievementModel ptam) -> {
1219
                                .comparing((PartnerTargetAchievementModel p) -> {
-
 
1220
                                    if (p.getRemarkTimestamp() == null) {
-
 
1221
                                        return false; // No remark → comes first
-
 
1222
                                    }
1128
                                    LocalDate remarkDate = ptam.getRemarkTimestamp() != null
1223
                                    LocalDate remarkDate = p.getRemarkTimestamp().toLocalDate();
-
 
1224
                                    if (!remarkDate.equals(LocalDate.now())) {
-
 
1225
                                        return false; // Not today's remark → comes first
-
 
1226
                                    }
-
 
1227
                                    // Today's remark - check if NO_ANSWER and older than 2 hours
-
 
1228
                                    if (CollectionRemark.NO_ANSWER.equals(p.getRemark())
1129
                                            ? ptam.getRemarkTimestamp().toLocalDate()
1229
                                            && p.getRemarkTimestamp().isBefore(twoHoursAgo)) {
-
 
1230
                                        return false; // NO_ANSWER older than 2 hours → comes back up
1130
                                            : null;
1231
                                    }
1131
                                    return remarkDate != null && remarkDate.equals(LocalDate.now());
1232
                                    return true; // Other today's remarks → goes to bottom
1132
                                }) // false → comes first, true (today) → goes last
1233
                                }) // false → comes first, true → goes to bottom
-
 
1234
                                .thenComparing(PartnerTargetAchievementModel::getCategoryPriority)
1133
                                .thenComparing(PartnerTargetAchievementModel::getRank)
1235
                                .thenComparing(PartnerTargetAchievementModel::getRank)
1134
                        )
1236
                        )
1135
                        .collect(Collectors.toList()));
1237
                        .collect(Collectors.toList()));
1136
 
1238
 
1137
 
1239
 
1138
            }
1240
            }
1139
 
1241
 
1140
        }
1242
        }
-
 
1243
        LOGGER.info("PERF: Total getPartnerTarget took {} ms", System.currentTimeMillis() - startTime);
1141
        return responseSender.ok(tm);
1244
        return responseSender.ok(tm);
1142
 
1245
 
1143
    }
1246
    }
1144
 
1247
 
1145
    //TODO:Amit
1248
    //TODO:Amit