Subversion Repositories SmartDukaan

Rev

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

Rev 37011 Rev 37012
Line 1326... Line 1326...
1326
 
1326
 
1327
        long calledCount = calledFofoIds.size() + calledNumbersWithoutFofoId.size();
1327
        long calledCount = calledFofoIds.size() + calledNumbersWithoutFofoId.size();
1328
        return new long[]{calledCount, totalRecordingCalls, uniqueRecordingNumbers.size()};
1328
        return new long[]{calledCount, totalRecordingCalls, uniqueRecordingNumbers.size()};
1329
    }
1329
    }
1330
 
1330
 
-
 
1331
    // Matches "Missed", "MISSED", "No Answer", "NO_ANSWER", "no-answer" etc.
-
 
1332
    // Kommuno currently emits "Missed" — kept liberal so we're covered if the tag changes.
-
 
1333
    private static boolean isMissedCustomerStatus(String status) {
-
 
1334
        if (status == null) return false;
-
 
1335
        String s = status.trim().toLowerCase().replace('_', ' ').replace('-', ' ').replaceAll("\\s+", " ");
-
 
1336
        return s.equals("missed") || s.equals("no answer") || s.equals("noanswer");
-
 
1337
    }
-
 
1338
 
1331
    public List<RbmCallTargetModel> getRbmCallTargetModels(LocalDate queryDate) throws Exception {
1339
    public List<RbmCallTargetModel> getRbmCallTargetModels(LocalDate queryDate) throws Exception {
1332
        long methodStart = System.currentTimeMillis();
1340
        long methodStart = System.currentTimeMillis();
1333
        List<RbmCallTargetModel> rbmCallTargetModels = new ArrayList<>();
1341
        List<RbmCallTargetModel> rbmCallTargetModels = new ArrayList<>();
1334
 
1342
 
1335
        // Get all RBM positions (L1 and L2)
1343
        // Get all RBM positions (L1 and L2)
Line 1687... Line 1695...
1687
            List<AgentCallLog> l1Logs = callLogsByAuthId.get((long) rbmAuthId);
1695
            List<AgentCallLog> l1Logs = callLogsByAuthId.get((long) rbmAuthId);
1688
            long[] callStats = getCallStatsFromLogs(l1Logs, mobileToFofoIdMap);
1696
            long[] callStats = getCallStatsFromLogs(l1Logs, mobileToFofoIdMap);
1689
            targetModel.setValueTargetAchieved(callStats[0]);
1697
            targetModel.setValueTargetAchieved(callStats[0]);
1690
            targetModel.setTotalRecordingCalls(callStats[1]);
1698
            targetModel.setTotalRecordingCalls(callStats[1]);
1691
            targetModel.setUniqueRecordingCalls(callStats[2]);
1699
            targetModel.setUniqueRecordingCalls(callStats[2]);
-
 
1700
            targetModel.setTriedUniqueCalls(computeUniqueTriedCount(l1Logs));
1692
 
1701
 
1693
            // Keep todayRemarks for movedToFuture calculation AND for Tried calculation
1702
            // Keep todayRemarks for movedToFuture calculation
1694
            List<PartnerCollectionRemark> todayRemarks = remarksByAuthId.getOrDefault(rbmAuthId, Collections.emptyList());
1703
            List<PartnerCollectionRemark> todayRemarks = remarksByAuthId.getOrDefault(rbmAuthId, Collections.emptyList());
1695
            targetModel.setTriedUniqueCalls(computeUniqueTriedCount(l1Logs, mobileToFofoIdMap, todayRemarks));
-
 
1696
 
1704
 
1697
            // Moved to Future = Partners in Future Plan category who have a remark today
1705
            // Moved to Future = Partners in Future Plan category who have a remark today
1698
            // These are partners who were contacted today but moved to a future date
1706
            // These are partners who were contacted today but moved to a future date
1699
            Set<Integer> todayRemarkedFofoIds = todayRemarks.stream()
1707
            Set<Integer> todayRemarkedFofoIds = todayRemarks.stream()
1700
                    .map(PartnerCollectionRemark::getFofoId)
1708
                    .map(PartnerCollectionRemark::getFofoId)
Line 1844... Line 1852...
1844
            List<AgentCallLog> l2Logs = callLogsByAuthId.get((long) l2AuthId);
1852
            List<AgentCallLog> l2Logs = callLogsByAuthId.get((long) l2AuthId);
1845
            long[] l2CallStats = getCallStatsFromLogs(l2Logs, mobileToFofoIdMap);
1853
            long[] l2CallStats = getCallStatsFromLogs(l2Logs, mobileToFofoIdMap);
1846
            l2Model.setValueTargetAchieved(l2CallStats[0]);
1854
            l2Model.setValueTargetAchieved(l2CallStats[0]);
1847
            l2Model.setTotalRecordingCalls(l2CallStats[1]);
1855
            l2Model.setTotalRecordingCalls(l2CallStats[1]);
1848
            l2Model.setUniqueRecordingCalls(l2CallStats[2]);
1856
            l2Model.setUniqueRecordingCalls(l2CallStats[2]);
1849
            l2Model.setTriedUniqueCalls(computeUniqueTriedCount(l2Logs, mobileToFofoIdMap,
1857
            l2Model.setTriedUniqueCalls(computeUniqueTriedCount(l2Logs));
1850
                    remarksByAuthId.getOrDefault(l2AuthId, Collections.emptyList())));
-
 
1851
 
1858
 
1852
            l2Model.setOutOfSequenceCount(outOfSequenceCountByAuthId.getOrDefault(l2AuthId, 0L));
1859
            l2Model.setOutOfSequenceCount(outOfSequenceCountByAuthId.getOrDefault(l2AuthId, 0L));
1853
            rbmCallTargetModels.add(l2Model);
1860
            rbmCallTargetModels.add(l2Model);
1854
        }
1861
        }
