Subversion Repositories SmartDukaan

Rev

Rev 36210 | Rev 36399 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
24383 amit.gupta 1
package com.spice.profitmandi.dao.repository.cs;
24500 govind 2
 
24383 amit.gupta 3
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
24417 govind 4
import com.spice.profitmandi.common.model.CustomRetailer;
24439 govind 5
import com.spice.profitmandi.common.model.ProfitMandiConstants;
24417 govind 6
import com.spice.profitmandi.dao.entity.auth.AuthUser;
31829 amit.gupta 7
import com.spice.profitmandi.dao.entity.cs.*;
24383 amit.gupta 8
import com.spice.profitmandi.dao.entity.fofo.ActivityType;
30003 tejbeer 9
import com.spice.profitmandi.dao.entity.fofo.FofoStore;
32923 ranu 10
import com.spice.profitmandi.dao.enumuration.auth.CollectionRemark;
24417 govind 11
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
34905 ranu 12
import com.spice.profitmandi.dao.model.*;
24417 govind 13
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
25570 tejbeer 14
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
35635 ranu 15
import com.spice.profitmandi.service.EmailService;
35963 amit 16
import com.spice.profitmandi.service.mail.MailOutboxService;
24417 govind 17
import com.spice.profitmandi.service.user.RetailerService;
31829 amit.gupta 18
import org.apache.commons.collections4.map.HashedMap;
19
import org.apache.commons.lang.RandomStringUtils;
20
import org.apache.commons.lang.StringUtils;
21
import org.apache.logging.log4j.LogManager;
22
import org.apache.logging.log4j.Logger;
34082 ranu 23
import org.hibernate.Session;
24
import org.hibernate.SessionFactory;
31829 amit.gupta 25
import org.springframework.beans.factory.annotation.Autowired;
26
import org.springframework.cache.annotation.Cacheable;
27
import org.springframework.mail.javamail.JavaMailSender;
28
import org.springframework.stereotype.Component;
24383 amit.gupta 29
 
34082 ranu 30
import javax.persistence.TypedQuery;
31829 amit.gupta 31
import java.time.LocalDateTime;
32
import java.util.*;
33
import java.util.stream.Collectors;
34
 
