Subversion Repositories SmartDukaan

Rev

Rev 35590 | Rev 35594 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 35590 Rev 35592
Line 504... Line 504...
504
        long size = 0;
504
        long size = 0;
505
        Map<Integer, AuthUser> authUserIdAndAuthUserMap = null;
505
        Map<Integer, AuthUser> authUserIdAndAuthUserMap = null;
506
        boolean isAdmin = roleManager.isAdmin(new HashSet<>(loginDetails.getRoleIds()));
506
        boolean isAdmin = roleManager.isAdmin(new HashSet<>(loginDetails.getRoleIds()));
507
        AuthUser currentAuthUser = isAdmin ? authRepository.selectByEmailOrMobile(loginDetails.getEmailId()) : null;
507
        AuthUser currentAuthUser = isAdmin ? authRepository.selectByEmailOrMobile(loginDetails.getEmailId()) : null;
508
 
508
 
-
 
509
        // Check if user is CRM category - CRM users see ALL tickets to handle partner communications
-
 
510
        boolean isCrmUser = isAdmin && currentAuthUser != null && positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
-
 
511
 
509
        if (isAdmin) {
512
        if (isAdmin) {
510
            int authUserId = currentAuthUser.getId();
513
            int authUserId = currentAuthUser.getId();
-
 
514
 
511
            if (ticketSearchType == null) {
515
            if (isCrmUser) {
-
 
516
                // CRM users see ALL tickets to respond to partner communications
512
                if (ticketStatus.equals(TicketStatus.RESOLVED)) {
517
                if (ticketStatus.equals(TicketStatus.RESOLVED)) {
513
                    tickets = ticketRepository.selectAllByAssignee(authUserId, Optional.empty(), sortOrder, null, searchTerm);
518
                    tickets = ticketRepository.selectAllTickets(Optional.empty(), sortOrder, ticketSearchType, searchTerm);
514
                    size = ticketRepository.selectAllCountByAssignee(authUserId, Optional.empty(), null, searchTerm);
519
                    size = ticketRepository.selectAllTicketsCount(Optional.empty(), ticketSearchType, searchTerm);
515
                } else {
520
                } else {
516
                    tickets = ticketRepository.selectAllByAssignee(authUserId, Optional.of(TicketStatus.CLOSED.equals(ticketStatus)), sortOrder, null, searchTerm);
521
                    tickets = ticketRepository.selectAllTickets(Optional.of(TicketStatus.CLOSED.equals(ticketStatus)), sortOrder, ticketSearchType, searchTerm);
517
                    size = ticketRepository.selectAllCountByAssignee(authUserId, Optional.of(TicketStatus.CLOSED.equals(ticketStatus)), null, searchTerm);
522
                    size = ticketRepository.selectAllTicketsCount(Optional.of(TicketStatus.CLOSED.equals(ticketStatus)), ticketSearchType, searchTerm);
518
                }
523
                }
519
 
-
 
520
            } else {
524
            } else {
521
 
-
 
-
 
525
                // Non-CRM admins see only tickets assigned to them
-
 
526
                if (ticketSearchType == null) {
522
                if (ticketStatus.equals(TicketStatus.RESOLVED)) {
527
                    if (ticketStatus.equals(TicketStatus.RESOLVED)) {
523
                    tickets = ticketRepository.selectAllByAssignee(authUserId, Optional.empty(), sortOrder, ticketSearchType, searchTerm);
528
                        tickets = ticketRepository.selectAllByAssignee(authUserId, Optional.empty(), sortOrder, null, searchTerm);
524
                    size = ticketRepository.selectAllCountByAssignee(authUserId, Optional.empty(), ticketSearchType, searchTerm);
529
                        size = ticketRepository.selectAllCountByAssignee(authUserId, Optional.empty(), null, searchTerm);
-
 
530
                    } else {
-
 
531
                        tickets = ticketRepository.selectAllByAssignee(authUserId, Optional.of(TicketStatus.CLOSED.equals(ticketStatus)), sortOrder, null, searchTerm);
-
 
532
                        size = ticketRepository.selectAllCountByAssignee(authUserId, Optional.of(TicketStatus.CLOSED.equals(ticketStatus)), null, searchTerm);
-
 
533
                    }
525
                } else {
534
                } else {
-
 
535
                    if (ticketStatus.equals(TicketStatus.RESOLVED)) {
-
 
536
                        tickets = ticketRepository.selectAllByAssignee(authUserId, Optional.empty(), sortOrder, ticketSearchType, searchTerm);
-
 
537
                        size = ticketRepository.selectAllCountByAssignee(authUserId, Optional.empty(), ticketSearchType, searchTerm);
-
 
538
                    } else {
526
                    tickets = ticketRepository.selectAllByAssignee(authUserId, Optional.of(TicketStatus.CLOSED.equals(ticketStatus)), sortOrder, ticketSearchType, searchTerm);
539
                        tickets = ticketRepository.selectAllByAssignee(authUserId, Optional.of(TicketStatus.CLOSED.equals(ticketStatus)), sortOrder, ticketSearchType, searchTerm);
527
                    size = ticketRepository.selectAllCountByAssignee(authUserId, Optional.of(TicketStatus.CLOSED.equals(ticketStatus)), ticketSearchType, searchTerm);
540
                        size = ticketRepository.selectAllCountByAssignee(authUserId, Optional.of(TicketStatus.CLOSED.equals(ticketStatus)), ticketSearchType, searchTerm);
-
 
541
                    }
528
                }
542
                }
529
            }
543
            }
530
            // LOGGER.info(size + "size");
544
            // LOGGER.info(size + "size");
531
            if (tickets.size() > 0) {
545
            if (tickets.size() > 0) {
532
                ticketAssigneds = ticketAssignedRepository.selectByTicketIds(tickets.stream().map(x -> x.getId()).collect(Collectors.toList()));
546
                ticketAssigneds = ticketAssignedRepository.selectByTicketIds(tickets.stream().map(x -> x.getId()).collect(Collectors.toList()));
Line 544... Line 558...
544
            authUserIdAndAuthUserMap = new HashMap<>();
558
            authUserIdAndAuthUserMap = new HashMap<>();
545
        }
559
        }
546
 
560
 
547
        model.addAttribute("size", size);
561
        model.addAttribute("size", size);
548
        model.addAttribute("roleType", isAdmin);
562
        model.addAttribute("roleType", isAdmin);
549
        // Check if user is in CRM category (only CRM can send external communications)
563
        // isCrmUser already calculated at start of method
550
        boolean isCrmUser = isAdmin && currentAuthUser != null && positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
-
 
551
        model.addAttribute("isCrmUser", isCrmUser);
564
        model.addAttribute("isCrmUser", isCrmUser);
552
 
565
 
553
        List<Integer> subCategoryIds = tickets.stream().map(x -> x.getSubCategoryId()).collect(Collectors.toList());
566
        List<Integer> subCategoryIds = tickets.stream().map(x -> x.getSubCategoryId()).collect(Collectors.toList());
554
        Map<Integer, TicketSubCategory> subCategoryIdAndSubCategoryMap = csService.getSubCategoryIdAndSubCategoryMap(subCategoryIds);
567
        Map<Integer, TicketSubCategory> subCategoryIdAndSubCategoryMap = csService.getSubCategoryIdAndSubCategoryMap(subCategoryIds);
555
        if (subCategoryIdAndSubCategoryMap == null) {
568
        if (subCategoryIdAndSubCategoryMap == null) {
Line 607... Line 620...
607
    }
620
    }
608
 
621
 
609
 
622
 
610
    @GetMapping(value = "/cs/getActivities")
623
    @GetMapping(value = "/cs/getActivities")
611
    public String getActivity(HttpServletRequest request, @RequestParam(name = "ticketId", defaultValue = "0") int ticketId, Model model) throws Exception {
624
    public String getActivity(HttpServletRequest request, @RequestParam(name = "ticketId", defaultValue = "0") int ticketId, Model model) throws Exception {
-
 
625
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
-
 
626
        Ticket ticket = ticketRepository.selectById(ticketId);
-
 
627
 
-
 
628
        if (ticket == null) {
-
 
629
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Ticket not found");
-
 
630
        }
-
 
631
 
-
 
632
        // Authorization check: verify user has access to this ticket
-
 
633
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
-
 
634
        if (!isAdmin) {
-
 
635
            // Partners can only view their own tickets
-
 
636
            if (ticket.getFofoId() != loginDetails.getFofoId()) {
-
 
637
                throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to view this ticket");
-
 
638
            }
-
 
639
        } else {
-
 
640
            // Admins must be assigned to the ticket OR be CRM user OR be in the escalation chain
-
 
641
            AuthUser currentAuthUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
-
 
642
            boolean isCrmUser = positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
-
 
643
 
-
 
644
            if (!isCrmUser) {
-
 
645
                // Check if user is assigned or in escalation chain
-
 
646
                List<TicketAssigned> assignments = ticketAssignedRepository.selectByTicketIds(Arrays.asList(ticketId));
-
 
647
                boolean isAssigned = assignments.stream().anyMatch(ta -> ta.getAssineeId() == currentAuthUser.getId() || ta.getManagerId() == currentAuthUser.getId());
-
 
648
                boolean isInEscalationChain = ticket.getL1AuthUser() == currentAuthUser.getId() ||
-
 
649
                        ticket.getL2AuthUser() == currentAuthUser.getId() ||
-
 
650
                        ticket.getL3AuthUser() == currentAuthUser.getId() ||
-
 
651
                        ticket.getL4AuthUser() == currentAuthUser.getId() ||
-
 
652
                        ticket.getL5AuthUser() == currentAuthUser.getId();
-
 
653
 
-
 
654
                if (!isAssigned && !isInEscalationChain) {
-
 
655
                    throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to view this ticket");
-
 
656
                }
-
 
657
            }
-
 
658
        }
-
 
659
 
612
        List<Activity> allactivities = activityRepository.selectAll(ticketId);
660
        List<Activity> allactivities = activityRepository.selectAll(ticketId);
613
 
661
 
614
        // Batch fetch all documents for attachments (fix N+1 query)
662
        // Batch fetch all documents for attachments (fix N+1 query)
615
        List<Integer> documentIds = allactivities.stream()
663
        List<Integer> documentIds = allactivities.stream()
616
                .flatMap(a -> a.getActivityAttachment().stream())
664
                .flatMap(a -> a.getActivityAttachment().stream())
Line 632... Line 680...
632
                    attachment.setDocumentName(document.getDisplayName());
680
                    attachment.setDocumentName(document.getDisplayName());
633
                }
681
                }
634
            }
682
            }
