Subversion Repositories SmartDukaan

Rev

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
36399 amit 51
    JavaMailSender gmailRelaySender;
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 {
36802 ranu 1123
        return buildAuthUserIdPartnerIdMapping(true);
1124
    }
1125
 
1126
    @Override
1127
    @Cacheable(value = "authUserIdAllPartnerIdMapping", cacheManager = "thirtyMinsTimeOutCacheManager")
1128
    public Map<Integer, List<Integer>> getAuthUserIdAllPartnerIdMapping() throws ProfitMandiBusinessException {
1129
        return buildAuthUserIdPartnerIdMapping(false);
1130
    }
1131
 
1132
    private Map<Integer, List<Integer>> buildAuthUserIdPartnerIdMapping(boolean activeOnly) throws ProfitMandiBusinessException {
31762 tejbeer 1133
        Map<Integer, List<Integer>> storeGuyMap = new HashMap<>();
36802 ranu 1134
        Set<Integer> fofoIdsScope = (activeOnly
1135
                ? fofoStoreRepository.selectActiveStores()
1136
                : fofoStoreRepository.selectAllFranchiseStores())
1137
                .stream().map(x -> x.getId()).collect(Collectors.toSet());
31020 tejbeer 1138
 
34077 tejus.loha 1139
        List<Position> categoryPositions = positionRepository.selectAllPosition();
31020 tejbeer 1140
 
31762 tejbeer 1141
        Map<Integer, Position> positionsMap = categoryPositions.stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
29229 tejbeer 1142
 
35454 amit 1143
        // OPTIMIZED: Batch fetch all AuthUsers instead of N+1 queries
1144
        List<Integer> authUserIds = categoryPositions.stream()
1145
                .map(Position::getAuthUserId)
1146
                .filter(id -> id != null && id > 0)
1147
                .distinct()
1148
                .collect(Collectors.toList());
1149
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(authUserIds).stream()
1150
                .collect(Collectors.toMap(AuthUser::getId, au -> au, (a, b) -> a));
1151
 
31762 tejbeer 1152
        Map<Integer, List<CustomRetailer>> positonPartnerMap = this.getPositionCustomRetailerMap(categoryPositions);
1153
        for (Map.Entry<Integer, List<CustomRetailer>> positionPartnerEntry : positonPartnerMap.entrySet()) {
1154
            int authUserId = positionsMap.get(positionPartnerEntry.getKey()).getAuthUserId();
36802 ranu 1155
            List<Integer> partnerIds = positionPartnerEntry.getValue().stream().filter(x -> fofoIdsScope.contains(x.getPartnerId())).map(x -> x.getPartnerId()).collect(Collectors.toList());
35454 amit 1156
            AuthUser authUser = authUserMap.get(authUserId);
31762 tejbeer 1157
            if (authUser != null && authUser.isActive()) {
1158
                if (!storeGuyMap.containsKey(authUserId)) {
1159
                    storeGuyMap.put(authUserId, partnerIds);
1160
                } else {
1161
                    storeGuyMap.get(authUserId).addAll(partnerIds);
1162
                }
1163
            }
1164
        }
1165
        storeGuyMap.keySet().stream().forEach(x -> {
1166
            List<Integer> fofoIds = storeGuyMap.get(x);
1167
            storeGuyMap.put(x, fofoIds.stream().distinct().collect(Collectors.toList()));
1168
        });
1169
        return storeGuyMap;
1170
    }
28908 tejbeer 1171
 
31762 tejbeer 1172
    @Override
1173
    @Cacheable(value = "L1L2Mapping", cacheManager = "thirtyMinsTimeOutCacheManager")
33244 ranu 1174
    public Map<Integer, List<Integer>> getL2L1Mapping() throws ProfitMandiBusinessException {
31762 tejbeer 1175
        List<Position> l1SalesPositions = positionRepository.selectPositionbyCategoryIdAndEscalationType(
1176
                ProfitMandiConstants.TICKET_CATEGORY_SALES, EscalationType.L1);
1177
        List<Position> l2SalesPositions = positionRepository.selectPositionbyCategoryIdAndEscalationType(
1178
                ProfitMandiConstants.TICKET_CATEGORY_SALES, EscalationType.L2);
28908 tejbeer 1179
 
33074 amit.gupta 1180
        //LOGGER.info("position" + l1SalesPositions);
31762 tejbeer 1181
        Map<Integer, List<Integer>> authUserPartnerListMap = this.getAuthUserIdPartnerIdMapping();
33074 amit.gupta 1182
        //LOGGER.info("map" + authUserPartnerListMap);
28908 tejbeer 1183
 
31762 tejbeer 1184
        Map<Integer, List<Integer>> l2l1ListMap = new HashMap<>();
29318 tejbeer 1185
 
31762 tejbeer 1186
        for (Position l2SalePosition : l2SalesPositions) {
1187
            int l2AuthUserId = l2SalePosition.getAuthUserId();
1188
            if (authUserPartnerListMap.containsKey(l2SalePosition.getAuthUserId())) {
1189
                List<Integer> mappedL1AuthUsers = new ArrayList<>();
1190
                l2l1ListMap.put(l2AuthUserId, mappedL1AuthUsers);
1191
                List<Integer> l2FofoIds = authUserPartnerListMap.get(l2AuthUserId);
1192
                for (Position l1SalePosition : l1SalesPositions) {
1193
                    int l1AuthUserId = l1SalePosition.getAuthUserId();
1194
                    if (authUserPartnerListMap.containsKey(l1AuthUserId)) {
1195
                        List<Integer> l1FofoIds = authUserPartnerListMap.get(l1SalePosition.getAuthUserId());
1196
                        if (l2FofoIds.containsAll(l1FofoIds)) {
1197
                            mappedL1AuthUsers.add(l1AuthUserId);
1198
                        }
1199
                    }
28856 manish 1200
 
31762 tejbeer 1201
                }
1202
            }
29296 manish 1203
 
31762 tejbeer 1204
        }
29296 manish 1205
 
31762 tejbeer 1206
        return l2l1ListMap;
1207
    }
29296 manish 1208
 
31762 tejbeer 1209
    @Override