24383 amit.gupta 35
@Component
36
public class CsServiceImpl implements CsService {
24417 govind 37
 
31762 tejbeer 38
    private static final int ALL_PARTNERS_REGION = 5;
27124 amit.gupta 39
 
31762 tejbeer 40
    private static final Logger LOGGER = LogManager.getLogger(CsServiceImpl.class);
24439 govind 41
 
31762 tejbeer 42
    private static final String ASSIGNED_TICKET = "Dear %s, New ticket #%s #%s created by %s has been assigned to you. Regards\nSmartdukaan";
43
    private static final String ESCALATED_TICKET = "Dear %s, Ticket #%s #%s created by %s has been escalated to you. Regards\nSmartdukaan";
44
    private static final String CATEGORY_CHANGED_TICKET = "Dear team, Category of Ticket #%s created by %s has been changed to %s. Regards\nSmartdukaan";
45
    private static final String ASSINMENT_SUBJECT = "Assignment Ticket";
24439 govind 46
 
31762 tejbeer 47
    @Autowired
48
    TicketRepository ticketRepository;
24417 govind 49
 
31762 tejbeer 50
    @Autowired
51
    JavaMailSender mailSender;
24439 govind 52
 
31762 tejbeer 53
    @Autowired
35963 amit 54
    MailOutboxService mailOutboxService;
55
 
56
    @Autowired
31762 tejbeer 57
    TicketCategoryRepository ticketCategoryRepository;
24417 govind 58
 
31762 tejbeer 59
    @Autowired
60
    TicketSubCategoryRepository ticketSubCategoryRepository;
24417 govind 61
 
31762 tejbeer 62
    @Autowired
63
    ActivityRepository activityRepository;
24417 govind 64
 
31762 tejbeer 65
    @Autowired
32923 ranu 66
    TicketActivityMediaRepository activityMediaRepository;
67
 
68
    @Autowired
31762 tejbeer 69
    PartnerRegionRepository partnerRegionRepository;
24417 govind 70
 
31762 tejbeer 71
    @Autowired
72
    private PositionRepository positionRepository;
24417 govind 73
 
31762 tejbeer 74
    @Autowired
75
    private AuthRepository authRepository;
24417 govind 76
 
31762 tejbeer 77
    @Autowired
78
    private RetailerService retailerService;
24500 govind 79
 
31762 tejbeer 80
    @Autowired
81
    private RegionRepository regionRepository;
24417 govind 82
 
31762 tejbeer 83
    @Autowired
84
    private TicketAssignedRepository ticketAssignedRepository;
24500 govind 85
 
31762 tejbeer 86
    @Autowired
32493 amit.gupta 87
    private PartnerPositionRepository partnerPositionRepository;
25570 tejbeer 88
 
31762 tejbeer 89
    @Autowired
90
    private FofoStoreRepository fofoStoreRepository;
25570 tejbeer 91
 
34082 ranu 92
    @Autowired
93
    private SessionFactory sessionFactory;
94
 
35635 ranu 95
    @Autowired
96
    EmailService emailService;
97
 
98
    @Autowired
99
    TicketReadStatusRepository ticketReadStatusRepository;
100
 
101
 
31762 tejbeer 102
    @Override
103
    public void createTicket(int fofoId, int categoryId, int subcategoryId, String message) throws ProfitMandiBusinessException {
32923 ranu 104
        this.createTicket(fofoId, categoryId, subcategoryId, message, 0);
105
    }
24417 govind 106
 
32923 ranu 107
 
108
    @Override
109
    public void createTicket(int fofoId, int categoryId, int subcategoryId, String message, int createdByAuthId) throws ProfitMandiBusinessException {
110
 
31762 tejbeer 111
        ActivityType type = ActivityType.OPENED;
112
        Ticket ticket = new Ticket();
113
        ticket.setSubCategoryId(subcategoryId);
114
        ticket.setFofoId(fofoId);
115
        ticket.setCreateTimestamp(LocalDateTime.now());
116
        ticket.setUpdateTimestamp(LocalDateTime.now());
117
        ticket.setHappyCode(getRandomString());
118
        ticketRepository.persist(ticket);
32923 ranu 119
        this.addActivity(ticket, this.createActivity(type, message, createdByAuthId));
120
        ticket.setFirstActivityId(ticket.getLastActivityId());
33041 ranu 121
        if (createdByAuthId != 0) {
122
            int l2AuthUser = this.getAuthUserId(categoryId, EscalationType.L2, fofoId);
32923 ranu 123
            this.updateTicket(categoryId, subcategoryId, ticket, l2AuthUser, EscalationType.L2);
33041 ranu 124
        } else {
32923 ranu 125
            this.assignTicket(ticket);
126
        }
27124 amit.gupta 127
 
31762 tejbeer 128
    }
27124 amit.gupta 129
 
31762 tejbeer 130
    @Override
32923 ranu 131
    public void createTicketWithMedia(int fofoId, int categoryId, int subcategoryId, String message, int createdByAuthId, ActivityMediaModel selectedRecording) throws ProfitMandiBusinessException {
132
        ActivityType type = ActivityType.OPENED;
133
        Ticket ticket = new Ticket();
134
        ticket.setSubCategoryId(subcategoryId);
135
        ticket.setFofoId(fofoId);
136
        ticket.setCreateTimestamp(LocalDateTime.now());
137
        ticket.setUpdateTimestamp(LocalDateTime.now());
138
        ticket.setHappyCode(getRandomString());
139
        ticketRepository.persist(ticket);
140
        this.addActivity(ticket, this.createActivity(type, message, createdByAuthId));
141
        this.addMediaActivity(ticket, this.createMediaActivity(selectedRecording));
142
        ticket.setFirstActivityId(ticket.getLastActivityId());
33041 ranu 143
        if (createdByAuthId != 0) {
144
            int l2AuthUser = this.getAuthUserId(categoryId, EscalationType.L2, fofoId);
32923 ranu 145
            this.updateTicket(categoryId, subcategoryId, ticket, l2AuthUser, EscalationType.L2);
33041 ranu 146
        } else {
32923 ranu 147
            this.assignTicket(ticket);
148
        }
149
    }
150
 
33204 ranu 151
    @Override
36210 ranu 152
    public void createTicket(int fofoId, int categoryId, int subcategoryId, String message, int createdByAuthId, EscalationType targetEscalation) throws ProfitMandiBusinessException {
153
        ActivityType type = ActivityType.OPENED;
154
        Ticket ticket = new Ticket();
155
        ticket.setSubCategoryId(subcategoryId);
156
        ticket.setFofoId(fofoId);
157
        ticket.setCreateTimestamp(LocalDateTime.now());
158
        ticket.setUpdateTimestamp(LocalDateTime.now());
159
        ticket.setHappyCode(getRandomString());
160
        ticketRepository.persist(ticket);
161
        this.addActivity(ticket, this.createActivity(type, message, createdByAuthId));
162
        ticket.setFirstActivityId(ticket.getLastActivityId());
163
        if (createdByAuthId != 0) {
164
            int authUser = this.getAuthUserIdWithFallback(categoryId, targetEscalation, fofoId);
165
            this.updateTicket(categoryId, subcategoryId, ticket, authUser, targetEscalation);
166
        } else {
167
            this.assignTicket(ticket);
168
        }
169
    }
170
 
171
    @Override
172
    public void createTicketWithMedia(int fofoId, int categoryId, int subcategoryId, String message, int createdByAuthId, ActivityMediaModel selectedRecording, EscalationType targetEscalation) throws ProfitMandiBusinessException {
173
        ActivityType type = ActivityType.OPENED;
174
        Ticket ticket = new Ticket();
175
        ticket.setSubCategoryId(subcategoryId);
176
        ticket.setFofoId(fofoId);
177
        ticket.setCreateTimestamp(LocalDateTime.now());
178
        ticket.setUpdateTimestamp(LocalDateTime.now());
179
        ticket.setHappyCode(getRandomString());
180
        ticketRepository.persist(ticket);
181
        this.addActivity(ticket, this.createActivity(type, message, createdByAuthId));
182
        this.addMediaActivity(ticket, this.createMediaActivity(selectedRecording));
183
        ticket.setFirstActivityId(ticket.getLastActivityId());
184
        if (createdByAuthId != 0) {
185
            int authUser = this.getAuthUserIdWithFallback(categoryId, targetEscalation, fofoId);
186
            this.updateTicket(categoryId, subcategoryId, ticket, authUser, targetEscalation);
187
        } else {
188
            this.assignTicket(ticket);
189
        }
190
    }
191
 
192
    /**
193
     * Gets auth user ID for given escalation level. If not found, falls back to next level (L1 -> L2 -> L3 -> L4 -> L5)
36212 ranu 194
     * Returns both the auth user ID and the actual escalation level that was used.
36210 ranu 195
     */
36212 ranu 196
    @Override
197
    public EscalationAssignmentResult getAuthUserWithFallback(int categoryId, EscalationType targetEscalation, int fofoId) throws ProfitMandiBusinessException {
36210 ranu 198
        EscalationType currentEscalation = targetEscalation;
199
        while (currentEscalation != null && !currentEscalation.equals(EscalationType.Final)) {
200
            try {
201
                int authUserId = this.getAuthUserId(categoryId, currentEscalation, fofoId);
202
                if (authUserId > 0) {
203
                    LOGGER.info("Found auth user {} for escalation level {} and fofoId {}", authUserId, currentEscalation, fofoId);
36212 ranu 204
                    return new EscalationAssignmentResult(authUserId, currentEscalation);
36210 ranu 205
                }
206
            } catch (Exception e) {
207
                LOGGER.warn("No auth user found for escalation level {} and fofoId {}, trying next level", currentEscalation, fofoId);
208
            }
209
            currentEscalation = currentEscalation.next();
210
        }
36212 ranu 211
        // If no user found at any level, return 0 with the target escalation
36210 ranu 212
        LOGGER.warn("No auth user found for any escalation level for categoryId {} and fofoId {}", categoryId, fofoId);
36212 ranu 213
        return new EscalationAssignmentResult(0, targetEscalation);
36210 ranu 214
    }
215
 
36212 ranu 216
    /**
217
     * Gets auth user ID with fallback (for backward compatibility)
218
     */
219
    private int getAuthUserIdWithFallback(int categoryId, EscalationType targetEscalation, int fofoId) throws ProfitMandiBusinessException {
220
        return getAuthUserWithFallback(categoryId, targetEscalation, fofoId).getAuthUserId();
221
    }
222
 
36210 ranu 223
    @Override
32923 ranu 224
    public TicketActivityMedia createMediaActivity(ActivityMediaModel selectedRecording) {
225
        TicketActivityMedia activity = new TicketActivityMedia();
226
        activity.setMobile(selectedRecording.getMobile());
33009 ranu 227
        // add a prefix endpoint of mediaUrl
34158 tejus.loha 228
        // String customValue = "https://ccs1.smartpingcc.io/v2/recording/direct/71287091";
33588 ranu 229
        activity.setMediaUrl(selectedRecording.getMediaUrl());
32923 ranu 230
        activity.setDurationInSec(selectedRecording.getDurationInSec());
231
        activity.setCallTime(selectedRecording.getCallConnectTime());
232
        activity.setCreatedBy(0);
233
        activity.setCreateTimestamp(LocalDateTime.now());
234
        activityMediaRepository.persist(activity);
235
        return activity;
236
    }
237
 
33204 ranu 238
    @Override
32923 ranu 239
    public void addMediaActivity(Ticket ticket, TicketActivityMedia activity) {
32940 ranu 240
        activity.setActivityId(ticket.getLastActivityId());
32923 ranu 241
    }
242
 
243
    @Override
244
    public void createTicketRemarkEscalation(int fofoId, int authId, int categoryId, int subcategoryId, String message, CollectionRemark remark) throws ProfitMandiBusinessException {
245
 
246
        ActivityType type = ActivityType.OPENED;
247
        Ticket ticket = new Ticket();
248
        ticket.setSubCategoryId(subcategoryId);
249
        ticket.setFofoId(fofoId);
250
        ticket.setCreateTimestamp(LocalDateTime.now());
251
        ticket.setUpdateTimestamp(LocalDateTime.now());
252
        ticket.setHappyCode(getRandomString());
253
        ticketRepository.persist(ticket);
254
        this.addActivity(ticket, this.createActivity(type, String.valueOf(remark), authId));
255
        ticket.setFirstActivityId(ticket.getLastActivityId());
33041 ranu 256
        this.assignTicketByAuthId(ticket, authId, EscalationType.L2);
32923 ranu 257
 
258
    }
259
 
260
 
261
    @Override
31762 tejbeer 262
    public void assignTicket(Ticket ticket) throws ProfitMandiBusinessException {
35683 ranu 263
        this.assignTicket(ticket,0);
264
    }
265
 
266
    @Override
267
    public void assignTicket(Ticket ticket,int currentUserId) throws ProfitMandiBusinessException {
31762 tejbeer 268
        TicketAssigned ticketAssigned = null;
269
        EscalationType newEscalationType = EscalationType.L1;
270
        if (ticket.getAssignmentId() > 0) {
271
            ticketAssigned = ticketAssignedRepository.selectById(ticket.getAssignmentId());
272
            newEscalationType = ticketAssigned.getEscalationType().next();
273
            if (newEscalationType == null || newEscalationType.equals(EscalationType.Final)) {
274
                LOGGER.info("Cant escalate further");
275
                return;
276
            }
277
        } else {
278
            ticket.setL1AuthUser(0);
279
            ticket.setL2AuthUser(0);
280
            ticket.setL3AuthUser(0);
281
            ticket.setL4AuthUser(0);
282
            ticket.setL5AuthUser(0);
283
        }
284
        ticket.setUpdateTimestamp(LocalDateTime.now());
27124 amit.gupta 285
 
286
 
31762 tejbeer 287
        TicketSubCategory ticketSubCategory = ticketSubCategoryRepository.selectById(ticket.getSubCategoryId());
288
        TicketCategory ticketCategory = ticketCategoryRepository.selectById(ticketSubCategory.getCategoryId());
289
        Map<Integer, EscalationType> escalationUserMap = new HashedMap<>();
290
        Set<Integer> assigneeUserIds = new LinkedHashSet<>();
291
        EscalationType escalationTypeNext = newEscalationType;
292
        do {
293
            int assigneeUserId = this.getAuthUserId(ticketCategory.getId(), escalationTypeNext, ticket.getFofoId());
294
            if (assigneeUserId == 0) {
295
                escalationTypeNext = escalationTypeNext.next();
296
                LOGGER.info("Escalation type next {}", escalationTypeNext);
297
                continue;
298
            }
299
            assigneeUserIds.add(assigneeUserId);
300
            escalationUserMap.put(assigneeUserId, escalationTypeNext);
301
            switch (escalationTypeNext) {
302
                case L1:
303
                    ticket.setL1AuthUser(assigneeUserId);
304
                    break;
305
                case L2:
306
                    ticket.setL2AuthUser(assigneeUserId);
307
                    break;
308
                case L3:
309
                    ticket.setL3AuthUser(assigneeUserId);
310
                    break;
311
                case L4:
312
                    ticket.setL4AuthUser(assigneeUserId);
313
                    break;
314
                case L5:
315
                    ticket.setL5AuthUser(assigneeUserId);
316
                    break;
27545 tejbeer 317
 
31762 tejbeer 318
                default:
319
                    break;
320
            }
321
            escalationTypeNext = escalationTypeNext.next();
322
            // LOGGER.info("Escalation type next {}", escalationTypeNext);
323
        } while (!escalationTypeNext.equals(EscalationType.Final));
27124 amit.gupta 324
 
31762 tejbeer 325
        int assigneeAuthId = assigneeUserIds.stream().findFirst().orElse(0);
27545 tejbeer 326
 
31762 tejbeer 327
        int managerAuthId = 0;
328
        EscalationType assigneeEscalationType = null;
329
        if (assigneeAuthId == 0) {
330
            assigneeAuthId = ProfitMandiConstants.FINAL_AUTH_ID;
331
            assigneeEscalationType = EscalationType.Final;
332
            managerAuthId = ProfitMandiConstants.FINAL_AUTH_ID;
333
        } else {
334
            assigneeEscalationType = escalationUserMap.get(assigneeAuthId);
335
            managerAuthId = assigneeUserIds.stream().skip(1).findFirst().orElse(0);
336
            if (managerAuthId == 0) {
337
                managerAuthId = ProfitMandiConstants.FINAL_AUTH_ID;
338
            }
339
        }
27545 tejbeer 340
 
31762 tejbeer 341
        TicketAssigned ticketAssignedNew = new TicketAssigned();
342
        ticketAssignedNew.setTicketId(ticket.getId());
343
        ticketAssignedNew.setAssineeId(assigneeAuthId);
344
        ticketAssignedNew.setEscalationType(assigneeEscalationType);
345
        ticketAssignedNew.setManagerId(managerAuthId);
35683 ranu 346
        ticketAssignedNew.setAssignedBy(currentUserId);
31762 tejbeer 347
        ticketAssignedNew.setCreateTimestamp(LocalDateTime.now());
348
        ticketAssignedRepository.persist(ticketAssignedNew);
349
        LOGGER.info(ticketAssigned);
24383 amit.gupta 350
 
31762 tejbeer 351
        AuthUser authUser = authRepository.selectById(ticketAssignedNew.getAssineeId());
352
        AuthUser authUserManager = null;
27124 amit.gupta 353
 
31762 tejbeer 354
        // Dont send cc mail if both are same
355
        if (managerAuthId != assigneeAuthId) {
356
            authUserManager = authRepository.selectById(managerAuthId);
357
        }
358
        ticket.setAssignmentId(ticketAssignedNew.getId());
27124 amit.gupta 359
 
31762 tejbeer 360
        List<Activity> activities = activityRepository.selectAll(ticket.getId());
361
        this.sendAssignedTicketMail(authUser, Arrays.asList(authUserManager), ticket, ticketAssigned != null, activities);
362
        if (!ticketAssignedNew.getEscalationType().equals(EscalationType.L1)) {
35683 ranu 363
            this.addActivity(ticket, this.createActivity(ActivityType.ESCALATED, "Ticket ecalated and assigned to " + authUser.getName(), currentUserId));
31762 tejbeer 364
        } else {
35683 ranu 365
            this.addActivity(ticket, this.createActivity(ActivityType.ASSIGNED, "Ticket assigned to " + authUser.getName(), currentUserId));
31762 tejbeer 366
        }
367
    }
27124 amit.gupta 368
 
31762 tejbeer 369
    public void updateTicket(int categoryId, int subCategoryId, Ticket ticket, int authUserId, EscalationType escalationType) throws ProfitMandiBusinessException {
35683 ranu 370
        this.updateTicket(categoryId, subCategoryId, ticket, authUserId, escalationType, null,0);
33204 ranu 371
    }
27545 tejbeer 372
 
33204 ranu 373
    @Override
35683 ranu 374
    public void updateTicket(int categoryId, int subCategoryId, Ticket ticket, int authUserId, EscalationType escalationType, ActivityMediaModel recording,int currentUserId) throws ProfitMandiBusinessException {
35647 ranu 375
        LOGGER.info("subCategoryId {}",subCategoryId);
31762 tejbeer 376
        TicketSubCategory ticketSubCategory = ticketSubCategoryRepository.getTicketSubCategoryMap().get(subCategoryId);
377
        if (ticketSubCategory == null) {
378
            throw new ProfitMandiBusinessException("Could not find subCategoryId " + subCategoryId + "- " + categoryId, "Problem", "Problem");
379
        }
380
        String storeName = retailerService.getAllFofoRetailers().get(ticket.getFofoId()).getBusinessName();
381
        List<TicketAssigned> oldTicketAssignedList = ticketAssignedRepository.selectByTicketIds(Arrays.asList(ticket.getId()));
382
        for (TicketAssigned oldTicketAssigned : oldTicketAssignedList) {
383
            ticketAssignedRepository.delete(oldTicketAssigned);
384
        }
27124 amit.gupta 385
 
31762 tejbeer 386
        if (ticket.getSubCategoryId() != ticketSubCategory.getId()) {
387
            ticket.setSubCategoryId(ticketSubCategory.getId());
388
            List<Integer> oldAssignedAuthUserIds = oldTicketAssignedList.stream().map(x -> x.getAssineeId()).collect(Collectors.toList());
35394 amit 389
            List<String> oldAssignedEmailIds = authRepository.selectByIds(oldAssignedAuthUserIds).stream().map(x -> x.getEmailId()).collect(Collectors.toList());
31762 tejbeer 390
            String mailTo = oldAssignedEmailIds.remove(0);
391
            String message = String.format(CATEGORY_CHANGED_TICKET, ticket.getId(), storeName, ticketSubCategory.getTicketCategory().getName() + " - " + ticketSubCategory.getName());
392
            try {
35963 amit 393
                mailOutboxService.queueMail(mailTo, oldAssignedEmailIds.toArray(new String[0]), "Ticket Category/Subcategory Changed", message, "CsServiceImpl.updateTicket");
31762 tejbeer 394
            } catch (Exception e) {
395
                LOGGER.info("Could not send mail for ticket {}", ticket.toString());
396
            }
24417 govind 397
 
31762 tejbeer 398
            Activity categoryChangedActivity = this.createActivity(ActivityType.CATEGORY_CHANGED, "Category changed to " + ticketSubCategory.getTicketCategory().getName() + " - " + ticketSubCategory.getName(), 0);
399
            this.addActivity(ticket, categoryChangedActivity);
34158 tejus.loha 400
            if (recording != null) {
33204 ranu 401
                this.addMediaActivity(ticket, this.createMediaActivity(recording));
402
            }
24439 govind 403
 
24383 amit.gupta 404
 
31762 tejbeer 405
        }
24383 amit.gupta 406
 
31762 tejbeer 407
        if (authUserId > 0) {
35683 ranu 408
            LOGGER.info("authUserId--1111444 {}",authUserId);
31762 tejbeer 409
            this.assignTicketByAuthId(ticket, authUserId, escalationType);
24417 govind 410
 
31762 tejbeer 411
        } else {
35683 ranu 412
            LOGGER.info("authUserId--11113355 {}",authUserId);
31762 tejbeer 413
            ticket.setAssignmentId(0);
35683 ranu 414
            this.assignTicket(ticket,currentUserId);
31762 tejbeer 415
        }
24417 govind 416
 
31762 tejbeer 417
    }
24500 govind 418
 
31762 tejbeer 419
    private void assignTicketByAuthId(Ticket ticket, int authUserId, EscalationType escalationType) throws ProfitMandiBusinessException {
24500 govind 420
 
31762 tejbeer 421
        AuthUser authUser = authRepository.selectById(authUserId);
24500 govind 422
 
31762 tejbeer 423
        LOGGER.info("authUser {}", authUser);
24417 govind 424
 
31762 tejbeer 425
        int managerAuthId = authUser.getManagerId();
24417 govind 426
 
33773 ranu 427
        TicketSubCategory ticketSubCategory = ticketSubCategoryRepository.selectById(ticket.getSubCategoryId());
428
        TicketCategory ticketCategory = ticketCategoryRepository.selectById(ticketSubCategory.getCategoryId());
429
 
430
        int authUserL2 = this.getAuthUserId(ticketCategory.getId(), EscalationType.L2, ticket.getFofoId());
431
        int authUserL3 = this.getAuthUserId(ticketCategory.getId(), EscalationType.L3, ticket.getFofoId());
432
        int authUserL4 = this.getAuthUserId(ticketCategory.getId(), EscalationType.L4, ticket.getFofoId());
433
        int authUserL5 = this.getAuthUserId(ticketCategory.getId(), EscalationType.L5, ticket.getFofoId());
434
 
31762 tejbeer 435
        if (escalationType.equals(EscalationType.L1)) {
436
            ticket.setL1AuthUser(authUserId);
33773 ranu 437
            ticket.setL2AuthUser(authUserL2);
438
            ticket.setL3AuthUser(authUserL3);
439
            ticket.setL4AuthUser(authUserL4);
440
            ticket.setL5AuthUser(authUserL5);
31762 tejbeer 441
        } else if (escalationType.equals(EscalationType.L2)) {
442
            ticket.setL2AuthUser(authUserId);
33773 ranu 443
            ticket.setL3AuthUser(authUserL3);
444
            ticket.setL4AuthUser(authUserL4);
445
            ticket.setL5AuthUser(authUserL5);
31762 tejbeer 446
        }
447
        if (escalationType.equals(EscalationType.L3)) {
448
            ticket.setL3AuthUser(authUserId);
33773 ranu 449
            ticket.setL4AuthUser(authUserL4);
450
            ticket.setL5AuthUser(authUserL5);
31762 tejbeer 451
        }
452
        if (escalationType.equals(EscalationType.L4)) {
30426 tejbeer 453
 
31762 tejbeer 454
            ticket.setL4AuthUser(authUserId);
33773 ranu 455
            ticket.setL5AuthUser(authUserL5);
31762 tejbeer 456
        }
457
        if (escalationType.equals(EscalationType.L5)) {
458
            ticket.setL5AuthUser(authUserId);
459
        }
30426 tejbeer 460
 
24417 govind 461
 
31762 tejbeer 462
        TicketAssigned ticketAssignedNew = new TicketAssigned();
463
        ticketAssignedNew.setTicketId(ticket.getId());
464
        ticketAssignedNew.setAssineeId(authUserId);
465
        ticketAssignedNew.setEscalationType(escalationType);
466
        ticketAssignedNew.setManagerId(managerAuthId);
467
        ticketAssignedNew.setCreateTimestamp(LocalDateTime.now());
468
        ticketAssignedRepository.persist(ticketAssignedNew);
24439 govind 469
 
31762 tejbeer 470
        LOGGER.info("ticketAssignedNew {}", ticketAssignedNew);
24439 govind 471
 
24500 govind 472
 
31762 tejbeer 473
        AuthUser authUserManager = null;
24439 govind 474
 
24500 govind 475
 
31762 tejbeer 476
        // Dont send cc mail if both are same
477
        if (managerAuthId != authUserId) {
478
            authUserManager = authRepository.selectById(managerAuthId);
479
        }
480
        ticket.setAssignmentId(ticketAssignedNew.getId());
27124 amit.gupta 481
 
25570 tejbeer 482
 
31762 tejbeer 483
        List<Activity> activities = activityRepository.selectAll(ticket.getId());
25570 tejbeer 484
 
31762 tejbeer 485
        this.sendAssignedTicketMail(authUser, Arrays.asList(authUserManager), ticket, false, activities);
486
        if (!ticketAssignedNew.getEscalationType().equals(EscalationType.L1)) {
487
            this.addActivity(ticket, this.createActivity(ActivityType.ESCALATED, "Ticket ecalated and assigned to " + authUser.getName(), 0));
488
        } else {
489
            this.addActivity(ticket, this.createActivity(ActivityType.ASSIGNED, "Ticket assigned to " + authUser.getName(), 0));
490
        }
25570 tejbeer 491
 
31762 tejbeer 492
    }
25570 tejbeer 493
 
31762 tejbeer 494
    @Override
495
    public Activity createActivity(ActivityType activityType, String message, int createdBy) {
496
        Activity activity = new Activity();
497
        activity.setMessage(message);
498
        activity.setCreatedBy(createdBy);
499
        activity.setType(activityType);
500
        activity.setCreateTimestamp(LocalDateTime.now());
501
        activityRepository.persist(activity);
502
        return activity;
503
    }
25570 tejbeer 504
 
31762 tejbeer 505
    @Override
33244 ranu 506
    public int getAuthUserId(int categoryId, EscalationType escalationType, int fofoId) throws ProfitMandiBusinessException {
31762 tejbeer 507
        int authUserId = 0;
508
        List<Position> positions = positionRepository.selectPositionbyCategoryIdAndEscalationType(categoryId, escalationType);
509
        List<Integer> regionIds = partnerRegionRepository.selectByfofoId(fofoId).stream().map(x -> x.getRegionId()).collect(Collectors.toList());
510
        // Add all Partner regions id
511
        regionIds.add(ALL_PARTNERS_REGION);
512
        LOGGER.info("Escalation Type {}, Region Ids {}", escalationType, regionIds);
32493 amit.gupta 513
        List<Integer> partnerPositionsIds = partnerPositionRepository.selectByRegionIdAndPartnerId(regionIds, Arrays.asList(0, fofoId)).stream().map(x -> x.getPositionId()).collect(Collectors.toList());
33022 amit.gupta 514
 
31829 amit.gupta 515
        List<Position> positionAssignee = positions.stream().filter(x -> x.isTicketAssignee() && partnerPositionsIds.contains(x.getId())).collect(Collectors.toList());
31762 tejbeer 516
        LOGGER.info("User List List {}", positions.stream().map(x -> x.getAuthUserId()).collect(Collectors.toList()));
34276 ranu 517
        LOGGER.info("positionAssignee List {}", positionAssignee);
31829 amit.gupta 518
        if (positionAssignee.size() > 0) {
34276 ranu 519
 
35394 amit 520
            List<AuthUser> authUsers = authRepository.selectByIds(
33022 amit.gupta 521
                    positionAssignee.stream().map(x -> x.getAuthUserId()).collect(Collectors.toList()));
31762 tejbeer 522
            authUsers = authUsers.stream().filter(x -> x.isActive()).collect(Collectors.toList());
34276 ranu 523
            LOGGER.info("Auth User List {}", authUsers);
31762 tejbeer 524
            if (authUsers.size() > 0) {
525
                authUserId = authUsers.get(0).getId();
526
                /*
527
                 * Random rand = new Random(); authUserId =
528
                 * authUsers.get(rand.nextInt(authUsers.size())).getId();
529
                 */
530
            }
531
        }
532
        return authUserId;
25570 tejbeer 533
 
31762 tejbeer 534
    }
25597 amit.gupta 535
 
34921 ranu 536
    @Override
537
    public int getAuthUserIdWithoutTicketAssignee(int categoryId, EscalationType escalationType, int fofoId) throws ProfitMandiBusinessException {
538
        int authUserId = 0;
539
        List<Position> positions = positionRepository.selectPositionbyCategoryIdAndEscalationType(categoryId, escalationType);
540
        List<Integer> regionIds = partnerRegionRepository.selectByfofoId(fofoId).stream().map(x -> x.getRegionId()).collect(Collectors.toList());
541
        // Add all Partner regions id
542
        regionIds.add(ALL_PARTNERS_REGION);
543
        LOGGER.info("Escalation Type {}, Region Ids {}", escalationType, regionIds);
544
        List<Integer> partnerPositionsIds = partnerPositionRepository.selectByRegionIdAndPartnerId(regionIds, Arrays.asList(0, fofoId)).stream().map(x -> x.getPositionId()).collect(Collectors.toList());
33022 amit.gupta 545
 
34921 ranu 546
        List<Position> positionAssignee = positions.stream().filter(x -> partnerPositionsIds.contains(x.getId())).collect(Collectors.toList());
547
        LOGGER.info("User List List {}", positions.stream().map(x -> x.getAuthUserId()).collect(Collectors.toList()));
548
        LOGGER.info("positionAssignee List {}", positionAssignee);
549
        if (positionAssignee.size() > 0) {
550
 
35394 amit 551
            List<AuthUser> authUsers = authRepository.selectByIds(
34921 ranu 552
                    positionAssignee.stream().map(x -> x.getAuthUserId()).collect(Collectors.toList()));
553
            authUsers = authUsers.stream().filter(x -> x.isActive()).collect(Collectors.toList());
554
            LOGGER.info("Auth User List {}", authUsers);
555
            if (authUsers.size() > 0) {
556
                authUserId = authUsers.get(0).getId();
557
                /*
558
                 * Random rand = new Random(); authUserId =
559
                 * authUsers.get(rand.nextInt(authUsers.size())).getId();
560
                 */
561
            }
562
        }
563
        return authUserId;
564
 
565
    }
566
 
567
 
31762 tejbeer 568
    @Override
569
    public void addActivity(Ticket ticket, Activity activity) {
570
        activity.setTicketId(ticket.getId());
571
        ticket.setLastActivity(activity.getType());
572
        ticket.setLastActivityId(activity.getId());
573
    }
25597 amit.gupta 574
 
31762 tejbeer 575
    private String getRandomString() {
576
        int length = 4;
577
        boolean useLetters = false;
578
        boolean useNumbers = true;
579
        String generatedString = RandomStringUtils.random(length, useLetters, useNumbers);
580
        return generatedString;
581
    }
25721 tejbeer 582
 
31762 tejbeer 583
    @Override
584
    public void addPartnerToRegion(int regionId, List<Integer> fofoIds) {
25721 tejbeer 585
 
31762 tejbeer 586
        for (int fofoId : fofoIds) {
587
            PartnerRegion partnerRegion = new PartnerRegion();
588
            partnerRegion.setFofoId(fofoId);
589
            partnerRegion.setRegionId(regionId);
590
            partnerRegionRepository.persist(partnerRegion);
591
        }
592
    }
25721 tejbeer 593
 
31762 tejbeer 594
    @Override
595
    public Map<Integer, AuthUser> getAuthUserIdAndAuthUserMap(List<TicketAssigned> ticketAssigneds) {
35454 amit 596
        if (ticketAssigneds == null || ticketAssigneds.isEmpty()) {
597
            return new HashMap<>();
598
        }
599
        // OPTIMIZED: Batch fetch all AuthUsers instead of N+1 queries
600
        List<Integer> assigneeIds = ticketAssigneds.stream()
601
                .map(TicketAssigned::getAssineeId)
602
                .distinct()
603
                .collect(Collectors.toList());
604
        Map<Integer, AuthUser> authUserById = authRepository.selectByIds(assigneeIds).stream()
605
                .collect(Collectors.toMap(AuthUser::getId, au -> au, (a, b) -> a));
606
 
31762 tejbeer 607
        Map<Integer, AuthUser> authUserIdAndAuthUserMap = new HashMap<>();
608
        for (TicketAssigned ticketAssigned : ticketAssigneds) {
35454 amit 609
            authUserIdAndAuthUserMap.put(ticketAssigned.getTicketId(), authUserById.get(ticketAssigned.getAssineeId()));
31762 tejbeer 610
        }
611
        return authUserIdAndAuthUserMap;
612
    }
31465 tejbeer 613
 
31762 tejbeer 614
    @Override
615
    public Map<Integer, AuthUser> getTicketIdAndAuthUserMapUsingTickets(List<Ticket> tickets) {
35454 amit 616
        if (tickets == null || tickets.isEmpty()) {
617
            return new HashMap<>();
618
        }
619
        // OPTIMIZED: Batch fetch all AuthUsers instead of N+1 queries
620
        List<Integer> authUserIds = tickets.stream()
35562 ranu 621
                .map(this::getEffectiveAuthUserId)
35454 amit 622
                .filter(id -> id != null && id > 0)
623
                .distinct()
624
                .collect(Collectors.toList());
625
        Map<Integer, AuthUser> authUserById = authRepository.selectByIds(authUserIds).stream()
626
                .collect(Collectors.toMap(AuthUser::getId, au -> au, (a, b) -> a));
627
 
31762 tejbeer 628
        Map<Integer, AuthUser> authUserIdAndAuthUserMap = new HashMap<>();
629
        for (Ticket ticket : tickets) {
35454 amit 630
            authUserIdAndAuthUserMap.put(ticket.getId(), authUserById.get(ticket.getL1AuthUser()));
31762 tejbeer 631
        }
632
        return authUserIdAndAuthUserMap;
633
    }
31152 tejbeer 634
 
35562 ranu 635
    private Integer getEffectiveAuthUserId(Ticket ticket) {
636
 
637
        if (ticket.getL1AuthUser() > 0) {
638
            return ticket.getL1AuthUser();
639
        }
640
        if (ticket.getL2AuthUser() > 0) {
641
            return ticket.getL2AuthUser();
642
        }
643
        if (ticket.getL3AuthUser() > 0) {
644
            return ticket.getL3AuthUser();
645
        }
35563 ranu 646
        if (ticket.getL4AuthUser() > 0) {
647
            return ticket.getL4AuthUser();
648
        }
35562 ranu 649
        return null;
650
    }
651
 
652
 
31762 tejbeer 653
    @Override
654
    public Map<Integer, TicketSubCategory> getSubCategoryIdAndSubCategoryMap(List<Integer> subCategoryIds) {
655
        Map<Integer, TicketSubCategory> subCategoryIdAndSubCategoryMap = new HashMap<>();
656
        subCategoryIdAndSubCategoryMap = ticketSubCategoryRepository.selectByIds(subCategoryIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
657
        return subCategoryIdAndSubCategoryMap;
658
    }
31152 tejbeer 659
 
31762 tejbeer 660
    @Override
33244 ranu 661
    public Map<Integer, CustomRetailer> getPartnerByFofoIds(List<Ticket> tickets) throws ProfitMandiBusinessException {
31762 tejbeer 662
        List<Integer> fofoIds = new ArrayList<>();
663
        LOGGER.info(tickets);
664
        if (tickets == null) {
665
            return null;
666
        }
667
        for (Ticket ticket : tickets) {
668
            fofoIds.add(ticket.getFofoId());
669
        }
25721 tejbeer 670
 
31762 tejbeer 671
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
25721 tejbeer 672
 
31762 tejbeer 673
        Map<Integer, CustomRetailer> fofoIdsAndCustomRetailer = fofoIds.stream().distinct().map(x -> customRetailerMap.get(x)).filter(x -> x != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
674
        return fofoIdsAndCustomRetailer;
675
    }
25799 tejbeer 676
 
31762 tejbeer 677
    @Override
678
    public List<TicketCategory> getAllTicketCategotyFromSubCategory() {
25721 tejbeer 679
 
31830 amit.gupta 680
        Collection<TicketSubCategory> ticketSubCategories = ticketSubCategoryRepository.getTicketSubCategoryMap().values();
681
        return new ArrayList<>(ticketSubCategories.stream().map(x -> x.getTicketCategory()).collect(Collectors.toSet()));
31762 tejbeer 682
    }
25799 tejbeer 683
 
31762 tejbeer 684
    @Override
685
    public Map<Integer, AuthUser> getAuthUserIdAndAuthUserMapUsingPositions(List<Position> positions) {
35454 amit 686
        if (positions == null || positions.isEmpty()) {
687
            return new HashMap<>();
31762 tejbeer 688
        }
35454 amit 689
        // OPTIMIZED: Batch fetch all AuthUsers instead of N+1 queries
690
        List<Integer> authUserIds = positions.stream()
691
                .map(Position::getAuthUserId)
692
                .filter(id -> id != null && id > 0)
693
                .distinct()
694
                .collect(Collectors.toList());
695
        return authRepository.selectByIds(authUserIds).stream()
696
                .collect(Collectors.toMap(AuthUser::getId, au -> au, (a, b) -> a));
31762 tejbeer 697
    }
25721 tejbeer 698
 
31762 tejbeer 699
    @Override
700
    public Map<Integer, TicketCategory> getCategoryIdAndCategoryUsingPositions(List<Position> positions) {
35454 amit 701
        if (positions == null || positions.isEmpty()) {
702
            return new HashMap<>();
31762 tejbeer 703
        }
35454 amit 704
        // OPTIMIZED: Batch fetch all categories instead of N+1 queries
705
        List<Integer> categoryIds = positions.stream()
706
                .map(Position::getCategoryId)
707
                .filter(id -> id != null && id > 0)
708
                .distinct()
709
                .collect(Collectors.toList());
710
        return ticketCategoryRepository.selectAll(categoryIds).stream()
711
                .collect(Collectors.toMap(TicketCategory::getId, tc -> tc, (a, b) -> a));
31762 tejbeer 712
    }
29318 tejbeer 713
 
31762 tejbeer 714
    @Override
715
    public Map<Integer, Region> getRegionIdAndRegionMap(List<Position> positions) {
35454 amit 716
        if (positions == null || positions.isEmpty()) {
717
            return new HashMap<>();
31762 tejbeer 718
        }
35454 amit 719
        // OPTIMIZED: Batch fetch all regions instead of N+1 queries
720
        Set<Integer> regionIds = positions.stream()
721
                .map(Position::getRegionId)
722
                .filter(id -> id != null && id > 0)
723
                .collect(Collectors.toSet());
724
        return regionRepository.selectAll().stream()
725
                .filter(r -> regionIds.contains(r.getId()))
726
                .collect(Collectors.toMap(Region::getId, r -> r, (a, b) -> a));
31762 tejbeer 727
    }
29318 tejbeer 728
 
31762 tejbeer 729
    private void sendAssignedTicketMail(AuthUser authUserTo, List<AuthUser> authUsersCc, Ticket ticket, boolean isEscalated, List<Activity> activities) throws ProfitMandiBusinessException {
730
        try {
731
            String[] ccTo = authUsersCc.stream().filter(x -> x != null).map(x -> x.getEmailId()).toArray(String[]::new);
25721 tejbeer 732
 
31762 tejbeer 733
            String messageFormat = null;
734
            if (isEscalated) {
735
                messageFormat = ESCALATED_TICKET;
736
            } else {
737
                messageFormat = ASSIGNED_TICKET;
738
            }
739
            String message = String.format(messageFormat, authUserTo.getName(), ticket.getId(), activities.get(0).getMessage(), retailerService.getFofoRetailer(ticket.getFofoId()).getBusinessName());
35963 amit 740
            mailOutboxService.queueMail(authUserTo.getEmailId(), ccTo, ASSINMENT_SUBJECT, message, "CsServiceImpl.sendAssignedTicketMail");
31762 tejbeer 741
        } catch (Exception e) {
742
            e.printStackTrace();
743
            throw new ProfitMandiBusinessException("Ticket Assingment", authUserTo.getEmailId(), "Could not send ticket assignment mail");
744
        }
745
    }
26298 tejbeer 746
 
31762 tejbeer 747
    @Override
33244 ranu 748
    public Map<Integer, List<CustomRetailer>> getPositionCustomRetailerMap(List<Position> positions) throws ProfitMandiBusinessException {
31762 tejbeer 749
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
750
        Map<Integer, List<CustomRetailer>> positionRetailerMap = new HashMap<>();
35443 amit 751
 
752
        // Batch fetch all PartnerPositions upfront to avoid N+1 queries
753
        List<Integer> positionIds = positions.stream().map(Position::getId).collect(Collectors.toList());
754
        Map<Integer, List<Integer>> positionIdToFofoIdsMap = partnerPositionRepository.selectByPositionIds(positionIds)
755
                .stream()
756
                .collect(Collectors.groupingBy(
757
                        pp -> pp.getPositionId(),
758
                        Collectors.mapping(pp -> pp.getFofoId(), Collectors.toList())
759
                ));
760
 
761
        // Collect all region IDs that might need lookup (positions with fofoId=0)
762
        Set<Integer> regionIdsNeedingLookup = new HashSet<>();
31762 tejbeer 763
        for (Position position : positions) {
35443 amit 764
            List<Integer> fofoIds = positionIdToFofoIdsMap.get(position.getId());
765
            if (fofoIds != null && fofoIds.contains(0)) {
766
                regionIdsNeedingLookup.add(position.getRegionId());
767
            }
768
        }
26978 tejbeer 769
 
35443 amit 770
        // Batch fetch all PartnerRegions for regions needing lookup
771
        Map<Integer, List<Integer>> regionIdToFofoIdsMap = new HashMap<>();
772
        if (!regionIdsNeedingLookup.isEmpty()) {
773
            regionIdToFofoIdsMap = partnerRegionRepository.selectAllByRegionIds(new ArrayList<>(regionIdsNeedingLookup))
774
                    .stream()
775
                    .collect(Collectors.groupingBy(
776
                            pr -> pr.getRegionId(),
777
                            Collectors.mapping(pr -> pr.getFofoId(), Collectors.toList())
778
                    ));
779
        }
26978 tejbeer 780
 
35443 amit 781
        // Build the result map using pre-fetched data
782
        for (Position position : positions) {
783
            List<Integer> fofoIds = positionIdToFofoIdsMap.get(position.getId());
784
            if (fofoIds == null || fofoIds.isEmpty()) {
785
                continue;
786
            }
787
 
788
            if (fofoIds.contains(0)) {
789
                // Need region-based lookup
790
                fofoIds = regionIdToFofoIdsMap.get(position.getRegionId());
791
                if (fofoIds == null || fofoIds.contains(0)) {
792
                    fofoIds = new ArrayList<>(customRetailerMap.keySet());
31762 tejbeer 793
                }
35443 amit 794
            }
26978 tejbeer 795
 
35443 amit 796
            positionRetailerMap.put(position.getId(),
797
                    fofoIds.stream()
798
                            .map(customRetailerMap::get)
799
                            .filter(x -> x != null)
800
                            .collect(Collectors.toList()));
31762 tejbeer 801
        }
802
        return positionRetailerMap;
803
    }
26978 tejbeer 804
 
31762 tejbeer 805
    @Override
33244 ranu 806
    public Map<Integer, List<CustomRetailer>> getRegionPartners(List<Position> positions) throws ProfitMandiBusinessException {
31762 tejbeer 807
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
808
        Map<Integer, List<CustomRetailer>> positionIdAndpartnerRegionMap = new HashedMap<>();
26978 tejbeer 809
 
35443 amit 810
        // Batch fetch all PartnerRegions upfront to avoid N+1 queries
811
        List<Integer> regionIds = positions.stream().map(Position::getRegionId).distinct().collect(Collectors.toList());
812
        Map<Integer, List<Integer>> regionIdToFofoIdsMap = partnerRegionRepository.selectAllByRegionIds(regionIds)
813
                .stream()
814
                .collect(Collectors.groupingBy(
815
                        pr -> pr.getRegionId(),
816
                        Collectors.mapping(pr -> pr.getFofoId(), Collectors.toList())
817
                ));
26978 tejbeer 818
 
35443 amit 819
        // Fetch all store IDs once in case any region has fofoId=0
820
        List<Integer> allStoreIds = null;
26978 tejbeer 821
 
35443 amit 822
        for (Position position : positions) {
823
            List<Integer> fofoIds = regionIdToFofoIdsMap.get(position.getRegionId());
824
            if (fofoIds == null || fofoIds.isEmpty()) {
825
                continue;
31762 tejbeer 826
            }
26978 tejbeer 827
 
35443 amit 828
            if (fofoIds.contains(0)) {
829
                if (allStoreIds == null) {
830
                    allStoreIds = fofoStoreRepository.selectAll().stream().map(x -> x.getId()).collect(Collectors.toList());
831
                }
832
                fofoIds = allStoreIds;
833
            }
834
 
835
            Map<Integer, CustomRetailer> fofoRetailers = fofoIds.stream()
836
                    .map(customRetailerMap::get)
837
                    .filter(x -> x != null)
838
                    .collect(Collectors.toMap(x -> x.getPartnerId(), x -> x, (a, b) -> a));
839
            positionIdAndpartnerRegionMap.put(position.getRegionId(), new ArrayList<>(fofoRetailers.values()));
31762 tejbeer 840
        }
26978 tejbeer 841
 
31762 tejbeer 842
        return positionIdAndpartnerRegionMap;
843
    }
26978 tejbeer 844
 
31762 tejbeer 845
    @Override
846
    @Cacheable(value = "authUserEmailMapping", cacheManager = "thirtyMinsTimeOutCacheManager")
33244 ranu 847
    public Map<String, Set<String>> getAuthUserPartnerEmailMapping() throws ProfitMandiBusinessException {
31762 tejbeer 848
        Map<String, Set<String>> storeGuyMap = new HashMap<>();
849
        Set<Integer> activeFofoIds = fofoStoreRepository.selectActiveStores().stream().map(x -> x.getId()).collect(Collectors.toSet());
35443 amit 850
 
851
        // Batch fetch positions by category IDs instead of multiple calls
852
        List<Position> categoryPositions = positionRepository.selectPositionByCategoryIds(Arrays.asList(
853
                ProfitMandiConstants.TICKET_CATEGORY_SALES,
854
                ProfitMandiConstants.TICKET_CATEGORY_RBM,
855
                ProfitMandiConstants.TICKET_CATEGORY_ABM));
31762 tejbeer 856
        Map<Integer, Position> positionsMap = categoryPositions.stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
29229 tejbeer 857
 
35443 amit 858
        // Batch fetch all AuthUsers upfront to avoid N+1 queries
859
        Set<Integer> authUserIds = categoryPositions.stream().map(Position::getAuthUserId).collect(Collectors.toSet());
860
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(new ArrayList<>(authUserIds)).stream()
861
                .collect(Collectors.toMap(AuthUser::getId, x -> x));
862
 
31762 tejbeer 863
        Map<Integer, List<CustomRetailer>> positonPartnerMap = this.getPositionCustomRetailerMap(categoryPositions);
864
        for (Map.Entry<Integer, List<CustomRetailer>> positionPartnerEntry : positonPartnerMap.entrySet()) {
865
            int authUserId = positionsMap.get(positionPartnerEntry.getKey()).getAuthUserId();
866
            Set<String> partnerEmails = positionPartnerEntry.getValue().stream().filter(x -> activeFofoIds.contains(x.getPartnerId())).map(x -> x.getEmail()).collect(Collectors.toSet());
35443 amit 867
            AuthUser authUser = authUserMap.get(authUserId);
868
            if (authUser != null && authUser.isActive()) {
31762 tejbeer 869
                if (!storeGuyMap.containsKey(authUser.getEmailId())) {
870
                    storeGuyMap.put(authUser.getEmailId(), partnerEmails);
871
                } else {
872
                    storeGuyMap.get(authUser.getEmailId()).addAll(partnerEmails);
873
                }
874
            }
875
        }
876
        return storeGuyMap;
877
    }
29229 tejbeer 878
 
31762 tejbeer 879
    @Override
880
    @Cacheable(value = "authUserEmailPartnerIdMapping", cacheManager = "thirtyMinsTimeOutCacheManager")
33244 ranu 881
    public Map<String, Set<Integer>> getAuthUserPartnerIdMapping() throws ProfitMandiBusinessException {
31762 tejbeer 882
        Map<String, Set<Integer>> storeGuyMap = new HashMap<>();
883
        Set<Integer> activeFofoIds = fofoStoreRepository.selectActiveStores().stream().map(x -> x.getId()).collect(Collectors.toSet());
35443 amit 884
 
885
        // Batch fetch positions by category IDs instead of multiple calls
886
        List<Position> categoryPositions = positionRepository.selectPositionByCategoryIds(Arrays.asList(
887
                ProfitMandiConstants.TICKET_CATEGORY_SALES,
888
                ProfitMandiConstants.TICKET_CATEGORY_RBM,
889
                ProfitMandiConstants.TICKET_CATEGORY_ABM,
890
                ProfitMandiConstants.TICKET_CATEGORY_BUSINESSINTELLIGENT,
891
                ProfitMandiConstants.TICKET_CATEGORY_TRAINING));
31762 tejbeer 892
        Map<Integer, Position> positionsMap = categoryPositions.stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
31161 tejbeer 893
 
35443 amit 894
        // Batch fetch all AuthUsers upfront to avoid N+1 queries
895
        Set<Integer> authUserIds = categoryPositions.stream().map(Position::getAuthUserId).collect(Collectors.toSet());
896
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(new ArrayList<>(authUserIds)).stream()
897
                .collect(Collectors.toMap(AuthUser::getId, x -> x));
898
 
31762 tejbeer 899
        Map<Integer, List<CustomRetailer>> positonPartnerMap = this.getPositionCustomRetailerMap(categoryPositions);
900
        for (Map.Entry<Integer, List<CustomRetailer>> positionPartnerEntry : positonPartnerMap.entrySet()) {
901
            int authUserId = positionsMap.get(positionPartnerEntry.getKey()).getAuthUserId();
902
            Set<Integer> partnerIds = positionPartnerEntry.getValue().stream().filter(x -> activeFofoIds.contains(x.getPartnerId())).map(x -> x.getPartnerId()).collect(Collectors.toSet());
35443 amit 903
            AuthUser authUser = authUserMap.get(authUserId);
904
            if (authUser != null && authUser.isActive()) {
31762 tejbeer 905
                if (!storeGuyMap.containsKey(authUser.getEmailId())) {
906
                    storeGuyMap.put(authUser.getEmailId(), partnerIds);
907
                } else {
908
                    storeGuyMap.get(authUser.getEmailId()).addAll(partnerIds);
909
                }
910
            }
911
        }
912
        return storeGuyMap;
913
    }
31472 tejbeer 914
 
31762 tejbeer 915
    @Override
35920 ranu 916
    @Cacheable(value = "authUserEmailInactivePartnerIdMapping", cacheManager = "thirtyMinsTimeOutCacheManager")
917
    public Map<String, Set<Integer>> getAuthUserInactivePartnerIdMapping() throws ProfitMandiBusinessException {
918
        Map<String, Set<Integer>> storeGuyMap = new HashMap<>();
919
        Set<Integer> activeFofoIds = fofoStoreRepository.selectInActiveStore().stream().map(x -> x.getId()).collect(Collectors.toSet());
920
 
921
        // Batch fetch positions by category IDs instead of multiple calls
922
        List<Position> categoryPositions = positionRepository.selectPositionByCategoryIds(Arrays.asList(
923
                ProfitMandiConstants.TICKET_CATEGORY_SALES,
924
                ProfitMandiConstants.TICKET_CATEGORY_RBM,
925
                ProfitMandiConstants.TICKET_CATEGORY_ABM,
926
                ProfitMandiConstants.TICKET_CATEGORY_BUSINESSINTELLIGENT,
927
                ProfitMandiConstants.TICKET_CATEGORY_TRAINING));
928
        Map<Integer, Position> positionsMap = categoryPositions.stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
929
 
930
        // Batch fetch all AuthUsers upfront to avoid N+1 queries
931
        Set<Integer> authUserIds = categoryPositions.stream().map(Position::getAuthUserId).collect(Collectors.toSet());
932
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(new ArrayList<>(authUserIds)).stream()
933
                .collect(Collectors.toMap(AuthUser::getId, x -> x));
934
 
935
        Map<Integer, List<CustomRetailer>> positonPartnerMap = this.getPositionCustomRetailerMap(categoryPositions);
936
        for (Map.Entry<Integer, List<CustomRetailer>> positionPartnerEntry : positonPartnerMap.entrySet()) {
937
            int authUserId = positionsMap.get(positionPartnerEntry.getKey()).getAuthUserId();
938
            Set<Integer> partnerIds = positionPartnerEntry.getValue().stream().filter(x -> activeFofoIds.contains(x.getPartnerId())).map(x -> x.getPartnerId()).collect(Collectors.toSet());
939
            AuthUser authUser = authUserMap.get(authUserId);
940
            if (authUser != null && authUser.isActive()) {
941
                if (!storeGuyMap.containsKey(authUser.getEmailId())) {
942
                    storeGuyMap.put(authUser.getEmailId(), partnerIds);
943
                } else {
944
                    storeGuyMap.get(authUser.getEmailId()).addAll(partnerIds);
945
                }
946
            }
947
        }
948
        return storeGuyMap;
949
    }
950
 
951
    @Override
31762 tejbeer 952
    @Cacheable(value = "authUserPartnerEmailPartnerIdMapping", cacheManager = "thirtyMinsTimeOutCacheManager")
33244 ranu 953
    public Map<String, Set<Integer>> getAuthUserPartnerIdMappingByCategoryIds(List<Integer> categoryIds, boolean activeOnly) throws ProfitMandiBusinessException {
31762 tejbeer 954
        Map<String, Set<Integer>> authUserPartnerMap = new HashMap<>();
955
        Set<Integer> activeFofoIds;
956
        if (activeOnly) {
957
            activeFofoIds = fofoStoreRepository.selectActiveStores().stream().map(x -> x.getId()).collect(Collectors.toSet());
26298 tejbeer 958
 
31762 tejbeer 959
        } else {
960
            activeFofoIds = fofoStoreRepository.selectAll().stream().map(x -> x.getId()).collect(Collectors.toSet());
26298 tejbeer 961
 
31762 tejbeer 962
        }
26298 tejbeer 963
 
31762 tejbeer 964
        List<Position> categoryPositions = positionRepository.selectPositionByCategoryIds(categoryIds);
965
        Map<Integer, Position> positionsMap = categoryPositions.stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
26298 tejbeer 966
 
35454 amit 967
        // OPTIMIZED: Batch fetch all AuthUsers instead of N+1 queries
968
        List<Integer> authUserIds = categoryPositions.stream()
969
                .map(Position::getAuthUserId)
970
                .filter(id -> id != null && id > 0)
971
                .distinct()
972
                .collect(Collectors.toList());
973
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(authUserIds).stream()
974
                .collect(Collectors.toMap(AuthUser::getId, au -> au, (a, b) -> a));
975
 
31762 tejbeer 976
        Map<Integer, List<CustomRetailer>> positonPartnerMap = this.getPositionCustomRetailerMap(categoryPositions);
977
        for (Map.Entry<Integer, List<CustomRetailer>> positionPartnerEntry : positonPartnerMap.entrySet()) {
978
            int authUserId = positionsMap.get(positionPartnerEntry.getKey()).getAuthUserId();
979
            Set<Integer> partnerIds = positionPartnerEntry.getValue().stream().filter(x -> activeFofoIds.contains(x.getPartnerId())).map(x -> x.getPartnerId()).collect(Collectors.toSet());
35454 amit 980
            AuthUser authUser = authUserMap.get(authUserId);
981
            if (authUser != null && authUser.isActive()) {
31762 tejbeer 982
                if (!authUserPartnerMap.containsKey(authUser.getEmailId())) {
983
                    authUserPartnerMap.put(authUser.getEmailId(), partnerIds);
984
                } else {
985
                    authUserPartnerMap.get(authUser.getEmailId()).addAll(partnerIds);
986
                }
987
            }
988
        }
989
        return authUserPartnerMap;
990
    }
26298 tejbeer 991
 
31762 tejbeer 992
    @Override
34082 ranu 993
    public Map<Integer, List<Integer>> authUserpartnerIdMap(int authId, int categoryId) {
994
        Session session = sessionFactory.getCurrentSession();
995
 
34084 ranu 996
        Map<Integer, List<Integer>> authUserpartnerIdMap = new HashMap<>();
34082 ranu 997
 
34158 tejus.loha 998
        List<Position> authPositions = positionRepository.selectPositionbyCategoryIdAndAuthId(categoryId, authId);
34082 ranu 999
 
35454 amit 1000
        // OPTIMIZED: Batch fetch all PartnerPositions instead of N+1 queries
1001
        List<Integer> positionIds = authPositions.stream()
1002
                .map(Position::getId)
34084 ranu 1003
                .collect(Collectors.toList());
35454 amit 1004
        List<PartnerPosition> partnerPositions = partnerPositionRepository.selectByPositionIds(positionIds);
34082 ranu 1005
 
34084 ranu 1006
        if (partnerPositions.stream().anyMatch(partnerPosition -> partnerPosition.getFofoId() == 0)) {
1007
            List<FofoStore> activeFofoStores = fofoStoreRepository.selectActiveStores();
1008
 
1009
            List<Integer> fofoStoreIds = activeFofoStores.stream()
1010
                    .map(FofoStore::getId) // Extract the IDs of FofoStores
1011
                    .collect(Collectors.toList());
1012
 
1013
            authUserpartnerIdMap.put(authId, fofoStoreIds);
1014
 
34158 tejus.loha 1015
        } else {
34084 ranu 1016
            final TypedQuery<AuthUserPartnerMapModel> typedQuerySimilar = session
1017
                    .createNamedQuery("Position.Auth_User_Partner_Maping", AuthUserPartnerMapModel.class);
1018
 
1019
            typedQuerySimilar.setParameter("authId", authId);
1020
            typedQuerySimilar.setParameter("categoryId", categoryId);
1021
 
1022
            List<AuthUserPartnerMapModel> authUserPartnerMapModels = typedQuerySimilar.getResultList();
1023
 
1024
            authUserpartnerIdMap = authUserPartnerMapModels.stream()
1025
                    .collect(Collectors.groupingBy(
1026
                            AuthUserPartnerMapModel::getAuthId,
1027
                            Collectors.mapping(AuthUserPartnerMapModel::getFofoId, Collectors.toList())
1028
                    ));
1029
 
1030
        }
1031
 
34082 ranu 1032
        LOGGER.info("partnerusermap {}", authUserpartnerIdMap);
1033
        return authUserpartnerIdMap;
1034
    }
1035
 
1036
    @Override
33244 ranu 1037
    public List<String> getAuthUserByPartnerId(int fofoId) throws ProfitMandiBusinessException {
26298 tejbeer 1038
 
31762 tejbeer 1039
        List<String> emails = new ArrayList<>();
1040
        List<Integer> regionIds = partnerRegionRepository.selectByfofoId(fofoId).stream().map(x -> x.getRegionId()).collect(Collectors.toList());
26298 tejbeer 1041
 
31762 tejbeer 1042
        regionIds.add(5);// All partners Id;
26298 tejbeer 1043
 
32493 amit.gupta 1044
        List<Integer> partnerPositionIds = partnerPositionRepository.selectByRegionIdAndPartnerId(regionIds, Arrays.asList(fofoId, 0)).stream().map(x -> x.getPositionId()).collect(Collectors.toList());
26448 amit.gupta 1045
 
31762 tejbeer 1046
        LOGGER.info("partnerPositionIds" + partnerPositionIds);
27205 amit.gupta 1047
 
35394 amit 1048
        List<Position> positions = positionRepository.selectByIds(partnerPositionIds);
27548 tejbeer 1049
 
34905 ranu 1050
        positions = positions.stream().filter(x -> (x.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_SALES || x.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_RBM || x.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_ABM)).collect(Collectors.toList());
27548 tejbeer 1051
 
31762 tejbeer 1052
        if (!positions.isEmpty()) {
35454 amit 1053
            // OPTIMIZED: Batch fetch all AuthUsers instead of N+1 queries
1054
            List<Integer> authUserIds = positions.stream()
1055
                    .map(Position::getAuthUserId)
1056
                    .filter(id -> id != null && id > 0)
1057
                    .distinct()
1058
                    .collect(Collectors.toList());
1059
            Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(authUserIds).stream()
1060
                    .collect(Collectors.toMap(AuthUser::getId, au -> au, (a, b) -> a));
1061
 
31762 tejbeer 1062
            for (Position partnerPostionId : positions) {
35454 amit 1063
                AuthUser authUser = authUserMap.get(partnerPostionId.getAuthUserId());
31762 tejbeer 1064
                LOGGER.info("authUser" + authUser);
35454 amit 1065
                if (authUser != null) {
1066
                    emails.add(authUser.getEmailId());
1067
                }
31762 tejbeer 1068
            }
1069
        }
27548 tejbeer 1070
 
31762 tejbeer 1071
        return emails;
1072
    }
27548 tejbeer 1073
 
31762 tejbeer 1074
    @Override
33244 ranu 1075
    public Map<EscalationType, String> getAuthUserAndEsclationTypeByPartnerId(int fofoId) throws ProfitMandiBusinessException {
27548 tejbeer 1076
 
31762 tejbeer 1077
        List<String> emails = new ArrayList<>();
1078
        Map<EscalationType, String> emailEsclationTypeMap = new HashMap<>();
1079
        List<Integer> regionIds = partnerRegionRepository.selectByfofoId(fofoId).stream().map(x -> x.getRegionId()).collect(Collectors.toList());
27548 tejbeer 1080
 
31762 tejbeer 1081
        regionIds.add(5);// All partners Id;
1082
        List<Integer> fofoIds = new ArrayList<>();
1083
        fofoIds.add(fofoId);
1084
        fofoIds.add(0);
27548 tejbeer 1085
 
33074 amit.gupta 1086
        //LOGGER.info("fofoIds" + fofoIds);
32493 amit.gupta 1087
        List<Integer> partnerPositionIds = partnerPositionRepository.selectByRegionIdAndPartnerId(regionIds, fofoIds).stream().map(x -> x.getPositionId()).collect(Collectors.toList());
27548 tejbeer 1088
 
33074 amit.gupta 1089
        //LOGGER.info("partnerPositionIds" + partnerPositionIds);
28377 tejbeer 1090
 
35454 amit 1091
        // OPTIMIZED: Batch fetch all positions instead of N+1 queries
1092
        List<Position> positions = positionRepository.selectByIds(partnerPositionIds).stream()
1093
                .filter(p -> p.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_SALES)
1094
                .collect(Collectors.toList());
28377 tejbeer 1095
 
35454 amit 1096
        if (!positions.isEmpty()) {
1097
            // OPTIMIZED: Batch fetch all AuthUsers instead of N+1 queries
1098
            List<Integer> authUserIds = positions.stream()
1099
                    .map(Position::getAuthUserId)
1100
                    .filter(id -> id != null && id > 0)
1101
                    .distinct()
1102
                    .collect(Collectors.toList());
1103
            Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(authUserIds).stream()
1104
                    .collect(Collectors.toMap(AuthUser::getId, au -> au, (a, b) -> a));
1105
 
1106
            for (Position position : positions) {
1107
                AuthUser authUser = authUserMap.get(position.getAuthUserId());
33074 amit.gupta 1108
                //LOGGER.info("authUser" + authUser);
35454 amit 1109
                if (authUser != null) {
1110
                    emailEsclationTypeMap.put(position.getEscalationType(), authUser.getEmailId());
1111
                }
31762 tejbeer 1112
            }
1113
        }
28377 tejbeer 1114
 
33074 amit.gupta 1115
        //LOGGER.info("emailEsclationTypeMap" + emailEsclationTypeMap);
28377 tejbeer 1116
 
31762 tejbeer 1117
        return emailEsclationTypeMap;
1118
    }
31020 tejbeer 1119
 
31762 tejbeer 1120
    @Override
1121
    @Cacheable(value = "authUserIdPartnerIdMapping", cacheManager = "thirtyMinsTimeOutCacheManager")
33244 ranu 1122
    public Map<Integer, List<Integer>> getAuthUserIdPartnerIdMapping() throws ProfitMandiBusinessException {
31762 tejbeer 1123
        Map<Integer, List<Integer>> storeGuyMap = new HashMap<>();
1124
        Set<Integer> activeFofoIds = fofoStoreRepository.selectActiveStores().stream().map(x -> x.getId()).collect(Collectors.toSet());
31020 tejbeer 1125
 
34077 tejus.loha 1126
        List<Position> categoryPositions = positionRepository.selectAllPosition();
31020 tejbeer 1127
 
31762 tejbeer 1128
        Map<Integer, Position> positionsMap = categoryPositions.stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
29229 tejbeer 1129
 
35454 amit 1130
        // OPTIMIZED: Batch fetch all AuthUsers instead of N+1 queries
1131
        List<Integer> authUserIds = categoryPositions.stream()
1132
                .map(Position::getAuthUserId)
1133
                .filter(id -> id != null && id > 0)
1134
                .distinct()
1135
                .collect(Collectors.toList());
1136
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(authUserIds).stream()
1137
                .collect(Collectors.toMap(AuthUser::getId, au -> au, (a, b) -> a));
1138
 
31762 tejbeer 1139
        Map<Integer, List<CustomRetailer>> positonPartnerMap = this.getPositionCustomRetailerMap(categoryPositions);
1140
        for (Map.Entry<Integer, List<CustomRetailer>> positionPartnerEntry : positonPartnerMap.entrySet()) {
1141
            int authUserId = positionsMap.get(positionPartnerEntry.getKey()).getAuthUserId();
1142
            List<Integer> partnerIds = positionPartnerEntry.getValue().stream().filter(x -> activeFofoIds.contains(x.getPartnerId())).map(x -> x.getPartnerId()).collect(Collectors.toList());
35454 amit 1143
            AuthUser authUser = authUserMap.get(authUserId);
31762 tejbeer 1144
            if (authUser != null && authUser.isActive()) {
1145
                if (!storeGuyMap.containsKey(authUserId)) {
1146
                    storeGuyMap.put(authUserId, partnerIds);
1147
                } else {
1148
                    storeGuyMap.get(authUserId).addAll(partnerIds);
1149
                }
1150
            }
1151
        }
1152
        storeGuyMap.keySet().stream().forEach(x -> {
1153
            List<Integer> fofoIds = storeGuyMap.get(x);
1154
            storeGuyMap.put(x, fofoIds.stream().distinct().collect(Collectors.toList()));
1155
        });
1156
        return storeGuyMap;
1157
    }
28908 tejbeer 1158
 
31762 tejbeer 1159
    @Override
1160
    @Cacheable(value = "L1L2Mapping", cacheManager = "thirtyMinsTimeOutCacheManager")
33244 ranu 1161
    public Map<Integer, List<Integer>> getL2L1Mapping() throws ProfitMandiBusinessException {
31762 tejbeer 1162
        List<Position> l1SalesPositions = positionRepository.selectPositionbyCategoryIdAndEscalationType(
1163
                ProfitMandiConstants.TICKET_CATEGORY_SALES, EscalationType.L1);
1164
        List<Position> l2SalesPositions = positionRepository.selectPositionbyCategoryIdAndEscalationType(
1165
                ProfitMandiConstants.TICKET_CATEGORY_SALES, EscalationType.L2);
28908 tejbeer 1166
 
33074 amit.gupta 1167
        //LOGGER.info("position" + l1SalesPositions);
31762 tejbeer 1168
        Map<Integer, List<Integer>> authUserPartnerListMap = this.getAuthUserIdPartnerIdMapping();
33074 amit.gupta 1169
        //LOGGER.info("map" + authUserPartnerListMap);
28908 tejbeer 1170
 
31762 tejbeer 1171
        Map<Integer, List<Integer>> l2l1ListMap = new HashMap<>();
29318 tejbeer 1172
 
31762 tejbeer 1173
        for (Position l2SalePosition : l2SalesPositions) {
1174
            int l2AuthUserId = l2SalePosition.getAuthUserId();
1175
            if (authUserPartnerListMap.containsKey(l2SalePosition.getAuthUserId())) {
1176
                List<Integer> mappedL1AuthUsers = new ArrayList<>();
1177
                l2l1ListMap.put(l2AuthUserId, mappedL1AuthUsers);
1178
                List<Integer> l2FofoIds = authUserPartnerListMap.get(l2AuthUserId);
1179
                for (Position l1SalePosition : l1SalesPositions) {
1180
                    int l1AuthUserId = l1SalePosition.getAuthUserId();
1181
                    if (authUserPartnerListMap.containsKey(l1AuthUserId)) {
1182
                        List<Integer> l1FofoIds = authUserPartnerListMap.get(l1SalePosition.getAuthUserId());
1183
                        if (l2FofoIds.containsAll(l1FofoIds)) {
1184
                            mappedL1AuthUsers.add(l1AuthUserId);
1185
                        }
1186
                    }
28856 manish 1187
 
31762 tejbeer 1188
                }
1189
            }
29296 manish 1190
 
31762 tejbeer 1191
        }
29296 manish 1192
 
31762 tejbeer 1193
        return l2l1ListMap;
1194
    }
29296 manish 1195
 
31762 tejbeer 1196
    @Override
1197
    public Map<Integer, List<AuthUser>> getAssignedAuthList(List<Ticket> tickets) {
1198
        if (tickets.size() == 0) {
1199
            return new HashMap<>();
1200
        }
1201
        List<TicketAssigned> ticketAssignedList = ticketAssignedRepository.selectByTicketIds(tickets.stream().map(x -> x.getId()).collect(Collectors.toList()));
1202
        List<Integer> authUserIds = ticketAssignedList.stream().map(x -> x.getAssineeId()).distinct().collect(Collectors.toList());
35394 amit 1203
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(authUserIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
31762 tejbeer 1204
        return ticketAssignedList.stream().collect(Collectors.groupingBy(x -> x.getTicketId(), Collectors.mapping(x -> authUserMap.get(x.getAssineeId()), Collectors.toList())));
1205
    }
28908 tejbeer 1206
 
31762 tejbeer 1207
    @Override
33244 ranu 1208
    public Map<EscalationType, AuthUser> getAuthUserAndEsclationByPartnerId(int fofoId) throws ProfitMandiBusinessException {
31762 tejbeer 1209
        Map<EscalationType, AuthUser> authuserEsclationTypeMap = new HashMap<>();
1210
        List<Integer> regionIds = partnerRegionRepository.selectByfofoId(fofoId).stream().map(x -> x.getRegionId()).collect(Collectors.toList());
28908 tejbeer 1211
 
35592 amit 1212
        regionIds.add(ALL_PARTNERS_REGION);// All partners Id;
31762 tejbeer 1213
        List<Integer> fofoIds = new ArrayList<>();
1214
        fofoIds.add(fofoId);
1215
        fofoIds.add(0);
28908 tejbeer 1216
 
32493 amit.gupta 1217
        List<Integer> partnerPositionIds = partnerPositionRepository.selectByRegionIdAndPartnerId(regionIds, fofoIds).stream().map(x -> x.getPositionId()).collect(Collectors.toList());
28908 tejbeer 1218
 
35592 amit 1219
        if (partnerPositionIds.isEmpty()) {
1220
            return authuserEsclationTypeMap;
1221
        }
30003 tejbeer 1222
 
35592 amit 1223
        // OPTIMIZED: Batch fetch all positions instead of N+1 queries
1224
        List<Position> salesPositions = positionRepository.selectByIds(partnerPositionIds).stream()
1225
                .filter(p -> p.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_SALES)
1226
                .collect(Collectors.toList());
30003 tejbeer 1227
 
35592 amit 1228
        if (salesPositions.isEmpty()) {
1229
            return authuserEsclationTypeMap;
1230
        }
30003 tejbeer 1231
 
35592 amit 1232
        // OPTIMIZED: Batch fetch all AuthUsers instead of N+1 queries
1233
        List<Integer> authUserIds = salesPositions.stream()
1234
                .map(Position::getAuthUserId)
1235
                .filter(id -> id != null && id > 0)
1236
                .distinct()
1237
                .collect(Collectors.toList());
1238
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(authUserIds).stream()
1239
                .collect(Collectors.toMap(AuthUser::getId, au -> au, (a, b) -> a));
1240
 
1241
        for (Position position : salesPositions) {
1242
            AuthUser authUser = authUserMap.get(position.getAuthUserId());
1243
            if (authUser != null) {
31762 tejbeer 1244
                authuserEsclationTypeMap.put(position.getEscalationType(), authUser);
1245
            }
1246
        }
30003 tejbeer 1247
 
31762 tejbeer 1248
        return authuserEsclationTypeMap;
1249
    }
30044 tejbeer 1250
 
31762 tejbeer 1251
    @Override
35394 amit 1252
    public Map<Integer, Map<EscalationType, AuthUser>> getAuthUserAndEsclationByPartnerIds(Set<Integer> fofoIds) throws ProfitMandiBusinessException {
1253
        Map<Integer, Map<EscalationType, AuthUser>> result = new HashMap<>();
1254
 
1255
        if (fofoIds == null || fofoIds.isEmpty()) {
1256
            return result;
1257
        }
1258
 
1259
        // Initialize result map
1260
        for (Integer fofoId : fofoIds) {
1261
            result.put(fofoId, new HashMap<>());
1262
        }
1263
 
1264
        // Batch fetch all partner regions
1265
        List<Integer> fofoIdListWithZero = new ArrayList<>(fofoIds);
1266
        fofoIdListWithZero.add(0);
1267
        List<PartnerRegion> allPartnerRegions = partnerRegionRepository.selectByfofoIds(fofoIdListWithZero);
1268
 
1269
        // Build fofoId -> regionIds map
1270
        Map<Integer, Set<Integer>> fofoRegionMap = new HashMap<>();
1271
        for (Integer fofoId : fofoIds) {
1272
            fofoRegionMap.put(fofoId, new HashSet<>());
1273
            fofoRegionMap.get(fofoId).add(ALL_PARTNERS_REGION);
1274
        }
1275
        for (PartnerRegion pr : allPartnerRegions) {
1276
            int prFofoId = pr.getFofoId();
1277
            if (prFofoId == 0) {
1278
                for (Integer fid : fofoIds) {
1279
                    fofoRegionMap.get(fid).add(pr.getRegionId());
1280
                }
1281
            } else if (fofoIds.contains(prFofoId)) {
1282
                fofoRegionMap.get(prFofoId).add(pr.getRegionId());
1283
            }
1284
        }
1285
 
1286
        // Collect all region IDs
1287
        Set<Integer> allRegionIds = fofoRegionMap.values().stream()
1288
                .flatMap(Set::stream).collect(Collectors.toSet());
1289
 
1290
        // Batch fetch all partner positions
1291
        List<PartnerPosition> allPartnerPositions = partnerPositionRepository.selectByRegionIdAndPartnerId(
1292
                new ArrayList<>(allRegionIds), fofoIdListWithZero);
1293
 
1294
        // Collect all position IDs
1295
        Set<Integer> allPositionIds = allPartnerPositions.stream()
1296
                .map(PartnerPosition::getPositionId).collect(Collectors.toSet());
1297
 
1298
        // Batch fetch all positions for SALES category
1299
        List<Position> salesPositions = positionRepository.selectPositionbyCategoryIdAndEscalationType(
1300
                ProfitMandiConstants.TICKET_CATEGORY_SALES, null);
1301
        Map<Integer, Position> positionMap = salesPositions.stream()
1302
                .filter(p -> allPositionIds.contains(p.getId()))
1303
                .collect(Collectors.toMap(Position::getId, p -> p, (a, b) -> a));
1304
 
1305
        // Collect all auth user IDs and batch fetch
1306
        Set<Integer> authUserIds = positionMap.values().stream()
1307
                .map(Position::getAuthUserId).collect(Collectors.toSet());
1308
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(new ArrayList<>(authUserIds))
1309
                .stream().collect(Collectors.toMap(AuthUser::getId, au -> au, (a, b) -> a));
1310
 
1311
        // For each fofoId, find matching positions and build result
1312
        for (Integer fofoId : fofoIds) {
1313
            Set<Integer> regionIds = fofoRegionMap.get(fofoId);
1314
            Map<EscalationType, AuthUser> escalationMap = result.get(fofoId);
1315
 
1316
            for (PartnerPosition pp : allPartnerPositions) {
1317
                if (regionIds.contains(pp.getRegionId()) &&
1318
                    (pp.getFofoId() == 0 || pp.getFofoId() == fofoId)) {
1319
                    Position position = positionMap.get(pp.getPositionId());
1320
                    if (position != null) {
1321
                        AuthUser authUser = authUserMap.get(position.getAuthUserId());
1322
                        if (authUser != null) {
1323
                            escalationMap.put(position.getEscalationType(), authUser);
1324
                        }
1325
                    }
1326
                }
1327
            }
1328
        }
1329
 
1330
        return result;
1331
    }
1332
 
1333
    @Override
33244 ranu 1334
    public List<AuthUser> getAuthUserIdByPartnerId(int fofoId) throws ProfitMandiBusinessException {
33041 ranu 1335
        return this.getAuthUserIdByPartnerId(fofoId, EscalationType.escalations.toArray(new EscalationType[0]));
1336
    }
1337
 
1338
    @Override
33244 ranu 1339
    public List<AuthUser> getAuthUserIdByPartnerId(int fofoId, EscalationType... escalationTypes) throws ProfitMandiBusinessException {
31762 tejbeer 1340
        List<AuthUser> authUsers = new ArrayList<>();
1341
        List<Integer> regionIds = partnerRegionRepository.selectByfofoId(fofoId).stream().map(x -> x.getRegionId()).collect(Collectors.toList());
30044 tejbeer 1342
 
31762 tejbeer 1343
        regionIds.add(5);// All partners Id;
1344
        List<Integer> fofoIds = new ArrayList<>();
1345
        fofoIds.add(fofoId);
1346
        fofoIds.add(0);
30044 tejbeer 1347
 
33074 amit.gupta 1348
        //LOGGER.info("fofoIds" + fofoIds);
32493 amit.gupta 1349
        List<Integer> partnerPositionIds = partnerPositionRepository.selectByRegionIdAndPartnerId(regionIds, fofoIds).stream().map(x -> x.getPositionId()).collect(Collectors.toList());
30003 tejbeer 1350
 
33074 amit.gupta 1351
        //LOGGER.info("partnerPositionIds" + partnerPositionIds);
34905 ranu 1352
        List<Integer> allowedTicketCategoryIds = Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_SALES, ProfitMandiConstants.TICKET_CATEGORY_RBM,ProfitMandiConstants.TICKET_CATEGORY_ABM);
30003 tejbeer 1353
 
30044 tejbeer 1354
 
35394 amit 1355
        List<Position> escalationBasedPositions = positionRepository.selectByIds(partnerPositionIds).stream().filter(x -> allowedTicketCategoryIds.contains(x.getCategoryId()) &&
33041 ranu 1356
                Arrays.stream(escalationTypes)
1357
                        .anyMatch(y -> y.equals(x.getEscalationType()))).collect(Collectors.toList());
30003 tejbeer 1358
 
33041 ranu 1359
        List<Integer> authUserIds = escalationBasedPositions.stream().map(x -> x.getAuthUserId()).collect(Collectors.toList());
30003 tejbeer 1360
 
35394 amit 1361
        return authRepository.selectByIds(authUserIds);
30003 tejbeer 1362
 
31762 tejbeer 1363
    }
30044 tejbeer 1364
 
31762 tejbeer 1365
    @Override
1366
    public List<AuthUser> getAuthUserIds(int categoryId, List<EscalationType> escalationType) {
30044 tejbeer 1367
 
31762 tejbeer 1368
        List<Position> positions = positionRepository.selectPositionbyCategoryIdAndEscalationTypes(categoryId, escalationType);
1369
        List<Integer> authIds = positions.stream().map(x -> x.getAuthUserId()).distinct().collect(Collectors.toList());
30003 tejbeer 1370
 
33074 amit.gupta 1371
        //LOGGER.info("authIds" + authIds);
35058 amit 1372
        List<AuthUser> authUsers = null;
1373
        if (authIds.size() > 0) {
35394 amit 1374
            authUsers = authRepository.selectByIds(authIds);
35058 amit 1375
        } else {
1376
            authUsers = new ArrayList<>();
1377
        }
30003 tejbeer 1378
 
31762 tejbeer 1379
        LOGGER.info("authUsers" + authUsers);
1380
        return authUsers;
1381
    }
1382
 
1383
    @Override
1384
    public List<AuthUser> getAuthUserByCategoryId(int categoryId, EscalationType escalationType) {
1385
 
1386
        List<Position> positions = positionRepository.selectPositionbyCategoryIdAndEscalationType(categoryId, escalationType);
1387
        List<Integer> authIds = positions.stream().map(x -> x.getAuthUserId()).distinct().collect(Collectors.toList());
1388
 
1389
        LOGGER.info("authIds" + authIds);
1390
        List<AuthUser> authUsers = new ArrayList<>();
1391
        if (!authIds.isEmpty()) {
35394 amit 1392
            authUsers = authRepository.selectByIds(authIds);
31762 tejbeer 1393
        }
1394
 
1395
        LOGGER.info("authUsers" + authUsers);
1396
        return authUsers;
1397
    }
1398
 
1399
    @Override
1400
    @Cacheable(value = "authUserByCategoryId", cacheManager = "thirtyMinsTimeOutCacheManager")
1401
    public List<AuthUser> getAuthUserByCategoryId(int categoryId) {
1402
        List<Position> positions = positionRepository.selectPositionByCategoryId(categoryId);
1403
        List<Integer> authIds = positions.stream().map(x -> x.getAuthUserId()).distinct().collect(Collectors.toList());
1404
 
1405
        LOGGER.info("authIds" + authIds);
1406
 
35394 amit 1407
        List<AuthUser> authUsers = authRepository.selectByIds(authIds).stream().filter(x -> x.getActive()).collect(Collectors.toList());
31762 tejbeer 1408
 
1409
        LOGGER.info("authUsers" + authUsers);
1410
        return authUsers;
1411
    }
1412
 
34380 amit.gupta 1413
    private class SaleRoles1 {
31762 tejbeer 1414
 
1415
        private List<String> l1;
1416
        private List<String> l2;
1417
        private List<String> l3;
1418
        private List<String> l4;
1419
 
34380 amit.gupta 1420
        public SaleRoles1() {
31762 tejbeer 1421
            l1 = new ArrayList<>();
1422
            l2 = new ArrayList<>();
1423
            l3 = new ArrayList<>();
1424
            l4 = new ArrayList<>();
1425
        }
1426
 
1427
        public List<String> getL1() {
1428
            return l1;
1429
        }
1430
 
1431
        public List<String> getL2() {
1432
            return l2;
1433
        }
1434
 
1435
        public List<String> getL3() {
1436
            return l3;
1437
        }
1438
 
1439
        public List<String> getL4() {
1440
            return l4;
1441
        }
1442
 
1443
        @Override
1444
        public String toString() {
1445
            return "SaleRoles [l1=" + l1 + ", l2=" + l2 + ", l3=" + l3 + ", l4=" + l4 + "]";
1446
        }
1447
 
1448
    }
1449
 
33161 ranu 1450
 
31762 tejbeer 1451
    @Override
1452
    @Cacheable(value = "partnerSaleHeader", cacheManager = "oneDayCacheManager")
33244 ranu 1453
    public Map<Integer, FofoReportingModel> getPartnerIdSalesHeaders() throws ProfitMandiBusinessException {
34380 amit.gupta 1454
        Map<String, SaleRoles1> partnerEmailSalesMap = new HashMap<>();
31762 tejbeer 1455
 
1456
        List<Position> positions = positionRepository.selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_SALES);
1457
        Map<Integer, AuthUser> authUsersMap = authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
1458
        Map<Integer, List<CustomRetailer>> positionIdRetailerMap = this.getPositionCustomRetailerMap(positions);
1459
        for (Position position : positions) {
1460
            List<CustomRetailer> crList = positionIdRetailerMap.get(position.getId());
1461
            if (crList == null)
1462
                continue;
1463
            for (CustomRetailer cr : crList) {
1464
                if (!partnerEmailSalesMap.containsKey(cr.getEmail())) {
34380 amit.gupta 1465
                    partnerEmailSalesMap.put(cr.getEmail(), new SaleRoles1());
31762 tejbeer 1466
                }
34380 amit.gupta 1467
                SaleRoles1 saleRoles1 = partnerEmailSalesMap.get(cr.getEmail());
31762 tejbeer 1468
                AuthUser authUser = authUsersMap.get(position.getAuthUserId());
1469
                if (authUser == null) {
1470
                    continue;
1471
                }
1472
                String name = authUser.getFirstName() + " " + authUser.getLastName();
1473
                if (position.getEscalationType().equals(EscalationType.L1)) {
34380 amit.gupta 1474
                    saleRoles1.getL1().add(name);
31762 tejbeer 1475
                } else if (position.getEscalationType().equals(EscalationType.L2)) {
34380 amit.gupta 1476
                    saleRoles1.getL2().add(name);
31762 tejbeer 1477
                }
1478
 
1479
            }
1480
        }
1481
 
1482
        Set<CustomRetailer> allCrList = new HashSet<>();
1483
        for (List<CustomRetailer> cr : positionIdRetailerMap.values()) {
1484
            allCrList.addAll(cr);
1485
        }
1486
 
1487
        Map<Integer, FofoStore> fofoStoresMap = fofoStoreRepository.selectActiveStores().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
1488
 
1489
        Map<Integer, FofoReportingModel> partnerIdSalesHeadersMap = new HashMap<>();
1490
 
33378 ranu 1491
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
1492
        for (Map.Entry<Integer, CustomRetailer> customRetailerEntry : customRetailerMap.entrySet()) {
1493
 
1494
            CustomRetailer customRetailer = customRetailerEntry.getValue();
1495
 
1496
            String code = customRetailer.getCode();
31762 tejbeer 1497
            // String storeName = "SmartDukaan-" +
1498
            // fofoStore.getCode().replaceAll("[a-zA-Z]", "");
33378 ranu 1499
            String businessName = customRetailer.getBusinessName();
31762 tejbeer 1500
            try {
34158 tejus.loha 1501
                String stateManager = StringUtils.join(new HashSet(partnerEmailSalesMap.get(customRetailer.getEmail()).getL2()), ", ");
1502
                String territoryManager = StringUtils.join(new HashSet(partnerEmailSalesMap.get(customRetailer.getEmail()).getL1()), ", ");
31762 tejbeer 1503
 
1504
                FofoReportingModel reportingModel = new FofoReportingModel();
1505
                reportingModel.setBusinessName(businessName);
1506
                reportingModel.setCode(code);
33378 ranu 1507
                reportingModel.setFofoId(customRetailer.getPartnerId());
31762 tejbeer 1508
                reportingModel.setRegionalManager(stateManager);
1509
                reportingModel.setTerritoryManager(territoryManager);
33378 ranu 1510
                partnerIdSalesHeadersMap.put(customRetailer.getPartnerId(), reportingModel);
31762 tejbeer 1511
            } catch (Exception e) {
33378 ranu 1512
                LOGGER.warn("Could not find partner with email - {}", customRetailer.getEmail());
31762 tejbeer 1513
            }
1514
        }
1515
        return partnerIdSalesHeadersMap;
1516
 
1517
    }
1518
 
33161 ranu 1519
 
34905 ranu 1520
    private class ABMRoles {
1521
 
1522
        private List<String> l1;
1523
        private List<String> l2;
1524
        private List<String> l3;
1525
        private List<String> l4;
1526
 
1527
        public ABMRoles() {
1528
            l1 = new ArrayList<>();
1529
            l2 = new ArrayList<>();
1530
            l3 = new ArrayList<>();
1531
            l4 = new ArrayList<>();
1532
        }
1533
 
1534
        public List<String> getL1() {
1535
            return l1;
1536
        }
1537
 
1538
        public List<String> getL2() {
1539
            return l2;
1540
        }
1541
 
1542
        public List<String> getL3() {
1543
            return l3;
1544
        }
1545
 
1546
        public List<String> getL4() {
1547
            return l4;
1548
        }
1549
 
1550
        @Override
1551
        public String toString() {
1552
            return "SaleRoles [l1=" + l1 + ", l2=" + l2 + ", l3=" + l3 + ", l4=" + l4 + "]";
1553
        }
1554
 
1555
    }
1556
 
1557
 
1558
    @Override
1559
    @Cacheable(value = "partnerABMHeader", cacheManager = "oneDayCacheManager")
1560
    public Map<Integer, FofoAbmReportingModel> getPartnerIdABMHeaders() throws ProfitMandiBusinessException {
1561
        Map<String, ABMRoles> partnerEmailABMMap = new HashMap<>();
1562
 
1563
        List<Position> positions = positionRepository.selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_ABM);
1564
        Map<Integer, AuthUser> authUsersMap = authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
1565
        Map<Integer, List<CustomRetailer>> positionIdRetailerMap = this.getPositionCustomRetailerMap(positions);
1566
        for (Position position : positions) {
1567
            List<CustomRetailer> crList = positionIdRetailerMap.get(position.getId());
1568
            if (crList == null)
1569
                continue;
1570
            for (CustomRetailer cr : crList) {
1571
                if (!partnerEmailABMMap.containsKey(cr.getEmail())) {
1572
                    partnerEmailABMMap.put(cr.getEmail(), new ABMRoles());
1573
                }
1574
                ABMRoles abmRoles = partnerEmailABMMap.get(cr.getEmail());
1575
                AuthUser authUser = authUsersMap.get(position.getAuthUserId());
1576
                if (authUser == null) {
1577
                    continue;
1578
                }
1579
                String name = authUser.getFirstName() + " " + authUser.getLastName();
1580
                if (position.getEscalationType().equals(EscalationType.L1)) {
1581
                    abmRoles.getL1().add(name);
1582
                } else if (position.getEscalationType().equals(EscalationType.L2)) {
1583
                    abmRoles.getL2().add(name);
1584
                }
1585
 
1586
            }
1587
        }
1588
 
1589
        Set<CustomRetailer> allCrList = new HashSet<>();
1590
        for (List<CustomRetailer> cr : positionIdRetailerMap.values()) {
1591
            allCrList.addAll(cr);
1592
        }
1593
 
1594
        Map<Integer, FofoStore> fofoStoresMap = fofoStoreRepository.selectActiveStores().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
1595
 
1596
        Map<Integer, FofoAbmReportingModel> partnerIdAbmHeadersMap = new HashMap<>();
1597
 
1598
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
1599
        for (Map.Entry<Integer, CustomRetailer> customRetailerEntry : customRetailerMap.entrySet()) {
1600
 
1601
            CustomRetailer customRetailer = customRetailerEntry.getValue();
1602
 
1603
            String code = customRetailer.getCode();
1604
            // String storeName = "SmartDukaan-" +
1605
            // fofoStore.getCode().replaceAll("[a-zA-Z]", "");
1606
            String businessName = customRetailer.getBusinessName();
1607
            try {
1608
                String l2Manager = StringUtils.join(new HashSet(partnerEmailABMMap.get(customRetailer.getEmail()).getL2()), ", ");
1609
                String l1Manager = StringUtils.join(new HashSet(partnerEmailABMMap.get(customRetailer.getEmail()).getL1()), ", ");
1610
 
1611
                if (StringUtils.isEmpty(l1Manager)) {
1612
                    l2Manager = StringUtils.join(new HashSet(partnerEmailABMMap.get(customRetailer.getEmail()).getL2()), ", ");
1613
                }
1614
 
1615
                FofoAbmReportingModel reportingModel = new FofoAbmReportingModel();
1616
                reportingModel.setBusinessName(businessName);
1617
                reportingModel.setCode(code);
1618
                reportingModel.setFofoId(customRetailer.getPartnerId());
1619
                reportingModel.setL1Manager(l2Manager);
1620
                reportingModel.setL2Manager(l1Manager);
1621
                partnerIdAbmHeadersMap.put(customRetailer.getPartnerId(), reportingModel);
1622
            } catch (Exception e) {
1623
                LOGGER.warn("Could not find partner with email - {}", customRetailer.getEmail());
1624
            }
1625
        }
1626
        return partnerIdAbmHeadersMap;
1627
 
1628
    }
1629
 
1630
 
33161 ranu 1631
    private class RBMRoles {
1632
 
1633
        private List<String> l1;
1634
        private List<String> l2;
1635
        private List<String> l3;
1636
        private List<String> l4;
1637
 
1638
        public RBMRoles() {
1639
            l1 = new ArrayList<>();
1640
            l2 = new ArrayList<>();
1641
            l3 = new ArrayList<>();
1642
            l4 = new ArrayList<>();
1643
        }
1644
 
1645
        public List<String> getL1() {
1646
            return l1;
1647
        }
1648
 
1649
        public List<String> getL2() {
1650
            return l2;
1651
        }
1652
 
1653
        public List<String> getL3() {
1654
            return l3;
1655
        }
1656
 
1657
        public List<String> getL4() {
1658
            return l4;
1659
        }
1660
 
1661
        @Override
1662
        public String toString() {
1663
            return "RBMRoles [l1=" + l1 + ", l2=" + l2 + ", l3=" + l3 + ", l4=" + l4 + "]";
1664
        }
1665
 
1666
    }
1667
 
31762 tejbeer 1668
    @Override
33161 ranu 1669
    @Cacheable(value = "partnerRBMHeader", cacheManager = "oneDayCacheManager")
33244 ranu 1670
    public Map<Integer, FofoRBMReportingModel> getPartnerIdRBMHeaders() throws ProfitMandiBusinessException {
33161 ranu 1671
        Map<String, RBMRoles> partnerEmailRbmMap = new HashMap<>();
1672
 
1673
        List<Position> positions = positionRepository.selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_RBM);
1674
        Map<Integer, AuthUser> authUsersMap = authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
1675
        Map<Integer, List<CustomRetailer>> positionIdRetailerMap = this.getPositionCustomRetailerMap(positions);
1676
        for (Position position : positions) {
1677
            List<CustomRetailer> crList = positionIdRetailerMap.get(position.getId());
1678
            if (crList == null)
1679
                continue;
1680
            for (CustomRetailer cr : crList) {
1681
                if (!partnerEmailRbmMap.containsKey(cr.getEmail())) {
1682
                    partnerEmailRbmMap.put(cr.getEmail(), new RBMRoles());
1683
                }
1684
                RBMRoles rbmRole = partnerEmailRbmMap.get(cr.getEmail());
1685
                AuthUser authUser = authUsersMap.get(position.getAuthUserId());
1686
                if (authUser == null) {
1687
                    continue;
1688
                }
1689
                String name = authUser.getFirstName() + " " + authUser.getLastName();
1690
                if (position.getEscalationType().equals(EscalationType.L1)) {
1691
                    rbmRole.getL1().add(name);
1692
                } else if (position.getEscalationType().equals(EscalationType.L2)) {
1693
                    rbmRole.getL2().add(name);
1694
                }
1695
 
1696
            }
1697
        }
1698
 
1699
        Set<CustomRetailer> allCrList = new HashSet<>();
1700
        for (List<CustomRetailer> cr : positionIdRetailerMap.values()) {
1701
            allCrList.addAll(cr);
1702
        }
1703
 
1704
 
1705
        Map<Integer, FofoRBMReportingModel> partnerIdRbmHeadersMap = new HashMap<>();
1706
 
33377 amit.gupta 1707
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
1708
        for (Map.Entry<Integer, CustomRetailer> customRetailerEntry : customRetailerMap.entrySet()) {
1709
 
1710
            CustomRetailer customRetailer = customRetailerEntry.getValue();
1711
 
1712
            String code = customRetailer.getCode();
33161 ranu 1713
            // String storeName = "SmartDukaan-" +
1714
            // fofoStore.getCode().replaceAll("[a-zA-Z]", "");
33377 amit.gupta 1715
            String businessName = customRetailer.getBusinessName();
33161 ranu 1716
            try {
33377 amit.gupta 1717
                String L2User = StringUtils.join(partnerEmailRbmMap.get(customRetailer.getEmail()).getL2(), ", ");
1718
                String L1USer = StringUtils.join(partnerEmailRbmMap.get(customRetailer.getEmail()).getL1(), ", ");
33161 ranu 1719
 
1720
                FofoRBMReportingModel reportingModel = new FofoRBMReportingModel();
1721
                reportingModel.setBusinessName(businessName);
1722
                reportingModel.setCode(code);
33377 amit.gupta 1723
                reportingModel.setFofoId(customRetailer.getPartnerId());
35180 amit 1724
                reportingModel.setL1Manager(L1USer);
1725
                reportingModel.setL2Manager(L2User);
33377 amit.gupta 1726
                partnerIdRbmHeadersMap.put(customRetailer.getPartnerId(), reportingModel);
33161 ranu 1727
            } catch (Exception e) {
33377 amit.gupta 1728
                LOGGER.warn("Could not find partner with email - {}", customRetailer.getEmail());
33161 ranu 1729
            }
1730
        }
1731
        return partnerIdRbmHeadersMap;
1732
 
1733
    }
