Browse Source

first commit

master
yoganandhan 2 years ago
commit
6f4f6a7a69
  1. 112
      backend/callcenter/controller/AgentAssignAPIController.java
  2. 320
      backend/callcenter/controller/AgentsAPIController.java
  3. 36
      backend/callcenter/controller/AttendanceAPIController.java
  4. 614
      backend/callcenter/controller/CampaignAPIController.java
  5. 29
      backend/callcenter/controller/CampaignDropdownApiController.java
  6. 100
      backend/callcenter/controller/CampaignReportAPIController.java
  7. 281
      backend/callcenter/controller/CategoryAPIController.java
  8. 219
      backend/callcenter/controller/MainController.java
  9. 26
      backend/callcenter/controller/WhatsappController.java
  10. 303
      backend/callcenter/service/AddcategoryServices.java
  11. 214
      backend/callcenter/service/AgentAssignService.java
  12. 656
      backend/callcenter/service/AgentsService.java
  13. 116
      backend/callcenter/service/AttendanceService.java
  14. 29
      backend/callcenter/service/CampaignDropdownApiService.java
  15. 334
      backend/callcenter/service/CampaignReportService.java
  16. 704
      backend/callcenter/service/CampaignService.java
  17. 40
      backend/callcenter/service/WhatsappMsgService.java
  18. 974
      frontend/callcenter/addcategory.html
  19. 1807
      frontend/callcenter/agentscampaign.html
  20. 230
      frontend/callcenter/attendancereport.html
  21. 1256
      frontend/callcenter/campaignlist.html
  22. 954
      frontend/callcenter/campaignreport.html
  23. 1956
      frontend/callcenter/createcampaign.html
  24. 56
      gcc_campaign_empty_dump/gcc_1913_campaign_agent_assign.sql
  25. 54
      gcc_campaign_empty_dump/gcc_1913_campaign_answer_type.sql
  26. 55
      gcc_campaign_empty_dump/gcc_1913_campaign_call_logs.sql
  27. 54
      gcc_campaign_empty_dump/gcc_1913_campaign_calls_status.sql
  28. 56
      gcc_campaign_empty_dump/gcc_1913_campaign_campaign_answers.sql
  29. 56
      gcc_campaign_empty_dump/gcc_1913_campaign_campaign_questions.sql
  30. 61
      gcc_campaign_empty_dump/gcc_1913_campaign_campaign_request.sql
  31. 53
      gcc_campaign_empty_dump/gcc_1913_campaign_category.sql
  32. 54
      gcc_campaign_empty_dump/gcc_1913_campaign_category_columns.sql
  33. 55
      gcc_campaign_empty_dump/gcc_1913_campaign_questions_answers.sql
  34. 73
      gcc_campaign_empty_dump/gcc_1913_campaign_upload_data.sql

112
backend/callcenter/controller/AgentAssignAPIController.java

@ -0,0 +1,112 @@
package in.gov.chennaicorporation.gccoffice.callcenter.controller;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import in.gov.chennaicorporation.gccoffice.callcenter.service.AgentAssignService;
@RequestMapping("/gcc/api/callcenter/admin")
@RestController("callcentercontroller")
public class AgentAssignAPIController
{
private AgentAssignService campaignmaster;
@Autowired
public AgentAssignAPIController(AgentAssignService campaignmaster) {
this.campaignmaster = campaignmaster;
}
@GetMapping("/getcategory")
public List<Map<String, Object>> getcategory()
{
return campaignmaster.getcategory();
}
@GetMapping("/getcampaignbycategory")
public List<Map<String, Object>> getcampaignbycategory(@RequestParam int id)
{
return campaignmaster.getcampaignbycategory(id);
}
// @GetMapping("/getcampaignbyid")
// public List<Map<String, Object>> getcampaignbyid(@RequestParam int id)
// {
// return campaignmaster.getcampaignbyid(id);
// }
@GetMapping("/getagentsfortask")
public List<Map<String, Object>> getagentsfortask(@RequestParam int id)
{
return campaignmaster.getagentsfortask(id);
}
@PostMapping("/addagentsfortask")
public ResponseEntity<List<Map<String, Object>>> addagentsfortask(@RequestBody List<Map<String, Object>> requestList) {
//System.out.println("Received POST request with data: " + requestList);
List<Map<String, Object>> insertedAgents = new ArrayList<>(); // To store successfully inserted agents
try {
for (Map<String, Object> request : requestList) {
int agentId = (int) request.get("agentId");
int categoryId = (int) request.get("categoryId");
int campaignId = (int) request.get("campaignId");
// Call the service method to insert the agent details
int rowsAffected = campaignmaster.addagentsfortask(agentId, categoryId, campaignId);
if (rowsAffected > 0) {
// If the insert was successful, add the agent data to the response list
Map<String, Object> insertedAgent = new HashMap<>();
insertedAgent.put("categoryId", categoryId);
insertedAgent.put("campaignId", campaignId);
insertedAgent.put("agentId", agentId);
insertedAgents.add(insertedAgent); // Add the successfully inserted agent to the list
} else {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(Collections.singletonList(Collections.singletonMap("error", "Failed to add agent for campaignId: " + campaignId)));
}
}
// Return the list of successfully inserted agents
return ResponseEntity.status(HttpStatus.CREATED).body(insertedAgents);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(Collections.singletonList(Collections.singletonMap("error", "Invalid request data: " + e.getMessage())));
}
}
@GetMapping("/getassignedcampaign")
public List<Map<String, Object>> checkcampaigninassignedtable(@RequestParam int id)
{
return campaignmaster.checkcampaigninassignedtable(id);
}
@GetMapping("/deleteassignedbyid")
public int editagentsfortask(@RequestParam int id)
{
return campaignmaster.editagentsfortask(id);
}
@GetMapping("/getcampaignbyid")
public List<Map<String, Object>> getcampaignquestionbyid(@RequestParam int id){
return campaignmaster.getcampaignquestionbyid(id);
}
}

320
backend/callcenter/controller/AgentsAPIController.java

@ -0,0 +1,320 @@
package in.gov.chennaicorporation.gccoffice.callcenter.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import in.gov.chennaicorporation.gccoffice.callcenter.service.AgentsService;
@RequestMapping("/gcc/api/agents")
@RestController
public class AgentsAPIController {
@Autowired
private AgentsService agentsService;
@GetMapping("/excel")
public List<Map<String, Object>> fetchDataFromExcel(@RequestParam int categoryId,@RequestParam Long campaignId) {
try {
return agentsService.fetchDataFromExcel(categoryId,campaignId);
} catch (IOException e) {
e.printStackTrace();
return null; // Handle the exception as needed
}
}
@PostMapping("/saveExcelData")
public String saveExcelData( @RequestParam int categoryId,@RequestParam Long campaignId,@RequestParam String filePath) {
try {
// Fetch data from Excel
List<Map<String, Object>> excelData = agentsService.getExcelData(categoryId,campaignId, filePath);
// Save data into the database
agentsService.saveExcelData(excelData);
return "Data saved successfully";
} catch (IOException e) {
e.printStackTrace();
return "Failed to save data";
}
}
@GetMapping("/getdataByIds")
public List<Map<String, Object>> getdataByIds(@RequestParam List<Integer> ids) {
return agentsService.getdataByIds(ids);
}
@GetMapping("/getPendingDataByIds")
public List<Map<String, Object>> getPendingDataByIds(@RequestParam List<Integer> ids) {
return agentsService.getPendingDataByIds(ids);
}
// @PostMapping("/updatecall")
// public ResponseEntity<String> updatecall(@RequestBody Map<String, Object> callData)
// {
// String call_status = (String) callData.get("call_status");
// int data_id = (int) callData.get("data_id");
// int agent_id=(int) callData.get("agent_id");
// int campaign_id=(int) callData.get("campaign_id");
//
// if (call_status == null || call_status.isEmpty()) {
// return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Call status is required.");
// }
//
// agentsService.saveInLogsTable(campaign_id, agent_id, data_id,call_status);
//
// return ResponseEntity.ok("Data Inserted successfully.");
// }
@GetMapping("/getAgentNames")
public List<Map<String, Object>> getAgentsNameById(@RequestParam List<Integer> agentIds){
return agentsService.getAgentsNameById(agentIds);
}
@GetMapping("/getDataFields")
public List<Map<String, Object>> getDataDetailsById(
@RequestParam String originalDataIds) throws JsonProcessingException {
// Parse originalDataIds from JSON string
ObjectMapper objectMapper = new ObjectMapper();
List<List<Integer>> originalDataIdsList = objectMapper.readValue(originalDataIds, new TypeReference<List<List<Integer>>>() {});
// Prepare a list to hold the results for each sub-array
List<Map<String, Object>> groupedResults = new ArrayList<>();
// Iterate through each sub-array of originalDataIds
for (List<Integer> dataIds : originalDataIdsList) {
List<Map<String, Object>> results = agentsService.getDataDetailsById(dataIds);
// Group results according to your business logic
Map<String, Object> combinedResult = new HashMap<>();
for (Map<String, Object> result : results) {
combinedResult.putAll(result);
}
groupedResults.add(combinedResult);
}
return groupedResults;
}
@GetMapping("/getCompletedDataFields")
public Map<String, Object> getCompletedDataDetailsById(
@RequestParam String originalCDataIds) throws JsonProcessingException {
// Parse originalDataIds from JSON string
ObjectMapper objectMapper = new ObjectMapper();
List<Integer> originalCDataIdsList = objectMapper.readValue(originalCDataIds, new TypeReference<List<Integer>>() {});
// Prepare a list to hold the results for each sub-array
//List<Map<String, Object>> groupedCompletedResults = new ArrayList<>();
List<Integer> completedDataIds = new ArrayList<>(); // List to hold data_ids with Complete_count > 0
// Iterate through each sub-array of originalDataIds
List<Map<String, Object>> results = agentsService.getCompletedDataDetailsById(originalCDataIdsList);
// Group results according to your business logic
//Map<String, Object> CompletedcombinedResult = new HashMap<>();
for (Map<String, Object> result : results) {
if (result.get("Complete_count") != null && ((Number) result.get("Complete_count")).intValue() > 0) {
completedDataIds.add((Integer) result.get("data_id"));
}
//groupedCompletedResults.add(result);
}
// Prepare the final response containing grouped results and completed dataIds
Map<String, Object> response = new HashMap<>();
//response.put("groupedCompletedResults", groupedCompletedResults);
response.put("completedDataIds", completedDataIds);
return response;
}
@GetMapping("/getCompletedDataById")
public List<Map<String, Object>> getCompletedDataById(@RequestParam List<Integer> completedDataIds){
return agentsService.getCompletedDataById(completedDataIds);
}
@PostMapping("/furtherAssignedAgents")
public ResponseEntity<Map<String, String>> updateAgentAssigndata(
@RequestBody Map<String, Object> requestData) {
String campaign_id = (String) requestData.get("campaign_id");
String category_id = (String) requestData.get("category_id");
String call_per_agent = (String) requestData.get("call_per_agent");
// Correct key name for selected agents
List<String> selectedAgentsList = (List<String>) requestData.get("selected_agents");
//System.out.println("campaign_id=" + campaign_id);
//System.out.println("category_id=" + category_id);
//System.out.println("call_per_agent=" + call_per_agent);
//System.out.println("selectedAgentsList=" + selectedAgentsList);
int campaignId = Integer.parseInt(campaign_id);
int categoryId = Integer.parseInt(category_id);
int callperagent = Integer.parseInt(call_per_agent);
agentsService.resetAgentAssignmentForNextDay(categoryId,campaignId);
int calls_assign = callperagent * selectedAgentsList.size();
//System.out.println("calls_assign== " + calls_assign);
List<Integer> DataIds=agentsService.getDataIdForFurtherAssign(categoryId, campaignId);
//System.out.println("dataids=== " + DataIds);
if (!DataIds.isEmpty()) {
int dataIndex = 0; // Initialize data index pointer
for (String agentId : selectedAgentsList) {
int selectedAgentId = Integer.parseInt(agentId);
agentsService.addAgentsForCampaign(selectedAgentId, categoryId, campaignId);
// Iterate for noOfCalls times and assign data IDs to the current agent
for (int i = 0; i < callperagent && dataIndex < DataIds.size(); i++, dataIndex++) {
int DataId = DataIds.get(dataIndex);
agentsService.updateAgentForCampaign(
selectedAgentId,
categoryId,
campaignId,
DataId
);
}
}
}
else {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(Map.of("status", "error", "message", "No data available for Further assign."));
}
return ResponseEntity.ok(Map.of("status", "success", "message", "Campaign details saved successfully"));
}
////////////////////Ajith code//////////////////////
@GetMapping("/Campaignview")
public ResponseEntity<?> getCampaignview(@RequestParam int categoryId, @RequestParam int agentId, @RequestParam int dataId) {
try {
List<Map<String, Object>> response = agentsService.getFilteredFields(categoryId, agentId, dataId);
if (response.isEmpty()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("No matching data found.");
}
return ResponseEntity.ok(response);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error: " + e.getMessage());
}
}
@GetMapping("/questions")
public List<Map<String, Object>> getCampaignQuestions(
@RequestParam int categoryId,
@RequestParam int campaignId) {
return agentsService.getCampaignQuestions(categoryId, campaignId);
}
@GetMapping("/fetchAnswer")
public List<Map<String, Object>> fetchAnswer(
@RequestParam int campaignId,
@RequestParam int agentId,
@RequestParam int questionId,
@RequestParam int dataId) {
return agentsService.FetchAnswer(campaignId,agentId,questionId,dataId);
}
@PostMapping("/submitAnswers")
public ResponseEntity<String> submitAnswers(@RequestBody Map<String, List<Map<String, Object>>> requestData) {
List<Map<String, Object>> answers = requestData.get("answers");
if (answers == null || answers.isEmpty()) {
return ResponseEntity.badRequest().body("No answers provided.");
}
agentsService.saveAnswers(answers);
return ResponseEntity.ok("Answers submitted successfully");
}
@GetMapping("/callstatus")
public List<Map<String, Object>> getCallStatus() {
//System.out.println("dropdown");
return agentsService.getCallStatus();
}
@GetMapping("/checkCounts")
public List<Map<String, Object>> checkCounts(
@RequestParam int campaignId,
@RequestParam int dataId) {
return agentsService.checkCounts(campaignId,dataId);
}
@PostMapping("/savecall")
public ResponseEntity<String> savecall(@RequestBody Map<String, Object> callData) {
String call_status = (String) callData.get("call_status");
String remarks = (String) callData.get("remarks");
int data_id = Integer.parseInt(callData.get("data_id").toString());
int agent_id = Integer.parseInt(callData.get("agent_id").toString());
int campaign_id = Integer.parseInt(callData.get("campaign_id").toString());
// System.out.println("controler");
//System.out.println(call_status);
// Add a debug statement to check the received values
// System.out.println("Received call_status: " + call_status);
if (call_status == null || call_status.isEmpty()) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Call status is required.");
}
agentsService.saveCallLogs(call_status, remarks,data_id,agent_id);
agentsService.saveInLogsTable(campaign_id, agent_id, data_id,call_status,remarks);
return ResponseEntity.ok("Data Inserted successfully.");
}
}

36
backend/callcenter/controller/AttendanceAPIController.java

@ -0,0 +1,36 @@
package in.gov.chennaicorporation.gccoffice.callcenter.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import in.gov.chennaicorporation.gccoffice.configuration.AppConfig;
@RequestMapping("/gcc/api/attendance")
@RestController
public class AttendanceAPIController {
private AppConfig appConfig;
private final RestTemplate restTemplate;
@Autowired
public AttendanceAPIController(RestTemplate restTemplate, AppConfig appConfig) {
this.restTemplate = restTemplate;
this.appConfig = appConfig;
}
@GetMapping("/getAttendancedetails")
public String getAttendancedetails(@RequestParam String fromDate,@RequestParam String toDate){
String apiUrl = appConfig.attendanceReport + "/callcenter/api/attendance/getattendancereport"+"?fromDate="+ fromDate + "&toDate="+ toDate;
ResponseEntity<String> responseEntity = restTemplate.getForEntity(apiUrl, String.class);
return responseEntity.getBody();
}
}

614
backend/callcenter/controller/CampaignAPIController.java

@ -0,0 +1,614 @@
package in.gov.chennaicorporation.gccoffice.callcenter.controller;
import org.apache.poi.ss.usermodel.*;
import org.springframework.web.multipart.MultipartFile;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import in.gov.chennaicorporation.gccoffice.callcenter.service.AddcategoryServices;
import in.gov.chennaicorporation.gccoffice.callcenter.service.AgentAssignService;
import in.gov.chennaicorporation.gccoffice.callcenter.service.CampaignService;
@RestController("callcenterapicontroller")
@RequestMapping("gcc/api/campaign")
public class CampaignAPIController {
@Autowired
private CampaignService campaignService;
@Autowired
private AddcategoryServices addCategoryServices; // Injecting the service
@Autowired
private AgentAssignService agentsAssignService;
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private Environment environment;
@GetMapping("/getCampaignDetails")
public ResponseEntity<Map<String, Object>> getCampaignDetails() {
Map<String, Object> response = new HashMap<>();
List<Map<String, Object>> data = campaignService.getCampaignDetails();
response.put("data", data);
return ResponseEntity.ok(response);
}
// Endpoint to get campaign details by ID
@GetMapping("/getCampaignDetailsById")
public @ResponseBody List<Map<String, Object>> getCampaignDetailsById(@RequestParam("campaign_id") Long campaignId) {
return campaignService.getCampaignDetailsById(campaignId);
}
@PostMapping("/updateCampaign")
public ResponseEntity<String> updateCampaign(
@RequestBody Map<String, Object> requestData) {
Long campaign_id = ((Number) requestData.get("campaign_id")).longValue();
String end_date = (String) requestData.get("end_date");
List<Map<String, Object>> questionsData =
(List<Map<String, Object>>) requestData.get("questionsData");
if (campaign_id == null) {
return ResponseEntity.badRequest().body("Campaign ID is required.");
}
try {
// Update campaign details
campaignService.updateCampaign(campaign_id, end_date);
// Save questions and answers
for (Map<String, Object> questionMap : questionsData) {
String category = (String) questionMap.get("category");
String question = (String) questionMap.get("question");
String answerType = (String) questionMap.get("answerType");
List<String> answers = (List<String>) questionMap.get("answers");
if (category != null && question != null && answerType != null) {
campaignService.saveQuestionsAndAnswers(
category,
String.valueOf(campaign_id), // Corrected data type
question,
answerType,
answers
);
}
}
return ResponseEntity.ok("Campaign updated successfully.");
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Error updating campaign: " + e.getMessage());
}
}
//save question and ansewers for campaign
@PostMapping("/saveQuestionsAndAnswers")
public ResponseEntity<String> saveQuestions(@RequestBody List<Map<String, Object>> requestData) {
String response = campaignService.saveQuestionsAnswers(requestData);
return ResponseEntity.ok(response);
}
//save file and get path
private String saveFile(MultipartFile file) throws IOException {
String uploadDirectory = environment.getProperty("file.upload.directory");
String folderName = environment.getProperty("campaign.foldername");
String fileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")) + "_" + file.getOriginalFilename();
String folderPath = uploadDirectory + "/" + folderName + "/excel/";
Path dirPath = Paths.get(folderPath);
if (!Files.exists(dirPath)) {
Files.createDirectories(dirPath);
}
Path filePath = dirPath.resolve(fileName);
Files.write(filePath, file.getBytes());
return filePath.toAbsolutePath().toString();
}
//read uploaded excel data and make condition for each category uploading same excel columns are other some other?
private List<Map<String, Object>> readExcelData(InputStream inputStream, List<String> categoryColumns) throws IOException {
List<Map<String, Object>> dataList = new ArrayList<>();
try (Workbook workbook = new XSSFWorkbook(inputStream)) {
Sheet sheet = workbook.getSheetAt(0);
FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
// Read header row from Excel
Row headerRow = sheet.getRow(0);
List<String> excelHeaders = new ArrayList<>();
for (Cell cell : headerRow) {
excelHeaders.add(cell.getStringCellValue().trim());
}
// Compare Excel headers with category columns
if (!excelHeaders.containsAll(categoryColumns)) {
// throw new IllegalArgumentException("Excel data does not match the category columns.");
}
// Proceed with reading data only if headers match
for (Row row : sheet) {
if (row.getRowNum() == 0) continue; // Skip header row
Map<String, Object> dataMap = new HashMap<>();
for (Cell cell : row) {
String cellValue = "";
switch (formulaEvaluator.evaluateInCell(cell).getCellType()) {
case STRING:
cellValue = cell.getStringCellValue();
break;
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
cellValue = new SimpleDateFormat("yyyy-MM-dd").format(cell.getDateCellValue());
} else {
// Check if value is an integer (whole number)
if (cell.getNumericCellValue() % 1 == 0) {
cellValue = String.valueOf((long) cell.getNumericCellValue()); // Format as integer
} else {
cellValue = String.valueOf(cell.getNumericCellValue()); // Keep decimal values as they are
}
}
break;
case BOOLEAN:
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
default:
cellValue = "Unknown";
break;
}
// Map cell data to correct column name
dataMap.put(excelHeaders.get(cell.getColumnIndex()), cellValue);
}
if (!dataMap.isEmpty()) {
dataList.add(dataMap);
}
}
}
return dataList;
}
@GetMapping("/getExcelData")
public ResponseEntity<List<Map<String, Object>>> getExcelData(@RequestParam("filePath") String filePath) {
try {
// Read data from the uploaded Excel file
List<Map<String, Object>> excelData = readExcelData(new FileInputStream(filePath), null);
// Return data as JSON
return ResponseEntity.ok(excelData);
} catch (IOException e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
@GetMapping("/getlastCampaignid")
public List<Map<String, Object>> getLastRow()
{
return campaignService.getLastRow();
}
@GetMapping("/startcampaign")
public List<Map<String, Object>> getDataforAgents(@RequestParam int campaign_id,@RequestParam int calls_per_agent)
{
return campaignService.getDataforAgents(campaign_id, calls_per_agent);
}
@GetMapping("/viewcampaignstatus")
public List<Map<String, Object>> viewcampaignstatus(@RequestParam int campaign_id)
{
return campaignService.viewcampaignstatus(campaign_id);
}
@GetMapping("/viewcompletedby")
public List<Map<String, Object>> viewcompletedby(@RequestParam int campaign_id,@RequestParam int agent_id)
{
return campaignService.viewcompletedby(campaign_id,agent_id);
}
@PostMapping(value = "/savecampaign", consumes = {"multipart/form-data"})
public ResponseEntity<Map<String, String>> saveCampaign(
@RequestParam String campaignId,
@RequestParam String categoryId,
@RequestParam String eventStartDate,
@RequestParam String eventEndDate,
@RequestParam int noOfCalls,
@RequestParam String description,
@RequestParam(required = false) String questionsData, // JSON as String
@RequestParam(required = false) String selectedAgents // JSON string
) {
// Convert JSON strings to List objects
List<Map<String, Object>> questionsDataList = new ArrayList<>();
List<String> selectedAgentsList = new ArrayList<>();
try {
if (questionsData != null) {
questionsDataList = new ObjectMapper().readValue(questionsData, new TypeReference<List<Map<String, Object>>>() {});
}
if (selectedAgents != null) {
selectedAgentsList = new ObjectMapper().readValue(selectedAgents, new TypeReference<List<String>>() {});
}
} catch (JsonProcessingException e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(Map.of("status", "error", "message", "Invalid JSON format in request data"));
}
// Campaign Details Mapping
Map<String, Object> campaignDetails = new HashMap<>();
campaignDetails.put("campaign_id", campaignId);
campaignDetails.put("category_id", categoryId);
campaignDetails.put("start_date", eventStartDate);
campaignDetails.put("end_date", eventEndDate);
campaignDetails.put("calls_per_agent", noOfCalls);
campaignDetails.put("description", description);
try {
campaignService.saveCampaignDetails(campaignDetails);
// Step 3: Assign Agents for the Campaign
if (!selectedAgentsList.isEmpty()) {
int parsedCampaignId = Integer.parseInt(campaignId);
int parsedCategoryId = Integer.parseInt(categoryId);
System.out.println("selectedAgentsList====== " + selectedAgentsList);
int calls_assign = noOfCalls * selectedAgentsList.size();
System.out.println("calls_assign== " + calls_assign);
List<Integer> DataIds=agentsAssignService.getDataIdForInitialAssign(parsedCategoryId, parsedCampaignId);
for (String agentId : selectedAgentsList) {
int selectedAgentId = Integer.parseInt(agentId);
agentsAssignService.addAgentsForCampaign(selectedAgentId, parsedCategoryId, parsedCampaignId);
}
//System.out.println("dataids=== " + DataIds);
if (!DataIds.isEmpty()) {
int dataIndex = 0; // Initialize data index pointer
for (String agentId : selectedAgentsList) {
int selectedAgentId = Integer.parseInt(agentId);
// Iterate for noOfCalls times and assign data IDs to the current agent
for (int i = 0; i < noOfCalls && dataIndex < DataIds.size(); i++, dataIndex++) {
int DataId = DataIds.get(dataIndex);
agentsAssignService.updateAgentForCampaign(
selectedAgentId,
parsedCategoryId,
parsedCampaignId,
DataId
);
}
}
// Update campaign status to 'ONGOING' after successful assignment
campaignService.updateCampaignStatus(parsedCampaignId, parsedCategoryId);
}
else {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(Map.of("status", "error", "message", "No data available for initial assignment."));
}
}
// Step 4: Save Questions and Answers
if (!questionsDataList.isEmpty()) {
for (Map<String, Object> questionMap : questionsDataList) {
String question = (String) questionMap.get("question");
String answerType = (String) questionMap.get("answerType");
List<String> answers = (List<String>) questionMap.get("answers");
if (question != null && answerType != null) {
campaignService.saveQuestionsAndAnswers(
categoryId,
campaignId,
question,
answerType,
answers
);
} else {
System.out.println("Skipping invalid question data: " + questionMap);
}
}
}
}
catch (Exception e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(Map.of("status", "error", "message", "Failed to save campaign details: " + e.getMessage()));
}
return ResponseEntity.ok(Map.of("status", "success", "message", "Campaign details saved successfully"));
}
//save excel data separate method
@PostMapping(value = "/saveexcelcampaign" ,consumes = {"multipart/form-data"})
public Map<String, String> saveExcelCampaign(
@RequestParam String name,
@RequestParam String category,
@RequestPart MultipartFile file) {
//System.out.println("Received campaign data:");
//System.out.println("Name: " + name);
//System.out.println("Category: " + category);
//System.out.println("File Name: " + file.getOriginalFilename());
Map<String, Object> campaignDetails = new HashMap<>();
campaignDetails.put("campaign_name", name);
campaignDetails.put("category_id", category);
try {
// Get category-specific columns
List<Map<String, Object>> categoryColumns = addCategoryServices.getCategoryColumns(Integer.parseInt(category));
//System.out.println("categorycolmns: " + categoryColumns);
List<String> expectedHeaders = categoryColumns.stream()
.map(column -> column.get("column_name").toString())
.collect(Collectors.toList());
// System.out.println("expectedheaders: " + expectedHeaders);
// Fetch field_ columns from upload_data table
List<String> fieldColumns = campaignService.getUploadDataFieldColumns();
//System.out.println("fieldColumns: " + fieldColumns);
// Read uploaded Excel data and extract headers
List<Map<String, Object>> excelData = readExcelData(file.getInputStream(), expectedHeaders);
// System.out.println("excedata: " + excelData );
List<String> uploadedHeaders = new ArrayList<>(excelData.get(0).keySet()); // Extract headers from first row
//System.out.println("uploadeddata : " + uploadedHeaders);
// Check column count mismatch with field_ columns
if (uploadedHeaders.size() > fieldColumns.size()) {
Map<String, String> response = new HashMap<>();
response.put("status", "column_mismatch"); // Changed status to differentiate
response.put("message", "Extend the columns in Database, Inform Admin.");
return response;
}
// Validate headers
if (!new HashSet<>(expectedHeaders).equals(new HashSet<>(uploadedHeaders))) {
Map<String, String> response = new HashMap<>();
response.put("status", "header_mismatch"); // Changed status to differentiate
response.put("message", "Excel data does not match the category columns.");
return response;
}
String fileUrl = saveFile(file);
campaignDetails.put("excel_url", fileUrl);
//System.out.println("Campaign Details: " + campaignDetails);
//System.out.println("Excel Data: " + excelData);
campaignService.saveCampaignDetailsExcel(campaignDetails);
int lastId = campaignService.getLastInsertedCampaignId();
String excelUrl = campaignService.getExcelUrlByCampaignId(lastId);
//List<Map<String, Object>> excelDatas = readExcelDataupdated(new FileInputStream(excelUrl));
List<Map<String, Object>> excelDatas = readExcelData(new FileInputStream(excelUrl), uploadedHeaders);
//System.out.println("excelDatas:" + excelDatas);
for (Map<String, Object> row : excelDatas) {
campaignService.saveUploadData(category, lastId, row,expectedHeaders);
//System.out.println("exceldatas:" + excelDatas);
}
Map<String, String> response = new HashMap<>();
response.put("status", "success");
response.put("message", "Campaign and Excel saved successfully");
return response;
}
catch (IOException e) {
e.printStackTrace();
Map<String, String> response = new HashMap<>();
response.put("status", "error");
response.put("message", "Failed to save campaign details: "+ e.getMessage());
return response;
}
}
@GetMapping("/availableAgents")
public ResponseEntity<List<Map<String, Object>>> getAvailableAgents() {
// Query 1: Fetch OUTBOUND agents
String outboundAgentsQuery = "SELECT agent_name, agent_id, calling_type " +
"FROM gcc_1913_qaqc.agents_list " +
"WHERE calling_type='OUTBOUND'";
List<Map<String, Object>> outboundAgents = jdbcTemplate.queryForList(outboundAgentsQuery);
//System.out.println("outboundagents" + outboundAgents);
// Query 2: Fetch agents from ongoing campaigns
String ongoingCampaignAgentsQuery = "SELECT ca.agent_id " +
"FROM gcc_1913_campaign.campaign_request cr " +
"JOIN gcc_1913_campaign.agent_assign ca " +
"ON ca.campaign_id = cr.campaign_id " +
"WHERE cr.campaign_status = 'ONGOING'";
List<Map<String, Object>> ongoingAgents = jdbcTemplate.queryForList(ongoingCampaignAgentsQuery);
//System.out.println("ongoingAgents" + ongoingAgents);
// Extract agent IDs from both lists
Set<Integer> ongoingAgentIds = ongoingAgents.stream()
.map(agent -> (Integer) agent.get("agent_id"))
.collect(Collectors.toSet());
// Filter OUTBOUND agents who are NOT in ongoing agents
List<Map<String, Object>> availableAgents = outboundAgents.stream()
.filter(agent -> !ongoingAgentIds.contains(agent.get("agent_id")))
.collect(Collectors.toList());
return ResponseEntity.ok(availableAgents);
}
private Object getCellValue(Cell cell) {
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue().trim();
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
return cell.getDateCellValue(); // Return Date for date-formatted cells
}
double numericValue = cell.getNumericCellValue();
// ✅ Convert numeric values that are likely mobile numbers to string
if (String.valueOf((long) numericValue).length() >= 10) { // Assuming mobile numbers are at least 10 digits
return String.valueOf((long) numericValue);
}
// ✅ Convert to int if no decimal part, else keep as double
return (numericValue % 1 == 0) ? (int) numericValue : numericValue;
case BOOLEAN:
return cell.getBooleanCellValue();
case FORMULA:
return cell.getCellFormula(); // Return formula as string
case BLANK:
return "";
default:
return "";
}
}
//question and answers report page api
@GetMapping("/question-answers")
public ResponseEntity<?> getQuestionAnswers(@RequestParam int campaignId) {
List<Map<String, Object>> response = campaignService.getQuestionAnswers(campaignId);
return ResponseEntity.ok(response);
}
//dizo campaignlist apicontroller
// Query Parameter Approach
@GetMapping("/statistics")
public ResponseEntity<Map<String, Object>> getCampaignStatisticsByQuery(@RequestParam int campaignId) {
Map<String, Object> statistics = campaignService.getCampaignStatistics(campaignId);
return ResponseEntity.ok(statistics);
}
@GetMapping("/assignagentid")
public ResponseEntity<List<Map<String, Object>>> getAllAgents() {
List<Map<String, Object>> assignAgentId = campaignService.getAllAgents();
return ResponseEntity.ok(assignAgentId);
}
@PostMapping("/close")
public ResponseEntity<String> closeCampaign(@RequestParam("campaignId") int campaignId) {
if (campaignId <= 0) {
return ResponseEntity.badRequest().body("Invalid Campaign ID");
}
System.out.println("Received request to close campaign ID: " + campaignId); // Debugging log
int rowsUpdated = campaignService.closeCampaign(campaignId);
if (rowsUpdated > 0) {
return ResponseEntity.ok("Campaign closed successfully");
} else {
return ResponseEntity.status(400).body("Failed to close campaign. Campaign ID " + campaignId + " may not exist.");
}
}
@PostMapping("/auto-close")
public ResponseEntity<String> autoCloseExpiredCampaigns() {
int rowsUpdated = campaignService.autoCloseExpiredCampaigns();
if (rowsUpdated > 0) {
return ResponseEntity.ok(rowsUpdated + " expired campaigns closed successfully.");
} else {
return ResponseEntity.ok("No expired campaigns found.");
}
}
}