1855
 
1862
 
Line 1888... Line 1895...
1888
            List<AgentCallLog> l3Logs = callLogsByAuthId.get((long) l3AuthId);
1895
            List<AgentCallLog> l3Logs = callLogsByAuthId.get((long) l3AuthId);
1889
            long[] l3CallStats = getCallStatsFromLogs(l3Logs, mobileToFofoIdMap);
1896
            long[] l3CallStats = getCallStatsFromLogs(l3Logs, mobileToFofoIdMap);
1890
            l3Model.setValueTargetAchieved(l3CallStats[0]);
1897
            l3Model.setValueTargetAchieved(l3CallStats[0]);
1891
            l3Model.setTotalRecordingCalls(l3CallStats[1]);
1898
            l3Model.setTotalRecordingCalls(l3CallStats[1]);
1892
            l3Model.setUniqueRecordingCalls(l3CallStats[2]);
1899
            l3Model.setUniqueRecordingCalls(l3CallStats[2]);
1893
            l3Model.setTriedUniqueCalls(computeUniqueTriedCount(l3Logs, mobileToFofoIdMap,
1900
            l3Model.setTriedUniqueCalls(computeUniqueTriedCount(l3Logs));
1894
                    remarksByAuthId.getOrDefault(l3AuthId, Collections.emptyList())));
-
 
1895
 
1901
 
1896
            l3Model.setOutOfSequenceCount(outOfSequenceCountByAuthId.getOrDefault(l3AuthId, 0L));
1902
            l3Model.setOutOfSequenceCount(outOfSequenceCountByAuthId.getOrDefault(l3AuthId, 0L));
1897
            rbmCallTargetModels.add(l3Model);
1903
            rbmCallTargetModels.add(l3Model);
1898
        }
1904
        }
1899
 
1905
 
Line 2076... Line 2082...
2076
        return sortedModels;
2082
        return sortedModels;
2077
    }
2083
    }
2078
 
2084
 
2079
    /**
2085
    /**
2080
     * Rule: count each distinct customer number this RBM attempted today, based on
2086
     * Rule: count each distinct customer number this RBM attempted today, based on
2081
     * post-call REMARKS (PartnerCollectionRemark), not the vendor callStatus:
2087
     * the vendor-reported customer-side outcome (AgentCallLog.customerStatus):
2082
     *   - If the RBM logged ANY remark other than NO_ANSWER for this partner today
2088
     *   - If ANY call to this number has customerStatus that is not "Missed"
2083
     *     → count as 1 (customer was reached / tagged with a real outcome).
2089
     *     → count as 1 (customer was reached at some point).
2084
     *   - Else if the RBM has NO remark row at all for this partner today → count
-
 
2085
     *     as 1 (treat missing remark as "not tagged no-answer" — matches the "-"
-
 
2086
     *     rows shown in the Called Partners modal which count as tried).
-
 
2087
     *   - Else (every remark is NO_ANSWER) → count only if attempts >= 3
2090
     *   - Else (every call to this number was Missed) → count only if attempts >= 3
2088
     *     (persistence credit).
2091
     *     (persistence credit).
2089
     * Unknown numbers (no fofoId mapping) always count as 1 — no remark to check.
2092
     * null/empty customerStatus is treated as "not Missed" (favours counting when
-
 
2093
     * the vendor didn't classify the outcome).
2090
     */
