Browse Source

Changes in socialmedia module

main
Hariprasath S 4 months ago
parent
commit
90705ac22c
  1. 69
      gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/callcenterqaqc/controller/QaqcCallsController.java
  2. 65
      gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/callcenterqaqc/controller/SocialMediaApiController.java
  3. 9
      gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/callcenterqaqc/controller/SocialMediaMainController.java
  4. 623
      gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/callcenterqaqc/service/SocialMediaService.java
  5. 4
      gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/configuration/DataSourceConfig.java
  6. 1
      gcc_officer_portal/src/main/resources/application.properties
  7. 217
      gcc_officer_portal/src/main/resources/templates/modules/callcenterqaqc/socialmediacomplaints.html
  8. 805
      gcc_officer_portal/src/main/resources/templates/modules/callcenterqaqc/socialmediaregcompclosing.html

69
gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/callcenterqaqc/controller/QaqcCallsController.java

@ -1,5 +1,7 @@
package in.gov.chennaicorporation.gccoffice.callcenterqaqc.controller; package in.gov.chennaicorporation.gccoffice.callcenterqaqc.controller;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -106,6 +108,18 @@ public class QaqcCallsController {
} }
} }
if("FOLLOWUP".equals(action)) {
String pname = (String) complaintDetails.get("complaint_person_name");
String mob_no = (String) complaintDetails.get("complaint_mobilenumber");
String cat = (String) complaintDetails.get("complaint_type");
String result = sendWhatsappMsg(pname, cat, mob_no, complaintNumber);
if(result.equals("200")) {
System.out.println("Followup Whatsapp Complaint Triggered for "+complaintNumber);
}
}
// Execute common update methods // Execute common update methods
qaqcCallsService.updateComplaintDetails(complaintNumber, dataId, action,remarks,updated_agent); qaqcCallsService.updateComplaintDetails(complaintNumber, dataId, action,remarks,updated_agent);
@ -444,5 +458,60 @@ public class QaqcCallsController {
* System.out.println("Request URL: " + url); * System.out.println("Request URL: " + url);
* *
*/ */
private String sendWhatsappMsg(String pname,String cat,String mob_no, String complaintNumber) {
String urlString = "";
//urlString="https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=5c995535-6244-11f0-98fc-02c8a5e042bd&from=919445061913&to="+mob_no+"&templateid=3285616&type=template&placeholders="+pname+"||"+cat+"||"+complaintNumber+"&button_placeholder="+complaintNumber;
try {
String placeholders =
URLEncoder.encode(
pname + "|~|" + cat + "|~|" + complaintNumber,
StandardCharsets.UTF_8.toString());
String buttonPlaceholder =
URLEncoder.encode(
complaintNumber,
StandardCharsets.UTF_8.toString());
String mobile =
URLEncoder.encode(
mob_no,
StandardCharsets.UTF_8.toString());
urlString="https://sendapiv1.pinbot.ai/pinwa/sendMessage?apikey=5c995535-6244-11f0-98fc-02c8a5e042bd&from=919445061913&to="+mobile+"&templateid=3285616&type=template&placeholders="+placeholders+"&button_placeholder="+buttonPlaceholder;
String res = hitURL(urlString);
return res;
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
private String hitURL(String urlString) {
String response = "";
try {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
response = String.valueOf(responseCode);
//System.out.println("Response Code for URL: " + urlString + " is " + responseCode);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("response=" + response);
return response;
}
} }

65
gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/callcenterqaqc/controller/SocialMediaApiController.java

@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@ -273,7 +274,7 @@ public class SocialMediaApiController {
String url="https://erp.chennaicorporation.gov.in/pgr/newmobileservice?serviceId=ms_dashboard_details&From_date="+formattedFromDate+"&To_date="+formattedToDate+"&jsonResp=Yes&Status="+status+"&isQcuser=Yes"+"&ComplaintType="+type+"&ComplaintGroupId="+group+"&compmode="+mode+"&Zoneid="+zone+"&RegionId="+region; String url="https://erp.chennaicorporation.gov.in/pgr/newmobileservice?serviceId=ms_dashboard_details&From_date="+formattedFromDate+"&To_date="+formattedToDate+"&jsonResp=Yes&Status="+status+"&isQcuser=Yes"+"&ComplaintType="+type+"&ComplaintGroupId="+group+"&compmode="+mode+"&Zoneid="+zone+"&RegionId="+region;
//System.out.println(url);
System.out.println("url==="+url);
RestTemplate restTemplate = new RestTemplate(); RestTemplate restTemplate = new RestTemplate();
@ -290,13 +291,15 @@ public class SocialMediaApiController {
Map<String, Object> responseMap = objectMapper.readValue(rawResponse, Map.class); Map<String, Object> responseMap = objectMapper.readValue(rawResponse, Map.class);
List<Map<String, Object>> details; List<Map<String, Object>> details;
details = (List<Map<String, Object>>) responseMap.get("Details"); details = (List<Map<String, Object>>) responseMap.get("Details");
//System.out.println(details);
System.out.println("details="+details);
if (details != null) {
if(status.equals("redressed") || status.equals("closed")) { if(status.equals("redressed") || status.equals("closed")) {
details=socialservice.getfiltreddetails(details); details=socialservice.getfiltreddetails(details);
} }
}
if (details == null) { if (details == null) {
response.put("status", "nodata"); response.put("status", "nodata");
@ -402,4 +405,60 @@ public class SocialMediaApiController {
} }
} }
@GetMapping("/checkregisteredcomplaint")
public Map<String, Object> checkRegisteredComplaint(
@RequestParam String complaintNumber) {
return socialservice.checkRegisteredComplaint(complaintNumber);
}
@PostMapping("/submitRegClosingComplaint")
public Map<String, Object> submitRegClosingComplaint(
@RequestParam String complaintNumber,
@RequestParam String remarks,
@RequestParam MultipartFile resolvedImage,
@RequestParam String cby) {
return socialservice.submitRegClosingComplaint(
complaintNumber,
remarks,
resolvedImage,
cby);
}
@GetMapping("/getfilteredregcomps")
public Map<String, Object> getFilteredRegComps() {
return socialservice.getFilteredRegComps();
}
@PostMapping("/approveComplaint")
@ResponseBody
public Map<String, Object> approveComplaint(
@RequestParam String complaintId,
@RequestParam String remarks,
@RequestParam String imgFullPath,
@RequestParam String userid
) {
return socialservice.approveComplaint(
complaintId,
remarks,
imgFullPath,
userid);
}
@PostMapping("/rejectComplaint")
public Map<String, Object> rejectComplaint(
@RequestParam String complaintId,
@RequestParam String userid
) {
return socialservice.rejectComplaint(
complaintId,
userid);
}
} }

9
gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/callcenterqaqc/controller/SocialMediaMainController.java

@ -37,5 +37,14 @@ public class SocialMediaMainController {
return "modules/callcenterqaqc/socialmediacompletedlist"; return "modules/callcenterqaqc/socialmediacompletedlist";
} }
@GetMapping("/regcompclosing")
public String viewregCompClosing(Model model) {
String userId = LoginUserInfo.getLoginUserId();
model.addAttribute("userId", userId);
return "modules/callcenterqaqc/socialmediaregcompclosing";
}
} }

