Subversion Repositories SmartDukaan

Rev

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