package com.gcc_manpower.gcctapaldetailsmanagement.controller; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.CacheControl; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.context.HttpSessionSecurityContextRepository; 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.multipart.MultipartFile; import com.gcc_manpower.gcctapaldetailsmanagement.service.TapalService; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; @Controller @RequestMapping("/gcctapaldetailsmanagement") public class TapalController { @Autowired private TapalService tapalService; @Autowired private AuthenticationManager authenticationManager; @Value("${tapal.upload.path:gcctapalfiles}") private String tapalUploadPathConfig; @GetMapping({ "", "/", "/dashboard" }) public String viewDashboard(Model model, HttpSession session) { String username = (String) session.getAttribute("tap_usrName"); if (username == null) { return "redirect:/gcctapaldetailsmanagement/login"; } String usrRole = (String) session.getAttribute("tap_usrRole"); boolean isAdmin = "ADMIN".equalsIgnoreCase(usrRole); model.addAttribute("isLoggedIn", true); model.addAttribute("isAdmin", isAdmin); model.addAttribute("usrName", username); model.addAttribute("curPage", "gcctapaldetailsmanagement"); return "gcctapaldetailsmanagement/dashboard"; } @GetMapping("/details") public String viewDetails(HttpSession session, Model model) { String username = (String) session.getAttribute("tap_usrName"); if (username == null) { return "redirect:/gcctapaldetailsmanagement/login"; } String usrRole = (String) session.getAttribute("tap_usrRole"); boolean isAdmin = "ADMIN".equalsIgnoreCase(usrRole); model.addAttribute("isLoggedIn", true); model.addAttribute("isAdmin", isAdmin); model.addAttribute("usrName", username); model.addAttribute("curPage", "gcctapaldetailsmanagement"); return "gcctapaldetailsmanagement/details"; } @GetMapping("/login") public String login(HttpSession session) { return "gcctapaldetailsmanagement/login"; } @PostMapping("/api/login") @ResponseBody public Map validateLogin( @RequestParam("usrName") String usrName, @RequestParam("usrPass") String usrPass, HttpSession session) { Map response = new HashMap<>(); try { UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(usrName, usrPass); Authentication authentication = authenticationManager.authenticate(authenticationToken); SecurityContextHolder.getContext().setAuthentication(authentication); session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext()); String role = authentication.getAuthorities().stream() .map(auth -> auth.getAuthority().replace("ROLE_", "")) .findFirst() .orElse("USER"); session.setAttribute("tap_usrName", usrName); session.setAttribute("tap_usrRole", role); session.setMaxInactiveInterval(1800); // 30 minutes session timeout response.put("result", true); response.put("usrName", usrName); } catch (AuthenticationException e) { response.put("result", false); response.put("error", e.getMessage() != null ? e.getMessage() : "Invalid username or password!"); } return response; } @GetMapping("/logout") public String logout(HttpSession session, HttpServletRequest request) { SecurityContextHolder.clearContext(); if (session != null) { session.removeAttribute("tap_usrName"); session.removeAttribute("tap_usrRole"); session.invalidate(); } request.getSession(true); return "redirect:/gcctapaldetailsmanagement/login"; } @GetMapping("/api/counts") @ResponseBody public ResponseEntity> getCounts() { return ResponseEntity.ok() .cacheControl(CacheControl.noCache().mustRevalidate()) .body(tapalService.getCountsByCategory()); } @GetMapping("/api/list") @ResponseBody public ResponseEntity>> 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> details = tapalService.searchTapals(category, fromDate, toDate, status); return ResponseEntity.ok() .cacheControl(CacheControl.noCache().mustRevalidate()) .body(details); } @PostMapping("/api/save") @ResponseBody public Map saveDetail( @RequestBody Map payload, HttpSession session) { Map response = new HashMap<>(); String username = (String) session.getAttribute("tap_usrName"); if (username == null) { 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("tap_usrRole"); if (usrRole == null) { 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 = tapalService.saveOrUpdateTapal(payload, username); response.put("success", saved); if (!saved) { response.put("error", "Failed to save Tapal details to database."); } } catch (Exception e) { response.put("success", false); response.put("error", "Error: " + e.getMessage()); } return response; } @PostMapping("/api/delete") @ResponseBody public Map deleteDetail( @RequestParam("id") int id, @RequestParam(value = "remarks", required = false, defaultValue = "") String remarks, HttpSession session) { Map response = new HashMap<>(); String username = (String) session.getAttribute("tap_usrName"); if (username == null) { 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("tap_usrRole"); if (usrRole == null) { 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 = tapalService.deleteTapal(id, remarks, username); 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-file") @ResponseBody public Map uploadFile( @RequestParam("file") MultipartFile file, @RequestParam(value = "type", required = false, defaultValue = "tapal") String type, HttpSession session) { Map response = new HashMap<>(); String username = (String) session.getAttribute("tap_usrName"); if (username == null) { 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("tap_usrRole"); if (usrRole == null) { 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 parentDir = new File(tapalUploadPathConfig).getAbsoluteFile(); File destDir = parentDir; String webPathPrefix = "/gcctapalfiles/"; if ("oc".equalsIgnoreCase(type)) { destDir = new File(parentDir, "oc"); webPathPrefix = "/gcctapalfiles/oc/"; } if (!destDir.exists()) { destDir.mkdirs(); } String originalFilename = file.getOriginalFilename(); String nameWithoutExt = type; 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(destDir, savedFilename).getAbsoluteFile(); file.transferTo(destFile); String fileWebUrl = webPathPrefix + 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/categories") @ResponseBody public List> getActiveCategories() { return tapalService.getActiveCategories(); } @GetMapping("/api/statuslist") @ResponseBody public List> getStatusList() { return tapalService.getActiveStatuses(); } @GetMapping("/api/history") @ResponseBody public ResponseEntity>> getHistory( @RequestParam("tapalNo") String tapalNo, HttpSession session) { String username = (String) session.getAttribute("tap_usrName"); if (username == null) { username = (String) session.getAttribute("usrName"); } if (username == null) { return ResponseEntity.status(401).body(null); } return ResponseEntity.ok() .cacheControl(CacheControl.noCache().mustRevalidate()) .body(tapalService.getHistory(tapalNo)); } @GetMapping("/api/deleted-list") @ResponseBody public ResponseEntity>> getDeletedList(HttpSession session) { String username = (String) session.getAttribute("tap_usrName"); if (username == null) { username = (String) session.getAttribute("usrName"); } if (username == null) { return ResponseEntity.status(401).body(null); } return ResponseEntity.ok() .cacheControl(CacheControl.noCache().mustRevalidate()) .body(tapalService.getDeletedTapals()); } @PostMapping("/api/restore") @ResponseBody public Map restoreDetail( @RequestParam("id") int id, HttpSession session) { Map response = new HashMap<>(); String username = (String) session.getAttribute("tap_usrName"); if (username == null) { 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("tap_usrRole"); if (usrRole == null) { usrRole = (String) session.getAttribute("usrRole"); } if (!"ADMIN".equalsIgnoreCase(usrRole)) { response.put("success", false); response.put("error", "Access denied! Only admins can restore records."); return response; } try { boolean restored = tapalService.restoreTapal(id, username); response.put("success", restored); if (!restored) { response.put("error", "Failed to restore record."); } } catch (Exception e) { response.put("success", false); response.put("error", "Error: " + e.getMessage()); } return response; } }