Subversion Repositories SmartDukaan

Rev

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

Rev 37749 Rev 37760
Line 17... Line 17...
17
import com.spice.profitmandi.dao.repository.dtr.LeadLiveLocationRepository;
17
import com.spice.profitmandi.dao.repository.dtr.LeadLiveLocationRepository;
18
import com.spice.profitmandi.dao.entity.cs.Position;
18
import com.spice.profitmandi.dao.entity.cs.Position;
19
import com.spice.profitmandi.dao.entity.cs.Region;
19
import com.spice.profitmandi.dao.entity.cs.Region;
20
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
20
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
21
import com.spice.profitmandi.dao.repository.cs.PositionRepository;
21
import com.spice.profitmandi.dao.repository.cs.PositionRepository;
-
 
22
import com.spice.profitmandi.dao.repository.dtr.RoleRepository;
-
 
23
import com.spice.profitmandi.dao.entity.dtr.Role;
-
 
24
import com.spice.profitmandi.service.authentication.RoleManager;
22
import com.spice.profitmandi.dao.repository.cs.RegionRepository;
25
import com.spice.profitmandi.dao.repository.cs.RegionRepository;
23
import com.spice.profitmandi.dao.entity.user.LeadCallAnswer;
26
import com.spice.profitmandi.dao.entity.user.LeadCallAnswer;
24
import com.spice.profitmandi.dao.entity.user.LeadCallQuestion;
27
import com.spice.profitmandi.dao.entity.user.LeadCallQuestion;
25
import com.spice.profitmandi.dao.repository.dtr.LeadCallChecklistRepository;
28
import com.spice.profitmandi.dao.repository.dtr.LeadCallChecklistRepository;
26
import com.spice.profitmandi.dao.repository.dtr.LeadRepository;
29
import com.spice.profitmandi.dao.repository.dtr.LeadRepository;
Line 131... Line 134...
131
 
134
 
132
    @Autowired
135
    @Autowired
133
    private LmsAssignmentService lmsAssignmentService;
136
    private LmsAssignmentService lmsAssignmentService;
134
 
137
 
135
    @Autowired
138
    @Autowired
-
 
139
    private RoleManager roleManager;
-
 
140
 
-
 
141
    @Autowired
-
 
142
    private RoleRepository roleRepository;
-
 
143
 
-
 
144
    @Autowired
136
    private CookiesProcessor cookiesProcessor;
145
    private CookiesProcessor cookiesProcessor;
137
 
146
 
138
    @Autowired
147
    @Autowired
139
    private ResponseSender<?> responseSender;
148
    private ResponseSender<?> responseSender;
140
 
149
 
Line 729... Line 738...
729
     *
738
     *
730
     * <p>{@code regionId} does not filter the list — it marks who covers that region, so an agent can
739
     * <p>{@code regionId} does not filter the list — it marks who covers that region, so an agent can
731
     * see the right owner first without being prevented from picking someone else. A lead in a
740
     * see the right owner first without being prevented from picking someone else. A lead in a
732
     * region with no active owner still has to go to somebody.
741
     * region with no active owner still has to go to somebody.
733
     */
742
     */
-
 
743
    /**
-
 
744
     * Assign or change the BM/RSM who owns a region. Writes the region's Sales L4 position in
-
 
745
     * {@code cs.position} -- the row the assignment engine reads first (L4 before L5 before L3) --
-
 
746
     * so the routing table, the Create-Lead preview and every future lead pick the new owner at
-
 
747
     * once. An existing L4 row is re-pointed (the region keeps one owner), otherwise one is created.
-
 
748
     * Leads already assigned are untouched; re-route those with {@code /lms/assignLead}.
-
 
749
     *
-
 
750
     * <p>Allowed for FOFO admins, the "Sales Admin" role, and anyone holding a Sales position at L5
-
 
751
     * or above (a sales head). A BM cannot hand a region to themselves.
-
 
752
     */
-
 
753
    @RequestMapping(value = "/lms/region-owner", method = RequestMethod.POST)
-
 
754
    @ResponseBody
-
 