29
backend/callcenter/controller/CampaignDropdownApiController.java

@ -0,0 +1,29 @@
package in.gov.chennaicorporation.gccoffice.callcenter.controller;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import in.gov.chennaicorporation.gccoffice.callcenter.service.CampaignDropdownApiService;
@RequestMapping("gcc/api")
@RestController
public class CampaignDropdownApiController {
@Autowired
private CampaignDropdownApiService dropdownApiService;
@GetMapping("/getAnswerTypes")
@ResponseBody
public List<Map<String, Object>> getAnswerTypes() {
return dropdownApiService.getAnswerTypes();
}
}

100
backend/callcenter/controller/CampaignReportAPIController.java

@ -0,0 +1,100 @@
package in.gov.chennaicorporation.gccoffice.callcenter.controller;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import in.gov.chennaicorporation.gccoffice.callcenter.service.CampaignReportService;
@RestController
@RequestMapping("gcc/api/campaignreport")
public class CampaignReportAPIController {
@Autowired
private CampaignReportService campaignReportService;
@GetMapping("/getcampaignData")
public List<Map<String, Object>> getCampaignData(
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate) {
List<Map<String, Object>> campaignData = campaignReportService.getCampaignData(startDate, endDate);
//System.out.println("Campaign Data: " + campaignData); // Debugging log
return campaignData;
}
@GetMapping("/getagentdatacount")
public List<Map<String, Object>> getAgentwiseData(@RequestParam String campaign_id) {
List<Map<String, Object>> agentData = campaignReportService.getAgentwiseData(campaign_id);
//System.out.println("Agent Data: " + agentData);
return agentData;
}
@GetMapping("/getReportCampaignid")
public ResponseEntity<?> getAgentReportCampaignId(@RequestParam String campaign_id) {
List<Map<String, Object>> agentData = campaignReportService.getAgentReportCampaignId(campaign_id);
//System.out.println("Agent Data: " + agentData);
return ResponseEntity.ok(agentData);
}
//question and answers report page api
@GetMapping("/question-answers")
public ResponseEntity<?> getQuestionAnswers(@RequestParam int campaign_id) {
List<Map<String, Object>> response = campaignReportService.getQuestionAnswers(campaign_id);
return ResponseEntity.ok(response);
}
// @GetMapping("/download-excel")
// public void downloadFilteredCSV(
// @RequestParam int categoryId,
// @RequestParam int campaignId,
//
//
//
// HttpServletResponse response) throws IOException {
//
// // Set response headers
// response.setContentType("text/csv");
// response.setHeader("Content-Disposition", "attachment; filename=filtered_data.csv");
//
// // Generate CSV and write to response
// PrintWriter writer = response.getWriter();
// campaignReportService.generateCSV(categoryId, campaignId, writer);
// writer.flush();
// writer.close();
// }
@GetMapping("/download-excel")
public void downloadFilteredCSV(
@RequestParam int categoryId,
@RequestParam int campaignId,
HttpServletResponse response) throws IOException {
String filename = campaignReportService.getCampaignName(campaignId);
// Format campaign name for file safety (remove spaces/special characters)
//String safeCampaignName = filename.replaceAll("[^a-zA-Z0-9]", "_");
// Set response headers
response.setContentType("text/csv");
response.setHeader("Content-Disposition", "attachment; filename=" + filename + ".csv");
// Generate CSV and write to response
PrintWriter writer = response.getWriter();
campaignReportService.generateCSV(categoryId, campaignId, writer);
writer.flush();
writer.close();
}
}

281
backend/callcenter/controller/CategoryAPIController.java

@ -0,0 +1,281 @@
package in.gov.chennaicorporation.gccoffice.callcenter.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import in.gov.chennaicorporation.gccoffice.callcenter.service.AddcategoryServices;
@RequestMapping("/gcc/api/category")
@RestController
public class CategoryAPIController {
@Autowired
private AddcategoryServices addCategoryServices; // Injecting the service
@PostMapping("/save")
public ResponseEntity<String> saveCategoryDetails(@RequestBody Map<String, Object> payload) {
try {
addCategoryServices.saveCategoryDetails(payload);
return ResponseEntity.ok("Category and columns saved successfully.");
} catch (IllegalArgumentException e) {
return ResponseEntity.badRequest().body("Validation Error: " + e.getMessage());
} catch (Exception e) {
return ResponseEntity.status(500).body("Internal Server Error: " + e.getMessage());
}
}
// Endpoint to save category details
// @PostMapping("/save")
// public ResponseEntity<String> saveCategoryDetails(@RequestBody Map<String, Object> payload) {
// try {
// addCategoryServices.saveCategoryDetails(payload); // Call the service method to save category details
// return ResponseEntity.ok("Category details saved successfully.");
// } catch (IllegalArgumentException e) {
// return ResponseEntity.badRequest().body("Error: " + e.getMessage());
// } catch (Exception e) {
// return ResponseEntity.status(500).body("Error saving category details: " + e.getMessage());
// }
// }
// Endpoint to get all categories
@GetMapping("/list")
public List<Map<String, Object>> getAllCategories() {
return addCategoryServices.getAllCategories();
}
@GetMapping("/showcategoryId")
public ResponseEntity<?> getCategoryById(@RequestParam("category_id") int categoryId) {
Map<String, Object> category = addCategoryServices.showCategory(categoryId);
if (category.isEmpty()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Category not found");
}
return ResponseEntity.ok(category);
}
@PostMapping("/deleteColumnById")
public ResponseEntity<Map<String, Object>> deleteCategoryColumnById(@RequestParam("columnId") int columnId) {
boolean updated = addCategoryServices.removeColumnById(columnId);
Map<String, Object> response = new HashMap<>();
response.put("success", updated);
return ResponseEntity.ok(response);
}
@PostMapping("/updateCategoryColumns")
public ResponseEntity<Map<String, Object>> updateCategoryColumnsById(@RequestBody Map<String, Object> requestData) {
try {
int categoryId = (int) requestData.get("categoryId");
List<Map<String, Object>> columns = (List<Map<String, Object>>) requestData.get("columns");
boolean allUpdated = true;
for (Map<String, Object> column : columns) {
int columnId = (int) column.get("id");
String columnName = (String) column.get("name");
boolean updated = addCategoryServices.updateColumnById(categoryId,columnId, columnName);
if (!updated) {
allUpdated = false;
}
}
Map<String, Object> response = new HashMap<>();
response.put("success", allUpdated);
return ResponseEntity.ok(response);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Map.of("error", "Invalid data format"));
}
}
@PostMapping("/addNewColumns")
public ResponseEntity<Map<String, Object>> addNewCategoryColumnsById(@RequestBody Map<String, Object> requestData) {
try {
int categoryId = (int) requestData.get("categoryId");
List<Map<String, Object>> columns = (List<Map<String, Object>>) requestData.get("columns");
boolean allUpdated = true;
for (Map<String, Object> column : columns) {
String columnName = (String) column.get("name");
boolean updated = addCategoryServices.addnewupdateColumn(categoryId, columnName);
if (!updated) {
allUpdated = false;
}
}
Map<String, Object> response = new HashMap<>();
response.put("success", allUpdated);
return ResponseEntity.ok(response);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Map.of("error", "Invalid data format"));
}
}
@PutMapping("/update/{categoryId}")
public ResponseEntity<String> updateCategoryWithColumns(
@PathVariable("categoryId") int categoryId,
@RequestBody Map<String, Object> payload) {
String categoryName = (String) payload.get("categoryName");
List<String> columns = (List<String>) payload.get("columns");
try {
int rowsAffected = addCategoryServices.updateCategoryWithColumns(categoryId, categoryName, columns);
return rowsAffected > 0
? ResponseEntity.ok("Category and columns updated successfully")
: ResponseEntity.status(HttpStatus.NOT_FOUND).body("Category not found or update failed");
} catch (IllegalArgumentException e) {
return ResponseEntity.badRequest().body("Validation Error: " + e.getMessage());
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Error updating category: " + e.getMessage());
}
}
// // Endpoint to get a category by its ID
// @GetMapping("/showcategoryId")
// public ResponseEntity<?> getCategoryById(@RequestParam("category_id") int categoryId) {
// Map<String, Object> category = addCategoryServices.showCategory(categoryId);
//
// if (category == null) {
// return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Category not found");
// }
//
// return ResponseEntity.ok(category);
// }
//
// @PutMapping("/update/{categoryId}")
// public ResponseEntity<String> updateCategoryWithColumns(
// @PathVariable("categoryId") int categoryId,
// @RequestBody Map<String, Object> payload) {
//
// String categoryName = (String) payload.get("categoryName");
// List<String> columns = (List<String>) payload.get("columns");
//
// try {
// int rowsAffected = addCategoryServices.updateCategoryWithColumns(categoryId, categoryName, columns);
// if (rowsAffected > 0) {
// return ResponseEntity.ok("Category and columns updated successfully");
// } else {
// return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Category not found or update failed");
// }
// } catch (IllegalArgumentException e) {
// return ResponseEntity.badRequest().body("Validation Error: " + e.getMessage());
// } catch (Exception e) {
// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
// .body("Error updating category: " + e.getMessage());
// }
// }
// @GetMapping("/showcategoryId")
// public ResponseEntity<?> showCategoryId(@RequestParam("category_id") int categoryId) {
// try {
// Map<String, Object> category = addCategoryServices.showCategory(categoryId);
// if (category != null && !category.isEmpty()) {
// return ResponseEntity.ok(category);
// } else {
// return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Category not found");
// }
// } catch (Exception e) {
// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
// .body("Error retrieving category: " + e.getMessage());
// }
// }
// @PutMapping("/update/{categoryId}")
// public ResponseEntity<String> updateCategory(
// @PathVariable("categoryId") int categoryId,
// @RequestParam String categoryName) {
//
// // Validate input
// if (categoryName == null || categoryName.trim().isEmpty()) {
// return ResponseEntity.badRequest().body("Category name cannot be empty");
// }
//
// try {
// // Call the service method to update the category
// int rowsAffected = addCategoryServices.updateCategory(categoryId, categoryName);
// if (rowsAffected > 0) {
// return ResponseEntity.ok("Category updated successfully");
// } else {
// return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Category not found or update failed");
// }
// } catch (Exception e) {
// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
// .body("Error updating category: " + e.getMessage());
// }
// }
// Endpoint to delete a category by its ID
@DeleteMapping("/delete/{categoryId}")
public ResponseEntity<String> deleteCategory(
@PathVariable("categoryId") int categoryId) {
try {
// Call the service method to delete the category
addCategoryServices.deleteCategory(categoryId);
return ResponseEntity.ok("Category deleted successfully");
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Error deleting category: " + e.getMessage());
}
}
//hari category api populate
@GetMapping("/getcategory")
public List<Map<String, Object>> getcategory(){
return addCategoryServices.getcategory();
}
// Get category-specific columns based on category_id
@GetMapping("/getCategoryColumns")
public List<Map<String, Object>> getCategoryColumns(@RequestParam int category_id) {
return addCategoryServices.getCategoryColumns(category_id);
}
@GetMapping("/getcampaignbycategory")
public List<Map<String, Object>> getcampaignbycategory(@RequestParam int id)
{
return addCategoryServices.getcampaignbycategory(id);
}
}

219
backend/callcenter/controller/MainController.java

@ -0,0 +1,219 @@
package in.gov.chennaicorporation.gccoffice.callcenter.controller;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import in.gov.chennaicorporation.gccoffice.callcenter.service.AddcategoryServices;
import in.gov.chennaicorporation.gccoffice.callcenter.service.AgentsService;
import in.gov.chennaicorporation.gccoffice.callcenter.service.AttendanceService;
import in.gov.chennaicorporation.gccoffice.callcenter.service.AgentAssignService;
import in.gov.chennaicorporation.gccoffice.callcenter.service.CampaignService;
import in.gov.chennaicorporation.gccoffice.configuration.AppConfig;
import in.gov.chennaicorporation.gccoffice.service.LoginUserInfo;
@RequestMapping("/gcc/callcenter")
@Controller("callCenterCampaignMainController")
public class MainController {
@Autowired
private AgentAssignService campaignmaster;
@Autowired
private CampaignService campaignService;
@Autowired
private AddcategoryServices addCategoryServices;
@Autowired
private AgentsService agentsService;
@Autowired
private AttendanceService attendanceSerivce;
private AppConfig appConfig;
private RestTemplate restTemplate;
@Autowired
public MainController(AgentAssignService campaignmaster,AgentsService agentsService,CampaignService campaignService,AddcategoryServices addCategoryServices,RestTemplate restTemplate, AppConfig appConfig)
{
this.campaignmaster=campaignmaster;
this.campaignService=campaignService;
this.addCategoryServices=addCategoryServices;
this.agentsService=agentsService;
this.restTemplate = restTemplate;
this.appConfig = appConfig;
}
@GetMapping("/admin/addcategory")
public String addcategory(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId",LoginUserId);
String UserRole = LoginUserInfo.getUserRole();
model.addAttribute("UserRole", UserRole);
List<Map<String, Object>> categories = addCategoryServices.getAllCategories();
//System.out.println(categories);
model.addAttribute("categories", categories);
return "modules/callcenter/addcategory";
}
@GetMapping("/admin/createcampaign")
public String createcampaign(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId",LoginUserId);
String UserRole = LoginUserInfo.getUserRole();
model.addAttribute("UserRole", UserRole);
/*
* List<Map<String, Object>> campaigns = campaignService.getCampaignDetails();
*
*
* System.out.println("campaignlist:"+campaigns);
*
* model.addAttribute("campaigns", campaigns);
*/
return "modules/callcenter/createcampaign"; // Name of the Thymeleaf template (e.g., campaignList.html)
}
@GetMapping("/admin/campaignlist")
public String viewCampaignList(Model model)
{
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId",LoginUserId);
String UserRole = LoginUserInfo.getUserRole();
model.addAttribute("UserRole", UserRole);
List<Map<String, Object>> campaigns = campaignService.getDetailsForStart();
model.addAttribute("campaigns", campaigns);
List<Map<String, Object>> activeCampaigns =campaignService.getActiveCampaigns();
model.addAttribute("activeCampaigns", activeCampaigns);
return "modules/callcenter/campaignlist";
}
@GetMapping("/agentscampaign")
public String targetPage(Model model)
{
String LoginUserId = LoginUserInfo.getLoginUserId();
int userId = Integer.parseInt(LoginUserId);
model.addAttribute("LoginUserId",LoginUserId);
String agent_name=LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("agent_name", agent_name);
String UserRole = LoginUserInfo.getUserRole();
model.addAttribute("UserRole", UserRole);
List<Map<String, Object>> agentsCampaigns=agentsService.getAgentsALLCampaigns(userId);
List<Map<String, Object>> agentsCampaignsList=agentsService.getAgentsALLCampaignsList(userId);
List<Map<String, Object>> agentsCampaignsList1=agentsService.getAgentsALLCampaignsList1(userId);
//List<Map<String, Object>> CampActions=agentsService.getCallCategories();
//model.addAttribute("CampActions", CampActions);
model.addAttribute("agentsCampaignsList", agentsCampaignsList);
model.addAttribute("agentsCampaigns", agentsCampaigns);
model.addAttribute("agentsCampaignsList1", agentsCampaignsList1);
//System.out.println("Agents Campaigns List: " + agentsCampaignsList);
//System.out.println("Agents Campaigns : " + agentsCampaigns);
return "modules/callcenter/agentscampaign";
}
@GetMapping("/admin/campaignreport")
public String campaignreport(Model model)
{
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId",LoginUserId);
String UserRole = LoginUserInfo.getUserRole();
model.addAttribute("UserRole", UserRole);
return "modules/callcenter/campaignreport";
}
@GetMapping("/attendancereport")
public String AttendanceList(
@RequestParam(required = false) String fromDate,
@RequestParam(required = false) String toDate,
Model model) {
List<Map<String, Object>> attendanceData = Collections.emptyList();
if (fromDate != null && !fromDate.isEmpty() && toDate != null && !toDate.isEmpty()) {
String apiUrl = appConfig.attendanceReport + "/callcenter/api/attendance/getattendancereport?fromDate=" + fromDate + "&toDate=" + toDate;
try {
ResponseEntity<String> responseEntity = restTemplate.getForEntity(apiUrl, String.class);
String responseBody = responseEntity.getBody();
if (responseBody != null && !responseBody.isEmpty()) {
ObjectMapper objectMapper = new ObjectMapper();
if (responseBody.trim().startsWith("{")) {
// Single object response
Map<String, Object> singleData = objectMapper.readValue(responseBody, new TypeReference<>() {});
attendanceData = List.of(singleData);
} else {
// Array response
attendanceData = objectMapper.readValue(responseBody, new TypeReference<>() {});
}
}
} catch (Exception e) {
System.err.println("Error fetching attendance data: " + e.getMessage());
}
}
model.addAttribute("attendanceData", attendanceData);
model.addAttribute("fromDate", fromDate);
model.addAttribute("toDate", toDate);
model.addAttribute("LoginUserId", LoginUserInfo.getLoginUserId());
model.addAttribute("UserRole", LoginUserInfo.getUserRole());
return "modules/callcenter/attendancereport";
}
}

26
backend/callcenter/controller/WhatsappController.java

@ -0,0 +1,26 @@
package in.gov.chennaicorporation.gccoffice.callcenter.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import in.gov.chennaicorporation.gccoffice.callcenter.service.WhatsappMsgService;
@RestController
@RequestMapping("/gcc/api/whatsapp")
public class WhatsappController {
@Autowired
private WhatsappMsgService whatsappMsgService;
@PostMapping("/send-whatsapp-message")
public ResponseEntity<String> sendWhatsAppMessage(@RequestParam String msgUrl) {
String response = whatsappMsgService.sendMsg(msgUrl);
return ResponseEntity.ok(response);
}
}

303
backend/callcenter/service/AddcategoryServices.java