1734
 
1735
    @Override
31762 tejbeer 1736
    public Map<Integer, TicketCategory> getSubCategoryIdAndCategoryMap(List<Integer> subCategoryIds) {
1737
        Map<Integer, TicketCategory> subCategoryIdAndCategoryMap = new HashMap<>();
35592 amit 1738
        if (subCategoryIds == null || subCategoryIds.isEmpty()) {
1739
            return subCategoryIdAndCategoryMap;
1740
        }
31762 tejbeer 1741
 
1742
        List<TicketSubCategory> ticketSubCategories = ticketSubCategoryRepository.selectByIds(subCategoryIds);
1743
 
35592 amit 1744
        // OPTIMIZED: Batch fetch all categories instead of N+1 queries
1745
        List<Integer> categoryIds = ticketSubCategories.stream()
1746
                .map(TicketSubCategory::getCategoryId)
1747
                .distinct()
1748
                .collect(Collectors.toList());
1749
        Map<Integer, TicketCategory> categoryMap = ticketCategoryRepository.selectAll(categoryIds).stream()
1750
                .collect(Collectors.toMap(TicketCategory::getId, tc -> tc, (a, b) -> a));
1751
 
31762 tejbeer 1752
        for (TicketSubCategory ticketSubCategory : ticketSubCategories) {
35592 amit 1753
            subCategoryIdAndCategoryMap.put(ticketSubCategory.getId(), categoryMap.get(ticketSubCategory.getCategoryId()));
31762 tejbeer 1754
        }
1755
        return subCategoryIdAndCategoryMap;
1756
    }