635
        }
683
        }
636
        List<Activity> activities = null;
684
        List<Activity> activities = null;
637
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
-
 
638
        if (roleManager.isAdmin(loginDetails.getRoleIds())) {
685
        if (isAdmin) {
639
            Set<Integer> authUserIds = allactivities.stream().map(x -> x.getCreatedBy()).collect(Collectors.toSet());
686
            Set<Integer> authUserIds = allactivities.stream().map(x -> x.getCreatedBy()).collect(Collectors.toSet());
640
            List<AuthUser> users = authRepository.selectByIds(new ArrayList<>(authUserIds));
687
            List<AuthUser> users = authRepository.selectByIds(new ArrayList<>(authUserIds));
641
            Map<Integer, String> authUserNameMap = users.stream().collect(Collectors.toMap(AuthUser::getId, x -> x.getFirstName() + " " + x.getLastName()));
688
            Map<Integer, String> authUserNameMap = users.stream().collect(Collectors.toMap(AuthUser::getId, x -> x.getFirstName() + " " + x.getLastName()));
642
            allactivities.stream().forEach(x -> x.setName(authUserNameMap.get(x.getCreatedBy())));
689
            allactivities.stream().forEach(x -> x.setName(authUserNameMap.get(x.getCreatedBy())));
643
            activities = allactivities;
690
            activities = allactivities;
Line 658... Line 705...
658
                                 Model model) throws Exception {
705
                                 Model model) throws Exception {
659
 
706
 
660
        LOGGER.info("documentIds" + documentIds);
707
        LOGGER.info("documentIds" + documentIds);
661
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
708
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
662
        Ticket ticket = ticketRepository.selectById(ticketId);
709
        Ticket ticket = ticketRepository.selectById(ticketId);
-
 
710
 
-
 
711
        if (ticket == null) {
-
 
712
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Ticket not found");
-
 
713
        }
-
 
714
 
-
 
715
        // Authorization check: verify user has access to add activity to this ticket
-
 
716
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
-
 
717
        if (!isAdmin) {
-
 
718
            // Partners can only add activity to their own tickets
-
 
719
            if (ticket.getFofoId() != loginDetails.getFofoId()) {
-
 
720
                throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to add activity to this ticket");
-
 
721
            }
-
 
722
        } else {
-
 
723
            // Admins must be assigned to the ticket OR be CRM user OR be in the escalation chain
-
 
724
            AuthUser currentAuthUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
-
 
725
            boolean isCrmUser = positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
-
 
726
 
-
 
727
            if (!isCrmUser) {
-
 
728
                List<TicketAssigned> assignments = ticketAssignedRepository.selectByTicketIds(Arrays.asList(ticketId));
-
 
729
                boolean isAssigned = assignments.stream().anyMatch(ta -> ta.getAssineeId() == currentAuthUser.getId() || ta.getManagerId() == currentAuthUser.getId());
-
 
730
                boolean isInEscalationChain = ticket.getL1AuthUser() == currentAuthUser.getId() ||
-
 
731
                        ticket.getL2AuthUser() == currentAuthUser.getId() ||
-
 
732
                        ticket.getL3AuthUser() == currentAuthUser.getId() ||
-
 
733
                        ticket.getL4AuthUser() == currentAuthUser.getId() ||
-
 
734
                        ticket.getL5AuthUser() == currentAuthUser.getId();
-
 
735
 
-
 
736
                if (!isAssigned && !isInEscalationChain) {
-
 
737
                    throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to add activity to this ticket");
-
 
738
                }
-
 
739
            }
-
 
740
        }
663
        List<TicketAssigned> ticketAssignedList = ticketAssignedRepository.selectByTicketIds(Arrays.asList(ticketId));
741
        List<TicketAssigned> ticketAssignedList = ticketAssignedRepository.selectByTicketIds(Arrays.asList(ticketId));
664
        List<Integer> authUserIds = ticketAssignedList.stream().map(x -> x.getAssineeId()).collect(Collectors.toList());
742
        List<Integer> authUserIds = ticketAssignedList.stream().map(x -> x.getAssineeId()).collect(Collectors.toList());
665
        authUserIds.add(ticketAssignedList.get(ticketAssignedList.size() - 1).getManagerId());
743
        authUserIds.add(ticketAssignedList.get(ticketAssignedList.size() - 1).getManagerId());
666
        Map<Integer, AuthUser> authUsersMap = authRepository.selectByIds(authUserIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
744
        Map<Integer, AuthUser> authUsersMap = authRepository.selectByIds(authUserIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
667
        if (ticket.getCloseTimestamp() == null) {
745
        if (ticket.getCloseTimestamp() == null) {
Line 726... Line 804...
726
        }
804
        }
727
    }
805
    }
728
 
806
 
729
    @PostMapping(value = "/cs/closeTicket")
807
    @PostMapping(value = "/cs/closeTicket")
730
    public String closeTicket(HttpServletRequest request, @RequestParam(name = "ticketId", defaultValue = "0") int ticketId, @RequestParam(name = "happyCode") String happyCode, Model model) throws Exception {
808
    public String closeTicket(HttpServletRequest request, @RequestParam(name = "ticketId", defaultValue = "0") int ticketId, @RequestParam(name = "happyCode") String happyCode, Model model) throws Exception {
-
 
809
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
731
        Ticket ticket = ticketRepository.selectById(ticketId);
810
        Ticket ticket = ticketRepository.selectById(ticketId);
-
 
811
 
-
 
812
        if (ticket == null) {
-
 
813
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Ticket not found");
-
 
814
        }
-
 
815
 
-
 
816
        // Authorization check: only the ticket owner (partner) can close the ticket
-
 
817
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
-
 
818
        if (isAdmin) {
-
 
819
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Only partners can close tickets using happy code");
-
 
820
        }
-
 
821
 
-
 
822
        // Verify the partner owns this ticket
-
 
823
        if (ticket.getFofoId() != loginDetails.getFofoId()) {
-
 
824
            throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to close this ticket");
-
 
825
        }
-
 
826
 
732
        if (ticket.getHappyCode().equals(happyCode)) {
827
        if (ticket.getHappyCode().equals(happyCode)) {
733
            ticket.setCloseTimestamp(LocalDateTime.now());
828
            ticket.setCloseTimestamp(LocalDateTime.now());
734
            ticketRepository.persist(ticket);
829
            ticketRepository.persist(ticket);
735
            model.addAttribute("response1", mvcResponseSender.createResponseString(true));
830
            model.addAttribute("response1", mvcResponseSender.createResponseString(true));
736
        } else {
831
        } else {
Line 948... Line 1043...
948
    }
1043
    }
949
 
1044
 
950
    @PostMapping(value = "/cs/edit-ticket")
1045
    @PostMapping(value = "/cs/edit-ticket")
951
    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 {
1046
    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 {
952
        LOGGER.info("Ticket Id {}, CategoryId {}, SubCategory Id {} authUserId {}", ticketId, categoryId, subCategoryId, authUserId);
1047
        LOGGER.info("Ticket Id {}, CategoryId {}, SubCategory Id {} authUserId {}", ticketId, categoryId, subCategoryId, authUserId);
-
 
1048
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
-
 
1049
 
-
 
1050
        // Only admins can edit tickets
-
 
1051
        if (!roleManager.isAdmin(loginDetails.getRoleIds())) {
-
 
1052
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Only admins can edit tickets");
-
 
1053
        }
-
 
1054
 
953
        Ticket ticket = ticketRepository.selectById(ticketId);
1055
        Ticket ticket = ticketRepository.selectById(ticketId);
-
 
1056
        if (ticket == null) {
-
 
1057
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Ticket not found");
-
 
1058
        }
-
 
1059
 
-
 
1060
        // Verify admin has access to this ticket (assigned, manager, escalation chain, or CRM)
-
 
1061
        AuthUser currentAuthUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
-
 
1062
        boolean isCrmUser = positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
-
 
1063
 
-
 
1064
        if (!isCrmUser) {
-
 
1065
            List<TicketAssigned> assignments = ticketAssignedRepository.selectByTicketIds(Arrays.asList(ticketId));
-
 
1066
            boolean isAssigned = assignments.stream().anyMatch(ta -> ta.getAssineeId() == currentAuthUser.getId() || ta.getManagerId() == currentAuthUser.getId());
-
 
1067
            boolean isInEscalationChain = ticket.getL1AuthUser() == currentAuthUser.getId() ||
-
 
1068
                    ticket.getL2AuthUser() == currentAuthUser.getId() ||
-
 
1069
                    ticket.getL3AuthUser() == currentAuthUser.getId() ||
-
 
1070
                    ticket.getL4AuthUser() == currentAuthUser.getId() ||
-
 
1071
                    ticket.getL5AuthUser() == currentAuthUser.getId();
-
 
1072
 
-
 
1073
            if (!isAssigned && !isInEscalationChain) {
-
 
1074
                throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to edit this ticket");
-
 
1075
            }
-
 
1076
        }
-
 
1077
 
954
        csService.updateTicket(categoryId, subCategoryId, ticket, authUserId, escalationType);
1078
        csService.updateTicket(categoryId, subCategoryId, ticket, authUserId, escalationType);
955
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
1079
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
956
        return "response";
1080
        return "response";
957
 
1081
 
958
    }
1082
    }
959
 
1083
 
960
    @PostMapping(value = "/cs/edit-partner-ticket")
1084
    @PostMapping(value = "/cs/edit-partner-ticket")
961
    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 {
1085
    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 {
962
        LOGGER.info("Ticket Id {}, CategoryId {}, SubCategory Id {} authUserId {}", ticketId, categoryId, subCategoryId, authUserId);
1086
        LOGGER.info("Ticket Id {}, CategoryId {}, SubCategory Id {} authUserId {}", ticketId, categoryId, subCategoryId, authUserId);
-
 
1087
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
-
 
1088
 
-
 
1089
        // Only admins can edit partner tickets
-
 
1090
        if (!roleManager.isAdmin(loginDetails.getRoleIds())) {
-
 
1091
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Only admins can edit partner tickets");
-
 
1092
        }
-
 
1093
 
963
        Ticket ticket = ticketRepository.selectById(ticketId);
1094
        Ticket ticket = ticketRepository.selectById(ticketId);
-
 
1095
        if (ticket == null) {
-
 
1096
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Ticket not found");
-
 
1097
        }
-
 
1098
 
-
 
1099
        // Verify admin has access (must be in Sales, ABM, or RBM position for the partner)
-
 
1100
        AuthUser currentAuthUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
-
 
1101
        Map<String, Set<Integer>> authUserPartnerMap = csService.getAuthUserPartnerIdMapping();
-
 
1102
        Set<Integer> allowedPartnerIds = authUserPartnerMap.get(currentAuthUser.getEmailId());
-
 
1103
 
-
 
1104
        if (allowedPartnerIds == null || !allowedPartnerIds.contains(ticket.getFofoId())) {
-
 
1105
            // Also allow CRM users
-
 
1106
            boolean isCrmUser = positionRepository.hasCategory(currentAuthUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
-
 
1107
            if (!isCrmUser) {
-
 
1108
                throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to edit this partner's ticket");
-
 
1109
            }
-
 
1110
        }
-
 
1111
 
964
        csService.updateTicket(categoryId, subCategoryId, ticket, authUserId, escalationType);
1112
        csService.updateTicket(categoryId, subCategoryId, ticket, authUserId, escalationType);
965
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
1113
        model.addAttribute("response1", mvcResponseSender.createResponseString(true));
966
        return "response";
1114
        return "response";
967
 
1115
 
968
    }
1116
    }
Line 989... Line 1137...
989
 
1137
 
990
    @PostMapping(value = "/cs/create-last-activity")
1138
    @PostMapping(value = "/cs/create-last-activity")
991
    public String createlastActivity(HttpServletRequest request, @RequestParam(name = "ticketId") int ticketId, @RequestParam(name = "lastactivity") ActivityType lastActivity, Model model) throws Exception {
1139
    public String createlastActivity(HttpServletRequest request, @RequestParam(name = "ticketId") int ticketId, @RequestParam(name = "lastactivity") ActivityType lastActivity, Model model) throws Exception {
992
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
1140
        LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
993
        Ticket ticket = ticketRepository.selectById(ticketId);
1141
        Ticket ticket = ticketRepository.selectById(ticketId);
-
 
1142
 
-
 
1143
        if (ticket == null) {
-
 
1144
            throw new ProfitMandiBusinessException("Ticket", ticketId, "Ticket not found");
-
 
1145
        }
-
 
1146
 
-
 
1147
        // Authorization check for partners: can only update their own tickets
-
 
1148
        boolean isAdmin = roleManager.isAdmin(loginDetails.getRoleIds());
-
 
1149
        if (!isAdmin && ticket.getFofoId() != loginDetails.getFofoId()) {
-
 
1150
            throw new ProfitMandiBusinessException("Ticket", ticketId, "You do not have permission to update this ticket");
-
 
1151
        }
-
 
1152
 
994
        Activity activity = new Activity();
1153
        Activity activity = new Activity();
995
        String subject = String.format(ACTIVITY_SUBJECT, ticket.getId());
1154
        String subject = String.format(ACTIVITY_SUBJECT, ticket.getId());
-
 
1155
        if (isAdmin) {
-
 
1156
            // Only CRM team members can mark tickets as resolved
996
        if (roleManager.isAdmin(loginDetails.getRoleIds())) {
1157
            AuthUser authUser = authRepository.selectByEmailOrMobile(loginDetails.getEmailId());
-
 
1158
            boolean isCrmUser = positionRepository.hasCategory(authUser.getId(), ProfitMandiConstants.TICKET_CATEGORY_CRM);
-
 
1159
            if (!isCrmUser) {
-
 
1160
                throw new ProfitMandiBusinessException("Ticket", ticketId, "Only CRM team members can mark tickets as resolved");
-
 
1161
            }
997
            ticket.setLastActivity(lastActivity);
1162
            ticket.setLastActivity(lastActivity);
998
            String to = retailerService.getFofoRetailer(ticket.getFofoId()).getEmail();
1163
            String to = retailerService.getFofoRetailer(ticket.getFofoId()).getEmail();
999
            String message = String.format(PARTNER_RESOLVED_TICKET_MAIL, ticketId, "REOPEN");
1164
            String message = String.format(PARTNER_RESOLVED_TICKET_MAIL, ticketId, "REOPEN");
1000
            activity.setMessage(message);
1165
            activity.setMessage(message);
1001
            activity.setCreatedBy(authRepository.selectByEmailOrMobile(loginDetails.getEmailId()).getId());
1166
            activity.setCreatedBy(authUser.getId());
1002
            activity.setTicketId(ticketId);
1167
            activity.setTicketId(ticketId);
1003
            activity.setCreateTimestamp(LocalDateTime.now());
1168
            activity.setCreateTimestamp(LocalDateTime.now());
1004
            activity.setType(ActivityType.COMMUNICATION_OUT);
1169
            activity.setType(ActivityType.COMMUNICATION_OUT);
1005
            this.activityRelatedMail(to, null, subject, message);
1170
            this.activityRelatedMail(to, null, subject, message);
1006
        } else {
1171
        } else {