| Line 12... |
Line 12... |
| 12 |
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
|
12 |
import com.spice.profitmandi.dao.enumuration.cs.EscalationType;
|
| 13 |
import com.spice.profitmandi.dao.model.*;
|
13 |
import com.spice.profitmandi.dao.model.*;
|
| 14 |
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
|
14 |
import com.spice.profitmandi.dao.repository.auth.AuthRepository;
|
| 15 |
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
|
15 |
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
|
| 16 |
import com.spice.profitmandi.service.user.RetailerService;
|
16 |
import com.spice.profitmandi.service.user.RetailerService;
|
| - |
|
17 |
import com.spice.profitmandi.dao.entity.cs.TicketReadStatus;
|
| - |
|
18 |
import com.spice.profitmandi.dao.entity.cs.TicketReadStatus.UserType;
|
| - |
|
19 |
import com.spice.profitmandi.service.EmailService;
|
| 17 |
import org.apache.commons.collections4.map.HashedMap;
|
20 |
import org.apache.commons.collections4.map.HashedMap;
|
| 18 |
import org.apache.commons.lang.RandomStringUtils;
|
21 |
import org.apache.commons.lang.RandomStringUtils;
|
| 19 |
import org.apache.commons.lang.StringUtils;
|
22 |
import org.apache.commons.lang.StringUtils;
|
| 20 |
import org.apache.logging.log4j.LogManager;
|
23 |
import org.apache.logging.log4j.LogManager;
|
| 21 |
import org.apache.logging.log4j.Logger;
|
24 |
import org.apache.logging.log4j.Logger;
|
| Line 86... |
Line 89... |
| 86 |
private FofoStoreRepository fofoStoreRepository;
|
89 |
private FofoStoreRepository fofoStoreRepository;
|
| 87 |
|
90 |
|
| 88 |
@Autowired
|
91 |
@Autowired
|
| 89 |
private SessionFactory sessionFactory;
|
92 |
private SessionFactory sessionFactory;
|
| 90 |
|
93 |
|
| - |
|
94 |
@Autowired
|
| - |
|
95 |
private TicketReadStatusRepository ticketReadStatusRepository;
|
| - |
|
96 |
|
| - |
|
97 |
@Autowired
|
| - |
|
98 |
private EmailService emailService;
|
| - |
|
99 |
|
| 91 |
@Override
|
100 |
@Override
|
| 92 |
public void createTicket(int fofoId, int categoryId, int subcategoryId, String message) throws ProfitMandiBusinessException {
|
101 |
public void createTicket(int fofoId, int categoryId, int subcategoryId, String message) throws ProfitMandiBusinessException {
|
| 93 |
this.createTicket(fofoId, categoryId, subcategoryId, message, 0);
|
102 |
this.createTicket(fofoId, categoryId, subcategoryId, message, 0);
|
| 94 |
}
|
103 |
}
|
| 95 |
|
104 |
|
| Line 478... |
Line 487... |
| 478 |
@Override
|
487 |
@Override
|
| 479 |
public void addActivity(Ticket ticket, Activity activity) {
|
488 |
public void addActivity(Ticket ticket, Activity activity) {
|
| 480 |
activity.setTicketId(ticket.getId());
|
489 |
activity.setTicketId(ticket.getId());
|
| 481 |
ticket.setLastActivity(activity.getType());
|
490 |
ticket.setLastActivity(activity.getType());
|
| 482 |
ticket.setLastActivityId(activity.getId());
|
491 |
ticket.setLastActivityId(activity.getId());
|
| - |
|
492 |
|
| - |
|
493 |
if (activity.getType() == ActivityType.COMMUNICATION_OUT) {
|
| - |
|
494 |
notifyPartnerOfExternalCommunication(ticket, activity);
|
| - |
|
495 |
}
|
| 483 |
}
|
496 |
}
|
| 484 |
|
497 |
|
| 485 |
private String getRandomString() {
|
498 |
private String getRandomString() {
|
| 486 |
int length = 4;
|
499 |
int length = 4;
|
| 487 |
boolean useLetters = false;
|
500 |
boolean useLetters = false;
|
| Line 1746... |
Line 1759... |
| 1746 |
}
|
1759 |
}
|
| 1747 |
|
1760 |
|
| 1748 |
return result;
|
1761 |
return result;
|
| 1749 |
}
|
1762 |
}
|
| 1750 |
|
1763 |
|
| - |
|
1764 |
@Override
|
| - |
|
1765 |
public Map<Integer, Boolean> getUnreadStatusForTickets(List<Ticket> tickets, int userId, UserType userType) {
|
| - |
|
1766 |
Map<Integer, Boolean> unreadMap = new HashMap<>();
|
| - |
|
1767 |
if (tickets == null || tickets.isEmpty()) {
|
| - |
|
1768 |
return unreadMap;
|
| - |
|
1769 |
}
|
| - |
|
1770 |
|
| - |
|
1771 |
List<Integer> ticketIds = tickets.stream().map(Ticket::getId).collect(Collectors.toList());
|
| - |
|
1772 |
List<TicketReadStatus> readStatuses = ticketReadStatusRepository.selectByTicketIdsAndUser(ticketIds, userId, userType);
|
| - |
|
1773 |
Map<Integer, Integer> ticketLastReadMap = readStatuses.stream()
|
| - |
|
1774 |
.collect(Collectors.toMap(TicketReadStatus::getTicketId, TicketReadStatus::getLastReadActivityId));
|
| - |
|
1775 |
|
| - |
|
1776 |
// Get last activities for all tickets to check who created them
|
| - |
|
1777 |
Map<Integer, Activity> lastActivityMap = getLastActivitiesForTickets(ticketIds);
|
| - |
|
1778 |
|
| - |
|
1779 |
for (Ticket ticket : tickets) {
|
| - |
|
1780 |
int lastActivityId = ticket.getLastActivityId();
|
| - |
|
1781 |
int lastReadActivityId = ticketLastReadMap.getOrDefault(ticket.getId(), 0);
|
| - |
|
1782 |
|
| - |
|
1783 |
if (lastActivityId <= lastReadActivityId) {
|
| - |
|
1784 |
unreadMap.put(ticket.getId(), false);
|
| - |
|
1785 |
continue;
|
| - |
|
1786 |
}
|
| - |
|
1787 |
|
| - |
|
1788 |
// Check if the current user created the last activity (exclude own updates)
|
| - |
|
1789 |
Activity lastActivity = lastActivityMap.get(ticket.getId());
|
| - |
|
1790 |
if (lastActivity != null) {
|
| - |
|
1791 |
if (userType == UserType.AUTH_USER && lastActivity.getCreatedBy() == userId) {
|
| - |
|
1792 |
unreadMap.put(ticket.getId(), false);
|
| - |
|
1793 |
continue;
|
| - |
|
1794 |
}
|
| - |
|
1795 |
if (userType == UserType.PARTNER && lastActivity.getCreatedBy() == 0
|
| - |
|
1796 |
&& lastActivity.getType() == ActivityType.COMMUNICATION_IN) {
|
| - |
|
1797 |
unreadMap.put(ticket.getId(), false);
|
| - |
|
1798 |
continue;
|
| - |
|
1799 |
}
|
| - |
|
1800 |
// For partners: only show as unread if activity type is external communication or resolved
|
| - |
|
1801 |
if (userType == UserType.PARTNER) {
|
| - |
|
1802 |
boolean isRelevantForPartner = ActivityType.PARTNER_ACTIVITIES.contains(lastActivity.getType());
|
| - |
|
1803 |
unreadMap.put(ticket.getId(), isRelevantForPartner);
|
| - |
|
1804 |
continue;
|
| - |
|
1805 |
}
|
| - |
|
1806 |
}
|
| - |
|
1807 |
|
| - |
|
1808 |
unreadMap.put(ticket.getId(), true);
|
| - |
|
1809 |
}
|
| - |
|
1810 |
return unreadMap;
|
| - |
|
1811 |
}
|
| - |
|
1812 |
|
| - |
|
1813 |
@Override
|
| - |
|
1814 |
public void markTicketAsRead(int ticketId, int userId, UserType userType) {
|
| - |
|
1815 |
Ticket ticket = ticketRepository.selectById(ticketId);
|
| - |
|
1816 |
if (ticket == null) {
|
| - |
|
1817 |
return;
|
| - |
|
1818 |
}
|
| - |
|
1819 |
TicketReadStatus readStatus = new TicketReadStatus();
|
| - |
|
1820 |
readStatus.setTicketId(ticketId);
|
| - |
|
1821 |
readStatus.setUserId(userId);
|
| - |
|
1822 |
readStatus.setUserType(userType);
|
| - |
|
1823 |
readStatus.setLastReadActivityId(ticket.getLastActivityId());
|
| - |
|
1824 |
ticketReadStatusRepository.upsert(readStatus);
|
| - |
|
1825 |
}
|
| - |
|
1826 |
|
| - |
|
1827 |
@Override
|
| - |
|
1828 |
public Map<Integer, Activity> getLastActivitiesForTickets(List<Integer> ticketIds) {
|
| - |
|
1829 |
Map<Integer, Activity> lastActivityMap = new HashMap<>();
|
| - |
|
1830 |
if (ticketIds == null || ticketIds.isEmpty()) {
|
| - |
|
1831 |
return lastActivityMap;
|
| - |
|
1832 |
}
|
| - |
|
1833 |
List<Activity> allActivities = activityRepository.selectAll(ticketIds);
|
| - |
|
1834 |
// Group by ticketId and get the last one (highest id)
|
| - |
|
1835 |
Map<Integer, List<Activity>> groupedByTicket = allActivities.stream()
|
| - |
|
1836 |
.collect(Collectors.groupingBy(Activity::getTicketId));
|
| - |
|
1837 |
for (Map.Entry<Integer, List<Activity>> entry : groupedByTicket.entrySet()) {
|
| - |
|
1838 |
Activity lastActivity = entry.getValue().stream()
|
| - |
|
1839 |
.max(Comparator.comparingInt(Activity::getId))
|
| - |
|
1840 |
.orElse(null);
|
| - |
|
1841 |
if (lastActivity != null) {
|
| - |
|
1842 |
lastActivityMap.put(entry.getKey(), lastActivity);
|
| - |
|
1843 |
}
|
| - |
|
1844 |
}
|
| - |
|
1845 |
return lastActivityMap;
|
| - |
|
1846 |
}
|
| - |
|
1847 |
|
| - |
|
1848 |
@Override
|
| - |
|
1849 |
public void notifyPartnerOfExternalCommunication(Ticket ticket, Activity activity) {
|
| - |
|
1850 |
try {
|
| - |
|
1851 |
CustomRetailer partner = retailerService.getFofoRetailer(ticket.getFofoId());
|
| - |
|
1852 |
if (partner == null || partner.getEmail() == null) {
|
| - |
|
1853 |
return;
|
| - |
|
1854 |
}
|
| - |
|
1855 |
|
| - |
|
1856 |
TicketSubCategory ticketSubCategory = ticketSubCategoryRepository.selectById(ticket.getSubCategoryId());
|
| - |
|
1857 |
TicketCategory ticketCategory = ticketCategoryRepository.selectById(ticketSubCategory.getCategoryId());
|
| - |
|
1858 |
|
| - |
|
1859 |
Map<String, Object> model = new HashMap<>();
|
| - |
|
1860 |
model.put("ticketId", ticket.getId());
|
| - |
|
1861 |
model.put("partnerName", partner.getBusinessName());
|
| - |
|
1862 |
model.put("categoryName", ticketCategory.getName());
|
| - |
|
1863 |
model.put("subCategoryName", ticketSubCategory.getName());
|
| - |
|
1864 |
model.put("activityMessage", activity.getMessage());
|
| - |
|
1865 |
|
| - |
|
1866 |
emailService.sendMailWithAttachments(
|
| - |
|
1867 |
"Update on Your Support Ticket #" + ticket.getId(),
|
| - |
|
1868 |
"partner-ticket-update.vm",
|
| - |
|
1869 |
model,
|
| - |
|
1870 |
new String[]{partner.getEmail()},
|
| - |
|
1871 |
null,
|
| - |
|
1872 |
null);
|
| - |
|
1873 |
} catch (Exception e) {
|
| - |
|
1874 |
LOGGER.error("Failed to send partner notification email for ticket {}", ticket.getId(), e);
|
| - |
|
1875 |
}
|
| - |
|
1876 |
}
|
| - |
|
1877 |
|
| 1751 |
}
|
1878 |
}
|