1757
 
35394 amit 1758
    @Override
1759
    public Map<Integer, Map<String, Integer>> getBmAsmRbmAuthUserIdsByFofoIds(Set<Integer> fofoIds) throws ProfitMandiBusinessException {
1760
        Map<Integer, Map<String, Integer>> result = new HashMap<>();
1761
 
1762
        if (fofoIds == null || fofoIds.isEmpty()) {
1763
            return result;
1764
        }
1765
 
1766
        // Initialize result map with empty values for each fofoId
1767
        for (Integer fofoId : fofoIds) {
1768
            Map<String, Integer> roleMap = new HashMap<>();
1769
            roleMap.put("BM", 0);
1770
            roleMap.put("ASM", 0);
1771
            roleMap.put("RBM", 0);
1772
            result.put(fofoId, roleMap);
1773
        }
1774
 
1775
        // Fetch positions by category + escalation type (same for all fofoIds)
1776
        List<Position> bmPositions = positionRepository.selectPositionbyCategoryIdAndEscalationType(
1777
                ProfitMandiConstants.TICKET_CATEGORY_SALES, EscalationType.L2);
1778
        List<Position> asmPositions = positionRepository.selectPositionbyCategoryIdAndEscalationType(
1779
                ProfitMandiConstants.TICKET_CATEGORY_SALES, EscalationType.L1);
1780
        List<Position> rbmPositions = positionRepository.selectPositionbyCategoryIdAndEscalationType(
1781
                ProfitMandiConstants.TICKET_CATEGORY_RBM, EscalationType.L1);
1782
 
1783
        // Batch fetch all partner regions for all fofoIds
1784
        List<Integer> fofoIdList = new ArrayList<>(fofoIds);
1785
        fofoIdList.add(0); // Include global entries
1786
        List<PartnerRegion> allPartnerRegions = partnerRegionRepository.selectByfofoIds(fofoIdList);
1787
 
1788
        // Build fofoId -> regionIds map
1789
        Map<Integer, Set<Integer>> fofoRegionMap = new HashMap<>();
1790
        for (Integer fofoId : fofoIds) {
1791
            fofoRegionMap.put(fofoId, new HashSet<>());
1792
            fofoRegionMap.get(fofoId).add(ALL_PARTNERS_REGION); // Add all partners region
1793
        }
1794
        for (PartnerRegion pr : allPartnerRegions) {
1795
            int fofoId = pr.getFofoId();
1796
            if (fofoId == 0) {
1797
                // Global entry applies to all fofoIds
1798
                for (Integer fid : fofoIds) {
1799
                    fofoRegionMap.get(fid).add(pr.getRegionId());
1800
                }
1801
            } else if (fofoIds.contains(fofoId)) {
1802
                fofoRegionMap.get(fofoId).add(pr.getRegionId());
1803
            }
1804
        }
1805
 
1806
        // Collect all unique region IDs and position IDs for batch query
1807
        Set<Integer> allRegionIds = fofoRegionMap.values().stream()
1808
                .flatMap(Set::stream).collect(Collectors.toSet());
1809
        Set<Integer> allPositionIds = new HashSet<>();
1810
        bmPositions.forEach(p -> allPositionIds.add(p.getId()));
1811
        asmPositions.forEach(p -> allPositionIds.add(p.getId()));
1812
        rbmPositions.forEach(p -> allPositionIds.add(p.getId()));
1813
 
1814
        // Batch fetch all partner positions
1815
        List<PartnerPosition> allPartnerPositions = partnerPositionRepository.selectByRegionIdAndPostionId(
1816
                new ArrayList<>(allRegionIds), new ArrayList<>(allPositionIds));
1817
 
1818
        // Build positionId -> set of (regionId, partnerId) for matching
1819
        Map<Integer, List<PartnerPosition>> positionIdToPartnerPositions = allPartnerPositions.stream()
1820
                .collect(Collectors.groupingBy(PartnerPosition::getPositionId));
1821
 
1822
        // Collect all auth user IDs we need
1823
        Set<Integer> allAuthUserIds = new HashSet<>();
1824
        bmPositions.forEach(p -> allAuthUserIds.add(p.getAuthUserId()));
1825
        asmPositions.forEach(p -> allAuthUserIds.add(p.getAuthUserId()));
1826
        rbmPositions.forEach(p -> allAuthUserIds.add(p.getAuthUserId()));
1827
 
1828
        // Batch fetch all auth users
1829
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(new ArrayList<>(allAuthUserIds))
1830
                .stream().filter(AuthUser::isActive)
1831
                .collect(Collectors.toMap(AuthUser::getId, au -> au, (a, b) -> a));
1832
 
1833
        // Build position ID sets for fast lookup
1834
        Set<Integer> bmPositionIds = bmPositions.stream().map(Position::getId).collect(Collectors.toSet());
1835
        Set<Integer> asmPositionIds = asmPositions.stream().map(Position::getId).collect(Collectors.toSet());
1836
        Set<Integer> rbmPositionIds = rbmPositions.stream().map(Position::getId).collect(Collectors.toSet());
1837
 
1838
        // Map position ID to auth user ID
1839
        Map<Integer, Integer> positionToAuthUser = new HashMap<>();
1840
        bmPositions.forEach(p -> positionToAuthUser.put(p.getId(), p.getAuthUserId()));
1841
        asmPositions.forEach(p -> positionToAuthUser.put(p.getId(), p.getAuthUserId()));
1842
        rbmPositions.forEach(p -> positionToAuthUser.put(p.getId(), p.getAuthUserId()));
1843
 
1844
        // For each fofoId, find matching positions
1845
        for (Integer fofoId : fofoIds) {
1846
            Set<Integer> regionIds = fofoRegionMap.get(fofoId);
1847
 
1848
            // Find position IDs that match this fofoId's regions (partnerId = 0 or fofoId)
1849
            Set<Integer> matchingPositionIds = new HashSet<>();
1850
            for (PartnerPosition pp : allPartnerPositions) {
1851
                if (regionIds.contains(pp.getRegionId()) &&
1852
                    (pp.getFofoId() == 0 || pp.getFofoId() == fofoId)) {
1853
                    matchingPositionIds.add(pp.getPositionId());
1854
                }
1855
            }
1856
 
1857
            // Find first active auth user for each role
1858
            Map<String, Integer> roleMap = result.get(fofoId);
1859
 
1860
            for (Integer positionId : matchingPositionIds) {
1861
                Integer authUserId = positionToAuthUser.get(positionId);
1862
                if (authUserId != null && authUserMap.containsKey(authUserId)) {
1863
                    if (bmPositionIds.contains(positionId) && roleMap.get("BM") == 0) {
1864
                        roleMap.put("BM", authUserId);
1865
                    } else if (asmPositionIds.contains(positionId) && roleMap.get("ASM") == 0) {
1866
                        roleMap.put("ASM", authUserId);
1867
                    } else if (rbmPositionIds.contains(positionId) && roleMap.get("RBM") == 0) {
1868
                        roleMap.put("RBM", authUserId);
1869
                    }
1870
                }
1871
            }
1872
        }
1873
 
1874
        return result;
1875
    }