1210
    public Map<Integer, List<AuthUser>> getAssignedAuthList(List<Ticket> tickets) {
1211
        if (tickets.size() == 0) {
1212
            return new HashMap<>();
1213
        }
1214
        List<TicketAssigned> ticketAssignedList = ticketAssignedRepository.selectByTicketIds(tickets.stream().map(x -> x.getId()).collect(Collectors.toList()));
1215
        List<Integer> authUserIds = ticketAssignedList.stream().map(x -> x.getAssineeId()).distinct().collect(Collectors.toList());
35394 amit 1216
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(authUserIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
31762 tejbeer 1217
        return ticketAssignedList.stream().collect(Collectors.groupingBy(x -> x.getTicketId(), Collectors.mapping(x -> authUserMap.get(x.getAssineeId()), Collectors.toList())));
1218
    }
28908 tejbeer 1219
 
31762 tejbeer 1220
    @Override
33244 ranu 1221
    public Map<EscalationType, AuthUser> getAuthUserAndEsclationByPartnerId(int fofoId) throws ProfitMandiBusinessException {
31762 tejbeer 1222
        Map<EscalationType, AuthUser> authuserEsclationTypeMap = new HashMap<>();
1223
        List<Integer> regionIds = partnerRegionRepository.selectByfofoId(fofoId).stream().map(x -> x.getRegionId()).collect(Collectors.toList());
28908 tejbeer 1224
 
35592 amit 1225
        regionIds.add(ALL_PARTNERS_REGION);// All partners Id;
31762 tejbeer 1226
        List<Integer> fofoIds = new ArrayList<>();
1227
        fofoIds.add(fofoId);
1228
        fofoIds.add(0);
28908 tejbeer 1229
 
32493 amit.gupta 1230
        List<Integer> partnerPositionIds = partnerPositionRepository.selectByRegionIdAndPartnerId(regionIds, fofoIds).stream().map(x -> x.getPositionId()).collect(Collectors.toList());
28908 tejbeer 1231
 
35592 amit 1232
        if (partnerPositionIds.isEmpty()) {
1233
            return authuserEsclationTypeMap;
1234
        }
30003 tejbeer 1235
 
35592 amit 1236
        // OPTIMIZED: Batch fetch all positions instead of N+1 queries
1237
        List<Position> salesPositions = positionRepository.selectByIds(partnerPositionIds).stream()
1238
                .filter(p -> p.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_SALES)
1239
                .collect(Collectors.toList());
30003 tejbeer 1240
 
35592 amit 1241
        if (salesPositions.isEmpty()) {
1242
            return authuserEsclationTypeMap;
1243
        }
30003 tejbeer 1244
 
35592 amit 1245
        // OPTIMIZED: Batch fetch all AuthUsers instead of N+1 queries
1246
        List<Integer> authUserIds = salesPositions.stream()
1247
                .map(Position::getAuthUserId)
1248
                .filter(id -> id != null && id > 0)
1249
                .distinct()
1250
                .collect(Collectors.toList());
1251
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(authUserIds).stream()
1252
                .collect(Collectors.toMap(AuthUser::getId, au -> au, (a, b) -> a));
1253
 
1254
        for (Position position : salesPositions) {
1255
            AuthUser authUser = authUserMap.get(position.getAuthUserId());
1256
            if (authUser != null) {
31762 tejbeer 1257
                authuserEsclationTypeMap.put(position.getEscalationType(), authUser);
1258
            }
1259
        }
30003 tejbeer 1260
 
31762 tejbeer 1261
        return authuserEsclationTypeMap;
1262
    }
30044 tejbeer 1263
 
31762 tejbeer 1264
    @Override
35394 amit 1265
    public Map<Integer, Map<EscalationType, AuthUser>> getAuthUserAndEsclationByPartnerIds(Set<Integer> fofoIds) throws ProfitMandiBusinessException {
1266
        Map<Integer, Map<EscalationType, AuthUser>> result = new HashMap<>();
1267
 
1268
        if (fofoIds == null || fofoIds.isEmpty()) {
1269
            return result;
1270
        }
1271
 
1272
        // Initialize result map
1273
        for (Integer fofoId : fofoIds) {
1274
            result.put(fofoId, new HashMap<>());
1275
        }
1276
 
1277
        // Batch fetch all partner regions
1278
        List<Integer> fofoIdListWithZero = new ArrayList<>(fofoIds);
1279
        fofoIdListWithZero.add(0);
1280
        List<PartnerRegion> allPartnerRegions = partnerRegionRepository.selectByfofoIds(fofoIdListWithZero);
1281
 
1282
        // Build fofoId -> regionIds map
1283
        Map<Integer, Set<Integer>> fofoRegionMap = new HashMap<>();
1284
        for (Integer fofoId : fofoIds) {
1285
            fofoRegionMap.put(fofoId, new HashSet<>());
1286
            fofoRegionMap.get(fofoId).add(ALL_PARTNERS_REGION);
1287
        }
1288
        for (PartnerRegion pr : allPartnerRegions) {
1289
            int prFofoId = pr.getFofoId();
1290
            if (prFofoId == 0) {
1291
                for (Integer fid : fofoIds) {
1292
                    fofoRegionMap.get(fid).add(pr.getRegionId());
1293
                }
1294
            } else if (fofoIds.contains(prFofoId)) {
1295
                fofoRegionMap.get(prFofoId).add(pr.getRegionId());
1296
            }
1297
        }
1298
 
1299
        // Collect all region IDs
1300
        Set<Integer> allRegionIds = fofoRegionMap.values().stream()
1301
                .flatMap(Set::stream).collect(Collectors.toSet());
1302
 
1303
        // Batch fetch all partner positions
1304
        List<PartnerPosition> allPartnerPositions = partnerPositionRepository.selectByRegionIdAndPartnerId(
1305
                new ArrayList<>(allRegionIds), fofoIdListWithZero);
1306
 
1307
        // Collect all position IDs
1308
        Set<Integer> allPositionIds = allPartnerPositions.stream()
1309
                .map(PartnerPosition::getPositionId).collect(Collectors.toSet());
1310
 
1311
        // Batch fetch all positions for SALES category
1312
        List<Position> salesPositions = positionRepository.selectPositionbyCategoryIdAndEscalationType(
1313
                ProfitMandiConstants.TICKET_CATEGORY_SALES, null);
1314
        Map<Integer, Position> positionMap = salesPositions.stream()
1315
                .filter(p -> allPositionIds.contains(p.getId()))
1316
                .collect(Collectors.toMap(Position::getId, p -> p, (a, b) -> a));
1317
 
1318
        // Collect all auth user IDs and batch fetch
1319
        Set<Integer> authUserIds = positionMap.values().stream()
1320
                .map(Position::getAuthUserId).collect(Collectors.toSet());
1321
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(new ArrayList<>(authUserIds))
1322
                .stream().collect(Collectors.toMap(AuthUser::getId, au -> au, (a, b) -> a));
1323
 
1324
        // For each fofoId, find matching positions and build result
1325
        for (Integer fofoId : fofoIds) {
1326
            Set<Integer> regionIds = fofoRegionMap.get(fofoId);
1327
            Map<EscalationType, AuthUser> escalationMap = result.get(fofoId);
1328
 
1329
            for (PartnerPosition pp : allPartnerPositions) {
1330
                if (regionIds.contains(pp.getRegionId()) &&
1331
                    (pp.getFofoId() == 0 || pp.getFofoId() == fofoId)) {
1332
                    Position position = positionMap.get(pp.getPositionId());
1333
                    if (position != null) {
1334
                        AuthUser authUser = authUserMap.get(position.getAuthUserId());
1335
                        if (authUser != null) {
1336
                            escalationMap.put(position.getEscalationType(), authUser);
1337
                        }
1338
                    }
1339
                }
1340
            }
1341
        }
1342
 
1343
        return result;
1344
    }
1345
 
1346
    @Override
33244 ranu 1347
    public List<AuthUser> getAuthUserIdByPartnerId(int fofoId) throws ProfitMandiBusinessException {
33041 ranu 1348
        return this.getAuthUserIdByPartnerId(fofoId, EscalationType.escalations.toArray(new EscalationType[0]));
1349
    }
1350
 
1351
    @Override
33244 ranu 1352
    public List<AuthUser> getAuthUserIdByPartnerId(int fofoId, EscalationType... escalationTypes) throws ProfitMandiBusinessException {
31762 tejbeer 1353
        List<AuthUser> authUsers = new ArrayList<>();
1354
        List<Integer> regionIds = partnerRegionRepository.selectByfofoId(fofoId).stream().map(x -> x.getRegionId()).collect(Collectors.toList());
30044 tejbeer 1355
 
31762 tejbeer 1356
        regionIds.add(5);// All partners Id;
1357
        List<Integer> fofoIds = new ArrayList<>();
1358
        fofoIds.add(fofoId);
1359
        fofoIds.add(0);
30044 tejbeer 1360
 
33074 amit.gupta 1361
        //LOGGER.info("fofoIds" + fofoIds);
32493 amit.gupta 1362
        List<Integer> partnerPositionIds = partnerPositionRepository.selectByRegionIdAndPartnerId(regionIds, fofoIds).stream().map(x -> x.getPositionId()).collect(Collectors.toList());
30003 tejbeer 1363
 
33074 amit.gupta 1364
        //LOGGER.info("partnerPositionIds" + partnerPositionIds);
34905 ranu 1365
        List<Integer> allowedTicketCategoryIds = Arrays.asList(ProfitMandiConstants.TICKET_CATEGORY_SALES, ProfitMandiConstants.TICKET_CATEGORY_RBM,ProfitMandiConstants.TICKET_CATEGORY_ABM);
30003 tejbeer 1366
 
30044 tejbeer 1367
 
35394 amit 1368
        List<Position> escalationBasedPositions = positionRepository.selectByIds(partnerPositionIds).stream().filter(x -> allowedTicketCategoryIds.contains(x.getCategoryId()) &&
33041 ranu 1369
                Arrays.stream(escalationTypes)
1370
                        .anyMatch(y -> y.equals(x.getEscalationType()))).collect(Collectors.toList());
30003 tejbeer 1371
 
33041 ranu 1372
        List<Integer> authUserIds = escalationBasedPositions.stream().map(x -> x.getAuthUserId()).collect(Collectors.toList());
30003 tejbeer 1373
 
35394 amit 1374
        return authRepository.selectByIds(authUserIds);
30003 tejbeer 1375
 
31762 tejbeer 1376
    }
30044 tejbeer 1377
 
31762 tejbeer 1378
    @Override
1379
    public List<AuthUser> getAuthUserIds(int categoryId, List<EscalationType> escalationType) {
30044 tejbeer 1380
 
31762 tejbeer 1381
        List<Position> positions = positionRepository.selectPositionbyCategoryIdAndEscalationTypes(categoryId, escalationType);
1382
        List<Integer> authIds = positions.stream().map(x -> x.getAuthUserId()).distinct().collect(Collectors.toList());
30003 tejbeer 1383
 
33074 amit.gupta 1384
        //LOGGER.info("authIds" + authIds);
35058 amit 1385
        List<AuthUser> authUsers = null;
1386
        if (authIds.size() > 0) {
35394 amit 1387
            authUsers = authRepository.selectByIds(authIds);
35058 amit 1388
        } else {
1389
            authUsers = new ArrayList<>();
1390
        }
30003 tejbeer 1391
 
31762 tejbeer 1392
        LOGGER.info("authUsers" + authUsers);
1393
        return authUsers;
1394
    }
1395
 
1396
    @Override
1397
    public List<AuthUser> getAuthUserByCategoryId(int categoryId, EscalationType escalationType) {
1398
 
1399
        List<Position> positions = positionRepository.selectPositionbyCategoryIdAndEscalationType(categoryId, escalationType);
1400
        List<Integer> authIds = positions.stream().map(x -> x.getAuthUserId()).distinct().collect(Collectors.toList());
1401
 
1402
        LOGGER.info("authIds" + authIds);
1403
        List<AuthUser> authUsers = new ArrayList<>();
1404
        if (!authIds.isEmpty()) {
35394 amit 1405
            authUsers = authRepository.selectByIds(authIds);
31762 tejbeer 1406
        }
1407
 
1408
        LOGGER.info("authUsers" + authUsers);
1409
        return authUsers;
1410
    }
1411
 
1412
    @Override
1413
    @Cacheable(value = "authUserByCategoryId", cacheManager = "thirtyMinsTimeOutCacheManager")
1414
    public List<AuthUser> getAuthUserByCategoryId(int categoryId) {
1415
        List<Position> positions = positionRepository.selectPositionByCategoryId(categoryId);
1416
        List<Integer> authIds = positions.stream().map(x -> x.getAuthUserId()).distinct().collect(Collectors.toList());
1417
 
1418
        LOGGER.info("authIds" + authIds);
1419
 
35394 amit 1420
        List<AuthUser> authUsers = authRepository.selectByIds(authIds).stream().filter(x -> x.getActive()).collect(Collectors.toList());
31762 tejbeer 1421
 
1422
        LOGGER.info("authUsers" + authUsers);
1423
        return authUsers;
1424
    }
1425
 
34380 amit.gupta 1426
    private class SaleRoles1 {
31762 tejbeer 1427
 
1428
        private List<String> l1;
1429
        private List<String> l2;
1430
        private List<String> l3;
1431
        private List<String> l4;
1432
 
34380 amit.gupta 1433
        public SaleRoles1() {
31762 tejbeer 1434
            l1 = new ArrayList<>();
1435
            l2 = new ArrayList<>();
1436
            l3 = new ArrayList<>();
1437
            l4 = new ArrayList<>();
1438
        }
1439
 
1440
        public List<String> getL1() {
1441
            return l1;
1442
        }
1443
 
1444
        public List<String> getL2() {
1445
            return l2;
1446
        }
1447
 
1448
        public List<String> getL3() {
1449
            return l3;
1450
        }
1451
 
1452
        public List<String> getL4() {
1453
            return l4;
1454
        }
1455
 
1456
        @Override
1457
        public String toString() {
1458
            return "SaleRoles [l1=" + l1 + ", l2=" + l2 + ", l3=" + l3 + ", l4=" + l4 + "]";
1459
        }
1460
 
1461
    }
1462
 
33161 ranu 1463
 
31762 tejbeer 1464
    @Override
1465
    @Cacheable(value = "partnerSaleHeader", cacheManager = "oneDayCacheManager")
33244 ranu 1466
    public Map<Integer, FofoReportingModel> getPartnerIdSalesHeaders() throws ProfitMandiBusinessException {
34380 amit.gupta 1467
        Map<String, SaleRoles1> partnerEmailSalesMap = new HashMap<>();
31762 tejbeer 1468
 
1469
        List<Position> positions = positionRepository.selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_SALES);
1470
        Map<Integer, AuthUser> authUsersMap = authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
1471
        Map<Integer, List<CustomRetailer>> positionIdRetailerMap = this.getPositionCustomRetailerMap(positions);
1472
        for (Position position : positions) {
1473
            List<CustomRetailer> crList = positionIdRetailerMap.get(position.getId());
1474
            if (crList == null)
1475
                continue;
1476
            for (CustomRetailer cr : crList) {
1477
                if (!partnerEmailSalesMap.containsKey(cr.getEmail())) {
34380 amit.gupta 1478
                    partnerEmailSalesMap.put(cr.getEmail(), new SaleRoles1());
31762 tejbeer 1479
                }
34380 amit.gupta 1480
                SaleRoles1 saleRoles1 = partnerEmailSalesMap.get(cr.getEmail());
31762 tejbeer 1481
                AuthUser authUser = authUsersMap.get(position.getAuthUserId());
1482
                if (authUser == null) {
1483
                    continue;
1484
                }
1485
                String name = authUser.getFirstName() + " " + authUser.getLastName();
1486
                if (position.getEscalationType().equals(EscalationType.L1)) {
34380 amit.gupta 1487
                    saleRoles1.getL1().add(name);
31762 tejbeer 1488
                } else if (position.getEscalationType().equals(EscalationType.L2)) {
34380 amit.gupta 1489
                    saleRoles1.getL2().add(name);
31762 tejbeer 1490
                }
1491
 
1492
            }
1493
        }
1494
 
1495
        Set<CustomRetailer> allCrList = new HashSet<>();
1496
        for (List<CustomRetailer> cr : positionIdRetailerMap.values()) {
1497
            allCrList.addAll(cr);
1498
        }
1499
 
1500
        Map<Integer, FofoStore> fofoStoresMap = fofoStoreRepository.selectActiveStores().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
1501
 
1502
        Map<Integer, FofoReportingModel> partnerIdSalesHeadersMap = new HashMap<>();
1503
 
33378 ranu 1504
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
1505
        for (Map.Entry<Integer, CustomRetailer> customRetailerEntry : customRetailerMap.entrySet()) {
1506
 
1507
            CustomRetailer customRetailer = customRetailerEntry.getValue();
1508
 
1509
            String code = customRetailer.getCode();
31762 tejbeer 1510
            // String storeName = "SmartDukaan-" +
1511
            // fofoStore.getCode().replaceAll("[a-zA-Z]", "");
33378 ranu 1512
            String businessName = customRetailer.getBusinessName();
31762 tejbeer 1513
            try {
34158 tejus.loha 1514
                String stateManager = StringUtils.join(new HashSet(partnerEmailSalesMap.get(customRetailer.getEmail()).getL2()), ", ");
1515
                String territoryManager = StringUtils.join(new HashSet(partnerEmailSalesMap.get(customRetailer.getEmail()).getL1()), ", ");
31762 tejbeer 1516
 
1517
                FofoReportingModel reportingModel = new FofoReportingModel();
1518
                reportingModel.setBusinessName(businessName);
1519
                reportingModel.setCode(code);
33378 ranu 1520
                reportingModel.setFofoId(customRetailer.getPartnerId());
31762 tejbeer 1521
                reportingModel.setRegionalManager(stateManager);
1522
                reportingModel.setTerritoryManager(territoryManager);
33378 ranu 1523
                partnerIdSalesHeadersMap.put(customRetailer.getPartnerId(), reportingModel);
31762 tejbeer 1524
            } catch (Exception e) {
33378 ranu 1525
                LOGGER.warn("Could not find partner with email - {}", customRetailer.getEmail());
31762 tejbeer 1526
            }
1527
        }
1528
        return partnerIdSalesHeadersMap;
1529
 
1530
    }