@ -0,0 +1,303 @@
package in.gov.chennaicorporation.gccoffice.callcenter.service;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import java.util.Locale.Category;
import java.util.Map;
import javax.sql.DataSource;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import java.sql.PreparedStatement;
import java.sql.Statement;
@Service
public class AddcategoryServices {
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(@Qualifier("mysql1913CampaignDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
// public void saveCategoryDetails(Map<String, Object> categoryData) {
// String sql = "INSERT INTO category (category_name, isactive, isdelete, created_date) VALUES (?, 1, 0, CURRENT_TIMESTAMP)";
//
// // Ensure that the key "categoryname" matches exactly what is being sent from the frontend
// String categoryName = (String) categoryData.get("categoryname");
//
// // Check if categoryName is null or empty and handle it properly
// if (categoryName == null || categoryName.trim().isEmpty()) {
// throw new IllegalArgumentException("Category name cannot be null or empty");
// }
//
// jdbcTemplate.update(sql, categoryName);
// }
@Transactional
public void saveCategoryDetails(Map<String, Object> categoryData) {
String categoryName = (String) categoryData.get("categoryname");
List<String> columns = (List<String>) categoryData.get("columns");
if (categoryName == null || categoryName.trim().isEmpty()) {
throw new IllegalArgumentException("Category name cannot be null or empty");
}
if (columns == null || columns.isEmpty() || columns.contains("")) {
throw new IllegalArgumentException("At least one column name is required");
}
// Insert into category table and get the generated category_id
String categorySql = "INSERT INTO category (category_name, isactive, isdelete, created_date) VALUES (?, 1, 0, CURRENT_TIMESTAMP)";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(categorySql, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, categoryName);
return ps;
}, keyHolder);
Integer categoryId = keyHolder.getKey().intValue(); // Extract generated category_id
// Insert columns into category_columns table
String columnSql = "INSERT INTO category_columns (category_id, column_name, isactive, isdelete, created_date) VALUES (?, ?, 1, 0, CURRENT_TIMESTAMP)";
jdbcTemplate.batchUpdate(columnSql, columns, columns.size(),
(PreparedStatement ps, String column) -> {
ps.setInt(1, categoryId);
ps.setString(2, column);
});
}
@Transactional
public List<Map<String, Object>> getAllCategories() {
String SqlQuery = "SELECT category_id,category_name FROM category where isactive=1 and isdelete=0";
List<Map<String, Object>> result = jdbcTemplate.queryForList(SqlQuery);
return result;
}
public Map<String, Object> showCategory(int categoryId) {
String categorySql = "SELECT category_id, category_name FROM category WHERE category_id = ? AND isactive = 1 AND isdelete = 0";
Map<String, Object> category;
try {
category = jdbcTemplate.queryForMap(categorySql, categoryId);
} catch (EmptyResultDataAccessException e) {
return Collections.emptyMap();
}
String columnsSql = "SELECT id,column_name FROM category_columns WHERE category_id = ? AND isactive = 1 AND isdelete = 0";
List<Map<String,Object>> columns = jdbcTemplate.queryForList(columnsSql,categoryId);
category.put("columns", columns);
return category;
}
@Transactional
public int updateCategoryWithColumns(int categoryId, String categoryName, List<String> columns) {
if (categoryName == null || categoryName.trim().isEmpty()) {
throw new IllegalArgumentException("Category name cannot be empty");
}
if (columns == null || columns.size() < 2 || columns.contains("")) {
throw new IllegalArgumentException("At least two column names are required");
}
String updateCategorySql = "UPDATE category SET category_name = ? WHERE category_id = ? AND isactive = 1 AND isdelete = 0";
int categoryUpdateCount = jdbcTemplate.update(updateCategorySql, categoryName, categoryId);
if (categoryUpdateCount == 0) {
throw new IllegalArgumentException("Category not found or update failed.");
}
String deleteColumnsSql = "DELETE FROM category_columns WHERE category_id = ? AND isactive = 1 AND isdelete = 0";
jdbcTemplate.update(deleteColumnsSql, categoryId);
String insertColumnsSql = "INSERT INTO category_columns (category_id, column_name, isactive, isdelete, created_date) VALUES (?, ?, 1, 0, CURRENT_TIMESTAMP)";
jdbcTemplate.batchUpdate(insertColumnsSql, columns, columns.size(), (PreparedStatement ps, String column) -> {
ps.setInt(1, categoryId);
ps.setString(2, column);
});
return categoryUpdateCount;
}
// @Transactional
// public int updateCategoryWithColumns(int categoryId, String categoryName, List<String> columns) {
// if (categoryName == null || categoryName.trim().isEmpty()) {
// throw new IllegalArgumentException("Category name cannot be empty");
// }
// if (columns == null || columns.isEmpty() || columns.contains("")) {
// throw new IllegalArgumentException("At least one column name is required");
// }
//
// String updateCategorySql = "UPDATE category SET category_name = ? WHERE category_id = ? AND isactive = 1 AND isdelete = 0";
// int categoryUpdateCount = jdbcTemplate.update(updateCategorySql, categoryName, categoryId);
//
// if (categoryUpdateCount == 0) {
// throw new IllegalArgumentException("Category not found or update failed.");
// }
//
// String deleteColumnsSql = "DELETE FROM category_columns WHERE category_id = ? AND isactive = 1 AND isdelete = 0";
// jdbcTemplate.update(deleteColumnsSql, categoryId);
//
// String insertColumnsSql = "INSERT INTO category_columns (category_id, column_name, isactive, isdelete, created_date) VALUES (?, ?, 1, 0, CURRENT_TIMESTAMP)";
// jdbcTemplate.batchUpdate(insertColumnsSql, columns, columns.size(), (PreparedStatement ps, String column) -> {
// ps.setInt(1, categoryId);
// ps.setString(2, column);
// });
//
// return categoryUpdateCount;
// }
// // Method to show a category by its ID
// public Map<String, Object> showCategory(int categoryId) {
// // Fetch category details
// String categorySql = "SELECT category_id, category_name FROM category WHERE category_id = ? AND isactive = 1 AND isdelete = 0";
// Map<String, Object> category;
// try {
// category = jdbcTemplate.queryForMap(categorySql, categoryId);
// } catch (EmptyResultDataAccessException e) {
// return null; // If no category found
// }
//
// // Fetch category columns
// String columnsSql = "SELECT column_name FROM category_columns WHERE category_id = ? AND isactive = 1 AND isdelete = 0";
// List<String> columns = jdbcTemplate.queryForList(columnsSql, String.class, categoryId);
//
// // Add columns to response
// category.put("columns", columns);
// return category;
// }
//
//
// @Transactional
// public int updateCategoryWithColumns(int categoryId, String categoryName, List<String> columns) {
// // Validate input
// if (categoryName == null || categoryName.trim().isEmpty()) {
// throw new IllegalArgumentException("Category name cannot be empty");
// }
// if (columns == null || columns.isEmpty() || columns.contains("")) {
// throw new IllegalArgumentException("At least one column name is required");
// }
//
// // Update category name
// String updateCategorySql = "UPDATE category SET category_name = ? WHERE category_id = ? AND isactive = 1 AND isdelete = 0";
// int categoryUpdateCount = jdbcTemplate.update(updateCategorySql, categoryName, categoryId);
//
// if (categoryUpdateCount == 0) {
// throw new IllegalArgumentException("Category not found or update failed.");
// }
//
// // Remove existing category columns before inserting new ones
// String deleteColumnsSql = "DELETE FROM category_columns WHERE category_id = ?";
// jdbcTemplate.update(deleteColumnsSql, categoryId);
//
// // Insert updated columns
// String insertColumnsSql = "INSERT INTO category_columns (category_id, column_name, isactive, isdelete, created_date) VALUES (?, ?, 1, 0, CURRENT_TIMESTAMP)";
// jdbcTemplate.batchUpdate(insertColumnsSql, columns, columns.size(),
// (PreparedStatement ps, String column) -> {
// ps.setInt(1, categoryId);
// ps.setString(2, column);
// });
//
// return categoryUpdateCount;
// }
// // Method to update a category's name by its ID
// public int updateCategory(int categoryId, String categoryName) {
// String sql = "UPDATE category SET category_name = ? WHERE category_id = ? AND isactive = 1 AND isdelete = 0";
// return jdbcTemplate.update(sql, categoryName, categoryId);
// }
// Method to delete a category by its name
public void deleteCategory(int categoryId) {
// String sql = "DELETE FROM category WHERE category_id = ?";
String sql = "UPDATE category SET isactive=0 , isdelete=1 WHERE category_id = ?";
jdbcTemplate.update(sql, categoryId);
}
//hari populate category services
@Transactional
public List<Map<String, Object>> getcategory() {
String sqlQuery = "SELECT category_id,category_name FROM category where isactive='1' and isdelete='0'";
return jdbcTemplate.queryForList(sqlQuery);
}
public List<Map<String, Object>> getCategoryColumns(int categoryId) {
String sqlQuery = "SELECT column_name FROM category_columns WHERE category_id = ? AND isactive = 1";
return jdbcTemplate.queryForList(sqlQuery, categoryId);
}
// Fetch category with columns
public List<Map<String, Object>> getCategoriesWithColumns() {
String sqlQuery = "SELECT c.category_id, c.category_name, cc.column " +
"FROM gcc_1913_campaign.category c " +
"INNER JOIN gcc_1913_campaign.category_columns cc ON c.category_id = cc.category_id " +
"WHERE c.isactive = 1 AND c.isdelete = 0 " +
"AND cc.isactive = 1 AND cc.isdelete = 0";
return jdbcTemplate.queryForList(sqlQuery);
}
@Transactional
public List<Map<String, Object>> getcampaignbycategory(int id) {
String sqlQuery = "SELECT cr.campaign_id,cr.campaign_name FROM campaign_request cr JOIN category c ON cr.category_id=c.category_id where cr.category_id=? and cr.isactive='1'";
return jdbcTemplate.queryForList(sqlQuery,id);
}
public boolean removeColumnById(int columnId) {
String sql = "UPDATE category_columns SET isactive = 0, isdelete = 1 WHERE id = ?";
int rowsAffected = jdbcTemplate.update(sql, columnId);
return rowsAffected > 0; // Returns true if at least one row was updated, otherwise false
}
public boolean updateColumnById(int categoryId,int columnId, String columnName) {
String sql = "UPDATE category_columns SET column_name = ? WHERE id = ? and category_id=?";
int rowsAffected = jdbcTemplate.update(sql, columnName, columnId,categoryId);
return rowsAffected > 0;
}
public boolean addnewupdateColumn(int categoryId, String columnName) {
//String sql = "UPDATE category_columns SET column_name = ? WHERE id = ? and category_id=?";
String sql = "INSERT INTO category_columns (category_id, column_name) VALUES (?, ?)";
int rowsAffected = jdbcTemplate.update(sql, categoryId,columnName);
return rowsAffected > 0;
}
}

214
backend/callcenter/service/AgentAssignService.java