1876
 
35626 amit 1877
    @Override
35635 ranu 1878
    public Map<Integer, Boolean> getUnreadStatusForTickets(List<Ticket> tickets, int userId, TicketReadStatus.UserType userType) {
35626 amit 1879
        Map<Integer, Boolean> unreadMap = new HashMap<>();
1880
        if (tickets == null || tickets.isEmpty()) {
1881
            return unreadMap;
1882
        }
1883
 
1884
        List<Integer> ticketIds = tickets.stream().map(Ticket::getId).collect(Collectors.toList());
1885
        List<TicketReadStatus> readStatuses = ticketReadStatusRepository.selectByTicketIdsAndUser(ticketIds, userId, userType);
1886
        Map<Integer, Integer> ticketLastReadMap = readStatuses.stream()
1887
                .collect(Collectors.toMap(TicketReadStatus::getTicketId, TicketReadStatus::getLastReadActivityId));
1888
 
1889
        // Get last activities for all tickets to check who created them
1890
        Map<Integer, Activity> lastActivityMap = getLastActivitiesForTickets(ticketIds);
1891
 
1892
        for (Ticket ticket : tickets) {
1893
            int lastActivityId = ticket.getLastActivityId();
1894
            int lastReadActivityId = ticketLastReadMap.getOrDefault(ticket.getId(), 0);
1895
 
1896
            if (lastActivityId <= lastReadActivityId) {
1897
                unreadMap.put(ticket.getId(), false);
1898
                continue;
1899
            }
1900
 
1901
            // Check if the current user created the last activity (exclude own updates)
1902
            Activity lastActivity = lastActivityMap.get(ticket.getId());
1903
            if (lastActivity != null) {
35635 ranu 1904
                if (userType == TicketReadStatus.UserType.AUTH_USER && lastActivity.getCreatedBy() == userId) {
35626 amit 1905
                    unreadMap.put(ticket.getId(), false);
1906
                    continue;
1907
                }
35635 ranu 1908
                if (userType == TicketReadStatus.UserType.PARTNER && lastActivity.getCreatedBy() == 0
35626 amit 1909
                        && lastActivity.getType() == ActivityType.COMMUNICATION_IN) {
1910
                    unreadMap.put(ticket.getId(), false);
1911
                    continue;
1912
                }
1913
                // For partners: only show as unread if activity type is external communication or resolved
35635 ranu 1914
                if (userType == TicketReadStatus.UserType.PARTNER) {
35626 amit 1915
                    boolean isRelevantForPartner = ActivityType.PARTNER_ACTIVITIES.contains(lastActivity.getType());
1916
                    unreadMap.put(ticket.getId(), isRelevantForPartner);
1917
                    continue;
1918
                }
1919
            }
1920
 
1921
            unreadMap.put(ticket.getId(), true);
1922
        }
1923
        return unreadMap;
1924
    }