1531
 
33161 ranu 1532
 
34905 ranu 1533
    private class ABMRoles {
1534
 
1535
        private List<String> l1;
1536
        private List<String> l2;
1537
        private List<String> l3;
1538
        private List<String> l4;
1539
 
1540
        public ABMRoles() {
1541
            l1 = new ArrayList<>();
1542
            l2 = new ArrayList<>();
1543
            l3 = new ArrayList<>();
1544
            l4 = new ArrayList<>();
1545
        }
1546
 
1547
        public List<String> getL1() {
1548
            return l1;
1549
        }
1550
 
1551
        public List<String> getL2() {
1552
            return l2;
1553
        }
1554
 
1555
        public List<String> getL3() {
1556
            return l3;
1557
        }
1558
 
1559
        public List<String> getL4() {
1560
            return l4;
1561
        }
1562
 
1563
        @Override
1564
        public String toString() {
1565
            return "SaleRoles [l1=" + l1 + ", l2=" + l2 + ", l3=" + l3 + ", l4=" + l4 + "]";
1566
        }
1567
 
1568
    }
1569
 
1570
 
1571
    @Override
1572
    @Cacheable(value = "partnerABMHeader", cacheManager = "oneDayCacheManager")
1573
    public Map<Integer, FofoAbmReportingModel> getPartnerIdABMHeaders() throws ProfitMandiBusinessException {
1574
        Map<String, ABMRoles> partnerEmailABMMap = new HashMap<>();
1575
 
1576
        List<Position> positions = positionRepository.selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_ABM);