@ -0,0 +1,214 @@
package in.gov.chennaicorporation.gccoffice.callcenter.service;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@Service
public class AgentAssignService
{
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(@Qualifier("mysql1913CampaignDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Autowired
public void setDataSource2(@Qualifier("mysql1913QAQCDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Autowired
private JdbcTemplate jdbcTemplate2;
@Transactional
public List<Map<String, Object>> getcategory() {
String sqlQuery = "SELECT category_id,category_name FROM gcc_1913_campaign.category where isactive='1' and isdelete='0'";
return jdbcTemplate.queryForList(sqlQuery);
}
@Transactional
public List<Map<String, Object>> getcampaignbycategory(int id) {
String sqlQuery = "SELECT cr.campaign_id, cr.campaign_name " +
"FROM gcc_1913_campaign.campaign_request cr " +
"JOIN gcc_1913_campaign.category c ON cr.category_id = c.category_id " +
"WHERE cr.category_id = ? AND campaign_status='PENDING' " +
"AND cr.isactive = '1' ";
return jdbcTemplate.queryForList(sqlQuery,id);
}
@Transactional
public List<Map<String, Object>> getcampaignbyid(int id) {
String sqlQuery = "SELECT * FROM gcc_1913_campaign.campaign_request where isactive='1' and campaign_id=?";
return jdbcTemplate.queryForList(sqlQuery,id);
}
@Transactional
public List<Map<String, Object>> getagentsfortask(int id) {
String sqlQuery = "SELECT al.agent_id,al.agent_name\r\n"
+ "FROM gcc_1913_qaqc.agents_list al\r\n"
+ "LEFT JOIN gcc_1913_campaign.agent_assign aa ON al.agent_id = aa.agent_id AND aa.isactive = '1' AND aa.campaign_id = ?\r\n"
+ "WHERE aa.agent_id IS NULL AND al.calling_type='OUTBOUND'AND al.isactive='1' AND al.isdelete='0'";
return jdbcTemplate.queryForList(sqlQuery,id);
}
@Transactional
public int addagentsfortask(int agent_id, int category_id, int campaign_id) {
String insertSql = "INSERT INTO gcc_1913_campaign.agent_assign (agent_id, category_id, campaign_id) VALUES (?, ?, ?)";
int rowsInserted = jdbcTemplate.update(insertSql, agent_id, category_id, campaign_id);
return rowsInserted;
}
@Transactional
public void addAgentsForCampaign(int selectedAgentId, int categoryId, int campaignId) {
String insertSql = "INSERT INTO gcc_1913_campaign.agent_assign (agent_id, category_id, campaign_id) VALUES (?, ?, ?)";
try {
int rowsInserted = jdbcTemplate.update(insertSql, selectedAgentId, categoryId, campaignId);
if (rowsInserted > 0) {
System.out.println("Successfully inserted agent ID in agent_assign== " + selectedAgentId + " into campaign ID " + campaignId);
} else {
System.out.println("No rows inserted for agent ID " + selectedAgentId);
}
} catch (DataAccessException | NumberFormatException ex) {
System.err.println("Error inserting data: " + ex.getMessage());
throw new RuntimeException("Failed to insert agents for campaign. Please try again.", ex);
}
}
@Transactional
public void updateAgentForCampaign(int selectedAgentId, int categoryId, int campaignId,int DataId) {
String updateSql = "UPDATE gcc_1913_campaign.upload_data SET agent_id = ? WHERE campaign_id = ? AND category_id = ? AND data_id=?";
try {
int rowsUpdated = jdbcTemplate.update(updateSql, selectedAgentId,campaignId,categoryId,DataId);
/* if (rowsUpdated > 0) {
System.out.println("Successfully updated agent ID in upload_data== " + selectedAgentId + " for campaign ID " + campaignId);
} else {
System.out.println("No rows updated for agent ID " + selectedAgentId);
}*/
} catch (DataAccessException | NumberFormatException ex) {
System.err.println("Error updating data: " + ex.getMessage());
throw new RuntimeException("Failed to update agents for campaign. Please try again.", ex);
}
}
@Transactional
public List<Integer> getDataIdForInitialAssign(int categoryId, int campaignId) {
String sql = "SELECT data_id FROM gcc_1913_campaign.upload_data "
+ "WHERE category_id = ? AND campaign_id = ? "
+ "AND agent_id IS NULL AND is_processed = 0 ORDER BY data_id";
// Correctly specify the return type for jdbcTemplate.queryForList
return jdbcTemplate.queryForList(sql, Integer.class, categoryId, campaignId);
}
@Transactional
public List<Map<String, Object>> checkcampaigninassignedtable(int id)
{
String sqlQuery = "SELECT al.agent_id,al.agent_name,aa.assigned_id\r\n"
+ "FROM gcc_1913_qaqc.agents_list al\r\n"
+ "JOIN gcc_1913_campaign.agent_assign aa ON al.agent_id = aa.agent_id\r\n"
+ "JOIN gcc_1913_campaign.campaign_request c ON aa.campaign_id=c.campaign_id\r\n"
+ "WHERE aa.campaign_id = ? AND aa.isactive = '1' AND al.calling_type='OUTBOUND'AND al.isactive='1' AND al.isdelete='0'";
return jdbcTemplate.queryForList(sqlQuery,id);
}
@Transactional
public int editagentsfortask(int assigned_id) {
String updateSql = "UPDATE gcc_1913_campaign.agent_assign SET isactive='0', isdelete='1',status='NOT_ASSIGNED' WHERE assigned_id=?";
int rowsInserted = jdbcTemplate.update(updateSql,assigned_id);
return rowsInserted;
}
@Transactional
public List<Map<String, Object>> getcampaignquestionbyid(int id) {
String sqlQuery = " SELECT " +
" cr.campaign_id, " +
" cr.campaign_name, " +
" cr.category_id, " +
" cr.start_date, " +
" cr.end_date, " +
" cr.no_of_agents, " +
" cr.calls_per_agent, " +
" cr.description, " +
" cr.created_date, " +
" cr.excel_url, " +
" cr.isactive, " +
" cr.campaign_status, " +
" cq.questions, " +
" cq.question_id, " +
" cq.answer_type_id, " +
" cat.type_name, " +
" ca.campaign_answer " + // Campaign Answer can be NULL
"FROM gcc_1913_campaign.campaign_request cr " +
"JOIN gcc_1913_campaign.campaign_questions cq " +
" ON cr.campaign_id = cq.campaign_id " +
"LEFT JOIN gcc_1913_campaign.campaign_answers ca " + // LEFT JOIN to include questions with no answers
" ON cq.question_id = ca.question_id " +
"JOIN gcc_1913_campaign.answer_type cat " +
" ON cat.answer_type_id = cq.answer_type_id " +
"WHERE cr.isactive = 1 AND cr.campaign_id = ?";
List<Map<String, Object>> queryResult = jdbcTemplate.queryForList(sqlQuery, id);
// Map to group answers by question_id
Map<Integer, Map<String, Object>> groupedData = new LinkedHashMap();
for (Map<String, Object> row : queryResult) {
Integer questionId = (Integer) row.get("question_id");
String campaignAnswer = (String) row.get("campaign_answer"); // Can be null
// Check if this question_id already exists in the map
if (!groupedData.containsKey(questionId)) {
// Copy the row data (excluding campaign_answer) and initialize answers list
Map<String, Object> newRow = new LinkedHashMap<>(row);
newRow.remove("campaign_answer"); // Remove individual answer
newRow.put("campaign_answers", new ArrayList<String>()); // Initialize answer list
groupedData.put(questionId, newRow);
}
// Only add answers if they are not null
if (campaignAnswer != null) {
((List<String>) groupedData.get(questionId).get("campaign_answers")).add(campaignAnswer);
}
}
// Convert grouped data to a list
return new ArrayList<>(groupedData.values());
}
}

656
backend/callcenter/service/AgentsService.java

@ -0,0 +1,656 @@
package in.gov.chennaicorporation.gccoffice.callcenter.service;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import javax.transaction.Transactional;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@Service
public class AgentsService {
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(@Qualifier("mysql1913CampaignDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Autowired
public void setDataSource2(@Qualifier("mysql1913QAQCDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Autowired
private JdbcTemplate jdbcTemplate2;
// Utility method to get cell value based on type
private String getCellValue(Cell cell) {
if (cell == null) {
return "";
}
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
// Check if the numeric cell contains a date
if (DateUtil.isCellDateFormatted(cell)) {
return new SimpleDateFormat("yyyy-MM-dd").format(cell.getDateCellValue());
}
return String.valueOf((long) cell.getNumericCellValue()); // Cast to long to avoid scientific notation
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
case FORMULA:
return cell.getCellFormula();
default:
return "";
}
}
// Parse integer values (for ID)
private Integer parseInteger(String value) {
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
return null; // return null if parsing fails
}
}
// Parse long values (for Mobile number)
private Long parseLong(String value) {
try {
return Long.parseLong(value);
} catch (NumberFormatException e) {
return null; // return null if parsing fails
}
}
// Example fetch method
public List<Map<String, Object>> fetchDataFromExcel(int categoryId,Long campaignId) throws IOException {
String excelUrl = getExcelUrlByCampaignId(campaignId);
List<Map<String, Object>>data=getExcelData(categoryId,campaignId, excelUrl);
return saveExcelData(data);
}
public String getExcelUrlByCampaignId(Long campaignId) {
String sql = "SELECT excel_url\r\n"
+ "FROM gcc_1913_campaign.campaign_request\r\n"
+ "WHERE campaign_id = ?";
return jdbcTemplate.queryForObject(sql, String.class, campaignId);
}
public List<Map<String, Object>> getExcelData(int categoryId,Long campaignId,String filePath) throws IOException {
List<Map<String, Object>> data = new ArrayList<>();
File file = new File(filePath);
try (FileInputStream fis = new FileInputStream(file);
Workbook workbook = new XSSFWorkbook(fis)) {
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
if (row.getRowNum() == 0) continue; // skip header row
Map<String, Object> rowData = new HashMap<>();
// Add the campaign_id and category_id to each row
rowData.put("category_id", categoryId);
rowData.put("campaign_id", campaignId);
// Convert ID to Integer
rowData.put("ID", getCellValue(row.getCell(0)));
// Name remains String
rowData.put("Name", getCellValue(row.getCell(1)));
// Address remains String
rowData.put("Address", getCellValue(row.getCell(2)));
// Dues remains String (you can convert if necessary)
rowData.put("Balance amount", parseLong(getCellValue(row.getCell(3))));
// Convert Mobile number to Long
rowData.put("Mobile number", parseLong(getCellValue(row.getCell(4))));
rowData.put("Tiny url", getCellValue(row.getCell(5)));
data.add(rowData);
}
}
return data;
}
public List<Map<String, Object>> saveExcelData(List<Map<String, Object>> data) {
// Prepare SQL query for inserting the specified columns
String sql = "INSERT INTO gcc_1913_campaign.upload_data (category_id, campaign_id, field_1, field_2, field_3, field_4, field_5,field_6) " +
"VALUES (?, ?, ?, ?, ?, ?, ?,?)";
// Loop through the data list and insert each row into the database
for (Map<String, Object> row : data) {
jdbcTemplate.update(sql,
row.get("category_id"), // Category ID
row.get("campaign_id"), // Campaign ID
row.get("ID"), // ID (String)
row.get("Name"), // Name (String)
row.get("Address"), // Address (String)
row.get("Balance amount"), // Dues if any (String)
row.get("Mobile number"), // Mobile number (Long)
row.get("Tiny url")
);
}
// Return the inserted data (if needed)
return data; // Optionally return the inserted data or change the return type as per your use case
}
//For Assigned tasks
// @Transactional
// public List<Map<String, Object>> getAgentsALLCampaigns(int agent_id) {
// String SqlQuery = "SELECT \r\n"
// + " c.category_name,\r\n"
// + " cr.campaign_name,\r\n"
// + " cr.calls_per_agent,\r\n"
// + " aa.campaign_id,\r\n"
// + " aa.agent_id,\r\n"
// + " (SELECT COUNT(data_id) \r\n"
// + " FROM gcc_1913_campaign.upload_data up \r\n"
// + " WHERE up.agent_id = aa.agent_id \r\n"
// + " AND up.campaign_id = cr.campaign_id\r\n"
// + " ) AS calls_assigned,\r\n"
// + " (SELECT COUNT(CASE WHEN up.field_14 IS NULL THEN 1 END) \r\n"
// + " FROM gcc_1913_campaign.upload_data up \r\n"
// + " WHERE up.agent_id = aa.agent_id \r\n"
// + " AND up.campaign_id = cr.campaign_id\r\n"
// + " ) AS pending_count,\r\n"
// + " (SELECT COUNT(CASE WHEN up.field_14 IS NOT NULL THEN 1 END) \r\n"
// + " FROM gcc_1913_campaign.upload_data up \r\n"
// + " WHERE up.agent_id = aa.agent_id \r\n"
// + " AND up.campaign_id = cr.campaign_id\r\n"
// + " ) AS complete_count,\r\n"
// + " (SELECT COUNT(CASE WHEN up.field_14 ='CALL_BACK_LATER' OR up.field_14 = 'UNATTENDED' THEN 1 END) \r\n"
// + " FROM gcc_1913_campaign.upload_data up \r\n"
// + " WHERE up.agent_id = aa.agent_id \r\n"
// + " AND up.campaign_id = cr.campaign_id\r\n"
// + " ) AS followup_count\r\n"
// + " \r\n"
// + "FROM \r\n"
// + " gcc_1913_campaign.agent_assign aa\r\n"
// + "JOIN \r\n"
// + " gcc_1913_qaqc.agents_list al ON aa.agent_id = al.agent_id\r\n"
// + "JOIN \r\n"
// + " gcc_1913_campaign.campaign_request cr ON cr.campaign_id = aa.campaign_id\r\n"
// + "JOIN \r\n"
// + " gcc_1913_campaign.category c ON cr.category_id = c.category_id\r\n"
// + "WHERE \r\n"
// + " aa.agent_id = ? \r\n"
// + " AND aa.isactive = '1'\r\n"
// + " AND cr.isactive = '0'";
//
// return jdbcTemplate.queryForList(SqlQuery,agent_id);
// }
@Transactional
public List<Map<String, Object>> getdataByIds(List<Integer> ids) {
// Construct the SQL query with placeholders for the number of IDs
String inSql = String.join(",", Collections.nCopies(ids.size(), "?"));
String SqlQuery = "SELECT data_id, field_1 as id, field_2 as name, field_3 as address, field_4 as dues, field_5 as cellnumber,field_6 as viewdetails,field_14 as call_status,field_15 as remarks " +
"FROM gcc_1913_campaign.upload_data " +
"WHERE data_id IN (" + inSql + ")";
// Convert the list of ids to an Object array
return jdbcTemplate.queryForList(SqlQuery, ids.toArray());
}
@Transactional
public void saveCallLogs(String call_status,String remarks ,int data_id,int agent_id)
{
String SqlQuery = "UPDATE gcc_1913_campaign.upload_data SET call_status = ?, remarks=?, updated_date = NOW() ,updated_agent_id=?, is_processed=1 WHERE (data_id = ? )";
jdbcTemplate.update(SqlQuery,call_status, remarks,agent_id,data_id);
}
@Transactional
public int saveInLogsTable(int campaignId, int agentId, int dataId, String call_status,String remarks) {
String sqlQuery = "INSERT INTO gcc_1913_campaign.call_logs (campaign_id,agent_id,data_id,call_status,remarks) VALUES (?, ?, ?,?,?)";
int rowsAffected = 0;
try {
rowsAffected = jdbcTemplate.update(sqlQuery, campaignId, agentId, dataId,call_status,remarks);
//System.out.println("Inserted into call_logs successfully. Rows affected: " + rowsAffected);
} catch (Exception e) {
System.err.println("Error inserting into call_logs: " + e.getMessage());
// Log the exception or rethrow it based on your error-handling strategy
}
return rowsAffected;
}
@Transactional
public List<Map<String, Object>> getPendingDataByIds(List<Integer> ids) {
// Construct the SQL query with placeholders for the number of IDs
String inSql = String.join(",", Collections.nCopies(ids.size(), "?"));
String SqlQuery = "SELECT data_id, field_1 as id, field_2 as name, field_3 as address, field_4 as dues, field_5 as cellnumber,field_6 as viewdetails,field_14 as call_status,field_15 as remarks " +
"FROM gcc_1913_campaign.upload_data " +
"WHERE data_id IN (" + inSql + ") " +
"AND field_14 IN ('UNATTENDED', 'CALL_BACK_LATER')";
// Convert the list of ids to an Object array
return jdbcTemplate.queryForList(SqlQuery, ids.toArray());
}
@Transactional
public List<Map<String, Object>> getAgentsNameById(List<Integer> agentIds)
{
String inSql = String.join(",", Collections.nCopies(agentIds.size(), "?"));
String SqlQuery ="select agent_name,agent_id from gcc_1913_qaqc.agents_list where agent_id IN (" + inSql + ")";
return jdbcTemplate.queryForList(SqlQuery, agentIds.toArray());
}
//agents performance
@Transactional
public List<Map<String, Object>> getDataDetailsById(List<Integer> dataIds)
{
if (dataIds.isEmpty()) {
// Handle the case where dataIds is empty to avoid SQL syntax error.
throw new IllegalArgumentException("The dataIds list is empty, cannot execute query.");
}
String inSql = String.join(",", Collections.nCopies(dataIds.size(), "?"));
String SqlQuery ="SELECT\r\n"
+ " COUNT(*) AS Assigned_count,\r\n"
+ " COUNT(CASE WHEN field_14 IS NOT NULL THEN 1 END) AS Complete_count,\r\n"
+ " COUNT(CASE WHEN field_14 IS NULL THEN 1 END) AS Pending_count ,\r\n"
+ " COUNT(CASE WHEN field_14 = 'INFORMATION_GIVEN' THEN 1 END) AS Information_Given_count,\r\n"
+ " COUNT(CASE WHEN field_14 = 'UNATTENDED' THEN 1 END) AS Unattended_count,\r\n"
+ " COUNT(CASE WHEN field_14 = 'CALL_BACK_LATER' THEN 1 END) AS Call_back_later_count,\r\n"
+ " COUNT(CASE WHEN field_14 = 'SWITCH_OFF' THEN 1 END) AS Switch_off_count,\r\n"
+ " COUNT(CASE WHEN field_14 = 'WRONG_NUMBER' THEN 1 END) AS Wrong_number_count,\r\n"
+ " CASE WHEN COUNT(*) = 0 THEN 0 ELSE ROUND((COUNT(CASE WHEN field_14 IS NOT NULL THEN 1 END) * 100.0 / COUNT(*)), 0)END AS Percentage\r\n"
+ "FROM gcc_1913_campaign.upload_data\r\n"
+ "WHERE data_id IN (" + inSql + ")";
List<Map<String, Object>> results = jdbcTemplate.queryForList(SqlQuery, dataIds.toArray());
return results;
}
@Transactional
public List<Map<String, Object>> getCompletedDataDetailsById(List<Integer> CdataIds)
{
if (CdataIds.isEmpty()) {
// Handle the case where dataIds is empty to avoid SQL syntax error.
throw new IllegalArgumentException("The CdataIds list is empty, cannot execute query.");
}
String inSql = String.join(",", Collections.nCopies(CdataIds.size(), "?"));
String SqlQuery ="SELECT\r\n"
+ " data_id,\r\n" // Add data_id to the result
+ " COUNT(*) AS Assigned_count,\r\n"
+ " COUNT(CASE WHEN field_14 IS NOT NULL THEN 1 END) AS Complete_count,\r\n"
+ " COUNT(CASE WHEN field_14 IS NULL THEN 1 END) AS Pending_count,\r\n"
+ " COUNT(CASE WHEN field_14 = 'INFORMATION_GIVEN' THEN 1 END) AS Information_Given_count,\r\n"
+ " COUNT(CASE WHEN field_14 = 'UNATTENDED' THEN 1 END) AS Unattended_count,\r\n"
+ " COUNT(CASE WHEN field_14 = 'CALL_BACK_LATER' THEN 1 END) AS Call_back_later_count,\r\n"
+ " COUNT(CASE WHEN field_14 = 'SWITCH_OFF' THEN 1 END) AS Switch_off_count,\r\n"
+ " COUNT(CASE WHEN field_14 = 'WRONG_NUMBER' THEN 1 END) AS Wrong_number_count,\r\n"
+ " CASE WHEN COUNT(*) = 0 THEN 0 ELSE ROUND((COUNT(CASE WHEN field_14 IS NOT NULL THEN 1 END) * 100.0 / COUNT(*)), 0) END AS Percentage\r\n"
+ "FROM gcc_1913_campaign.upload_data\r\n"
+ "WHERE data_id IN (" + inSql + ")\r\n"
+ "GROUP BY data_id"; // Group by data_id
return jdbcTemplate.queryForList(SqlQuery, CdataIds.toArray());
}
@Transactional
public List<Map<String,Object>> getCompletedDataById(List<Integer> completedDataIds)
{
if (completedDataIds.isEmpty()) {
// Handle the case where dataIds is empty to avoid SQL syntax error.
throw new IllegalArgumentException("The completedDataIds list is empty, cannot execute query.");
}
String inSql = String.join(",", Collections.nCopies(completedDataIds.size(), "?"));
String SqlQuery = "SELECT field_1 as id, field_2 as name, field_3 as address, " +
"field_5 as cellnumber, field_14 as call_status, updated_date as updated_date,field_15 as remarks, " +
"(SELECT COUNT(data_id) FROM call_logs WHERE data_id = upload_data.data_id) as call_count " +
"FROM gcc_1913_campaign.upload_data " +
"WHERE data_id IN (" + inSql + ")";
return jdbcTemplate.queryForList(SqlQuery, completedDataIds.toArray());
}
@Transactional
public void addAgentsForCampaign(int selectedAgentId, int categoryId, int campaignId) {
String checkSql = "SELECT COUNT(*) FROM gcc_1913_campaign.agent_assign "
+ "WHERE agent_id = ? AND category_id = ? AND campaign_id = ?";
String insertSql = "INSERT INTO gcc_1913_campaign.agent_assign (agent_id, category_id, campaign_id) VALUES (?, ?, ?)";
try {
// Check if the record already exists
int count = jdbcTemplate.queryForObject(checkSql, Integer.class, selectedAgentId, categoryId, campaignId);
if (count == 0) {
// Insert only if no existing record found
int rowsInserted = jdbcTemplate.update(insertSql, selectedAgentId, categoryId, campaignId);
if (rowsInserted > 0) {
System.out.println("Successfully inserted agent ID " + selectedAgentId + " into campaign ID " + campaignId);
} else {
System.out.println("No rows inserted for agent ID " + selectedAgentId);
}
} else {
System.out.println("Agent ID " + selectedAgentId + " is already assigned to campaign ID " + campaignId);
}
} catch (DataAccessException | NumberFormatException ex) {
System.err.println("Error inserting data: " + ex.getMessage());
throw new RuntimeException("Failed to insert agents for campaign. Please try again.", ex);
}
}
@Transactional
public void updateAgentForCampaign(int selectedAgentId, int categoryId, int campaignId,int DataId) {
String updateSql = "UPDATE gcc_1913_campaign.upload_data SET agent_id = ? WHERE campaign_id = ? AND category_id = ? AND data_id=?";
try {
int rowsUpdated = jdbcTemplate.update(updateSql, selectedAgentId,campaignId,categoryId,DataId);
/* if (rowsUpdated > 0) {
System.out.println("Successfully updated agent ID in upload_data== " + selectedAgentId + " for campaign ID " + campaignId);
} else {
System.out.println("No rows updated for agent ID " + selectedAgentId);
}*/
} catch (DataAccessException | NumberFormatException ex) {
System.err.println("Error updating data: " + ex.getMessage());
throw new RuntimeException("Failed to update agents for campaign. Please try again.", ex);
}
}
@Transactional
public List<Integer> getDataIdForFurtherAssign(int categoryId, int campaignId) {
String sql = "SELECT data_id FROM gcc_1913_campaign.upload_data "
+ "WHERE category_id = ? "
+ "AND campaign_id = ? "
+ "AND is_processed = 0 "
+ "ORDER BY data_id";
return jdbcTemplate.queryForList(sql, Integer.class, categoryId, campaignId);
}
@Transactional
public void resetAgentAssignmentForNextDay(int categoryId, int campaignId) {
String sql = "UPDATE gcc_1913_campaign.upload_data "
+ "SET agent_id = NULL, "
+ " call_status = NULL, "
+ " remarks = NULL, "
+ " updated_agent_id = NULL, "
+ " updated_date = NULL, "
+ " is_processed = 0 "
+ "WHERE category_id = ? "
+ " AND campaign_id = ? "
+ " AND call_status IN ('CALL BACK LATER', 'UNATTENDED')";
jdbcTemplate.update(sql, categoryId, campaignId);
}
//////////////////////Ajith code///////////////////
@Transactional
public List<Map<String, Object>> getFilteredFields(int categoryId, int agentId, int dataId) {
List<Map<String, Object>> resultList = new ArrayList<>();
// Fetch ordered field column names
String fetchColumnsSQL = "SELECT COLUMN_NAME " +
"FROM INFORMATION_SCHEMA.COLUMNS " +
"WHERE TABLE_SCHEMA = 'gcc_1913_campaign' " +
"AND TABLE_NAME = 'upload_data' " +
"AND COLUMN_NAME LIKE 'field_%' " +
"ORDER BY CAST(SUBSTRING(COLUMN_NAME, 7) AS UNSIGNED)";
List<String> fieldColumns = jdbcTemplate.queryForList(fetchColumnsSQL, String.class);
if (fieldColumns.isEmpty()) {
throw new RuntimeException("No matching columns found");
}
// Fetch ordered fields data
String query1 = "SELECT " + String.join(", ", fieldColumns) + " FROM gcc_1913_campaign.upload_data WHERE data_id = ?";
List<Map<String, Object>> orderedFieldsList = jdbcTemplate.queryForList(query1, dataId);
if (orderedFieldsList.isEmpty()) {
throw new RuntimeException("No data found for data_id: " + dataId);
}
Map<String, Object> orderedFields = orderedFieldsList.get(0);
// Fetch category columns
String query2 = "SELECT column_name FROM gcc_1913_campaign.category_columns WHERE category_id = ? and isactive=1 ";
List<String> categoryColumns = new ArrayList<>(jdbcTemplate.queryForList(query2, String.class, categoryId));
//System.out.println("service===="+categoryColumns);
if (categoryColumns.isEmpty()) {
throw new RuntimeException("No category columns found for category_id: " + categoryId);
}
int categoryCount = categoryColumns.size();
// Collect first 'categoryCount' non-null values from orderedFields
List<Object> nonNullValues = new ArrayList<>();
for (String field : fieldColumns) {
Object value = orderedFields.get(field);
if (value != null) {
nonNullValues.add(value);
if (nonNullValues.size() == categoryCount) {
break; // Stop after collecting required count
}
}
}
if (nonNullValues.size() < categoryCount) {
throw new RuntimeException("Not enough non-null values to match category columns");
}
// Map category columns to non-null ordered field values
Map<String, Object> finalMapping = new HashMap<>();
for (int i = 0; i < categoryCount; i++) {
finalMapping.put(categoryColumns.get(i), nonNullValues.get(i));
}
resultList.add(finalMapping);
return resultList;
}
@Transactional
public List<Map<String, Object>> getCampaignQuestions(int categoryId, int campaignId) {
// Fetch questions along with answer type
// String questionQuery = "SELECT cq.*, at.type_name " +
// "FROM gcc_1913_campaign.campaign_questions cq " +
// "JOIN gcc_1913_campaign.answer_type at " +
// "ON cq.answer_type_id = at.answer_type_id " +
//
// "WHERE cq.category_id = ? AND cq.campaign_id = ? ";
String questionQuery="SELECT cq.questions AS questions, \r\n"
+ " MIN(cq.question_id) AS question_id, \r\n"
+ " MIN(cq.category_id) AS category_id, \r\n"
+ " MIN(cq.campaign_id) AS campaign_id, \r\n"
+ " MIN(cq.answer_type_id) AS answer_type_id, \r\n"
+ " MIN(cat.type_name) AS type_name \r\n"
+ "FROM gcc_1913_campaign.campaign_questions cq \r\n"
+ "JOIN gcc_1913_campaign.answer_type cat \r\n"
+ " ON cq.answer_type_id = cat.answer_type_id \r\n"
+ "WHERE cq.category_id = ? \r\n"
+ "AND cq.campaign_id = ? \r\n"
+ "AND cq.isactive = 1\r\n"
+ "GROUP BY cq.questions\r\n"
+ "ORDER BY MIN(cq.question_id)";
List<Map<String, Object>> questions = jdbcTemplate.queryForList(questionQuery, categoryId, campaignId);
// Iterate over each question and fetch answers
for (Map<String, Object> question : questions) {
int questionId = (int) question.get("question_id");
// String answerQuery = "SELECT campaign_answer FROM gcc_1913_campaign.campaign_answers " +
// "WHERE question_id = ?";
String answerQuery="SELECT distinct(question_id) as qid, campaign_answer, created_date FROM gcc_1913_campaign.campaign_answers\r\n"
+ "WHERE question_id = ?";
List<Map<String, Object>> answers = jdbcTemplate.queryForList(answerQuery, questionId);
// Extract answer values and add to the question map
List<String> answerList = answers.stream()
.map(a -> (String) a.get("campaign_answer"))
.collect(Collectors.toList());
question.put("answers", answerList);
}
return questions;
}
@Transactional
public List<Map<String, Object>> FetchAnswer(int campaignId,int agentId,int questionId,int dataId) {
String sqlQuery = "SELECT distinct(campaign_answer) FROM gcc_1913_campaign.questions_answers where campaign_id=? and agent_id=? and question_id=? and data_id=?; ";
//System.out.println("dropdown l");
return jdbcTemplate.queryForList(sqlQuery,campaignId,agentId,questionId,dataId);
}
@Transactional
public void saveAnswers(List<Map<String, Object>> answers) {
String sql = "INSERT INTO gcc_1913_campaign.questions_answers " +
"(campaign_id, data_id, agent_id, question_id, campaign_answer, created_date) " +
"VALUES (?, ?, ?, ?, ?, NOW())";
for (Map<String, Object> answer : answers) {
jdbcTemplate.update(sql,
answer.get("campaign_id"),
answer.get("data_id"),
answer.get("agent_id"),
answer.get("question_id"),
answer.get("campaign_answer")
);
}
}
@Transactional
public List<Map<String, Object>> getCallStatus() {
String sqlQuery = "SELECT * FROM gcc_1913_campaign.calls_status ";
//System.out.println("dropdown l");
return jdbcTemplate.queryForList(sqlQuery);
}
@Transactional
public List<Map<String, Object>> checkCounts(int campaignId, int dataId) {
// Query to get the count of answered questions for a given dataId
String answersCountQuery = "SELECT COUNT(distinct(question_id)) AS answersCount FROM gcc_1913_campaign.questions_answers WHERE data_id = ?";
// Query to get the count of required questions for a given campaignId
String questionsCountQuery = "SELECT COUNT(distinct(questions)) AS questionsCount FROM gcc_1913_campaign.campaign_questions WHERE campaign_id = ?";
// Execute queries
int answersCount = jdbcTemplate.queryForObject(answersCountQuery, Integer.class, dataId);
int questionsCount = jdbcTemplate.queryForObject(questionsCountQuery, Integer.class, campaignId);
// Construct response as a list of maps
return List.of(Map.of(
"answersCount", answersCount,
"questionsCount", questionsCount
));
}
@Transactional
public List<Map<String, Object>> getAgentsALLCampaignsList(int agent_id) {
String SqlQuery = "SELECT * FROM gcc_1913_campaign.upload_data ud inner join gcc_1913_campaign.campaign_request cr on ud.campaign_id=cr.campaign_id where cr.campaign_status='ONGOING'"+
" and ud.agent_id = ? and ud.is_processed=0 ";
//System.out.println("text");
return jdbcTemplate.queryForList(SqlQuery,agent_id);
}
@Transactional
public List<Map<String, Object>> getAgentsALLCampaignsList1(int agent_id) {
String SqlQuery = "SELECT * FROM gcc_1913_campaign.upload_data ud inner join gcc_1913_campaign.campaign_request cr on ud.campaign_id=cr.campaign_id where cr.campaign_status='ONGOING'"+
" and ud.agent_id = ? and ud.is_processed=1";
// System.out.println("text");
return jdbcTemplate.queryForList(SqlQuery,agent_id);
}
@Transactional
public List<Map<String, Object>> getAgentsALLCampaigns(int agent_id) {
String SqlQuery = "SELECT c.category_name,cr.*,\r\n"
+ "(SELECT COUNT(data_id)\r\n"
+ "FROM gcc_1913_campaign.upload_data up\r\n"
+ "WHERE up.agent_id = aa.agent_id \r\n"
+ "AND up.campaign_id = cr.campaign_id\r\n"
+ ") AS calls_assigned,\r\n"
+ "(SELECT COUNT(CASE WHEN up.call_status IS NOT NULL THEN 1 END) \r\n"
+ "FROM gcc_1913_campaign.upload_data up \r\n"
+ "WHERE up.agent_id = aa.agent_id \r\n"
+ "AND up.campaign_id = cr.campaign_id\r\n"
+ ") AS complete_count,\r\n"
+ "(SELECT COUNT(CASE WHEN up.call_status IS NULL THEN 1 END) \r\n"
+ "FROM gcc_1913_campaign.upload_data up \r\n"
+ "WHERE up.agent_id = aa.agent_id \r\n"
+ "AND up.campaign_id = cr.campaign_id\r\n"
+ ") AS pending_count\r\n"
+ "FROM gcc_1913_campaign.agent_assign aa\r\n"
+ "JOIN gcc_1913_campaign.campaign_request cr ON cr.campaign_id=aa.campaign_id\r\n"
+ "JOIN gcc_1913_campaign.category c ON c.category_id=cr.category_id\r\n"
+ "WHERE cr.campaign_status='ONGOING' AND aa.isactive=1 AND cr.isactive=1 AND aa.agent_id=?";
return jdbcTemplate.queryForList(SqlQuery,agent_id);
}
// public List<Map<String, Object>> getCallCategories()
// {
// String query = "SELECT id,call_status FROM gcc_1913_campaign.calls_status WHERE isactive=1 AND isdelete=0";
// return jdbcTemplate.queryForList(query);
// }
}

116
backend/callcenter/service/AttendanceService.java

@ -0,0 +1,116 @@
package in.gov.chennaicorporation.gccoffice.callcenter.service;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@Service
public class AttendanceService {
// private JdbcTemplate jdbcTemplate;
//
//
// @Autowired
// public void setDataSource(@Qualifier("BiometricDataSource") DataSource dataSource) {
// this.jdbcTemplate = new JdbcTemplate(dataSource);
// }
//
//
// public List<Map<String, Object>> getAttendanceReport(String fromDate, String toDate) {
// String reportQuery;
//
// if (fromDate != null && toDate != null) {
// // Query with date filter if dates are provided
// reportQuery = "SELECT d.zone, d.division, b.user_id, b.user_name, f.departmentname, e.designation, " +
// "c.device_name, CAST(a.officepunch AS DATE) AS punch_date, MIN(a.OFFICEPUNCH) AS PUNCHIN, " +
// "CASE WHEN MAX(a.OFFICEPUNCH) = MIN(a.OFFICEPUNCH) THEN NULL ELSE MAX(a.OFFICEPUNCH) END AS PUNCHOUT " +
// "FROM machinerawpunch a, tbl_realtime_userinfo b, tbl_fkdevice_status c, zone_div_mast d, " +
// "tblemployee e, tbldepartment f " +
// "WHERE a.paycode = b.user_id AND a.deviceid = c.device_id AND c.device_name = d.devname " +
// "AND a.paycode = e.paycode AND e.departmentcode = f.departmentcode " +
// "AND CAST(a.officepunch AS DATE) BETWEEN ? AND ? " +
// "AND a.paycode LIKE '%19130%' " +
// "GROUP BY d.zone, d.division, b.user_id, b.user_name, f.departmentname, e.designation, " +
// "c.device_name, CAST(a.officepunch AS DATE) " +
// "ORDER BY d.zone, d.division, b.user_id, CAST(a.officepunch AS DATE)";
//
// // Execute query with date parameters
// return jdbcTemplate.queryForList(reportQuery, fromDate, toDate);
//
// } else {
// // Query without date filter
// reportQuery = "SELECT d.zone, d.division, b.user_id, b.user_name, f.departmentname, e.designation, " +
// "c.device_name, CAST(a.officepunch AS DATE) AS punch_date, MIN(a.OFFICEPUNCH) AS PUNCHIN, " +
// "CASE WHEN MAX(a.OFFICEPUNCH) = MIN(a.OFFICEPUNCH) THEN NULL ELSE MAX(a.OFFICEPUNCH) END AS PUNCHOUT " +
// "FROM machinerawpunch a, tbl_realtime_userinfo b, tbl_fkdevice_status c, zone_div_mast d, " +
// "tblemployee e, tbldepartment f " +
// "WHERE a.paycode = b.user_id AND a.deviceid = c.device_id AND c.device_name = d.devname " +
// "AND a.paycode = e.paycode AND e.departmentcode = f.departmentcode " +
// "AND a.paycode LIKE '%19130%' " +
// "GROUP BY d.zone, d.division, b.user_id, b.user_name, f.departmentname, e.designation, " +
// "c.device_name, CAST(a.officepunch AS DATE) " +
// "ORDER BY d.zone, d.division, b.user_id, CAST(a.officepunch AS DATE)";
//
// // Execute query without date parameters
// return jdbcTemplate.queryForList(reportQuery);
// }
// }
//
//
//
//// public List<Map<String, Object>> getAttendanceReport(String fromDate, String toDate) {
//// System.out.println("Service Layer: Generating attendance report");
////
//// String reportQuery = "SELECT d.zone, d.division, b.user_id, b.user_name, f.departmentname, e.designation, c.device_name, " +
//// "CAST(a.officepunch AS DATE) AS punch_date, MIN(a.OFFICEPUNCH) AS PUNCHIN, " +
//// "CASE WHEN MAX(a.OFFICEPUNCH) = MIN(a.OFFICEPUNCH) THEN NULL ELSE MAX(a.OFFICEPUNCH) END AS PUNCHOUT " +
//// "FROM machinerawpunch a, tbl_realtime_userinfo b, tbl_fkdevice_status c, zone_div_mast d, " +
//// "tblemployee e, tbldepartment f " +
//// "WHERE a.paycode = b.user_id AND a.deviceid = c.device_id AND c.device_name = d.devname " +
//// "AND a.paycode = e.paycode AND e.departmentcode = f.departmentcode ";
////
//// // Dynamic date filter
//// if (fromDate != null && toDate != null) {
//// reportQuery += "AND CAST(a.officepunch AS DATE) BETWEEN ? AND ? ";
//// } else if (fromDate != null) {
//// reportQuery += "AND CAST(a.officepunch AS DATE) = ? ";
//// } else {
//// throw new IllegalArgumentException("fromDate or toDate must be provided");
//// }
////
//// reportQuery += "AND a.paycode LIKE '%19130%' " +
//// "GROUP BY d.zone, d.division, b.user_id, b.user_name, f.departmentname, e.designation, c.device_name, " +
//// "CAST(a.officepunch AS DATE) " +
//// "ORDER BY d.zone, d.division, b.user_id, CAST(a.officepunch AS DATE)";
////
//// // Execute query based on dates
//// if (fromDate != null && toDate != null) {
//// return jdbcTemplate.queryForList(reportQuery, fromDate, toDate);
//// } else {
//// return jdbcTemplate.queryForList(reportQuery, fromDate);
//// }
//// }
//
//// public List<Map<String, Object>> getAttendanceReport() {
//// System.out.println("check 2");
//// String reportQuery ="SELECT d.zone,d.division,b.user_id,b.user_name,f.departmentname,e.designation,c.device_name,CAST(a.officepunch AS DATE) as punch_date,MIN(a.OFFICEPUNCH) AS PUNCHIN,\r\n"
//// + "CASE WHEN MAX(a.OFFICEPUNCH) = MIN(a.OFFICEPUNCH) THEN NULL ELSE MAX(a.OFFICEPUNCH) END AS PUNCHOUT FROM machinerawpunch a,tbl_realtime_userinfo b,tbl_fkdevice_status c,\r\n"
//// + "zone_div_mast d,tblemployee e,tbldepartment f WHERE a.paycode = b.user_id AND a.deviceid = c.device_id AND c.device_name = d.devname AND a.paycode = e.paycode AND \r\n"
//// + "e.departmentcode = f.departmentcode AND CAST(officepunch AS DATE) BETWEEN '2024-10-01' AND '2024-10-10'\r\n"
//// + "AND a.paycode LIKE '%19130%' \r\n"
//// + "GROUP BY d.zone,d.division,b.user_id,b.user_name,f.departmentname,e.designation,c.device_name,CAST(a.officepunch AS DATE)\r\n"
//// + "ORDER BY d.zone,d.division,b.user_id,CAST(a.officepunch AS DATE)";
//// System.out.println("check 3");
//// List<Map<String,Object>> reports = jdbcTemplate.queryForList(reportQuery);
//// System.out.println("check 4");
//// return reports;
//// }
}

29
backend/callcenter/service/CampaignDropdownApiService.java

@ -0,0 +1,29 @@
package in.gov.chennaicorporation.gccoffice.callcenter.service;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@Service
public class CampaignDropdownApiService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(@Qualifier("mysql1913CampaignDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public List<Map<String,Object>> getAnswerTypes(){
String sql = "SELECT answer_type_id,type_name FROM answer_type";
return jdbcTemplate.queryForList(sql);
}
}

334
backend/callcenter/service/CampaignReportService.java

@ -0,0 +1,334 @@
package in.gov.chennaicorporation.gccoffice.callcenter.service;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@Service
public class CampaignReportService {
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSourcemysql(@Qualifier("mysql1913CampaignDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Autowired
public void setDataSource2(@Qualifier("mysql1913QAQCDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public List<Map<String, Object>> getCampaignData(String startDate, String endDate) {
StringBuilder query = new StringBuilder(
"SELECT " +
" cr.campaign_id, " +
" cr.category_id, " +
" cr.campaign_name, " +
" cc.category_name, " +
" cr.start_date, " +
" cr.end_date, " +
" COUNT(ud.campaign_id) AS total_count, " +
" COUNT(ud.agent_id) AS assigned_count, " +
" COUNT(ud.campaign_id) - COUNT(ud.agent_id) AS not_assigned_count, " +
" COUNT(CASE WHEN ud.call_status = 'INFORMATION GIVEN' THEN 1 ELSE NULL END) AS informationgiven_count, " +
" COUNT(CASE WHEN ud.call_status = 'CALL BACK LATER' THEN 1 ELSE NULL END) AS callback_count, " +
" COUNT(CASE WHEN ud.call_status = 'UNATTENDED' THEN 1 ELSE NULL END) AS unattended_count, " +
" COUNT(CASE WHEN ud.call_status = 'SWITCH OFF' THEN 1 ELSE NULL END) AS switchoff_count, " +
" COUNT(CASE WHEN ud.call_status = 'WRONG NUMBER' THEN 1 ELSE NULL END) AS wrongnumber_count " +
"FROM gcc_1913_campaign.campaign_request cr " +
"JOIN gcc_1913_campaign.upload_data ud ON cr.campaign_id = ud.campaign_id " +
"JOIN gcc_1913_campaign.category cc ON cr.category_id = cc.category_id " +
"WHERE cr.campaign_status IN ('ONGOING', 'CLOSED') " +
"AND ud.agent_id IS NOT NULL "
);
// Apply date filter dynamically if dates are provided
if (startDate != null && endDate != null) {
query.append("AND DATE(cr.created_date) BETWEEN ? AND ? ");
}
query.append("GROUP BY cr.campaign_id ");
query.append("ORDER BY cr.campaign_id DESC");
// Execute query with or without parameters
if (startDate != null && endDate != null) {
return jdbcTemplate.queryForList(query.toString(), startDate, endDate);
} else {
return jdbcTemplate.queryForList(query.toString());
}
}
public List<Map<String, Object>> getAgentwiseData(String campaignId) {
String query = "SELECT aa.agent_id, al.agent_name, \r\n"
+ " COUNT(ud.agent_id) AS assigned_count, \r\n"
+ " COUNT(CASE WHEN ud.is_processed = 1 THEN 1 ELSE NULL END) AS completed_count, \r\n"
+ " COUNT(ud.agent_id) - COUNT(CASE WHEN ud.is_processed = 1 THEN 1 ELSE NULL END) AS pending_count, \r\n"
+ " COUNT(CASE WHEN ud.call_status = 'INFORMATION GIVEN' THEN 1 ELSE NULL END) AS informationgiven_count, \r\n"
+ " COUNT(CASE WHEN ud.call_status = 'CALL BACK LATER' THEN 1 ELSE NULL END) AS callback_count, \r\n"
+ " COUNT(CASE WHEN ud.call_status = 'UNATTENDED' THEN 1 ELSE NULL END) AS unattended_count, \r\n"
+ " COUNT(CASE WHEN ud.call_status = 'SWITCH OFF' THEN 1 ELSE NULL END) AS switchoff_count, \r\n"
+ " COUNT(CASE WHEN ud.call_status = 'WRONG NUMBER' THEN 1 ELSE NULL END) AS wrongnumber_count, \r\n"
+ " CASE \r\n"
+ " WHEN COUNT(ud.agent_id) = 0 THEN 0 \r\n"
+ " ELSE FLOOR((COUNT(CASE WHEN ud.is_processed = 1 THEN 1 ELSE NULL END) * 100) / COUNT(ud.agent_id))\r\n"
+ " END AS completed_percentage\r\n"
+ "FROM gcc_1913_campaign.agent_assign aa \r\n"
+ "JOIN gcc_1913_qaqc.agents_list al ON al.agent_id = aa.agent_id \r\n"
+ "JOIN gcc_1913_campaign.upload_data ud ON ud.agent_id = aa.agent_id AND ud.campaign_id = aa.campaign_id\r\n"
+ "WHERE aa.campaign_id = ? AND aa.isactive = 1 AND aa.isdelete = 0 AND ud.agent_id IS NOT NULL \r\n"
+ "GROUP BY aa.agent_id, al.agent_name \r\n"
+ "ORDER BY aa.agent_id";
return jdbcTemplate.queryForList(query, campaignId);
}
//report for campaign details
public List<Map<String, Object>> getAgentReportCampaignId(String campaignId) {
String query = "SELECT cr.category_id,cr.campaign_id, cc.category_name, \r\n"
+ " cr.start_date, cr.end_date, \r\n"
+ " cr.description, date (cr.created_date) as created_date \r\n"
+ " FROM gcc_1913_campaign.category cc \r\n"
+ " join gcc_1913_campaign.campaign_request cr on cr.category_id = cc.category_id \r\n"
+ " where cr.campaign_id = ?;";
return jdbcTemplate.queryForList(query, campaignId);
}
//get campaignname
public String getCampaignName(int campaignId) {
String query = "SELECT campaign_name FROM gcc_1913_campaign.campaign_request WHERE campaign_id = ?";
return jdbcTemplate.queryForObject(query, String.class, campaignId);
}
//question and answers counts with percentage in report page method
public List<Map<String, Object>> getQuestionAnswers(int campaignId) {
String sql = "SELECT cq.question_id, cq.questions, ca.campaign_answer, " +
"COUNT(qa.campaign_answer) AS answer_count, " +
"FLOOR(IFNULL((COUNT(qa.campaign_answer) / " +
"(SELECT COUNT(*) FROM gcc_1913_campaign.upload_data " +
"WHERE campaign_id = cq.campaign_id AND call_status = 'INFORMATION GIVEN') * 100), 0)) AS answer_percentage " +
"FROM gcc_1913_campaign.campaign_questions cq " +
"JOIN gcc_1913_campaign.campaign_answers ca ON cq.question_id = ca.question_id AND cq.campaign_id = ca.campaign_id " +
"LEFT JOIN gcc_1913_campaign.questions_answers qa ON cq.question_id = qa.question_id AND ca.campaign_answer = qa.campaign_answer AND cq.campaign_id = qa.campaign_id " +
"WHERE cq.campaign_id = ? AND cq.isactive = 1 AND cq.isdelete = 0 " +
"GROUP BY cq.question_id, cq.questions, ca.campaign_answer " +
"ORDER BY cq.question_id";
// String sql = "SELECT cq.question_id, cq.questions, ca.campaign_answer, " +
// "COUNT(DISTINCT qa.id) AS answer_count, " +
// "FLOOR(IFNULL( (COUNT(DISTINCT qa.id) * 100) / (SELECT COUNT(DISTINCT data_id) FROM gcc_1913_campaign.upload_data WHERE campaign_id = cq.campaign_id AND call_status = 'INFORMATION GIVEN'),0)) AS answer_percentage " +
// "FROM gcc_1913_campaign.campaign_questions cq " +
// "JOIN gcc_1913_campaign.campaign_answers ca ON cq.question_id = ca.question_id AND cq.campaign_id = ca.campaign_id " +
// "LEFT JOIN gcc_1913_campaign.questions_answers qa ON cq.question_id = qa.question_id AND ca.campaign_answer = qa.campaign_answer AND cq.campaign_id = qa.campaign_id " +
// "WHERE cq.campaign_id = ? AND cq.isactive = 1 AND cq.isdelete = 0 " +
// "GROUP BY cq.question_id, cq.questions, ca.campaign_answer " +
// "ORDER BY cq.question_id";
List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, campaignId);
Map<Integer, Map<String, Object>> responseMap = new LinkedHashMap<>();
for (Map<String, Object> row : result) {
int questionId = (int) row.get("question_id");
if (!responseMap.containsKey(questionId)) {
Map<String, Object> questionData = new HashMap<>();
questionData.put("question_id", questionId);
questionData.put("questions", row.get("questions"));
questionData.put("answers", new ArrayList<>());
responseMap.put(questionId, questionData);
}
Map<String, Object> answerData = new HashMap<>();
answerData.put("campaign_answer", row.get("campaign_answer"));
answerData.put("answer_count", row.get("answer_count"));
answerData.put("answer_percentage", row.get("answer_percentage"));
((List<Map<String, Object>>) responseMap.get(questionId).get("answers")).add(answerData);
}
return new ArrayList<>(responseMap.values());
}
// Method to escape CSV values
private String escapeCsvValue(String value) {
if (value == null) return "";
// If the value contains commas, double quotes, or newlines, wrap it in quotes and escape inner quotes
if (value.contains(",") || value.contains("\"") || value.contains("\n")) {
value = "\"" + value.replace("\"", "\"\"") + "\"";
}
return value;
}
public void generateCSV(int categoryId, int campaignId, PrintWriter writer) {
List<Map<String, Object>> resultList = new ArrayList<>();
// Fetch ordered field column names
String fetchColumnsSQL = "SELECT COLUMN_NAME " +
"FROM INFORMATION_SCHEMA.COLUMNS " +
"WHERE TABLE_SCHEMA = 'gcc_1913_campaign' " +
"AND TABLE_NAME = 'upload_data' " +
"AND COLUMN_NAME LIKE 'field_%' " +
"ORDER BY CAST(SUBSTRING(COLUMN_NAME, 7) AS UNSIGNED)";
List<String> fieldColumns = jdbcTemplate.queryForList(fetchColumnsSQL, String.class);
if (fieldColumns.isEmpty()) {
writer.println("No matching columns found");
return;
}
// Fetch ordered fields data based on campaign_id, including data_id, agent_id, and call_status
String query1 = "SELECT data_id, " + String.join(", ", fieldColumns) + ", agent_id, call_status,remarks " +
"FROM gcc_1913_campaign.upload_data WHERE campaign_id = ?";
List<Map<String, Object>> orderedFieldsList = jdbcTemplate.queryForList(query1, campaignId);
if (orderedFieldsList.isEmpty()) {
writer.println("No data found for campaign_id: " + campaignId);
return;
}
// Fetch category columns
String query2 = "SELECT column_name FROM gcc_1913_campaign.category_columns WHERE category_id = ? AND isactive=1";
List<String> categoryColumns = jdbcTemplate.queryForList(query2, String.class, categoryId);
if (categoryColumns.isEmpty()) {
writer.println("No category columns found for category_id: " + categoryId);
return;
}
int categoryCount = categoryColumns.size();
// Fetch Agent Names from agent_id
String fetchAgentSQL = "SELECT agent_id, agent_name FROM gcc_1913_qaqc.agents_list";
Map<Integer, String> agentMap = jdbcTemplate.query(fetchAgentSQL, rs -> {
Map<Integer, String> map = new HashMap<>();
while (rs.next()) {
map.put(rs.getInt("agent_id"), rs.getString("agent_name"));
}
return map;
});
// Fetch Questions for given campaign_id
String fetchQuestionsQuery = "SELECT question_id, questions FROM gcc_1913_campaign.campaign_questions WHERE campaign_id = ?";
Map<Integer, String> questionsMap = jdbcTemplate.query(fetchQuestionsQuery, rs -> {
Map<Integer, String> map = new LinkedHashMap<>();
while (rs.next()) {
map.put(rs.getInt("question_id"), rs.getString("questions"));
}
return map;
}, campaignId);
// Fetch Answers mapped to questions and grouped by data_id
String fetchAnswersQuery = "SELECT data_id, question_id, campaign_answer FROM gcc_1913_campaign.questions_answers " +
"WHERE campaign_id = ?";
Map<Integer, Map<Integer, String>> answersMap = jdbcTemplate.query(fetchAnswersQuery, rs -> {
Map<Integer, Map<Integer, String>> map = new HashMap<>();
while (rs.next()) {
int dataId = rs.getInt("data_id");
int questionId = rs.getInt("question_id");
String answer = rs.getString("campaign_answer");
map.computeIfAbsent(dataId, k -> new HashMap<>()).put(questionId, answer);
}
return map;
}, campaignId);
// Process each row and collect data
for (Map<String, Object> orderedFields : orderedFieldsList) {
List<Object> nonNullValues = new ArrayList<>();
for (String field : fieldColumns) {
Object value = orderedFields.get(field);
if (value != null) {
nonNullValues.add(value);
if (nonNullValues.size() == categoryCount) {
break; // Stop after collecting required count
}
}
}
if (nonNullValues.size() < categoryCount) {
continue; // Skip if not enough non-null values
}
Integer dataId = orderedFields.get("data_id") != null ? ((Number) orderedFields.get("data_id")).intValue() : null;
// Map category columns to non-null ordered field values
Map<String, Object> finalMapping = new LinkedHashMap<>();
// Add category columns
for (int i = 0; i < categoryCount; i++) {
finalMapping.put(categoryColumns.get(i), nonNullValues.get(i));
}
// Add Questions and Corresponding Answers for this specific data_id
Map<Integer, String> currentAnswers = answersMap.getOrDefault(dataId, new HashMap<>());
for (Map.Entry<Integer, String> entry : questionsMap.entrySet()) {
Integer questionId = entry.getKey();
String questionText = entry.getValue();
String answer = currentAnswers.getOrDefault(questionId, "-"); // Default to "-"
finalMapping.put(questionText, answer);
}
Integer agentId = orderedFields.get("agent_id") != null ? ((Number) orderedFields.get("agent_id")).intValue() : null;
String agentName = agentMap.getOrDefault(agentId, "Not Assigned");
finalMapping.put("Agent Name", agentName);
String callstatus = orderedFields.get("call_status") != null ? orderedFields.get("call_status").toString() : "-";
finalMapping.put("Call Status", callstatus);
// Add Remarks
String remarks = orderedFields.get("remarks") != null ? orderedFields.get("remarks").toString() : "-";
finalMapping.put("Remarks", remarks);
resultList.add(finalMapping);
}
// Write CSV data
if (resultList.isEmpty()) {
writer.println("No Data Available");
return;
}
// Extract headers from the first row and escape them
String headers = resultList.get(0).keySet().stream()
.map(this::escapeCsvValue) // Escape each header value
.collect(Collectors.joining(","));
writer.println(headers);
// Write data rows
for (Map<String, Object> rowData : resultList) {
List<String> values = rowData.values().stream()
.map(value -> escapeCsvValue(value != null ? value.toString() : ""))
.collect(Collectors.toList());
writer.println(String.join(",", values));
}
}
}

704
backend/callcenter/service/CampaignService.java

@ -0,0 +1,704 @@
package in.gov.chennaicorporation.gccoffice.callcenter.service;
import java.io.File;
import java.io.IOException;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Service
public class CampaignService {
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSourcemysql(@Qualifier("mysql1913CampaignDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Autowired
public void setDataSource2(@Qualifier("mysql1913QAQCDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Autowired
private JdbcTemplate jdbcTemplate2;
//Method to save file and return its URL
public String saveFile(MultipartFile file) {
String fileName = file.getOriginalFilename();
String filePath = "/uploads/" + fileName; // Path to save the file
try {
File destinationFile = new File(filePath);
file.transferTo(destinationFile); // Save the file locally
} catch (IOException e) {
throw new RuntimeException("Failed to store file " + fileName, e);
}
return filePath; // Return the file path (URL) for saving to the database
}
//Method to save campaign details into the database
public void saveCampaignDetails(Map<String, Object> campaignDetails) {
String sql = "UPDATE gcc_1913_campaign.campaign_request " +
"SET start_date = :start_date, " +
"end_date = :end_date, " +
"calls_per_agent = :calls_per_agent, " +
"description = :description " +
"WHERE campaign_id = :campaign_id";
// Using NamedParameterJdbcTemplate for mapping campaignDetails into query
NamedParameterJdbcTemplate namedJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
namedJdbcTemplate.update(sql, campaignDetails);
}
// Method to save campaign details into the database
public String saveCampaignDetailsExcel(Map<String, Object> campaignDetailsExcel) {
campaignDetailsExcel.putIfAbsent("campaign_status", "PENDING");
String sql = "INSERT INTO gcc_1913_campaign.campaign_request (campaign_name, category_id, excel_url,campaign_status) " +
"VALUES (:campaign_name, :category_id, :excel_url ,:campaign_status)";
// Using NamedParameterJdbcTemplate for mapping campaignDetails into query
NamedParameterJdbcTemplate namedJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
namedJdbcTemplate.update(sql, campaignDetailsExcel);
// Return the category to use in the next step
return campaignDetailsExcel.get("category_id").toString();
}
// campaign_status change as ongoing in campaign_request table
@Transactional
public void updateCampaignStatus(int campaignId, int categoryId) {
String checkSql = "SELECT COUNT(*) FROM gcc_1913_campaign.agent_assign "
+ "WHERE campaign_id = ? AND category_id = ? AND status = 'ASSIGNED'";
int assignedCount = jdbcTemplate.queryForObject(checkSql, Integer.class, campaignId, categoryId);
if (assignedCount > 0) {
String updateSql = "UPDATE gcc_1913_campaign.campaign_request "
+ "SET campaign_status = 'ONGOING' WHERE campaign_id = ? AND category_id = ?";
jdbcTemplate.update(updateSql, campaignId, categoryId);
System.out.println("Campaign status updated to ONGOING for campaign ID: " + campaignId);
} else {
System.out.println("No agents assigned yet. Campaign status remains PENDING.");
}
}
//Validated uploaded excel column count with field column in our DB
public List<String> getUploadDataFieldColumns() {
String query = "SELECT column_name FROM information_schema.columns "
+ "WHERE table_schema = 'gcc_1913_campaign' "
+ "AND table_name = 'upload_data' "
+ "AND column_name LIKE 'field_%'";
return jdbcTemplate.queryForList(query, String.class);
}
public String saveQuestionsAnswers(List<Map<String, Object>> questionsData) {
for (Map<String, Object> question : questionsData) {
String questionText = (String) question.get("question");
String answerType = (String) question.get("answerType");
// Validate and parse categoryId and campaignId
Integer categoryId = Integer.parseInt(question.get("categoryId").toString());
Integer campaignId = Integer.parseInt(question.get("campaignId").toString());
List<String> answers = (List<String>) question.get("answers");
// Insert question and get generated question_id
String questionInsertQuery = "INSERT INTO gcc_1913_campaign.campaign_questions (category_id, campaign_id, questions, answer_type_id) VALUES (?, ?, ?, ?)";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(questionInsertQuery, Statement.RETURN_GENERATED_KEYS);
ps.setInt(1, categoryId);
ps.setInt(2, campaignId);
ps.setString(3, questionText);
ps.setString(4, answerType);
return ps;
}, keyHolder);
Integer questionId = keyHolder.getKey().intValue();
// Insert answers if available
if (answers != null && !answers.isEmpty()) {
String answerInsertQuery = "INSERT INTO gcc_1913_campaign.campaign_answers (category_id, campaign_id, question_id, campaign_answer) VALUES (?, ?, ?, ?)";
for (String answer : answers) {
jdbcTemplate.update(answerInsertQuery, categoryId, campaignId, questionId, answer);
}
}
}
return "Questions and Answers saved successfully!";
}
public void saveQuestionsAndAnswers(String category, String campaignId, String question, String answerType, List<String> answers) {
// Convert category and answerType to integers once to avoid redundant parsing
int categoryId = Integer.parseInt(category);
int answerTypeId = Integer.parseInt(answerType);
int campaignIdd = Integer.parseInt(campaignId);
// Query to insert question into campaign_questions and retrieve generated question_id
String query1 = "INSERT INTO gcc_1913_campaign.campaign_questions (category_id, campaign_id, questions, answer_type_id) VALUES (?, ?, ?, ?)";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(query1, Statement.RETURN_GENERATED_KEYS);
ps.setInt(1, categoryId);
ps.setInt(2, campaignIdd);
ps.setString(3, question);
ps.setInt(4, answerTypeId);
return ps;
}, keyHolder);
int questionId = keyHolder.getKey().intValue();
// If answerType is NOT "Text" (ID = 1), save answers
if (answerTypeId != 1 && answers != null && !answers.isEmpty()) {
String query2 = "INSERT INTO gcc_1913_campaign.campaign_answers (category_id, campaign_id, question_id, campaign_answer) VALUES (?, ?, ?, ?)";
for (String answer : answers) {
jdbcTemplate.update(query2, categoryId, campaignId, questionId, answer);
}
}
System.out.println("Inserted Question ID: " + questionId + " with Answers: " + (answers != null ? answers : "None"));
}
//
// public Map<String, Object> getCampaignDetailsById(Long campaign_id) {
// String sql = "SELECT * FROM gcc_1913_campaign.campaign_request WHERE campaign_id = ?";
// return jdbcTemplate.queryForMap(sql, campaign_id);
// }
public void updateCampaign(Long campaign_id, String end_date) {
String sql = "UPDATE gcc_1913_campaign.campaign_request SET end_date = ? WHERE campaign_id = ?";
jdbcTemplate.update(sql, end_date,campaign_id);
}
public List<Map<String, Object>> getCampaignDetails() {
String sql = "SELECT campaign_id, " +
" campaign_name, " +
" CONCAT(" +
" DATE_FORMAT(start_date, '%d/%m/%Y'), " +
" ' to ', " +
" DATE_FORMAT(end_date, '%d/%m/%Y')" +
" ) AS event_dates, " +
" no_of_agents, " +
" calls_per_agent, " +
" (no_of_agents)*(calls_per_agent) as total_calls, " +
" description " +
"FROM gcc_1913_campaign.campaign_request;";
List<Map<String, Object>> campaigns = jdbcTemplate.queryForList(sql);
return campaigns;
}
public List<Map<String, Object>> getLastRow()
{
String sqlQuery ="SELECT campaign_id\r\n"
+ "FROM gcc_1913_campaign.campaign_request\r\n"
+ "ORDER BY campaign_id DESC\r\n"
+ "LIMIT 1";
return jdbcTemplate.queryForList(sqlQuery);
}
public String getLastInsertedCategoryId() {
String sqlQuery = "SELECT category_id " +
"FROM gcc_1913_campaign.campaign_request " +
"ORDER BY campaign_id DESC " +
"LIMIT 1";
return jdbcTemplate.queryForObject(sqlQuery, String.class);
}
public Integer getLastInsertedCampaignId()
{
String sqlQuery ="SELECT campaign_id\r\n"
+ "FROM gcc_1913_campaign.campaign_request\r\n"
+ "ORDER BY campaign_id DESC\r\n"
+ "LIMIT 1";
return jdbcTemplate.queryForObject(sqlQuery,Integer.class);
}
public List<Map<String, Object>> getDetailsForStart()
{
String sqlQuery ="SELECT cr.campaign_id,cr.category_id,ca.category_name,cr.campaign_name,start_date\r\n"
+ "FROM gcc_1913_campaign.campaign_request cr \r\n"
+ "join gcc_1913_campaign.category ca ON cr.category_id = ca.category_id \r\n"
+ "where cr.campaign_status='ONGOING' AND cr.isactive='1' and cr.isdelete='0' \r\n"
+ "order by cr.campaign_id desc";
return jdbcTemplate.queryForList(sqlQuery);
}
public List<Map<String, Object>> getDataforAgents(int campaign_id, int calls_per_agent)
{
List<Map<String, Object>> assignedAgent_list =getAssignedAgentId(campaign_id);
List<Map<String, Object>> data_list =getDataId(campaign_id);
List<Map<String, Object>> task = getTask(assignedAgent_list,data_list,calls_per_agent,campaign_id);
// Perform the update query here
if (task != null && !task.isEmpty()) {
assignAgentIds(task);
updateAgentStatus(campaign_id);
}
return task;
}
//Method to update agent_id for each data_id in upload_data table
public void assignAgentIds(List<Map<String, Object>> taskList) {
String updateQuery = "UPDATE gcc_1913_campaign.upload_data SET agent_id = ? WHERE data_id = ? AND campaign_id = ?";
// Loop through each agent's task list
for (Map<String, Object> task : taskList) {
Integer agentId = (Integer) task.get("agent_id");
Integer campaignId = (Integer) task.get("campaign_id");
List<Integer> dataIds = (List<Integer>) task.get("data_ids");
// Update each data_id with the respective agent_id
for (Integer dataId : dataIds) {
jdbcTemplate.update(updateQuery, agentId, dataId, campaignId);
}
}
}
//Example update method
private void updateAgentStatus(int campaign_id) {
String updateQuery = "UPDATE gcc_1913_campaign.campaign_request SET isactive = '0', isdelete='1' WHERE campaign_id = ?";
jdbcTemplate.update(updateQuery, campaign_id);
}
private List<Map<String, Object>> getTask(List<Map<String, Object>> assignedAgent_list, List<Map<String, Object>> data_list,
int calls_per_agent,int campaign_id) {
List<Map<String, Object>> result = new ArrayList<>();
int dataIndex = 0;
// Loop through each assigned ID
for (Map<String, Object> assigned : assignedAgent_list) {
// Create a map to store the assigned_id and corresponding data_ids
Map<String, Object> assignedTaskMap = new HashMap<>();
List<Integer> assignedDataIds = new ArrayList<>();
// Get assigned_id
Integer agent_id = (Integer) assigned.get("agent_id");
// Loop to assign the appropriate number of data IDs (calls_per_agent)
for (int i = 0; i < calls_per_agent; i++) {
if (dataIndex >= data_list.size()) {
// Exit if we run out of data IDs
break;
}
Map<String, Object> data = data_list.get(dataIndex);
Integer data_id = (Integer) data.get("data_id");
assignedDataIds.add(data_id);
dataIndex++;
}
// Put the agent_id and the corresponding data_ids in the map
assignedTaskMap.put("agent_id", agent_id);
assignedTaskMap.put("data_ids", assignedDataIds);
assignedTaskMap.put("campaign_id", campaign_id);
// Add the map to the result list
result.add(assignedTaskMap);
}
return result;
}
private List<Map<String, Object>> getDataId(int campaign_id) {
String sqlQuery ="SELECT data_id\r\n"
+ "from gcc_1913_campaign.upload_data\r\n"
+ "where campaign_id=?";
return jdbcTemplate.queryForList(sqlQuery, new Object[]{campaign_id});
}
private List<Map<String, Object>> getAssignedAgentId(int campaign_id) {
String sqlQuery ="SELECT agent_id\r\n"
+ "FROM gcc_1913_campaign.agent_assign \r\n"
+ "where campaign_id=? and isactive='1'";
return jdbcTemplate.queryForList(sqlQuery, new Object[]{campaign_id});
}
public List<Map<String, Object>> getActiveCampaigns()
{
String sqlQuery ="SELECT cr.campaign_id,cr.calls_per_agent,cr.category_id,cr.campaign_name,c.category_name,cr.start_date,cr.end_date,cr.description,cr.campaign_status\r\n"
+ "FROM gcc_1913_campaign.campaign_request cr\r\n"
+ "JOIN gcc_1913_campaign.category c ON cr.category_id=c.category_id\r\n"
+ "where cr.isactive='1' and cr.campaign_status IN ('ONGOING', 'CLOSED') Order by cr.campaign_id desc";
return jdbcTemplate.queryForList(sqlQuery);
}
public List<Map<String, Object>> viewcampaignstatus(int campaign_id) {
String sqlQuery ="SELECT \r\n"
+ "aa.campaign_id as campaign_id,\r\n"
+ " al.agent_id as agent_id,\r\n"
+ " al.agent_name as agent_name,\r\n"
+ " COUNT(up.agent_id) AS Assigned_count,\r\n"
+ " COUNT(CASE WHEN up.field_14 IS NOT NULL THEN 1 END) AS Complete_count,\r\n"
+ " COUNT(CASE WHEN up.field_14 IS NULL THEN 1 END) AS Pending_count,\r\n"
+ " ROUND(\r\n"
+ " (COUNT(CASE WHEN up.field_14 IS NOT NULL THEN 1 END) * 100) / \r\n"
+ " COUNT(up.agent_id)\r\n"
+ " ) as Percentage,\r\n"
+ " COUNT(CASE WHEN up.field_14 = 'INFORMATION_GIVEN' THEN 1 END) AS Information_Given_count,\r\n"
+ " COUNT(CASE WHEN up.field_14 = 'UNATTENDED' THEN 1 END) AS Unattended_count,\r\n"
+ " COUNT(CASE WHEN up.field_14 = 'CALL_BACK_LATER' THEN 1 END) AS Call_back_later_count,\r\n"
+ " COUNT(CASE WHEN up.field_14 = 'SWITCH_OFF' THEN 1 END) AS Switch_off_count,\r\n"
+ " COUNT(CASE WHEN up.field_14 = 'WRONG_NUMBER' THEN 1 END) AS Wrong_number_count\r\n"
+ "FROM gcc_1913_campaign.agent_assign aa\r\n"
+ "JOIN gcc_1913_qaqc.agents_list al ON al.agent_id = aa.agent_id\r\n"
+ "JOIN gcc_1913_campaign.upload_data up ON up.agent_id = al.agent_id AND up.campaign_id = ?\r\n"
+ "WHERE aa.campaign_id = ? AND aa.isactive = '1'\r\n"
+ "GROUP BY aa.campaign_id,al.agent_id, al.agent_name";
return jdbcTemplate.queryForList(sqlQuery,campaign_id,campaign_id);
}
public List<Map<String, Object>> viewcompletedby(int campaign_id, int agent_id) {
String sqlQuery ="SELECT \r\n"
+ "up.data_id as data_id,up.field_1 as id, up.field_2 as name, up.field_3 as address,field_5 as cellnumber, field_14 as call_status, \r\n"
+ "count(cl.data_id) as call_count,updated_date as updated_date,field_15 as remarks\r\n"
+ "FROM gcc_1913_campaign.agent_assign aa\r\n"
+ "JOIN gcc_1913_campaign.upload_data up ON up.agent_id = aa.agent_id AND up.campaign_id = ?\r\n"
+ "JOIN gcc_1913_campaign.call_logs cl ON cl.data_id=up.data_id\r\n"
+ "WHERE aa.campaign_id = ? AND aa.isactive = '1' AND aa.agent_id=? AND up.field_14 IS NOT NULL\r\n"
+ "group by up.data_id,up.field_1, up.field_2";
return jdbcTemplate.queryForList(sqlQuery,campaign_id,campaign_id,agent_id);
}
public String getExcelUrlByCampaignId(int lastId) {
String sqlQuery = "SELECT excel_url FROM gcc_1913_campaign.campaign_request WHERE campaign_id = ?";
return jdbcTemplate.queryForObject(sqlQuery, String.class, lastId);
}
public void saveUploadData(String category, int campaignId, Map<String, Object> rowData, List<String> expectedHeaders) {
int fieldCount = rowData.size();
List<String> columnNames = new ArrayList<>();
for (int i = 1; i <= fieldCount; i++) {
columnNames.add("field_" + i);
}
String columnNamesString = String.join(", ", columnNames);
String placeholders = columnNames.stream().map(col -> "?").collect(Collectors.joining(", "));
String sql = "INSERT INTO gcc_1913_campaign.upload_data (category_id, campaign_id, " + columnNamesString + ") VALUES (?, ?, " + placeholders + ")";
//System.out.println("SQL Query========= " + sql);
List<Object> values = new ArrayList<>();
values.add(category);
values.add(campaignId);
// Ensure rowData values are ordered based on expected headers
for (String header : expectedHeaders) {
values.add(rowData.getOrDefault(header, "")); // Ensures the correct mapping
}
final Logger logger = LoggerFactory.getLogger(CampaignService.class);
try {
jdbcTemplate.update(sql, values.toArray());
} catch (Exception e) {
logger.error("Error inserting upload data for campaign {}: {}", campaignId, e.getMessage());
}
}
// public void saveUploadData(String category, int campaignId, Map<String, Object> rowData) {
// // Get total number of fields in the row
// int fieldCount = rowData.size();
//
// // Generate dynamic column names as field_1, field_2, ..., field_N
// List<String> columnNames = new ArrayList<>();
// for (int i = 1; i <= fieldCount; i++) {
// columnNames.add("field_" + i);
// }
//
// // Build dynamic SQL query
// String columnNamesString = String.join(", ", columnNames);
// String placeholders = columnNames.stream().map(col -> "?").collect(Collectors.joining(", "));
//
// String sql = "INSERT INTO upload_data (category_id, campaign_id, " + columnNamesString + ") VALUES (?, ?, " + placeholders + ")";
//
// System.out.println("SQL Query========= " + sql);
//
// // Prepare values list
// List<Object> values = new ArrayList<>();
// values.add(category);
// values.add(campaignId);
// values.addAll(rowData.values()); // Add row data values dynamically
//
//
//
// final Logger logger = LoggerFactory.getLogger(CampaignService.class);
// try {
// jdbcTemplate.update(sql, values.toArray());
// } catch (Exception e) {
// logger.error("Error inserting upload data for campaign {}: {}", campaignId, e.getMessage());
// }
// }
//Agent List
public List<Map<String, Object>> getAllAgents() {
String sql = "SELECT agent_id, agent_name FROM gcc_1913_qaqc.agents_list WHERE calling_type = 'OUTBOUND' AND isactive = '1'";
return jdbcTemplate.queryForList(sql);
}
//count based on total, completed and pending
public Map<String, Object> getCampaignStatistics(int campaignId) {
Map<String, Object> result = new HashMap<>();
// Total Count
String totalQuery = "SELECT COUNT(*) AS total FROM gcc_1913_campaign.upload_data WHERE campaign_id = ?";
int totalCount = jdbcTemplate.queryForObject(totalQuery, Integer.class, campaignId);
result.put("totalCount", totalCount);
// Completed Count (agent_id is not null and call_status is null)
String completedQuery = "SELECT COUNT(*) AS completed FROM gcc_1913_campaign.upload_data ud\r\n"
+ "JOIN gcc_1913_campaign.campaign_request cr ON ud.campaign_id = cr.campaign_id\r\n"
+ "WHERE ud.campaign_id = ? AND cr.campaign_status = 'ONGOING' AND ud.agent_id IS NOT NULL AND\r\n"
+ "( ud.call_status NOT IN ('CALL BACK LATER','UNATTENDED'))";
int completedCount = jdbcTemplate.queryForObject(completedQuery, Integer.class, campaignId);
result.put("completedCount", completedCount);
// Pending Count (agent_id is not null and call_status is not null)
String pendingQuery = "SELECT COUNT(*) AS pending FROM gcc_1913_campaign.upload_data ud\r\n"
+ "JOIN gcc_1913_campaign.campaign_request cr ON ud.campaign_id = cr.campaign_id\r\n"
+ "WHERE ud.campaign_id = ? AND ud.agent_id IS NOT NULL \r\n"
+ "AND (ud.call_status IS NULL OR ud.call_status IN ('CALL BACK LATER','UNATTENDED'))";
int pendingCount = jdbcTemplate.queryForObject(pendingQuery, Integer.class, campaignId);
result.put("pendingCount", pendingCount);
return result;
}
public List<Map<String, Object>> getCampaignDetailsById(Long campaign_id) {
String sql = "SELECT \r\n"
+ " cr.campaign_id, \r\n"
+ " cr.campaign_name, \r\n"
+ " cr.category_id, \r\n"
+ " cr.start_date, \r\n"
+ " cr.end_date, \r\n"
+ " cr.calls_per_agent, \r\n"
+ " cr.description, \r\n"
+ " cr.created_date, \r\n"
+ " cr.excel_url, \r\n"
+ " cr.isactive, \r\n"
+ " cr.isdelete, \r\n"
+ " cr.campaign_status, \r\n"
+ " cq.question_id, \r\n"
+ " cq.questions, \r\n"
+ " cq.answer_type_id, \r\n"
+ " at.type_name, \r\n"
+ " ca.id AS answer_id, \r\n"
+ " ca.campaign_answer\r\n"
+ "FROM gcc_1913_campaign.campaign_request cr\r\n"
+ "JOIN gcc_1913_campaign.campaign_questions cq \r\n"
+ " ON cr.campaign_id = cq.campaign_id\r\n"
+ "LEFT JOIN gcc_1913_campaign.answer_type at\r\n"
+ " ON cq.answer_type_id = at.answer_type_id \r\n"
+ "LEFT JOIN gcc_1913_campaign.campaign_answers ca\r\n"
+ " ON cq.question_id = ca.question_id\r\n"
+ "WHERE cr.campaign_id = ?";
List<Map<String, Object>> results = jdbcTemplate.queryForList(sql, campaign_id);
// Group answers by question_id
Map<Long, Map<String, Object>> groupedData = new LinkedHashMap();
for (Map<String, Object> row : results) {
Object questionIdObj = row.get("question_id");
Long questionId = null;
// Convert Integer to Long if needed
if (questionIdObj instanceof Integer) {
questionId = ((Integer) questionIdObj).longValue();
} else if (questionIdObj instanceof Long) {
questionId = (Long) questionIdObj;
}
if (questionId == null) continue;
if (!groupedData.containsKey(questionId)) {
// Ensure `campaign_answer` is initialized correctly
List<String> answers = new ArrayList<>();
if (row.get("campaign_answer") != null) {
answers.add(row.get("campaign_answer").toString());
}
row.put("campaign_answer", answers);
groupedData.put(questionId, row);
} else {
// Append the answer to the existing question
List<String> answers = (List<String>) groupedData.get(questionId).get("campaign_answer");
if (row.get("campaign_answer") != null) {
answers.add(row.get("campaign_answer").toString());
}
}
}
return new ArrayList<>(groupedData.values());
}
//question and answers counts with percentage in report page method
public List<Map<String, Object>> getQuestionAnswers(int campaignId) {
String sql = "SELECT cq.question_id, cq.questions, ca.campaign_answer, " +
"COUNT(qa.campaign_answer) AS answer_count, " +
"FLOOR(IFNULL((COUNT(qa.campaign_answer) / " +
"(SELECT COUNT(*) FROM gcc_1913_campaign.upload_data " +
"WHERE campaign_id = cq.campaign_id AND call_status = 'INFORMATION GIVEN') * 100), 0)) AS answer_percentage " +
"FROM campaign_questions cq " +
"JOIN campaign_answers ca ON cq.question_id = ca.question_id AND cq.campaign_id = ca.campaign_id " +
"LEFT JOIN questions_answers qa ON cq.question_id = qa.question_id AND ca.campaign_answer = qa.campaign_answer AND cq.campaign_id = qa.campaign_id " +
"WHERE cq.campaign_id = ? AND cq.isactive = 1 AND cq.isdelete = 0 " +
"GROUP BY cq.question_id, cq.questions, ca.campaign_answer " +
"ORDER BY cq.question_id;";
List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, campaignId);
Map<Integer, Map<String, Object>> responseMap = new LinkedHashMap<>();
for (Map<String, Object> row : result) {
int questionId = (int) row.get("question_id");
if (!responseMap.containsKey(questionId)) {
Map<String, Object> questionData = new HashMap<>();
questionData.put("question_id", questionId);
questionData.put("questions", row.get("questions"));
questionData.put("answers", new ArrayList<>());
responseMap.put(questionId, questionData);
}
Map<String, Object> answerData = new HashMap<>();
answerData.put("campaign_answer", row.get("campaign_answer"));
answerData.put("answer_count", row.get("answer_count"));
answerData.put("answer_percentage", row.get("answer_percentage"));
((List<Map<String, Object>>) responseMap.get(questionId).get("answers")).add(answerData);
}
return new ArrayList<>(responseMap.values());
}
//////////////dizo//////////////
public int closeCampaign(int campaignId) {
String sql = "UPDATE gcc_1913_campaign.campaign_request SET campaign_status = 'CLOSED' WHERE campaign_id = ?";
int rowsAffected = jdbcTemplate.update(sql, campaignId);
if (rowsAffected == 0) {
System.out.println("Failed to update. Check if campaignId exists: " + campaignId);
} else {
System.out.println("Campaign ID " + campaignId + " successfully updated to CLOSED.");
}
return rowsAffected;
}
public int autoCloseExpiredCampaigns() {
String sql = "UPDATE gcc_1913_campaign.campaign_request " +
"SET campaign_status = 'CLOSED' " +
"WHERE campaign_status = 'ONGOING' AND end_date < CURRENT_DATE";
int rowsAffected = jdbcTemplate.update(sql);
if (rowsAffected == 0) {
System.out.println("No expired campaigns found to close.");
} else {
System.out.println(rowsAffected + " campaigns successfully updated to CLOSED.");
}
return rowsAffected;
}
// Scheduled job to run daily at midnight
/*
* @Scheduled(cron = "0 0 0 * * ?") public void scheduledAutoClose() {
* System.out.println("Running scheduled auto-close for expired campaigns...");
* autoCloseExpiredCampaigns(); }
*/
}

40
backend/callcenter/service/WhatsappMsgService.java

@ -0,0 +1,40 @@
package in.gov.chennaicorporation.gccoffice.callcenter.service;
import java.net.HttpURLConnection;
import java.net.URL;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class WhatsappMsgService {
public String sendMsg(String msgUrl) {
String response ="";
try{
HttpURLConnection connection =null;
URL url = new URL(msgUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
response=responseCode+"";
System.out.println("Response Code: " + responseCode);
}catch (Exception e){
e.printStackTrace();
}
return response;
}
public String sendSMS(String SMS_Url) {
RestTemplate restTemplate = new RestTemplate();
String response =restTemplate.getForObject(SMS_Url,String.class);
return response;
}
}

974
frontend/callcenter/addcategory.html

@ -0,0 +1,974 @@
<!DOCTYPE html>
<html lang="en" dir="">
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>
.required{
color: red;
}
/* Custom CSS for SweetAlert2 */
.swal-container {
display: flex;
align-items: center;
justify-content: center;
}
.swal-popup {
width: 80% !important; /* Adjust width as needed */
max-width: 600px; /* Max width for larger screens */
border-radius: 8px; /* Optional: round the corners */
padding: 2rem; /* Optional: adjust padding */
}
.swal-confirm-button {
background-color: #dc3545; /* Example: red background for delete button */
border: none;
color: #fff;
}
.swal-cancel-button {
background-color: #6c757d; /* Example: gray background for cancel button */
border: none;
color: #fff;
}
#addcategoryform .modal-body {
max-height: 500px; /* Set max height */
overflow-y: auto; /* Enable vertical scrolling when content overflows */
}
#editCategoryModal .modal-body {
max-height: 500px; /* Set max height */
overflow-y: auto; /* Enable vertical scrolling when content overflows */
}
</style>
<body>
<!--[if lt IE 8]>
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<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="fas fa-th-large bg-blue"></i>
<div class="d-inline">
<h5>Add Category</h5>
<span>1913 Add Category</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 Campaign</li>
<li class="breadcrumb-item active" aria-current="page">Add Category</li>
</ol>
</nav>
</div>
</div>
</div>
<h4 class="h4 text-right text-mute" style="font-size: 12px;">
Auot refresh in <font id="refresh-countdown">00</font> seconds
</h4>
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-block">
<div class="page-header-title" >
<h5 style="margin: 0;font-weight: bold;">Category List</h5><hr>
</div>
<div>
<table id="categoryDatatable" class="table table-striped table-bordered table-hover dataTable" role="grid" width="100%">
<thead class="thead-dark">
<tr role="row">
<th class="text-center no-sort">S.No</th>
<th class="text-center">Category</th>
<th class="text-center no-sort">Action</th>
</tr>
</thead>
<tbody>
<tr th:each="category, iterStat : ${categories}">
<td class="text-center" th:text="${iterStat.index + 1}"></td>
<td class="text-center" th:text="${category.category_name}"></td>
<td class="text-center">
<a href="#" th:onclick="return callEdit([[${category.category_id}]])" data-animation="true" data-toggle="tooltip" data-placement="top" title="Edit" data-original-title="Edit">
<i class="ik ik-edit f-16 mr-15 text-green"></i>
</a>
<!-- Delete button -->
<a href="javascript:void(0);" th:onclick="return openDeleteModal([[${category.category_id}]])" title="Delete">
<i class="ik ik-trash-2 f-16 text-red ml-4"></i>
</a>
</td>
</tr>
</tbody>
<tfoot class="thead-dark">
<tr>
<th class="text-center no-sort">S.No</th>
<th class="text-center">Category</th>
<th class="text-center no-sort">Action</th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- Category Modal Form -->
<div class="modal fade" id="addcategoryform" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Category Form</h5>
<button type="button" class="close" data-dismiss="modal">&times;</button>
</div>
<div class="modal-body">
<form id="addCategoryForm">
<div class="form-group">
<label>Category Name <span class="required">*</span></label>
<input type="text" class="form-control" id="categoryname" name="categoryname" placeholder="Enter Category Name" required>
</div>
<div id="columnInputs">
<label>Column Name <span class="required">*</span></label>
<div class="form-group row column-group">
<div class="col-sm-10">
<input type="text" class="form-control columnname" name="columns[]" placeholder="Column Name" required>
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-danger remove-column">&times;</button>
</div>
</div>
</div>
<button type="button" class="btn btn-primary" id="addMoreColumn">+ Add Column</button>
<button type="button" class="btn btn-success" id="createCategoryBtn">Save Category</button>
</form>
</div>
</div>
</div>
</div>
<!-- Edit Category Modal -->
<div class="modal fade" id="editCategoryModal" tabindex="-1" role="dialog" aria-labelledby="editCategoryModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editCategoryModalLabel">Edit Category</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form id="editCategoryForm">
<input type="hidden" id="categoryId" name="categoryId">
<div class="form-group">
<label for="showcategoryName">Category Name <span class="required">*</span></label>
<input type="text" class="form-control" id="showcategoryName" name="showcategoryName" required readonly="readonly">
</div>
<div id="editColumnInputs"></div>
<div id="editaddColumnInputs"></div>
<hr>
<button type="button" class="btn btn-success" id="addMoreEditColumn">+ Add Column</button>
<button type="button" class="btn btn-primary" id="updateCategoryButton">Save Changes</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</form>
</div>
</div>
</div>
</div>
<!-- Delete Confirmation Modal -->
<div class="modal fade" id="deleteCategoryModal" tabindex="-1" role="dialog" aria-labelledby="deleteCategoryModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document"> <!-- Add modal-lg here -->
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteCategoryModalLabel">Confirm Deletion</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p>Are you sure you want to delete this category?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger" id="confirmDeleteButton">Delete</button>
</div>
</div>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script src="node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script>
$(document).ready(function () {
// Initialize DataTables with export buttons
var buttons = [
{
extend: 'pageLength',
className: 'btn btn-warning'
},
{
title: 'Data export',
extend: 'copyHtml5',
text: 'Copy',
className: 'btn btn-secondary'
},
{
extend: 'excelHtml5',
text: 'Excel',
className: 'btn btn-secondary'
},
{
extend: 'csvHtml5',
text: 'CSV',
className: 'btn btn-secondary'
},
{
extend: 'pdfHtml5',
text: 'PDF',
className: 'btn btn-secondary'
},
{
text: '<i class="far fa-plus-square"></i> Add New Category',
className: 'btn btn-warning',
action: function () {
callAdd(); // Now it will work
}
}
];
$('#categoryDatatable').DataTable({
dom: 'Bftip',
columnDefs: [
{ targets: 'no-sort', orderable: false }
],
lengthMenu: [
[50, 100, 200, 500, -1],
['50 rows', '100 rows', '200 rows', '500 rows', 'Show all']
],
scrollY: '30vh',
fixedColumns: {
left: 1,
right: 1
},
buttons: buttons,
fixedHeader: true,
autoWidth: true,
responsive: true,
searching: false,
select: false,
processing: false,
});
// Show Modal
function callAdd() {
resetForm();
$('#addcategoryform').modal({ backdrop: 'static', keyboard: false });
$('#addcategoryform').modal('show');
}
// Reset Form
function resetForm() {
$('#addCategoryForm')[0].reset();
$("#columnInputs .column-group:not(:first)").remove();
$(".remove-column").hide();
}
//validateColumns
function validateColumns(columns) {
let columnSet = new Set();
let regex = /^[A-Za-z0-9_ ]+$/; // Allow alphabets, numbers, underscores, and spaces
let invalidRegex = /^[_ ]+$/; // Match column names with only underscores and/or spaces
for (let col of columns) {
if (!regex.test(col)) {
Swal.fire({
title: "Validation Error",
text: "Column names must contain only alphabets (A-Z, a-z), numbers (0-9), underscores (_), and spaces.",
icon: "warning",
confirmButtonText: "OK"
});
return false;
}
if (invalidRegex.test(col)) {
Swal.fire({
title: "Validation Error",
text: "Column names cannot contain only spaces and underscores (_).",
icon: "warning",
confirmButtonText: "OK"
});
return false;
}
let trimmedCol = col.trim().toLowerCase(); // Trim spaces for uniqueness check
if (columnSet.has(trimmedCol)) {
Swal.fire({
title: "Validation Error",
text: "Duplicate column names are not allowed.",
icon: "warning",
confirmButtonText: "OK"
});
return false;
}
columnSet.add(trimmedCol);
}
return true;
}
// Add default fields on page load
/* var defaultFields = `
<div class="form-group row column-group">
<div class="col-sm-10">
<input type="text" class="form-control" name="columns[]" value="name" readonly>
<input type="text" class="form-control" name="columns[]" value="mobilenumber" readonly>
<input type="text" class="form-control" name="columns[]" value="address" readonly>
</div>
</div>`;
$('#columnInputs').append(defaultFields); */
var defaultFields = `
<div class="form-group row column-group">
<div class="col-sm-10">
<input type="text" class="form-control" name="columns[]" value="Name" >
</div>
</div>
<div class="form-group row column-group">
<div class="col-sm-10">
<input type="text" class="form-control" name="columns[]" value="Mobilenumber" >
</div>
</div>
</div>`;
$('#columnInputs').append(defaultFields);
$('#addcategoryform').on('shown.bs.modal', function () {
$('#columnInputs').html(''); // Clear existing columns
$('#columnInputs').append(defaultFields); // Append default values
});
$('#addcategoryform').on('hidden.bs.modal', function () {
$('#categoryname').val(""); // Reset category name
$('#columnInputs').html(""); // Clear all columns
});
$('#editCategoryModal').on('hidden.bs.modal', function () {
$('#editColumnInputs').html(''); // Clear all columns when modal is closed
$('#editaddColumnInputs').html(''); // Clear additional columns if applicable
});
// Add More Column Fields
$('#addMoreColumn').click(function () {
var newColumnField = `
<div class="form-group row column-group">
<div class="col-sm-10">
<input type="text" class="form-control columnname" name="columns[]" placeholder="Column Name" required>
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-danger remove-column">&times;</button>
</div>
</div>`;
$('#columnInputs').append(newColumnField);
$('.remove-column').show();
});
// Remove Column Field
$(document).on('click', '.remove-column', function () {
$(this).closest('.column-group').remove();
if ($('.column-group').length === 1) {
$('.remove-column').hide();
}
});
$('#createCategoryBtn').click(function () {
var categoryName = $('#categoryname').val().trim();
//var columnNames = $('.columnname').map(function () {
var columnNames = $('input[name="columns[]"]').map(function () {
return $(this).val().trim();
}).get().filter(name => name !== "");
console.log("categoryName=", categoryName);
console.log("columnNames=", columnNames);
if (categoryName === "") {
Swal.fire({
title: "Validation Error",
text: "Please enter a category name.",
icon: "warning",
confirmButtonText: "OK"
});
return;
}
if (columnNames.length < 2) {
Swal.fire({
title: "Validation Error",
text: "Please enter at least two column names.",
icon: "warning",
confirmButtonText: "OK"
});
return;
}
if (!validateColumns(columnNames)) {
return;
}
$('#createCategoryBtn').prop('disabled', true).text('Processing...');
$.ajax({
url: '/gcc/api/category/save',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ categoryname: categoryName, columns: columnNames }),
success: function (response) {
$('#createCategoryBtn').prop('disabled', false).text('Save Category');
Swal.fire({
title: "Success",
text: "Category saved successfully!",
icon: "success",
confirmButtonText: "OK"
}).then(function () {
$('#addcategoryform').modal('hide');
$('#createCategoryBtn').prop('disabled', false).text('Save Category');
location.reload();
});
},
error: function (error) {
$('#createCategoryBtn').prop('disabled', false).text('Save Category');
Swal.fire({
title: "Error",
text: error.responseText,
icon: "error",
confirmButtonText: "OK"
});
}
});
});
/* $('#createCategoryBtn').click(function () {
var categoryName = $('#categoryname').val().trim();
var columnNames = $('.columnname').map(function () {
return $(this).val().trim();
}).get().filter(name => name !== "");
console.log("categoryName=========="+categoryName);
console.log("columnNames=========="+columnNames);
// Validation: Ensure category name is not empty and at least two columns are provided
if (categoryName === "") {
Swal.fire({
title: 'Validation Error',
text: 'Please enter a category name.',
icon: 'warning',
confirmButtonText: 'OK'
});
return;
}
if (columnNames.length < 2) {
Swal.fire({
title: 'Validation Error',
text: 'Please enter at least two column names.',
icon: 'warning',
confirmButtonText: 'OK'
});
return;
}
// Proceed with AJAX request if validation passes
$.ajax({
url: '/gcc/api/category/save',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ categoryname: categoryName, columns: columnNames }),
success: function (response) {
Swal.fire({
title: 'Success',
text: 'Category saved successfully!',
icon: 'success',
confirmButtonText: 'OK'
}).then(function () {
$('#addcategoryform').modal('hide');
location.reload();
});
},
error: function (error) {
Swal.fire({
title: 'Error',
text: error.responseText,
icon: 'error',
confirmButtonText: 'OK'
});
}
});
}); */
// Function to fetch category details and populate the edit modal
window.callEdit = function (categoryId) {
fetchCategoryDetails(categoryId);
return false;
};
function fetchCategoryDetails(categoryId) {
$.ajax({
url: '/gcc/api/category/showcategoryId',
type: 'GET',
data: { category_id: categoryId },
success: function (response) {
if (response) {
$('#categoryId').val(response.category_id);
$('#showcategoryName').val(response.category_name);
$('#editColumnInputs').empty();
$('#editaddColumnInputs').empty();
if (response.columns && response.columns.length > 0) {
response.columns.forEach(col => addEditColumnField(col.id, col.column_name));
} else {
addEditColumnField();
}
$('#editCategoryModal').modal({ backdrop: 'static', keyboard: false });
} else {
Swal.fire('Error', 'Category not found.', 'error');
}
},
error: function (xhr) {
Swal.fire('Error', 'Error fetching category details: ' + xhr.responseText, 'error');
}
});
}
function addEditColumnField(id = "", value = "", containerId = "editColumnInputs") {
let removeButton = containerId === "editColumnInputs"
? `<button type="button" class="btn btn-danger" onclick="removeColumn(this, '${id}')">&times;</button>`
: `<button type="button" class="btn btn-danger remove-column">&times;</button>`;
let columnField = `
<div class="form-group row column-group">
<input type="hidden" class="showcolumnId" value="${id}">
<div class="col-sm-10">
<input type="text" class="form-control showcolumnname" name="columns[]" placeholder="Column Name" value="${value}" required>
</div>
<div class="col-sm-2">
${removeButton}
</div>
</div>`;
$('#' + containerId).append(columnField);
}
$('#addMoreEditColumn').click(function () {
addEditColumnField("", "", "editaddColumnInputs");
});
$(document).ready(function () {
window.removeColumn = function (button, columnId) {
if (columnId) {
Swal.fire({
title: "Are you sure?",
text: "This column will be permanently deleted!",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#d33",
cancelButtonColor: "#3085d6",
confirmButtonText: "Yes, delete it!"
}).then((result) => {
if (result.isConfirmed) {
$.ajax({
url: '/gcc/api/category/deleteColumnById',
type: 'POST',
data: { columnId: columnId },
success: function (response) {
if (response.success) {
$(button).closest('.column-group').remove();
Swal.fire({
title: "Deleted!",
text: "Column has been removed.",
icon: "success",
timer: 2000, // Auto-close after 2 seconds
showConfirmButton: false
});
} else {
Swal.fire({
title: "Error",
text: "Unable to delete column. Try again.",
icon: "error",
timer: 2000, // Auto-close after 2 seconds
showConfirmButton: false
});
}
},
error: function (xhr) {
Swal.fire("Error", "Something went wrong: " + xhr.responseText, "error");
}
});
}
});
} else {
console.log("columnId=" + columnId);
Swal.fire("Error!", "Problem in columnId", "error");
}
};
});
// Event to remove column input dynamically
$(document).on('click', '.remove-column', function () {
$(this).closest('.column-group').remove();
});
$('#updateCategoryButton').click(function () {
let categoryId = parseInt($('#categoryId').val(), 10);
let existingColumns = [];
$('#editColumnInputs .column-group').each(function () {
let columnId = parseInt($(this).find('.showcolumnId').val(), 10);
let columnName = $(this).find('.showcolumnname').val();
if (columnName.trim() !== "") {
existingColumns.push({ id: columnId, name: columnName });
}
});
let newColumns = [];
$('#editaddColumnInputs .column-group').each(function () {
let columnName = $(this).find('.showcolumnname').val();
if (columnName.trim() !== "") {
newColumns.push({ name: columnName });
}
});
console.log("Category ID:", categoryId);
console.log("Existing Columns:", existingColumns);
console.log("New Columns:", newColumns);
let allColumnNames = [...existingColumns.map(col => col.name), ...newColumns.map(col => col.name)];
console.log("allColumnNames="+allColumnNames);
if ((existingColumns.length + newColumns.length) < 2) {
Swal.fire({
title: "Info",
text: "You must have at least 2 columns!",
icon: "info",
confirmButtonText: "OK"
});
return;
}
if (!validateColumns(allColumnNames)) {
return;
}
$('#updateCategoryButton').prop('disabled', true).text('Processing');
$.ajax({
url: '/gcc/api/category/updateCategoryColumns',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ categoryId: categoryId, columns: existingColumns }),
success: function (response) {
$('#updateCategoryButton').prop('disabled', false).text('Save Changes');
if (response.success) {
Swal.fire({
title: "Success!",
text: "Category updated successfully!",
icon: "success",
showConfirmButton: false,
timer: 2000
}).then(() => {
$('#updateCategoryButton').prop('disabled', false).text('Save Changes');
location.reload();
});
} else {
$('#updateCategoryButton').prop('disabled', false).text('Save Changes');
Swal.fire({
title: "Error",
text: "Unable to update column. Try again.",
icon: "error",
showConfirmButton: true
});
}
},
error: function (xhr) {
$('#updateCategoryButton').prop('disabled', false).text('Save Changes');
Swal.fire("Error", "Failed to update category: " + xhr.responseText, "error");
}
});
if (newColumns.length > 0) {
$('#updateCategoryButton').prop('disabled', true).text('Processing');
$.ajax({
url: '/gcc/api/category/addNewColumns',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ categoryId: categoryId, columns: newColumns }),
success: function (response) {
$('#updateCategoryButton').prop('disabled', false).text('Save Changes');
if (response.success) {
Swal.fire({
title: "Success!",
text: "Category updated successfully!",
icon: "success",
showConfirmButton: false,
timer: 2000
}).then(() => {
$('#updateCategoryButton').prop('disabled', false).text('Save Changes');
location.reload();
});
} else {
$('#updateCategoryButton').prop('disabled', false).text('Save Changes');
Swal.fire({
title: "Error",
text: "Unable to update column. Try again.",
icon: "error",
showConfirmButton: true
});
}
},
error: function (xhr) {
$('#updateCategoryButton').prop('disabled', false).text('Save Changes');
Swal.fire("Error", "Failed to add new columns: " + xhr.responseText, "error");
}
});
$('#updateCategoryButton').prop('disabled', false).text('Save Changes');
}
});
/* $('#updateCategoryButton').click(function () {
let categoryId = parseInt($('#categoryId').val(), 10);
// Collect existing columns
let existingColumns = [];
$('#editColumnInputs .column-group').each(function () {
let columnId = parseInt($(this).find('.showcolumnId').val(), 10);
let columnName = $(this).find('.showcolumnname').val();
if (columnName.trim() !== "") {
existingColumns.push({ id: columnId, name: columnName });
}
});
// Collect new columns
let newColumns = [];
$('#editaddColumnInputs .column-group').each(function () {
let columnName = $(this).find('.showcolumnname').val();
if (columnName.trim() !== "") {
newColumns.push({ name: columnName });
}
});
// Debugging: Log values before AJAX calls
console.log("Category ID:", categoryId);
console.log("Existing Columns:", existingColumns);
console.log("New Columns:", newColumns);
if ((existingColumns.length + newColumns.length) < 2) {
Swal.fire({
title: "Info",
text: "You must have at least 2 columns!",
icon: "info",
confirmButtonText: "OK"
});
return; // Stop execution if condition fails
}
// 1️⃣ Send existing columns update AJAX
$.ajax({
url: '/gcc/api/category/updateCategoryColumns',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ categoryId: categoryId, columns: existingColumns }),
success: function (response) {
if (response.success) {
Swal.fire({
title: "Success!",
text: "Category updated successfully!",
icon: "success",
showConfirmButton: false,
timer: 2000 // Show message for 2 seconds
}).then(() => {
location.reload(); // Reload the page after SweetAlert closes
});
} else {
Swal.fire({
title: "Error",
text: "Unable to update column. Try again.",
icon: "error",
showConfirmButton: true
});
}
},
error: function (xhr) {
Swal.fire("Error", "Failed to update category: " + xhr.responseText, "error");
}
});
// 2️⃣ Send new columns addition AJAX (only if there are new columns)
if (newColumns.length > 0) {
$.ajax({
url: '/gcc/api/category/addNewColumns',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ categoryId: categoryId, columns: newColumns }),
success: function (response) {
if (response.success) {
Swal.fire({
title: "Success!",
text: "Category updated successfully!",
icon: "success",
showConfirmButton: false,
timer: 2000 // Show message for 2 seconds
}).then(() => {
location.reload(); // Reload the page after SweetAlert closes
});
} else {
Swal.fire({
title: "Error",
text: "Unable to update column. Try again.",
icon: "error",
showConfirmButton: true
});
}
},
error: function (xhr) {
Swal.fire("Error", "Failed to add new columns: " + xhr.responseText, "error");
}
});
}
}); */
window.openDeleteModal = function (categoryId) {
$('#categoryId').val(categoryId); // Set the categoryId before showing the modal
fetchDeleteCategoryDetails();
return false; // Prevent default anchor click behavior
};
function fetchDeleteCategoryDetails() {
Swal.fire({
title: 'Confirm Deletion',
text: 'Are you sure you want to delete this category?',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Delete',
cancelButtonText: 'Cancel',
customClass: {
container: 'swal-container',
popup: 'swal-popup',
confirmButton: 'swal-confirm-button',
cancelButton: 'swal-cancel-button'
},
width: '80%',
padding: '3rem',
heightAuto: false
}).then((result) => {
if (result.isConfirmed) {
// Call the function to delete the category
deleteCategory();
}
});
}
function deleteCategory() {
var categoryId = $('#categoryId').val(); // Ensure this is correctly set
console.log("Deleting category with ID: " + categoryId); // Debugging line
$.ajax({
url: '/gcc/api/category/delete/' + categoryId,
type: 'DELETE',
success: function (response) {
Swal.fire({
title: 'Deleted!',
text: 'Category has been deleted.',
icon: 'success'
}).then(() => {
location.reload(); // Refresh the page or update the UI as needed
});
},
error: function (xhr, status, error) {
Swal.fire({
title: 'Error',
text: 'Error deleting category: ' + xhr.responseText,
icon: 'error'
});
}
});
}
});
</script>
</body>
</html>