2094
     */
2091
    private long computeUniqueTriedCount(List<AgentCallLog> callLogs,
2095
    private long computeUniqueTriedCount(List<AgentCallLog> callLogs) {
2092
                                         Map<String, Integer> mobileToFofoIdMap,
-
 
2093
                                         List<PartnerCollectionRemark> rbmRemarksToday) {
-
 
2094
        if (callLogs == null || callLogs.isEmpty()) return 0L;
2096
        if (callLogs == null || callLogs.isEmpty()) return 0L;
2095
 
-
 
2096
        // Build fofoId -> remarks (only the current RBM's remarks today are in scope).
-
 
2097
        Map<Integer, List<PartnerCollectionRemark>> remarksByFofoId = new HashMap<>();
-
 
2098
        if (rbmRemarksToday != null) {
-
 
2099
            for (PartnerCollectionRemark r : rbmRemarksToday) {
-
 
2100
                remarksByFofoId.computeIfAbsent(r.getFofoId(), k -> new ArrayList<>()).add(r);
-
 
2101
            }
-
 
2102
        }
-
 
2103
 
-
 
2104
        // Attempts (call count) per fofoId, or per raw number if unresolved.
-
 
2105
        Map<Integer, Integer> attemptsByFofo = new HashMap<>();
2097
        Map<String, List<AgentCallLog>> byNumber = new HashMap<>();
2106
        Set<String> unresolvedNumbers = new HashSet<>();
-
 
2107
        for (AgentCallLog log : callLogs) {
2098
        for (AgentCallLog log : callLogs) {
2108
            String num = log.getCustomerNumber();
2099
            String num = log.getCustomerNumber();
2109
            if (num == null) continue;
2100
            if (num == null) continue;
2110
            String normalized = num.startsWith("+91") ? num.substring(3) : num;
2101
            String normalized = num.startsWith("+91") ? num.substring(3) : num;
2111
            Integer fofoId = mobileToFofoIdMap != null ? mobileToFofoIdMap.get(normalized) : null;
2102
            byNumber.computeIfAbsent(normalized, k -> new ArrayList<>()).add(log);
2112
            if (fofoId != null) {
-
 
2113
                attemptsByFofo.merge(fofoId, 1, Integer::sum);
-
 
2114
            } else {
-
 
2115
                unresolvedNumbers.add(normalized);
-
 
2116
            }
-
 
2117
        }
2103
        }
2118
 
-
 
2119
        long count = 0L;
2104
        long count = 0L;
2120
        for (Map.Entry<Integer, Integer> e : attemptsByFofo.entrySet()) {
2105
        for (List<AgentCallLog> logs : byNumber.values()) {
2121
            int fofoId = e.getKey();
-
 
2122
            int attempts = e.getValue();
-
 
2123
            List<PartnerCollectionRemark> remarks = remarksByFofoId.getOrDefault(fofoId, Collections.emptyList());
-
 
2124
            if (remarks.isEmpty()) {
-
 
2125
                // No remark logged today for this fofoId — counts.
-
 
2126
                count++;
-
 
2127
                continue;
-
 
2128
            }
-
 
2129
            boolean hasNonNoAnswer = false;
2106
            boolean hasNonMissed = false;
2130
            for (PartnerCollectionRemark r : remarks) {
2107
            for (AgentCallLog l : logs) {
2131
                if (r.getRemark() != CollectionRemark.NO_ANSWER) {
2108
                if (!isMissedCustomerStatus(l.getCustomerStatus())) {
2132
                    hasNonNoAnswer = true;
2109
                    hasNonMissed = true;
2133
                    break;
2110
                    break;
2134
                }
2111
                }
2135
            }
2112
            }
2136
            if (hasNonNoAnswer) count++;
2113
            if (hasNonMissed) count++;
2137
            else if (attempts >= 3) count++;
2114
            else if (logs.size() >= 3) count++;
2138
        }
2115
        }
2139
        // Unresolved numbers — count each as 1.
-
 
2140
        count += unresolvedNumbers.size();
-
 
2141
        return count;
2116
        return count;
2142
    }
2117
    }
2143
 
2118
 
2144
    /**
2119
    /**
2145
     * Returns call stats: [0] = called count, [1] = total recording calls, [2] = unique recording calls
2120
     * Returns call stats: [0] = called count, [1] = total recording calls, [2] = unique recording calls