1577
        Map<Integer, AuthUser> authUsersMap = authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
1578
        Map<Integer, List<CustomRetailer>> positionIdRetailerMap = this.getPositionCustomRetailerMap(positions);
1579
        for (Position position : positions) {
1580
            List<CustomRetailer> crList = positionIdRetailerMap.get(position.getId());
1581
            if (crList == null)
1582
                continue;
1583
            for (CustomRetailer cr : crList) {
1584
                if (!partnerEmailABMMap.containsKey(cr.getEmail())) {
1585
                    partnerEmailABMMap.put(cr.getEmail(), new ABMRoles());
1586
                }
1587
                ABMRoles abmRoles = partnerEmailABMMap.get(cr.getEmail());
1588
                AuthUser authUser = authUsersMap.get(position.getAuthUserId());
1589
                if (authUser == null) {
1590
                    continue;
1591
                }
1592
                String name = authUser.getFirstName() + " " + authUser.getLastName();
1593
                if (position.getEscalationType().equals(EscalationType.L1)) {
1594
                    abmRoles.getL1().add(name);
1595
                } else if (position.getEscalationType().equals(EscalationType.L2)) {
1596
                    abmRoles.getL2().add(name);
1597
                }
1598
 
1599
            }
1600
        }
1601
 
1602
        Set<CustomRetailer> allCrList = new HashSet<>();