1807
frontend/callcenter/agentscampaign.html
File diff suppressed because it is too large
View File

230
frontend/callcenter/attendancereport.html

@ -0,0 +1,230 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}">
<style>
</style>
</head>
<body>
<div class="wrapper">
<!-- Header -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<div class="page-wrap">
<!-- Left Menu -->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<div class="main-content">
<div class="container-fluid">
<div class="page-header">
<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>1913 Attendance Reports</h5>
<span>List of 1913 Agents Attendance</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="/index"><i class="ik ik-home"></i></a>
</li>
<li class="breadcrumb-item" aria-current="page">1913 Attendance</li>
<li class="breadcrumb-item active" aria-current="page">Attendance Report</li>
</ol>
</nav>
</div>
</div>
</div>
<hr>
<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>
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<div class ="card-body">
<form th:action="@{/gcc/callcenter/attendancereport}" method="get" onsubmit="showLoader()">
<div class="row">
<div class="col-sm-6 mb-3">
<label for="fromDate"
style="font-size: medium;; margin-bottom: 0px;">From
Date:</label> <input type="date" id="fromDate" name="fromDate"
th:value="${fromDate}" class="form-control" required>
</div>
<div class="col-sm-6 mb-3">
<label for="toDate"
style="font-size: medium; margin-bottom: 0px;">To
Date:</label> <input type="date" id="toDate" name="toDate"
th:value="${toDate}" class="form-control" required>
</div>
</div>
<div class="row">
<div class="col-12 d-flex justify-content-center">
<button type="submit" id="filterButton"
class="btn btn-primary mx-2">Filter</button>
<button class="btn btn-danger mx-2" onclick="resetDate()"
name="reset">Reset</button>
</div>
</div>
</form>
</div>
<!-- Agents Attendance report -->
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-block">
<div class="page-header-title" >
<h5 style="margin: 0;font-weight: bold;">Attendance Reports</h5><hr>
</div>
<div>
<table id="AttendanceDatatable" class="table table-striped table-bordered table-hover dataTable" role="grid" width="100%" height="100%">
<thead class="thead-dark">
<tr role="row">
<th class="text-center">S.No</th>
<!-- <th class="text-center">Zone</th>
<th class="text-center">Division</th> -->
<th class="text-center">Employee Id</th>
<th class="text-center">Employee Name</th>
<!-- <th class="text-center">Department Name</th> -->
<th class="text-center">Designation</th>
<th class="text-center">Device Location</th>
<th class="text-center">Punch Date</th>
<th class="text-center">Punch In</th>
<th class="text-center">Punch Out</th>
<th class="text-center">Total Working hours</th>
</tr>
</thead>
<tbody>
<tr th:each="row,sno : ${attendanceData}">
<td th:text="${sno.index + 1}" class="text-center"></td>
<!-- <td th:text="${row.zone}" class="text-center"></td>
<td th:text="${row.division}" class="text-center"></td> -->
<td th:text="${row.user_id}" class="text-center"></td>
<td th:text="${row.user_name}" class="text-center"></td>
<!-- <td th:text="${row.departmentname}" class="text-center"></td> -->
<td th:text="${row.designation}" class="text-center"></td>
<td th:text="${row.device_name}" class="text-center"></td>
<td th:text="${row.punch_date}" class="text-center"></td>
<td th:text="${row.PUNCHIN}" class="text-center"></td>
<td th:text="${row.PUNCHOUT}" class="text-center"></td>
<td th:text="${row.total_working_hours}" class="text-center"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- 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">
// Initialize DataTables with export buttons
$(document).ready(function () {
var buttons = [
{ extend: 'pageLength', className: 'btn btn-warning' },
{ title: 'Data export', extend: 'copyHtml5', text: 'Copy', className: 'btn btn-secondary' },
{ extend: 'excelHtml5', text: 'Excel', className: 'btn btn-secondary' },
{ extend: 'csvHtml5', text: 'CSV', className: 'btn btn-secondary' },
{ extend: 'pdfHtml5', text: 'PDF', className: 'btn btn-secondary' },
];
$('#AttendanceDatatable').DataTable({
dom: 'Bftip',
columnDefs: [
{ targets: 'no-sort', orderable: false }
],
lengthMenu: [
[50, 100, 200, 500, -1],
['50 rows', '100 rows', '200 rows', '500 rows', 'Show all']
],
scrollY: '50vh',
fixedColumns: { left: 1, right: 1 },
buttons: buttons,
fixedHeader: true,
autoWidth: true,
responsive: true,
searching: true,
select: false,
processing: false,
});
});
$("#fromDate").on("change", function() {
const startDate = $(this).val(); // Get the selected start date
// Set the min value for To Date to be the selected From Date
$("#toDate").attr("min", startDate);
});
// Event listener for To Date selection
$("#toDate").on("change", function() {
const endDate = $(this).val(); // Get the selected end date
// Set the max value for From Date to be the selected To Date
$("#fromDate").attr("max", endDate);
});
//Function to reset the date fields and reload the page with cleared data
function resetDate() {
// Clear the date inputs
document.getElementById("fromDate").value = "";
document.getElementById("toDate").value = "";
// Redirect to the endpoint without parameters to reset the page
window.location.href = "/gcc/callcenter/attendancereport";
}
//Function to show the loader when the form is submitted
function showLoader() {
document.getElementById('pageLoader').style.display = 'block';
}
// Function to hide the loader after the page has loaded
window.onload = function () {
document.getElementById('pageLoader').style.display = 'none';
};
</script>
</body>
</html>