755
    public ResponseEntity<?> setRegionOwner(HttpServletRequest request,
-
 
756
                                            @RequestParam(name = "regionId") int regionId,
-
 
757
                                            @RequestParam(name = "authId") int authId) {
-
 
758
        AuthUser me = currentUser(request);
-
 
759
        if (me == null) {
-
 
760
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
-
 
761
        }
-
 
762
        if (!canManageRegionOwners(request, me)) {
-
 
763
            return ResponseEntity.status(HttpStatus.FORBIDDEN)
-
 
764
                    .body("Only an admin, a Sales Admin or a sales head (L5+) can change a region's owner");
-
 
765
        }
-
 
766
        Region region = regionRepository.selectById(regionId);
-
 
767
        if (region == null) {
-
 
768
            return responseSender.notFound("Region not found");
-
 
769
        }
-
 
770
        AuthUser owner = authRepository.selectById(authId);
-
 
771
        if (owner == null || !Boolean.TRUE.equals(owner.isActive())) {
-
 
772
            return responseSender.badRequest("That person is not an active user");
-
 
773
        }
-
 
774
 
-
 
775
        List<Position> l4 = positionRepository.selectPositionbyCategoryIdAndEscalationType(
-
 
776
                SALES_CATEGORY, EscalationType.L4, regionId);
-
 
777
        Position target = (l4 == null || l4.isEmpty()) ? null : l4.get(0);
-
 
778
        AuthUser previous = null;
-
 
779
        if (target != null) {
-
 
780
            if (target.getAuthUserId() == authId) {
-
 
781
                return responseSender.badRequest(owner.getFullName() + " already owns this region");
-
 
782
            }
-
 
783
            previous = authRepository.selectById(target.getAuthUserId());
-
 
784
            target.setAuthUserId(authId);
-
 
785
        } else {
-
 
786
            target = new Position();
-
 
787
            target.setAuthUserId(authId);
-
 
788
            target.setCategoryId(SALES_CATEGORY);
-
 
789
            target.setEscalationType(EscalationType.L4);
-
 
790
            target.setRegionId(regionId);
-
 
791
            target.setCreateTimestamp(LocalDateTime.now());
-
 
792
            target.setTicketAssignee(false);
-
 
793
        }
-
 
794
        positionRepository.persist(target);
-
 
795
 
-
 
796
        // Report what the engine now resolves for the region, not just what was written.
-
 
797
        LmsAssignmentService.Assignment now = lmsAssignmentService.resolve(regionId);
-
 
798
        LOGGER.info("LMS region {} ({}) owner set to auth {} by auth {}{}", regionId, now.regionCode, authId,
-
 
799
                me.getId(), previous != null ? " (was " + previous.getId() + ")" : " (new L4 position)");
-
 
800
 
-
 
801
        Map<String, Object> res = new LinkedHashMap<>();
-
 
802
        res.put("ok", true);
-
 
803
        res.put("regionId", regionId);
-
 
804
        res.put("regionCode", now.regionCode);
-
 
805
        res.put("bmName", now.bm != null ? now.bm.getFullName() : null);
-
 
806
        res.put("assignmentStatus", now.assignmentStatus);
-
 
807
        res.put("previous", previous != null ? previous.getFullName() : null);
-
 
808
        res.put("created", previous == null);
-
 
809
        return responseSender.ok(res);
-
 
810
    }
-
 
811
 
-
 
812
    /**
-
 
813
     * Who may create leads from the LMS dashboard: FOFO admins, or anyone holding a position (any
-
 
814
     * category) at L2 or above. Mirrors the {@code canCreateLead} flag that hides the tab.
-
 
815
     */
-
 
