| Line 1061... |
Line 1061... |
| 1061 |
|| t.getL5AuthUser() == authId)
|
1061 |
|| t.getL5AuthUser() == authId)
|
| 1062 |
.map(Ticket::getFofoId)
|
1062 |
.map(Ticket::getFofoId)
|
| 1063 |
.distinct()
|
1063 |
.distinct()
|
| 1064 |
.collect(Collectors.toList());
|
1064 |
.collect(Collectors.toList());
|
| 1065 |
|
1065 |
|
| 1066 |
// Get today's remarks created by L2
|
1066 |
// Get today's remarks created by L2 (all remarks, not deduplicated)
|
| 1067 |
List<PartnerCollectionRemark> todayRemarks = partnerCollectionRemarkRepository
|
1067 |
List<PartnerCollectionRemark> todayRemarks = partnerCollectionRemarkRepository
|
| 1068 |
.selectAllByAuthIdsOnDate(Collections.singletonList(authId), today);
|
1068 |
.selectAllByAuthIdsOnDate(Collections.singletonList(authId), today);
|
| 1069 |
|
1069 |
|
| 1070 |
// Deduplicate by fofoId - keep latest remark per partner (list is ordered by id DESC)
|
- |
|
| 1071 |
Map<Integer, PartnerCollectionRemark> uniqueRemarksByFofoId = new LinkedHashMap<>();
|
- |
|
| 1072 |
for (PartnerCollectionRemark remark : todayRemarks) {
|
- |
|
| 1073 |
uniqueRemarksByFofoId.putIfAbsent(remark.getFofoId(), remark);
|
- |
|
| 1074 |
}
|
- |
|
| 1075 |
|
- |
|
| 1076 |
return buildCalledPartnerResult(uniqueRemarksByFofoId);
|
1070 |
return buildCalledPartnerResult(todayRemarks);
|
| 1077 |
}
|
1071 |
}
|
| 1078 |
|
1072 |
|
| 1079 |
// L1 Logic
|
1073 |
// L1 Logic
|
| 1080 |
Map<String, Set<Integer>> storeGuyMap;
|
1074 |
Map<String, Set<Integer>> storeGuyMap;
|
| 1081 |
try {
|
1075 |
try {
|
| Line 1161... |
Line 1155... |
| 1161 |
targetFofoIds.add(fofoId);
|
1155 |
targetFofoIds.add(fofoId);
|
| 1162 |
}
|
1156 |
}
|
| 1163 |
// rank 4 (FuturePlan) and rank 5 (Normal) are NOT in target
|
1157 |
// rank 4 (FuturePlan) and rank 5 (Normal) are NOT in target
|
| 1164 |
}
|
1158 |
}
|
| 1165 |
|
1159 |
|
| 1166 |
// Get today's remarks created by L1
|
1160 |
// Get today's remarks created by L1 (all remarks, not deduplicated)
|
| 1167 |
List<PartnerCollectionRemark> todayRemarks = partnerCollectionRemarkRepository
|
1161 |
List<PartnerCollectionRemark> todayRemarks = partnerCollectionRemarkRepository
|
| 1168 |
.selectAllByAuthIdsOnDate(Collections.singletonList(authId), today);
|
1162 |
.selectAllByAuthIdsOnDate(Collections.singletonList(authId), today);
|
| 1169 |
|
1163 |
|
| 1170 |
// Deduplicate by fofoId - keep latest remark per partner (list is ordered by id DESC)
|
- |
|
| 1171 |
Map<Integer, PartnerCollectionRemark> uniqueRemarksByFofoId = new LinkedHashMap<>();
|
- |
|
| 1172 |
for (PartnerCollectionRemark remark : todayRemarks) {
|
- |
|
| 1173 |
uniqueRemarksByFofoId.putIfAbsent(remark.getFofoId(), remark);
|
- |
|
| 1174 |
}
|
- |
|
| 1175 |
|
- |
|
| 1176 |
return buildCalledPartnerResult(uniqueRemarksByFofoId);
|
1164 |
return buildCalledPartnerResult(todayRemarks);
|
| 1177 |
}
|
1165 |
}
|
| 1178 |
|
1166 |
|
| 1179 |
private List<CalledPartnerDetailModel> buildCalledPartnerResult(Map<Integer, PartnerCollectionRemark> uniqueRemarksByFofoId) {
|
1167 |
private List<CalledPartnerDetailModel> buildCalledPartnerResult(List<PartnerCollectionRemark> allRemarks) {
|
| 1180 |
if (uniqueRemarksByFofoId.isEmpty()) {
|
1168 |
if (allRemarks.isEmpty()) {
|
| 1181 |
return Collections.emptyList();
|
1169 |
return Collections.emptyList();
|
| 1182 |
}
|
1170 |
}
|
| 1183 |
|
1171 |
|
| - |
|
1172 |
// Get unique fofoIds for retailer lookup
|
| 1184 |
Set<Integer> fofoIds = uniqueRemarksByFofoId.keySet();
|
1173 |
Set<Integer> fofoIds = allRemarks.stream()
|
| - |
|
1174 |
.map(PartnerCollectionRemark::getFofoId)
|
| - |
|
1175 |
.collect(Collectors.toSet());
|
| 1185 |
Map<Integer, CustomRetailer> retailerMap = Collections.emptyMap();
|
1176 |
Map<Integer, CustomRetailer> retailerMap = Collections.emptyMap();
|
| 1186 |
try {
|
1177 |
try {
|
| 1187 |
retailerMap = retailerService.getFofoRetailers(new ArrayList<>(fofoIds));
|
1178 |
retailerMap = retailerService.getFofoRetailers(new ArrayList<>(fofoIds));
|
| 1188 |
} catch (ProfitMandiBusinessException e) {
|
1179 |
} catch (ProfitMandiBusinessException e) {
|
| 1189 |
LOGGER.error("Error fetching fofo stores", e);
|
1180 |
LOGGER.error("Error fetching fofo stores", e);
|
| 1190 |
}
|
1181 |
}
|
| 1191 |
|
1182 |
|
| 1192 |
// Fetch call logs for remarks that have agentCallLogId
|
1183 |
// Fetch call logs for remarks that have agentCallLogId
|
| 1193 |
Map<Long, com.spice.profitmandi.dao.entity.cs.AgentCallLog> callLogMap = new HashMap<>();
|
1184 |
Map<Long, com.spice.profitmandi.dao.entity.cs.AgentCallLog> callLogMap = new HashMap<>();
|
| 1194 |
try {
|
1185 |
try {
|
| 1195 |
List<Long> callLogIds = uniqueRemarksByFofoId.values().stream()
|
1186 |
List<Long> callLogIds = allRemarks.stream()
|
| 1196 |
.filter(r -> r.getAgentCallLogId() > 0)
|
1187 |
.filter(r -> r.getAgentCallLogId() > 0)
|
| 1197 |
.map(PartnerCollectionRemark::getAgentCallLogId)
|
1188 |
.map(PartnerCollectionRemark::getAgentCallLogId)
|
| 1198 |
.collect(Collectors.toList());
|
1189 |
.collect(Collectors.toList());
|
| 1199 |
|
1190 |
|
| 1200 |
if (!callLogIds.isEmpty()) {
|
1191 |
if (!callLogIds.isEmpty()) {
|
| Line 1210... |
Line 1201... |
| 1210 |
|
1201 |
|
| 1211 |
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm a");
|
1202 |
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm a");
|
| 1212 |
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm a");
|
1203 |
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm a");
|
| 1213 |
List<CalledPartnerDetailModel> result = new ArrayList<>();
|
1204 |
List<CalledPartnerDetailModel> result = new ArrayList<>();
|
| 1214 |
|
1205 |
|
| 1215 |
for (PartnerCollectionRemark remark : uniqueRemarksByFofoId.values()) {
|
1206 |
for (PartnerCollectionRemark remark : allRemarks) {
|
| 1216 |
CustomRetailer retailer = retailerMap.get(remark.getFofoId());
|
1207 |
CustomRetailer retailer = retailerMap.get(remark.getFofoId());
|
| 1217 |
String partyName = retailer != null
|
1208 |
String partyName = retailer != null
|
| 1218 |
? retailer.getBusinessName()
|
1209 |
? retailer.getBusinessName()
|
| 1219 |
: "Unknown (" + remark.getFofoId() + ")";
|
1210 |
: "Unknown (" + remark.getFofoId() + ")";
|
| 1220 |
String code = retailer != null
|
1211 |
String code = retailer != null
|
| Line 1270... |
Line 1261... |
| 1270 |
if (authUsers.isEmpty()) {
|
1261 |
if (authUsers.isEmpty()) {
|
| 1271 |
return rows;
|
1262 |
return rows;
|
| 1272 |
}
|
1263 |
}
|
| 1273 |
AuthUser authUser = authUsers.get(0);
|
1264 |
AuthUser authUser = authUsers.get(0);
|
| 1274 |
|
1265 |
|
| 1275 |
// Get positions to determine if L1 or L2
|
1266 |
// Get positions to determine if L2
|
| 1276 |
List<Position> positions = positionRepository.selectPositionByAuthIds(Collections.singletonList(authId));
|
1267 |
List<Position> positions = positionRepository.selectPositionByAuthIds(Collections.singletonList(authId));
|
| 1277 |
boolean isL1 = positions.stream()
|
- |
|
| 1278 |
.anyMatch(p -> ProfitMandiConstants.TICKET_CATEGORY_RBM == p.getCategoryId()
|
- |
|
| 1279 |
&& EscalationType.L1.equals(p.getEscalationType()));
|
- |
|
| 1280 |
boolean isL2 = positions.stream()
|
1268 |
boolean isL2 = positions.stream()
|
| 1281 |
.anyMatch(p -> ProfitMandiConstants.TICKET_CATEGORY_RBM == p.getCategoryId()
|
1269 |
.anyMatch(p -> ProfitMandiConstants.TICKET_CATEGORY_RBM == p.getCategoryId()
|
| 1282 |
&& EscalationType.L2.equals(p.getEscalationType()));
|
1270 |
&& EscalationType.L2.equals(p.getEscalationType()));
|
| 1283 |
|
1271 |
|
| 1284 |
// Get fofo IDs for this RBM
|
1272 |
LocalDateTime startDate = LocalDate.now().atStartOfDay();
|
| 1285 |
Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();
|
1273 |
LocalDate firstOfMonth = LocalDate.now().withDayOfMonth(1);
|
| 1286 |
List<Integer> fofoIdList = new ArrayList<>();
|
1274 |
LocalDate endOfMonth = LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth()).plusDays(1);
|
| 1287 |
|
1275 |
|
| - |
|
1276 |
// Get fofo IDs from mtdBillingData (same source as Partner Count in getRbmCallTargetModels)
|
| - |
|
1277 |
List<RbmWeeklyBillingModel> mtdBillingData = getWeeklyBillingDataForMonth(firstOfMonth, endOfMonth);
|
| - |
|
1278 |
|
| - |
|
1279 |
List<Integer> fofoIdList;
|
| 1288 |
if (isL2) {
|
1280 |
if (isL2) {
|
| 1289 |
// L2: get fofo IDs from escalated tickets
|
1281 |
// L2: get fofo IDs from escalated tickets (same as getRbmCallTargetModels)
|
| 1290 |
List<Ticket> escalatedTickets = ticketRepository.selectOpenEscalatedTicketsByAuthIds(Collections.singletonList(authId));
|
1282 |
List<Ticket> escalatedTickets = ticketRepository.selectOpenEscalatedTicketsByAuthIds(Collections.singletonList(authId));
|
| 1291 |
fofoIdList = escalatedTickets.stream()
|
1283 |
fofoIdList = escalatedTickets.stream()
|
| 1292 |
.filter(t -> t.getL2AuthUser() == authId
|
1284 |
.filter(t -> t.getL2AuthUser() == authId
|
| 1293 |
|| t.getL3AuthUser() == authId
|
1285 |
|| t.getL3AuthUser() == authId
|
| 1294 |
|| t.getL4AuthUser() == authId
|
1286 |
|| t.getL4AuthUser() == authId
|
| 1295 |
|| t.getL5AuthUser() == authId)
|
1287 |
|| t.getL5AuthUser() == authId)
|
| 1296 |
.map(Ticket::getFofoId)
|
1288 |
.map(Ticket::getFofoId)
|
| 1297 |
.distinct()
|
1289 |
.distinct()
|
| 1298 |
.collect(Collectors.toList());
|
1290 |
.collect(Collectors.toList());
|
| - |
|
1291 |
} else {
|
| - |
|
1292 |
// L1: get fofo IDs from mtdBillingData with isTargetedPartner (same as Partner Count)
|
| - |
|
1293 |
fofoIdList = mtdBillingData.stream()
|
| 1299 |
} else if (storeGuyMap.containsKey(authUser.getEmailId())) {
|
1294 |
.filter(RbmWeeklyBillingModel::isTargetedPartner)
|
| 1300 |
fofoIdList = new ArrayList<>(storeGuyMap.get(authUser.getEmailId()));
|
1295 |
.filter(m -> m.getAuthId() == authId)
|
| - |
|
1296 |
.map(RbmWeeklyBillingModel::getFofoId)
|
| - |
|
1297 |
.distinct()
|
| - |
|
1298 |
.collect(Collectors.toList());
|
| 1301 |
}
|
1299 |
}
|
| 1302 |
|
1300 |
|
| 1303 |
if (fofoIdList.isEmpty()) {
|
1301 |
if (fofoIdList.isEmpty()) {
|
| 1304 |
return rows;
|
1302 |
return rows;
|
| 1305 |
}
|
1303 |
}
|
| 1306 |
|
1304 |
|
| 1307 |
LocalDateTime startDate = LocalDate.now().atStartOfDay();
|
- |
|
| 1308 |
LocalDate firstOfMonth = LocalDate.now().withDayOfMonth(1);
|
- |
|
| 1309 |
LocalDate endOfMonth = LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth()).plusDays(1);
|
- |
|
| 1310 |
|
- |
|
| 1311 |
// Get fofo stores
|
1305 |
// MTD billed fofoIds for zero billing check
|
| 1312 |
Map<Integer, FofoStore> fofoStoresMap = new HashMap<>();
|
1306 |
Set<Integer> mtdBilledFofoIds = mtdBillingData.stream()
|
| 1313 |
try {
|
- |
|
| 1314 |
fofoStoresMap = fofoStoreRepository.selectByRetailerIds(fofoIdList).stream()
|
- |
|
| 1315 |
.collect(Collectors.toMap(FofoStore::getId, x -> x, (a, b) -> a));
|
- |
|
| 1316 |
} catch (ProfitMandiBusinessException e) {
|
- |
|
| 1317 |
LOGGER.error("Error fetching fofo stores", e);
|
- |
|
| 1318 |
}
|
- |
|
| 1319 |
|
- |
|
| 1320 |
// For L1 RBMs, filter escalated partners
|
- |
|
| 1321 |
if (isL1) {
|
- |
|
| 1322 |
List<Integer> allRemarkIds = partnerCollectionRemarkRepository.selectMaxRemarkId(fofoIdList);
|
- |
|
| 1323 |
if (!allRemarkIds.isEmpty()) {
|
- |
|
| 1324 |
Map<Integer, PartnerCollectionRemark> partnerCollectionRemarks = partnerCollectionRemarkRepository.selectByIds(allRemarkIds).stream()
|
- |
|
| 1325 |
.collect(Collectors.toMap(PartnerCollectionRemark::getFofoId, x -> x, (a, b) -> a));
|
- |
|
| 1326 |
fofoIdList = partnerCollectionRemarks.entrySet().stream()
|
1307 |
.filter(RbmWeeklyBillingModel::isMtdBilled)
|
| 1327 |
.filter(entry -> {
|
- |
|
| 1328 |
PartnerCollectionRemark pcrMap = entry.getValue();
|
- |
|
| 1329 |
return !(CollectionRemark.RBM_L2_ESCALATION.equals(pcrMap.getRemark())
|
- |
|
| 1330 |
|| CollectionRemark.SALES_ESCALATION.equals(pcrMap.getRemark()));
|
- |
|
| 1331 |
})
|
- |
|
| 1332 |
.map(Map.Entry::getKey)
|
1308 |
.map(RbmWeeklyBillingModel::getFofoId)
|
| 1333 |
.collect(Collectors.toList());
|
1309 |
.collect(Collectors.toSet());
|
| 1334 |
}
|
- |
|
| 1335 |
}
|
- |
|
| 1336 |
|
1310 |
|
| 1337 |
// Collection rank map
|
1311 |
// Collection rank map for status calculation
|
| 1338 |
Map<Integer, Integer> collectionRankMap = new HashMap<>();
|
1312 |
Map<Integer, Integer> collectionRankMap = new HashMap<>();
|
| 1339 |
try {
|
1313 |
try {
|
| 1340 |
collectionRankMap = partnerCollectionService.getCollectionRankMap(fofoIdList, startDate);
|
1314 |
collectionRankMap = partnerCollectionService.getCollectionRankMap(fofoIdList, startDate);
|
| 1341 |
} catch (ProfitMandiBusinessException e) {
|
1315 |
} catch (ProfitMandiBusinessException e) {
|
| 1342 |
LOGGER.error("Error fetching collection rank map", e);
|
1316 |
LOGGER.error("Error fetching collection rank map", e);
|
| 1343 |
}
|
1317 |
}
|
| 1344 |
|
1318 |
|
| 1345 |
// MTD billing data
|
- |
|
| 1346 |
List<RbmWeeklyBillingModel> mtdBillingData = getWeeklyBillingDataForMonth(firstOfMonth, endOfMonth);
|
- |
|
| 1347 |
Set<Integer> mtdBilledFofoIds = mtdBillingData.stream()
|
- |
|
| 1348 |
.filter(RbmWeeklyBillingModel::isMtdBilled)
|
- |
|
| 1349 |
.map(RbmWeeklyBillingModel::getFofoId)
|
- |
|
| 1350 |
.collect(Collectors.toSet());
|
- |
|
| 1351 |
|
- |
|
| 1352 |
// Filter to valid fofo IDs (external, ACTIVE, has collection plan)
|
- |
|
| 1353 |
Map<Integer, Integer> finalCollectionRankMap = collectionRankMap;
|
- |
|
| 1354 |
Map<Integer, FofoStore> finalFofoStoresMap = fofoStoresMap;
|
- |
|
| 1355 |
List<Integer> validFofoIds = fofoIdList.stream()
|
- |
|
| 1356 |
.filter(fofoId -> {
|
- |
|
| 1357 |
FofoStore store = finalFofoStoresMap.get(fofoId);
|
- |
|
| 1358 |
if (store == null || store.isInternal()) return false;
|
- |
|
| 1359 |
if (!ActivationType.ACTIVE.equals(store.getActivationType())) return false;
|
- |
|
| 1360 |
return finalCollectionRankMap.containsKey(fofoId);
|
- |
|
| 1361 |
})
|
- |
|
| 1362 |
.collect(Collectors.toList());
|
- |
|
| 1363 |
|
- |
|
| 1364 |
// Resolve partner names/codes
|
1319 |
// Resolve partner names/codes
|
| 1365 |
Map<Integer, CustomRetailer> retailerMap = Collections.emptyMap();
|
1320 |
Map<Integer, CustomRetailer> retailerMap = Collections.emptyMap();
|
| 1366 |
if (!validFofoIds.isEmpty()) {
|
1321 |
if (!fofoIdList.isEmpty()) {
|
| 1367 |
try {
|
1322 |
try {
|
| 1368 |
retailerMap = retailerService.getFofoRetailers(validFofoIds);
|
1323 |
retailerMap = retailerService.getFofoRetailers(fofoIdList);
|
| 1369 |
} catch (ProfitMandiBusinessException e) {
|
1324 |
} catch (ProfitMandiBusinessException e) {
|
| 1370 |
LOGGER.error("Error fetching fofo retailers for raw data", e);
|
1325 |
LOGGER.error("Error fetching fofo retailers for raw data", e);
|
| 1371 |
}
|
1326 |
}
|
| 1372 |
}
|
1327 |
}
|
| 1373 |
|
1328 |
|
| 1374 |
String rbmName = authUser.getFullName() + (isL2 ? " (L2)" : "");
|
1329 |
String rbmName = authUser.getFullName() + (isL2 ? " (L2)" : "");
|
| 1375 |
|
1330 |
|
| 1376 |
// Build rows
|
1331 |
// Build rows for ALL partners (same count as Partner Count)
|
| 1377 |
for (Integer fofoId : validFofoIds) {
|
1332 |
for (Integer fofoId : fofoIdList) {
|
| - |
|
1333 |
// Default to rank 5 (Normal) for partners without collection plan
|
| 1378 |
int rank = collectionRankMap.getOrDefault(fofoId, 5);
|
1334 |
int rank = collectionRankMap.getOrDefault(fofoId, 5);
|
| 1379 |
boolean hasZeroBilling = !mtdBilledFofoIds.contains(fofoId);
|
1335 |
boolean hasZeroBilling = !mtdBilledFofoIds.contains(fofoId);
|
| 1380 |
|
1336 |
|
| - |
|
1337 |
// Status assignment with same priority as getRbmCallTargetModels
|
| 1381 |
String status;
|
1338 |
String status;
|
| 1382 |
if (rank == 1) {
|
1339 |
if (rank == 1) {
|
| 1383 |
status = "Plan Today";
|
1340 |
status = "Plan Today";
|
| 1384 |
} else if (rank == 2) {
|
1341 |
} else if (rank == 2) {
|
| 1385 |
status = "Carry Forward";
|
1342 |
status = "Carry Forward";
|
| 1386 |
} else if (rank == 3) {
|
- |
|
| 1387 |
status = "Untouched";
|
- |
|
| 1388 |
} else if (hasZeroBilling) {
|
1343 |
} else if (hasZeroBilling) {
|
| 1389 |
status = "Zero Billing";
|
1344 |
status = "Zero Billing";
|
| - |
|
1345 |
} else if (rank == 3) {
|
| - |
|
1346 |
status = "Untouched";
|
| 1390 |
} else if (rank == 4) {
|
1347 |
} else if (rank == 4) {
|
| 1391 |
status = "Future Plan";
|
1348 |
status = "Future Plan";
|
| 1392 |
} else {
|
1349 |
} else {
|
| 1393 |
status = "Normal";
|
1350 |
status = "Normal";
|
| 1394 |
}
|
1351 |
}
|