1256
frontend/callcenter/campaignlist.html
File diff suppressed because it is too large
View File

954
frontend/callcenter/campaignreport.html

@ -0,0 +1,954 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}">
</head>
<style>
.required{
color: red;
}
.card-box {
box-shadow: rgba(0, 0, 0, 0.5) 0px 3px 8px;
}
@media (max-width: 768px) {
.card-box {
text-align: center;
}
}
/* #questionDatatable {
table-layout: fixed !important;
width: 100% !important;
}
#questionDatatable th,
#questionDatatable td {
white-space: nowrap !important;
text-align: center;
vertical-align: middle;
}
#questionDatatable td:nth-child(2) {
text-align: left !important;
} */
.table-responsive {
min-width: 100%;
overflow-x: auto;
}
/* Active tab color */
.nav-tabs .nav-link.active {
background-color: rgb(40, 185, 123) !important;
color: white !important;
border-color: rgb(40, 185, 123) !important;
}
/* Inactive tab color */
.nav-tabs .nav-link {
background-color: #f8f9fa;
color: black;
border-color: #ddd;
}
/* Hover effect */
.nav-tabs .nav-link:hover {
background-color: rgba(40, 185, 123, 0.8);
color: white;
}
.modal-body {
max-height: 70vh;
overflow-y: auto; /* Enables vertical scrolling */
overflow-x: hidden; /* Hides horizontal scrolling */
padding-right: 15px; /* Prevents content cutoff */
}
</style>
<body>
<div class="wrapper">
<!-- Header -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<div class="page-wrap">
<!-- Left Menu -->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<div class="main-content">
<div class="container-fluid">
<div class="page-header">
<div class="row align-items-end">
<div class="col-lg-6">
<div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline">
<h5>Campaign Report</h5>
<span>1913 Campaign Report</span>
</div>
</div>
</div>
<div class="col-lg-6">
<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 Campaign</li>
<li class="breadcrumb-item active" aria-current="page">Campaign Report</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h3>Task Details</h3>
</div>
<div class="row mt-3 ml-2">
<div class="col-md-3">
<label for="startDate" class="form-label" style="font-size: medium;">From Date:</label>
<input type="date" id="startDate" class="form-control" placeholder="Start Date" onclick="this.showPicker()">
</div>
<div class="col-md-3">
<label for="endDate" class="form-label" style="font-size: medium;">To Date:</label>
<input type="date" id="endDate" class="form-control" placeholder="End Date" onclick="this.showPicker()">
</div>
<div class="col-md-3" style="margin-top: 30px;">
<button id="searchBtn" class="btn btn-primary">Search</button>
<button id="resetBtn" class="btn btn-secondary">Reset</button>
</div>
</div>
<div class="card-body">
<table id="QaqcDatatable" class="table table-striped table-bordered table-hover dataTable" role="grid">
<thead class="thead-dark">
<tr role="row">
<th rowspan="2" class="text-center" width="1%;">S.No</th>
<th colspan="3" class="text-center">Campaign</th>
<th colspan="3" class="text-center">Performance</th>
<th colspan="5" class="text-center">Call Results</th>
<th rowspan="2" class="text-center">Action</th>
</tr>
<tr role="row">
<th class="text-center no-sort" style="text-align: center;">Campaign Name</th>
<th class="text-center no-sort" style="text-align: center;">Date</th>
<th class="text-center no-sort" style="text-align: center;">Category</th>
<th class="text-center no-sort" style="text-align: center;">Total Data</th>
<th class="text-center no-sort" style="text-align: center;">Assigned Calls</th>
<th class="text-center no-sort" style="text-align: center;">Not Assigned Calls</th>
<!-- <th class="text-center no-sort">Completion(%)</th> -->
<th class="no-sort" style="text-align: center;">Information Given</th>
<th class="no-sort" style="text-align: center;">Call Back Later</th>
<th class="no-sort" style="text-align: center;">Unattended</th>
<th class="no-sort" style="text-align: center;">Switch Off</th>
<th class="no-sort" style="text-align: center;">Wrong Number</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!--agentperformance Modal -->
<div class="modal fade" id="agentperformance" tabindex="-1"
role="dialog" aria-labelledby="exampleModalCenterLabel"
aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable"
role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalCenterLabel">Task
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">
<form id="editForm" onsubmit="submitForm(event)">
<input type="hidden" name="campaign_id" id="campaign_id" />
<div class="form-group">
<input type="hidden" name="category_id" class="form-control"
id="category_id" readonly>
</div>
<div class="mt-1" style="font-size: 14px;">
<div class="row pb-2">
<div class="col-md-6">
<strong>From Date:</strong> <span id="start_date">N/A</span>
</div>
<div class="col-md-6">
<strong>To Date:</strong> <span id="end_date">N/A</span>
</div>
</div>
<div class="row pb-2">
<div class="col-md-6">
<strong>Description:</strong> <span id="description_modal">N/A</span>
</div>
<div class="col-md-6">
<strong>Campaign Category:</strong> <span id="category">N/A</span>
</div>
</div>
</div>
</form>
<!-- Bootstrap Tabs for Switching Tables -->
<ul class="nav nav-tabs" id="tableTabs" role="tablist"
style="margin-bottom: 10px;">
<li class="nav-item"><a class="nav-link active mr-2"
id="performance-tab" data-toggle="tab" href="#performanceTable"
role="tab" aria-controls="performanceTable" aria-selected="true">Agent
With Report</a></li>
<li class="nav-item"><a class="nav-link" id="question-tab"
data-toggle="tab" href="#questionTable" role="tab"
aria-controls="questionTable" aria-selected="false">Feedback
Report</a></li>
</ul>
<!-- <div class="modal-body"> -->
<div class="tab-content">
<!-- Performance Table -->
<div class="tab-pane fade show active" id="performanceTable"
role="tabpanel" aria-labelledby="performance-tab">
<div class="table-responsive">
<table id="agentperformanceDatatable"
class="table table-striped table-bordered table-hover dataTable"
role="grid">
<thead class="thead-dark">
<tr role="row">
<th rowspan="2" class="text-center">S.No</th>
<th rowspan="2" class="text-center">Agent Name</th>
<th colspan="4" class="text-center">Performance</th>
<th colspan="5" class="text-center">Call Results</th>
</tr>
<tr role="row">
<th class="text-center">Assigned Calls</th>
<th class="text-center">Finished</th>
<th class="text-center">Pending Calls</th>
<th class="text-center">Completion (%)</th>
<th class="text-center">Information Given</th>
<th class="text-center">Call Back</th>
<th class="text-center">Unattended</th>
<th class="text-center">Switch Off</th>
<th class="text-center">Wrong Number</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<!-- Questions Table -->
<div class="tab-pane fade" id="questionTable" role="tabpanel"
aria-labelledby="question-tab">
<table id="questionDatatable"
class="table table-striped table-bordered table-hover dataTable"
role="grid">
<thead class="thead-dark">
<tr role="row">
<th class="text-center ">S.No</th>
<th class="text-center no-sort">Question</th>
<th class="text-center no-sort">Answers</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<!-- </div> -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
<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() {
$('#agentperformance').on('shown.bs.modal', function () {
let buttons = [
{
extend: 'pageLength',
className: 'btn btn-warning'
},
{
title: 'Data export',
extend: 'copyHtml5',
text: 'Copy',
className: 'btn btn-secondary'
},
{
extend: 'excelHtml5',
text: 'Excel',
className: 'btn btn-secondary'
},
{
extend: 'csvHtml5',
text: 'CSV',
className: 'btn btn-secondary'
},
{
extend: 'pdfHtml5',
text: 'PDF',
className: 'btn btn-secondary'
}
];
if (!$.fn.DataTable.isDataTable('#agentperformanceDatatable')) {
$('#agentperformanceDatatable').DataTable({
dom: 'Bftip',
columnDefs: [
{ targets: 'no-sort', orderable: false }
],
lengthMenu: [
[50, 100, 200, 500, -1],
['50 rows', '100 rows', '200 rows', '500 rows', 'Show all']
],
scrollY: '30vh',
scrollX: true, // Enable horizontal scrolling
fixedColumns: {
left: 1,
right: 1
},
buttons: buttons,
fixedHeader: false,
autoWidth: false,
responsive: true,
searching: true,
select: false,
processing: false,
});
}
});
var table = $('#QaqcDatatable').DataTable({
dom: 'Bftip',
columnDefs: [
{ targets: 'no-sort', orderable: false }
],
lengthMenu: [
[50, 100, 200, 500, -1],
['50 rows', '100 rows', '200 rows', 'Show all']
],
scrollY: '50vh',
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
});
/* var questiontable = $('#questionDatatable').DataTable({
dom: 'Bftip',
columnDefs: [
{ targets: 'no-sort', orderable: false }
],
lengthMenu: [
[50, 100, 200, 500, -1],
['50 rows', '100 rows', '200 rows', 'Show all']
],
scrollY: '50vh',
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: false,
autoWidth: true,
responsive: false,
searching:true,
select: false,
processing: false
}); */
// Ensure DataTable columns adjust when modal is shown
/* $('#agentperformance').on('shown.bs.modal', function () {
if ($.fn.DataTable.isDataTable('#questionDatatable')) {
let questionDatatable = $('#questionDatatable').DataTable();
questionDatatable.columns.adjust().draw();
}
}); */
// Initialize DataTable with export buttons
//const overallcountapiUrl = "/gcc/api/callcenterqaqc/qaqctasklist/overalltaskcount"; // Replace with your API endpoint
const tableApiUrl = "/gcc/api/campaignreport/getcampaignData";
const agentApiUrl = "/gcc/api/campaignreport/getagentdatacount";
const excelurl = "/gcc/api/campaign/getCampaignQuestionData";
//const dataTableElement = $("#QaqcDatatable").DataTable(); // Initialize DataTable
//const questionTableElement = $("#questionDatatable").DataTable(); // Initialize DataTable
// Fetch Data Function
// Fetch and Populate Table Data Function
const fetchTableData = async (startDate = "", endDate = "") => {
try {
const params = new URLSearchParams();
if (startDate) params.append("startDate", startDate);
if (endDate) params.append("endDate", endDate);
const response = await fetch(`${tableApiUrl}?${params.toString()}`);
const tableData = await response.json();
// Update DataTable with new data
table.clear(); // Clear existing data
tableData.forEach((row, index) => {
table.row.add([
`<div style="text-align: center;">${index + 1}</div>`,
`<button class="btn btn-success" data-campaign_id="${row.campaign_id}"
onclick="handleTaskButtonClick('${row.campaign_id}')">${row.campaign_name}</button>`,
`<div style="text-align: center;"> ${row.start_date} - ${row.end_date}</div>`,
`<div style="text-align: center;">${row.category_name}</div>`,
`<div style="text-align: center;">${row.assigned_count}</div>`,
`<div style="text-align: center;">${row.total_count}</div>`,
`<div style="text-align: center;">${row.not_assigned_count}</div>`,
`<div style="text-align: center;">${row.informationgiven_count}</div>`,
`<div style="text-align: center;">${row.callback_count}</div>`,
`<div style="text-align: center;">${row.unattended_count}</div>`,
`<div style="text-align: center;">${row.switchoff_count}</div>`,
`<div style="text-align: center;">${row.wrongnumber_count}</div>`,
`<button class="btn btn-primary downloadExcelBtn"
data-categoryid="${row.category_id}"
data-campaignid="${row.campaign_id}"
>
Download Excel
</button>`
]);
});
table.draw(); // Redraw the DataTable with the updated data
} catch (error) {
console.error("Error fetching table data:", error);
}
};
$(document).on("click", ".downloadExcelBtn", function () {
let categoryId = $(this).data("categoryid");
let campaignId = $(this).data("campaignid");
console.log("dfd",categoryId);
console.log("d",campaignId);
//console.log("Row Data:", row);
window.location.href = `/gcc/api/campaignreport/download-excel?categoryId=${categoryId}&campaignId=${campaignId}`;
});
// Example: Fetch Data initially without filters
fetchTableData();
// Function to Download Campaign Excel
// Event listener for From Date selection
$("#startDate").on("change", function() {
const startDate = $(this).val(); // Get the selected start date
// Set the min value for To Date to be the selected From Date
$("#endDate").attr("min", startDate);
});
// Event listener for To Date selection
$("#endDate").on("change", function() {
const endDate = $(this).val(); // Get the selected end date
// Set the max value for From Date to be the selected To Date
$("#startDate").attr("max", endDate);
});
// Search Button Click
document.getElementById("searchBtn").addEventListener("click", () => {
const startDate = document.getElementById("startDate").value;
const endDate = document.getElementById("endDate").value;
//console.log("xsnskjx");
console.log(startDate);
// Check if startDate or endDate is empty
if (!startDate || !endDate) {
Swal.fire({
icon: "warning",
title: "Incomplete Search",
text: "Please select the Date Before searching",
confirmButtonText: "OK",
});
} else {
// Call fetchTableData if dates are provided
fetchTableData(startDate, endDate);
}
});
// Reset Button Click
document.getElementById("resetBtn").addEventListener("click", () => {
/* document.getElementById("startDate").value = "";
document.getElementById("endDate").value = "";
fetchData(); // Fetch data without date filters
fetchTableData(); */
window.location.reload();
});
// Initial Load
//fetchData(); // Load overall data initially
fetchTableData();
});
/* function downloadCampaignExcel(campaignId) {
const excelurl = `/gcc/api/campaign/exportCampaignData?campaign_id=${campaignId}`;
$.ajax({
url: excelurl,
type: 'GET',
xhrFields: {
responseType: 'blob' // Ensure response is treated as a Blob (binary file)
},
success: function (data, status, xhr) {
const blob = new Blob([data], { type: xhr.getResponseHeader('Content-Type') });
// Extract filename from Content-Disposition header
let filename = "campaign_data.xlsx"; // Default filename
const disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.includes('filename=')) {
filename = disposition.split('filename=')[1].trim().replace(/['"]/g, ''); // Clean up filename
}
const downloadUrl = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = downloadUrl;
link.setAttribute("download", filename); // Set dynamic filename
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(downloadUrl); // Clean up memory
},
error: function (xhr, status, error) {
console.error("Error downloading Excel file:", error);
alert("Failed to download the file. Please try again.");
}
});
} */
function handleTaskButtonClick(CampaignId)
{
//console.log("CampaignId",CampaignId);
$('#agentperformance').modal({
backdrop: 'static',
keyboard: false
});
$('#agentperformance').modal('show');
$.ajax({
url: '/gcc/api/campaignreport/getReportCampaignid?campaign_id='+CampaignId,
type: 'GET',
contentType: 'application/json',
success: function (response) {
if (response && response.length > 0) {
const campaign = response[0];
// Populate form fields with response data
$('#campaign_id').val(campaign.campaign_id);
$('#category_id').val(campaign.category_id);
/* $('#start_date').val(campaign.start_date);
$('#end_date').val(campaign.end_date);
$('#description_modal').val(campaign.description);
$('#category').val(campaign.category_name); */
$('#start_date').text(campaign.start_date || 'N/A');
$('#end_date').text(campaign.end_date || 'N/A');
$('#description_modal').text(campaign.description || 'N/A');
$('#category').text(campaign.category_name || 'N/A');
// Update modal title dynamically
$('#exampleModalCenterLabel').html(
`<b>Campaign ID:</b> ${campaign.campaign_id} and
<b>Created Date:</b> ${campaign.created_date}`
);
/* <b>Category:</b> ${campaign.category_name} | */
// Open modal
$('#agentperformance').modal('show');
} else {
console.warn('No data found for the given campaign ID');
$('#exampleModalCenterLabel').html('<b>No data found</b>');
}
},
error: function (xhr, status, error) {
console.error('Error fetching campaign details:', error);
$('#exampleModalCenterLabel').html('<b class="text-danger">Failed to load campaign details</b>');
}
});
if ($.fn.DataTable.isDataTable('#agentperformanceDatatable')) {
$('#agentperformanceDatatable').DataTable().clear().destroy();
}
$.ajax({
url: '/gcc/api/campaignreport/getagentdatacount?campaign_id='+CampaignId,
type: 'GET',
contentType: 'application/json',
success: function (response) {
//console.log("response",response);
if (response && response.length > 0) {
let CtableBody = $('#agentperformanceDatatable tbody');
CtableBody.empty();
response.forEach((item, index) => {
let row = `
<tr>
<td class="text-center">${index + 1}</td>
<td class="text-center">${item.agent_name}</td>
<td class="text-center">${item.assigned_count || 0}</td>
<td class="text-center">${item.completed_count || 0}</td>
<td class="text-center">${item.pending_count || 0}</td>
<td class="text-center">${item.completed_percentage || 0}%</td>
<td class="text-center">${item.informationgiven_count || 0}</td>
<td class="text-center">${item.callback_count || 0}</td>
<td class="text-center">${item.unattended_count || 0}</td>
<td class="text-center">${item.switchoff_count || 0}</td>
<td class="text-center">${item.wrongnumber_count || 0}</td>
</tr>
`;
CtableBody.append(row);
});
}
else {
$('#agentperformanceDatatable tbody').html(`
<tr>
<td colspan="10" class="text-center">No data available</td>
</tr>
`);
}
},
error: function (xhr, status, error) {
console.error('Error in Fetching Task:', error);
$('#agentperformanceDatatable tbody').html(`
<tr>
<td colspan="10" class="text-center text-danger">Failed to load data</td>
</tr>
`);
}
});
if ($.fn.DataTable.isDataTable('#questionDatatable')) {
$('#questionDatatable').DataTable().clear().destroy();
}
$.ajax({
url: '/gcc/api/campaignreport/question-answers?campaign_id=' + CampaignId,
type: 'GET',
contentType: 'application/json',
success: function (response) {
if (response && response.length > 0) {
let Qtable = $('#questionDatatable tbody');
Qtable.empty(); // Clear existing data
response.forEach((item, index) => {
let answerColumn = item.answers.map(ans => `${ans.campaign_answer} - ${ans.answer_percentage}%`).join('<br>');
let row = `
<tr>
<td class="text-center">${index + 1}</td>
<td class="text-center">${item.questions}</td>
<td class="text-center">${answerColumn}</td>
</tr>
`;
Qtable.append(row);
});
} else {
$('#questionDatatable tbody').html(`
<tr>
<td colspan="1" class="text-center">No data available</td>
</tr>
`);
}
},
error: function (xhr, status, error) {
console.error('Error fetching question answers:', error);
console.error('Error in Fetching Task:', error);
$('#questionDatatable tbody').html(`
<tr>
<td colspan="1" class="text-center text-danger">Failed to load data</td>
</tr>
`);
}
});
/* $.ajax({
url: '/gcc/api/campaignreport/question-answers?campaign_id='+CampaignId,
type: 'GET',
contentType: 'application/json',
success: function (response) {
let QtableBody = $('#questionDatatable tbody');
QtableBody.empty();
if (response && response.length > 0) {
response.forEach((item, index) => {
// Extract Yes and No answers from the array
let yesAnswer = item.answers.find(ans => ans.campaign_answer.toLowerCase() === "yes") || { answer_percentage: 0 };
let noAnswer = item.answers.find(ans => ans.campaign_answer.toLowerCase() === "no") || { answer_percentage: 0 };
// Create the table row with percentage values
let row = `
<tr>
<td >${index + 1}</td>
<td >${item.questions}</td>
<td >${yesAnswer.answer_percentage}%</td>
<td >${noAnswer.answer_percentage}%</td>
</tr>
`;
QtableBody.append(row);
});
} else {
QtableBody.html(`
<tr>
<td colspan="4" class="text-center">No data available</td>
</tr>
`);
}
},
error: function (xhr, status, error) {
console.error('Error fetching question answers:', error);
$('#questionDatatable tbody').html(`
<tr>
<td colspan="4" class="text-center text-danger">Failed to load data</td>
</tr>
`);
}
}); */
}
$(document).ready(function() {
$('#agentperformance').on('shown.bs.modal', function () {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
let target = $(e.target).attr("href"); // Get the active tab
if (target === "#questionTable") {
if ($.fn.DataTable.isDataTable('#questionDatatable')) {
$('#questionDatatable').DataTable().clear().destroy();
}
}
});
let buttons = [
{
extend: 'pageLength',
className: 'btn btn-warning'
},
{
title: 'Data export',
extend: 'copyHtml5',
text: 'Copy',
className: 'btn btn-secondary'
},
{
extend: 'excelHtml5',
text: 'Excel',
className: 'btn btn-secondary'
},
{
extend: 'csvHtml5',
text: 'CSV',
className: 'btn btn-secondary'
},
{
extend: 'pdfHtml5',
text: 'PDF',
className: 'btn btn-secondary'
}
];
if (!$.fn.DataTable.isDataTable('#questionDatatable')) {
$('#questionDatatable').DataTable({
dom: 'Bftip',
columnDefs: [
{ targets: 'no-sort', orderable: false }
],
lengthMenu: [
[50, 100, 200, 500, -1],
['50 rows', '100 rows', '200 rows', '500 rows', 'Show all']
],
scrollY: '30vh',
scrollX: true, // Enable horizontal scrolling
buttons: buttons,
fixedHeader: false,
autoWidth: false,
responsive: false,
searching: true,
select: false,
processing: false,
});
}
});
});
</script>
</body>
</html>