1925
 
1926
    @Override
35635 ranu 1927
    public void markTicketAsRead(int ticketId, int userId, TicketReadStatus.UserType userType) {
35626 amit 1928
        Ticket ticket = ticketRepository.selectById(ticketId);
1929
        if (ticket == null) {
1930
            return;
1931
        }
1932
        TicketReadStatus readStatus = new TicketReadStatus();
1933
        readStatus.setTicketId(ticketId);
1934
        readStatus.setUserId(userId);
1935
        readStatus.setUserType(userType);
1936
        readStatus.setLastReadActivityId(ticket.getLastActivityId());
1937
        ticketReadStatusRepository.upsert(readStatus);
1938
    }
1939
 
1940
    @Override
1941
    public Map<Integer, Activity> getLastActivitiesForTickets(List<Integer> ticketIds) {
1942
        Map<Integer, Activity> lastActivityMap = new HashMap<>();
1943
        if (ticketIds == null || ticketIds.isEmpty()) {
1944
            return lastActivityMap;
1945
        }
1946
        List<Activity> allActivities = activityRepository.selectAll(ticketIds);
1947
        // Group by ticketId and get the last one (highest id)
1948
        Map<Integer, List<Activity>> groupedByTicket = allActivities.stream()
1949
                .collect(Collectors.groupingBy(Activity::getTicketId));
1950
        for (Map.Entry<Integer, List<Activity>> entry : groupedByTicket.entrySet()) {
1951
            Activity lastActivity = entry.getValue().stream()
1952
                    .max(Comparator.comparingInt(Activity::getId))
1953
                    .orElse(null);
1954
            if (lastActivity != null) {
1955
                lastActivityMap.put(entry.getKey(), lastActivity);
1956
            }
1957
        }
1958
        return lastActivityMap;
1959
    }