623
gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/callcenterqaqc/service/SocialMediaService.java

@ -2,30 +2,81 @@ package in.gov.chennaicorporation.gccoffice.callcenterqaqc.service;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.HashMap; import java.util.HashMap;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.env.Environment;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import in.gov.chennaicorporation.gccoffice.vendor.service.DateTimeUtil;
@Service @Service
@Transactional @Transactional
public class SocialMediaService { public class SocialMediaService {
private final RestTemplate restTemplate;
@Autowired @Autowired
private JdbcTemplate jdbcTemplate; private JdbcTemplate jdbcTemplate;
@Autowired @Autowired
public void setDataSource(@Qualifier("mysql1913QAQCDataSource") DataSource dataSource) { public void setDataSource(@Qualifier("mysql1913QAQCDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource); this.jdbcTemplate = new JdbcTemplate(dataSource);
} }
@Autowired
@Qualifier("vendorDateTimeUtil")
private DateTimeUtil dateTimeUtil;
private final Environment environment;
private String fileBaseUrl;
public SocialMediaService(Environment environment,RestTemplate restTemplate) {
this.restTemplate=restTemplate;
this.environment = environment;
this.fileBaseUrl = environment.getProperty("fileBaseUrl");
}
@Transactional @Transactional
public int uploadComplaintDetailsInLogs(Map<String, Object> details,String action,String remarks,int updated_agent,String remainderDate) { public int uploadComplaintDetailsInLogs(Map<String, Object> details,String action,String remarks,int updated_agent,String remainderDate) {
//System.out.println("Complaint Details: " + details); //System.out.println("Complaint Details: " + details);
@ -90,7 +141,7 @@ public class SocialMediaService {
public String getErpusernamebyId(String userId) { public String getErpusernamebyId(String userId) {
String query="SELECT erp_username FROM gcc_1913_qaqc.agents_list\r\n"
String query="SELECT erp_username FROM gcc_1913_qaqc.agents_list "
+ "where calling_type='SOCIALMEDIA' and agent_id=?"; + "where calling_type='SOCIALMEDIA' and agent_id=?";
//System.out.println("query====="+query); //System.out.println("query====="+query);
@ -100,6 +151,19 @@ public class SocialMediaService {
return erpUsername; return erpUsername;
} }
public String get1913AdminErpusernamebyId(String userId) {
String query="SELECT erp_username FROM gcc_1913_qaqc.agents_list "
+ "where agent_id=?";
//System.out.println("query====="+query);
//String erpUsername = jdbcTemplate.queryForObject(query,new Object[]{userId},String.class);
String erpUsername = jdbcTemplate.queryForObject(query,String.class,userId);
return erpUsername;
}
public List<Map<String, Object>> getA1dropdowns() { public List<Map<String, Object>> getA1dropdowns() {
String sql="SELECT * FROM call_status WHERE isactive=1 AND isdelete=0 AND call_category_id=5"; String sql="SELECT * FROM call_status WHERE isactive=1 AND isdelete=0 AND call_category_id=5";
@ -128,6 +192,10 @@ public class SocialMediaService {
if (followupData == null || followupData.isEmpty()) { if (followupData == null || followupData.isEmpty()) {
return details; return details;
} }
// if(details.isEmpty()) {
// return details;
// }
LocalDate currentDate = LocalDate.now(); LocalDate currentDate = LocalDate.now();
@ -195,6 +263,559 @@ public class SocialMediaService {
return jdbcTemplate.queryForList(sqlQuery); return jdbcTemplate.queryForList(sqlQuery);
} }
public Map<String, Object> checkRegisteredComplaint(String complaintNumber) {
Map<String, Object> result = new HashMap<>();
String sql = "SELECT is_processed "
+ " FROM socialmedia_reg_completed "
+ " WHERE complaint_number = ? AND isactive=1 AND isdelete=0 "
+ " LIMIT 1";
List<Map<String, Object>> list =
jdbcTemplate.queryForList(sql, complaintNumber);
// Case 1
if (list.isEmpty()) {
result.put("status", "NOT_FOUND");
return result;
}
Boolean isProcessed = (Boolean) list.get(0).get("is_processed");
if (!isProcessed) {
result.put("status", "PENDING_APPROVAL");
} else {
result.put("status", "PROCESSED");
}
return result;
}
public Map<String, Object> submitRegClosingComplaint(
String complaintNumber,
String remarks,
MultipartFile resolvedImage,
String cby) {
Map<String, Object> response = new HashMap<>();
try {
Integer loginId = Integer.parseInt(cby);
String imagePath = fileUpload(resolvedImage, "resolved_img");
String sql = "INSERT INTO socialmedia_reg_completed "
+ "(complaint_number, resolved_img, remarks, cby) "
+ "VALUES (?, ?, ?, ?)";
int rows = jdbcTemplate.update(
sql,
complaintNumber,
imagePath,
remarks,
loginId
);
if (rows > 0) {
response.put("status", "SUCCESS");
response.put("message", "Complaint submitted successfully for admin approval.");
} else {
response.put("status", "FAILED");
response.put("message", "Unable to submit complaint.");
}
} catch (Exception e) {
e.printStackTrace();
response.put("status", "error");
response.put("message", e.getMessage() != null
? e.getMessage()
: "Something went wrong while submitting complaint.");
}
return response;
}
public String fileUpload(MultipartFile file, String name) {
// Set the file path where you want to save it
String uploadDirectory = environment.getProperty("file.upload.directory");
String serviceFolderName = environment.getProperty("socialmedia_1913_regcomp_foldername");
var year = DateTimeUtil.getCurrentYear();
var month = DateTimeUtil.getCurrentMonth();
uploadDirectory = uploadDirectory + serviceFolderName + "/" + year + "/" + month;
try {
// Create directory if it doesn't exist
Path directoryPath = Paths.get(uploadDirectory);
if (!Files.exists(directoryPath)) {
Files.createDirectories(directoryPath);
}
// Datetime string
String datetimetxt = DateTimeUtil.getCurrentDateTime();
// File name
String fileName = name + "_" + datetimetxt + "_" + file.getOriginalFilename();
fileName = fileName.replaceAll("\\s+", ""); // Remove space on filename
String filePath = uploadDirectory + "/" + fileName;
String filepath_txt = "/" + serviceFolderName + "/" + year + "/" + month + "/" + fileName;
// Create a new Path object
Path path = Paths.get(filePath);
// Get the bytes of the file
byte[] bytes = file.getBytes();
BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes));
byte[] compressedBytes = compressImage(image, 0.5f); // Compress with 50%quality
// Write the bytes to the file
Files.write(path, bytes);
// Write the bytes to the file
Files.write(path, compressedBytes);
//System.out.println(filePath);
return filepath_txt;
} catch (IOException e) {
e.printStackTrace();
return "Failed to save file " + file.getOriginalFilename();
}
}
private byte[] compressImage(BufferedImage image, float quality) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream);
ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();
writer.setOutput(imageOutputStream);
ImageWriteParam param = writer.getDefaultWriteParam();
if (param.canWriteCompressed()) {
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
}
writer.write(null, new javax.imageio.IIOImage(image, null, null), param);
writer.dispose();
imageOutputStream.close();
return byteArrayOutputStream.toByteArray();
}
public Map<String, Object> getDetailsByComplaintNumber(String complaintNumber) {
Map<String, Object> resultMap = new HashMap<>();
try {
String url = "https://erp.chennaicorporation.gov.in/pgr/newmobileservice?serviceId=getComplaintByID&ComplaintId="
+ complaintNumber + "&imgUrlonly=yes&isQcuser=Yes&jsonResp=Yes";
//System.out.println("Request URL: " + url);
ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
if (responseEntity.getStatusCode().is2xxSuccessful()) {
String responseBody = responseEntity.getBody();
//System.out.println("Response Body: " + responseBody);
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(responseBody);
JsonNode complaintDetails = rootNode.path(0).path("ComplaintListHistory").path(0);
String registerDate=complaintDetails.path("complaintopendate").asText("N/A");
//System.out.println("registerdate====="+registerDate);
String formattedDate = "N/A"; // Default value if parsing fails
if (!registerDate.equals("N/A") && !registerDate.isEmpty()) {
try {
// Parse the input date string
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
Date date = inputFormat.parse(registerDate);
// Format the date to dd-MM-yyyy
SimpleDateFormat outputFormat = new SimpleDateFormat("dd-MM-yyyy");
formattedDate = outputFormat.format(date);
} catch (Exception e) {
e.printStackTrace(); // Log exception for debugging
}
}
if (!complaintDetails.isMissingNode()) {
// Existing fields
resultMap.put("complaintid", complaintDetails.path("complaintid").asText("N/A"));
resultMap.put("complaintdate", formattedDate);
resultMap.put("complainantName", complaintDetails.path("CustomerName").asText("N/A"));
resultMap.put("mobileNumber", complaintDetails.path("CustomerMobile").asText("N/A"));
resultMap.put("complaintType", complaintDetails.path("complainttype").asText("N/A"));
resultMap.put("description", complaintDetails.path("complaintdetails").asText("N/A"));
resultMap.put("currentStatus", complaintDetails.path("complaintcurrentstatus").asText("N/A"));
resultMap.put("Street", complaintDetails.path("Street").asText("N/A"));
resultMap.put("Area", complaintDetails.path("Area").asText("N/A"));
resultMap.put("Landmark", complaintDetails.path("Landmark").asText("N/A"));
resultMap.put("Location", complaintDetails.path("Location").asText("N/A"));
resultMap.put("Zone", complaintDetails.path("Zone").asText("N/A"));
resultMap.put("Division", complaintDetails.path("Division").asText("N/A"));
resultMap.put("OfficialMobile", complaintDetails.path("OfficialMobile").asText("N/A"));
resultMap.put("gender", complaintDetails.path("GENDER").asText("N/A"));
resultMap.put("deptname",complaintDetails.path("DEPT_NAME").asText("N/A"));
resultMap.put("compmode", complaintDetails.path("COMP_MODE").asText("N/A"));
resultMap.put("Officialname", complaintDetails.path("Officialname").asText("N/A"));
}
} else {
resultMap.put("error", "Failed to retrieve complaint details.");
}
} catch (Exception e) {
e.printStackTrace();
resultMap.put("error", "Error processing request");
}
return resultMap;
}
public Map<String, Object> getFilteredRegComps() {
Map<String, Object> response = new HashMap<>();
try {
String sql =
"SELECT src.complaint_number, src.created_date,CONCAT('" + fileBaseUrl + "/gcc/files',src.resolved_img) AS img_full_path,al.agent_name as agent_name,src.remarks as remarks" +
" FROM socialmedia_reg_completed src "
+ " LEFT JOIN agents_list al ON al.agent_id=src.cby " +
"WHERE src.is_processed = 0 " +
"AND src.isactive = 1 " +
"AND src.isdelete = 0";
List<Map<String, Object>> dbList = jdbcTemplate.queryForList(sql);
List<Map<String, Object>> finalList = new ArrayList<>();
for (Map<String, Object> row : dbList) {
String complaintNumber =
String.valueOf(row.get("complaint_number"));
Map<String, Object> complaintDetails =
getDetailsByComplaintNumber(complaintNumber);
String currentStatus =
String.valueOf(
complaintDetails.getOrDefault(
"currentStatus",
""
)
);
//System.out.println("currentStatus==="+currentStatus);
if ("REGISTERED".equalsIgnoreCase(currentStatus)) {
Map<String, Object> resultRow = new HashMap<>();
resultRow.put("complaintnumber", complaintNumber);
//resultRow.put("submitted_date", row.get("created_date"));
Timestamp ts = (Timestamp) row.get("created_date");
SimpleDateFormat sdf =
new SimpleDateFormat("dd/MM/yyyy HH:mm");
resultRow.put("submitted_date", sdf.format(ts));
String img = (String) row.get("img_full_path");
resultRow.put("img_full_path", img);
String agent_name = (String) row.get("agent_name");
resultRow.put("agent_name", agent_name);
String remarks = (String) row.get("remarks");
resultRow.put("remarks", remarks);
finalList.add(resultRow);
} else {
String updateSql =
"UPDATE socialmedia_reg_completed " +
"SET updated_by = ?, " +
"updated_date = NOW(), " +
"isactive = 0, " +
"isdelete = 1 " +
"WHERE complaint_number = ?";
jdbcTemplate.update(
updateSql,
0,
complaintNumber
);
}
}
if (finalList.isEmpty()) {
response.put("status", "nodata");
response.put("message", "No registered complaints found.");
} else {
response.put("status", "success");
response.put("details", finalList);
}
} catch (Exception e) {
e.printStackTrace();
response.put("status", "error");
response.put("message", e.getMessage());
}
return response;
}
public Map<String, Object> approveComplaint(String complaintId, String remarks, String imgFullPath, String userid) {
Map<String, Object> response = new HashMap<>();
try {
Integer updated_by = Integer.parseInt(userid);
String erp_name=get1913AdminErpusernamebyId(userid);
boolean statusUpdated =
ChangeStatusInErp(
complaintId,
"ActionLevel1",
remarks,
erp_name,
imgFullPath);
if (!statusUpdated) {
response.put("status", "FAILED");
response.put("message", "Unable to move complaint to Action Level 1.");
return response;
}
boolean statusUpdated1 =
ChangeStatusInErp(
complaintId,
"Close",
remarks,
erp_name,
"");
if (!statusUpdated1) {
response.put("status", "FAILED");
response.put("message", "Unable to move complaint to Close.");
return response;
}
String sql="UPDATE socialmedia_reg_completed "
+ "SET is_processed = 1, "
+ " updated_by = ?, "
+ " updated_date = NOW() "
+ "WHERE complaint_number = ? AND isactive=1 AND isdelete=0";
int rows=jdbcTemplate.update(sql,updated_by,complaintId);
if (rows > 0) {
response.put("status", "SUCCESS");
response.put("message", "Complaint Closed successfully.");
} else {
response.put("status", "FAILED");
response.put("message", "Complaint Closed,Unable to insert in logs.");
}
} catch (Exception e) {
e.printStackTrace();
response.put("status", "error");
response.put("message", e.getMessage() != null
? e.getMessage()
: "Something went wrong while submitting complaint.");
}
return response;
}
public boolean ChangeStatusInErp(String complaintNumber,String action ,String remarks,String erp_name,String imgFullPath) {
String baseUrl = "https://erp.chennaicorporation.gov.in/pgr/external/mobileservice";
String status = "";
try {
// Determine status based on action
if ("ActionLevel1".equals(action)) {
status = "5";
} else if ("Close".equals(action)) {
status = "11";
} else {
return false; // Invalid action, return false
}
//String img="https://gccservices.in/gccofficialapp/files/app_icon/menu/gcc_survey_icons/Cow.png";
// Convert image to Base64
String base64Image = "";
if (imgFullPath != null && !imgFullPath.trim().isEmpty()) {
URL imageUrl = new URL(imgFullPath);
try (InputStream inputStream = imageUrl.openStream()) {
byte[] imageBytes = inputStream.readAllBytes();
base64Image =
Base64.getEncoder().encodeToString(imageBytes);
}
}
String postData =
"serviceId=" + URLEncoder.encode("UpdateComplaint", "UTF-8")
+ "&ComplaintId=" + URLEncoder.encode(complaintNumber, "UTF-8")
+ "&Message=" + URLEncoder.encode(remarks, "UTF-8")
+ "&UserType=Official"
+ "&Status=" + status
+ "&Comp_Image=" + URLEncoder.encode(base64Image, "UTF-8")
+ "&erp_username=" + URLEncoder.encode(erp_name, "UTF-8");
System.out.println("Complaint = " + complaintNumber);
System.out.println("Action = " + action);
System.out.println("Base64 Length = " + base64Image.length());
System.out.println("Post Data Length = " + postData.length());
return sendRequest(baseUrl, postData);
// return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private boolean sendRequest(String urlString, String postData) {
try {
URL url = new URL(urlString);
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty(
"Content-Type",
"application/x-www-form-urlencoded"
);
//System.out.println("Method = " + connection.getRequestMethod());
try (OutputStream os = connection.getOutputStream()) {
byte[] input = postData.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
int responseCode = connection.getResponseCode();
System.out.println("Response Code = " + responseCode);
System.out.println("Response Message = " + connection.getResponseMessage());
InputStream stream;
if (responseCode >= 200 && responseCode < 300) {
stream = connection.getInputStream();
} else {
stream = connection.getErrorStream();
}
StringBuilder responseBuilder = new StringBuilder();
if (stream != null) {
BufferedReader reader =
new BufferedReader(
new InputStreamReader(stream));
String line;
while ((line = reader.readLine()) != null) {
responseBuilder.append(line);
}
reader.close();
}
String response = responseBuilder.toString();
System.out.println("ERP Response = " + response);
return response.contains("\"ResultStatus\": true");
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public Map<String, Object> rejectComplaint(String complaintId, String userid) {
Map<String, Object> response = new HashMap<>();
try {
Integer updated_by = Integer.parseInt(userid);
String sql="UPDATE socialmedia_reg_completed "
+ "SET isactive=0,isdelete=1, "
+ " updated_by = ?, "
+ " updated_date = NOW() "
+ "WHERE complaint_number = ? AND isactive=1 AND isdelete=0";
int rows=jdbcTemplate.update(sql,updated_by,complaintId);
if (rows > 0) {
response.put("status", "SUCCESS");
response.put("message", "Complaint Rejected successfully.");
} else {
response.put("status", "FAILED");
response.put("message", "Unable to Reject the Complaint.");
}
} catch (Exception e) {
e.printStackTrace();
response.put("status", "error");
response.put("message", e.getMessage() != null
? e.getMessage()
: "Something went wrong while submitting complaint.");
}
return response;
}
} }

4
gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/configuration/DataSourceConfig.java

@ -24,8 +24,8 @@ import java.util.Properties;
@EnableTransactionManagement @EnableTransactionManagement
public class DataSourceConfig { public class DataSourceConfig {
// private static String host = "localhost:3306";
// private static String dbpassword = "root";
// private static String host = "localhost:3306";
// private static String dbpassword = "root";
// private static String dbpassword = "gccroot"; // private static String dbpassword = "gccroot";

1
gcc_officer_portal/src/main/resources/application.properties

@ -119,3 +119,4 @@ street_vendor_foldername=street_vendor_files
green_committee_foldername=green_committee_files green_committee_foldername=green_committee_files
socialmedia_1913_regcomp_foldername=socialmedia_1913_regcompfiles

217
gcc_officer_portal/src/main/resources/templates/modules/callcenterqaqc/socialmediacomplaints.html

@ -882,6 +882,9 @@
// Update modal content // Update modal content
document.getElementById('modalBody').innerHTML = detailsHtml; document.getElementById('modalBody').innerHTML = detailsHtml;
// Check Registered Complaint Closing Section
loadRegCompSection(data.complaintid, data.currentStatus);
}, },
error: function () { error: function () {
document.getElementById('modalBody').innerHTML = '<p>Error loading agent details. Please try again later.</p>'; document.getElementById('modalBody').innerHTML = '<p>Error loading agent details. Please try again later.</p>';
@ -893,6 +896,219 @@
} }
}); });
} }
function submitRegClosingComplaint(complaintNumber) {
const reg_remarks = $('#closingRemarks').val().trim();
const fileInput = $('#resolvedImage')[0];
const cby = document.getElementById('userIdSpan').textContent;
// Remarks Validation
if (reg_remarks === '') {
Swal.fire({
icon: 'warning',
title: 'Remarks Required',
text: 'Please enter remarks.'
});
return;
}
// File Validation
if (!fileInput.files || fileInput.files.length === 0) {
Swal.fire({
icon: 'warning',
title: 'Image Required',
text: 'Please select a resolved image.'
});
return;
}
const file = fileInput.files[0];
// Allowed Extensions
const allowedTypes = [
'image/jpeg',
'image/jpg',
'image/png'
];
if (!allowedTypes.includes(file.type)) {
Swal.fire({
icon: 'error',
title: 'Invalid File',
text: 'Only JPG, JPEG and PNG images are allowed.'
});
return;
}
// 10 MB Validation
const maxSize = 10 * 1024 * 1024; // 10MB
if (file.size > maxSize) {
Swal.fire({
icon: 'error',
title: 'File Too Large',
text: 'Image size should not exceed 10 MB.'
});
return;
}
let formData = new FormData();
formData.append('complaintNumber', complaintNumber);
formData.append('remarks', reg_remarks);
formData.append('resolvedImage', file);
formData.append('cby', cby);
Swal.fire({
title: 'Are you sure?',
text: 'You want to submit this complaint for closing approval?',
icon: 'question',
showCancelButton: true,
confirmButtonText: 'Yes, Submit'
}).then((result) => {
if (result.isConfirmed) {
$.ajax({
url: '/gcc/api/callcenterqaqc/socialmedia/submitRegClosingComplaint',
type: 'POST',
data: formData,
processData: false,
contentType: false,
beforeSend: function () {
Swal.fire({
title: 'Please Wait...',
text: 'Uploading data...',
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
}
});
},
success: function (response) {
Swal.close();
if (response.status === 'SUCCESS') {
Swal.fire({
icon: 'success',
title: 'Success',
text: response.message
}).then(() => {
loadRegCompSection(complaintNumber, 'REGISTERED');
});
} else {
Swal.fire({
icon: 'error',
title: 'Failed',
text: response.message
});
}
},
error: function () {
Swal.close();
Swal.fire({
icon: 'error',
title: 'Error',
text: 'Server error occurred. Please try again.'
});
}
});
}
});
}
function loadRegCompSection(complaintNumber, currentStatus) {
// Hide by default
$('#regCompHtml').html('');
// Show only for REGISTERED complaints
if (currentStatus !== 'REGISTERED') {
return;
}
$.ajax({
url: '/gcc/api/callcenterqaqc/socialmedia/checkregisteredcomplaint',
type: 'GET',
data: {
complaintNumber: complaintNumber
},
success: function(response) {
let html = '';
// Case 1
if (response.status === 'NOT_FOUND') {
html = `
<hr>
<h4>Registered Complaint Closing Details</h4>
<div class="form-group">
<label><strong>Remarks</strong></label>
<textarea class="form-control"
id="closingRemarks"
rows="3"></textarea>
</div>
<div class="form-group mt-2">
<label><strong>Resolved Image</strong></label>
<input type="file"
class="form-control"
id="resolvedImage"
accept="image/*">
</div>
<div class="text-center">
<button class="btn btn-primary mt-3"
onclick="submitRegClosingComplaint('${complaintNumber}')">
Submit to Approval
</button>
</div>
`;
}
// Case 2
else if (response.status === 'PENDING_APPROVAL') {
html = `
<hr>
<div class="alert alert-warning">
This Complaint submitted to Admin For Closing Purpose
</div>
`;
}
// Case 3
else if (response.status === 'PROCESSED') {
html = '';
}
$('#regCompHtml').html(html);
},
error: function() {
$('#regCompHtml').html(
'<div class="alert alert-danger">Unable to load Registered closing details.</div>'
);
}
});
}
// Function to generate complaint and agent details HTML // Function to generate complaint and agent details HTML
function generateDetailsHtml(data, agentResponse) { function generateDetailsHtml(data, agentResponse) {
@ -1038,6 +1254,7 @@
${agentRepliedHtml} ${agentRepliedHtml}
<hr> <hr>
${imageLink} ${imageLink}
<div id="regCompHtml"></div>
`; `;
return detailsHtml; return detailsHtml;

805
gcc_officer_portal/src/main/resources/templates/modules/callcenterqaqc/socialmediaregcompclosing.html

@ -0,0 +1,805 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}">
</head>
<style>
#modalBody h4 {
font-weight: bold;
margin-top: 15px;
margin-bottom: 10px;
}
#modalBody p {
margin: 5px 0;
}
#modalBody hr {
margin: 15px 0;
}
.comment {
margin-bottom: 20px;
}
.comment p {
margin: 0;
}
hr {
border: 1px solid #ccc;
}
.col-4 {
font-weight: bold;
text-align: right;
}
.col-8 {
padding-left: 20px;
}
.comment {
padding: 10px 0;
}
.comment .text-muted {
font-size: 0.9em;
color: #6c757d;
}
.comment hr {
border-top: 1px solid #ccc;
}
.comment .btn-link {
font-size: 0.9em;
text-decoration: underline;
color: #007bff;
}
/* Make the modal body scrollable */
#detailsModal .modal-body {
max-height: 70vh; /* Limit the height to 70% of the viewport */
overflow-y: auto; /* Enable vertical scrolling */
}
.width1{
width: 100px;
}
.width2{
width: 120px;
}
</style>
<body>
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header mb-2">
<div class="row align-items-end">
<div class="col-lg-8">
<div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline">
<h5>SocialMedia Complaints</h5>
<span>Closing Social Media Registered Complaints</span>
</div>
</div>
</div>
<div class="col-lg-4">
<nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/gcc/index"><i
class="ik ik-home"></i></a></li>
<li class="breadcrumb-item" aria-current="page">1913 Social Media</li>
<li class="breadcrumb-item active" aria-current="page">Close Reg Complaints</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-12">
<div class="card">
<div class="card-header">
<span style="font-size: medium;font-weight: bold;">Complaints List</span>
<span th:text="${userId}" style="display:none;" id="userIdSpan"></span>
</div>
<div class="card-body">
<div class="table-responsive">
<table id="ReportDatatable"
class="table table-striped table-bordered table-hover dataTable"
role="grid">
<thead class="thead-dark">
<tr role="row">
<th class="text-center no-sort">S.No</th>
<th class="text-center no-sort">Complaint No</th>
<th class="text-center">Agent</th>
<th class="text-center">Agent Submitted Date</th>
<th class="text-center">View</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="pageLoader" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" role="dialog"
aria-labelledby="detailsModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="detailsModalLabel">Complaint
Details</h5>
<button type="button" class="close" data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" id="modalBody">
<!-- Details will be populated here -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- in the code use to show the download different type microsoft -->
<!-- Include jQuery and Bootstrap JavaScript -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<!-- sweet alert -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script type="text/javascript">
$(document).ready(function() {
var table = $('#ReportDatatable').DataTable({
dom: 'Bftip',
columnDefs: [
{ targets: 'no-sort', orderable: false }
],
lengthMenu: [
[50, 100, 200, 500, -1],
['50 rows', '100 rows', '200 rows', 'Show all']
],
scrollY: '100vh',
fixedColumns: {
left: 1,
right: 1
},
buttons: [
{
extend: 'pageLength',
className: 'btn btn-warning'
},
{
title: 'Data export',
extend: 'copyHtml5',
text: 'Copy',
className: 'btn btn-secondary',
id: 'copyBtn'
},
{
extend: 'excelHtml5',
text: 'Excel',
className: 'btn btn-secondary',
id: 'excelBtn'
},
{
extend: 'csvHtml5',
text: 'CSV',
className: 'btn btn-secondary',
id: 'csvBtn'
},
{
extend: 'pdfHtml5',
text: 'PDF',
className: 'btn btn-secondary',
id: 'pdfBtn'
}
],
fixedHeader: true,
autoWidth: true,
responsive: true,
searching: true,
select: false,
processing: false
});
$('#pageLoader').show();
$.ajax({
type: "GET",
url: `/gcc/api/callcenterqaqc/socialmedia/getfilteredregcomps`,
success: function (response) {
$('#pageLoader').hide();
if (response.status === "success") {
console.log("Details Array:", response.details);
// Ensure details is an array and has at least one entry
if (Array.isArray(response.details) && response.details.length > 0) {
let columns = [
{
data: null,
render: (data, type, row, meta) => meta.row + 1,
className: 'text-center'
},
{ data: 'complaintnumber', defaultContent: '-', className: 'text-center' },
{ data: 'agent_name', defaultContent: '-', className: 'text-center' },
{ data: 'submitted_date', defaultContent: '-', className: 'text-center' },
{
data: null,
render: function(data, type, row) {
return `
<button
type="button"
class="btn btn-info btn-view"
data-complaint-number="${row.complaintnumber}"
data-remarks="${row.remarks || ''}"
data-img="${row.img_full_path || ''}">
View
</button>
`;
},
className: 'text-center'
}
];
// Initialize the DataTable
$('#ReportDatatable').DataTable({
destroy: true,
searching: true,
autoWidth: true,
responsive: true,
paging: true,
info: true,
data: response.details,
columns: columns,
dom: 'Bfrtip',
buttons: [
{
extend: 'pageLength',
className: 'btn btn-warning'
},
{
title: 'Data export',
extend: 'copyHtml5',
text: 'Copy',
className: 'btn btn-secondary',
id: 'copyBtn'
},
{
extend: 'excelHtml5',
text: 'Excel',
className: 'btn btn-secondary',
id: 'excelBtn'
},
{
extend: 'csvHtml5',
text: 'CSV',
className: 'btn btn-secondary',
id: 'csvBtn'
},
{
extend: 'pdfHtml5',
text: 'PDF',
className: 'btn btn-secondary',
id: 'pdfBtn'
}
],
columnDefs: [
{ targets: 'no-sort', orderable: false }
],
lengthMenu: [
[50, 100, 200, 500, -1],
['50 rows', '100 rows', '200 rows', 'Show all']
],
scrollY: '100vh',
fixedColumns: {
left: 1,
right: 1
}
});
}
}
else if (response.status === "nodata") {
$('#pageLoader').hide();
Swal.fire({
icon: 'warning',
title: 'No Data',
text: 'No data available.'
});
}
else if (response.status === "error") {
$('#pageLoader').hide();
Swal.fire({
icon: 'error',
title: 'Error',
text: response.message
});
}
else {
$('#pageLoader').hide();
Swal.fire({
icon: 'error',
title: 'Error',
text: response.message
});
}
},
error: function (error) {
$('#pageLoader').hide();
Swal.fire({
icon: 'error',
title: 'Error',
text: response.message
});
}
});
});
$(document).on('click', '.btn-info', function () {
const complaintNumber = $(this).data('complaint-number');
const remarks = $(this).data('remarks');
const imgFullPath = $(this).data('img');
viewDetails(complaintNumber, remarks, imgFullPath);
});
function viewDetails(complaintNumber, remarks, imgFullPath) {
document.getElementById('modalBody').innerHTML = '<p style="text-align:center;">Please wait, loading data...</p>';
$('#detailsModal').modal('show');
// Fetch the main complaint details
$.ajax({
url: '/gcc/api/callcenterqaqc/agent/qaqccalls/getComplaintDetails',
type: 'GET',
data:{complaintNumber:complaintNumber},
success: function (data) {
//console.log('Complaint Data:', data);
// Fetch agent response details
$.ajax({
url: '/gcc/api/callcenterqaqc/agent/attendedcomplaintshistory',
type: 'GET',
data: { complaintNumber },
success: function (agentResponse) {
//console.log('Agent Response:', agentResponse);
// Use the logic for building complaint and agent details as HTML
const detailsHtml = generateDetailsHtml(data, agentResponse,remarks,imgFullPath);
// Update modal content
document.getElementById('modalBody').innerHTML = detailsHtml;
},
error: function () {
document.getElementById('modalBody').innerHTML = '<p>Error loading agent details. Please try again later.</p>';
}
});
},
error: function () {
document.getElementById('modalBody').innerHTML = '<p>Error loading complaint details. Please try again later.</p>';
}
});
}
function generateDetailsHtml(data, agentResponse,remarks,imgFullPath) {
// Helper function to format date to yyyy-mm-dd
function formatDate(dateStr) {
if (!dateStr) return 'N/A';
const date = new Date(dateStr);
return date.toISOString().split('T')[0]; // Formats to yyyy-mm-dd
}
// Format complaint messages
let messagesHtml = '';
if (data.comments && data.comments.length > 0) {
data.comments.forEach((comment) => {
const commentImageLink = comment.Comp_Image && comment.Comp_Image !== "No image available"
? `<a href="${comment.Comp_Image}" target="_blank" style="color: green; text-decoration: underline;">View Image</a>`
: '<p style="color: red;">No image available for this comment.</p>';
messagesHtml += `
<div class="comment mb-4">
<div class="row">
<div class="col-2 text-center">
<p class="text-muted">${comment.comment_date}</p>
</div>
<div class="col-10">
<p><strong>${comment.user || 'N/A'}</strong> Says:</p>
<p>${comment.message || 'No message available'}</p>
<div class="user-image">${commentImageLink}</div>
</div>
</div>
</div>
`;
});
} else {
messagesHtml = '<p>No comments available.</p>';
}
// Format agent responses
let agentRepliedHtml = '';
if (agentResponse.length > 0) {
agentResponse.forEach((agentItem) => {
agentRepliedHtml += `
<div class="comment mb-4">
<div class="row">
<div class="col-2 text-center">
<p class="text-muted"><strong>${formatDate(agentItem.created_date) || 'N/A'}</strong></p>
</div>
<div class="col-10">
<p><strong>${agentItem.agent_name || 'N/A'}</strong>, Says: ${agentItem.call_status || 'N/A'}</p>
<p><strong>Remarks: </strong>${agentItem.remarks || 'N/A'}</p>
<p><strong>Remainder Date: </strong> ${formatDate(agentItem.remainder_date) || 'N/A'}</p>
</div>
</div>
</div>
`;
});
} else {
agentRepliedHtml = '<p>No agent replied messages available.</p>';
}
// Check for user images
const userImages = data.userimages && data.userimages.length > 0 ? data.userimages[0] : {};
const imageLink = userImages.Comp_Image && userImages.Comp_Image !== "null" && userImages.Comp_Image !== ""
? `<a href="${userImages.Comp_Image}" target="_blank" style="color: green; text-decoration: underline;">UserImages: View Image</a>`
: '<p style="color: red;">UserImages: No image available.</p>';
// Combine all sections into the final HTML
const detailsHtml = `
<div class="row">
<div class="col-md-12">
<h4>Complaint Person's Details:</h4>
<div class="row">
<div class="col-6">
<p><strong>Complaint Number:</strong> ${data.complaintid || 'N/A'}</p>
</div>
<div class="col-6">
<p><strong>Complaint Date:</strong> ${data.complaintdate}</p>
</div>
</div>
<div class="row">
<div class="col-6">
<p><strong>Complainant's Name:</strong> ${data.complainantName || 'N/A'}</p>
</div>
<div class="col-6">
<p><strong>Phone Number:</strong> ${data.mobileNumber || 'N/A'}</p>
</div>
</div>
<div class="row">
<div class="col-6">
<p><strong>Zone:</strong> ${data.Zone || 'N/A'}</p>
</div>
<div class="col-6">
<p><strong>Division:</strong> ${data.Division || 'N/A'}</p>
</div>
</div>
<div class="row">
<div class="col-6">
<p><strong>Gender:</strong> ${data.gender || 'N/A'}</p>
</div>
<div class="col-6">
<p><strong>Complainant's Address:</strong> ${data.Street || 'N/A'}, ${data.Area || 'N/A'}, ${data.Landmark || 'N/A'}, ${data.Location || 'N/A'}</p>
</div>
</div>
</div>
</div>
<hr>
<h4>Complaint Details:</h4>
<div class="row">
<div class="col-6">
<p><strong>Complaint Dept:</strong> ${data.deptname || 'N/A'}</p>
</div>
<div class="col-6">
<p><strong>Complaint Mode:</strong> ${data.compmode || 'N/A'}</p>
</div>
</div>
<div class="row">
<div class="col-6">
<p><strong>Complaint Type:</strong> ${data.complaintType || 'N/A'}</p>
</div>
<div class="col-6">
<p><strong>Details of Complaint:</strong> ${data.description || 'N/A'}</p>
</div>
</div>
<div class="row">
<div class="col-6">
<p><strong>Current Status:</strong> ${data.currentStatus || 'N/A'}</p>
</div>
<div class="col-6">
<p><strong style="color:blue;">Official Mobile:</strong> ${data.OfficialMobile || 'N/A'}</p>
</div>
</div>
<div class="row">
<div class="col-6">
<p><strong>Last Updated Date:</strong> ${data.greatestDate || 'N/A'}</p>
</div>
</div>
<hr>
<h4>Complaint Messages:</h4>
${messagesHtml}
<hr>
<h4>Agent Replied Messages:</h4>
${agentRepliedHtml}
<hr>
${imageLink}
<hr>
<h4>Registered Complaint Closing Details</h4>
<div class="row">
<div class="col-md-12">
<p>
<strong>Resolved Image:</strong>
${
imgFullPath
? `<a href="${imgFullPath}"
target="_blank"
style="color:blue;text-decoration:underline;">
View Resolved Image
</a>`
: 'No Image Available'
}
</p>
<p>
<strong>Remarks:</strong>
${remarks || 'N/A'}
</p>
<div class="d-flex justify-content-center mt-3">
<button
type="button"
class="btn btn-success"
onclick="approveComplaint(
'${data.complaintid}',
'${remarks ? remarks.replace(/'/g, "\\'") : ""}',
'${imgFullPath || ""}'
)">
Complaint Close
</button>
<button
type="button"
class="btn btn-danger ml-2"
onclick="rejectComplaint(
'${data.complaintid}'
)">
Reject
</button>
</div>
</div>
</div>
`;
return detailsHtml;
}
function rejectComplaint(complaintId) {
const userid = document.getElementById('userIdSpan').textContent;
Swal.fire({
title: 'Are you sure?',
text: 'You want to Reject this complaint?',
icon: 'question',
showCancelButton: true,
confirmButtonText: 'Yes, Reject',
cancelButtonText: 'Cancel'
}).then((result) => {
if (result.isConfirmed) {
$.ajax({
url: '/gcc/api/callcenterqaqc/socialmedia/rejectComplaint',
type: 'POST',
data: {
complaintId: complaintId,
userid:userid
},
beforeSend: function () {
Swal.fire({
title: 'Please Wait...',
text: 'Processing approval...',
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
}
});
},
success: function (response) {
Swal.close();
if (response.status === 'SUCCESS') {
Swal.fire({
icon: 'success',
title: 'Success',
text: response.message
}).then(() => {
$('#detailsModal').modal('hide');
// reload datatable data if required
location.reload();
});
} else {
Swal.fire({
icon: 'error',
title: 'Failed',
text: response.message
});
}
},
error: function () {
Swal.close();
Swal.fire({
icon: 'error',
title: 'Error',
text: 'Server error occurred.'
});
}
});
}
});
}
function approveComplaint(complaintId, remarks, imgFullPath) {
const userid = document.getElementById('userIdSpan').textContent;
//console.log("userid===="+userid);
Swal.fire({
title: 'Are you sure?',
text: 'You want to Close this complaint?',
icon: 'question',
showCancelButton: true,
confirmButtonText: 'Yes, Close',
cancelButtonText: 'Cancel'
}).then((result) => {
if (result.isConfirmed) {
$.ajax({
url: '/gcc/api/callcenterqaqc/socialmedia/approveComplaint',
type: 'POST',
data: {
complaintId: complaintId,
remarks: remarks,
imgFullPath: imgFullPath,
userid:userid
},
beforeSend: function () {
Swal.fire({
title: 'Please Wait...',
text: 'Processing approval...',
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
}
});
},
success: function (response) {
Swal.close();
if (response.status === 'SUCCESS') {
Swal.fire({
icon: 'success',
title: 'Approved',
text: response.message
}).then(() => {
$('#detailsModal').modal('hide');
// reload datatable data if required
location.reload();
});
} else {
Swal.fire({
icon: 'error',
title: 'Failed',
text: response.message
});
}
},
error: function () {
Swal.close();
Swal.fire({
icon: 'error',
title: 'Error',
text: 'Server error occurred.'
});
}
});
}
});
}
</script>
</body>
</html>
Loading…
Cancel
Save