1956
frontend/callcenter/createcampaign.html
File diff suppressed because it is too large
View File

56
gcc_campaign_empty_dump/gcc_1913_campaign_agent_assign.sql

@ -0,0 +1,56 @@
-- MySQL dump 10.13 Distrib 8.0.36, for Win64 (x86_64)
--
-- Host: localhost Database: gcc_1913_campaign
-- ------------------------------------------------------
-- Server version 8.0.36
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `agent_assign`
--
DROP TABLE IF EXISTS `agent_assign`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `agent_assign` (
`assigned_id` int NOT NULL AUTO_INCREMENT,
`agent_id` int DEFAULT NULL,
`category_id` int DEFAULT NULL,
`campaign_id` int DEFAULT NULL,
`status` varchar(255) DEFAULT 'ASSIGNED',
`isactive` tinyint(1) NOT NULL DEFAULT '1',
`isdelete` tinyint(1) NOT NULL DEFAULT '0',
`created_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`assigned_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `agent_assign`
--
LOCK TABLES `agent_assign` WRITE;
/*!40000 ALTER TABLE `agent_assign` DISABLE KEYS */;
/*!40000 ALTER TABLE `agent_assign` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-03-22 11:56:40

54
gcc_campaign_empty_dump/gcc_1913_campaign_answer_type.sql

@ -0,0 +1,54 @@
-- MySQL dump 10.13 Distrib 8.0.36, for Win64 (x86_64)
--
-- Host: localhost Database: gcc_1913_campaign
-- ------------------------------------------------------
-- Server version 8.0.36
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `answer_type`
--
DROP TABLE IF EXISTS `answer_type`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `answer_type` (
`answer_type_id` int NOT NULL AUTO_INCREMENT,
`type_name` text NOT NULL,
`isactive` tinyint(1) NOT NULL DEFAULT '1',
`isdelete` tinyint(1) NOT NULL DEFAULT '0',
`created_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`answer_type_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `answer_type`
--
LOCK TABLES `answer_type` WRITE;
/*!40000 ALTER TABLE `answer_type` DISABLE KEYS */;
INSERT INTO `answer_type` VALUES (1,'Text',1,0,'2025-03-03 07:55:57'),(2,'Radio',1,0,'2025-03-03 07:55:57'),(3,'Dropdown',1,0,'2025-03-03 07:55:57'),(4,'Checkbox',1,0,'2025-03-03 09:16:39');
/*!40000 ALTER TABLE `answer_type` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-03-22 11:56:38

55
gcc_campaign_empty_dump/gcc_1913_campaign_call_logs.sql

@ -0,0 +1,55 @@
-- MySQL dump 10.13 Distrib 8.0.36, for Win64 (x86_64)
--
-- Host: localhost Database: gcc_1913_campaign
-- ------------------------------------------------------
-- Server version 8.0.36
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `call_logs`
--
DROP TABLE IF EXISTS `call_logs`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `call_logs` (
`id` int NOT NULL AUTO_INCREMENT,
`data_id` int DEFAULT NULL,
`call_status` varchar(255) DEFAULT NULL,
`remarks` varchar(255) DEFAULT NULL,
`created_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`agent_id` int DEFAULT NULL,
`campaign_id` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `call_logs`
--
LOCK TABLES `call_logs` WRITE;
/*!40000 ALTER TABLE `call_logs` DISABLE KEYS */;
/*!40000 ALTER TABLE `call_logs` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-03-22 11:56:38

54
gcc_campaign_empty_dump/gcc_1913_campaign_calls_status.sql

@ -0,0 +1,54 @@
-- MySQL dump 10.13 Distrib 8.0.36, for Win64 (x86_64)
--
-- Host: localhost Database: gcc_1913_campaign
-- ------------------------------------------------------
-- Server version 8.0.36
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `calls_status`
--
DROP TABLE IF EXISTS `calls_status`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `calls_status` (
`id` int NOT NULL AUTO_INCREMENT,
`call_status` text NOT NULL,
`isactive` tinyint(1) NOT NULL DEFAULT '1',
`isdelete` tinyint(1) NOT NULL DEFAULT '0',
`created_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `calls_status`
--
LOCK TABLES `calls_status` WRITE;
/*!40000 ALTER TABLE `calls_status` DISABLE KEYS */;
INSERT INTO `calls_status` VALUES (1,'INFORMATION GIVEN',1,0,'2025-03-20 07:49:35'),(2,'UNATTENDED',1,0,'2025-03-20 07:49:35'),(3,'CALL BACK LATER',1,0,'2025-03-20 07:49:35'),(4,'SWITCH OFF',1,0,'2025-03-20 07:49:35'),(5,'WRONG NUMBER',1,0,'2025-03-20 07:49:35');
/*!40000 ALTER TABLE `calls_status` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-03-22 11:56:39

56
gcc_campaign_empty_dump/gcc_1913_campaign_campaign_answers.sql

@ -0,0 +1,56 @@
-- MySQL dump 10.13 Distrib 8.0.36, for Win64 (x86_64)
--
-- Host: localhost Database: gcc_1913_campaign
-- ------------------------------------------------------
-- Server version 8.0.36
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `campaign_answers`
--
DROP TABLE IF EXISTS `campaign_answers`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `campaign_answers` (
`id` int NOT NULL AUTO_INCREMENT,
`category_id` int NOT NULL,
`campaign_id` int NOT NULL,
`question_id` int NOT NULL,
`campaign_answer` text NOT NULL,
`isactive` tinyint(1) NOT NULL DEFAULT '1',
`isdelete` tinyint(1) NOT NULL DEFAULT '0',
`created_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `campaign_answers`
--
LOCK TABLES `campaign_answers` WRITE;
/*!40000 ALTER TABLE `campaign_answers` DISABLE KEYS */;
/*!40000 ALTER TABLE `campaign_answers` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-03-22 11:56:38

56
gcc_campaign_empty_dump/gcc_1913_campaign_campaign_questions.sql

@ -0,0 +1,56 @@
-- MySQL dump 10.13 Distrib 8.0.36, for Win64 (x86_64)
--
-- Host: localhost Database: gcc_1913_campaign
-- ------------------------------------------------------
-- Server version 8.0.36
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `campaign_questions`
--
DROP TABLE IF EXISTS `campaign_questions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `campaign_questions` (
`question_id` int NOT NULL AUTO_INCREMENT,
`category_id` int NOT NULL,
`campaign_id` int NOT NULL,
`questions` text NOT NULL,
`answer_type_id` int NOT NULL,
`isactive` tinyint(1) NOT NULL DEFAULT '1',
`isdelete` tinyint(1) NOT NULL DEFAULT '0',
`created_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`question_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `campaign_questions`
--
LOCK TABLES `campaign_questions` WRITE;
/*!40000 ALTER TABLE `campaign_questions` DISABLE KEYS */;
/*!40000 ALTER TABLE `campaign_questions` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-03-22 11:56:39

61
gcc_campaign_empty_dump/gcc_1913_campaign_campaign_request.sql

@ -0,0 +1,61 @@
-- MySQL dump 10.13 Distrib 8.0.36, for Win64 (x86_64)
--
-- Host: localhost Database: gcc_1913_campaign
-- ------------------------------------------------------
-- Server version 8.0.36
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `campaign_request`
--
DROP TABLE IF EXISTS `campaign_request`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `campaign_request` (
`campaign_id` int NOT NULL AUTO_INCREMENT,
`campaign_name` varchar(255) DEFAULT NULL,
`category_id` int DEFAULT NULL,
`start_date` date DEFAULT NULL,
`end_date` date DEFAULT NULL,
`no_of_agents` int DEFAULT NULL,
`calls_per_agent` int DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
`created_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`excel_url` varchar(255) DEFAULT NULL,
`isactive` tinyint(1) NOT NULL DEFAULT '1',
`isdelete` tinyint(1) NOT NULL DEFAULT '0',
`campaign_status` varchar(45) DEFAULT NULL,
PRIMARY KEY (`campaign_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `campaign_request`
--
LOCK TABLES `campaign_request` WRITE;
/*!40000 ALTER TABLE `campaign_request` DISABLE KEYS */;
/*!40000 ALTER TABLE `campaign_request` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-03-22 11:56:39

53
gcc_campaign_empty_dump/gcc_1913_campaign_category.sql

@ -0,0 +1,53 @@
-- MySQL dump 10.13 Distrib 8.0.36, for Win64 (x86_64)
--
-- Host: localhost Database: gcc_1913_campaign
-- ------------------------------------------------------
-- Server version 8.0.36
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `category`
--
DROP TABLE IF EXISTS `category`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `category` (
`category_id` int NOT NULL AUTO_INCREMENT,
`category_name` varchar(255) NOT NULL,
`isactive` tinyint(1) NOT NULL DEFAULT '1',
`isdelete` tinyint(1) NOT NULL DEFAULT '0',
`created_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `category`
--
LOCK TABLES `category` WRITE;
/*!40000 ALTER TABLE `category` DISABLE KEYS */;
/*!40000 ALTER TABLE `category` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-03-22 11:56:38

54
gcc_campaign_empty_dump/gcc_1913_campaign_category_columns.sql

@ -0,0 +1,54 @@
-- MySQL dump 10.13 Distrib 8.0.36, for Win64 (x86_64)
--
-- Host: localhost Database: gcc_1913_campaign
-- ------------------------------------------------------
-- Server version 8.0.36
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `category_columns`
--
DROP TABLE IF EXISTS `category_columns`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `category_columns` (
`id` int NOT NULL AUTO_INCREMENT,
`category_id` int NOT NULL,
`column_name` text NOT NULL,
`isactive` tinyint(1) NOT NULL DEFAULT '1',
`isdelete` tinyint(1) NOT NULL DEFAULT '0',
`created_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `category_columns`
--
LOCK TABLES `category_columns` WRITE;
/*!40000 ALTER TABLE `category_columns` DISABLE KEYS */;
/*!40000 ALTER TABLE `category_columns` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-03-22 11:56:39

55
gcc_campaign_empty_dump/gcc_1913_campaign_questions_answers.sql

@ -0,0 +1,55 @@
-- MySQL dump 10.13 Distrib 8.0.36, for Win64 (x86_64)
--
-- Host: localhost Database: gcc_1913_campaign
-- ------------------------------------------------------
-- Server version 8.0.36
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `questions_answers`
--
DROP TABLE IF EXISTS `questions_answers`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `questions_answers` (
`id` int NOT NULL AUTO_INCREMENT,
`campaign_id` int DEFAULT NULL,
`data_id` int DEFAULT NULL,
`agent_id` int DEFAULT NULL,
`question_id` int NOT NULL,
`campaign_answer` text NOT NULL,
`created_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `questions_answers`
--
LOCK TABLES `questions_answers` WRITE;
/*!40000 ALTER TABLE `questions_answers` DISABLE KEYS */;
/*!40000 ALTER TABLE `questions_answers` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-03-22 11:56:39

73
gcc_campaign_empty_dump/gcc_1913_campaign_upload_data.sql

@ -0,0 +1,73 @@
-- MySQL dump 10.13 Distrib 8.0.36, for Win64 (x86_64)
--
-- Host: localhost Database: gcc_1913_campaign
-- ------------------------------------------------------
-- Server version 8.0.36
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `upload_data`
--
DROP TABLE IF EXISTS `upload_data`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `upload_data` (
`data_id` bigint NOT NULL AUTO_INCREMENT,
`category_id` int NOT NULL,
`campaign_id` int NOT NULL,
`field_1` varchar(255) DEFAULT NULL,
`field_2` varchar(255) DEFAULT NULL,
`field_3` varchar(255) DEFAULT NULL,
`field_4` varchar(255) DEFAULT NULL,
`field_5` varchar(255) DEFAULT NULL,
`field_6` varchar(255) DEFAULT NULL,
`field_7` varchar(255) DEFAULT NULL,
`field_8` varchar(255) DEFAULT NULL,
`field_9` varchar(255) DEFAULT NULL,
`field_10` varchar(255) DEFAULT NULL,
`field_11` varchar(255) DEFAULT NULL,
`field_12` varchar(255) DEFAULT NULL,
`field_13` varchar(255) DEFAULT NULL,
`field_14` varchar(255) DEFAULT NULL,
`field_15` varchar(255) DEFAULT NULL,
`agent_id` int DEFAULT NULL,
`call_status` varchar(255) DEFAULT NULL,
`remarks` text,
`updated_agent_id` int DEFAULT NULL,
`updated_date` varchar(255) DEFAULT NULL,
`is_processed` tinyint(1) NOT NULL DEFAULT '0',
`created_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`data_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `upload_data`
--
LOCK TABLES `upload_data` WRITE;
/*!40000 ALTER TABLE `upload_data` DISABLE KEYS */;
/*!40000 ALTER TABLE `upload_data` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-03-22 11:56:40
Loading…
Cancel
Save