1603
        for (List<CustomRetailer> cr : positionIdRetailerMap.values()) {
1604
            allCrList.addAll(cr);
1605
        }
1606
 
1607
        Map<Integer, FofoStore> fofoStoresMap = fofoStoreRepository.selectActiveStores().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
1608
 
1609
        Map<Integer, FofoAbmReportingModel> partnerIdAbmHeadersMap = new HashMap<>();
1610
 
1611
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
1612
        for (Map.Entry<Integer, CustomRetailer> customRetailerEntry : customRetailerMap.entrySet()) {
1613
 
1614
            CustomRetailer customRetailer = customRetailerEntry.getValue();
1615
 
1616
            String code = customRetailer.getCode();
1617
            // String storeName = "SmartDukaan-" +
1618
            // fofoStore.getCode().replaceAll("[a-zA-Z]", "");
1619
            String businessName = customRetailer.getBusinessName();
1620
            try {
1621
                String l2Manager = StringUtils.join(new HashSet(partnerEmailABMMap.get(customRetailer.getEmail()).getL2()), ", ");
1622
                String l1Manager = StringUtils.join(new HashSet(partnerEmailABMMap.get(customRetailer.getEmail()).getL1()), ", ");
1623
 
1624
                if (StringUtils.isEmpty(l1Manager)) {
1625
                    l2Manager = StringUtils.join(new HashSet(partnerEmailABMMap.get(customRetailer.getEmail()).getL2()), ", ");
1626
                }
1627
 
1628
                FofoAbmReportingModel reportingModel = new FofoAbmReportingModel();
1629
                reportingModel.setBusinessName(businessName);
1630
                reportingModel.setCode(code);
1631
                reportingModel.setFofoId(customRetailer.getPartnerId());
1632
                reportingModel.setL1Manager(l2Manager);
1633
                reportingModel.setL2Manager(l1Manager);
1634
                partnerIdAbmHeadersMap.put(customRetailer.getPartnerId(), reportingModel);
1635
            } catch (Exception e) {
1636
                LOGGER.warn("Could not find partner with email - {}", customRetailer.getEmail());
1637
            }
1638
        }
1639
        return partnerIdAbmHeadersMap;
1640
 
1641
    }
1642
 
1643
 
33161 ranu 1644
    private class RBMRoles {
1645
 
1646
        private List<String> l1;
1647
        private List<String> l2;
1648
        private List<String> l3;
1649
        private List<String> l4;
1650
 
1651
        public RBMRoles() {
1652
            l1 = new ArrayList<>();
1653
            l2 = new ArrayList<>();
1654
            l3 = new ArrayList<>();
1655
            l4 = new ArrayList<>();
1656
        }
1657
 
1658
        public List<String> getL1() {
1659
            return l1;
1660
        }
1661
 
1662
        public List<String> getL2() {
1663
            return l2;
1664
        }
1665
 
1666
        public List<String> getL3() {
1667
            return l3;
1668
        }
1669
 
1670
        public List<String> getL4() {
1671
            return l4;
1672
        }
1673
 
1674
        @Override
1675
        public String toString() {
1676
            return "RBMRoles [l1=" + l1 + ", l2=" + l2 + ", l3=" + l3 + ", l4=" + l4 + "]";
1677
        }
1678
 
1679
    }
1680
 
31762 tejbeer 1681
    @Override
33161 ranu 1682
    @Cacheable(value = "partnerRBMHeader", cacheManager = "oneDayCacheManager")