1960
 
1961
    @Override
35639 amit 1962
    public Map<Integer, Activity> getLastMessageActivitiesForTickets(List<Integer> ticketIds) {
1963
        Map<Integer, Activity> lastMessageMap = new HashMap<>();
1964
        if (ticketIds == null || ticketIds.isEmpty()) {
1965
            return lastMessageMap;
1966
        }
1967
        Set<ActivityType> messageTypes = EnumSet.of(
1968
                ActivityType.COMMUNICATION_IN, ActivityType.COMMUNICATION_OUT,
1969
                ActivityType.COMMUNICATION_INTERNAL, ActivityType.OPENED);
1970
        List<Activity> allActivities = activityRepository.selectAll(ticketIds);
1971
        Map<Integer, List<Activity>> groupedByTicket = allActivities.stream()
1972
                .filter(a -> messageTypes.contains(a.getType()))
1973
                .collect(Collectors.groupingBy(Activity::getTicketId));
1974
        for (Map.Entry<Integer, List<Activity>> entry : groupedByTicket.entrySet()) {
1975
            Activity lastMessage = entry.getValue().stream()
1976
                    .max(Comparator.comparingInt(Activity::getId))
1977
                    .orElse(null);
1978
            if (lastMessage != null) {
1979
                lastMessageMap.put(entry.getKey(), lastMessage);
1980
            }
1981
        }
1982
        return lastMessageMap;
1983
    }
