12 changed files with 2883 additions and 43 deletions
-
19src/main/java/com/gcc_manpower/config/DataSourceConfig.java
-
13src/main/java/com/gcc_manpower/config/WebConfig.java
-
11src/main/java/com/gcc_manpower/gccservicedocuments/controller/GccServiceDocumentsController.java
-
4src/main/java/com/gcc_manpower/gccservicedocuments/service/GccServiceDocumentsService.java
-
8src/main/java/com/gcc_manpower/gccservicedocuments/service/VideoCompressionService.java
-
260src/main/java/com/gcc_manpower/gccservicepaymenttracker/controller/GccServicePaymentTrackerController.java
-
285src/main/java/com/gcc_manpower/gccservicepaymenttracker/service/GccServicePaymentTrackerService.java
-
2src/main/resources/application-local.properties
-
4src/main/resources/application.properties
-
4src/main/resources/templates/fragments/navbar.html
-
2151src/main/resources/templates/gccservicepaymenttracker/dashboard.html
-
115src/main/resources/templates/gccservicepaymenttracker/login.html
@ -0,0 +1,260 @@ |
|||
package com.gcc_manpower.gccservicepaymenttracker.controller; |
|||
|
|||
import com.gcc_manpower.gccservicepaymenttracker.service.GccServicePaymentTrackerService; |
|||
import com.gcc_manpower.service.AppUserService; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.stereotype.Controller; |
|||
import org.springframework.ui.Model; |
|||
import org.springframework.web.bind.annotation.*; |
|||
import org.springframework.web.multipart.MultipartFile; |
|||
import jakarta.servlet.http.HttpSession; |
|||
import org.springframework.http.CacheControl; |
|||
import org.springframework.http.ResponseEntity; |
|||
import java.io.File; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
@Controller |
|||
@RequestMapping("/gccservicepaymenttracker") |
|||
public class GccServicePaymentTrackerController { |
|||
|
|||
@Autowired |
|||
private GccServicePaymentTrackerService paymentTrackerService; |
|||
|
|||
@Autowired |
|||
private AppUserService appUserService; |
|||
|
|||
@Value("${payment.tracker.upload.path:gccpaymenttrackerfiles}") |
|||
private String paymentTrackerUploadPathConfig; |
|||
|
|||
@GetMapping({ "", "/", "/dashboard" }) |
|||
public String viewDashboard(Model model, HttpSession session) { |
|||
String username = (String) session.getAttribute("usrName"); |
|||
if (username == null) { |
|||
return "redirect:/gccservicepaymenttracker/login"; |
|||
} |
|||
|
|||
String usrRole = (String) session.getAttribute("usrRole"); |
|||
boolean isAdmin = "ADMIN".equalsIgnoreCase(usrRole); |
|||
|
|||
List<Map<String, Object>> vendorDetails = appUserService.getVendorDetailsWithCounts(); |
|||
|
|||
model.addAttribute("isLoggedIn", true); |
|||
model.addAttribute("isAdmin", isAdmin); |
|||
model.addAttribute("usrName", username); |
|||
model.addAttribute("curPage", "gccservicepaymenttracker"); |
|||
model.addAttribute("vendorDetails", vendorDetails); |
|||
|
|||
return "gccservicepaymenttracker/dashboard"; |
|||
} |
|||
|
|||
@GetMapping("/login") |
|||
public String login(HttpSession session) { |
|||
if (session.getAttribute("usrName") != null) { |
|||
return "redirect:/gccservicepaymenttracker/dashboard"; |
|||
} |
|||
return "gccservicepaymenttracker/login"; |
|||
} |
|||
|
|||
@PostMapping("/api/login") |
|||
@ResponseBody |
|||
public Map<String, Object> validateLogin( |
|||
@RequestParam("usrName") String usrName, |
|||
@RequestParam("usrPass") String usrPass, |
|||
HttpSession session) { |
|||
|
|||
Map<String, Object> authResult = appUserService.authenticate(usrName, usrPass); |
|||
Map<String, Object> response = new HashMap<>(); |
|||
|
|||
if (Boolean.TRUE.equals(authResult.get("success"))) { |
|||
session.setAttribute("usrName", authResult.get("usrName")); |
|||
session.setAttribute("usrRole", authResult.get("usrRole")); |
|||
session.setMaxInactiveInterval(1800); // 30 minutes session timeout |
|||
response.put("result", true); |
|||
response.put("usrName", authResult.get("usrName")); |
|||
} else { |
|||
response.put("result", false); |
|||
response.put("error", authResult.get("error")); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
|
|||
@PostMapping("/logout") |
|||
public String logout(HttpSession session) { |
|||
session.removeAttribute("usrName"); |
|||
session.removeAttribute("usrRole"); |
|||
session.invalidate(); |
|||
return "redirect:/gccservicepaymenttracker/login"; |
|||
} |
|||
|
|||
@GetMapping("/logout") |
|||
public String logoutGet(HttpSession session) { |
|||
session.removeAttribute("usrName"); |
|||
session.removeAttribute("usrRole"); |
|||
session.invalidate(); |
|||
return "redirect:/gccservicepaymenttracker/login"; |
|||
} |
|||
|
|||
@GetMapping("/api/counts") |
|||
@ResponseBody |
|||
public ResponseEntity<Map<String, Integer>> getCounts() { |
|||
return ResponseEntity.ok() |
|||
.cacheControl(CacheControl.noCache().mustRevalidate()) |
|||
.body(paymentTrackerService.getCountsByCategory()); |
|||
} |
|||
|
|||
@GetMapping("/api/list") |
|||
@ResponseBody |
|||
public ResponseEntity<List<Map<String, Object>>> listDetails( |
|||
@RequestParam(value = "category", required = false) String category, |
|||
@RequestParam(value = "fromDate", required = false) String fromDate, |
|||
@RequestParam(value = "toDate", required = false) String toDate, |
|||
@RequestParam(value = "status", required = false) String status) { |
|||
List<Map<String, Object>> details = paymentTrackerService.searchDetails(category, fromDate, toDate, status); |
|||
return ResponseEntity.ok() |
|||
.cacheControl(CacheControl.noCache().mustRevalidate()) |
|||
.body(details); |
|||
} |
|||
|
|||
@PostMapping("/api/save") |
|||
@ResponseBody |
|||
public Map<String, Object> saveDetail( |
|||
@RequestBody Map<String, Object> payload, |
|||
HttpSession session) { |
|||
|
|||
Map<String, Object> response = new HashMap<>(); |
|||
String username = (String) session.getAttribute("usrName"); |
|||
if (username == null) { |
|||
response.put("success", false); |
|||
response.put("error", "Unauthorized access! Please log in."); |
|||
return response; |
|||
} |
|||
|
|||
String usrRole = (String) session.getAttribute("usrRole"); |
|||
if (!"ADMIN".equalsIgnoreCase(usrRole)) { |
|||
response.put("success", false); |
|||
response.put("error", "Access denied! Only admins can save or update records."); |
|||
return response; |
|||
} |
|||
|
|||
try { |
|||
boolean saved = paymentTrackerService.saveOrUpdateDetail(payload); |
|||
response.put("success", saved); |
|||
if (!saved) { |
|||
response.put("error", "Failed to save details to database."); |
|||
} |
|||
} catch (Exception e) { |
|||
response.put("success", false); |
|||
response.put("error", "Error: " + e.getMessage()); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
|
|||
@PostMapping("/api/delete") |
|||
@ResponseBody |
|||
public Map<String, Object> deleteDetail( |
|||
@RequestParam("id") int id, |
|||
HttpSession session) { |
|||
|
|||
Map<String, Object> response = new HashMap<>(); |
|||
String username = (String) session.getAttribute("usrName"); |
|||
if (username == null) { |
|||
response.put("success", false); |
|||
response.put("error", "Unauthorized access! Please log in."); |
|||
return response; |
|||
} |
|||
|
|||
String usrRole = (String) session.getAttribute("usrRole"); |
|||
if (!"ADMIN".equalsIgnoreCase(usrRole)) { |
|||
response.put("success", false); |
|||
response.put("error", "Access denied! Only admins can delete records."); |
|||
return response; |
|||
} |
|||
|
|||
try { |
|||
boolean deleted = paymentTrackerService.deleteDetail(id); |
|||
response.put("success", deleted); |
|||
if (!deleted) { |
|||
response.put("error", "Failed to delete record."); |
|||
} |
|||
} catch (Exception e) { |
|||
response.put("success", false); |
|||
response.put("error", "Error: " + e.getMessage()); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
|
|||
@PostMapping("/api/upload-pdf") |
|||
@ResponseBody |
|||
public Map<String, Object> uploadPdf( |
|||
@RequestParam("file") MultipartFile file, |
|||
HttpSession session) { |
|||
Map<String, Object> response = new HashMap<>(); |
|||
String username = (String) session.getAttribute("usrName"); |
|||
if (username == null) { |
|||
response.put("success", false); |
|||
response.put("error", "Unauthorized access! Please log in."); |
|||
return response; |
|||
} |
|||
|
|||
String usrRole = (String) session.getAttribute("usrRole"); |
|||
if (!"ADMIN".equalsIgnoreCase(usrRole)) { |
|||
response.put("success", false); |
|||
response.put("error", "Access denied! Only admins can upload files."); |
|||
return response; |
|||
} |
|||
|
|||
if (file.isEmpty()) { |
|||
response.put("success", false); |
|||
response.put("error", "Please select a file to upload."); |
|||
return response; |
|||
} |
|||
|
|||
try { |
|||
File uploadDir = new File(paymentTrackerUploadPathConfig).getAbsoluteFile(); |
|||
if (!uploadDir.exists()) { |
|||
uploadDir.mkdirs(); |
|||
} |
|||
|
|||
String originalFilename = file.getOriginalFilename(); |
|||
String nameWithoutExt = "pdf"; |
|||
String ext = ".pdf"; |
|||
if (originalFilename != null && originalFilename.contains(".")) { |
|||
int dotIdx = originalFilename.lastIndexOf("."); |
|||
nameWithoutExt = originalFilename.substring(0, dotIdx); |
|||
ext = originalFilename.substring(dotIdx); |
|||
} |
|||
nameWithoutExt = nameWithoutExt.replaceAll("[^a-zA-Z0-9-_]", "_"); |
|||
String savedFilename = nameWithoutExt + "_" + System.currentTimeMillis() + ext; |
|||
|
|||
File destFile = new File(uploadDir, savedFilename).getAbsoluteFile(); |
|||
file.transferTo(destFile); |
|||
|
|||
String fileWebUrl = "/gccpaymenttrackerfiles/" + savedFilename; |
|||
response.put("success", true); |
|||
response.put("filePath", fileWebUrl); |
|||
} catch (Exception e) { |
|||
response.put("success", false); |
|||
response.put("error", "File upload failed: " + e.getMessage()); |
|||
} |
|||
|
|||
return response; |
|||
} |
|||
|
|||
@GetMapping("/api/types") |
|||
@ResponseBody |
|||
public List<Map<String, Object>> getActiveTypes() { |
|||
return paymentTrackerService.getActiveTypes(); |
|||
} |
|||
|
|||
@GetMapping("/api/vendors") |
|||
@ResponseBody |
|||
public List<Map<String, Object>> getActiveVendors() { |
|||
return paymentTrackerService.getActiveVendors(); |
|||
} |
|||
} |
|||
@ -0,0 +1,285 @@ |
|||
package com.gcc_manpower.gccservicepaymenttracker.service; |
|||
|
|||
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; |
|||
import javax.sql.DataSource; |
|||
import jakarta.annotation.PostConstruct; |
|||
import java.util.ArrayList; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
|
|||
@Service |
|||
public class GccServicePaymentTrackerService { |
|||
|
|||
private JdbcTemplate jdbcTemplate; |
|||
|
|||
@Autowired |
|||
public void setDataSource(@Qualifier("mysqlPaymentTrackingServiceDataSource") DataSource dataSource) { |
|||
this.jdbcTemplate = new JdbcTemplate(dataSource); |
|||
} |
|||
|
|||
public Map<String, Integer> getCountsByCategory() { |
|||
Map<String, Integer> counts = new HashMap<>(); |
|||
counts.put("sd", 0); |
|||
counts.put("tax invoice", 0); |
|||
counts.put("emd", 0); |
|||
counts.put("bank guarantee", 0); |
|||
counts.put("delivery chellan", 0); |
|||
counts.put("asd", 0); |
|||
counts.put("agreement", 0); |
|||
|
|||
String sql = "SELECT " |
|||
+ "CASE WHEN p.type REGEXP '^[0-9]+$' THEN t.type_name ELSE p.type END as type_resolved, " |
|||
+ "COUNT(*) as cnt " |
|||
+ "FROM payment_tracking_details p " |
|||
+ "LEFT JOIN type_list t ON p.type REGEXP '^[0-9]+$' AND t.id = p.type " |
|||
+ "WHERE p.is_active = 1 AND p.is_delete = 0 " |
|||
+ "GROUP BY type_resolved"; |
|||
|
|||
try { |
|||
List<Map<String, Object>> rows = jdbcTemplate.queryForList(sql); |
|||
for (Map<String, Object> row : rows) { |
|||
String type = String.valueOf(row.get("type_resolved")).toLowerCase().trim(); |
|||
Number countNum = (Number) row.get("cnt"); |
|||
int count = countNum != null ? countNum.intValue() : 0; |
|||
|
|||
// Map database values back to categories |
|||
if (type.equals("asd") || type.contains("asd") || type.contains("additional security")) { |
|||
counts.put("asd", counts.getOrDefault("asd", 0) + count); |
|||
} else if (type.equals("agreement") || type.contains("agreement")) { |
|||
counts.put("agreement", counts.getOrDefault("agreement", 0) + count); |
|||
} else if (type.equals("sd") || type.contains("security")) { |
|||
counts.put("sd", counts.getOrDefault("sd", 0) + count); |
|||
} else if (type.contains("invoice") || type.contains("bill")) { |
|||
counts.put("tax invoice", counts.getOrDefault("tax invoice", 0) + count); |
|||
} else if (type.equals("emd")) { |
|||
counts.put("emd", counts.getOrDefault("emd", 0) + count); |
|||
} else if (type.contains("guarantee") || type.contains("bg")) { |
|||
counts.put("bank guarantee", counts.getOrDefault("bank guarantee", 0) + count); |
|||
} else if (type.contains("chellan") || type.contains("challan") || type.contains("dc")) { |
|||
counts.put("delivery chellan", counts.getOrDefault("delivery chellan", 0) + count); |
|||
} |
|||
} |
|||
} catch (Exception e) { |
|||
System.err.println("Error getting category counts: " + e.getMessage()); |
|||
} |
|||
return counts; |
|||
} |
|||
|
|||
public List<Map<String, Object>> searchDetails(String type, String fromDate, String toDate, String status) { |
|||
StringBuilder sql = new StringBuilder( |
|||
"SELECT p.*, " |
|||
+ "t.type_name as resolved_type, " |
|||
+ "v.vendor_name as resolved_vendor " |
|||
+ "FROM payment_tracking_details p " |
|||
+ "LEFT JOIN type_list t ON p.type REGEXP '^[0-9]+$' AND t.id = p.type " |
|||
+ "LEFT JOIN vendors_list v ON p.vendor_name REGEXP '^[0-9]+$' AND v.id = p.vendor_name " |
|||
+ "WHERE p.is_active = 1 AND p.is_delete = 0"); |
|||
List<Object> params = new ArrayList<>(); |
|||
|
|||
if (type != null && !type.trim().isEmpty()) { |
|||
String category = type.trim().toLowerCase(); |
|||
if (category.equals("asd")) { |
|||
sql.append(" AND (LOWER(p.type) = 'asd' OR LOWER(p.type) LIKE '%asd%' OR LOWER(t.type_name) LIKE '%asd%' OR LOWER(t.type_name) LIKE '%additional security%')"); |
|||
} else if (category.equals("agreement")) { |
|||
sql.append(" AND (LOWER(p.type) LIKE '%agreement%' OR LOWER(t.type_name) LIKE '%agreement%')"); |
|||
} else if (category.equals("sd")) { |
|||
sql.append(" AND ((LOWER(p.type) = 'sd' OR LOWER(p.type) LIKE '%security%' OR LOWER(t.type_name) LIKE '%security%') " |
|||
+ "AND LOWER(p.type) NOT LIKE '%additional security%' AND LOWER(p.type) NOT LIKE '%asd%' " |
|||
+ "AND (t.type_name IS NULL OR (LOWER(t.type_name) NOT LIKE '%additional security%' AND LOWER(t.type_name) NOT LIKE '%asd%')))"); |
|||
} else if (category.equals("tax invoice")) { |
|||
sql.append(" AND (LOWER(p.type) LIKE '%invoice%' OR LOWER(p.type) LIKE '%bill%' OR LOWER(t.type_name) LIKE '%invoice%' OR LOWER(t.type_name) LIKE '%bill%')"); |
|||
} else if (category.equals("emd")) { |
|||
sql.append(" AND (LOWER(p.type) = 'emd' OR LOWER(p.type) LIKE '%earnest%' OR LOWER(t.type_name) LIKE '%emd%' OR LOWER(t.type_name) LIKE '%earnest%')"); |
|||
} else if (category.equals("bank guarantee")) { |
|||
sql.append(" AND (LOWER(p.type) LIKE '%guarantee%' OR LOWER(p.type) = 'bg' OR LOWER(t.type_name) LIKE '%guarantee%' OR LOWER(t.type_name) = 'bg')"); |
|||
} else if (category.equals("delivery chellan")) { |
|||
sql.append(" AND (LOWER(p.type) LIKE '%chellan%' OR LOWER(p.type) LIKE '%challan%' OR LOWER(p.type) = 'dc' " |
|||
+ "OR LOWER(t.type_name) LIKE '%chellan%' OR LOWER(t.type_name) LIKE '%challan%' OR LOWER(t.type_name) = 'dc')"); |
|||
} else { |
|||
sql.append(" AND (LOWER(p.type) = ? OR LOWER(t.type_name) = ?)"); |
|||
params.add(category); |
|||
params.add(category); |
|||
} |
|||
} |
|||
|
|||
if (fromDate != null && !fromDate.trim().isEmpty()) { |
|||
sql.append(" AND p.received_date >= ?"); |
|||
params.add(parseDate(fromDate)); |
|||
} |
|||
|
|||
if (toDate != null && !toDate.trim().isEmpty()) { |
|||
sql.append(" AND p.received_date <= ?"); |
|||
params.add(parseDate(toDate)); |
|||
} |
|||
|
|||
if (status != null && !status.trim().isEmpty()) { |
|||
sql.append(" AND LOWER(p.status) = ?"); |
|||
params.add(status.trim().toLowerCase()); |
|||
} |
|||
|
|||
sql.append(" ORDER BY p.order_by ASC, p.received_date DESC, p.id DESC"); |
|||
|
|||
try { |
|||
return jdbcTemplate.queryForList(sql.toString(), params.toArray()); |
|||
} catch (Exception e) { |
|||
System.err.println("Error searching payment tracking details: " + e.getMessage()); |
|||
return new ArrayList<>(); |
|||
} |
|||
} |
|||
|
|||
public Map<String, Object> getDetailById(int id) { |
|||
String sql = "SELECT * FROM payment_tracking_details WHERE id = ? AND is_active = 1 AND is_delete = 0"; |
|||
try { |
|||
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, id); |
|||
if (list != null && !list.isEmpty()) { |
|||
return list.get(0); |
|||
} |
|||
} catch (Exception e) { |
|||
System.err.println("Error fetching payment tracking detail ID " + id + ": " + e.getMessage()); |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public boolean saveOrUpdateDetail(Map<String, Object> payload) { |
|||
Object idObj = payload.get("id"); |
|||
java.sql.Date receivedDate = parseDate(payload.get("received_date")); |
|||
String vendorName = (String) payload.get("vendor_name"); |
|||
String subject = (String) payload.get("subject"); |
|||
String amount = (String) payload.get("amount"); |
|||
String invoiceNo = (String) payload.get("invoice_no"); |
|||
String receiptNo = payload.get("receiptno") != null ? String.valueOf(payload.get("receiptno")) : null; |
|||
java.sql.Date invoiceDate = parseDate(payload.get("invoice_date")); |
|||
String type = (String) payload.get("type"); |
|||
String physicalFileNo = (String) payload.get("physical_file_no"); |
|||
String remarks = (String) payload.get("remarks"); |
|||
String tat = (String) payload.get("tat"); |
|||
String status = (String) payload.get("status"); |
|||
String followup = (String) payload.get("followup"); |
|||
String myfollowup = (String) payload.get("myfollowup"); |
|||
String orderBy = (String) payload.get("order_by"); |
|||
String filePath = (String) payload.get("file_path"); |
|||
|
|||
if (idObj != null && !String.valueOf(idObj).trim().isEmpty()) { |
|||
// Update |
|||
int id = Integer.parseInt(String.valueOf(idObj).trim()); |
|||
String sql = "UPDATE payment_tracking_details SET " |
|||
+ "received_date = ?, vendor_name = ?, subject = ?, amount = ?, invoice_no = ?, " |
|||
+ "receiptno = ?, invoice_date = ?, type = ?, physical_file_no = ?, remarks = ?, " |
|||
+ "tat = ?, status = ?, followup = ?, myfollowup = ?, order_by = ?, file_path = ? " |
|||
+ "WHERE id = ? AND is_active = 1 AND is_delete = 0"; |
|||
try { |
|||
int rows = jdbcTemplate.update(sql, receivedDate, vendorName, subject, amount, invoiceNo, |
|||
receiptNo, invoiceDate, type, physicalFileNo, remarks, |
|||
tat, status, followup, myfollowup, orderBy, filePath, id); |
|||
return rows > 0; |
|||
} catch (Exception e) { |
|||
System.err.println("Error updating payment tracking detail ID " + id + ": " + e.getMessage()); |
|||
return false; |
|||
} |
|||
} else { |
|||
// Insert |
|||
String sql = "INSERT INTO payment_tracking_details (" |
|||
+ "received_date, vendor_name, subject, amount, invoice_no, receiptno, " |
|||
+ "invoice_date, type, physical_file_no, remarks, tat, status, " |
|||
+ "followup, myfollowup, is_active, is_delete, order_by, file_path" |
|||
+ ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 0, ?, ?)"; |
|||
try { |
|||
int rows = jdbcTemplate.update(sql, receivedDate, vendorName, subject, amount, invoiceNo, |
|||
receiptNo, invoiceDate, type, physicalFileNo, remarks, |
|||
tat, status, followup, myfollowup, orderBy, filePath); |
|||
return rows > 0; |
|||
} catch (Exception e) { |
|||
System.err.println("Error saving payment tracking detail: " + e.getMessage()); |
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public boolean deleteDetail(int id) { |
|||
String sql = "UPDATE payment_tracking_details SET is_active = 0, is_delete = 1 WHERE id = ?"; |
|||
try { |
|||
int rows = jdbcTemplate.update(sql, id); |
|||
return rows > 0; |
|||
} catch (Exception e) { |
|||
System.err.println("Error soft-deleting payment tracking detail ID " + id + ": " + e.getMessage()); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
private java.sql.Date parseDate(Object obj) { |
|||
if (obj == null || String.valueOf(obj).trim().isEmpty()) { |
|||
return null; |
|||
} |
|||
String str = String.valueOf(obj).trim(); |
|||
try { |
|||
// Support both yyyy-MM-dd and dd/MM/yyyy |
|||
if (str.contains("/")) { |
|||
String[] parts = str.split("/"); |
|||
if (parts.length == 3) { |
|||
// Convert dd/MM/yyyy to yyyy-MM-dd |
|||
str = parts[2] + "-" + parts[1] + "-" + parts[0]; |
|||
} |
|||
} |
|||
return java.sql.Date.valueOf(str); |
|||
} catch (Exception e) { |
|||
System.err.println("Error parsing date '" + obj + "': " + e.getMessage()); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
private java.sql.Timestamp parseTimestamp(Object obj) { |
|||
if (obj == null || String.valueOf(obj).trim().isEmpty()) { |
|||
return null; |
|||
} |
|||
String str = String.valueOf(obj).trim(); |
|||
try { |
|||
if (str.contains("/")) { |
|||
// Parse format dd/MM/yyyy HH:mm:ss or similar if provided |
|||
// For simplicity, fallback to current time or standard parsing if it fails |
|||
} |
|||
if (str.contains("T")) { |
|||
str = str.replace("T", " "); |
|||
} |
|||
if (str.length() == 16) { |
|||
str = str + ":00"; |
|||
} |
|||
return java.sql.Timestamp.valueOf(str); |
|||
} catch (Exception e) { |
|||
// Try parsing as DATE first, then convert to TIMESTAMP |
|||
java.sql.Date d = parseDate(obj); |
|||
if (d != null) { |
|||
return new java.sql.Timestamp(d.getTime()); |
|||
} |
|||
System.err.println("Error parsing timestamp '" + obj + "': " + e.getMessage()); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
public List<Map<String, Object>> getActiveTypes() { |
|||
String sql = "SELECT id, type_name FROM type_list " |
|||
+ "WHERE is_active = 1 AND is_delete = 0 " |
|||
+ "ORDER BY order_by ASC, type_name ASC"; |
|||
try { |
|||
return jdbcTemplate.queryForList(sql); |
|||
} catch (Exception e) { |
|||
System.err.println("Error fetching active types: " + e.getMessage()); |
|||
return new ArrayList<>(); |
|||
} |
|||
} |
|||
|
|||
public List<Map<String, Object>> getActiveVendors() { |
|||
String sql = "SELECT id, vendor_name FROM vendors_list " |
|||
+ "WHERE is_active = 1 AND is_delete = 0 " |
|||
+ "ORDER BY order_by ASC, vendor_name ASC"; |
|||
try { |
|||
return jdbcTemplate.queryForList(sql); |
|||
} catch (Exception e) { |
|||
System.err.println("Error fetching active vendors: " + e.getMessage()); |
|||
return new ArrayList<>(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,5 +1,5 @@ |
|||
#spring.profiles.active=local |
|||
spring.profiles.active=prod |
|||
spring.profiles.active=local |
|||
#spring.profiles.active=prod |
|||
spring.application.name=gcc-manpower |
|||
server.servlet.session.timeout=10m |
|||
|
|||
2151
src/main/resources/templates/gccservicepaymenttracker/dashboard.html
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,115 @@ |
|||
<!DOCTYPE html> |
|||
<html xmlns:th="http://www.thymeleaf.org" lang="en"> |
|||
|
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|||
<title>GCC Payment Tracker - Login</title> |
|||
|
|||
<!-- CSRF Tokens --> |
|||
<meta th:if="${_csrf != null}" name="_csrf" th:content="${_csrf.token}" /> |
|||
<meta th:if="${_csrf != null}" name="_csrf_header" th:content="${_csrf.headerName}" /> |
|||
|
|||
<!-- Include CSS --> |
|||
<link rel="stylesheet" type="text/css" th:href="@{/assets/css/login-form-styles.css}"> |
|||
|
|||
<!-- Awesome Font --> |
|||
<link th:href="@{/assets/font-awesome-6.5.2/css/all.min.css}" rel="stylesheet" type="text/css"> |
|||
</head> |
|||
|
|||
<body> |
|||
<div class="container"> |
|||
<img th:src="@{/assets/header-images/gcc1.png}" alt="Greater Chennai Corporation" class="small-logo"> |
|||
<h3>GREATER CHENNAI CORPORATION</h3> |
|||
<h4>பெருநகர சென்னை மாநகராட்சி</h4> |
|||
<br> |
|||
<h3>GCC Service Payment Processing Tracker</h3> |
|||
<br> |
|||
<h2>Login</h2> |
|||
|
|||
<div id="error-box" |
|||
style="color: #c0392b; font-weight: 500; font-size: 0.85rem; margin-bottom: 1.5rem; text-align: center; display: none;"> |
|||
<i class="fa-solid fa-circle-exclamation"></i> <span id="error-text">Invalid username or password!</span> |
|||
</div> |
|||
|
|||
<form id="loginForm" onsubmit="handleLogin(event)"> |
|||
<div class="input-field"> |
|||
<input type="text" name="usrName" id="usrName" placeholder="Enter Username" required |
|||
autocomplete="username"> |
|||
<div class="underline"></div> |
|||
</div> |
|||
<div class="input-field"> |
|||
<input type="password" name="usrPass" id="usrPass" placeholder="Enter Password" required |
|||
autocomplete="current-password"> |
|||
<div class="underline"></div> |
|||
</div> |
|||
<input type="submit" value="Login" id="submit-btn"> |
|||
</form> |
|||
</div> |
|||
|
|||
<!-- Footer Fragment --> |
|||
<th:block th:replace="~{fragments/footer :: footer}"></th:block> |
|||
|
|||
<!-- Custom JS --> |
|||
<script th:inline="javascript"> |
|||
const contextPath = /*[[@{/}]]*/ ''; |
|||
</script> |
|||
|
|||
<script> |
|||
function handleLogin(event) { |
|||
event.preventDefault(); |
|||
|
|||
const errorBox = document.getElementById("error-box"); |
|||
const errorText = document.getElementById("error-text"); |
|||
const submitBtn = document.getElementById("submit-btn"); |
|||
|
|||
errorBox.style.display = "none"; |
|||
submitBtn.disabled = true; |
|||
submitBtn.value = 'Authenticating...'; |
|||
|
|||
const username = document.getElementById("usrName").value; |
|||
const password = document.getElementById("usrPass").value; |
|||
|
|||
const urlParams = new URLSearchParams(); |
|||
urlParams.append('usrName', username); |
|||
urlParams.append('usrPass', password); |
|||
|
|||
// Fetch CSRF tokens |
|||
const csrfToken = document.querySelector("meta[name='_csrf']")?.getAttribute("content"); |
|||
const csrfHeader = document.querySelector("meta[name='_csrf_header']")?.getAttribute("content"); |
|||
|
|||
const headers = { |
|||
'Content-Type': 'application/x-www-form-urlencoded' |
|||
}; |
|||
if (csrfToken && csrfHeader) { |
|||
headers[csrfHeader] = csrfToken; |
|||
} |
|||
|
|||
fetch(contextPath + 'gccservicepaymenttracker/api/login', { |
|||
method: 'POST', |
|||
headers: headers, |
|||
body: urlParams |
|||
}) |
|||
.then(response => response.json()) |
|||
.then(data => { |
|||
if (data.result) { |
|||
window.location.href = contextPath + 'gccservicepaymenttracker/dashboard'; |
|||
} else { |
|||
submitBtn.disabled = false; |
|||
submitBtn.value = 'Login'; |
|||
errorText.textContent = data.error || "Authentication failed."; |
|||
errorBox.style.display = "block"; |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
console.error("Login Error:", err); |
|||
submitBtn.disabled = false; |
|||
submitBtn.value = 'Login'; |
|||
errorText.textContent = "Network error. Please try again later."; |
|||
errorBox.style.display = "block"; |
|||
}); |
|||
} |
|||
</script> |
|||
</body> |
|||
|
|||
</html> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue