Subversion Repositories SmartDukaan

Rev

Rev 37559 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
24417 govind 1
package com.spice.profitmandi.web.controller;
2
 
3
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
4
import com.spice.profitmandi.common.model.CustomRetailer;
32812 shampa 5
import com.spice.profitmandi.common.model.ProfitMandiConstants;
37559 ranu 6
import com.spice.profitmandi.common.util.FileUtil;
24417 govind 7
import com.spice.profitmandi.dao.entity.auth.AuthUser;
27690 amit.gupta 8
import com.spice.profitmandi.dao.entity.cs.*;
36040 ranu 9
import com.spice.profitmandi.dao.entity.cs.TicketReadStatus.UserType;
27270 tejbeer 10
import com.spice.profitmandi.dao.entity.dtr.Document;
24417 govind 11
import com.spice.profitmandi.dao.entity.fofo.ActivityType;
12
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
24699 govind 13
import com.spice.profitmandi.dao.enumuration.cs.TicketStatus;
25570 tejbeer 14
import com.spice.profitmandi.dao.model.CreatePositionModel;
24417 govind 15
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
27690 amit.gupta 16
import com.spice.profitmandi.dao.repository.cs.*;
27270 tejbeer 17
import com.spice.profitmandi.dao.repository.dtr.DocumentRepository;
25570 tejbeer 18
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
24417 govind 19
import com.spice.profitmandi.service.authentication.RoleManager;
36040 ranu 20
import com.spice.profitmandi.service.mail.MailOutboxService;
37559 ranu 21
import com.spice.profitmandi.service.order.OrderService;
24417 govind 22
import com.spice.profitmandi.service.user.RetailerService;
23
import com.spice.profitmandi.web.model.LoginDetails;
24
import com.spice.profitmandi.web.util.CookiesProcessor;
25
import com.spice.profitmandi.web.util.MVCResponseSender;
27690 amit.gupta 26
import org.apache.logging.log4j.LogManager;
27
import org.apache.logging.log4j.Logger;
28
import org.springframework.beans.factory.annotation.Autowired;
37559 ranu 29
import org.springframework.http.ResponseEntity;
27690 amit.gupta 30
import org.springframework.mail.javamail.JavaMailSender;
31
import org.springframework.stereotype.Controller;
32
import org.springframework.transaction.annotation.Transactional;
33
import org.springframework.ui.Model;
34
import org.springframework.web.bind.annotation.*;
24417 govind 35
 
27690 amit.gupta 36
import javax.servlet.http.HttpServletRequest;
36040 ranu 37
import javax.swing.*;
27690 amit.gupta 38
import java.time.LocalDateTime;
39
import java.util.*;
40
import java.util.stream.Collectors;
41
 