1984
 
1985
    @Override
35626 amit 1986
    public void notifyPartnerOfExternalCommunication(Ticket ticket, Activity activity) {
1987
        try {
1988
            CustomRetailer partner = retailerService.getFofoRetailer(ticket.getFofoId());
1989
            if (partner == null || partner.getEmail() == null) {
1990
                return;
1991
            }
1992
 
1993
            TicketSubCategory ticketSubCategory = ticketSubCategoryRepository.selectById(ticket.getSubCategoryId());
1994
            TicketCategory ticketCategory = ticketCategoryRepository.selectById(ticketSubCategory.getCategoryId());
1995
 
1996
            Map<String, Object> model = new HashMap<>();
1997
            model.put("ticketId", ticket.getId());
1998
            model.put("partnerName", partner.getBusinessName());
1999
            model.put("categoryName", ticketCategory.getName());
2000
            model.put("subCategoryName", ticketSubCategory.getName());
2001
            model.put("activityMessage", activity.getMessage());
2002
 
2003
            emailService.sendMailWithAttachments(
2004
                    "Update on Your Support Ticket #" + ticket.getId(),
2005
                    "partner-ticket-update.vm",
2006
                    model,
2007
                    new String[]{partner.getEmail()},
2008
                    null,
2009
                    null);
2010
        } catch (Exception e) {
2011
            LOGGER.error("Failed to send partner notification email for ticket {}", ticket.getId(), e);
2012
        }
2013
    }
2014
 
24383 amit.gupta 2015
}