| 33917 |
ranu |
1 |
package com.spice.profitmandi.service;
|
|
|
2 |
|
| 35631 |
ranu |
3 |
import com.spice.profitmandi.common.enumuration.ActivationType;
|
|
|
4 |
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
|
|
|
5 |
import com.spice.profitmandi.common.model.CustomRetailer;
|
| 33917 |
ranu |
6 |
import com.spice.profitmandi.common.model.ProfitMandiConstants;
|
| 35631 |
ranu |
7 |
import com.spice.profitmandi.dao.entity.auth.AuthUser;
|
|
|
8 |
import com.spice.profitmandi.dao.entity.auth.PartnerCollectionRemark;
|
|
|
9 |
import com.spice.profitmandi.dao.entity.auth.RbmCallSequenceLog;
|
|
|
10 |
import com.spice.profitmandi.dao.entity.cs.Position;
|
|
|
11 |
import com.spice.profitmandi.dao.entity.cs.Ticket;
|
|
|
12 |
import com.spice.profitmandi.dao.entity.fofo.FofoStore;
|
| 34397 |
ranu |
13 |
import com.spice.profitmandi.dao.entity.fofo.MonthlyTarget;
|
| 33985 |
ranu |
14 |
import com.spice.profitmandi.dao.entity.inventory.RbmAchievements;
|
| 33926 |
ranu |
15 |
import com.spice.profitmandi.dao.entity.inventory.RbmTargets;
|
| 35631 |
ranu |
16 |
import com.spice.profitmandi.dao.enumuration.auth.CollectionRemark;
|
|
|
17 |
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
|
| 33917 |
ranu |
18 |
import com.spice.profitmandi.dao.model.*;
|
| 35631 |
ranu |
19 |
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
|
|
|
20 |
import com.spice.profitmandi.dao.repository.auth.PartnerCollectionRemarkRepository;
|
|
|
21 |
import com.spice.profitmandi.dao.repository.auth.RbmCallSequenceLogRepository;
|
| 33985 |
ranu |
22 |
import com.spice.profitmandi.dao.repository.catalog.RbmAchievementsRepository;
|
| 33926 |
ranu |
23 |
import com.spice.profitmandi.dao.repository.catalog.RbmTargetsRepository;
|
| 35631 |
ranu |
24 |
import com.spice.profitmandi.dao.repository.cs.CsService;
|
|
|
25 |
import com.spice.profitmandi.dao.repository.cs.PositionRepository;
|
|
|
26 |
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
|
| 34397 |
ranu |
27 |
import com.spice.profitmandi.dao.repository.fofo.MonthlyTargetRepository;
|
| 34880 |
ranu |
28 |
import com.spice.profitmandi.dao.repository.logistics.PublicHolidaysRepository;
|
| 35631 |
ranu |
29 |
import com.spice.profitmandi.dao.repository.transaction.LoanRepository;
|
| 34397 |
ranu |
30 |
import com.spice.profitmandi.dao.repository.transaction.OrderRepository;
|
| 35631 |
ranu |
31 |
import com.spice.profitmandi.service.user.RetailerService;
|
| 33917 |
ranu |
32 |
import org.apache.logging.log4j.LogManager;
|
|
|
33 |
import org.apache.logging.log4j.Logger;
|
|
|
34 |
import org.hibernate.Session;
|
|
|
35 |
import org.hibernate.SessionFactory;
|
|
|
36 |
import org.hibernate.query.NativeQuery;
|
|
|
37 |
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
38 |
import org.springframework.stereotype.Component;
|
|
|
39 |
|
|
|
40 |
import javax.persistence.TypedQuery;
|
| 34880 |
ranu |
41 |
import java.time.*;
|
| 35631 |
ranu |
42 |
import java.time.format.DateTimeFormatter;
|
| 34880 |
ranu |
43 |
import java.time.temporal.ChronoUnit;
|
| 35631 |
ranu |
44 |
import java.util.*;
|
| 33997 |
ranu |
45 |
import java.util.stream.Collectors;
|
| 33917 |
ranu |
46 |
|
|
|
47 |
@Component
|
|
|
48 |
public class RbmTargetServiceImpl implements RbmTargetService {
|
|
|
49 |
private static final Logger LOGGER = LogManager.getLogger(RbmTargetServiceImpl.class);
|
|
|
50 |
|
|
|
51 |
@Autowired
|
|
|
52 |
SessionFactory sessionFactory;
|
|
|
53 |
|
| 33926 |
ranu |
54 |
@Autowired
|
|
|
55 |
RbmTargetsRepository rbmTargetsRepository;
|
| 33917 |
ranu |
56 |
|
| 33985 |
ranu |
57 |
@Autowired
|
|
|
58 |
RbmAchievementsRepository rbmAchievementsRepository;
|
|
|
59 |
|
| 34397 |
ranu |
60 |
@Autowired
|
|
|
61 |
MonthlyTargetRepository monthlyTargetRepository;
|
|
|
62 |
|
| 34880 |
ranu |
63 |
@Autowired
|
|
|
64 |
PublicHolidaysRepository publicHolidaysRepository;
|
|
|
65 |
|
| 35631 |
ranu |
66 |
@Autowired
|
|
|
67 |
RetailerService retailerService;
|
|
|
68 |
|
| 33917 |
ranu |
69 |
@Override
|
|
|
70 |
public List<WarehouseRbmTargetModel> getWarehouseWiseRbmMonthlyTarget() {
|
|
|
71 |
Session session = sessionFactory.getCurrentSession();
|
|
|
72 |
final TypedQuery<WarehouseRbmTargetModel> typedQuerySimilar = session.createNamedQuery("RbmTarget.getWarehouseWiseMonthlyTarget", WarehouseRbmTargetModel.class);
|
|
|
73 |
|
|
|
74 |
return typedQuerySimilar.getResultList();
|
|
|
75 |
|
|
|
76 |
}
|
|
|
77 |
|
|
|
78 |
@Override
|
|
|
79 |
public List<MTDAchievedTargetModel> getDateWiseAchievedTargetOfRbm(LocalDate startDate, LocalDate endDate) {
|
|
|
80 |
Session session = sessionFactory.getCurrentSession();
|
|
|
81 |
final TypedQuery<MTDAchievedTargetModel> typedQuerySimilar = session.createNamedQuery("RbmTarget.getRbmAchievedMonthlyTarget", MTDAchievedTargetModel.class);
|
|
|
82 |
typedQuerySimilar.setParameter("startDate", startDate);
|
|
|
83 |
typedQuerySimilar.setParameter("endDate", endDate);
|
|
|
84 |
return typedQuerySimilar.getResultList();
|
|
|
85 |
|
|
|
86 |
}
|
|
|
87 |
|
|
|
88 |
@Override
|
| 34055 |
ranu |
89 |
public List<TodayAchievedMovementModel> getMovementWiseAchievementByDate(LocalDate startDate, LocalDate endDate) {
|
| 33917 |
ranu |
90 |
LOGGER.info("start date {}, end date {}", startDate, endDate);
|
|
|
91 |
Session session = sessionFactory.getCurrentSession();
|
| 34055 |
ranu |
92 |
final TypedQuery<TodayAchievedMovementModel> typedQuerySimilar = session.createNamedQuery("RBMTarget.TodayAchivementByMovement", TodayAchievedMovementModel.class);
|
| 33917 |
ranu |
93 |
typedQuerySimilar.setParameter("startDate", startDate);
|
|
|
94 |
typedQuerySimilar.setParameter("endDate", endDate);
|
|
|
95 |
return typedQuerySimilar.getResultList();
|
|
|
96 |
|
|
|
97 |
}
|
|
|
98 |
|
|
|
99 |
@Override
|
|
|
100 |
public List<WarehouseMobileStockByMovementModel> getWarehouseMobileStockByMovement() {
|
|
|
101 |
Session session = sessionFactory.getCurrentSession();
|
|
|
102 |
final TypedQuery<WarehouseMobileStockByMovementModel> typedQuerySimilar = session.createNamedQuery("WarehouseStock.MovementWiseMobileStock", WarehouseMobileStockByMovementModel.class);
|
|
|
103 |
|
|
|
104 |
return typedQuerySimilar.getResultList();
|
|
|
105 |
|
|
|
106 |
}
|
|
|
107 |
|
| 33991 |
ranu |
108 |
@Override
|
|
|
109 |
public List<SoldCatalogsReportModel> getCatalogSoldReport(LocalDate startDate, LocalDate endDate) {
|
|
|
110 |
Session session = sessionFactory.getCurrentSession();
|
|
|
111 |
final TypedQuery<SoldCatalogsReportModel> typedQuerySimilar = session.createNamedQuery("CatalogsReport.SoldCatalogsReport", SoldCatalogsReportModel.class);
|
|
|
112 |
typedQuerySimilar.setParameter("startDate", startDate);
|
|
|
113 |
typedQuerySimilar.setParameter("endDate", endDate);
|
|
|
114 |
return typedQuerySimilar.getResultList();
|
| 33917 |
ranu |
115 |
|
| 33991 |
ranu |
116 |
}
|
|
|
117 |
|
|
|
118 |
|
| 33917 |
ranu |
119 |
public int getWorkingDaysCount(LocalDate startDate) {
|
|
|
120 |
Session session = sessionFactory.getCurrentSession();
|
|
|
121 |
|
|
|
122 |
// Convert the LocalDate to a format MySQL can interpret
|
|
|
123 |
String startDateString = startDate.toString();
|
|
|
124 |
|
|
|
125 |
final NativeQuery<?> nativeQuery = session.createNativeQuery(
|
|
|
126 |
"SELECT (DATEDIFF(LAST_DAY(:startDate), :startDate) + 1) " +
|
|
|
127 |
" - (FLOOR((DATEDIFF(LAST_DAY(:startDate), :startDate) + (WEEKDAY(:startDate) + 1)) / 7)) " +
|
|
|
128 |
" - (SELECT COUNT(*) " +
|
|
|
129 |
" FROM logistics.publicholidays " +
|
|
|
130 |
" WHERE date BETWEEN :startDate AND LAST_DAY(:startDate) " +
|
|
|
131 |
" AND WEEKDAY(date) != 6) AS working_days"
|
|
|
132 |
);
|
|
|
133 |
|
|
|
134 |
// Set the start date parameter for each placeholder
|
|
|
135 |
nativeQuery.setParameter("startDate", startDateString);
|
|
|
136 |
|
|
|
137 |
Object result = nativeQuery.getSingleResult();
|
|
|
138 |
return result != null ? ((Number) result).intValue() : 0;
|
|
|
139 |
}
|
|
|
140 |
|
|
|
141 |
|
| 35044 |
ranu |
142 |
|
| 33917 |
ranu |
143 |
@Override
|
|
|
144 |
public List<RbmArrViewModel> getRbmTodayArr() throws Exception {
|
|
|
145 |
LocalDate todayDate = LocalDate.now();
|
|
|
146 |
return getRbmTodayArr(todayDate);
|
|
|
147 |
}
|
|
|
148 |
|
|
|
149 |
@Override
|
| 33997 |
ranu |
150 |
public List<RbmTargetAndAchievementsModel> getRbmTargetsAndAchievemnts(LocalDate startDate, LocalDate endDate) {
|
|
|
151 |
|
| 34002 |
ranu |
152 |
List<RbmTargetsModel> rbmTargetsList = rbmTargetsRepository.selectTargetsModelListByDates(startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
|
| 33997 |
ranu |
153 |
|
|
|
154 |
LOGGER.info("rbmTargetsList {}", rbmTargetsList);
|
|
|
155 |
// Group Targtes by RBM and Warehouse
|
| 34002 |
ranu |
156 |
Map<String, RbmTargetsModel> targetsMap = rbmTargetsList.stream()
|
| 33997 |
ranu |
157 |
.collect(Collectors.toMap(
|
|
|
158 |
a -> a.getRbmAuthId() + "-" + a.getWarehouseId(),
|
|
|
159 |
a -> a,
|
|
|
160 |
(a1, a2) -> mergeTargets(a1, a2) // Handle duplicates by merging
|
|
|
161 |
));
|
|
|
162 |
|
|
|
163 |
|
| 34002 |
ranu |
164 |
List<RbmAchievementsModel> rbmAchievements = rbmAchievementsRepository.selectAchievementsModelListByDates(startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX));
|
| 33997 |
ranu |
165 |
LOGGER.info("rbmTargetsList {}", rbmAchievements);
|
|
|
166 |
// Group achievements by RBM and Warehouse
|
| 34002 |
ranu |
167 |
Map<String, RbmAchievementsModel> achievementMap = rbmAchievements.stream()
|
| 33997 |
ranu |
168 |
.collect(Collectors.toMap(
|
|
|
169 |
a -> a.getRbmAuthId() + "-" + a.getWarehouseId(),
|
|
|
170 |
a -> a,
|
|
|
171 |
(a1, a2) -> mergeAchievements(a1, a2) // Handle duplicates by merging
|
|
|
172 |
));
|
|
|
173 |
|
|
|
174 |
return targetsMap.keySet().stream()
|
|
|
175 |
.map(key -> {
|
|
|
176 |
String[] parts = key.split("-");
|
|
|
177 |
int rbmAuthId = Integer.parseInt(parts[0]);
|
|
|
178 |
int warehouseId = Integer.parseInt(parts[1]);
|
|
|
179 |
|
| 34002 |
ranu |
180 |
RbmTargetsModel target = targetsMap.get(key);
|
|
|
181 |
RbmAchievementsModel achievement = achievementMap.getOrDefault(key, new RbmAchievementsModel());
|
| 33997 |
ranu |
182 |
|
|
|
183 |
RbmTargetAndAchievementsModel model = new RbmTargetAndAchievementsModel();
|
|
|
184 |
model.setAuthId(rbmAuthId);
|
|
|
185 |
model.setRbmName(target.getRbmName());
|
|
|
186 |
model.setWarehouseName(ProfitMandiConstants.WAREHOUSE_MAP.getOrDefault(warehouseId, "Unknown"));
|
|
|
187 |
|
|
|
188 |
// Set target values
|
| 34006 |
ranu |
189 |
model.setHidTarget((long) target.getHidTarget());
|
| 34098 |
ranu |
190 |
model.setRunningTarget((long) target.getRunningTarget());
|
| 34006 |
ranu |
191 |
model.setFastMovingTarget((long) target.getFastMovingTarget());
|
|
|
192 |
model.setSlowMovingTarget((long) target.getSlowMovingTarget());
|
|
|
193 |
model.setOtherMovingTarget((long) target.getOtherTarget());
|
| 33997 |
ranu |
194 |
|
|
|
195 |
// Set achievement values
|
| 34006 |
ranu |
196 |
model.setAchievedHid((long) achievement.getAchievedHidTarget());
|
| 34098 |
ranu |
197 |
model.setAchievedRunning((long) achievement.getAchievedRunningTarget());
|
| 34006 |
ranu |
198 |
model.setAchievedFastMoving((long) achievement.getAchievedFastMovingTarget());
|
|
|
199 |
model.setAchievedSlowMoving((long) achievement.getAchievedSlowMovingTarget());
|
|
|
200 |
model.setAchievedOtherMoving((long) achievement.getAchievedOtherTarget());
|
| 33997 |
ranu |
201 |
|
|
|
202 |
model.setTotalTarget(
|
| 34006 |
ranu |
203 |
(long) target.getHidTarget() +
|
| 34098 |
ranu |
204 |
(long) target.getRunningTarget() +
|
| 34006 |
ranu |
205 |
(long) target.getFastMovingTarget() +
|
|
|
206 |
(long) target.getSlowMovingTarget() +
|
|
|
207 |
(long) target.getOtherTarget()
|
| 33997 |
ranu |
208 |
);
|
|
|
209 |
model.setTotalAchievemnt(
|
| 34006 |
ranu |
210 |
(long) achievement.getAchievedHidTarget() +
|
| 34098 |
ranu |
211 |
(long) achievement.getAchievedRunningTarget() +
|
| 34006 |
ranu |
212 |
(long) achievement.getAchievedFastMovingTarget() +
|
|
|
213 |
(long) achievement.getAchievedSlowMovingTarget() +
|
|
|
214 |
(long) achievement.getAchievedOtherTarget()
|
| 33997 |
ranu |
215 |
);
|
|
|
216 |
|
|
|
217 |
return model;
|
|
|
218 |
})
|
|
|
219 |
.collect(Collectors.toList());
|
|
|
220 |
|
|
|
221 |
}
|
|
|
222 |
|
| 34002 |
ranu |
223 |
private RbmTargetsModel mergeTargets(RbmTargetsModel a1, RbmTargetsModel a2) {
|
| 33997 |
ranu |
224 |
|
|
|
225 |
// Merge logic for achievements (aggregate the target and achieved values)
|
| 34006 |
ranu |
226 |
a1.setHidTarget((a1.getHidTarget()) +
|
|
|
227 |
(a2.getHidTarget()));
|
| 33997 |
ranu |
228 |
|
| 34006 |
ranu |
229 |
a1.setFastMovingTarget((a1.getFastMovingTarget()) +
|
|
|
230 |
(a2.getFastMovingTarget()));
|
| 33997 |
ranu |
231 |
|
| 34006 |
ranu |
232 |
a1.setSlowMovingTarget((a1.getSlowMovingTarget()) +
|
|
|
233 |
(a2.getSlowMovingTarget()));
|
| 33997 |
ranu |
234 |
|
| 34098 |
ranu |
235 |
a1.setRunningTarget((a1.getRunningTarget()) +
|
|
|
236 |
(a2.getRunningTarget()));
|
| 33997 |
ranu |
237 |
|
| 34006 |
ranu |
238 |
a1.setOtherTarget((a1.getOtherTarget()) +
|
|
|
239 |
(a2.getOtherTarget()));
|
| 33997 |
ranu |
240 |
return a1;
|
|
|
241 |
}
|
|
|
242 |
|
| 34002 |
ranu |
243 |
private RbmAchievementsModel mergeAchievements(RbmAchievementsModel a1, RbmAchievementsModel a2) {
|
| 33997 |
ranu |
244 |
// Merge logic for achievements (aggregate the target and achieved values)
|
| 34006 |
ranu |
245 |
a1.setAchievedHidTarget((a1.getAchievedHidTarget()) +
|
|
|
246 |
(a2.getAchievedHidTarget()));
|
| 33997 |
ranu |
247 |
|
| 34098 |
ranu |
248 |
a1.setAchievedRunningTarget((a1.getAchievedRunningTarget()) +
|
|
|
249 |
(a2.getAchievedRunningTarget()));
|
| 33997 |
ranu |
250 |
|
| 34006 |
ranu |
251 |
a1.setAchievedFastMovingTarget((a1.getAchievedFastMovingTarget()) +
|
|
|
252 |
(a2.getAchievedFastMovingTarget()));
|
| 33997 |
ranu |
253 |
|
| 34006 |
ranu |
254 |
a1.setAchievedSlowMovingTarget((a1.getAchievedSlowMovingTarget()) +
|
|
|
255 |
(a2.getAchievedSlowMovingTarget()));
|
| 33997 |
ranu |
256 |
|
| 34006 |
ranu |
257 |
a1.setAchievedOtherTarget((a1.getAchievedOtherTarget()) +
|
|
|
258 |
(a2.getAchievedOtherTarget()));
|
| 33997 |
ranu |
259 |
|
|
|
260 |
return a1;
|
|
|
261 |
}
|
| 34002 |
ranu |
262 |
|
| 33997 |
ranu |
263 |
@Override
|
| 33917 |
ranu |
264 |
public List<RbmArrViewModel> getRbmTodayArr(LocalDate todayDate) throws Exception {
|
|
|
265 |
|
|
|
266 |
LocalDate startDateOfMonthDay1 = LocalDate.now().withDayOfMonth(1);
|
|
|
267 |
|
| 34289 |
ranu |
268 |
List<WarehouseRbmTargetModel> warehouseRbmTargetModelList = this.getWarehouseWiseRbmMonthlyTarget();
|
|
|
269 |
List<WarehouseRbmTargetModel> warehouseRbmTargetModels = warehouseRbmTargetModelList.stream().filter(x -> x.getMonthlyTarget() > 0).collect(Collectors.toList());
|
|
|
270 |
LOGGER.info("warehouseRbmTargetModels {}", warehouseRbmTargetModels);
|
|
|
271 |
List<TodayAchievedMovementModel> todayAchievedMovementModels = getMovementWiseAchievementByDate(todayDate, todayDate.plusDays(1));
|
| 33917 |
ranu |
272 |
|
|
|
273 |
List<MTDAchievedTargetModel> mtdAchievedTargetModels = getDateWiseAchievedTargetOfRbm(startDateOfMonthDay1, todayDate);
|
|
|
274 |
|
| 35044 |
ranu |
275 |
int remainingWorkingDaysCount = (int) getRemainingDaysInMonth(todayDate);
|
| 33917 |
ranu |
276 |
|
| 33926 |
ranu |
277 |
List<RbmTargets> todayRbmTargetsList = rbmTargetsRepository.selectTargetsByDates(todayDate.atStartOfDay(), todayDate.atTime(LocalTime.MAX));
|
| 33917 |
ranu |
278 |
|
| 33926 |
ranu |
279 |
LOGGER.info("todayRbmTargetsList {}", todayRbmTargetsList);
|
| 33917 |
ranu |
280 |
|
|
|
281 |
List<RbmArrViewModel> rbmArrViewModels = new ArrayList<>();
|
|
|
282 |
|
| 34028 |
ranu |
283 |
if (!todayRbmTargetsList.isEmpty()) {
|
| 33917 |
ranu |
284 |
|
| 35454 |
amit |
285 |
// OPTIMIZED: Pre-build maps for O(1) lookup instead of O(n) filter in each iteration
|
|
|
286 |
// Map key: "authId-warehouseId"
|
|
|
287 |
Map<String, Double> mtdAchievedMap = mtdAchievedTargetModels.stream()
|
|
|
288 |
.collect(Collectors.groupingBy(
|
|
|
289 |
x -> x.getAuthId() + "-" + x.getWarehouseId(),
|
|
|
290 |
Collectors.summingDouble(MTDAchievedTargetModel::getAcheivedMonthlyTarget)
|
|
|
291 |
));
|
|
|
292 |
|
|
|
293 |
Map<String, TodayAchievedMovementModel> todayAchievedMap = todayAchievedMovementModels.stream()
|
|
|
294 |
.collect(Collectors.toMap(
|
|
|
295 |
x -> x.getAuthId() + "-" + x.getWarehouseId(),
|
|
|
296 |
x -> x,
|
|
|
297 |
(a, b) -> a
|
|
|
298 |
));
|
|
|
299 |
|
|
|
300 |
Map<String, RbmTargets> todayRbmTargetsMap = todayRbmTargetsList.stream()
|
|
|
301 |
.collect(Collectors.toMap(
|
|
|
302 |
x -> x.getRbmAuthId() + "-" + x.getWarehouseId(),
|
|
|
303 |
x -> x,
|
|
|
304 |
(a, b) -> a
|
|
|
305 |
));
|
|
|
306 |
|
| 34028 |
ranu |
307 |
for (WarehouseRbmTargetModel rbmTarget : warehouseRbmTargetModels) {
|
| 33917 |
ranu |
308 |
|
| 35454 |
amit |
309 |
String lookupKey = rbmTarget.getAuthId() + "-" + rbmTarget.getWarehouseId();
|
|
|
310 |
|
| 34028 |
ranu |
311 |
float monthlyTarget = rbmTarget.getMonthlyTarget();
|
| 35454 |
amit |
312 |
float achievedSoFar = mtdAchievedMap.getOrDefault(lookupKey, 0.0).floatValue();
|
| 33917 |
ranu |
313 |
|
| 34028 |
ranu |
314 |
float remainingTarget = monthlyTarget - achievedSoFar;
|
| 33953 |
ranu |
315 |
|
| 34028 |
ranu |
316 |
float todayTarget = (remainingWorkingDaysCount > 0 && remainingTarget > 0) ? remainingTarget / remainingWorkingDaysCount : 0;
|
|
|
317 |
|
| 33926 |
ranu |
318 |
String warehouseName = ProfitMandiConstants.WAREHOUSE_MAP.getOrDefault(rbmTarget.getWarehouseId(), "Unknown");
|
| 33917 |
ranu |
319 |
|
| 34288 |
ranu |
320 |
LOGGER.info("rbmTarget ==== {}", rbmTarget);
|
| 34281 |
ranu |
321 |
|
| 35454 |
amit |
322 |
TodayAchievedMovementModel todayAchievedMovementModel = todayAchievedMap.get(lookupKey);
|
| 34283 |
ranu |
323 |
|
| 35454 |
amit |
324 |
RbmTargets todayRbmTargets = todayRbmTargetsMap.get(lookupKey);
|
| 34285 |
ranu |
325 |
|
| 35454 |
amit |
326 |
if (todayRbmTargets != null) {
|
| 34034 |
ranu |
327 |
LOGGER.info("todayRbmTargets {}", todayRbmTargets);
|
|
|
328 |
RbmArrViewModel viewModel = new RbmArrViewModel();
|
| 33917 |
ranu |
329 |
|
| 34034 |
ranu |
330 |
viewModel.setAuthId(rbmTarget.getAuthId());
|
|
|
331 |
viewModel.setRbmName(rbmTarget.getRbmName());
|
|
|
332 |
viewModel.setWarehouseName(warehouseName);
|
|
|
333 |
viewModel.setTodayTarget(Math.round(todayTarget));
|
|
|
334 |
viewModel.setMonthlyTarget(Math.round(monthlyTarget));
|
|
|
335 |
viewModel.setMtdAchievedTarget(Math.round(achievedSoFar));
|
| 33926 |
ranu |
336 |
|
| 34034 |
ranu |
337 |
viewModel.setTodayHidTarget(Math.round((todayRbmTargets.getHidTarget())));
|
|
|
338 |
viewModel.setTodayFastMovingTarget(Math.round(todayRbmTargets.getFastMovingTarget()));
|
| 34098 |
ranu |
339 |
viewModel.setTodaySlowMovingTarget(Math.round(todayRbmTargets.getSlowMovingtarget()));
|
|
|
340 |
viewModel.setTodayRunningTarget(Math.round(todayRbmTargets.getRunningtarget()));
|
| 34034 |
ranu |
341 |
viewModel.setTodayOtherMovingTarget(Math.round(todayRbmTargets.getOtherTarget()));
|
| 33926 |
ranu |
342 |
|
| 34283 |
ranu |
343 |
if (todayAchievedMovementModel != null) {
|
|
|
344 |
viewModel.setTodayAchievedHidTarget(Math.round(todayAchievedMovementModel.getHidBilled()));
|
|
|
345 |
viewModel.setTodayAchievedFastMovingTarget(Math.round(todayAchievedMovementModel.getFastMovingBilled()));
|
|
|
346 |
viewModel.setTodayAchievedSlowMovingTarget(Math.round(todayAchievedMovementModel.getSlowMovinBilled()));
|
|
|
347 |
viewModel.setTodayAchievedRunningTarget(Math.round(todayAchievedMovementModel.getRunningBilled()));
|
|
|
348 |
viewModel.setTodayAchievedOtherMovingTarget(Math.round(todayAchievedMovementModel.getOtherBilled()));
|
|
|
349 |
viewModel.setTotalAchievedTarget(Math.round(todayAchievedMovementModel.getHidBilled() + todayAchievedMovementModel.getFastMovingBilled() + todayAchievedMovementModel.getSlowMovinBilled() + todayAchievedMovementModel.getRunningBilled() + todayAchievedMovementModel.getOtherBilled()));
|
|
|
350 |
} else {
|
|
|
351 |
viewModel.setTodayAchievedHidTarget(0);
|
|
|
352 |
viewModel.setTodayAchievedFastMovingTarget(0);
|
|
|
353 |
viewModel.setTodayAchievedSlowMovingTarget(0);
|
|
|
354 |
viewModel.setTodayAchievedRunningTarget(0);
|
|
|
355 |
viewModel.setTodayAchievedOtherMovingTarget(0);
|
|
|
356 |
viewModel.setTotalAchievedTarget(0);
|
|
|
357 |
}
|
| 34034 |
ranu |
358 |
rbmArrViewModels.add(viewModel);
|
|
|
359 |
} else {
|
|
|
360 |
LOGGER.info("No matching RbmTargets found for AuthId: {} and rbmname {} and WarehouseId: {}", rbmTarget.getAuthId(), rbmTarget.getRbmName(), rbmTarget.getWarehouseId());
|
|
|
361 |
}
|
| 33917 |
ranu |
362 |
|
| 34034 |
ranu |
363 |
|
|
|
364 |
|
| 34028 |
ranu |
365 |
}
|
| 33917 |
ranu |
366 |
}
|
|
|
367 |
|
|
|
368 |
LOGGER.info("rbmArrViewModels {}", rbmArrViewModels);
|
|
|
369 |
return rbmArrViewModels;
|
|
|
370 |
}
|
|
|
371 |
|
| 33926 |
ranu |
372 |
@Override
|
|
|
373 |
public void setMovementWiseRbmTargets() {
|
|
|
374 |
LocalDate todayDate = LocalDate.now();
|
| 33917 |
ranu |
375 |
|
| 33926 |
ranu |
376 |
LocalDate startDateOfMonthDay1 = LocalDate.now().withDayOfMonth(1);
|
|
|
377 |
|
|
|
378 |
List<WarehouseRbmTargetModel> warehouseRbmTargetModels = this.getWarehouseWiseRbmMonthlyTarget();
|
|
|
379 |
|
|
|
380 |
List<MTDAchievedTargetModel> mtdAchievedTargetModels = getDateWiseAchievedTargetOfRbm(startDateOfMonthDay1, todayDate);
|
|
|
381 |
|
|
|
382 |
|
| 35044 |
ranu |
383 |
int remainingWorkingDaysCount = (int) getRemainingDaysInMonth(todayDate);
|
| 33926 |
ranu |
384 |
|
|
|
385 |
List<WarehouseMobileStockByMovementModel> warehouseMobileStockByMovementModels = getWarehouseMobileStockByMovement();
|
|
|
386 |
|
| 35454 |
amit |
387 |
// OPTIMIZED: Pre-build maps for O(1) lookup instead of O(n) filter in each iteration
|
|
|
388 |
Map<String, Double> mtdAchievedMap = mtdAchievedTargetModels.stream()
|
|
|
389 |
.collect(Collectors.groupingBy(
|
|
|
390 |
x -> x.getAuthId() + "-" + x.getWarehouseId(),
|
|
|
391 |
Collectors.summingDouble(MTDAchievedTargetModel::getAcheivedMonthlyTarget)
|
|
|
392 |
));
|
|
|
393 |
|
|
|
394 |
Map<Integer, WarehouseMobileStockByMovementModel> warehouseStockMap = warehouseMobileStockByMovementModels.stream()
|
|
|
395 |
.collect(Collectors.toMap(
|
|
|
396 |
WarehouseMobileStockByMovementModel::getWarehouseId,
|
|
|
397 |
x -> x,
|
|
|
398 |
(a, b) -> a
|
|
|
399 |
));
|
|
|
400 |
|
| 33926 |
ranu |
401 |
for (WarehouseRbmTargetModel rbmTarget : warehouseRbmTargetModels) {
|
|
|
402 |
|
| 35454 |
amit |
403 |
String lookupKey = rbmTarget.getAuthId() + "-" + rbmTarget.getWarehouseId();
|
|
|
404 |
|
| 33926 |
ranu |
405 |
float monthlyTarget = rbmTarget.getMonthlyTarget();
|
| 35454 |
amit |
406 |
float achievedSoFar = mtdAchievedMap.getOrDefault(lookupKey, 0.0).floatValue();
|
| 33926 |
ranu |
407 |
|
|
|
408 |
|
|
|
409 |
float remainingTarget = monthlyTarget - achievedSoFar;
|
| 33953 |
ranu |
410 |
LOGGER.info("remainingTarget {}", remainingTarget);
|
| 33926 |
ranu |
411 |
|
| 33953 |
ranu |
412 |
float todayTarget = (remainingWorkingDaysCount > 0 && remainingTarget > 0) ? remainingTarget / remainingWorkingDaysCount : 0;
|
|
|
413 |
LOGGER.info("todayTarget {}", todayTarget);
|
|
|
414 |
|
| 33926 |
ranu |
415 |
// Get the warehouse stock data
|
| 35454 |
amit |
416 |
WarehouseMobileStockByMovementModel warehouseMobileStockByMovementModel = warehouseStockMap.get(rbmTarget.getWarehouseId());
|
| 33926 |
ranu |
417 |
|
|
|
418 |
|
|
|
419 |
if (warehouseMobileStockByMovementModel != null) {
|
|
|
420 |
|
|
|
421 |
// Total stock value for this warehouse
|
|
|
422 |
float totalStockValue = warehouseMobileStockByMovementModel.getTotalAvailabilityPrice();
|
|
|
423 |
|
|
|
424 |
// Calculate target allocation based on stock value proportion
|
|
|
425 |
float hidTarget = (warehouseMobileStockByMovementModel.getTotalHidCatalogPrice() / totalStockValue) * todayTarget;
|
|
|
426 |
float fastMovingTarget = (warehouseMobileStockByMovementModel.getTotalFastMovingCatalogPrice() / totalStockValue) * todayTarget;
|
|
|
427 |
float slowMovingTarget = (warehouseMobileStockByMovementModel.getTotalSlowMovingCatalogPrice() / totalStockValue) * todayTarget;
|
| 34098 |
ranu |
428 |
float runningTarget = (warehouseMobileStockByMovementModel.getTotalRunningCatalogPrice() / totalStockValue) * todayTarget;
|
| 33926 |
ranu |
429 |
float otherTarget = (warehouseMobileStockByMovementModel.getTotalOtherCategoryCatalogPrice() / totalStockValue) * todayTarget;
|
|
|
430 |
|
|
|
431 |
RbmTargets rbmTargets = new RbmTargets();
|
|
|
432 |
rbmTargets.setWarehouseId(rbmTarget.getWarehouseId());
|
|
|
433 |
rbmTargets.setRbmAuthId(rbmTarget.getAuthId());
|
|
|
434 |
rbmTargets.setRbmName(rbmTarget.getRbmName());
|
| 34098 |
ranu |
435 |
rbmTargets.setRunningtarget(runningTarget);
|
| 33926 |
ranu |
436 |
rbmTargets.setHidTarget(hidTarget);
|
|
|
437 |
rbmTargets.setFastMovingTarget(fastMovingTarget);
|
| 34098 |
ranu |
438 |
rbmTargets.setSlowMovingtarget(slowMovingTarget);
|
| 33926 |
ranu |
439 |
rbmTargets.setOtherTarget(otherTarget);
|
|
|
440 |
rbmTargets.setCreateTimestamp(LocalDateTime.now());
|
|
|
441 |
|
|
|
442 |
rbmTargetsRepository.persist(rbmTargets);
|
|
|
443 |
|
|
|
444 |
}
|
|
|
445 |
}
|
|
|
446 |
|
|
|
447 |
}
|
|
|
448 |
|
|
|
449 |
|
| 33985 |
ranu |
450 |
@Override
|
|
|
451 |
public void setMovementWiseRbmAchievement() {
|
|
|
452 |
LocalDate todayDate = LocalDate.now();
|
|
|
453 |
|
| 34055 |
ranu |
454 |
List<TodayAchievedMovementModel> todayAchievedMovementModels = getMovementWiseAchievementByDate(todayDate, todayDate.plusDays(1));
|
| 33985 |
ranu |
455 |
|
|
|
456 |
|
|
|
457 |
for (TodayAchievedMovementModel achievement : todayAchievedMovementModels) {
|
|
|
458 |
|
|
|
459 |
RbmAchievements rbmAchievements = new RbmAchievements();
|
|
|
460 |
|
|
|
461 |
rbmAchievements.setRbmAuthId(achievement.getAuthId());
|
|
|
462 |
rbmAchievements.setRbmName(achievement.getRbmName());
|
|
|
463 |
rbmAchievements.setWarehouseId(achievement.getWarehouseId());
|
|
|
464 |
rbmAchievements.setAchievedHidTarget(achievement.getHidBilled());
|
|
|
465 |
rbmAchievements.setAchievedFastMovingTarget(achievement.getFastMovingBilled());
|
| 34098 |
ranu |
466 |
rbmAchievements.setAchievedSlowMovingTarget(achievement.getSlowMovinBilled());
|
|
|
467 |
rbmAchievements.setAchievedRunningTarget(achievement.getRunningBilled());
|
| 34012 |
ranu |
468 |
rbmAchievements.setAchievedOtherTarget(achievement.getOtherBilled());
|
| 33985 |
ranu |
469 |
rbmAchievements.setCreateTimestamp(LocalDateTime.now());
|
|
|
470 |
|
|
|
471 |
rbmAchievementsRepository.persist(rbmAchievements);
|
|
|
472 |
|
|
|
473 |
}
|
|
|
474 |
|
|
|
475 |
}
|
|
|
476 |
|
| 34055 |
ranu |
477 |
@Override
|
|
|
478 |
public List<Sold15daysOldAgingModel> getAgingSale(LocalDate startDate, LocalDate endDate) {
|
|
|
479 |
Session session = sessionFactory.getCurrentSession();
|
|
|
480 |
final TypedQuery<Sold15daysOldAgingModel> typedQuerySimilar = session.createNamedQuery("Aging.SoldAgingModel", Sold15daysOldAgingModel.class);
|
| 34056 |
ranu |
481 |
typedQuerySimilar.setParameter("startDate", startDate);
|
|
|
482 |
typedQuerySimilar.setParameter("endDate", endDate);
|
| 34055 |
ranu |
483 |
return typedQuerySimilar.getResultList();
|
| 33985 |
ranu |
484 |
|
| 34055 |
ranu |
485 |
}
|
|
|
486 |
|
| 34103 |
ranu |
487 |
@Override
|
|
|
488 |
public List<RbmBilledFofoIdsModel> getDateWiseBilledFofoIdByRbm(LocalDate startDate, LocalDate endDate) {
|
|
|
489 |
Session session = sessionFactory.getCurrentSession();
|
|
|
490 |
final TypedQuery<RbmBilledFofoIdsModel> typedQuerySimilar = session.createNamedQuery("RBM.RbmBilledFofoId", RbmBilledFofoIdsModel.class);
|
|
|
491 |
typedQuerySimilar.setParameter("startDate", startDate);
|
|
|
492 |
typedQuerySimilar.setParameter("endDate", endDate);
|
|
|
493 |
return typedQuerySimilar.getResultList();
|
| 35453 |
amit |
494 |
}
|
| 34103 |
ranu |
495 |
|
| 35453 |
amit |
496 |
@Override
|
|
|
497 |
public List<RbmWeeklyBillingModel> getWeeklyBillingDataForMonth(LocalDate monthStart, LocalDate monthEnd) {
|
|
|
498 |
Session session = sessionFactory.getCurrentSession();
|
|
|
499 |
final TypedQuery<RbmWeeklyBillingModel> typedQuery = session.createNamedQuery("RBM.WeeklyBilling", RbmWeeklyBillingModel.class);
|
|
|
500 |
typedQuery.setParameter("startDate", monthStart);
|
|
|
501 |
typedQuery.setParameter("endDate", monthEnd);
|
|
|
502 |
return typedQuery.getResultList();
|
| 34103 |
ranu |
503 |
}
|
|
|
504 |
|
| 34055 |
ranu |
505 |
public List<Our15DaysOldAgingStock> our15DaysAgingStock() {
|
|
|
506 |
Session session = sessionFactory.getCurrentSession();
|
|
|
507 |
final TypedQuery<Our15DaysOldAgingStock> typedQuerySimilar = session.createNamedQuery("Aging.15DaysOurStock", Our15DaysOldAgingStock.class);
|
|
|
508 |
return typedQuerySimilar.getResultList();
|
|
|
509 |
|
|
|
510 |
}
|
|
|
511 |
|
| 34397 |
ranu |
512 |
@Autowired
|
|
|
513 |
OrderRepository orderRepository;
|
| 34055 |
ranu |
514 |
|
| 34397 |
ranu |
515 |
@Override
|
| 34641 |
ranu |
516 |
public double calculateFofoIdTodayTarget(int fofoId, double secondryMtd,LocalDate date) {
|
| 34397 |
ranu |
517 |
|
|
|
518 |
MonthlyTarget monthlyTarget = monthlyTargetRepository.selectByDateAndFofoId(YearMonth.now(), fofoId);
|
| 34404 |
ranu |
519 |
if (monthlyTarget == null) {
|
|
|
520 |
// Log or handle as needed
|
|
|
521 |
return 0; // or -1 or some fallback
|
|
|
522 |
}
|
| 34397 |
ranu |
523 |
|
|
|
524 |
double remainingTarget = monthlyTarget.getPurchaseTarget() - secondryMtd;
|
| 34880 |
ranu |
525 |
// double remainingWorkingDays = getWorkingDaysCount(date);
|
|
|
526 |
double remainingWorkingDays = (double) getRemainingDaysInMonth(date);
|
| 34397 |
ranu |
527 |
|
|
|
528 |
|
| 34716 |
ranu |
529 |
|
| 34397 |
ranu |
530 |
if (remainingWorkingDays == 0) return remainingTarget; // Last day
|
| 34716 |
ranu |
531 |
LOGGER.info("remainingWorkingDays {}", remainingWorkingDays);
|
|
|
532 |
LOGGER.info("remainingTarget {}", remainingTarget);
|
| 34397 |
ranu |
533 |
|
|
|
534 |
return (int) Math.ceil(remainingTarget / remainingWorkingDays);
|
|
|
535 |
}
|
|
|
536 |
|
| 34880 |
ranu |
537 |
@Override
|
|
|
538 |
public long getRemainingDaysInMonth(LocalDate date) {
|
|
|
539 |
LocalDate lastDayOfMonth = YearMonth.from(date).atEndOfMonth();
|
| 34397 |
ranu |
540 |
|
| 34880 |
ranu |
541 |
long totalDays = ChronoUnit.DAYS.between(date, lastDayOfMonth) + 1;
|
| 34397 |
ranu |
542 |
|
| 34880 |
ranu |
543 |
// Count Sundays manually
|
|
|
544 |
long sundayCount = 0;
|
|
|
545 |
LocalDate current = date;
|
|
|
546 |
while (!current.isAfter(lastDayOfMonth)) {
|
|
|
547 |
if (current.getDayOfWeek() == DayOfWeek.SUNDAY) {
|
|
|
548 |
sundayCount++;
|
|
|
549 |
}
|
|
|
550 |
current = current.plusDays(1);
|
|
|
551 |
}
|
|
|
552 |
|
|
|
553 |
// Public holidays in the range
|
|
|
554 |
long publicHolidays = publicHolidaysRepository
|
|
|
555 |
.selectAllBetweenDates(date, lastDayOfMonth)
|
|
|
556 |
.size();
|
|
|
557 |
|
|
|
558 |
long remainingDays = totalDays - sundayCount - publicHolidays;
|
|
|
559 |
|
|
|
560 |
LOGGER.info("remainingDays {}", remainingDays);
|
|
|
561 |
LOGGER.info("totalDays {}", totalDays);
|
|
|
562 |
LOGGER.info("sundays {}", sundayCount);
|
|
|
563 |
LOGGER.info("publicHolidays {}", publicHolidays);
|
|
|
564 |
|
|
|
565 |
return remainingDays;
|
|
|
566 |
}
|
|
|
567 |
|
| 35631 |
ranu |
568 |
@Autowired
|
|
|
569 |
PositionRepository positionRepository;
|
| 34880 |
ranu |
570 |
|
| 35631 |
ranu |
571 |
@Autowired
|
|
|
572 |
CsService csService;
|
| 34880 |
ranu |
573 |
|
| 35631 |
ranu |
574 |
@Autowired
|
|
|
575 |
FofoStoreRepository fofoStoreRepository;
|
|
|
576 |
|
|
|
577 |
@Autowired
|
|
|
578 |
AuthRepository authRepository;
|
|
|
579 |
|
|
|
580 |
@Autowired
|
|
|
581 |
LoanRepository loanRepository;
|
|
|
582 |
|
|
|
583 |
@Autowired
|
|
|
584 |
PartnerCollectionService partnerCollectionService;
|
|
|
585 |
|
|
|
586 |
@Autowired
|
|
|
587 |
PartnerCollectionRemarkRepository partnerCollectionRemarkRepository;
|
|
|
588 |
|
|
|
589 |
@Autowired
|
|
|
590 |
RbmCallSequenceLogRepository rbmCallSequenceLogRepository;
|
|
|
591 |
|
|
|
592 |
@Autowired
|
|
|
593 |
com.spice.profitmandi.dao.repository.cs.TicketRepository ticketRepository;
|
|
|
594 |
|
| 35702 |
ranu |
595 |
@Autowired
|
|
|
596 |
com.spice.profitmandi.dao.repository.cs.AgentCallLogRepository agentCallLogRepository;
|
|
|
597 |
|
| 35631 |
ranu |
598 |
@Override
|
|
|
599 |
public List<RbmCallTargetModel> getRbmCallTargetModels() throws Exception {
|
|
|
600 |
long methodStart = System.currentTimeMillis();
|
|
|
601 |
List<RbmCallTargetModel> rbmCallTargetModels = new ArrayList<>();
|
|
|
602 |
|
|
|
603 |
// Get all RBM positions (L1 and L2)
|
|
|
604 |
long start = System.currentTimeMillis();
|
|
|
605 |
List<Position> allRbmPositions = positionRepository
|
|
|
606 |
.selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_RBM).stream()
|
|
|
607 |
.filter(x -> Arrays.asList(EscalationType.L1, EscalationType.L2).contains(x.getEscalationType()))
|
|
|
608 |
.collect(Collectors.toList());
|
|
|
609 |
|
|
|
610 |
// Separate L1 and L2 auth IDs
|
|
|
611 |
List<Integer> l1AuthIds = allRbmPositions.stream()
|
|
|
612 |
.filter(p -> EscalationType.L1.equals(p.getEscalationType()))
|
|
|
613 |
.map(Position::getAuthUserId).distinct().collect(Collectors.toList());
|
|
|
614 |
List<Integer> l2AuthIds = allRbmPositions.stream()
|
|
|
615 |
.filter(p -> EscalationType.L2.equals(p.getEscalationType()))
|
|
|
616 |
.map(Position::getAuthUserId).distinct().collect(Collectors.toList());
|
|
|
617 |
|
|
|
618 |
// Union of all auth IDs for batch fetching
|
|
|
619 |
List<Integer> rbmPositionsAuthIds = allRbmPositions.stream()
|
|
|
620 |
.map(Position::getAuthUserId).distinct().collect(Collectors.toList());
|
|
|
621 |
LOGGER.info("RBM Call Target - RBM positions fetch: {}ms, L1: {}, L2: {}", System.currentTimeMillis() - start, l1AuthIds.size(), l2AuthIds.size());
|
|
|
622 |
|
|
|
623 |
start = System.currentTimeMillis();
|
|
|
624 |
Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();
|
|
|
625 |
LOGGER.info("RBM Call Target - StoreGuyMap fetch: {}ms", System.currentTimeMillis() - start);
|
|
|
626 |
|
|
|
627 |
LocalDateTime startDate = LocalDate.now().atStartOfDay();
|
|
|
628 |
LocalDate firstOfMonth = LocalDate.now().withDayOfMonth(1);
|
|
|
629 |
LocalDate endOfMonth = LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth()).plusDays(1);
|
|
|
630 |
|
|
|
631 |
// Get auth user map
|
|
|
632 |
start = System.currentTimeMillis();
|
|
|
633 |
Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(rbmPositionsAuthIds).stream()
|
|
|
634 |
.collect(Collectors.toMap(AuthUser::getId, au -> au));
|
|
|
635 |
LOGGER.info("RBM Call Target - AuthUser fetch: {}ms", System.currentTimeMillis() - start);
|
|
|
636 |
|
|
|
637 |
// Batch fetch positions by auth IDs (to check if RBM is L1)
|
|
|
638 |
start = System.currentTimeMillis();
|
|
|
639 |
Map<Integer, List<Position>> positionsByAuthId = positionRepository.selectPositionByAuthIds(rbmPositionsAuthIds).stream()
|
|
|
640 |
.collect(Collectors.groupingBy(Position::getAuthUserId));
|
|
|
641 |
LOGGER.info("RBM Call Target - Positions by AuthId fetch: {}ms", System.currentTimeMillis() - start);
|
|
|
642 |
|
|
|
643 |
// Get all fofo IDs for all RBMs
|
|
|
644 |
Set<Integer> allFofoIds = new HashSet<>();
|
|
|
645 |
Map<Integer, List<Integer>> rbmToFofoIdsMap = new HashMap<>();
|
|
|
646 |
for (int rbmAuthId : rbmPositionsAuthIds) {
|
|
|
647 |
AuthUser au = authUserMap.get(rbmAuthId);
|
|
|
648 |
if (au != null && storeGuyMap.containsKey(au.getEmailId())) {
|
|
|
649 |
List<Integer> fofoIds = new ArrayList<>(storeGuyMap.get(au.getEmailId()));
|
|
|
650 |
allFofoIds.addAll(fofoIds);
|
|
|
651 |
rbmToFofoIdsMap.put(rbmAuthId, fofoIds);
|
|
|
652 |
}
|
|
|
653 |
}
|
|
|
654 |
// Fetch escalated tickets for L2 early so their fofoIds are included in batch fetches
|
|
|
655 |
List<Ticket> escalatedTickets = Collections.emptyList();
|
|
|
656 |
Map<Integer, List<Integer>> l2AuthIdToFofoIds = new HashMap<>();
|
|
|
657 |
if (!l2AuthIds.isEmpty()) {
|
|
|
658 |
start = System.currentTimeMillis();
|
|
|
659 |
escalatedTickets = ticketRepository.selectOpenEscalatedTicketsByAuthIds(l2AuthIds);
|
|
|
660 |
LOGGER.info("RBM Call Target - Escalated tickets fetch: {}ms, count: {}", System.currentTimeMillis() - start, escalatedTickets.size());
|
|
|
661 |
|
|
|
662 |
for (int l2AuthId : l2AuthIds) {
|
|
|
663 |
List<Integer> l2FofoIds = escalatedTickets.stream()
|
|
|
664 |
.filter(t -> t.getL2AuthUser() == l2AuthId
|
|
|
665 |
|| t.getL3AuthUser() == l2AuthId
|
|
|
666 |
|| t.getL4AuthUser() == l2AuthId
|
|
|
667 |
|| t.getL5AuthUser() == l2AuthId)
|
|
|
668 |
.map(Ticket::getFofoId)
|
|
|
669 |
.distinct()
|
|
|
670 |
.collect(Collectors.toList());
|
|
|
671 |
l2AuthIdToFofoIds.put(l2AuthId, l2FofoIds);
|
|
|
672 |
allFofoIds.addAll(l2FofoIds);
|
|
|
673 |
}
|
|
|
674 |
}
|
|
|
675 |
LOGGER.info("RBM Call Target - Total fofo IDs to process: {}", allFofoIds.size());
|
|
|
676 |
|
|
|
677 |
// Get only needed fofo stores (OPTIMIZED - was fetching ALL stores before)
|
|
|
678 |
start = System.currentTimeMillis();
|
|
|
679 |
Map<Integer, FofoStore> fofoStoresMap = new HashMap<>();
|
|
|
680 |
if (!allFofoIds.isEmpty()) {
|
|
|
681 |
try {
|
|
|
682 |
fofoStoresMap = fofoStoreRepository.selectByRetailerIds(new ArrayList<>(allFofoIds)).stream()
|
|
|
683 |
.collect(Collectors.toMap(FofoStore::getId, x -> x, (a, b) -> a));
|
|
|
684 |
} catch (ProfitMandiBusinessException e) {
|
|
|
685 |
LOGGER.error("Error fetching fofo stores", e);
|
|
|
686 |
}
|
|
|
687 |
}
|
|
|
688 |
LOGGER.info("RBM Call Target - FofoStores fetch (only needed): {}ms, count: {}", System.currentTimeMillis() - start, fofoStoresMap.size());
|
|
|
689 |
|
|
|
690 |
// Batch fetch max remark ids for all fofoIds (for escalation filtering)
|
|
|
691 |
start = System.currentTimeMillis();
|
|
|
692 |
Map<Integer, PartnerCollectionRemark> allPartnerCollectionRemarks = new HashMap<>();
|
|
|
693 |
if (!allFofoIds.isEmpty()) {
|
|
|
694 |
List<Integer> allRemarkIds = partnerCollectionRemarkRepository.selectMaxRemarkId(new ArrayList<>(allFofoIds));
|
|
|
695 |
if (!allRemarkIds.isEmpty()) {
|
|
|
696 |
allPartnerCollectionRemarks = partnerCollectionRemarkRepository.selectByIds(allRemarkIds).stream()
|
|
|
697 |
.collect(Collectors.toMap(PartnerCollectionRemark::getFofoId, x -> x, (a, b) -> a));
|
|
|
698 |
}
|
|
|
699 |
}
|
|
|
700 |
LOGGER.info("RBM Call Target - PartnerCollectionRemarks fetch: {}ms", System.currentTimeMillis() - start);
|
|
|
701 |
|
|
|
702 |
// Batch fetch collection RANK map for all fofoIds (OPTIMIZED - only fetches rank, not full model)
|
|
|
703 |
start = System.currentTimeMillis();
|
|
|
704 |
Map<Integer, Integer> allCollectionRankMap = new HashMap<>();
|
|
|
705 |
if (!allFofoIds.isEmpty()) {
|
|
|
706 |
try {
|
|
|
707 |
allCollectionRankMap = partnerCollectionService.getCollectionRankMap(new ArrayList<>(allFofoIds), startDate);
|
|
|
708 |
} catch (ProfitMandiBusinessException e) {
|
|
|
709 |
LOGGER.error("Error fetching collection rank map for all fofoIds", e);
|
|
|
710 |
}
|
|
|
711 |
}
|
|
|
712 |
LOGGER.info("RBM Call Target - CollectionRankMap fetch (OPTIMIZED): {}ms", System.currentTimeMillis() - start);
|
|
|
713 |
|
| 35669 |
ranu |
714 |
// Get MTD billing data for zero billing calculation and partner counts
|
| 35631 |
ranu |
715 |
start = System.currentTimeMillis();
|
|
|
716 |
List<RbmWeeklyBillingModel> mtdBillingData = getWeeklyBillingDataForMonth(firstOfMonth, endOfMonth);
|
|
|
717 |
Set<Integer> allMtdBilledFofoIds = mtdBillingData.stream()
|
|
|
718 |
.filter(RbmWeeklyBillingModel::isMtdBilled)
|
|
|
719 |
.map(RbmWeeklyBillingModel::getFofoId)
|
|
|
720 |
.collect(Collectors.toSet());
|
| 35669 |
ranu |
721 |
// Build partner count and fofoIds per RBM from mtdBillingData (same source as Today ARR page)
|
|
|
722 |
Map<Integer, Set<Integer>> mtdFofoIdsByAuthId = mtdBillingData.stream()
|
|
|
723 |
.filter(RbmWeeklyBillingModel::isTargetedPartner)
|
|
|
724 |
.collect(Collectors.groupingBy(RbmWeeklyBillingModel::getAuthId,
|
|
|
725 |
Collectors.mapping(RbmWeeklyBillingModel::getFofoId, Collectors.toSet())));
|
| 35631 |
ranu |
726 |
LOGGER.info("RBM Call Target - MTD Billing fetch: {}ms", System.currentTimeMillis() - start);
|
|
|
727 |
|
|
|
728 |
// Batch fetch today's remarks for all auth IDs (to calculate Value Achieved)
|
|
|
729 |
start = System.currentTimeMillis();
|
|
|
730 |
Map<Integer, List<PartnerCollectionRemark>> remarksByAuthId = partnerCollectionRemarkRepository
|
|
|
731 |
.selectAllByAuthIdsOnDate(rbmPositionsAuthIds, LocalDate.now()).stream()
|
|
|
732 |
.collect(Collectors.groupingBy(PartnerCollectionRemark::getAuthId));
|
|
|
733 |
LOGGER.info("RBM Call Target - Today Remarks fetch: {}ms", System.currentTimeMillis() - start);
|
|
|
734 |
|
|
|
735 |
// Batch fetch today's out-of-sequence logs for all RBMs
|
|
|
736 |
start = System.currentTimeMillis();
|
|
|
737 |
LocalDateTime todayStart = LocalDate.now().atStartOfDay();
|
|
|
738 |
LocalDateTime todayEnd = LocalDate.now().plusDays(1).atStartOfDay();
|
|
|
739 |
List<RbmCallSequenceLog> outOfSequenceLogs = rbmCallSequenceLogRepository.selectOutOfSequenceByDateRange(todayStart, todayEnd);
|
|
|
740 |
Map<Integer, Long> outOfSequenceCountByAuthId = outOfSequenceLogs.stream()
|
| 35654 |
ranu |
741 |
.collect(Collectors.groupingBy(RbmCallSequenceLog::getAuthId,
|
|
|
742 |
Collectors.mapping(RbmCallSequenceLog::getFofoId, Collectors.collectingAndThen(Collectors.toSet(), s -> (long) s.size()))));
|
| 35631 |
ranu |
743 |
LOGGER.info("RBM Call Target - Out of Sequence fetch: {}ms", System.currentTimeMillis() - start);
|
|
|
744 |
|
|
|
745 |
// Process L1 RBMs (existing logic)
|
|
|
746 |
for (int rbmAuthId : l1AuthIds) {
|
|
|
747 |
AuthUser authUser = authUserMap.get(rbmAuthId);
|
|
|
748 |
if (authUser == null || !storeGuyMap.containsKey(authUser.getEmailId())) {
|
|
|
749 |
continue;
|
|
|
750 |
}
|
|
|
751 |
|
|
|
752 |
List<Integer> fofoIdList = rbmToFofoIdsMap.getOrDefault(rbmAuthId, Collections.emptyList());
|
|
|
753 |
|
|
|
754 |
// Check if RBM is L1 (same logic as getSummaryModel)
|
|
|
755 |
List<Position> positions = positionsByAuthId.getOrDefault(authUser.getId(), Collections.emptyList());
|
|
|
756 |
boolean isRBMAndL1 = positions.stream()
|
|
|
757 |
.anyMatch(position ->
|
|
|
758 |
ProfitMandiConstants.TICKET_CATEGORY_RBM == position.getCategoryId()
|
|
|
759 |
&& EscalationType.L1.equals(position.getEscalationType()));
|
|
|
760 |
|
|
|
761 |
// Filter escalated partners for L1 RBMs (same logic as getSummaryModel)
|
|
|
762 |
List<Integer> fofoIds = fofoIdList;
|
|
|
763 |
if (isRBMAndL1) {
|
|
|
764 |
Map<Integer, PartnerCollectionRemark> partnerCollectionRemarks = new HashMap<>();
|
|
|
765 |
for (Integer fofoId : fofoIdList) {
|
|
|
766 |
if (allPartnerCollectionRemarks.containsKey(fofoId)) {
|
|
|
767 |
partnerCollectionRemarks.put(fofoId, allPartnerCollectionRemarks.get(fofoId));
|
|
|
768 |
}
|
|
|
769 |
}
|
|
|
770 |
fofoIds = partnerCollectionRemarks.entrySet().stream()
|
|
|
771 |
.filter(entry -> {
|
|
|
772 |
PartnerCollectionRemark pcrMap = entry.getValue();
|
|
|
773 |
return !(CollectionRemark.RBM_L2_ESCALATION.equals(pcrMap.getRemark())
|
|
|
774 |
|| CollectionRemark.SALES_ESCALATION.equals(pcrMap.getRemark()));
|
|
|
775 |
})
|
|
|
776 |
.map(Map.Entry::getKey)
|
|
|
777 |
.collect(Collectors.toList());
|
|
|
778 |
}
|
|
|
779 |
|
| 35669 |
ranu |
780 |
// Filter to only external, ACTIVE stores (collection plan not required)
|
| 35631 |
ranu |
781 |
Map<Integer, Integer> finalAllCollectionRankMap = allCollectionRankMap;
|
|
|
782 |
Map<Integer, FofoStore> finalFofoStoresMap = fofoStoresMap;
|
|
|
783 |
List<Integer> validFofoIds = fofoIds.stream()
|
|
|
784 |
.filter(fofoId -> {
|
|
|
785 |
FofoStore store = finalFofoStoresMap.get(fofoId);
|
|
|
786 |
if (store == null || store.isInternal()) {
|
|
|
787 |
return false;
|
|
|
788 |
}
|
|
|
789 |
// Only include ACTIVE partners (not Low Sale, not Disputed, not Billing Pending)
|
| 35669 |
ranu |
790 |
return ActivationType.ACTIVE.equals(store.getActivationType());
|
| 35631 |
ranu |
791 |
})
|
|
|
792 |
.collect(Collectors.toList());
|
|
|
793 |
|
|
|
794 |
if (validFofoIds.isEmpty()) {
|
|
|
795 |
continue;
|
|
|
796 |
}
|
|
|
797 |
|
|
|
798 |
RbmCallTargetModel targetModel = new RbmCallTargetModel();
|
|
|
799 |
targetModel.setAuthId(rbmAuthId);
|
|
|
800 |
targetModel.setRbmName(authUser.getFullName());
|
| 35669 |
ranu |
801 |
// Use partner count from mtdBillingData (same source as Today ARR page)
|
|
|
802 |
Set<Integer> mtdFofoIds = mtdFofoIdsByAuthId.getOrDefault(rbmAuthId, Collections.emptySet());
|
|
|
803 |
targetModel.setPartnerCount(mtdFofoIds.size());
|
| 35631 |
ranu |
804 |
|
|
|
805 |
// Categorize each partner - each partner belongs to ONE category only
|
| 35665 |
ranu |
806 |
// Priority: PlanToday > CarryForward > ZeroBilling > Untouched > FuturePlan > Normal
|
| 35631 |
ranu |
807 |
Set<Integer> planTodayPartners = new HashSet<>();
|
|
|
808 |
Set<Integer> carryForwardPartners = new HashSet<>();
|
|
|
809 |
Set<Integer> untouchedPartners = new HashSet<>();
|
|
|
810 |
Set<Integer> zeroBillingPartners = new HashSet<>();
|
|
|
811 |
Set<Integer> futurePlanPartners = new HashSet<>();
|
|
|
812 |
Set<Integer> normalPartners = new HashSet<>();
|
|
|
813 |
|
|
|
814 |
for (Integer fofoId : validFofoIds) {
|
|
|
815 |
// Get collection plan rank (from optimized rank map)
|
|
|
816 |
int rank = allCollectionRankMap.getOrDefault(fofoId, 5); // default to Normal if no plan
|
|
|
817 |
|
|
|
818 |
// Check if partner has zero billing in MTD
|
|
|
819 |
boolean hasZeroBilling = !allMtdBilledFofoIds.contains(fofoId);
|
|
|
820 |
|
|
|
821 |
// Assign to category based on priority
|
|
|
822 |
if (rank == 1) {
|
|
|
823 |
planTodayPartners.add(fofoId);
|
|
|
824 |
} else if (rank == 2) {
|
|
|
825 |
carryForwardPartners.add(fofoId);
|
| 35665 |
ranu |
826 |
} else if (hasZeroBilling) {
|
|
|
827 |
zeroBillingPartners.add(fofoId);
|
| 35631 |
ranu |
828 |
} else if (rank == 3) {
|
|
|
829 |
untouchedPartners.add(fofoId);
|
|
|
830 |
} else if (rank == 4) {
|
|
|
831 |
futurePlanPartners.add(fofoId);
|
|
|
832 |
} else {
|
|
|
833 |
normalPartners.add(fofoId);
|
|
|
834 |
}
|
|
|
835 |
}
|
|
|
836 |
|
|
|
837 |
// Set counts
|
|
|
838 |
targetModel.setCreditCollection(0); // Credit collection is handled in separate list
|
|
|
839 |
targetModel.setPlanToday(planTodayPartners.size());
|
|
|
840 |
targetModel.setCarryForward(carryForwardPartners.size());
|
|
|
841 |
targetModel.setUntouched(untouchedPartners.size());
|
|
|
842 |
targetModel.setZeroBilling(zeroBillingPartners.size());
|
|
|
843 |
targetModel.setFuturePlan(futurePlanPartners.size());
|
|
|
844 |
targetModel.setNormal(normalPartners.size());
|
|
|
845 |
|
|
|
846 |
// Today Target = PlanToday + CarryForward + ZeroBilling + Untouched
|
|
|
847 |
// These are mutually exclusive now, so we can sum them
|
|
|
848 |
long todayTarget = planTodayPartners.size() +
|
|
|
849 |
carryForwardPartners.size() + zeroBillingPartners.size() + untouchedPartners.size();
|
|
|
850 |
targetModel.setTodayTargetOfCall(todayTarget);
|
|
|
851 |
|
|
|
852 |
// Create set of partners in Today Target categories
|
|
|
853 |
Set<Integer> todayTargetPartners = new HashSet<>();
|
|
|
854 |
todayTargetPartners.addAll(planTodayPartners);
|
|
|
855 |
todayTargetPartners.addAll(carryForwardPartners);
|
|
|
856 |
todayTargetPartners.addAll(zeroBillingPartners);
|
|
|
857 |
todayTargetPartners.addAll(untouchedPartners);
|
|
|
858 |
|
|
|
859 |
// Value Achieved = Partners from Today Target that have been contacted today (have remark today)
|
|
|
860 |
List<PartnerCollectionRemark> todayRemarks = remarksByAuthId.getOrDefault(rbmAuthId, Collections.emptyList());
|
|
|
861 |
long valueAchieved = todayRemarks.stream()
|
|
|
862 |
.map(PartnerCollectionRemark::getFofoId)
|
|
|
863 |
.filter(todayTargetPartners::contains)
|
|
|
864 |
.distinct()
|
|
|
865 |
.count();
|
|
|
866 |
targetModel.setValueTargetAchieved(valueAchieved);
|
|
|
867 |
|
|
|
868 |
// Moved to Future = Partners in Future Plan category who have a remark today
|
|
|
869 |
// These are partners who were contacted today but moved to a future date
|
|
|
870 |
Set<Integer> todayRemarkedFofoIds = todayRemarks.stream()
|
|
|
871 |
.map(PartnerCollectionRemark::getFofoId)
|
|
|
872 |
.collect(Collectors.toSet());
|
|
|
873 |
long movedToFuture = futurePlanPartners.stream()
|
|
|
874 |
.filter(todayRemarkedFofoIds::contains)
|
|
|
875 |
.count();
|
|
|
876 |
targetModel.setMovedToFuture(movedToFuture);
|
|
|
877 |
|
|
|
878 |
// Set out of sequence count for this RBM
|
|
|
879 |
targetModel.setOutOfSequenceCount(outOfSequenceCountByAuthId.getOrDefault(rbmAuthId, 0L));
|
|
|
880 |
|
|
|
881 |
rbmCallTargetModels.add(targetModel);
|
|
|
882 |
}
|
|
|
883 |
|
|
|
884 |
// Process L2 RBMs (escalated ticket logic with categorization)
|
|
|
885 |
for (int l2AuthId : l2AuthIds) {
|
|
|
886 |
AuthUser authUser = authUserMap.get(l2AuthId);
|
|
|
887 |
if (authUser == null) {
|
|
|
888 |
continue;
|
|
|
889 |
}
|
|
|
890 |
|
|
|
891 |
List<Integer> l2FofoIdList = l2AuthIdToFofoIds.getOrDefault(l2AuthId, Collections.emptyList());
|
|
|
892 |
|
| 35662 |
ranu |
893 |
// For L2, use all escalated ticket fofoIds as target (no collection plan filter)
|
|
|
894 |
Set<Integer> l2TargetFofoIds = new HashSet<>(l2FofoIdList);
|
| 35631 |
ranu |
895 |
|
|
|
896 |
RbmCallTargetModel l2Model = new RbmCallTargetModel();
|
|
|
897 |
l2Model.setAuthId(l2AuthId);
|
|
|
898 |
l2Model.setRbmName(authUser.getFullName() + " (L2)");
|
|
|
899 |
l2Model.setL2Position(true);
|
|
|
900 |
l2Model.setL2CallingList(l2FofoIdList.size());
|
|
|
901 |
// Partner count = total assigned partners (same as L1 source)
|
|
|
902 |
List<Integer> l2AssignedFofoIds = rbmToFofoIdsMap.getOrDefault(l2AuthId, Collections.emptyList());
|
|
|
903 |
l2Model.setPartnerCount(l2AssignedFofoIds.size());
|
|
|
904 |
|
| 35662 |
ranu |
905 |
// L2 Target = all escalated ticket fofoIds
|
|
|
906 |
l2Model.setTodayTargetOfCall(l2TargetFofoIds.size());
|
| 35631 |
ranu |
907 |
|
| 35662 |
ranu |
908 |
// Value Achieved = distinct fofoIds from today's remarks that are in escalated tickets
|
|
|
909 |
List<PartnerCollectionRemark> l2TodayRemarks = remarksByAuthId.getOrDefault(l2AuthId, Collections.emptyList());
|
|
|
910 |
long l2ValueAchieved = l2TodayRemarks.stream()
|
|
|
911 |
.map(PartnerCollectionRemark::getFofoId)
|
|
|
912 |
.filter(l2TargetFofoIds::contains)
|
|
|
913 |
.distinct()
|
|
|
914 |
.count();
|
|
|
915 |
l2Model.setValueTargetAchieved(l2ValueAchieved);
|
| 35631 |
ranu |
916 |
|
|
|
917 |
l2Model.setOutOfSequenceCount(outOfSequenceCountByAuthId.getOrDefault(l2AuthId, 0L));
|
|
|
918 |
rbmCallTargetModels.add(l2Model);
|
|
|
919 |
}
|
|
|
920 |
|
|
|
921 |
// Group L1 under their L2 manager using authUser.managerId
|
|
|
922 |
Map<Integer, RbmCallTargetModel> l2ModelsByAuthId = new HashMap<>();
|
|
|
923 |
Map<Integer, RbmCallTargetModel> l1ModelsByAuthId = new HashMap<>();
|
|
|
924 |
for (RbmCallTargetModel m : rbmCallTargetModels) {
|
|
|
925 |
if (m.isL2Position()) {
|
|
|
926 |
l2ModelsByAuthId.put(m.getAuthId(), m);
|
|
|
927 |
} else {
|
|
|
928 |
l1ModelsByAuthId.put(m.getAuthId(), m);
|
|
|
929 |
}
|
|
|
930 |
}
|
|
|
931 |
|
|
|
932 |
// Build L2 -> L1 team map using managerId from AuthUser
|
|
|
933 |
Map<Integer, List<RbmCallTargetModel>> l2TeamMap = new LinkedHashMap<>();
|
|
|
934 |
for (RbmCallTargetModel l2Model : l2ModelsByAuthId.values()) {
|
|
|
935 |
l2TeamMap.put(l2Model.getAuthId(), new ArrayList<>());
|
|
|
936 |
}
|
|
|
937 |
|
|
|
938 |
Set<Integer> addedL1AuthIds = new HashSet<>();
|
|
|
939 |
for (RbmCallTargetModel l1Model : l1ModelsByAuthId.values()) {
|
|
|
940 |
AuthUser l1User = authUserMap.get(l1Model.getAuthId());
|
|
|
941 |
if (l1User != null && l2TeamMap.containsKey(l1User.getManagerId())) {
|
|
|
942 |
l2TeamMap.get(l1User.getManagerId()).add(l1Model);
|
|
|
943 |
addedL1AuthIds.add(l1Model.getAuthId());
|
|
|
944 |
}
|
|
|
945 |
}
|
|
|
946 |
|
|
|
947 |
// Build sorted result: L2 row, then its L1 team (sorted by name)
|
|
|
948 |
List<RbmCallTargetModel> sortedModels = new ArrayList<>();
|
|
|
949 |
|
|
|
950 |
List<RbmCallTargetModel> l2Sorted = new ArrayList<>(l2ModelsByAuthId.values());
|
|
|
951 |
l2Sorted.sort(Comparator.comparing(RbmCallTargetModel::getRbmName));
|
|
|
952 |
|
|
|
953 |
for (RbmCallTargetModel l2Model : l2Sorted) {
|
|
|
954 |
sortedModels.add(l2Model);
|
|
|
955 |
List<RbmCallTargetModel> team = l2TeamMap.getOrDefault(l2Model.getAuthId(), Collections.emptyList());
|
|
|
956 |
team.sort(Comparator.comparing(RbmCallTargetModel::getRbmName));
|
|
|
957 |
sortedModels.addAll(team);
|
|
|
958 |
}
|
|
|
959 |
|
|
|
960 |
// Add any L1 RBMs not mapped to any L2 (sorted by name)
|
|
|
961 |
List<RbmCallTargetModel> unmappedL1 = new ArrayList<>();
|
|
|
962 |
for (RbmCallTargetModel m : l1ModelsByAuthId.values()) {
|
|
|
963 |
if (!addedL1AuthIds.contains(m.getAuthId())) {
|
|
|
964 |
unmappedL1.add(m);
|
|
|
965 |
}
|
|
|
966 |
}
|
|
|
967 |
unmappedL1.sort(Comparator.comparing(RbmCallTargetModel::getRbmName));
|
|
|
968 |
sortedModels.addAll(unmappedL1);
|
|
|
969 |
|
|
|
970 |
LOGGER.info("RBM Call Target - TOTAL TIME: {}ms, RBM count: {}", System.currentTimeMillis() - methodStart, sortedModels.size());
|
|
|
971 |
return sortedModels;
|
|
|
972 |
}
|
|
|
973 |
|
|
|
974 |
@Override
|
|
|
975 |
public List<OutOfSequenceDetailModel> getOutOfSequenceDetails(int authId) {
|
|
|
976 |
|
|
|
977 |
LocalDate today = LocalDate.now();
|
|
|
978 |
LocalDateTime start = today.atStartOfDay();
|
|
|
979 |
LocalDateTime end = today.plusDays(1).atStartOfDay();
|
|
|
980 |
|
|
|
981 |
List<RbmCallSequenceLog> logs =
|
|
|
982 |
rbmCallSequenceLogRepository.selectByAuthIdAndDateRange(authId, start, end);
|
|
|
983 |
|
| 35654 |
ranu |
984 |
Map<Integer, RbmCallSequenceLog> uniqueOosLogsByFofoId = new LinkedHashMap<>();
|
| 35631 |
ranu |
985 |
|
|
|
986 |
for (RbmCallSequenceLog log : logs) {
|
|
|
987 |
if (log.isOutOfSequence()) {
|
| 35654 |
ranu |
988 |
// Keep only the first occurrence per fofoId (latest entry since ordered by id DESC)
|
|
|
989 |
uniqueOosLogsByFofoId.putIfAbsent(log.getFofoId(), log);
|
| 35631 |
ranu |
990 |
}
|
|
|
991 |
}
|
|
|
992 |
|
| 35654 |
ranu |
993 |
if (uniqueOosLogsByFofoId.isEmpty()) {
|
| 35631 |
ranu |
994 |
return Collections.emptyList();
|
|
|
995 |
}
|
|
|
996 |
|
| 35654 |
ranu |
997 |
Set<Integer> fofoIds = uniqueOosLogsByFofoId.keySet();
|
| 35631 |
ranu |
998 |
Map<Integer, CustomRetailer> retailerMap = Collections.emptyMap();
|
|
|
999 |
try {
|
|
|
1000 |
retailerMap = retailerService.getFofoRetailers(new ArrayList<>(fofoIds));
|
|
|
1001 |
} catch (ProfitMandiBusinessException e) {
|
|
|
1002 |
LOGGER.error("Error fetching fofo stores", e);
|
|
|
1003 |
}
|
|
|
1004 |
|
|
|
1005 |
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm a");
|
|
|
1006 |
List<OutOfSequenceDetailModel> result = new ArrayList<>();
|
|
|
1007 |
|
| 35654 |
ranu |
1008 |
for (RbmCallSequenceLog log : uniqueOosLogsByFofoId.values()) {
|
| 35631 |
ranu |
1009 |
CustomRetailer retailer = retailerMap.get(log.getFofoId());
|
|
|
1010 |
String partyName = retailer != null
|
|
|
1011 |
? retailer.getBusinessName()
|
|
|
1012 |
: "Unknown (" + log.getFofoId() + ")";
|
|
|
1013 |
String code = retailer != null
|
|
|
1014 |
? retailer.getCode()
|
|
|
1015 |
: "-";
|
|
|
1016 |
|
|
|
1017 |
String time = log.getCreateTimestamp() != null
|
|
|
1018 |
? log.getCreateTimestamp().format(timeFormatter)
|
|
|
1019 |
: "-";
|
|
|
1020 |
|
|
|
1021 |
result.add(new OutOfSequenceDetailModel(partyName, code, time));
|
|
|
1022 |
}
|
|
|
1023 |
|
|
|
1024 |
return result;
|
|
|
1025 |
}
|
|
|
1026 |
|
| 35645 |
ranu |
1027 |
@Override
|
| 35672 |
ranu |
1028 |
public List<CalledPartnerDetailModel> getCalledPartnerDetails(int authId) throws ProfitMandiBusinessException {
|
| 35670 |
ranu |
1029 |
LocalDate today = LocalDate.now();
|
| 35672 |
ranu |
1030 |
LocalDateTime startDate = today.atStartOfDay();
|
|
|
1031 |
LocalDate firstOfMonth = today.withDayOfMonth(1);
|
|
|
1032 |
LocalDate endOfMonth = today.withDayOfMonth(today.lengthOfMonth()).plusDays(1);
|
| 35670 |
ranu |
1033 |
|
| 35672 |
ranu |
1034 |
// Get auth user
|
|
|
1035 |
List<AuthUser> authUsers = authRepository.selectByIds(Collections.singletonList(authId));
|
|
|
1036 |
if (authUsers.isEmpty()) {
|
|
|
1037 |
return Collections.emptyList();
|
|
|
1038 |
}
|
|
|
1039 |
AuthUser authUser = authUsers.get(0);
|
| 35670 |
ranu |
1040 |
|
| 35672 |
ranu |
1041 |
// Check if L1 or L2
|
|
|
1042 |
List<Position> positions = positionRepository.selectPositionByAuthIds(Collections.singletonList(authId));
|
|
|
1043 |
boolean isL2 = positions.stream()
|
|
|
1044 |
.anyMatch(p -> ProfitMandiConstants.TICKET_CATEGORY_RBM == p.getCategoryId()
|
|
|
1045 |
&& EscalationType.L2.equals(p.getEscalationType()));
|
|
|
1046 |
|
|
|
1047 |
// Get fofo IDs for this RBM
|
|
|
1048 |
List<Integer> fofoIdList;
|
|
|
1049 |
if (isL2) {
|
|
|
1050 |
// L2: get fofo IDs from escalated tickets (all escalated tickets are target)
|
|
|
1051 |
List<Ticket> escalatedTickets = ticketRepository.selectOpenEscalatedTicketsByAuthIds(Collections.singletonList(authId));
|
|
|
1052 |
fofoIdList = escalatedTickets.stream()
|
|
|
1053 |
.filter(t -> t.getL2AuthUser() == authId
|
|
|
1054 |
|| t.getL3AuthUser() == authId
|
|
|
1055 |
|| t.getL4AuthUser() == authId
|
|
|
1056 |
|| t.getL5AuthUser() == authId)
|
|
|
1057 |
.map(Ticket::getFofoId)
|
|
|
1058 |
.distinct()
|
|
|
1059 |
.collect(Collectors.toList());
|
|
|
1060 |
|
| 35720 |
ranu |
1061 |
// For L2, all escalated tickets are target
|
|
|
1062 |
Set<Integer> targetFofoIds = new HashSet<>(fofoIdList);
|
|
|
1063 |
|
|
|
1064 |
// Get today's remarks
|
| 35672 |
ranu |
1065 |
List<PartnerCollectionRemark> todayRemarks = partnerCollectionRemarkRepository
|
|
|
1066 |
.selectAllByAuthIdsOnDate(Collections.singletonList(authId), today);
|
|
|
1067 |
|
| 35720 |
ranu |
1068 |
// Filter to only target partners and deduplicate
|
| 35672 |
ranu |
1069 |
Map<Integer, PartnerCollectionRemark> uniqueRemarksByFofoId = new LinkedHashMap<>();
|
|
|
1070 |
for (PartnerCollectionRemark remark : todayRemarks) {
|
| 35720 |
ranu |
1071 |
if (targetFofoIds.contains(remark.getFofoId())) {
|
|
|
1072 |
uniqueRemarksByFofoId.putIfAbsent(remark.getFofoId(), remark);
|
|
|
1073 |
}
|
| 35672 |
ranu |
1074 |
}
|
|
|
1075 |
|
|
|
1076 |
return buildCalledPartnerResult(uniqueRemarksByFofoId);
|
|
|
1077 |
}
|
|
|
1078 |
|
|
|
1079 |
// L1 Logic
|
|
|
1080 |
Map<String, Set<Integer>> storeGuyMap;
|
|
|
1081 |
try {
|
|
|
1082 |
storeGuyMap = csService.getAuthUserPartnerIdMapping();
|
|
|
1083 |
} catch (ProfitMandiBusinessException e) {
|
|
|
1084 |
LOGGER.error("Error fetching store guy map", e);
|
| 35670 |
ranu |
1085 |
return Collections.emptyList();
|
|
|
1086 |
}
|
|
|
1087 |
|
| 35672 |
ranu |
1088 |
if (!storeGuyMap.containsKey(authUser.getEmailId())) {
|
|
|
1089 |
return Collections.emptyList();
|
|
|
1090 |
}
|
|
|
1091 |
fofoIdList = new ArrayList<>(storeGuyMap.get(authUser.getEmailId()));
|
|
|
1092 |
|
|
|
1093 |
if (fofoIdList.isEmpty()) {
|
|
|
1094 |
return Collections.emptyList();
|
|
|
1095 |
}
|
|
|
1096 |
|
|
|
1097 |
// Get fofo stores for filtering
|
|
|
1098 |
Map<Integer, FofoStore> fofoStoresMap;
|
|
|
1099 |
try {
|
|
|
1100 |
fofoStoresMap = fofoStoreRepository.selectByRetailerIds(fofoIdList).stream()
|
|
|
1101 |
.collect(Collectors.toMap(FofoStore::getId, x -> x, (a, b) -> a));
|
|
|
1102 |
} catch (ProfitMandiBusinessException e) {
|
|
|
1103 |
LOGGER.error("Error fetching fofo stores", e);
|
|
|
1104 |
return Collections.emptyList();
|
|
|
1105 |
}
|
|
|
1106 |
|
|
|
1107 |
// Filter escalated partners for L1
|
|
|
1108 |
List<Integer> allRemarkIds = partnerCollectionRemarkRepository.selectMaxRemarkId(fofoIdList);
|
|
|
1109 |
if (!allRemarkIds.isEmpty()) {
|
|
|
1110 |
Map<Integer, PartnerCollectionRemark> partnerCollectionRemarks = partnerCollectionRemarkRepository.selectByIds(allRemarkIds).stream()
|
|
|
1111 |
.collect(Collectors.toMap(PartnerCollectionRemark::getFofoId, x -> x, (a, b) -> a));
|
|
|
1112 |
fofoIdList = partnerCollectionRemarks.entrySet().stream()
|
|
|
1113 |
.filter(entry -> {
|
|
|
1114 |
PartnerCollectionRemark pcrMap = entry.getValue();
|
|
|
1115 |
return !(CollectionRemark.RBM_L2_ESCALATION.equals(pcrMap.getRemark())
|
|
|
1116 |
|| CollectionRemark.SALES_ESCALATION.equals(pcrMap.getRemark()));
|
|
|
1117 |
})
|
|
|
1118 |
.map(Map.Entry::getKey)
|
|
|
1119 |
.collect(Collectors.toList());
|
|
|
1120 |
}
|
|
|
1121 |
|
|
|
1122 |
// Filter to only external, ACTIVE stores
|
|
|
1123 |
List<Integer> validFofoIds = fofoIdList.stream()
|
|
|
1124 |
.filter(fofoId -> {
|
|
|
1125 |
FofoStore store = fofoStoresMap.get(fofoId);
|
|
|
1126 |
if (store == null || store.isInternal()) {
|
|
|
1127 |
return false;
|
|
|
1128 |
}
|
|
|
1129 |
return ActivationType.ACTIVE.equals(store.getActivationType());
|
|
|
1130 |
})
|
|
|
1131 |
.collect(Collectors.toList());
|
|
|
1132 |
|
|
|
1133 |
if (validFofoIds.isEmpty()) {
|
|
|
1134 |
return Collections.emptyList();
|
|
|
1135 |
}
|
|
|
1136 |
|
|
|
1137 |
// Get collection rank map
|
|
|
1138 |
Map<Integer, Integer> collectionRankMap;
|
|
|
1139 |
try {
|
|
|
1140 |
collectionRankMap = partnerCollectionService.getCollectionRankMap(validFofoIds, startDate);
|
|
|
1141 |
} catch (ProfitMandiBusinessException e) {
|
|
|
1142 |
LOGGER.error("Error fetching collection rank map", e);
|
|
|
1143 |
collectionRankMap = new HashMap<>();
|
|
|
1144 |
}
|
|
|
1145 |
|
|
|
1146 |
// Get MTD billing data for zero billing check
|
|
|
1147 |
List<RbmWeeklyBillingModel> mtdBillingData = getWeeklyBillingDataForMonth(firstOfMonth, endOfMonth);
|
|
|
1148 |
Set<Integer> mtdBilledFofoIds = mtdBillingData.stream()
|
|
|
1149 |
.filter(RbmWeeklyBillingModel::isMtdBilled)
|
|
|
1150 |
.map(RbmWeeklyBillingModel::getFofoId)
|
|
|
1151 |
.collect(Collectors.toSet());
|
|
|
1152 |
|
|
|
1153 |
// Build target partner set (PlanToday + CarryForward + ZeroBilling + Untouched)
|
|
|
1154 |
Set<Integer> targetFofoIds = new HashSet<>();
|
|
|
1155 |
for (Integer fofoId : validFofoIds) {
|
|
|
1156 |
int rank = collectionRankMap.getOrDefault(fofoId, 5);
|
|
|
1157 |
boolean hasZeroBilling = !mtdBilledFofoIds.contains(fofoId);
|
|
|
1158 |
|
|
|
1159 |
// Same priority logic as in getRbmCallTargetModels
|
|
|
1160 |
if (rank == 1 || rank == 2 || hasZeroBilling || rank == 3) {
|
|
|
1161 |
targetFofoIds.add(fofoId);
|
|
|
1162 |
}
|
|
|
1163 |
// rank 4 (FuturePlan) and rank 5 (Normal) are NOT in target
|
|
|
1164 |
}
|
|
|
1165 |
|
| 35720 |
ranu |
1166 |
// Get today's remarks
|
| 35672 |
ranu |
1167 |
List<PartnerCollectionRemark> todayRemarks = partnerCollectionRemarkRepository
|
|
|
1168 |
.selectAllByAuthIdsOnDate(Collections.singletonList(authId), today);
|
|
|
1169 |
|
| 35720 |
ranu |
1170 |
// Filter to only target partners and deduplicate
|
| 35670 |
ranu |
1171 |
Map<Integer, PartnerCollectionRemark> uniqueRemarksByFofoId = new LinkedHashMap<>();
|
|
|
1172 |
for (PartnerCollectionRemark remark : todayRemarks) {
|
| 35720 |
ranu |
1173 |
if (targetFofoIds.contains(remark.getFofoId())) {
|
|
|
1174 |
uniqueRemarksByFofoId.putIfAbsent(remark.getFofoId(), remark);
|
|
|
1175 |
}
|
| 35670 |
ranu |
1176 |
}
|
|
|
1177 |
|
| 35672 |
ranu |
1178 |
return buildCalledPartnerResult(uniqueRemarksByFofoId);
|
|
|
1179 |
}
|
|
|
1180 |
|
|
|
1181 |
private List<CalledPartnerDetailModel> buildCalledPartnerResult(Map<Integer, PartnerCollectionRemark> uniqueRemarksByFofoId) {
|
|
|
1182 |
if (uniqueRemarksByFofoId.isEmpty()) {
|
|
|
1183 |
return Collections.emptyList();
|
|
|
1184 |
}
|
|
|
1185 |
|
| 35670 |
ranu |
1186 |
Set<Integer> fofoIds = uniqueRemarksByFofoId.keySet();
|
|
|
1187 |
Map<Integer, CustomRetailer> retailerMap = Collections.emptyMap();
|
|
|
1188 |
try {
|
|
|
1189 |
retailerMap = retailerService.getFofoRetailers(new ArrayList<>(fofoIds));
|
|
|
1190 |
} catch (ProfitMandiBusinessException e) {
|
|
|
1191 |
LOGGER.error("Error fetching fofo stores", e);
|
|
|
1192 |
}
|
|
|
1193 |
|
| 35702 |
ranu |
1194 |
// Fetch call logs for remarks that have agentCallLogId
|
|
|
1195 |
List<Long> callLogIds = uniqueRemarksByFofoId.values().stream()
|
|
|
1196 |
.filter(r -> r.getAgentCallLogId() > 0)
|
|
|
1197 |
.map(PartnerCollectionRemark::getAgentCallLogId)
|
|
|
1198 |
.collect(Collectors.toList());
|
|
|
1199 |
|
|
|
1200 |
Map<Long, com.spice.profitmandi.dao.entity.cs.AgentCallLog> callLogMap = new HashMap<>();
|
|
|
1201 |
if (!callLogIds.isEmpty()) {
|
| 35720 |
ranu |
1202 |
try {
|
|
|
1203 |
List<com.spice.profitmandi.dao.entity.cs.AgentCallLog> callLogs = agentCallLogRepository.findByIds(callLogIds);
|
|
|
1204 |
callLogMap = callLogs.stream()
|
|
|
1205 |
.collect(Collectors.toMap(com.spice.profitmandi.dao.entity.cs.AgentCallLog::getId, c -> c, (a, b) -> a));
|
|
|
1206 |
} catch (Exception e) {
|
|
|
1207 |
LOGGER.error("Error fetching call logs by ids", e);
|
|
|
1208 |
}
|
| 35702 |
ranu |
1209 |
}
|
|
|
1210 |
|
| 35670 |
ranu |
1211 |
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm a");
|
| 35702 |
ranu |
1212 |
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm a");
|
| 35670 |
ranu |
1213 |
List<CalledPartnerDetailModel> result = new ArrayList<>();
|
|
|
1214 |
|
|
|
1215 |
for (PartnerCollectionRemark remark : uniqueRemarksByFofoId.values()) {
|
|
|
1216 |
CustomRetailer retailer = retailerMap.get(remark.getFofoId());
|
|
|
1217 |
String partyName = retailer != null
|
|
|
1218 |
? retailer.getBusinessName()
|
|
|
1219 |
: "Unknown (" + remark.getFofoId() + ")";
|
|
|
1220 |
String code = retailer != null
|
|
|
1221 |
? retailer.getCode()
|
|
|
1222 |
: "-";
|
|
|
1223 |
|
|
|
1224 |
String remarkValue = remark.getRemark() != null
|
|
|
1225 |
? remark.getRemark().getValue()
|
|
|
1226 |
: "-";
|
|
|
1227 |
|
| 35677 |
ranu |
1228 |
String messageValue = remark.getMessage() != null
|
|
|
1229 |
? remark.getMessage()
|
|
|
1230 |
: "-";
|
|
|
1231 |
|
| 35670 |
ranu |
1232 |
String time = remark.getCreateTimestamp() != null
|
|
|
1233 |
? remark.getCreateTimestamp().format(timeFormatter)
|
|
|
1234 |
: "-";
|
|
|
1235 |
|
| 35702 |
ranu |
1236 |
// Get call log data if available
|
|
|
1237 |
String recordingUrl = null;
|
|
|
1238 |
String callStatus = null;
|
|
|
1239 |
String callDuration = null;
|
|
|
1240 |
String callDateTime = null;
|
|
|
1241 |
|
|
|
1242 |
if (remark.getAgentCallLogId() > 0 && callLogMap.containsKey(remark.getAgentCallLogId())) {
|
|
|
1243 |
com.spice.profitmandi.dao.entity.cs.AgentCallLog callLog = callLogMap.get(remark.getAgentCallLogId());
|
|
|
1244 |
recordingUrl = callLog.getRecordingUrl();
|
|
|
1245 |
callStatus = callLog.getCallStatus();
|
|
|
1246 |
callDuration = callLog.getCallDuration();
|
|
|
1247 |
if (callLog.getCallDate() != null && callLog.getCallTime() != null) {
|
|
|
1248 |
LocalDateTime callDateTimeObj = LocalDateTime.of(callLog.getCallDate(), callLog.getCallTime());
|
|
|
1249 |
callDateTime = callDateTimeObj.format(dateTimeFormatter);
|
|
|
1250 |
}
|
|
|
1251 |
}
|
|
|
1252 |
|
|
|
1253 |
result.add(new CalledPartnerDetailModel(partyName, code, remarkValue, messageValue, time,
|
|
|
1254 |
recordingUrl, callStatus, callDuration, callDateTime));
|
| 35670 |
ranu |
1255 |
}
|
|
|
1256 |
|
|
|
1257 |
return result;
|
|
|
1258 |
}
|
|
|
1259 |
|
|
|
1260 |
@Override
|
| 35645 |
ranu |
1261 |
public List<List<String>> getRbmCallTargetRawDataByAuthId(int authId) throws Exception {
|
|
|
1262 |
List<List<String>> rows = new ArrayList<>();
|
| 35631 |
ranu |
1263 |
|
| 35645 |
ranu |
1264 |
// Get auth user
|
|
|
1265 |
List<AuthUser> authUsers = authRepository.selectByIds(Collections.singletonList(authId));
|
|
|
1266 |
if (authUsers.isEmpty()) {
|
|
|
1267 |
return rows;
|
|
|
1268 |
}
|
|
|
1269 |
AuthUser authUser = authUsers.get(0);
|
|
|
1270 |
|
|
|
1271 |
// Get positions to determine if L1 or L2
|
|
|
1272 |
List<Position> positions = positionRepository.selectPositionByAuthIds(Collections.singletonList(authId));
|
|
|
1273 |
boolean isL1 = positions.stream()
|
|
|
1274 |
.anyMatch(p -> ProfitMandiConstants.TICKET_CATEGORY_RBM == p.getCategoryId()
|
|
|
1275 |
&& EscalationType.L1.equals(p.getEscalationType()));
|
|
|
1276 |
boolean isL2 = positions.stream()
|
|
|
1277 |
.anyMatch(p -> ProfitMandiConstants.TICKET_CATEGORY_RBM == p.getCategoryId()
|
|
|
1278 |
&& EscalationType.L2.equals(p.getEscalationType()));
|
|
|
1279 |
|
|
|
1280 |
// Get fofo IDs for this RBM
|
|
|
1281 |
Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();
|
|
|
1282 |
List<Integer> fofoIdList = new ArrayList<>();
|
|
|
1283 |
|
|
|
1284 |
if (isL2) {
|
|
|
1285 |
// L2: get fofo IDs from escalated tickets
|
|
|
1286 |
List<Ticket> escalatedTickets = ticketRepository.selectOpenEscalatedTicketsByAuthIds(Collections.singletonList(authId));
|
|
|
1287 |
fofoIdList = escalatedTickets.stream()
|
|
|
1288 |
.filter(t -> t.getL2AuthUser() == authId
|
|
|
1289 |
|| t.getL3AuthUser() == authId
|
|
|
1290 |
|| t.getL4AuthUser() == authId
|
|
|
1291 |
|| t.getL5AuthUser() == authId)
|
|
|
1292 |
.map(Ticket::getFofoId)
|
|
|
1293 |
.distinct()
|
|
|
1294 |
.collect(Collectors.toList());
|
|
|
1295 |
} else if (storeGuyMap.containsKey(authUser.getEmailId())) {
|
|
|
1296 |
fofoIdList = new ArrayList<>(storeGuyMap.get(authUser.getEmailId()));
|
|
|
1297 |
}
|
|
|
1298 |
|
|
|
1299 |
if (fofoIdList.isEmpty()) {
|
|
|
1300 |
return rows;
|
|
|
1301 |
}
|
|
|
1302 |
|
|
|
1303 |
LocalDateTime startDate = LocalDate.now().atStartOfDay();
|
|
|
1304 |
LocalDate firstOfMonth = LocalDate.now().withDayOfMonth(1);
|
|
|
1305 |
LocalDate endOfMonth = LocalDate.now().withDayOfMonth(LocalDate.now().lengthOfMonth()).plusDays(1);
|
|
|
1306 |
|
|
|
1307 |
// Get fofo stores
|
|
|
1308 |
Map<Integer, FofoStore> fofoStoresMap = new HashMap<>();
|
|
|
1309 |
try {
|
|
|
1310 |
fofoStoresMap = fofoStoreRepository.selectByRetailerIds(fofoIdList).stream()
|
|
|
1311 |
.collect(Collectors.toMap(FofoStore::getId, x -> x, (a, b) -> a));
|
|
|
1312 |
} catch (ProfitMandiBusinessException e) {
|
|
|
1313 |
LOGGER.error("Error fetching fofo stores", e);
|
|
|
1314 |
}
|
|
|
1315 |
|
|
|
1316 |
// For L1 RBMs, filter escalated partners
|
|
|
1317 |
if (isL1) {
|
|
|
1318 |
List<Integer> allRemarkIds = partnerCollectionRemarkRepository.selectMaxRemarkId(fofoIdList);
|
|
|
1319 |
if (!allRemarkIds.isEmpty()) {
|
|
|
1320 |
Map<Integer, PartnerCollectionRemark> partnerCollectionRemarks = partnerCollectionRemarkRepository.selectByIds(allRemarkIds).stream()
|
|
|
1321 |
.collect(Collectors.toMap(PartnerCollectionRemark::getFofoId, x -> x, (a, b) -> a));
|
|
|
1322 |
fofoIdList = partnerCollectionRemarks.entrySet().stream()
|
|
|
1323 |
.filter(entry -> {
|
|
|
1324 |
PartnerCollectionRemark pcrMap = entry.getValue();
|
|
|
1325 |
return !(CollectionRemark.RBM_L2_ESCALATION.equals(pcrMap.getRemark())
|
|
|
1326 |
|| CollectionRemark.SALES_ESCALATION.equals(pcrMap.getRemark()));
|
|
|
1327 |
})
|
|
|
1328 |
.map(Map.Entry::getKey)
|
|
|
1329 |
.collect(Collectors.toList());
|
|
|
1330 |
}
|
|
|
1331 |
}
|
|
|
1332 |
|
|
|
1333 |
// Collection rank map
|
|
|
1334 |
Map<Integer, Integer> collectionRankMap = new HashMap<>();
|
|
|
1335 |
try {
|
|
|
1336 |
collectionRankMap = partnerCollectionService.getCollectionRankMap(fofoIdList, startDate);
|
|
|
1337 |
} catch (ProfitMandiBusinessException e) {
|
|
|
1338 |
LOGGER.error("Error fetching collection rank map", e);
|
|
|
1339 |
}
|
|
|
1340 |
|
|
|
1341 |
// MTD billing data
|
|
|
1342 |
List<RbmWeeklyBillingModel> mtdBillingData = getWeeklyBillingDataForMonth(firstOfMonth, endOfMonth);
|
|
|
1343 |
Set<Integer> mtdBilledFofoIds = mtdBillingData.stream()
|
|
|
1344 |
.filter(RbmWeeklyBillingModel::isMtdBilled)
|
|
|
1345 |
.map(RbmWeeklyBillingModel::getFofoId)
|
|
|
1346 |
.collect(Collectors.toSet());
|
|
|
1347 |
|
|
|
1348 |
// Filter to valid fofo IDs (external, ACTIVE, has collection plan)
|
|
|
1349 |
Map<Integer, Integer> finalCollectionRankMap = collectionRankMap;
|
|
|
1350 |
Map<Integer, FofoStore> finalFofoStoresMap = fofoStoresMap;
|
|
|
1351 |
List<Integer> validFofoIds = fofoIdList.stream()
|
|
|
1352 |
.filter(fofoId -> {
|
|
|
1353 |
FofoStore store = finalFofoStoresMap.get(fofoId);
|
|
|
1354 |
if (store == null || store.isInternal()) return false;
|
|
|
1355 |
if (!ActivationType.ACTIVE.equals(store.getActivationType())) return false;
|
|
|
1356 |
return finalCollectionRankMap.containsKey(fofoId);
|
|
|
1357 |
})
|
|
|
1358 |
.collect(Collectors.toList());
|
|
|
1359 |
|
|
|
1360 |
// Resolve partner names/codes
|
|
|
1361 |
Map<Integer, CustomRetailer> retailerMap = Collections.emptyMap();
|
|
|
1362 |
if (!validFofoIds.isEmpty()) {
|
|
|
1363 |
try {
|
|
|
1364 |
retailerMap = retailerService.getFofoRetailers(validFofoIds);
|
|
|
1365 |
} catch (ProfitMandiBusinessException e) {
|
|
|
1366 |
LOGGER.error("Error fetching fofo retailers for raw data", e);
|
|
|
1367 |
}
|
|
|
1368 |
}
|
|
|
1369 |
|
|
|
1370 |
String rbmName = authUser.getFullName() + (isL2 ? " (L2)" : "");
|
|
|
1371 |
|
|
|
1372 |
// Build rows
|
|
|
1373 |
for (Integer fofoId : validFofoIds) {
|
|
|
1374 |
int rank = collectionRankMap.getOrDefault(fofoId, 5);
|
|
|
1375 |
boolean hasZeroBilling = !mtdBilledFofoIds.contains(fofoId);
|
|
|
1376 |
|
|
|
1377 |
String status;
|
|
|
1378 |
if (rank == 1) {
|
|
|
1379 |
status = "Plan Today";
|
|
|
1380 |
} else if (rank == 2) {
|
|
|
1381 |
status = "Carry Forward";
|
|
|
1382 |
} else if (rank == 3) {
|
|
|
1383 |
status = "Untouched";
|
|
|
1384 |
} else if (hasZeroBilling) {
|
|
|
1385 |
status = "Zero Billing";
|
|
|
1386 |
} else if (rank == 4) {
|
|
|
1387 |
status = "Future Plan";
|
|
|
1388 |
} else {
|
|
|
1389 |
status = "Normal";
|
|
|
1390 |
}
|
|
|
1391 |
|
|
|
1392 |
CustomRetailer retailer = retailerMap.get(fofoId);
|
|
|
1393 |
String partnerName = retailer != null ? retailer.getBusinessName() : "Unknown (" + fofoId + ")";
|
|
|
1394 |
String partnerCode = retailer != null ? retailer.getCode() : "-";
|
|
|
1395 |
|
|
|
1396 |
rows.add(Arrays.asList(partnerName, partnerCode, status, rbmName));
|
|
|
1397 |
}
|
|
|
1398 |
|
|
|
1399 |
return rows;
|
|
|
1400 |
}
|
|
|
1401 |
|
| 33917 |
ranu |
1402 |
}
|