816
    private boolean canCreateLeads(HttpServletRequest request, AuthUser me) {
-
 
817
        try {
-
 
818
            LoginDetails login = cookiesProcessor.getCookiesObject(request);
-
 
819
            if (login != null && login.getRoleIds() != null && roleManager.isAdmin(login.getRoleIds())) {
-
 
820
                return true;
-
 
821
            }
-
 
822
        } catch (Exception e) {
-
 
823
            LOGGER.warn("Could not read roles for auth {}", me.getId(), e);
-
 
824
        }
-
 
825
        List<Position> held = positionRepository.selectPositionByAuthId(me.getId());
-
 
826
        if (held != null) {
-
 
827
            for (Position p : held) {
-
 
828
                if (p.getEscalationType() != null && p.getEscalationType().ordinal() >= EscalationType.L2.ordinal()) {
-
 
829
                    return true;
-
 
830
                }
-
 
831
            }
-
 
832
        }
-
 
833
        return false;
-
 
834
    }
-
 
835
 
-
 
836
    /** FOFO admin, the "Sales Admin" role, or a Sales position at L5 or above. */
-
 
837
    private boolean canManageRegionOwners(HttpServletRequest request, AuthUser me) {
-
 
838
        try {
-
 
839
            LoginDetails login = cookiesProcessor.getCookiesObject(request);
-
 
840
            Set<Integer> roleIds = login != null && login.getRoleIds() != null ? login.getRoleIds() : new HashSet<>();
-
 
841
            if (roleManager.isAdmin(roleIds)) {
-
 
842
                return true;
-
 
843
            }
-
 
844
            if (!roleIds.isEmpty()) {
-
 
845
                for (Role r : roleRepository.selectByIds(roleIds)) {
-
 
846
                    if (r.getName() != null && "Sales Admin".equalsIgnoreCase(r.getName().trim())) {
-
 
847
                        return true;
-
 
848
                    }
-
 
849
                }
-
 
850
            }
-
 
851
        } catch (Exception e) {
-
 
852
            LOGGER.warn("Could not read roles for auth {}", me.getId(), e);
-
 
853
        }
-
 
854
        List<Position> held = positionRepository.selectPositionByAuthId(me.getId());
-
 
855
        if (held != null) {
-
 
856
            for (Position p : held) {
-
 
857
                if (p.getCategoryId() == SALES_CATEGORY && p.getEscalationType() != null
-
 
858
                        && p.getEscalationType().ordinal() >= EscalationType.L5.ordinal()) {
-
 
859
                    return true;
-
 
860
                }
-
 
861
            }
-
 
862
        }
-
 
863
        return false;
-
 
864
    }
-
 
865
 
734
    @RequestMapping(value = "/lms/salespeople", method = RequestMethod.GET)
866
    @RequestMapping(value = "/lms/salespeople", method = RequestMethod.GET)
735
    @ResponseBody
867
    @ResponseBody
736
    public ResponseEntity<?> salespeople(@RequestParam(name = "regionId", required = false) Integer regionId) {
868
    public ResponseEntity<?> salespeople(@RequestParam(name = "regionId", required = false) Integer regionId) {
737
        List<Position> positions = positionRepository.selectPositionByCategoryId(SALES_CATEGORY);
869
        List<Position> positions = positionRepository.selectPositionByCategoryId(SALES_CATEGORY);
738
        if (positions == null) {
870
        if (positions == null) {
Line 1233... Line 1365...
1233
 
1365
 
1234
        AuthUser me = currentUser(request);
1366
        AuthUser me = currentUser(request);
1235
        if (me == null) {
1367
        if (me == null) {
1236
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
1368
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
1237
        }
1369
        }
-
 
1370
        if (!canCreateLeads(request, me)) {
-
 
1371
            return ResponseEntity.status(HttpStatus.FORBIDDEN)
-
 
1372
                    .body("Creating leads here needs a position at L2 or above");
-
 
1373
        }
1238
 
1374
 
1239
        Lead lead = new Lead();
1375
        Lead lead = new Lead();
1240
        // Split on the last space so "Jitu Katara" keeps a surname; user.lead.last_name is NOT NULL.
1376
        // Split on the last space so "Jitu Katara" keeps a surname; user.lead.last_name is NOT NULL.
1241
        int space = name.lastIndexOf(' ');
1377
        int space = name.lastIndexOf(' ');
1242
        lead.setFirstName(space > 0 ? name.substring(0, space) : name);
1378
        lead.setFirstName(space > 0 ? name.substring(0, space) : name);