24417 govind 42
@Controller
43
@Transactional(rollbackFor = Throwable.class)
44
public class CsController {
45
 
31762 tejbeer 46
    private static final Logger LOGGER = LogManager.getLogger(CsController.class);
47
    private static final String ACTIVITY_SUBJECT = "Message related ticketId#%s";
48
    private static final String PARTNER_RESOLVED_TICKET_MAIL = "Dear Partner , we have resolved your ticket # %s , request to kindly accept the same. In case you still have any concerns regarding the same pls click on %s so that we can help you.Regards\nSmartdukaan";
49
    private static final String PARTNER_REOPEN = "Dear Partner , Your ticket # %s has been re-opened as per your confirmation & we are committed to resolve it on priority.Regards\nSmartdukaan";
50
    private static final String INTERNAL_REOPEN_MAIL = "Team, Pls note that the Ticket Id %s has been re-opened by %s , pls respond on priority";
51
    private static final String INTERNAL_REOPEN_ACTIVITY_MESSAGE = "Hi,My ticket is not resolved yet,so I have reopened it";
24699 govind 52
 
31762 tejbeer 53
    @Autowired
36401 amit 54
    JavaMailSender gmailRelaySender;
24620 govind 55
 
31762 tejbeer 56
    @Autowired
35957 amit 57
    MailOutboxService mailOutboxService;
58
 
59
    @Autowired
31762 tejbeer 60
    private CsService csService;
24417 govind 61
 
31762 tejbeer 62
    @Autowired
63
    private CookiesProcessor cookiesProcessor;
24417 govind 64
 
31762 tejbeer 65
    @Autowired
66
    private TicketCategoryRepository ticketCategoryRepository;
24417 govind 67
 
31762 tejbeer 68
    @Autowired
69
    private TicketSubCategoryRepository ticketSubCategoryRepository;
24417 govind 70
 
31762 tejbeer 71
    @Autowired
72
    private RegionRepository regionRepository;
24417 govind 73
 
31762 tejbeer 74
    @Autowired
75
    private RetailerService retailerService;
24417 govind 76
 
31762 tejbeer 77
    @Autowired
78
    private MVCResponseSender mvcResponseSender;
24417 govind 79
 
31762 tejbeer 80
    @Autowired
81
    private AuthRepository authRepository;
24417 govind 82
 
31762 tejbeer 83
    @Autowired
84
    private PositionRepository positionRepository;
24417 govind 85
 
31762 tejbeer 86
    @Autowired
87
    private TicketRepository ticketRepository;
24417 govind 88
 
31762 tejbeer 89
    @Autowired
90
    private RoleManager roleManager;
24417 govind 91
 
31762 tejbeer 92
    @Autowired
93
    private ActivityRepository activityRepository;
24417 govind 94
 
31762 tejbeer 95
    @Autowired
37559 ranu 96
    private OrderService orderService;
97
 
98
    @Autowired
31762 tejbeer 99
    private ActivityAttachmentRepository activityAttachmentRepository;
27270 tejbeer 100
 
31762 tejbeer 101
    @Autowired
102
    private TicketAssignedRepository ticketAssignedRepository;
24569 govind 103
 
31762 tejbeer 104
    @Autowired
105
    private PartnerRegionRepository partnerRegionRepository;
24500 govind 106
 
31762 tejbeer 107
    @Autowired
32493 amit.gupta 108
    PartnerPositionRepository partnerPositionRepository;
25570 tejbeer 109
 
31762 tejbeer 110
    @Autowired
111
    FofoStoreRepository fofoStoreRepository;
25570 tejbeer 112
 
31762 tejbeer 113
    @Autowired
114
    DocumentRepository documentRepository;
27270 tejbeer 115
 
31762 tejbeer 116
    @GetMapping(value = "/cs/createCategory")
117
    public String getCreateCategory(HttpServletRequest request, Model model) {
118
        List<TicketCategory> ticketCategories = ticketCategoryRepository.selectAll();
119
        model.addAttribute("ticketCategories", ticketCategories);
120
        return "create-ticket-category";
121
    }
24417 govind 122
 
31762 tejbeer 123
    @PostMapping(value = "/cs/createCategory")
33081 ranu 124
    public String createCategory(HttpServletRequest request,
125
                                 @RequestParam(name = "name") String name,
126
                                 @RequestParam(name = "categoryType") int categoryType,
127
                                 @RequestParam(name = "description") String description,
128
                                 Model model) throws ProfitMandiBusinessException {
31762 tejbeer 129
        TicketCategory ticketCategory = ticketCategoryRepository.selectByName(name);
130
        if (ticketCategory != null) {
131
            throw new ProfitMandiBusinessException("name", name, "already exists!");
132
        }
33081 ranu 133
 
31762 tejbeer 134
        ticketCategory = new TicketCategory();
135
        ticketCategory.setName(name);
136
        ticketCategory.setDescription(description);
33081 ranu 137
 
138
        ticketCategory.setCategoryType(categoryType == 1);
31762 tejbeer 139
        ticketCategoryRepository.persist(ticketCategory);
140
        return "create-ticket-category";
141
    }
24417 govind 142
 
33081 ranu 143
 
31762 tejbeer 144
    @GetMapping(value = "/cs/createSubCategory")
145
    public String getCreateSubCategory(HttpServletRequest request, Model model) {
146
        List<TicketCategory> ticketCategories = ticketCategoryRepository.selectAll();
147
        model.addAttribute("ticketCategories", ticketCategories);
148
        return "create-ticket-sub-category";
149
    }
24417 govind 150
 
31762 tejbeer 151
    @GetMapping(value = "/cs/getSubCategoryByCategoryId")
152
    public String getSubCategoryByCategoryId(HttpServletRequest request, @RequestParam(name = "ticketCategoryId", defaultValue = "") int ticketCategoryId, Model model) {
153
        List<TicketSubCategory> ticketSubCategories = ticketSubCategoryRepository.selectAll(ticketCategoryId);
154
        TicketCategory ticketCategory = ticketCategoryRepository.selectById(ticketCategoryId);
33081 ranu 155
        LOGGER.info("ticketSubCategories {}", ticketSubCategories);
156
        LOGGER.info("ticketCategory {}", ticketCategory);
31762 tejbeer 157
        model.addAttribute("ticketSubCategories", ticketSubCategories);
158
        model.addAttribute("ticketCategory", ticketCategory);
159
        return "ticket-sub-category";
160
    }
24417 govind 161
 
31762 tejbeer 162
    @PostMapping(value = "/cs/createSubCategory")
163
    public String createSubCategory(HttpServletRequest request, @RequestParam(name = "categoryId", defaultValue = "0") int categoryId, @RequestParam(name = "name") String name, @RequestParam(name = "description") String description, Model model) throws ProfitMandiBusinessException {
24417 govind 164
 
31762 tejbeer 165
        TicketSubCategory ticketSubCategory = ticketSubCategoryRepository.selectTicketSubCategory(categoryId, name);
166
        if (ticketSubCategory != null) {
167
            throw new ProfitMandiBusinessException("name & categoryId", name + "  " + categoryId, "already exists!");
168
        }
24417 govind 169
 
31762 tejbeer 170
        ticketSubCategory = new TicketSubCategory();
171
        ticketSubCategory.setCategoryId(categoryId);
172
        ticketSubCategory.setName(name);
173
        ticketSubCategory.setDescription(description);
174
        ticketSubCategoryRepository.persist(ticketSubCategory);
175
        return "create-ticket-sub-category";
176
    }
24417 govind 177
 
31762 tejbeer 178
    @GetMapping(value = "/cs/createRegion")
179
    public String createRegion(HttpServletRequest request, Model model) {
180
        List<Region> regions = regionRepository.selectAll();
181
        model.addAttribute("regions", regions);
182
        return "create-region";
183
    }
24417 govind 184
 
31762 tejbeer 185
    @PostMapping(value = "/cs/createRegion")
186
    public String createRegion(HttpServletRequest request, @RequestParam(name = "name") String name, @RequestParam(name = "description") String description, Model model) throws Exception {
187
        Region region = regionRepository.selectByName(name);
188
        if (region != null) {
189
            throw new ProfitMandiBusinessException("name", name, "already exists!");
190
        }
191
        region = new Region();
192
        region.setName(name);
193
        region.setDescription(description);
194
        regionRepository.persist(region);
195
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
196
        return "response";
197
    }
24417 govind 198
 
31762 tejbeer 199
    @GetMapping(value = "/cs/getPartners")
33244 ranu 200
    public String getPartners(HttpServletRequest request, @RequestParam(name = "regionId", defaultValue = "0") int regionId, Model model) throws ProfitMandiBusinessException {
31762 tejbeer 201
        List<Integer> fofoIds = fofoStoreRepository.selectAll().stream().map(x -> x.getId()).collect(Collectors.toList());
202
        List<Integer> addedfofoIds = partnerRegionRepository.selectByRegionId(regionId).stream().map(x -> x.getFofoId()).collect(Collectors.toList());
30426 tejbeer 203
 
31762 tejbeer 204
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
205
        Map<Integer, CustomRetailer> fofoRetailers = fofoIds.stream().map(x -> customRetailerMap.get(x)).filter(x -> x != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
206
        model.addAttribute("fofoRetailers", fofoRetailers);
207
        model.addAttribute("addedfofoIds", addedfofoIds);
208
        return "added-region-partners";
209
    }
24569 govind 210
 
31762 tejbeer 211
    @GetMapping(value = "/cs/getPartnersByRegion")
33244 ranu 212
    public String getPartnersByRegion(HttpServletRequest request, @RequestParam(name = "regionId", defaultValue = "0") int regionId, Model model) throws ProfitMandiBusinessException {
31762 tejbeer 213
        List<Integer> fofoIds = null;
214
        fofoIds = partnerRegionRepository.selectByRegionId(regionId).stream().map(x -> x.getFofoId()).collect(Collectors.toList());
25570 tejbeer 215
 
31762 tejbeer 216
        if (fofoIds.contains(0)) {
217
            fofoIds = fofoStoreRepository.selectAll().stream().filter(x -> x.isActive()).collect(Collectors.toList()).stream().map(x -> x.getId()).collect(Collectors.toList());
25570 tejbeer 218
 
31762 tejbeer 219
        }
220
        Map<Integer, CustomRetailer> customRetailerMap = retailerService.getAllFofoRetailers();
25570 tejbeer 221
 
31762 tejbeer 222
        Map<Integer, CustomRetailer> fofoRetailers = fofoIds.stream().map(x -> customRetailerMap.get(x)).filter(x -> x != null).collect(Collectors.toList()).stream().collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
223
        model.addAttribute("fofoRetailers", fofoRetailers);
224
        return "added-subregion-partners";
225
    }
25570 tejbeer 226
 
31762 tejbeer 227
    @GetMapping(value = "/cs/createPartnerRegion")
228
    public String createPartnerRegion(HttpServletRequest request, Model model) {
229
        List<Region> regions = regionRepository.selectAll();
230
        model.addAttribute("regions", regions);
231
        return "create-partner-region";
232
    }
24417 govind 233
 
31762 tejbeer 234
    @PostMapping(value = "/cs/createPartnerRegion")
235
    public String createPartnerRegion(HttpServletRequest request, @RequestParam(name = "regionId") int regionId, @RequestBody List<Integer> selectedFofoIds, Model model) throws Exception {
236
        partnerRegionRepository.delete(regionId);
237
        LOGGER.info("successfully removed");
238
        LOGGER.info(selectedFofoIds.size());
239
        csService.addPartnerToRegion(regionId, selectedFofoIds);
240
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
241
        return "response";
242
    }
24417 govind 243
 
31762 tejbeer 244
    @GetMapping(value = "/cs/getPosition")
33244 ranu 245
    public String getPosition(HttpServletRequest request, @RequestParam int positionId, Model model) throws ProfitMandiBusinessException {
27410 tejbeer 246
 
31762 tejbeer 247
        Position position = positionRepository.selectById(positionId);
27410 tejbeer 248
 
31762 tejbeer 249
        List<CustomRetailer> positionIdCustomRetailer = csService.getPositionCustomRetailerMap(Arrays.asList(position)).get(position.getId());
27410 tejbeer 250
 
31762 tejbeer 251
        Map<Integer, CustomRetailer> regionRetailerMap = csService.getRegionPartners(Arrays.asList(position)).get(position.getRegionId()).stream().collect(Collectors.toMap(x -> x.getPartnerId(), x -> x));
27410 tejbeer 252
 
31762 tejbeer 253
        model.addAttribute("position", position);
254
        model.addAttribute("regionRetailerMap", regionRetailerMap);
255
        model.addAttribute("positionIdCustomRetailer", positionIdCustomRetailer);
27410 tejbeer 256
 
31762 tejbeer 257
        return "position-partner";
258
    }
27410 tejbeer 259
 
31762 tejbeer 260
    @GetMapping(value = "/cs/createPosition")
261
    public String createPosition(HttpServletRequest request, @RequestParam(name = "offset", defaultValue = "0") int offset, @RequestParam(name = "limit", defaultValue = "10") int limit, Model model) {
262
        List<AuthUser> authUsers = authRepository.selectAllActiveUser();
263
        List<TicketCategory> ticketCategories = ticketCategoryRepository.selectAll();
264
        List<Region> regions = regionRepository.selectAll();
265
        model.addAttribute("escalationTypes", EscalationType.values());
266
        model.addAttribute("authUsers", authUsers);
267
        model.addAttribute("ticketCategories", ticketCategories);
268
        model.addAttribute("regions", regions);
24500 govind 269
 
31762 tejbeer 270
        List<Position> positions = positionRepository.selectAllPosition();
271
        LOGGER.info("positions" + positions);
30426 tejbeer 272
 
31762 tejbeer 273
        Map<Integer, AuthUser> authUserIdAndAuthUserMap = csService.getAuthUserIdAndAuthUserMapUsingPositions(positions);
274
        Map<Integer, TicketCategory> categoryIdAndCategoryMap = csService.getCategoryIdAndCategoryUsingPositions(positions);
275
        Map<Integer, Region> regionIdAndRegionMap = csService.getRegionIdAndRegionMap(positions);
25570 tejbeer 276
 
27410 tejbeer 277
//	    Map<Integer, List<CustomRetailer>> positionIdAndpartnerRegionMap = csService
278
//			.getpositionIdAndpartnerRegionMap(positions);
25570 tejbeer 279
 
27410 tejbeer 280
//	     Map<Integer, List<CustomRetailer>> addedpositionIdAndCustomRetailerMap = csService
281
//				.getPositionCustomRetailerMap(positions);
282
//		LOGGER.info("fofoIdAndCustomRetailerMap" + addedpositionIdAndCustomRetailerMap);
24500 govind 283
 
31762 tejbeer 284
        model.addAttribute("start", offset + 1);
30426 tejbeer 285
 
31762 tejbeer 286
        model.addAttribute("positions", positions);
287
        model.addAttribute("authUserIdAndAuthUserMap", authUserIdAndAuthUserMap);
288
        model.addAttribute("categoryIdAndCategoryMap", categoryIdAndCategoryMap);
289
        model.addAttribute("regionIdAndRegionMap", regionIdAndRegionMap);
290
        // model.addAttribute("positionIdAndCustomRetailerMap",
291
        // addedpositionIdAndCustomRetailerMap);
292
        // model.addAttribute("positionIdAndpartnerRegionMap",
27410 tejbeer 293
// positionIdAndpartnerRegionMap);
25570 tejbeer 294
 
31762 tejbeer 295
        return "create-position";
296
    }
24500 govind 297
 
31762 tejbeer 298
    @GetMapping(value = "/cs/position-paginated")
299
    public String positionPaginated(HttpServletRequest request, @RequestParam(name = "offset", defaultValue = "0") int offset, @RequestParam(name = "limit", defaultValue = "10") int limit, Model model) {
24500 govind 300
 
31762 tejbeer 301
        List<Position> positions = positionRepository.selectAll(offset, limit);
302
        Map<Integer, AuthUser> authUserIdAndAuthUserMap = csService.getAuthUserIdAndAuthUserMapUsingPositions(positions);
303
        Map<Integer, TicketCategory> categoryIdAndCategoryMap = csService.getCategoryIdAndCategoryUsingPositions(positions);
304
        Map<Integer, Region> regionIdAndRegionMap = csService.getRegionIdAndRegionMap(positions);
305
        /*
306
         * Map<Integer, List<CustomRetailer>> positionIdAndpartnerRegionMap = csService
307
         * .getpositionIdAndpartnerRegionMap(positions);
308
         * 
309
         * Map<Integer, List<CustomRetailer>> addedpositionIdAndCustomRetailerMap =
310
         * csService .getPositionCustomRetailerMap(positions);
311
         */
25570 tejbeer 312
 
31762 tejbeer 313
        model.addAttribute("positions", positions);
314
        model.addAttribute("authUserIdAndAuthUserMap", authUserIdAndAuthUserMap);
315
        model.addAttribute("categoryIdAndCategoryMap", categoryIdAndCategoryMap);
316
        model.addAttribute("regionIdAndRegionMap", regionIdAndRegionMap);
317
        // model.addAttribute("positionIdAndCustomRetailerMap",
318
        // addedpositionIdAndCustomRetailerMap);
319
        // model.addAttribute("positionIdAndpartnerRegionMap",
320
        // positionIdAndpartnerRegionMap);
25570 tejbeer 321
 
31762 tejbeer 322
        return "position-paginated";
323
    }
24417 govind 324
 
31762 tejbeer 325
    @PostMapping(value = "/cs/createPosition")
326
    public String createPosition(HttpServletRequest request, @RequestBody CreatePositionModel createPositionModel, Model model) throws Exception {
24417 govind 327
 
35570 amit 328
        LOGGER.info("partnerPosition" + createPositionModel.isTicketAssigned());
25570 tejbeer 329
 
35570 amit 330
        // Validate authUserId exists
331
        int authUserId = createPositionModel.getAuthUserId();
332
        if (authUserId <= 0 || authRepository.selectById(authUserId) == null) {
333
            throw new ProfitMandiBusinessException("Position", authUserId, "Invalid authUserId");
334
        }
335
 
336
        // Validate categoryId exists (0 means "All Categories")
337
        int categoryId = createPositionModel.getCategoryId();
338
        if (categoryId > 0 && ticketCategoryRepository.selectById(categoryId) == null) {
339
            throw new ProfitMandiBusinessException("Position", categoryId, "Invalid categoryId");
340
        }
341
 
342
        // Validate regionId exists (0 or 5 typically means "All Partners/Regions")
343
        int regionId = createPositionModel.getRegionId();
344
        if (regionId > 0 && regionId != 5 && regionRepository.selectById(regionId) == null) {
345
            throw new ProfitMandiBusinessException("Position", regionId, "Invalid regionId");
346
        }
347
 
37003 ranu 348
        // Partners are optional — a position can be created for a region that doesn't have
349
        // partners yet (e.g., a newly opened region). Partners can be added later via
350
        // /cs/updatePartnerPosition. When provided, validate the list; when empty, skip.
35570 amit 351
        List<Integer> fofoIds = createPositionModel.getFofoIds();
37003 ranu 352
        boolean hasAllPartners = fofoIds != null && fofoIds.contains(0);
35590 amit 353
        if (hasAllPartners && fofoIds.size() > 1) {
354
            throw new ProfitMandiBusinessException("Position", 0, "Cannot mix 'All Partners' (0) with specific partner IDs");
355
        }
37003 ranu 356
        if (fofoIds != null && !fofoIds.isEmpty() && !hasAllPartners) {
35590 amit 357
            Map<Integer, CustomRetailer> validRetailers = retailerService.getFofoRetailers(false);
358
            for (int fofoId : fofoIds) {
359
                if (!validRetailers.containsKey(fofoId)) {
360
                    throw new ProfitMandiBusinessException("Position", fofoId, "Invalid fofoId");
35570 amit 361
                }
362
            }
363
        }
364
 
365
        Position position = positionRepository.selectPosition(authUserId, categoryId, regionId, createPositionModel.getEscalationType());
31762 tejbeer 366
        if (position == null) {
367
            position = new Position();
35570 amit 368
            position.setAuthUserId(authUserId);
369
            position.setCategoryId(categoryId);
31762 tejbeer 370
            position.setEscalationType(createPositionModel.getEscalationType());
35570 amit 371
            position.setRegionId(regionId);
31762 tejbeer 372
            position.setCreateTimestamp(LocalDateTime.now());
373
            position.setTicketAssignee(createPositionModel.isTicketAssigned());
374
            positionRepository.persist(position);
25570 tejbeer 375
 
35570 amit 376
            if (fofoIds != null) {
377
                for (int fofoId : fofoIds) {
378
                    PartnerPosition partnerPosition = new PartnerPosition();
379
                    partnerPosition.setFofoId(fofoId);
380
                    partnerPosition.setRegionId(regionId);
381
                    partnerPosition.setPositionId(position.getId());
382
                    partnerPositionRepository.persist(partnerPosition);
383
                    LOGGER.info("partnerPosition" + partnerPosition);
384
                }
31762 tejbeer 385
            }
24417 govind 386
 
31762 tejbeer 387
            model.addAttribute("response1", mvcResponseSender.createResponseString(true));
388
        } else {
35570 amit 389
            throw new ProfitMandiBusinessException("Position", authUserId, "already exists!");
31762 tejbeer 390
        }
391
        return "response";
392
    }
25570 tejbeer 393
 
31762 tejbeer 394
    @PostMapping(value = "/cs/updatePartnerPosition")
395
    public String updatePartnerPosition(HttpServletRequest request, @RequestParam(name = "regionId") int regionId, @RequestBody List<Integer> selectedFofoIds, @RequestParam(name = "positionId") int positionId, Model model) throws Exception {
25570 tejbeer 396
 
35571 amit 397
        // Validate positionId exists
398
        Position position = positionRepository.selectById(positionId);
399
        if (position == null) {
400
            throw new ProfitMandiBusinessException("Position", positionId, "Position not found");
401
        }
402
 
403
        // Validate regionId exists (0 or 5 typically means "All Partners/Regions")
404
        if (regionId > 0 && regionId != 5 && regionRepository.selectById(regionId) == null) {
405
            throw new ProfitMandiBusinessException("Position", regionId, "Invalid regionId");
406
        }
407
 
35589 amit 408
        // Validate fofoIds exist (0 means "All Partners")
35590 amit 409
        if (selectedFofoIds == null || selectedFofoIds.isEmpty()) {
410
            throw new ProfitMandiBusinessException("Position", 0, "At least one partner must be specified");
411
        }
412
        boolean hasAllPartners = selectedFofoIds.contains(0);
413
        if (hasAllPartners && selectedFofoIds.size() > 1) {
414
            throw new ProfitMandiBusinessException("Position", 0, "Cannot mix 'All Partners' (0) with specific partner IDs");
415
        }
416
        if (!hasAllPartners) {
35607 amit 417
            // Use direct database query instead of cached retailerService to include newly added partners
418
            Set<Integer> validFofoIds = fofoStoreRepository.selectAll().stream()
419
                    .map(fs -> fs.getId())
420
                    .collect(Collectors.toSet());
35590 amit 421
            for (int fofoId : selectedFofoIds) {
35607 amit 422
                if (!validFofoIds.contains(fofoId)) {
35590 amit 423
                    throw new ProfitMandiBusinessException("Position", fofoId, "Invalid fofoId");
35571 amit 424
                }
425
            }
426
        }
427
 
32493 amit.gupta 428
        partnerPositionRepository.delete(positionId);
35571 amit 429
        if (selectedFofoIds != null) {
430
            for (int fofoId : selectedFofoIds) {
431
                PartnerPosition partnerPosition = new PartnerPosition();
432
                partnerPosition.setFofoId(fofoId);
433
                partnerPosition.setRegionId(regionId);
434
                partnerPosition.setPositionId(positionId);
435
                partnerPositionRepository.persist(partnerPosition);
436
            }
31762 tejbeer 437
        }
25570 tejbeer 438
 
31762 tejbeer 439
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
25570 tejbeer 440
 
31762 tejbeer 441
        return "response";
442
    }
24417 govind 443
 
31762 tejbeer 444
    @GetMapping(value = "/cs/createTicket")
445
    public String createTicket(HttpServletRequest request, Model model) throws ProfitMandiBusinessException {
446
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
35594 amit 447
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
448
        boolean isCrmUser = false;
449
 
31762 tejbeer 450
        List<TicketCategory> ticketCategories = csService.getAllTicketCategotyFromSubCategory();
35594 amit 451
 
452
        if (isAdmin) {
453
            AuthUser currentAuthUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
454
            isCrmUser = positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
455
 
456
            // CRM users should not see Sales and RBM categories
457
            if (isCrmUser) {
458
                ticketCategories = ticketCategories.stream()
459
                        .filter(tc -> tc.getId() != ProfitMandiConstants.TICKET_CATEGORY_SALES
460
                                && tc.getId() != ProfitMandiConstants.TICKET_CATEGORY_RBM)
461
                        .collect(Collectors.toList());
462
            }
35626 amit 463
        } else {
464
            // For partners/customers: hide categories where ALL subcategories are invisible
465
            ticketCategories = ticketCategories.stream()
466
                    .filter(category -> {
467
                        List<TicketSubCategory> subs = ticketSubCategoryRepository.selectAll(category.getId());
468
                        // Keep category if at least one subcategory is visible
469
                        return subs.stream().anyMatch(TicketSubCategory::isVisibility);
470
                    })
471
                    .collect(Collectors.toList());
35594 amit 472
        }
473
 
474
        model.addAttribute("roleType", isAdmin);
31762 tejbeer 475
        model.addAttribute("ticketCategories", ticketCategories);
35594 amit 476
        model.addAttribute("isCrmUser", isCrmUser);
31762 tejbeer 477
        return "create-ticket";
478
    }
24417 govind 479
 
31762 tejbeer 480
    @GetMapping(value = "/cs/getSubCategoriesByCategoryId")
35594 amit 481
    public String getSubCategoriesByCategoryId(HttpServletRequest request, @RequestParam(name = "categoryId", defaultValue = "0") int categoryId, Model model) throws ProfitMandiBusinessException {
482
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
483
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
484
        boolean isCrmUser = false;
485
 
486
        if (isAdmin) {
487
            AuthUser currentAuthUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
488
            isCrmUser = positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
489
        }
490
 
31830 amit.gupta 491
        List<TicketSubCategory> ticketSubCategories = ticketSubCategoryRepository.selectAllVisible(categoryId);
35594 amit 492
 
35617 amit 493
        // CRM users should not see invisible subcategories
35594 amit 494
        if (isCrmUser) {
495
            ticketSubCategories = ticketSubCategories.stream()
35617 amit 496
                    .filter(TicketSubCategory::isVisibility)
35594 amit 497
                    .collect(Collectors.toList());
498
        }
499
 
31762 tejbeer 500
        LOGGER.info(ticketSubCategories);
501
        model.addAttribute("ticketSubCategories", ticketSubCategories);
502
        return "ticket-sub-categories";
503
    }
24417 govind 504
 
24791 govind 505
 
31762 tejbeer 506
    @GetMapping(value = "/cs/getEscalationTypeByCategoryId")
507
    public String getEscalationTypeByCategoryId(HttpServletRequest request, @RequestParam(name = "categoryId", defaultValue = "0") int categoryId, @RequestParam(name = "authId", defaultValue = "0") int authId, Model model) {
508
        List<Position> positions = positionRepository.selectPositionbyCategoryIdAndAuthId(categoryId, authId);
509
        List<EscalationType> escalationTypes = new ArrayList<>();
24791 govind 510
 
31762 tejbeer 511
        if (!positions.isEmpty()) {
512
            escalationTypes = positions.stream().map(x -> x.getEscalationType()).distinct().collect(Collectors.toList());
513
        }
24620 govind 514
 
31762 tejbeer 515
        LOGGER.info("escalationTypes {}", escalationTypes);
24500 govind 516
 
31762 tejbeer 517
        model.addAttribute("escalationTypes", escalationTypes);
518
        return "ticket-escalationtype";
519
    }
24500 govind 520
 
24824 govind 521
 
31762 tejbeer 522
    @GetMapping(value = "/cs/getCategoriesByAuthId")
523
    public String getCategoriesByAuthId(HttpServletRequest request, @RequestParam(name = "authId", defaultValue = "0") int authId, Model model) {
24824 govind 524
 
24787 govind 525
 
31762 tejbeer 526
        List<Position> positions = positionRepository.selectPositionByAuthId(authId);
24791 govind 527
 
31762 tejbeer 528
        LOGGER.info("positions {}", positions);
24417 govind 529
 
31762 tejbeer 530
        List<TicketCategory> ticketCategories = new ArrayList<TicketCategory>();
24417 govind 531
 
31762 tejbeer 532
        if (!positions.isEmpty()) {
24417 govind 533
 
31762 tejbeer 534
            List<Integer> categoryIds = positions.stream().map(x -> x.getCategoryId()).collect(Collectors.toList());
535
            ticketCategories = ticketCategoryRepository.selectAll(categoryIds);
536
        }
537
        LOGGER.info("ticketCategories {}", ticketCategories);
538
        model.addAttribute("ticketCategories", ticketCategories);
539
        return "ticket-categories";
540
    }
27270 tejbeer 541
 
31762 tejbeer 542
    @PostMapping(value = "/cs/createTicket")
543
    public String createTicket(HttpServletRequest request, @RequestParam(name = "categoryId") int categoryId, @RequestParam(name = "subCategoryId") int subCategoryId, @RequestParam(name = "message") String message, Model model) throws Exception {
544
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
545
        List<Ticket> tickets = ticketRepository.selectAllResolvedMarkedTicketByCreator(loginDetails.getFofoId());
546
        if (tickets.size() > 3 || tickets.size() == 3) {
547
            model.addAttribute("response1", mvcResponseSender.createResponseString(false));
548
        } else {
549
            csService.createTicket(loginDetails.getFofoId(), categoryId, subCategoryId, message);
550
            model.addAttribute("response1", mvcResponseSender.createResponseString(true));
551
        }
552
        return "response";
553
    }
27270 tejbeer 554
 
31762 tejbeer 555
    @GetMapping(value = "/cs/myticket")
35626 amit 556
    public String getTicket(HttpServletRequest request,
557
                            @RequestParam(name = "orderby", defaultValue = "DESCENDING") SortOrder sortOrder,
558
                            @RequestParam(name = "ticketStatus", defaultValue = "OPENED") TicketStatus ticketStatus,
559
                            @RequestParam(name = "ticketSearchType", defaultValue = "") TicketSearchType ticketSearchType,
560
                            @RequestParam(name = "searchTerm", defaultValue = "0") int searchTerm,
561
                            @RequestParam(name = "page", defaultValue = "0") int page,
562
                            @RequestParam(name = "pageSize", defaultValue = "25") int pageSize,
563
                            @RequestParam(name = "search", required = false) String searchText,
564
                            Model model) throws ProfitMandiBusinessException {
565
        populateMyTicketModel(request, sortOrder, ticketStatus, ticketSearchType, searchTerm, page, pageSize, searchText, model);
566
        return "ticket";
567
    }
568
 
569
    @GetMapping(value = "/cs/myticket-content")
570
    public String getTicketContent(HttpServletRequest request,
571
                                   @RequestParam(name = "orderby", defaultValue = "DESCENDING") SortOrder sortOrder,
572
                                   @RequestParam(name = "ticketStatus", defaultValue = "OPENED") TicketStatus ticketStatus,
573
                                   @RequestParam(name = "ticketSearchType", defaultValue = "") TicketSearchType ticketSearchType,
574
                                   @RequestParam(name = "searchTerm", defaultValue = "0") int searchTerm,
575
                                   @RequestParam(name = "page", defaultValue = "0") int page,
576
                                   @RequestParam(name = "pageSize", defaultValue = "25") int pageSize,
577
                                   @RequestParam(name = "search", required = false) String searchText,
578
                                   Model model) throws ProfitMandiBusinessException {
579
        populateMyTicketModel(request, sortOrder, ticketStatus, ticketSearchType, searchTerm, page, pageSize, searchText, model);
580
        return "ticket-content";
581
    }
582
 
37559 ranu 583
    private static String nvl(String s) {
584
        return s == null ? "" : s;
585
    }
586
 
587
    // Download every ticket the user can see in the current filter (respects ticketStatus /
588
    // sortOrder / search — but ignores pagination) as CSV with the same 8 columns rendered
589
    // in ticket-content.vm: Ticket Id, Partner, Category, SubCategory, Message, Created By,
590
    // Assigned To, Created TimeStamp.
591
    @GetMapping(value = "/cs/downloadMyTickets")
592
    public ResponseEntity<?> downloadMyTickets(HttpServletRequest request,
593
                                               @RequestParam(name = "orderby", defaultValue = "DESCENDING") SortOrder sortOrder,
594
                                               @RequestParam(name = "ticketStatus", defaultValue = "OPENED") TicketStatus ticketStatus,
595
                                               @RequestParam(name = "ticketSearchType", defaultValue = "") TicketSearchType ticketSearchType,
596
                                               @RequestParam(name = "searchTerm", defaultValue = "0") int searchTerm,
597
                                               @RequestParam(name = "search", required = false) String searchText) throws Exception {
598
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
599
        boolean isAdmin = roleManager.isAdmin(new HashSet<>(loginDetails.getRoleIds()));
600
        AuthUser currentAuthUser = isAdmin ? authRepository.selectByEmailOrMobile(loginDetails.getEmailId()) : null;
601
        boolean isCrmUser = isAdmin && currentAuthUser != null
602
                && positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
603
        List<Integer> userCategoryIds = isAdmin && currentAuthUser != null
604
                ? positionRepository.selectCategoryIdsByAuthUserId(currentAuthUser.getId())
605
                : Collections.emptyList();
606
 
607
        List<Ticket> tickets;
608
        if (isAdmin) {
609
            int authUserId = currentAuthUser.getId();
610
            Optional<Boolean> resolvedOpt = ticketStatus.equals(TicketStatus.RESOLVED)
611
                    ? Optional.empty()
612
                    : Optional.of(TicketStatus.CLOSED.equals(ticketStatus));
613
            long total;
614
            if (isCrmUser) {
615
                total = ticketRepository.selectAllTicketsPaginatedCount(
616
                        resolvedOpt, ticketSearchType, searchTerm, searchText, userCategoryIds);
617
                tickets = ticketRepository.selectAllTicketsPaginated(
618
                        resolvedOpt, sortOrder, ticketSearchType, searchTerm, searchText,
619
                        userCategoryIds, 0, (int) Math.max(1L, total));
620
            } else {
621
                total = ticketRepository.selectAllByAssigneePaginatedCount(
622
                        authUserId, resolvedOpt, ticketSearchType, searchTerm, searchText);
623
                tickets = ticketRepository.selectAllByAssigneePaginated(
624
                        authUserId, resolvedOpt, sortOrder, ticketSearchType, searchTerm, searchText,
625
                        0, (int) Math.max(1L, total));
626
            }
627
        } else {
628
            tickets = ticketRepository.selectAllByCreator(
629
                    loginDetails.getFofoId(),
630
                    Optional.of(TicketStatus.OPENED.equals(ticketStatus)),
631
                    sortOrder);
632
        }
633
        if (tickets == null) tickets = new ArrayList<>();
37560 ranu 634
        return renderTicketsAsCsv(tickets, "Tickets_" + ticketStatus.name());
635
    }
37559 ranu 636
 
37560 ranu 637
    // Download every manager ticket the current user can see in the panel's filter —
638
    // tickets escalated to this user (or all tickets in the user's categories for CRM).
639
    // Requires L2+ position, mirroring populateManagerTicketModel.
640
    @GetMapping(value = "/cs/downloadManagerTickets")
641
    public ResponseEntity<?> downloadManagerTickets(HttpServletRequest request,
642
                                                    @RequestParam(name = "orderby", defaultValue = "DESCENDING") SortOrder sortOrder,
643
                                                    @RequestParam(name = "ticketStatus", defaultValue = "OPENED") TicketStatus ticketStatus,
644
                                                    @RequestParam(name = "ticketSearchType", defaultValue = "") TicketSearchType ticketSearchType,
645
                                                    @RequestParam(name = "searchTerm", defaultValue = "0") int searchTerm,
646
                                                    @RequestParam(name = "search", required = false) String searchText) throws Exception {
647
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
648
        AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
649
 
650
        List<Position> positions = positionRepository.selectAllByAuthUserId(authUser.getId());
651
        boolean isAboveL1 = positions.stream().anyMatch(p -> p.getEscalationType() != EscalationType.L1);
652
        if (!isAboveL1) {
653
            throw new ProfitMandiBusinessException("ManagerTicket", 0, "Access denied: requires at least L2 position");
654
        }
655
        boolean isCrmUser = positionRepository.hasCategory(authUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
656
        List<Integer> userCategoryIds = positionRepository.selectCategoryIdsByAuthUserId(authUser.getId());
657
        Optional<Boolean> resolvedOpt = ticketStatus.equals(TicketStatus.RESOLVED)
658
                ? Optional.empty()
659
                : Optional.of(TicketStatus.CLOSED.equals(ticketStatus));
660
 
661
        List<Ticket> tickets;
662
        long total;
663
        if (isCrmUser) {
664
            total = ticketRepository.selectAllTicketsPaginatedCount(
665
                    resolvedOpt, ticketSearchType, searchTerm, searchText, userCategoryIds);
666
            tickets = ticketRepository.selectAllTicketsPaginated(
667
                    resolvedOpt, sortOrder, ticketSearchType, searchTerm, searchText,
668
                    userCategoryIds, 0, (int) Math.max(1L, total));
669
        } else {
670
            total = ticketRepository.selectAllCountByManagerTicketPaginated(
671
                    authUser.getId(), resolvedOpt, ticketSearchType, searchTerm, searchText);
672
            tickets = ticketRepository.selectAllManagerTicketPaginated(
673
                    authUser.getId(), sortOrder, resolvedOpt, ticketSearchType, searchTerm, searchText,
674
                    0, (int) Math.max(1L, total));
675
        }
676
        if (tickets == null) tickets = new ArrayList<>();
677
        return renderTicketsAsCsv(tickets, "ManagerTickets_" + ticketStatus.name());
678
    }
679
 
680
    // Download every partner ticket the current user is a store-guy for. Mirrors
681
    // populateMyPartnerTicketModel: always OPEN + drops RESOLVED via lastActivity check.
682
    @GetMapping(value = "/cs/downloadPartnerTickets")
683
    public ResponseEntity<?> downloadPartnerTickets(HttpServletRequest request) throws Exception {
684
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
685
        AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
686
 
687
        List<Ticket> tickets = new ArrayList<>();
688
        Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();
689
        Set<Integer> fofoIds = storeGuyMap.get(authUser.getEmailId());
690
 
691
        if (fofoIds != null && !fofoIds.isEmpty()) {
692
            List<Ticket> allPartnerTickets = ticketRepository.selectAllOpenTickets(new ArrayList<>(fofoIds));
693
            if (allPartnerTickets != null && !allPartnerTickets.isEmpty()) {
694
                tickets = allPartnerTickets.stream()
695
                        .filter(t -> t.getLastActivity() == null || t.getLastActivity() != ActivityType.RESOLVED)
696
                        .collect(Collectors.toList());
697
            }
698
        }
699
        return renderTicketsAsCsv(tickets, "PartnerTickets_OPENED");
700
    }
701
 
702
    // Shared row-builder + CSV render for the three download endpoints. Given a ticket
703
    // list, resolves every display field (partner, category, sub-category, first + last
704
    // activity, assignees) and returns the CSV response.
705
    private ResponseEntity<?> renderTicketsAsCsv(List<Ticket> tickets, String fileNamePrefix) throws Exception {
37559 ranu 706
        List<Integer> subCategoryIds = tickets.stream().map(Ticket::getSubCategoryId).collect(Collectors.toList());
707
        Map<Integer, TicketSubCategory> subMap = csService.getSubCategoryIdAndSubCategoryMap(subCategoryIds);
708
        if (subMap == null) subMap = new HashMap<>();
709
        Map<Integer, TicketCategory> catMap = csService.getSubCategoryIdAndCategoryMap(subCategoryIds);
710
        if (catMap == null) catMap = new HashMap<>();
711
        Map<Integer, CustomRetailer> partnerMap = tickets.isEmpty()
712
                ? new HashMap<>()
713
                : csService.getPartnerByFofoIds(tickets);
714
        if (partnerMap == null) partnerMap = new HashMap<>();
715
        Map<Integer, List<AuthUser>> assigneeListMap = csService.getAssignedAuthList(tickets);
716
        if (assigneeListMap == null) assigneeListMap = new HashMap<>();
717
        Map<Integer, AuthUser> authUserIdMap = csService.getTicketIdAndAuthUserMapUsingTickets(tickets);
718
        if (authUserIdMap == null) authUserIdMap = new HashMap<>();
719
 
720
        List<Integer> ticketIds = tickets.stream().map(Ticket::getId).collect(Collectors.toList());
721
        Map<Integer, Activity> lastMessageMap = ticketIds.isEmpty()
722
                ? new HashMap<>()
723
                : csService.getLastMessageActivitiesForTickets(ticketIds);
724
        if (lastMessageMap == null) lastMessageMap = new HashMap<>();
725
 
726
        List<Activity> allActs = ticketIds.isEmpty()
727
                ? new ArrayList<>()
728
                : activityRepository.selectAll(ticketIds);
729
        Map<Integer, List<Activity>> activityByTicket = allActs.stream()
730
                .collect(Collectors.groupingBy(Activity::getTicketId));
731
        Map<Integer, Activity> activityById = allActs.stream()
732
                .collect(Collectors.toMap(Activity::getId, x -> x, (a, b) -> a));
733
 
734
        Set<Integer> creatorIds = new HashSet<>();
735
        for (Activity a : allActs) if (a.getCreatedBy() > 0) creatorIds.add(a.getCreatedBy());
736
        for (Activity a : lastMessageMap.values()) if (a.getCreatedBy() > 0) creatorIds.add(a.getCreatedBy());
737
        Map<Integer, AuthUser> authUserMap = creatorIds.isEmpty()
738
                ? new HashMap<>()
739
                : authRepository.selectByIds(new ArrayList<>(creatorIds)).stream()
740
                .collect(Collectors.toMap(AuthUser::getId, x -> x));
741
 
742
        List<List<?>> rows = new ArrayList<>();
743
        for (Ticket t : tickets) {
744
            int id = t.getId();
745
            CustomRetailer cr = partnerMap.get(t.getFofoId());
746
            String partner = cr != null ? nvl(cr.getBusinessName()) : "";
747
            TicketCategory cat = catMap.get(t.getSubCategoryId());
748
            String category = cat != null ? nvl(cat.getName()) : "";
749
            TicketSubCategory sub = subMap.get(t.getSubCategoryId());
750
            String subCategory = sub != null ? nvl(sub.getName()) : "";
751
 
752
            String message = "-";
753
            Activity msgAct = lastMessageMap.get(id);
754
            if (msgAct == null) {
755
                List<Activity> list = activityByTicket.get(id);
756
                if (list != null && !list.isEmpty()) msgAct = list.get(0);
757
            }
758
            if (msgAct != null) {
759
                String prefix = "~Partner";
760
                if (msgAct.getCreatedBy() > 0 && authUserMap.get(msgAct.getCreatedBy()) != null) {
761
                    prefix = "~" + nvl(authUserMap.get(msgAct.getCreatedBy()).getFirstName());
762
                }
763
                message = prefix + " " + nvl(msgAct.getMessage());
764
            }
765
 
766
            String createdBy = "Partner";
767
            Activity firstAct = activityById.get(t.getFirstActivityId());
768
            if (firstAct != null && firstAct.getCreatedBy() > 0) {
769
                AuthUser u = authUserMap.get(firstAct.getCreatedBy());
770
                if (u != null) createdBy = (nvl(u.getFirstName()) + " " + nvl(u.getLastName())).trim();
771
            }
772
 
773
            String assignedTo = "";
774
            List<AuthUser> assignees = assigneeListMap.get(id);
775
            if (assignees != null && !assignees.isEmpty()) {
776
                assignedTo = assignees.stream()
777
                        .map(u -> (nvl(u.getFirstName()) + " " + nvl(u.getLastName())).trim())
778
                        .collect(Collectors.joining(", "));
779
            } else if (authUserIdMap.get(id) != null) {
780
                AuthUser a = authUserIdMap.get(id);
781
                assignedTo = (nvl(a.getFirstName()) + " " + nvl(a.getLastName())).trim();
782
            }
783
 
784
            String createdTs = t.getFormattedCreateTimestamp() != null ? t.getFormattedCreateTimestamp() : "";
785
            rows.add(Arrays.asList(id, partner, category, subCategory, message, createdBy, assignedTo, createdTs));
786
        }
787
 
788
        org.apache.commons.io.output.ByteArrayOutputStream baos = FileUtil.getCSVByteStream(
789
                Arrays.asList("Ticket Id", "Partner", "Category", "SubCategory", "Message",
790
                        "Created By", "Assigned To", "Created TimeStamp"),
791
                rows);
37560 ranu 792
        return orderService.downloadReportInCsv(baos, rows, fileNamePrefix);
37559 ranu 793
    }
794
 
35626 amit 795
    private void populateMyTicketModel(HttpServletRequest request, SortOrder sortOrder, TicketStatus ticketStatus,
796
                                       TicketSearchType ticketSearchType, int searchTerm, int page, int pageSize,
797
                                       String searchText, Model model) throws ProfitMandiBusinessException {
31762 tejbeer 798
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
799
        List<Ticket> tickets = null;
800
        List<TicketAssigned> ticketAssigneds = null;
35626 amit 801
        long totalRecords = 0;
31762 tejbeer 802
        Map<Integer, AuthUser> authUserIdAndAuthUserMap = null;
35569 amit 803
        boolean isAdmin = roleManager.isAdmin(new HashSet<>(loginDetails.getRoleIds()));
804
        AuthUser currentAuthUser = isAdmin ? authRepository.selectByEmailOrMobile(loginDetails.getEmailId()) : null;
805
 
35592 amit 806
        boolean isCrmUser = isAdmin && currentAuthUser != null && positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
35603 amit 807
        boolean isSalesUser = isAdmin && currentAuthUser != null && positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_SALES);
808
        boolean isRbmUser = isAdmin && currentAuthUser != null && positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_RBM);
35592 amit 809
 
35626 amit 810
        List<Integer> userCategoryIds = isAdmin && currentAuthUser != null
811
                ? positionRepository.selectCategoryIdsByAuthUserId(currentAuthUser.getId())
812
                : Collections.emptyList();
813
 
814
        int offset = page * pageSize;
815
 
35569 amit 816
        if (isAdmin) {
817
            int authUserId = currentAuthUser.getId();
35592 amit 818
 
819
            if (isCrmUser) {
35626 amit 820
                Optional<Boolean> resolvedOpt = ticketStatus.equals(TicketStatus.RESOLVED) ? Optional.empty() : Optional.of(TicketStatus.CLOSED.equals(ticketStatus));
821
                tickets = ticketRepository.selectAllTicketsPaginated(
822
                        resolvedOpt, sortOrder, ticketSearchType, searchTerm, searchText,
823
                        userCategoryIds, offset, pageSize);
824
                totalRecords = ticketRepository.selectAllTicketsPaginatedCount(
825
                        resolvedOpt, ticketSearchType, searchTerm, searchText, userCategoryIds);
31762 tejbeer 826
            } else {
35626 amit 827
                Optional<Boolean> resolvedOpt = ticketStatus.equals(TicketStatus.RESOLVED) ? Optional.empty() : Optional.of(TicketStatus.CLOSED.equals(ticketStatus));
828
                tickets = ticketRepository.selectAllByAssigneePaginated(
829
                        authUserId, resolvedOpt, sortOrder, ticketSearchType, searchTerm, searchText,
830
                        offset, pageSize);
831
                totalRecords = ticketRepository.selectAllByAssigneePaginatedCount(
832
                        authUserId, resolvedOpt, ticketSearchType, searchTerm, searchText);
31762 tejbeer 833
            }
35626 amit 834
 
31762 tejbeer 835
            if (tickets.size() > 0) {
836
                ticketAssigneds = ticketAssignedRepository.selectByTicketIds(tickets.stream().map(x -> x.getId()).collect(Collectors.toList()));
837
                authUserIdAndAuthUserMap = csService.getAuthUserIdAndAuthUserMap(ticketAssigneds);
838
                Map<Integer, CustomRetailer> fofoIdsAndCustomRetailer = csService.getPartnerByFofoIds(tickets);
839
                model.addAttribute("fofoIdsAndCustomRetailer", fofoIdsAndCustomRetailer);
840
            }
24500 govind 841
 
31762 tejbeer 842
        } else {
843
            tickets = ticketRepository.selectAllByCreator(loginDetails.getFofoId(), Optional.of(TicketStatus.OPENED.equals(ticketStatus)), sortOrder);
35626 amit 844
            totalRecords = ticketRepository.selectAllCountByCreator(loginDetails.getFofoId(), Optional.of(TicketStatus.OPENED.equals(ticketStatus)));
31762 tejbeer 845
        }
846
        authUserIdAndAuthUserMap = csService.getTicketIdAndAuthUserMapUsingTickets(tickets);
35571 amit 847
        if (authUserIdAndAuthUserMap == null) {
848
            authUserIdAndAuthUserMap = new HashMap<>();
849
        }
24620 govind 850
 
36040 ranu 851
        Map<Integer, List<AuthUser>> authUserListMap = csService.getAssignedAuthList(tickets);
852
        if (authUserListMap == null) {
853
            authUserListMap = new HashMap<>();
854
        }
855
 
35626 amit 856
        int totalPages = (int) Math.ceil((double) totalRecords / pageSize);
857
        if (totalPages == 0) totalPages = 1;
858
        int startRecord = totalRecords > 0 ? offset + 1 : 0;
859
        int endRecord = (int) Math.min(offset + pageSize, totalRecords);
860
 
861
        model.addAttribute("size", totalRecords);
862
        model.addAttribute("totalRecords", totalRecords);
863
        model.addAttribute("currentPage", page);
864
        model.addAttribute("pageSize", pageSize);
865
        model.addAttribute("totalPages", totalPages);
866
        model.addAttribute("startRecord", startRecord);
867
        model.addAttribute("endRecord", endRecord);
868
        model.addAttribute("searchText", searchText != null ? searchText : "");
869
        model.addAttribute("currentPageDisplay", page + 1);
870
        model.addAttribute("prevPage", page - 1);
871
        model.addAttribute("nextPage", page + 1);
872
        model.addAttribute("lastPage", totalPages - 1);
873
 
35569 amit 874
        model.addAttribute("roleType", isAdmin);
875
        model.addAttribute("isCrmUser", isCrmUser);
35603 amit 876
        model.addAttribute("isSalesUser", isSalesUser);
877
        model.addAttribute("salesCategoryId", ProfitMandiConstants.TICKET_CATEGORY_SALES);
878
        model.addAttribute("isRbmUser", isRbmUser);
879
        model.addAttribute("rbmCategoryId", ProfitMandiConstants.TICKET_CATEGORY_RBM);
35626 amit 880
        model.addAttribute("userCategoryIds", userCategoryIds);
24500 govind 881
 
31762 tejbeer 882
        List<Integer> subCategoryIds = tickets.stream().map(x -> x.getSubCategoryId()).collect(Collectors.toList());
883
        Map<Integer, TicketSubCategory> subCategoryIdAndSubCategoryMap = csService.getSubCategoryIdAndSubCategoryMap(subCategoryIds);
35571 amit 884
        if (subCategoryIdAndSubCategoryMap == null) {
885
            subCategoryIdAndSubCategoryMap = new HashMap<>();
886
        }
24747 govind 887
 
31762 tejbeer 888
        Map<Integer, TicketCategory> subCategoryIdAndCategoryMap = csService.getSubCategoryIdAndCategoryMap(subCategoryIds);
35571 amit 889
        if (subCategoryIdAndCategoryMap == null) {
890
            subCategoryIdAndCategoryMap = new HashMap<>();
891
        }
27318 amit.gupta 892
 
31762 tejbeer 893
        List<Integer> ticketIds = tickets.stream().map(x -> x.getId()).collect(Collectors.toList());
24500 govind 894
 
35569 amit 895
        Map<Integer, List<Activity>> activityMap = new HashMap<>();
33864 ranu 896
        Map<Integer, List<Activity>> activityMapWithActivityId = new HashMap<>();
35569 amit 897
        Map<Integer, AuthUser> authUserMap = new HashMap<>();
24500 govind 898
 
31762 tejbeer 899
        if (!ticketIds.isEmpty()) {
35569 amit 900
            List<Activity> allActivities = activityRepository.selectAll(ticketIds);
901
            activityMap = allActivities.stream().collect(Collectors.groupingBy(Activity::getTicketId));
902
            activityMapWithActivityId = allActivities.stream().collect(Collectors.groupingBy(Activity::getId));
24787 govind 903
 
35569 amit 904
            Set<Integer> activityCreatorIds = allActivities.stream()
905
                    .map(Activity::getCreatedBy)
906
                    .filter(id -> id > 0)
907
                    .collect(Collectors.toSet());
908
            if (!activityCreatorIds.isEmpty()) {
909
                authUserMap = authRepository.selectByIds(new ArrayList<>(activityCreatorIds))
910
                        .stream().collect(Collectors.toMap(AuthUser::getId, x -> x));
911
            }
31762 tejbeer 912
        }
24787 govind 913
 
35626 amit 914
        int currentUserId;
915
        UserType currentUserType;
916
        if (isAdmin) {
917
            currentUserId = currentAuthUser.getId();
918
            currentUserType = UserType.AUTH_USER;
919
        } else {
920
            currentUserId = loginDetails.getFofoId();
921
            currentUserType = UserType.PARTNER;
922
        }
923
        Map<Integer, Boolean> unreadMap = csService.getUnreadStatusForTickets(tickets, currentUserId, currentUserType);
924
        Map<Integer, Activity> lastActivityMap = csService.getLastActivitiesForTickets(ticketIds);
35640 amit 925
        Map<Integer, Activity> lastMessageMap = csService.getLastMessageActivitiesForTickets(ticketIds);
35626 amit 926
        model.addAttribute("unreadMap", unreadMap);
927
        model.addAttribute("lastActivityMap", lastActivityMap);
35640 amit 928
        model.addAttribute("lastMessageMap", lastMessageMap);
35626 amit 929
 
31762 tejbeer 930
        model.addAttribute("tickets", tickets);
931
        model.addAttribute("resolved", ActivityType.RESOLVED);
932
        model.addAttribute("resolved-accepted", ActivityType.RESOLVED_ACCEPTED);
933
        model.addAttribute("resolved-rejected", ActivityType.RESOLVED_REJECTED);
934
        model.addAttribute("authUserIdAndAuthUserMap", authUserIdAndAuthUserMap);
36040 ranu 935
        model.addAttribute("authUserListMap", authUserListMap);
31762 tejbeer 936
        model.addAttribute("subCategoryIdAndSubCategoryMap", subCategoryIdAndSubCategoryMap);
27318 amit.gupta 937
 
31762 tejbeer 938
        model.addAttribute("subCategoryIdAndCategoryMap", subCategoryIdAndCategoryMap);
939
        model.addAttribute("activityMap", activityMap);
33864 ranu 940
        model.addAttribute("authUserMap", authUserMap);
941
        model.addAttribute("activityMapWithActivityId", activityMapWithActivityId);
24500 govind 942
 
31762 tejbeer 943
        model.addAttribute("ticketStatusValues", TicketStatus.values());
944
        model.addAttribute("orderByValues", SortOrder.values());
945
        model.addAttribute("selectedticketStatus", ticketStatus);
946
        model.addAttribute("selectedorderby", sortOrder);
947
        model.addAttribute("ticketSearchTypes", TicketSearchType.values());
948
        model.addAttribute("ticketSearchType", ticketSearchType);
949
        model.addAttribute("searchTerm", searchTerm);
950
    }
24500 govind 951
 
27124 amit.gupta 952
 
31762 tejbeer 953
    @GetMapping(value = "/cs/getActivities")
954
    public String getActivity(HttpServletRequest request, @RequestParam(name = "ticketId", defaultValue = "0") int ticketId, Model model) throws Exception {
35592 amit 955
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
956
        Ticket ticket = ticketRepository.selectById(ticketId);
957
 
958
        if (ticket == null) {
959
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Ticket not found");
960
        }
961
 
962
        // Authorization check: verify user has access to this ticket
963
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
964
        if (!isAdmin) {
965
            // Partners can only view their own tickets
966
            if (ticket.getFofoId() != loginDetails.getFofoId()) {
967
                throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to view this ticket");
968
            }
969
        } else {
970
            // Admins must be assigned to the ticket OR be CRM user OR be in the escalation chain
971
            AuthUser currentAuthUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
972
            boolean isCrmUser = positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
973
 
974
            if (!isCrmUser) {
37145 ranu 975
                // Assigned = user was ever the assignee or manager on this ticket (any level).
976
                // The old l1..l5AuthUser fallback check was fully subsumed by this since it
977
                // includes every past TicketAssigned row.
35592 amit 978
                List<TicketAssigned> assignments = ticketAssignedRepository.selectByTicketIds(Arrays.asList(ticketId));
979
                boolean isAssigned = assignments.stream().anyMatch(ta -> ta.getAssineeId() == currentAuthUser.getId() || ta.getManagerId() == currentAuthUser.getId());
980
 
36231 ranu 981
                // Check if user is related to this partner (RBM, ASM, BM etc.)
982
                boolean isRelatedToPartner = false;
37145 ranu 983
                if (!isAssigned) {
36231 ranu 984
                    List<AuthUser> relatedUsers = csService.getAuthUserIdByPartnerId(ticket.getFofoId());
985
                    isRelatedToPartner = relatedUsers.stream()
986
                            .anyMatch(au -> au.getId() == currentAuthUser.getId());
987
                    if (!isRelatedToPartner) {
988
                        throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to view this ticket");
989
                    }
35592 amit 990
                }
36231 ranu 991
 
37145 ranu 992
                // User can view but cannot take action if only related to partner (not assigned)
993
                model.addAttribute("canTakeAction", isAssigned);
35592 amit 994
            }
995
        }
996
 
31762 tejbeer 997
        List<Activity> allactivities = activityRepository.selectAll(ticketId);
35570 amit 998
 
999
        // Batch fetch all documents for attachments (fix N+1 query)
1000
        List<Integer> documentIds = allactivities.stream()
1001
                .flatMap(a -> a.getActivityAttachment().stream())
1002
                .map(ActivityAttachment::getDocumentId)
1003
                .distinct()
1004
                .collect(Collectors.toList());
1005
 
1006
        Map<Integer, Document> documentMap = Collections.emptyMap();
1007
        if (!documentIds.isEmpty()) {
1008
            documentMap = documentRepository.selectByIds(documentIds).stream()
1009
                    .collect(Collectors.toMap(Document::getId, d -> d));
1010
        }
1011
 
1012
        // Set document names transiently (do not persist during GET)
1013
        for (Activity activity : allactivities) {
1014
            for (ActivityAttachment attachment : activity.getActivityAttachment()) {
1015
                Document document = documentMap.get(attachment.getDocumentId());
1016
                if (document != null) {
1017
                    attachment.setDocumentName(document.getDisplayName());
1018
                }
31762 tejbeer 1019
            }
1020
        }
1021
        List<Activity> activities = null;
35592 amit 1022
        if (isAdmin) {
31762 tejbeer 1023
            Set<Integer> authUserIds = allactivities.stream().map(x -> x.getCreatedBy()).collect(Collectors.toSet());
36040 ranu 1024
 
1025
            // Fetch current assignees for this ticket to show in ASSIGNED/ESCALATED activities
1026
            List<TicketAssigned> ticketAssignments = ticketAssignedRepository.selectByTicketIds(Arrays.asList(ticketId));
1027
            Set<Integer> assigneeIds = ticketAssignments.stream()
1028
                    .map(TicketAssigned::getAssineeId)
1029
                    .collect(Collectors.toSet());
1030
            authUserIds.addAll(assigneeIds);
1031
 
35395 amit 1032
            List<AuthUser> users = authRepository.selectByIds(new ArrayList<>(authUserIds));
31762 tejbeer 1033
            Map<Integer, String> authUserNameMap = users.stream().collect(Collectors.toMap(AuthUser::getId, x -> x.getFirstName() + " " + x.getLastName()));
36040 ranu 1034
 
1035
            // Get current assignee name (most recent assignment)
1036
            String currentAssigneeName = null;
1037
            if (!ticketAssignments.isEmpty()) {
1038
                int latestAssigneeId = ticketAssignments.get(ticketAssignments.size() - 1).getAssineeId();
1039
                currentAssigneeName = authUserNameMap.get(latestAssigneeId);
1040
            }
1041
            final String assigneeName = currentAssigneeName;
1042
 
1043
            allactivities.stream().forEach(x -> {
1044
                x.setName(authUserNameMap.get(x.getCreatedBy()));
1045
                // For ASSIGNED/ESCALATED activities, use name field to show assignee
1046
                ActivityType actType = x.getType();
1047
                if (assigneeName != null && (actType == ActivityType.ASSIGNED || actType == ActivityType.ESCALATED || actType == ActivityType.ESCALATED_FINAL)) {
1048
                    x.setName(assigneeName);
1049
                }
1050
            });
31762 tejbeer 1051
            activities = allactivities;
1052
        } else {
1053
            activities = allactivities.stream().filter(x -> ActivityType.PARTNER_ACTIVITIES.contains(x.getType())).collect(Collectors.toList());
1054
        }
1055
        if (activities == null) {
1056
            throw new ProfitMandiBusinessException("Activity", ticketId, "No Activity Found");
1057
        }
1058
        model.addAttribute("response1", mvcResponseSender.createResponseString(activities));
1059
        return "response";
24500 govind 1060
 
31762 tejbeer 1061
    }
24620 govind 1062
 
31762 tejbeer 1063
    @PostMapping(value = "/cs/createActivity")
1064
    public String createActivity(HttpServletRequest request, @RequestParam(name = "ticketId", defaultValue = "0") int ticketId, @RequestParam(name = "assigneeId", defaultValue = "0") int assigneeId, @RequestParam(name = "internal", defaultValue = "true") boolean internal, @RequestParam(name = "message", defaultValue = "") String message, @RequestBody List<Integer> documentIds,
24620 govind 1065
 
31762 tejbeer 1066
                                 Model model) throws Exception {
24620 govind 1067
 
31762 tejbeer 1068
        LOGGER.info("documentIds" + documentIds);
1069
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
1070
        Ticket ticket = ticketRepository.selectById(ticketId);
35592 amit 1071
 
1072
        if (ticket == null) {
1073
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Ticket not found");
1074
        }
1075
 
1076
        // Authorization check: verify user has access to add activity to this ticket
1077
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
1078
        if (!isAdmin) {
1079
            // Partners can only add activity to their own tickets
1080
            if (ticket.getFofoId() != loginDetails.getFofoId()) {
1081
                throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to add activity to this ticket");
1082
            }
1083
        } else {
1084
            // Admins must be assigned to the ticket OR be CRM user OR be in the escalation chain
1085
            AuthUser currentAuthUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
1086
            boolean isCrmUser = positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
1087
 
1088
            if (!isCrmUser) {
1089
                List<TicketAssigned> assignments = ticketAssignedRepository.selectByTicketIds(Arrays.asList(ticketId));
1090
                boolean isAssigned = assignments.stream().anyMatch(ta -> ta.getAssineeId() == currentAuthUser.getId() || ta.getManagerId() == currentAuthUser.getId());
1091
 
37145 ranu 1092
                if (!isAssigned) {
35592 amit 1093
                    throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to add activity to this ticket");
1094
                }
1095
            }
1096
        }
31762 tejbeer 1097
        List<TicketAssigned> ticketAssignedList = ticketAssignedRepository.selectByTicketIds(Arrays.asList(ticketId));
1098
        List<Integer> authUserIds = ticketAssignedList.stream().map(x -> x.getAssineeId()).collect(Collectors.toList());
1099
        authUserIds.add(ticketAssignedList.get(ticketAssignedList.size() - 1).getManagerId());
35395 amit 1100
        Map<Integer, AuthUser> authUsersMap = authRepository.selectByIds(authUserIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
31762 tejbeer 1101
        if (ticket.getCloseTimestamp() == null) {
1102
            Activity activity = new Activity();
1103
            activity.setCreatedBy(0);
1104
            activity.setCreateTimestamp(LocalDateTime.now());
1105
            String subject = null;
1106
            String mailMessage = null;
1107
            activity.setMessage(message);
1108
            if (!roleManager.isAdmin(new HashSet<>(loginDetails.getRoleIds()))) {
1109
                CustomRetailer customRetailer = retailerService.getFofoRetailers(true).get(loginDetails.getFofoId());
1110
                activity.setType(ActivityType.COMMUNICATION_IN);
1111
                subject = String.format("Ticket Update #%s by franchisee %s", ticket.getId(), customRetailer.getBusinessName() + "(" + customRetailer.getCode() + ")");
1112
                mailMessage = String.format("Franchisee message - %s", message);
1113
            } else {
1114
                AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
1115
                activity.setCreatedBy(authUser.getId());
1116
                authUsersMap.remove(authUser.getId());
1117
                subject = String.format("Ticket Update #%s by %s", ticket.getId(), authUser.getName());
1118
                mailMessage = String.format("%s's message - %s", authUser.getFirstName(), message);
35569 amit 1119
                // Only CRM users can send external communications
1120
                boolean isCrmUser = positionRepository.hasCategory(authUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
1121
                if (internal || !isCrmUser) {
31762 tejbeer 1122
                    activity.setType(ActivityType.COMMUNICATION_INTERNAL);
1123
                } else {
1124
                    String updatedBy = "SD Team";
31854 amit.gupta 1125
                    CustomRetailer customRetailer = retailerService.getFofoRetailers(false).get(ticket.getFofoId());
31762 tejbeer 1126
                    subject = String.format("Ticket Update #%s by %s", ticket.getId(), updatedBy);
1127
                    String partnerMessage = String.format("%s's message - %s", updatedBy, message);
1128
                    this.activityRelatedMail(customRetailer.getEmail(), null, "subject", partnerMessage);
1129
                    activity.setType(ActivityType.COMMUNICATION_OUT);
1130
                }
1131
            }
1132
            activityRepository.persist(activity);
1133
 
1134
            for (Integer documentId : documentIds) {
1135
                ActivityAttachment activityAttachment = new ActivityAttachment();
1136
                activityAttachment.setActivityId(activity.getId());
1137
                activityAttachment.setDocumentId(documentId);
1138
                activityAttachmentRepository.persist(activityAttachment);
1139
            }
1140
 
1141
            csService.addActivity(ticket, activity);
1142
            AuthUser authUser = authUsersMap.remove(authUserIds.get(0));
1143
            if (authUser == null) {
1144
                authUser = authUsersMap.remove(authUserIds.get(1));
1145
            }
1146
            model.addAttribute("response1", mvcResponseSender.createResponseString(authUser));
1147
            String[] cc = authUsersMap.entrySet().stream().map(x -> x.getValue().getEmailId()).toArray(String[]::new);
1148
            this.activityRelatedMail(authUser.getEmailId(), cc, subject, mailMessage);
1149
        } else {
1150
            throw new ProfitMandiBusinessException("Ticket", ticket.getId(), "Already closed ticket");
1151
        }
1152
        return "response";
1153
    }
1154
 
1155
    private void activityRelatedMail(String to, String[] cc, String subject, String message) throws ProfitMandiBusinessException {
1156
        try {
35957 amit 1157
            mailOutboxService.queueMail(to, cc, subject, message, "CsController.activityRelatedMail");
31762 tejbeer 1158
        } catch (Exception e) {
1159
            throw new ProfitMandiBusinessException("Ticket Activity", to, "Could not send ticket activity mail");
1160
        }
1161
    }
1162
 
1163
    @PostMapping(value = "/cs/closeTicket")
1164
    public String closeTicket(HttpServletRequest request, @RequestParam(name = "ticketId", defaultValue = "0") int ticketId, @RequestParam(name = "happyCode") String happyCode, Model model) throws Exception {
35592 amit 1165
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
31762 tejbeer 1166
        Ticket ticket = ticketRepository.selectById(ticketId);
35592 amit 1167
 
1168
        if (ticket == null) {
1169
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Ticket not found");
1170
        }
1171
 
1172
        // Authorization check: only the ticket owner (partner) can close the ticket
1173
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
1174
        if (isAdmin) {
1175
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Only partners can close tickets using happy code");
1176
        }
1177
 
1178
        // Verify the partner owns this ticket
1179
        if (ticket.getFofoId() != loginDetails.getFofoId()) {
1180
            throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to close this ticket");
1181
        }
1182
 
31762 tejbeer 1183
        if (ticket.getHappyCode().equals(happyCode)) {
1184
            ticket.setCloseTimestamp(LocalDateTime.now());
1185
            ticketRepository.persist(ticket);
1186
            model.addAttribute("response1", mvcResponseSender.createResponseString(true));
1187
        } else {
1188
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Happy Code can't match");
1189
        }
1190
        return "response";
1191
    }
1192
 
34913 ranu 1193
    @GetMapping(value = "/cs/myPartyTicketTicket")
1194
    public String getMyPartyTicketTicket(HttpServletRequest request, @RequestParam(name = "orderby", defaultValue = "DESCENDING") SortOrder sortOrder, @RequestParam(name = "ticketStatus", defaultValue = "OPENED") TicketStatus ticketStatus, @RequestParam(name = "ticketSearchType", defaultValue = "") TicketSearchType ticketSearchType, @RequestParam(name = "searchTerm", defaultValue = "0") int searchTerm, Model model) throws ProfitMandiBusinessException {
35626 amit 1195
        populateMyPartnerTicketModel(request, sortOrder, ticketStatus, ticketSearchType, searchTerm, model);
1196
        return "my-partner-tickets";
1197
    }
1198
 
1199
    @GetMapping(value = "/cs/myPartyTicket-content")
1200
    public String getMyPartyTicketContent(HttpServletRequest request,
1201
                                          @RequestParam(name = "orderby", defaultValue = "DESCENDING") SortOrder sortOrder,
1202
                                          @RequestParam(name = "ticketStatus", defaultValue = "OPENED") TicketStatus ticketStatus,
1203
                                          @RequestParam(name = "ticketSearchType", defaultValue = "") TicketSearchType ticketSearchType,
1204
                                          @RequestParam(name = "searchTerm", defaultValue = "0") int searchTerm,
1205
                                          Model model) throws ProfitMandiBusinessException {
1206
        populateMyPartnerTicketModel(request, sortOrder, ticketStatus, ticketSearchType, searchTerm, model);
1207
        return "my-partner-tickets-content";
1208
    }
1209
 
1210
    private void populateMyPartnerTicketModel(HttpServletRequest request, SortOrder sortOrder, TicketStatus ticketStatus,
1211
                                              TicketSearchType ticketSearchType, int searchTerm, Model model) throws ProfitMandiBusinessException {
34913 ranu 1212
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
1213
        AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
1214
        List<Ticket> tickets = new ArrayList<>();
1215
        Map<String, Set<Integer>> storeGuyMap = csService.getAuthUserPartnerIdMapping();
1216
        Set<Integer> fofoIds = storeGuyMap.get(authUser.getEmailId());
1217
 
1218
        Map<Integer, List<AuthUser>> authUserListMap = null;
1219
        if (fofoIds != null && !fofoIds.isEmpty()) {
35571 amit 1220
            List<Ticket> allPartnerTickets = ticketRepository.selectAllOpenTickets(new ArrayList<>(fofoIds));
1221
            if (allPartnerTickets != null && !allPartnerTickets.isEmpty()) {
1222
                tickets = allPartnerTickets.stream()
1223
                        .filter(ticket -> ticket.getLastActivity() == null ||
1224
                                ticket.getLastActivity() != ActivityType.RESOLVED)
1225
                        .collect(Collectors.toList());
34913 ranu 1226
            }
1227
        }
1228
 
1229
        authUserListMap = csService.getAssignedAuthList(tickets);
1230
 
37145 ranu 1231
        // Find which tickets are assigned to or escalated to this user (can take action).
1232
        // TicketAssigned history covers every past assignee + manager pair, which fully
1233
        // subsumes the previous l1..l5AuthUser fallback loop.
36231 ranu 1234
        Set<Integer> actionableTicketIds = new HashSet<>();
34913 ranu 1235
        if (tickets.size() > 0) {
36231 ranu 1236
            List<TicketAssigned> allAssignments = ticketAssignedRepository.selectByTicketIds(
1237
                    tickets.stream().map(Ticket::getId).collect(Collectors.toList()));
1238
            for (TicketAssigned ta : allAssignments) {
1239
                if (ta.getAssineeId() == authUser.getId() || ta.getManagerId() == authUser.getId()) {
1240
                    actionableTicketIds.add(ta.getTicketId());
1241
                }
1242
            }
34913 ranu 1243
            Map<Integer, CustomRetailer> fofoIdsAndCustomRetailer = csService.getPartnerByFofoIds(tickets);
1244
            model.addAttribute("fofoIdsAndCustomRetailer", fofoIdsAndCustomRetailer);
1245
        }
36231 ranu 1246
        model.addAttribute("actionableTicketIds", actionableTicketIds);
34913 ranu 1247
 
35626 amit 1248
        // Pagination for partner tickets (in-memory since selectAllOpenTickets doesn't support DB-level pagination)
1249
        long totalRecords = tickets.size();
1250
        int totalPages = totalRecords > 0 ? (int) Math.ceil((double) totalRecords / 25) : 1;
1251
        model.addAttribute("totalRecords", totalRecords);
1252
        model.addAttribute("currentPage", 0);
1253
        model.addAttribute("pageSize", 25);
1254
        model.addAttribute("totalPages", totalPages);
1255
        model.addAttribute("startRecord", totalRecords > 0 ? 1 : 0);
1256
        model.addAttribute("endRecord", totalRecords);
1257
        model.addAttribute("currentPageDisplay", 1);
1258
        model.addAttribute("prevPage", 0);
1259
        model.addAttribute("nextPage", 1);
1260
        model.addAttribute("lastPage", totalPages - 1);
1261
 
34913 ranu 1262
        model.addAttribute("size", tickets.size());
1263
        model.addAttribute("tickets", tickets);
1264
 
1265
        List<Integer> subCategoryIds = tickets.stream().map(x -> x.getSubCategoryId()).collect(Collectors.toList());
1266
        Map<Integer, TicketSubCategory> subCategoryIdAndSubCategoryMap = csService.getSubCategoryIdAndSubCategoryMap(subCategoryIds);
35571 amit 1267
        if (subCategoryIdAndSubCategoryMap == null) {
1268
            subCategoryIdAndSubCategoryMap = new HashMap<>();
1269
        }
34913 ranu 1270
 
1271
        Map<Integer, TicketCategory> subCategoryIdAndCategoryMap = csService.getSubCategoryIdAndCategoryMap(subCategoryIds);
35571 amit 1272
        if (subCategoryIdAndCategoryMap == null) {
1273
            subCategoryIdAndCategoryMap = new HashMap<>();
1274
        }
34913 ranu 1275
 
1276
        List<Integer> ticketIds = tickets.stream().map(x -> x.getId()).collect(Collectors.toList());
1277
        Map<Integer, List<Activity>> activityMap = new HashMap<>();
1278
        Map<Integer, List<Activity>> activityMapWithActivityId = new HashMap<>();
35569 amit 1279
        Map<Integer, AuthUser> authUserMap = new HashMap<>();
34913 ranu 1280
 
1281
        if (!ticketIds.isEmpty()) {
35569 amit 1282
            List<Activity> allActivities = activityRepository.selectAll(ticketIds);
1283
            activityMap = allActivities.stream().collect(Collectors.groupingBy(Activity::getTicketId));
1284
            activityMapWithActivityId = allActivities.stream().collect(Collectors.groupingBy(Activity::getId));
34913 ranu 1285
 
35569 amit 1286
            Set<Integer> activityCreatorIds = allActivities.stream()
1287
                    .map(Activity::getCreatedBy)
1288
                    .filter(id -> id > 0)
1289
                    .collect(Collectors.toSet());
1290
            if (!activityCreatorIds.isEmpty()) {
1291
                authUserMap = authRepository.selectByIds(new ArrayList<>(activityCreatorIds))
1292
                        .stream().collect(Collectors.toMap(AuthUser::getId, x -> x));
1293
            }
34913 ranu 1294
        }
1295
 
35626 amit 1296
        Map<Integer, Boolean> unreadMap = csService.getUnreadStatusForTickets(tickets, authUser.getId(), UserType.AUTH_USER);
35640 amit 1297
        List<Integer> partnerTicketIds = tickets.stream().map(Ticket::getId).collect(Collectors.toList());
1298
        Map<Integer, Activity> lastActivityMap = csService.getLastActivitiesForTickets(partnerTicketIds);
1299
        Map<Integer, Activity> lastMessageMap = csService.getLastMessageActivitiesForTickets(partnerTicketIds);
35626 amit 1300
        model.addAttribute("unreadMap", unreadMap);
1301
        model.addAttribute("lastActivityMap", lastActivityMap);
35640 amit 1302
        model.addAttribute("lastMessageMap", lastMessageMap);
35626 amit 1303
 
34913 ranu 1304
        model.addAttribute("ticketStatusValues", TicketStatus.values());
1305
        model.addAttribute("orderByValues", SortOrder.values());
1306
        model.addAttribute("selectedticketStatus", ticketStatus);
1307
        model.addAttribute("selectedorderby", sortOrder);
1308
        model.addAttribute("ticketSearchTypes", TicketSearchType.values());
1309
        model.addAttribute("ticketSearchType", ticketSearchType);
1310
        model.addAttribute("searchTerm", searchTerm);
35571 amit 1311
        model.addAttribute("authUserListMap", authUserListMap != null ? authUserListMap : new HashMap<>());
34913 ranu 1312
        model.addAttribute("subCategoryIdAndSubCategoryMap", subCategoryIdAndSubCategoryMap);
1313
 
1314
        model.addAttribute("subCategoryIdAndCategoryMap", subCategoryIdAndCategoryMap);
1315
 
1316
        model.addAttribute("activityMap", activityMap);
1317
        model.addAttribute("authUserMap", authUserMap);
1318
        model.addAttribute("activityMapWithActivityId", activityMapWithActivityId);
35569 amit 1319
        boolean isCrmUser = positionRepository.hasCategory(authUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
1320
        model.addAttribute("isCrmUser", isCrmUser);
35626 amit 1321
    }
34913 ranu 1322
 
35626 amit 1323
    @GetMapping(value = "/cs/managerTicket")
1324
    public String getManagerTickets(HttpServletRequest request,
1325
                                    @RequestParam(name = "orderby", defaultValue = "DESCENDING") SortOrder sortOrder,
1326
                                    @RequestParam(name = "ticketStatus", defaultValue = "OPENED") TicketStatus ticketStatus,
1327
                                    @RequestParam(name = "ticketSearchType", defaultValue = "") TicketSearchType ticketSearchType,
1328
                                    @RequestParam(name = "searchTerm", defaultValue = "0") int searchTerm,
1329
                                    @RequestParam(name = "page", defaultValue = "0") int page,
1330
                                    @RequestParam(name = "pageSize", defaultValue = "25") int pageSize,
1331
                                    @RequestParam(name = "search", required = false) String searchText,
1332
                                    Model model) throws ProfitMandiBusinessException {
1333
        populateManagerTicketModel(request, sortOrder, ticketStatus, ticketSearchType, searchTerm, page, pageSize, searchText, model);
1334
        return "managerTicket";
34913 ranu 1335
    }
1336
 
35626 amit 1337
    @GetMapping(value = "/cs/managerTicket-content")
1338
    public String getManagerTicketContent(HttpServletRequest request,
1339
                                          @RequestParam(name = "orderby", defaultValue = "DESCENDING") SortOrder sortOrder,
1340
                                          @RequestParam(name = "ticketStatus", defaultValue = "OPENED") TicketStatus ticketStatus,
1341
                                          @RequestParam(name = "ticketSearchType", defaultValue = "") TicketSearchType ticketSearchType,
1342
                                          @RequestParam(name = "searchTerm", defaultValue = "0") int searchTerm,
1343
                                          @RequestParam(name = "page", defaultValue = "0") int page,
1344
                                          @RequestParam(name = "pageSize", defaultValue = "25") int pageSize,
1345
                                          @RequestParam(name = "search", required = false) String searchText,
1346
                                          Model model) throws ProfitMandiBusinessException {
1347
        populateManagerTicketModel(request, sortOrder, ticketStatus, ticketSearchType, searchTerm, page, pageSize, searchText, model);
1348
        return "managerTicket-content";
1349
    }
1350
 
1351
    private void populateManagerTicketModel(HttpServletRequest request, SortOrder sortOrder, TicketStatus ticketStatus,
1352
                                            TicketSearchType ticketSearchType, int searchTerm, int page, int pageSize,
1353
                                            String searchText, Model model) throws ProfitMandiBusinessException {
31762 tejbeer 1354
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
35626 amit 1355
        long totalRecords = 0;
31762 tejbeer 1356
        AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
35626 amit 1357
 
1358
        // Block L1-only users from accessing manager tickets
1359
        List<Position> positions = positionRepository.selectAllByAuthUserId(authUser.getId());
1360
        boolean isAboveL1 = positions.stream().anyMatch(pos -> pos.getEscalationType() != EscalationType.L1);
1361
        if (!isAboveL1) {
1362
            throw new ProfitMandiBusinessException("ManagerTicket", 0, "Access denied: requires at least L2 position");
1363
        }
1364
 
35594 amit 1365
        boolean isCrmUser = positionRepository.hasCategory(authUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
1366
 
35626 amit 1367
        List<Integer> userCategoryIds = positionRepository.selectCategoryIdsByAuthUserId(authUser.getId());
1368
 
31762 tejbeer 1369
        List<Ticket> tickets = null;
1370
        Map<Integer, List<AuthUser>> authUserListMap = null;
35594 amit 1371
 
35626 amit 1372
        int offset = page * pageSize;
1373
        Optional<Boolean> resolvedOpt = ticketStatus.equals(TicketStatus.RESOLVED) ? Optional.empty() : Optional.of(TicketStatus.CLOSED.equals(ticketStatus));
1374
 
35594 amit 1375
        if (isCrmUser) {
35626 amit 1376
            tickets = ticketRepository.selectAllTicketsPaginated(
1377
                    resolvedOpt, sortOrder, ticketSearchType, searchTerm, searchText,
1378
                    userCategoryIds, offset, pageSize);
1379
            totalRecords = ticketRepository.selectAllTicketsPaginatedCount(
1380
                    resolvedOpt, ticketSearchType, searchTerm, searchText, userCategoryIds);
31762 tejbeer 1381
        } else {
35626 amit 1382
            tickets = ticketRepository.selectAllManagerTicketPaginated(
1383
                    authUser.getId(), sortOrder, resolvedOpt, ticketSearchType, searchTerm, searchText,
1384
                    offset, pageSize);
1385
            totalRecords = ticketRepository.selectAllCountByManagerTicketPaginated(
1386
                    authUser.getId(), resolvedOpt, ticketSearchType, searchTerm, searchText);
31762 tejbeer 1387
        }
1388
        authUserListMap = csService.getAssignedAuthList(tickets);
1389
 
1390
        if (tickets.size() > 0) {
1391
            Map<Integer, CustomRetailer> fofoIdsAndCustomRetailer = csService.getPartnerByFofoIds(tickets);
1392
            model.addAttribute("fofoIdsAndCustomRetailer", fofoIdsAndCustomRetailer);
1393
        }
1394
 
35626 amit 1395
        int totalPages = (int) Math.ceil((double) totalRecords / pageSize);
1396
        if (totalPages == 0) totalPages = 1;
1397
        int startRecord = totalRecords > 0 ? offset + 1 : 0;
1398
        int endRecord = (int) Math.min(offset + pageSize, totalRecords);
1399
 
1400
        model.addAttribute("size", totalRecords);
1401
        model.addAttribute("totalRecords", totalRecords);
1402
        model.addAttribute("currentPage", page);
1403
        model.addAttribute("pageSize", pageSize);
1404
        model.addAttribute("totalPages", totalPages);
1405
        model.addAttribute("startRecord", startRecord);
1406
        model.addAttribute("endRecord", endRecord);
1407
        model.addAttribute("searchText", searchText != null ? searchText : "");
1408
        model.addAttribute("currentPageDisplay", page + 1);
1409
        model.addAttribute("prevPage", page - 1);
1410
        model.addAttribute("nextPage", page + 1);
1411
        model.addAttribute("lastPage", totalPages - 1);
31762 tejbeer 1412
        model.addAttribute("tickets", tickets);
1413
 
1414
        List<Integer> subCategoryIds = tickets.stream().map(x -> x.getSubCategoryId()).collect(Collectors.toList());
1415
        Map<Integer, TicketSubCategory> subCategoryIdAndSubCategoryMap = csService.getSubCategoryIdAndSubCategoryMap(subCategoryIds);
35571 amit 1416
        if (subCategoryIdAndSubCategoryMap == null) {
1417
            subCategoryIdAndSubCategoryMap = new HashMap<>();
1418
        }
31762 tejbeer 1419
 
1420
        Map<Integer, TicketCategory> subCategoryIdAndCategoryMap = csService.getSubCategoryIdAndCategoryMap(subCategoryIds);
35571 amit 1421
        if (subCategoryIdAndCategoryMap == null) {
1422
            subCategoryIdAndCategoryMap = new HashMap<>();
1423
        }
31762 tejbeer 1424
 
1425
        List<Integer> ticketIds = tickets.stream().map(x -> x.getId()).collect(Collectors.toList());
1426
        Map<Integer, List<Activity>> activityMap = new HashMap<>();
33778 ranu 1427
        Map<Integer, List<Activity>> activityMapWithActivityId = new HashMap<>();
35570 amit 1428
        Map<Integer, AuthUser> authUserMap = new HashMap<>();
31762 tejbeer 1429
 
1430
        if (!ticketIds.isEmpty()) {
35570 amit 1431
            List<Activity> allActivities = activityRepository.selectAll(ticketIds);
1432
            activityMap = allActivities.stream().collect(Collectors.groupingBy(Activity::getTicketId));
1433
            activityMapWithActivityId = allActivities.stream().collect(Collectors.groupingBy(Activity::getId));
31762 tejbeer 1434
 
35570 amit 1435
            Set<Integer> activityCreatorIds = allActivities.stream()
1436
                    .map(Activity::getCreatedBy)
1437
                    .filter(id -> id > 0)
1438
                    .collect(Collectors.toSet());
1439
            if (!activityCreatorIds.isEmpty()) {
1440
                authUserMap = authRepository.selectByIds(new ArrayList<>(activityCreatorIds))
1441
                        .stream().collect(Collectors.toMap(AuthUser::getId, x -> x));
1442
            }
31762 tejbeer 1443
        }
33778 ranu 1444
 
35626 amit 1445
        Map<Integer, Boolean> unreadMap = csService.getUnreadStatusForTickets(tickets, authUser.getId(), UserType.AUTH_USER);
35640 amit 1446
        List<Integer> managerTicketIds = tickets.stream().map(Ticket::getId).collect(Collectors.toList());
1447
        Map<Integer, Activity> lastActivityMap = csService.getLastActivitiesForTickets(managerTicketIds);
1448
        Map<Integer, Activity> lastMessageMap = csService.getLastMessageActivitiesForTickets(managerTicketIds);
35626 amit 1449
        model.addAttribute("unreadMap", unreadMap);
1450
        model.addAttribute("lastActivityMap", lastActivityMap);
35640 amit 1451
        model.addAttribute("lastMessageMap", lastMessageMap);
35626 amit 1452
 
31762 tejbeer 1453
        model.addAttribute("ticketStatusValues", TicketStatus.values());
1454
        model.addAttribute("orderByValues", SortOrder.values());
1455
        model.addAttribute("selectedticketStatus", ticketStatus);
1456
        model.addAttribute("selectedorderby", sortOrder);
1457
        model.addAttribute("ticketSearchTypes", TicketSearchType.values());
1458
        model.addAttribute("ticketSearchType", ticketSearchType);
1459
        model.addAttribute("searchTerm", searchTerm);
1460
        model.addAttribute("authUserListMap", authUserListMap);
1461
        model.addAttribute("subCategoryIdAndSubCategoryMap", subCategoryIdAndSubCategoryMap);
1462
 
1463
        model.addAttribute("subCategoryIdAndCategoryMap", subCategoryIdAndCategoryMap);
1464
 
1465
        model.addAttribute("activityMap", activityMap);
33778 ranu 1466
        model.addAttribute("authUserMap", authUserMap);
1467
        model.addAttribute("activityMapWithActivityId", activityMapWithActivityId);
35594 amit 1468
        model.addAttribute("isCrmUser", isCrmUser);
31762 tejbeer 1469
    }
1470
 
1471
 
1472
    @GetMapping(value = "/cs/edit-ticket")
35594 amit 1473
    public String getEditTicket(HttpServletRequest request, @RequestParam(name = "ticketId", defaultValue = "0") int ticketId, Model model) throws ProfitMandiBusinessException {
1474
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
1475
        AuthUser currentAuthUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
1476
        boolean isCrmUser = positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
1477
 
31762 tejbeer 1478
        Ticket ticket = ticketRepository.selectById(ticketId);
35626 amit 1479
        if (ticket == null) {
1480
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Ticket not found");
1481
        }
1482
 
1483
        TicketSubCategory ticketSubCategory = ticketSubCategoryRepository.selectById(ticket.getSubCategoryId());
1484
        int ticketCategoryId = ticketSubCategory.getCategoryId();
1485
        boolean isVisibleSubCategory = ticketSubCategory.isVisibility();
1486
 
1487
        // Check permissions
1488
        boolean hasPositionInCategory = positionRepository.hasCategory(currentAuthUser.getId(), ticketCategoryId);
1489
        List<TicketAssigned> assignments = ticketAssignedRepository.selectByTicketIds(Arrays.asList(ticketId));
1490
        boolean isAssigned = assignments.stream().anyMatch(ta -> ta.getAssineeId() == currentAuthUser.getId() || ta.getManagerId() == currentAuthUser.getId());
1491
 
1492
        boolean canEdit = (isCrmUser && isVisibleSubCategory)
1493
                || hasPositionInCategory
37145 ranu 1494
                || isAssigned;
35626 amit 1495
 
1496
        if (!canEdit) {
1497
            throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to edit this ticket");
1498
        }
1499
 
31762 tejbeer 1500
        List<TicketCategory> ticketCategories = csService.getAllTicketCategotyFromSubCategory();
1501
        List<TicketSubCategory> ticketSubCategories = ticketSubCategoryRepository.selectAll(ticketSubCategory.getCategoryId());
1502
        List<AuthUser> authUsers = authRepository.selectAllActiveUser();
35594 amit 1503
 
35617 amit 1504
        // CRM users should not see invisible subcategories
35594 amit 1505
        if (isCrmUser) {
1506
            ticketSubCategories = ticketSubCategories.stream()
35617 amit 1507
                    .filter(TicketSubCategory::isVisibility)
35594 amit 1508
                    .collect(Collectors.toList());
1509
        }
1510
 
1511
        // Get partner name for modal title
1512
        String partnerName = retailerService.getFofoRetailer(ticket.getFofoId()).getBusinessName();
1513
 
31762 tejbeer 1514
        model.addAttribute("ticket", ticket);
1515
        model.addAttribute("ticketCategories", ticketCategories);
1516
        model.addAttribute("ticketSubCategories", ticketSubCategories);
1517
        model.addAttribute("ticketSubCategory", ticketSubCategory);
1518
        model.addAttribute("authUsers", authUsers);
35594 amit 1519
        model.addAttribute("isCrmUser", isCrmUser);
1520
        model.addAttribute("partnerName", partnerName);
31762 tejbeer 1521
        return "edit-ticket-modal";
1522
    }
1523
 
34913 ranu 1524
    @GetMapping(value = "/cs/edit-partner-ticket")
35594 amit 1525
    public String getEditPartnerTicket(HttpServletRequest request, @RequestParam(name = "ticketId", defaultValue = "0") int ticketId, Model model) throws ProfitMandiBusinessException {
1526
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
1527
        AuthUser currentAuthUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
1528
        boolean isCrmUser = positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
1529
 
34913 ranu 1530
        Ticket ticket = ticketRepository.selectById(ticketId);
1531
        List<TicketCategory> ticketCategories = csService.getAllTicketCategotyFromSubCategory();
1532
        TicketSubCategory ticketSubCategory = ticketSubCategoryRepository.selectById(ticket.getSubCategoryId());
1533
        List<TicketSubCategory> ticketSubCategories = ticketSubCategoryRepository.selectAll(ticketSubCategory.getCategoryId());
1534
        List<AuthUser> authUsers = authRepository.selectAllActiveUser();
35594 amit 1535
 
35617 amit 1536
        // CRM users should not see invisible subcategories
35594 amit 1537
        if (isCrmUser) {
1538
            ticketSubCategories = ticketSubCategories.stream()
35617 amit 1539
                    .filter(TicketSubCategory::isVisibility)
35594 amit 1540
                    .collect(Collectors.toList());
1541
        }
1542
 
1543
        // Get partner name for modal title
1544
        String partnerName = retailerService.getFofoRetailer(ticket.getFofoId()).getBusinessName();
1545
 
34913 ranu 1546
        model.addAttribute("ticket", ticket);
1547
        model.addAttribute("ticketCategories", ticketCategories);
1548
        model.addAttribute("ticketSubCategories", ticketSubCategories);
1549
        model.addAttribute("ticketSubCategory", ticketSubCategory);
1550
        model.addAttribute("authUsers", authUsers);
35594 amit 1551
        model.addAttribute("isCrmUser", isCrmUser);
1552
        model.addAttribute("partnerName", partnerName);
34913 ranu 1553
        return "edit-ticket-partner-modal";
1554
    }
1555
 
31762 tejbeer 1556
    @PostMapping(value = "/cs/edit-ticket")
1557
    public String editTicket(HttpServletRequest request, @RequestParam(name = "ticketId", defaultValue = "0") int ticketId, @RequestParam(name = "subCategoryId", defaultValue = "0") int subCategoryId, @RequestParam(name = "categoryId", defaultValue = "0") int categoryId, @RequestParam(name = "authUserId", defaultValue = "0") int authUserId, @RequestParam(name = "escalationType", defaultValue = "L1") EscalationType escalationType, Model model) throws Exception {
1558
        LOGGER.info("Ticket Id {}, CategoryId {}, SubCategory Id {} authUserId {}", ticketId, categoryId, subCategoryId, authUserId);
35592 amit 1559
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
1560
 
1561
        // Only admins can edit tickets
1562
        if (!roleManager.isAdmin(loginDetails.getRoleIds())) {
1563
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Only admins can edit tickets");
1564
        }
1565
 
31762 tejbeer 1566
        Ticket ticket = ticketRepository.selectById(ticketId);
35592 amit 1567
        if (ticket == null) {
1568
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Ticket not found");
1569
        }
1570
 
35626 amit 1571
        // Verify admin has access to this ticket
35592 amit 1572
        AuthUser currentAuthUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
1573
        boolean isCrmUser = positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
1574
 
35626 amit 1575
        // Get ticket's subcategory to check visibility
1576
        TicketSubCategory ticketSubCategory = ticketSubCategoryRepository.selectById(ticket.getSubCategoryId());
1577
        int ticketCategoryId = ticketSubCategory.getCategoryId();
1578
        boolean isVisibleSubCategory = ticketSubCategory.isVisibility();
35592 amit 1579
 
35626 amit 1580
        // Check if user has position in ticket's category
1581
        boolean hasPositionInCategory = positionRepository.hasCategory(currentAuthUser.getId(), ticketCategoryId);
1582
 
37145 ranu 1583
        // Check if assigned (assignee or manager at any level in history)
35626 amit 1584
        List<TicketAssigned> assignments = ticketAssignedRepository.selectByTicketIds(Arrays.asList(ticketId));
1585
        boolean isAssigned = assignments.stream().anyMatch(ta -> ta.getAssineeId() == currentAuthUser.getId() || ta.getManagerId() == currentAuthUser.getId());
1586
 
1587
        // Permission rules:
1588
        // 1. CRM user AND ticket has visible subcategory, OR
1589
        // 2. Has position in ticket's category (can edit even invisible), OR
37145 ranu 1590
        // 3. Is assigned to ticket at any past level (assignee or manager)
35626 amit 1591
        boolean canEdit = (isCrmUser && isVisibleSubCategory)
1592
                || hasPositionInCategory
37145 ranu 1593
                || isAssigned;
35626 amit 1594
 
1595
        if (!canEdit) {
1596
            throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to edit this ticket");
35592 amit 1597
        }
1598
 
31762 tejbeer 1599
        csService.updateTicket(categoryId, subCategoryId, ticket, authUserId, escalationType);
1600
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
1601
        return "response";
1602
 
1603
    }
1604
 
34913 ranu 1605
    @PostMapping(value = "/cs/edit-partner-ticket")
1606
    public String editPartnerTicket(HttpServletRequest request, @RequestParam(name = "ticketId", defaultValue = "0") int ticketId, @RequestParam(name = "subCategoryId", defaultValue = "0") int subCategoryId, @RequestParam(name = "categoryId", defaultValue = "0") int categoryId, @RequestParam(name = "authUserId", defaultValue = "0") int authUserId, @RequestParam(name = "escalationType", defaultValue = "L1") EscalationType escalationType, Model model) throws Exception {
1607
        LOGGER.info("Ticket Id {}, CategoryId {}, SubCategory Id {} authUserId {}", ticketId, categoryId, subCategoryId, authUserId);
35592 amit 1608
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
1609
 
1610
        // Only admins can edit partner tickets
1611
        if (!roleManager.isAdmin(loginDetails.getRoleIds())) {
1612
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Only admins can edit partner tickets");
1613
        }
1614
 
34913 ranu 1615
        Ticket ticket = ticketRepository.selectById(ticketId);
35592 amit 1616
        if (ticket == null) {
1617
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Ticket not found");
1618
        }
1619
 
1620
        // Verify admin has access (must be in Sales, ABM, or RBM position for the partner)
1621
        AuthUser currentAuthUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
1622
        Map<String, Set<Integer>> authUserPartnerMap = csService.getAuthUserPartnerIdMapping();
1623
        Set<Integer> allowedPartnerIds = authUserPartnerMap.get(currentAuthUser.getEmailId());
1624
 
1625
        if (allowedPartnerIds == null || !allowedPartnerIds.contains(ticket.getFofoId())) {
1626
            // Also allow CRM users
1627
            boolean isCrmUser = positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
1628
            if (!isCrmUser) {
1629
                throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to edit this partner's ticket");
1630
            }
1631
        }
1632
 
34913 ranu 1633
        csService.updateTicket(categoryId, subCategoryId, ticket, authUserId, escalationType);
1634
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
1635
        return "response";
1636
 
1637
    }
1638
 
31762 tejbeer 1639
    @PostMapping(value = "/cs/changeTicketAssignee")
1640
    public String changeTicketAssignee(HttpServletRequest request, @RequestParam(name = "positionId", defaultValue = "0") int positionId, Model model) throws Exception {
1641
        Position position = positionRepository.selectById(positionId);
1642
        if (position.isTicketAssignee()) {
1643
            position.setTicketAssignee(false);
1644
        } else {
1645
            position.setTicketAssignee(true);
1646
        }
1647
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
1648
        return "response";
1649
    }
1650
 
1651
 
1652
    @DeleteMapping(value = "/cs/removePosition")
1653
    public String removePosition(HttpServletRequest request, @RequestParam(name = "positionId", defaultValue = "0") int positionId, Model model) throws Exception {
1654
        positionRepository.delete(positionId);
1655
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
1656
        return "response";
1657
    }
1658
 
1659
    @PostMapping(value = "/cs/create-last-activity")
1660
    public String createlastActivity(HttpServletRequest request, @RequestParam(name = "ticketId") int ticketId, @RequestParam(name = "lastactivity") ActivityType lastActivity, Model model) throws Exception {
1661
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
1662
        Ticket ticket = ticketRepository.selectById(ticketId);
35592 amit 1663
 
1664
        if (ticket == null) {
1665
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Ticket not found");
1666
        }
1667
 
1668
        // Authorization check for partners: can only update their own tickets
1669
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
1670
        if (!isAdmin && ticket.getFofoId() != loginDetails.getFofoId()) {
1671
            throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to update this ticket");
1672
        }
1673
 
31762 tejbeer 1674
        Activity activity = new Activity();
1675
        String subject = String.format(ACTIVITY_SUBJECT, ticket.getId());
35592 amit 1676
        if (isAdmin) {
35603 amit 1677
            // CRM team members can resolve any ticket
1678
            // Sales team members can resolve their own Sales category tickets
1679
            // RBM team members can resolve their own RBM category tickets
35592 amit 1680
            AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
1681
            boolean isCrmUser = positionRepository.hasCategory(authUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
35603 amit 1682
            boolean isSalesUser = positionRepository.hasCategory(authUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_SALES);
1683
            boolean isRbmUser = positionRepository.hasCategory(authUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_RBM);
1684
 
1685
            // Check if ticket belongs to Sales or RBM category
1686
            TicketSubCategory ticketSubCategory = ticketSubCategoryRepository.selectById(ticket.getSubCategoryId());
1687
            boolean isSalesTicket = ticketSubCategory != null && ticketSubCategory.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_SALES;
1688
            boolean isRbmTicket = ticketSubCategory != null && ticketSubCategory.getCategoryId() == ProfitMandiConstants.TICKET_CATEGORY_RBM;
1689
 
1690
            // Allow if CRM user OR (Sales user AND Sales ticket) OR (RBM user AND RBM ticket)
1691
            if (!isCrmUser && !(isSalesUser && isSalesTicket) && !(isRbmUser && isRbmTicket)) {
1692
                throw new ProfitMandiBusinessException("Ticket", ticketId, "Only CRM, Sales (for Sales tickets), or RBM (for RBM tickets) team can mark tickets as resolved");
35592 amit 1693
            }
31762 tejbeer 1694
            ticket.setLastActivity(lastActivity);
1695
            String to = retailerService.getFofoRetailer(ticket.getFofoId()).getEmail();
1696
            String message = String.format(PARTNER_RESOLVED_TICKET_MAIL, ticketId, "REOPEN");
1697
            activity.setMessage(message);
35592 amit 1698
            activity.setCreatedBy(authUser.getId());
31762 tejbeer 1699
            activity.setTicketId(ticketId);
1700
            activity.setCreateTimestamp(LocalDateTime.now());
1701
            activity.setType(ActivityType.COMMUNICATION_OUT);
1702
            this.activityRelatedMail(to, null, subject, message);
1703
        } else {
1704
            if (ActivityType.RESOLVED_ACCEPTED == lastActivity) {
1705
                ticket.setLastActivity(lastActivity);
1706
                ticket.setCloseTimestamp(LocalDateTime.now());
1707
                activity.setMessage(ActivityType.RESOLVED_ACCEPTED.toString());
1708
                activity.setCreatedBy(0);
1709
                activity.setTicketId(ticketId);
1710
                activity.setType(ActivityType.COMMUNICATION_IN);
1711
                activity.setCreateTimestamp(LocalDateTime.now());
1712
            } else {
1713
                String message = String.format(INTERNAL_REOPEN_MAIL, ticketId, retailerService.getFofoRetailer(loginDetails.getFofoId()).getBusinessName());
37145 ranu 1714
                // Reopen mail goes to the current assignee with the current manager on CC.
1715
                // Previously fanned out to all l1..l5 slots which were pre-populated at creation.
1716
                String to = ticket.getCurrentAssigneeId() > 0
1717
                        ? authRepository.selectById(ticket.getCurrentAssigneeId()).getEmailId()
1718
                        : null;
1719
                String[] ccTo = ticket.getCurrentManagerId() > 0
1720
                        ? new String[]{authRepository.selectById(ticket.getCurrentManagerId()).getEmailId()}
1721
                        : new String[0];
31762 tejbeer 1722
                ticket.setLastActivity(lastActivity);
1723
                ticket.setUpdateTimestamp(LocalDateTime.now());
1724
                ticketAssignedRepository.deleteByTicketId(ticketId);
1725
                TicketAssigned ticketAssigned = new TicketAssigned();
37145 ranu 1726
                ticketAssigned.setAssineeId(ticket.getCurrentAssigneeId());
31762 tejbeer 1727
                ticketAssigned.setTicketId(ticketId);
1728
                ticketAssignedRepository.persist(ticketAssigned);
1729
                activity.setMessage(INTERNAL_REOPEN_ACTIVITY_MESSAGE);
1730
                activity.setCreatedBy(0);
1731
                activity.setTicketId(ticketId);
1732
                activity.setType(ActivityType.COMMUNICATION_IN);
1733
                activity.setCreateTimestamp(LocalDateTime.now());
1734
                this.activityRelatedMail(to, ccTo, subject, message);
1735
                this.activityRelatedMail(retailerService.getFofoRetailer(loginDetails.getFofoId()).getEmail(), null, subject, String.format(PARTNER_REOPEN, ticketId));
1736
            }
1737
 
1738
        }
1739
        activityRepository.persist(activity);
1740
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
1741
        return "response";
1742
    }
1743
 
32812 shampa 1744
 
1745
 
1746
 
1747
 
1748
    @PostMapping(value = "/partner-position/update")
1749
    public String positionUpdated(Model model, @RequestBody List<PartnerPositonUpdateModel> partnerPositionUpdateModels)
1750
            throws Exception {
1751
 
32821 shampa 1752
        Map<Integer, List<String>> positionIdsToAddMap = partnerPositionUpdateModels.stream().filter(x->x.getPositionIdTo()!=0).collect(Collectors.groupingBy(x->x.getPositionIdTo(),
32812 shampa 1753
                Collectors.mapping(x->x.getStoreCode(), Collectors.toList())));
1754
 
32821 shampa 1755
        Map<Integer, List<String>> positionIdsToRemoveMap = partnerPositionUpdateModels.stream().filter(x->x.getPositionIdFrom()!=0).collect(Collectors.groupingBy(x->x.getPositionIdFrom(),
32812 shampa 1756
                Collectors.mapping(x->x.getStoreCode(), Collectors.toList())));
1757
 
1758
        List<Integer> positionIdsToUpdate = new ArrayList<>();
1759
        positionIdsToUpdate.addAll(positionIdsToAddMap.keySet());
1760
        positionIdsToUpdate.addAll(positionIdsToRemoveMap.keySet());
1761
 
35395 amit 1762
        Map<Integer, Position> positionsToUpdateMap =  positionRepository.selectByIds(positionIdsToUpdate).stream().collect(Collectors.toMap(x->x.getId(), x->x));
32812 shampa 1763
        List<Integer> invalidPositionIds = positionsToUpdateMap.values().stream().filter(x-> x.getCategoryId()!= ProfitMandiConstants.TICKET_CATEGORY_RBM
34908 ranu 1764
                && x.getCategoryId() != ProfitMandiConstants.TICKET_CATEGORY_SALES && x.getCategoryId() != ProfitMandiConstants.TICKET_CATEGORY_ABM).map(x -> x.getId()).collect(Collectors.toList());
32812 shampa 1765
        if(invalidPositionIds.size() > 0) {
34908 ranu 1766
            String message = "Non RBM/Sales/ABM are not allowed - " + invalidPositionIds;
32812 shampa 1767
            throw new ProfitMandiBusinessException(message, message, message);
1768
        }
1769
 
1770
        for (Map.Entry<Integer, List<String>> positionIdStoreMapEntry : positionIdsToAddMap.entrySet()) {
1771
            int positionId = positionIdStoreMapEntry.getKey();
1772
            Position position = positionsToUpdateMap.get(positionId);
32821 shampa 1773
            LOGGER.info("positionId - {}, Position - {}", positionId, position);
32812 shampa 1774
            List<String> storeCodesToAdd = positionIdStoreMapEntry.getValue();
1775
            List<Integer> retailerIdsToAdd = fofoStoreRepository.selectByStoreCodes(storeCodesToAdd).stream().map(x->x.getId()).collect(Collectors.toList());
1776
            Map<Integer, PartnerPosition> partnerPositionsMapByFofoId  = partnerPositionRepository
32821 shampa 1777
                    .selectByRegionIdAndPostionId(Arrays.asList(position.getRegionId())
1778
                            ,Arrays.asList(positionId)).stream().collect(Collectors.toMap(x->x.getFofoId(),x->x));
32812 shampa 1779
            for (Integer retailerIdToAdd : retailerIdsToAdd) {
1780
                if (!partnerPositionsMapByFofoId.containsKey(retailerIdToAdd)) {
1781
                    PartnerPosition partnerPositionNew = new PartnerPosition();
1782
                    partnerPositionNew.setPositionId(positionId);
1783
                    partnerPositionNew.setFofoId(retailerIdToAdd);
1784
                    partnerPositionNew.setRegionId(position.getRegionId());
32865 amit.gupta 1785
                    partnerPositionRepository.persist(partnerPositionNew);
32812 shampa 1786
                }
1787
            }
1788
        }
1789
 
1790
        for (Map.Entry<Integer, List<String>> positionIdStoreMapEntry : positionIdsToRemoveMap.entrySet()) {
1791
 
1792
            int positionId = positionIdStoreMapEntry.getKey();
1793
            Position position = positionsToUpdateMap.get(positionId);
1794
            List<String> storeCodesToRemove = positionIdStoreMapEntry.getValue();
1795
            List<Integer> retailerIdsToRemove = fofoStoreRepository.selectByStoreCodes(storeCodesToRemove).stream().map(x->x.getId()).collect(Collectors.toList());
1796
            Map<Integer, PartnerPosition> partnerPositionsMapByFofoId  = partnerPositionRepository
1797
                    .selectByRegionIdAndPostionId(Arrays.asList(position.getRegionId()),Arrays.asList(positionId)).stream().collect(Collectors.toMap(x->x.getFofoId(),x->x));
1798
            for (Integer retailerIdToRemove : retailerIdsToRemove) {
1799
                if (partnerPositionsMapByFofoId.containsKey(retailerIdToRemove)) {
1800
                   PartnerPosition partnerPositionToRemove =  partnerPositionsMapByFofoId.get(retailerIdToRemove);
1801
                   partnerPositionRepository.delete(partnerPositionToRemove);
1802
                }
1803
            }
1804
        }
1805
 
1806
 
1807
 
1808
        /*partnerPositionUpdateModels.str
1809
 
1810
        Map<Integer, Position> positionIdMap = positionsToUpdate.stream().collect(Collectors.toMap(x->x.getId(), x->x));
1811
        for (PartnerPositonUpdateModel partnerPositionUpdateModel : partnerPositionUpdateModels) {
1812
            FofoStore fofoStore = fofoStoreRepository.selectByStoreCode(partnerPositionUpdateModel.getStoreCode());
1813
            Position positionFrom = positionIdMap.get(partnerPositionUpdateModel.getPositionIdFrom());
1814
            Position positionTo = positionIdMap.get(partnerPositionUpdateModel.getPositionIdTo());
1815
            if(positionFrom != null) {
1816
                partnerPositionRepository.selectByRegionIdAndPostionId(Arrays.)
1817
              int regionId = positionFrom.getRegionId()
1818
            }
1819
            if(positionTo != null) {
1820
 
1821
            }
1822
        }*/
1823
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
1824
        return "response";
1825
 
1826
    }
1827
 
35626 amit 1828
    @PostMapping(value = "/cs/markTicketRead")
1829
    @ResponseBody
1830
    public Map<String, Object> markTicketRead(HttpServletRequest request,
1831
                                              @RequestParam(name = "ticketId") int ticketId,
1832
                                              Model model) throws ProfitMandiBusinessException {
1833
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
1834
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
1835
        Map<String, Object> response = new HashMap<>();
32812 shampa 1836
 
35626 amit 1837
        if (isAdmin) {
1838
            AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
1839
            csService.markTicketAsRead(ticketId, authUser.getId(), UserType.AUTH_USER);
1840
        } else {
1841
            csService.markTicketAsRead(ticketId, loginDetails.getFofoId(), UserType.PARTNER);
1842
        }
1843
 
1844
        response.put("success", true);
1845
        return response;
1846
    }
1847
 
1848
    @GetMapping(value = "/cs/unreadCount")
1849
    @ResponseBody
1850
    public Map<String, Object> getUnreadCount(HttpServletRequest request) throws ProfitMandiBusinessException {
1851
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
1852
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
1853
        Map<String, Object> response = new HashMap<>();
1854
 
1855
        List<Ticket> tickets;
1856
        int userId;
1857
        UserType userType;
1858
 
1859
        if (isAdmin) {
1860
            AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
1861
            userId = authUser.getId();
1862
            userType = UserType.AUTH_USER;
1863
            boolean isCrmUser = positionRepository.hasCategory(authUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
1864
            List<Integer> userCategoryIds = positionRepository.selectCategoryIdsByAuthUserId(authUser.getId());
1865
            if (isCrmUser) {
1866
                tickets = ticketRepository.selectAllTicketsPaginated(
1867
                        Optional.of(false), null, null, 0, null,
1868
                        userCategoryIds, 0, 1000);
1869
            } else {
1870
                tickets = ticketRepository.selectAllByAssigneePaginated(
1871
                        authUser.getId(), Optional.of(false), null, null, 0, null,
1872
                        0, 1000);
1873
            }
1874
        } else {
1875
            userId = loginDetails.getFofoId();
1876
            userType = UserType.PARTNER;
1877
            tickets = ticketRepository.selectAllByCreator(loginDetails.getFofoId(), Optional.of(true), null);
1878
        }
1879
 
1880
        Map<Integer, Boolean> unreadMap = csService.getUnreadStatusForTickets(tickets, userId, userType);
1881
        long unreadCount = unreadMap.values().stream().filter(v -> v).count();
1882
 
1883
        response.put("success", true);
1884
        response.put("unreadCount", unreadCount);
1885
        return response;
1886
    }
1887
 
24417 govind 1888
}