33244 ranu 1683
    public Map<Integer, FofoRBMReportingModel> getPartnerIdRBMHeaders() throws ProfitMandiBusinessException {
33161 ranu 1684
        Map<String, RBMRoles> partnerEmailRbmMap = new HashMap<>();
1685
 
1686
        List<Position> positions = positionRepository.selectPositionByCategoryId(ProfitMandiConstants.TICKET_CATEGORY_RBM);
1687
        Map<Integer, AuthUser> authUsersMap = authRepository.selectAllActiveUser().stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
1688
        Map<Integer, List<CustomRetailer>> positionIdRetailerMap = this.getPositionCustomRetailerMap(positions);
1689
        for (Position position : positions) {
1690
            List<CustomRetailer> crList = positionIdRetailerMap.get(position.getId());
1691
            if (crList == null)
1692
                continue;
1693
            for (CustomRetailer cr : crList) {
1694
                if (!partnerEmailRbmMap.containsKey(cr.getEmail())) {
1695
                    partnerEmailRbmMap.put(cr.getEmail(), new RBMRoles());
1696
                }
1697
                RBMRoles rbmRole = partnerEmailRbmMap.get(cr.getEmail());
1698
                AuthUser authUser = authUsersMap.get(position.getAuthUserId());
1699
                if (authUser == null) {
1700
                    continue;
1701
                }
1702
                String name = authUser.getFirstName() + " " + authUser.getLastName();
1703
                if (position.getEscalationType().equals(EscalationType.L1)) {
1704
                    rbmRole.getL1().add(name);
1705
                } else if (position.getEscalationType().equals(EscalationType.L2)) {
1706
                    rbmRole.getL2().add(name);
1707
                }
1708
 
1709
            }
1710
        }
1711
 
1712
        Set<CustomRetailer> allCrList = new HashSet<>();
1713
        for (List<CustomRetailer> cr : positionIdRetailerMap.values()) {
1714
            allCrList.addAll(cr);
1715
        }
1716
 
1717
 
1718
        Map<Integer, FofoRBMReportingModel> partnerIdRbmHeadersMap = new HashMap<>();
1719
 
33377 amit.gupta 1720
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
1721
        for (Map.Entry<Integer, CustomRetailer> customRetailerEntry : customRetailerMap.entrySet()) {
1722
 
1723
            CustomRetailer customRetailer = customRetailerEntry.getValue();
1724
 
1725
            String code = customRetailer.getCode();
33161 ranu 1726
            // String storeName = "SmartDukaan-" +
1727
            // fofoStore.getCode().replaceAll("[a-zA-Z]", "");
33377 amit.gupta 1728
            String businessName = customRetailer.getBusinessName();
33161 ranu 1729
            try {
33377 amit.gupta 1730
                String L2User = StringUtils.join(partnerEmailRbmMap.get(customRetailer.getEmail()).getL2(), ", ");
1731
                String L1USer = StringUtils.join(partnerEmailRbmMap.get(customRetailer.getEmail()).getL1(), ", ");
33161 ranu 1732
 
1733
                FofoRBMReportingModel reportingModel = new FofoRBMReportingModel();
1734
                reportingModel.setBusinessName(businessName);
1735
                reportingModel.setCode(code);
33377 amit.gupta 1736
                reportingModel.setFofoId(customRetailer.getPartnerId());
35180 amit 1737
                reportingModel.setL1Manager(L1USer);
1738
                reportingModel.setL2Manager(L2User);
33377 amit.gupta 1739
                partnerIdRbmHeadersMap.put(customRetailer.getPartnerId(), reportingModel);
33161 ranu 1740
            } catch (Exception e) {
33377 amit.gupta 1741
                LOGGER.warn("Could not find partner with email - {}", customRetailer.getEmail());
33161 ranu 1742
            }
1743
        }
1744
        return partnerIdRbmHeadersMap;
1745
 
1746
    }
1747
 
1748
    @Override
31762 tejbeer 1749
    public Map<Integer, TicketCategory> getSubCategoryIdAndCategoryMap(List<Integer> subCategoryIds) {
1750
        Map<Integer, TicketCategory> subCategoryIdAndCategoryMap = new HashMap<>();
35592 amit 1751
        if (subCategoryIds == null || subCategoryIds.isEmpty()) {
1752
            return subCategoryIdAndCategoryMap;
1753
        }
31762 tejbeer 1754
 
1755
        List<TicketSubCategory> ticketSubCategories = ticketSubCategoryRepository.selectByIds(subCategoryIds);
1756
 
35592 amit 1757
        // OPTIMIZED: Batch fetch all categories instead of N+1 queries
1758
        List<Integer> categoryIds = ticketSubCategories.stream()
1759
                .map(TicketSubCategory::getCategoryId)
1760
                .distinct()
1761
                .collect(Collectors.toList());
1762
        Map<Integer, TicketCategory> categoryMap = ticketCategoryRepository.selectAll(categoryIds).stream()
1763
                .collect(Collectors.toMap(TicketCategory::getId, tc -> tc, (a, b) -> a));
1764
 
31762 tejbeer 1765
        for (TicketSubCategory ticketSubCategory : ticketSubCategories) {
35592 amit 1766
            subCategoryIdAndCategoryMap.put(ticketSubCategory.getId(), categoryMap.get(ticketSubCategory.getCategoryId()));
31762 tejbeer 1767
        }
1768
        return subCategoryIdAndCategoryMap;
1769
    }
1770
 
35394 amit 1771
    @Override
1772
    public Map<Integer, Map<String, Integer>> getBmAsmRbmAuthUserIdsByFofoIds(Set<Integer> fofoIds) throws ProfitMandiBusinessException {
1773
        Map<Integer, Map<String, Integer>> result = new HashMap<>();
1774
 
1775
        if (fofoIds == null || fofoIds.isEmpty()) {
1776
            return result;
1777
        }
1778
 
1779
        // Initialize result map with empty values for each fofoId
1780
        for (Integer fofoId : fofoIds) {
1781
            Map<String, Integer> roleMap = new HashMap<>();
1782
            roleMap.put("BM", 0);
1783
            roleMap.put("ASM", 0);
1784
            roleMap.put("RBM", 0);
1785
            result.put(fofoId, roleMap);
1786
        }
1787
 
1788
        // Fetch positions by category + escalation type (same for all fofoIds)
1789
        List<Position> bmPositions = positionRepository.selectPositionbyCategoryIdAndEscalationType(
1790
                ProfitMandiConstants.TICKET_CATEGORY_SALES, EscalationType.L2);
1791
        List<Position> asmPositions = positionRepository.selectPositionbyCategoryIdAndEscalationType(
1792
                ProfitMandiConstants.TICKET_CATEGORY_SALES, EscalationType.L1);
1793
        List<Position> rbmPositions = positionRepository.selectPositionbyCategoryIdAndEscalationType(
1794
                ProfitMandiConstants.TICKET_CATEGORY_RBM, EscalationType.L1);
1795
 
1796
        // Batch fetch all partner regions for all fofoIds
1797
        List<Integer> fofoIdList = new ArrayList<>(fofoIds);
1798
        fofoIdList.add(0); // Include global entries
1799
        List<PartnerRegion> allPartnerRegions = partnerRegionRepository.selectByfofoIds(fofoIdList);
1800
 
1801
        // Build fofoId -> regionIds map
1802
        Map<Integer, Set<Integer>> fofoRegionMap = new HashMap<>();
1803
        for (Integer fofoId : fofoIds) {
1804
            fofoRegionMap.put(fofoId, new HashSet<>());
1805
            fofoRegionMap.get(fofoId).add(ALL_PARTNERS_REGION); // Add all partners region
1806
        }
1807
        for (PartnerRegion pr : allPartnerRegions) {
1808
            int fofoId = pr.getFofoId();
1809
            if (fofoId == 0) {
1810
                // Global entry applies to all fofoIds
1811
                for (Integer fid : fofoIds) {
1812
                    fofoRegionMap.get(fid).add(pr.getRegionId());
1813
                }
1814
            } else if (fofoIds.contains(fofoId)) {
1815
                fofoRegionMap.get(fofoId).add(pr.getRegionId());
1816
            }
1817
        }
1818
 
1819
        // Collect all unique region IDs and position IDs for batch query
1820
        Set<Integer> allRegionIds = fofoRegionMap.values().stream()
1821
                .flatMap(Set::stream).collect(Collectors.toSet());
1822
        Set<Integer> allPositionIds = new HashSet<>();
1823
        bmPositions.forEach(p -> allPositionIds.add(p.getId()));
1824
        asmPositions.forEach(p -> allPositionIds.add(p.getId()));
1825
        rbmPositions.forEach(p -> allPositionIds.add(p.getId()));
1826
 
1827
        // Batch fetch all partner positions
1828
        List<PartnerPosition> allPartnerPositions = partnerPositionRepository.selectByRegionIdAndPostionId(
1829
                new ArrayList<>(allRegionIds), new ArrayList<>(allPositionIds));
1830
 
1831
        // Build positionId -> set of (regionId, partnerId) for matching
1832
        Map<Integer, List<PartnerPosition>> positionIdToPartnerPositions = allPartnerPositions.stream()
1833
                .collect(Collectors.groupingBy(PartnerPosition::getPositionId));
1834
 
1835
        // Collect all auth user IDs we need
1836
        Set<Integer> allAuthUserIds = new HashSet<>();
1837
        bmPositions.forEach(p -> allAuthUserIds.add(p.getAuthUserId()));
1838
        asmPositions.forEach(p -> allAuthUserIds.add(p.getAuthUserId()));
1839
        rbmPositions.forEach(p -> allAuthUserIds.add(p.getAuthUserId()));
1840
 
1841
        // Batch fetch all auth users
1842
        Map<Integer, AuthUser> authUserMap = authRepository.selectByIds(new ArrayList<>(allAuthUserIds))
1843
                .stream().filter(AuthUser::isActive)
1844
                .collect(Collectors.toMap(AuthUser::getId, au -> au, (a, b) -> a));
1845
 
1846
        // Build position ID sets for fast lookup
1847
        Set<Integer> bmPositionIds = bmPositions.stream().map(Position::getId).collect(Collectors.toSet());
1848
        Set<Integer> asmPositionIds = asmPositions.stream().map(Position::getId).collect(Collectors.toSet());
1849
        Set<Integer> rbmPositionIds = rbmPositions.stream().map(Position::getId).collect(Collectors.toSet());
1850
 
1851
        // Map position ID to auth user ID
1852
        Map<Integer, Integer> positionToAuthUser = new HashMap<>();
1853
        bmPositions.forEach(p -> positionToAuthUser.put(p.getId(), p.getAuthUserId()));
1854
        asmPositions.forEach(p -> positionToAuthUser.put(p.getId(), p.getAuthUserId()));
1855
        rbmPositions.forEach(p -> positionToAuthUser.put(p.getId(), p.getAuthUserId()));
1856
 
1857
        // For each fofoId, find matching positions
1858
        for (Integer fofoId : fofoIds) {
1859
            Set<Integer> regionIds = fofoRegionMap.get(fofoId);
1860
 
1861
            // Find position IDs that match this fofoId's regions (partnerId = 0 or fofoId)
1862
            Set<Integer> matchingPositionIds = new HashSet<>();
1863
            for (PartnerPosition pp : allPartnerPositions) {
1864
                if (regionIds.contains(pp.getRegionId()) &&
1865
                    (pp.getFofoId() == 0 || pp.getFofoId() == fofoId)) {
1866
                    matchingPositionIds.add(pp.getPositionId());
1867
                }
1868
            }
1869
 
1870
            // Find first active auth user for each role
1871
            Map<String, Integer> roleMap = result.get(fofoId);
1872
 
1873
            for (Integer positionId : matchingPositionIds) {
1874
                Integer authUserId = positionToAuthUser.get(positionId);
1875
                if (authUserId != null && authUserMap.containsKey(authUserId)) {
1876
                    if (bmPositionIds.contains(positionId) && roleMap.get("BM") == 0) {
1877
                        roleMap.put("BM", authUserId);
1878
                    } else if (asmPositionIds.contains(positionId) && roleMap.get("ASM") == 0) {
1879
                        roleMap.put("ASM", authUserId);
1880
                    } else if (rbmPositionIds.contains(positionId) && roleMap.get("RBM") == 0) {
1881
                        roleMap.put("RBM", authUserId);
1882
                    }
1883
                }
1884
            }
1885
        }
1886
 
1887
        return result;
1888
    }
1889
 
35626 amit 1890
    @Override
35635 ranu 1891
    public Map<Integer, Boolean> getUnreadStatusForTickets(List<Ticket> tickets, int userId, TicketReadStatus.UserType userType) {
35626 amit 1892
        Map<Integer, Boolean> unreadMap = new HashMap<>();
1893
        if (tickets == null || tickets.isEmpty()) {
1894
            return unreadMap;
1895
        }
1896
 
1897
        List<Integer> ticketIds = tickets.stream().map(Ticket::getId).collect(Collectors.toList());
1898
        List<TicketReadStatus> readStatuses = ticketReadStatusRepository.selectByTicketIdsAndUser(ticketIds, userId, userType);
1899
        Map<Integer, Integer> ticketLastReadMap = readStatuses.stream()
1900
                .collect(Collectors.toMap(TicketReadStatus::getTicketId, TicketReadStatus::getLastReadActivityId));
1901
 
1902
        // Get last activities for all tickets to check who created them
1903
        Map<Integer, Activity> lastActivityMap = getLastActivitiesForTickets(ticketIds);
1904
 
1905
        for (Ticket ticket : tickets) {
1906
            int lastActivityId = ticket.getLastActivityId();
1907
            int lastReadActivityId = ticketLastReadMap.getOrDefault(ticket.getId(), 0);
1908
 
1909
            if (lastActivityId <= lastReadActivityId) {
1910
                unreadMap.put(ticket.getId(), false);
1911
                continue;
1912
            }
1913
 
1914
            // Check if the current user created the last activity (exclude own updates)
1915
            Activity lastActivity = lastActivityMap.get(ticket.getId());
1916
            if (lastActivity != null) {
35635 ranu 1917
                if (userType == TicketReadStatus.UserType.AUTH_USER && lastActivity.getCreatedBy() == userId) {
35626 amit 1918
                    unreadMap.put(ticket.getId(), false);
1919
                    continue;
1920
                }
35635 ranu 1921
                if (userType == TicketReadStatus.UserType.PARTNER && lastActivity.getCreatedBy() == 0
35626 amit 1922
                        && lastActivity.getType() == ActivityType.COMMUNICATION_IN) {
1923
                    unreadMap.put(ticket.getId(), false);
1924
                    continue;
1925
                }
1926
                // For partners: only show as unread if activity type is external communication or resolved
35635 ranu 1927
                if (userType == TicketReadStatus.UserType.PARTNER) {
35626 amit 1928
                    boolean isRelevantForPartner = ActivityType.PARTNER_ACTIVITIES.contains(lastActivity.getType());
1929
                    unreadMap.put(ticket.getId(), isRelevantForPartner);
1930
                    continue;
1931
                }
1932
            }
1933
 
1934
            unreadMap.put(ticket.getId(), true);
1935
        }
1936
        return unreadMap;
1937
    }
1938
 
1939
    @Override
35635 ranu 1940
    public void markTicketAsRead(int ticketId, int userId, TicketReadStatus.UserType userType) {
35626 amit 1941
        Ticket ticket = ticketRepository.selectById(ticketId);
1942
        if (ticket == null) {
1943
            return;
1944
        }
1945
        TicketReadStatus readStatus = new TicketReadStatus();
1946
        readStatus.setTicketId(ticketId);
1947
        readStatus.setUserId(userId);
1948
        readStatus.setUserType(userType);
1949
        readStatus.setLastReadActivityId(ticket.getLastActivityId());
1950
        ticketReadStatusRepository.upsert(readStatus);
1951
    }
1952
 
1953
    @Override
1954
    public Map<Integer, Activity> getLastActivitiesForTickets(List<Integer> ticketIds) {
1955
        Map<Integer, Activity> lastActivityMap = new HashMap<>();
1956
        if (ticketIds == null || ticketIds.isEmpty()) {
1957
            return lastActivityMap;
1958
        }
1959
        List<Activity> allActivities = activityRepository.selectAll(ticketIds);
1960
        // Group by ticketId and get the last one (highest id)
1961
        Map<Integer, List<Activity>> groupedByTicket = allActivities.stream()
1962
                .collect(Collectors.groupingBy(Activity::getTicketId));
1963
        for (Map.Entry<Integer, List<Activity>> entry : groupedByTicket.entrySet()) {
1964
            Activity lastActivity = entry.getValue().stream()
1965
                    .max(Comparator.comparingInt(Activity::getId))
1966
                    .orElse(null);
1967
            if (lastActivity != null) {
1968
                lastActivityMap.put(entry.getKey(), lastActivity);
1969
            }
1970
        }
1971
        return lastActivityMap;
1972
    }
1973
 
1974
    @Override
35639 amit 1975
    public Map<Integer, Activity> getLastMessageActivitiesForTickets(List<Integer> ticketIds) {
1976
        Map<Integer, Activity> lastMessageMap = new HashMap<>();
1977
        if (ticketIds == null || ticketIds.isEmpty()) {
1978
            return lastMessageMap;
1979
        }
1980
        Set<ActivityType> messageTypes = EnumSet.of(
1981
                ActivityType.COMMUNICATION_IN, ActivityType.COMMUNICATION_OUT,
1982
                ActivityType.COMMUNICATION_INTERNAL, ActivityType.OPENED);
1983
        List<Activity> allActivities = activityRepository.selectAll(ticketIds);
1984
        Map<Integer, List<Activity>> groupedByTicket = allActivities.stream()
1985
                .filter(a -> messageTypes.contains(a.getType()))
1986
                .collect(Collectors.groupingBy(Activity::getTicketId));
1987
        for (Map.Entry<Integer, List<Activity>> entry : groupedByTicket.entrySet()) {
1988
            Activity lastMessage = entry.getValue().stream()
1989
                    .max(Comparator.comparingInt(Activity::getId))
1990
                    .orElse(null);
1991
            if (lastMessage != null) {
1992
                lastMessageMap.put(entry.getKey(), lastMessage);
1993
            }
1994
        }
1995
        return lastMessageMap;
1996
    }
1997
 
1998
    @Override
35626 amit 1999
    public void notifyPartnerOfExternalCommunication(Ticket ticket, Activity activity) {
2000
        try {
2001
            CustomRetailer partner = retailerService.getFofoRetailer(ticket.getFofoId());
2002
            if (partner == null || partner.getEmail() == null) {
2003
                return;
2004
            }
2005
 
2006
            TicketSubCategory ticketSubCategory = ticketSubCategoryRepository.selectById(ticket.getSubCategoryId());
2007
            TicketCategory ticketCategory = ticketCategoryRepository.selectById(ticketSubCategory.getCategoryId());
2008
 
2009
            Map<String, Object> model = new HashMap<>();
2010
            model.put("ticketId", ticket.getId());
2011
            model.put("partnerName", partner.getBusinessName());
2012
            model.put("categoryName", ticketCategory.getName());
2013
            model.put("subCategoryName", ticketSubCategory.getName());
2014
            model.put("activityMessage", activity.getMessage());
2015
 
2016
            emailService.sendMailWithAttachments(
2017
                    "Update on Your Support Ticket #" + ticket.getId(),
2018
                    "partner-ticket-update.vm",
2019
                    model,
2020
                    new String[]{partner.getEmail()},
2021
                    null,
2022
                    null);
2023
        } catch (Exception e) {
2024
            LOGGER.error("Failed to send partner notification email for ticket {}", ticket.getId(), e);
2025
        }
2026
    }
2027
 
24383 amit.gupta 2028
}