diff --git a/src/main/java/com/gcc_manpower/config/DataSourceConfig.java b/src/main/java/com/gcc_manpower/config/DataSourceConfig.java index 67ecdc4..7eeb080 100644 --- a/src/main/java/com/gcc_manpower/config/DataSourceConfig.java +++ b/src/main/java/com/gcc_manpower/config/DataSourceConfig.java @@ -14,7 +14,8 @@ public class DataSourceConfig { private static String dbpassword = "root"; // AWS - // private static String host = "gcc-facial-db-instance-1.cf48eqcciziq.ap-south-1.rds.amazonaws.com:3306"; + // private static String host = + // "gcc-facial-db-instance-1.cf48eqcciziq.ap-south-1.rds.amazonaws.com:3306"; // private static String dbpassword = "gcc-facial-password"; @Bean(name = "mysqlManpowerDataSource") @@ -46,4 +47,14 @@ public class DataSourceConfig { dataSource.setPassword(dbpassword); return dataSource; } + + @Bean(name = "mysqlTonerManagementDataSource") + public DataSource mysqlTonerManagementDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_toner_management"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } } diff --git a/src/main/java/com/gcc_manpower/config/WebConfig.java b/src/main/java/com/gcc_manpower/config/WebConfig.java index 5436af3..9191f8f 100644 --- a/src/main/java/com/gcc_manpower/config/WebConfig.java +++ b/src/main/java/com/gcc_manpower/config/WebConfig.java @@ -18,6 +18,9 @@ public class WebConfig implements WebMvcConfigurer { @Value("${payment.tracker.upload.path:gccpaymenttrackerfiles}") private String paymentTrackerUploadPathConfig; + @Value("${toner.upload.path:gcctonermanagementfiles}") + private String tonerUploadPathConfig; + @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // Resolve absolute path (supports both relative and absolute paths) @@ -39,5 +42,11 @@ public class WebConfig implements WebMvcConfigurer { .toString(); registry.addResourceHandler("/gccpaymenttrackerfiles/**") .addResourceLocations(trackerUploadPath); + + // Map URL path /gcctonermanagementfiles/** to the configured toner folder + String tonerUploadPath = Paths.get(tonerUploadPathConfig).toAbsolutePath().toUri() + .toString(); + registry.addResourceHandler("/gcctonermanagementfiles/**") + .addResourceLocations(tonerUploadPath); } } diff --git a/src/main/java/com/gcc_manpower/gccservicedocuments/service/GccServiceDocumentsService.java b/src/main/java/com/gcc_manpower/gccservicedocuments/service/GccServiceDocumentsService.java index b24237d..3e14986 100644 --- a/src/main/java/com/gcc_manpower/gccservicedocuments/service/GccServiceDocumentsService.java +++ b/src/main/java/com/gcc_manpower/gccservicedocuments/service/GccServiceDocumentsService.java @@ -226,7 +226,8 @@ public class GccServiceDocumentsService { return null; } - public boolean updateDocument(Long id, String title, String mainCategory, String subCategory, String fileType, String filePath, + public boolean updateDocument(Long id, String title, String mainCategory, String subCategory, String fileType, + String filePath, String originalFilename) { // Insert old record into history before update try { diff --git a/src/main/java/com/gcc_manpower/gcctonermanagement/controller/TonerController.java b/src/main/java/com/gcc_manpower/gcctonermanagement/controller/TonerController.java new file mode 100644 index 0000000..dc527ed --- /dev/null +++ b/src/main/java/com/gcc_manpower/gcctonermanagement/controller/TonerController.java @@ -0,0 +1,226 @@ +package com.gcc_manpower.gcctonermanagement.controller; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +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.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.multipart.MultipartFile; +import java.io.File; +import com.gcc_manpower.gcctonermanagement.service.TonerService; +import com.gcc_manpower.service.AppUserService; + +import jakarta.servlet.http.HttpSession; + +@Controller +@RequestMapping("/gcctonermanagement") +public class TonerController { + + @Autowired + private AppUserService appUserService; + + @Autowired + private TonerService tonerService; + + @Value("${toner.upload.path:gcctonermanagementfiles}") + private String tonerUploadPathConfig; + + @GetMapping({ "", "/", "/upload" }) + public String viewDashboard(Model model, HttpSession session) { + String username = (String) session.getAttribute("toner_usrName"); + if (username == null) { + return "redirect:/gcctonermanagement/login"; + } + + String usrRole = (String) session.getAttribute("toner_usrRole"); + boolean isAdmin = "ADMIN".equalsIgnoreCase(usrRole); + + // List> vendorDetails = + // appUserService.getVendorDetailsWithCounts(); + + model.addAttribute("isLoggedIn", true); + model.addAttribute("isAdmin", isAdmin); + model.addAttribute("usrName", username); + model.addAttribute("curPage", "gcctonermanagement"); + // model.addAttribute("vendorDetails", vendorDetails); + + return "gcctonermanagement/upload"; + } + + @GetMapping("/login") + public String login(HttpSession session) { + return "gcctonermanagement/login"; + } + + @PostMapping("/api/login") + @ResponseBody + public Map validateLogin( + @RequestParam("usrName") String usrName, + @RequestParam("usrPass") String usrPass, + HttpSession session) { + + Map authResult = appUserService.authenticate(usrName, usrPass); + Map response = new HashMap<>(); + + if (Boolean.TRUE.equals(authResult.get("success"))) { + session.setAttribute("toner_usrName", authResult.get("usrName")); + session.setAttribute("toner_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; + } + + @GetMapping("/logout") + public String logoutGet(HttpSession session) { + session.removeAttribute("toner_usrName"); + session.removeAttribute("toner_usrRole"); + return "redirect:/gcctonermanagement/login"; + } + + @GetMapping("/api/printers") + @ResponseBody + public List> getPrinters(HttpSession session) { + if (session.getAttribute("toner_usrName") == null) { + return java.util.Collections.emptyList(); + } + return tonerService.getActivePrinters(); + } + + @GetMapping("/api/toners") + @ResponseBody + public List> getToners(@RequestParam("pid") int pid, HttpSession session) { + if (session.getAttribute("toner_usrName") == null) { + return java.util.Collections.emptyList(); + } + return tonerService.getActiveTonersByPrinter(pid); + } + + @PostMapping("/api/upload") + @ResponseBody + public Map uploadToner( + @RequestParam("companyName") String companyName, + @RequestParam("pid") int pid, + @RequestParam("tid") int tid, + @RequestParam("qty") String qty, + @RequestParam(value = "dcFile", required = false) MultipartFile dcFile, + @RequestParam(value = "userRequestFile", required = false) MultipartFile userRequestFile, + @RequestParam(value = "finalDeliveredFile", required = false) MultipartFile finalDeliveredFile, + HttpSession session) { + + Map response = new HashMap<>(); + String username = (String) session.getAttribute("toner_usrName"); + if (username == null) { + response.put("success", false); + response.put("error", "Unauthorized access. Please log in."); + return response; + } + + // Validate PDF extension on non-empty files + if (dcFile != null && !dcFile.isEmpty() && !isPdfFile(dcFile)) { + response.put("success", false); + response.put("error", "Delivery Challan file must be a PDF."); + return response; + } + if (userRequestFile != null && !userRequestFile.isEmpty() && !isPdfFile(userRequestFile)) { + response.put("success", false); + response.put("error", "User Request file must be a PDF."); + return response; + } + if (finalDeliveredFile != null && !finalDeliveredFile.isEmpty() && !isPdfFile(finalDeliveredFile)) { + response.put("success", false); + response.put("error", "Final Delivered file must be a PDF."); + return response; + } + + try { + File uploadDir = new File(tonerUploadPathConfig).getAbsoluteFile(); + if (!uploadDir.exists()) { + uploadDir.mkdirs(); + } + + // Save files + String dcPath = saveUploadedFile(dcFile, "dc", uploadDir); + String userRequestPath = saveUploadedFile(userRequestFile, "user_request", uploadDir); + String finalDeliveredPath = saveUploadedFile(finalDeliveredFile, "final_delivered", uploadDir); + + boolean saved = tonerService.saveInventoryDetails( + companyName.trim(), + pid, + tid, + qty.trim(), + dcPath, + userRequestPath, + finalDeliveredPath, + username); + + if (saved) { + response.put("success", true); + response.put("message", "Toner details saved successfully."); + } else { + // Delete newly saved files on DB insert failure + deleteFileIfExists(dcPath, uploadDir); + deleteFileIfExists(userRequestPath, uploadDir); + deleteFileIfExists(finalDeliveredPath, uploadDir); + response.put("success", false); + response.put("error", "Failed to save registration details in the database."); + } + } catch (Exception e) { + response.put("success", false); + response.put("error", "An error occurred during saving: " + e.getMessage()); + e.printStackTrace(); + } + + return response; + } + + private boolean isPdfFile(MultipartFile file) { + String originalFilename = file.getOriginalFilename(); + if (originalFilename == null) + return false; + return originalFilename.toLowerCase().endsWith(".pdf"); + } + + private String saveUploadedFile(MultipartFile file, String prefix, File uploadDir) throws Exception { + if (file == null || file.isEmpty()) { + return null; + } + String originalFilename = file.getOriginalFilename(); + String ext = ".pdf"; // Since we only allow PDFs + + // Clean filename, make it unique + String savedFilename = prefix + "_" + System.currentTimeMillis() + ext; + File destFile = new File(uploadDir, savedFilename).getAbsoluteFile(); + file.transferTo(destFile); + + return "/gcctonermanagementfiles/" + savedFilename; + } + + private void deleteFileIfExists(String webPath, File uploadDir) { + if (webPath == null || webPath.isEmpty()) + return; + try { + String filename = webPath.substring(webPath.lastIndexOf('/') + 1); + File file = new File(uploadDir, filename).getAbsoluteFile(); + if (file.exists()) { + file.delete(); + } + } catch (Exception e) { + System.err.println("Error deleting file: " + e.getMessage()); + } + } +} diff --git a/src/main/java/com/gcc_manpower/gcctonermanagement/service/TonerService.java b/src/main/java/com/gcc_manpower/gcctonermanagement/service/TonerService.java new file mode 100644 index 0000000..76a783f --- /dev/null +++ b/src/main/java/com/gcc_manpower/gcctonermanagement/service/TonerService.java @@ -0,0 +1,97 @@ +package com.gcc_manpower.gcctonermanagement.service; + +import java.util.ArrayList; +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 TonerService { + + private JdbcTemplate jdbcTemplate; + + @Autowired + public void setDataSource(@Qualifier("mysqlTonerManagementDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + public List> getActivePrinters() { + String sql = "SELECT id, printer_name FROM printer_model_list where is_active = 1 AND is_delete = 0 "; + try { + return jdbcTemplate.queryForList(sql); + } catch (Exception e) { + System.err.println("Error fetching printers list: " + e.getMessage()); + return new ArrayList<>(); + } + } + + public List> getActiveTonersByPrinter(int pid) { + String sql = "SELECT id, model_name FROM toner_model_list WHERE pid = ? AND is_active = 1 AND is_delete = 0 "; + try { + return jdbcTemplate.queryForList(sql, pid); + } catch (Exception e) { + System.err.println("Error fetching toners list: " + e.getMessage()); + return new ArrayList<>(); + } + } + + public String getTonerModelName(int tid) { + String sql = "SELECT model_name FROM toner_model_list WHERE id = ?"; + try { + return jdbcTemplate.queryForObject(sql, String.class, tid); + } catch (Exception e) { + System.err.println("Error fetching toner model name for id " + tid + ": " + e.getMessage()); + return "UNKNOWN"; + } + } + + public int getMaxInventoryId() { + String sql = "SELECT COALESCE(MAX(id), 0) FROM inventory_registered_details"; + try { + return jdbcTemplate.queryForObject(sql, Integer.class); + } catch (Exception e) { + System.err.println("Error fetching max id from inventory_registered_details: " + e.getMessage()); + return 0; + } + } + + public boolean saveInventoryDetails(String companyName, int pid, int tid, String qty, String dcUpload, + String userRequestUpload, String finalDeliveredUpload, String username) { + // 1. Get toner model name + String tonerModel = getTonerModelName(tid); + String cleanModel = tonerModel.trim().replaceAll("\\s+", "-").replaceAll("[^a-zA-Z0-9-]", ""); + + // 2. Get next sequential number + int maxId = getMaxInventoryId(); + int seqNum = 1000 + maxId + 1; + + // 3. Get current year + int year = java.util.Calendar.getInstance().get(java.util.Calendar.YEAR); + + // 4. Construct request number + String reqNo = String.format("%s-%d-%04d", cleanModel, year, seqNum); + + // 5. Insert row + String sql = "INSERT INTO department_requested_details " + + "(req_no, company_name, pid, tid, qty_registered, dc_upload, user_request_upload, final_delivered_upload, cdate, updated_date, updated_by, is_active, is_delete) " + + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 0)"; + + java.sql.Timestamp now = new java.sql.Timestamp(System.currentTimeMillis()); + try { + int rows = jdbcTemplate.update(sql, reqNo, companyName, String.valueOf(pid), String.valueOf(tid), qty, + dcUpload, userRequestUpload, finalDeliveredUpload, now, now, username); + return rows > 0; + } catch (Exception e) { + System.err.println("Error saving inventory details: " + e.getMessage()); + e.printStackTrace(); + return false; + } + } +} diff --git a/src/main/java/com/gcc_manpower/service/AppUserService.java b/src/main/java/com/gcc_manpower/service/AppUserService.java index d71a3bb..bc2151d 100644 --- a/src/main/java/com/gcc_manpower/service/AppUserService.java +++ b/src/main/java/com/gcc_manpower/service/AppUserService.java @@ -851,6 +851,7 @@ public class AppUserService { " e.joined_date, " + " e.cdate, " + " e.updated_at, " + + " e.designation AS raw_designation, " + " COALESCE(u.usr_name, e.updated_by) AS updated_by_name, " + " COALESCE(v.vendor_name, e.vendor_id) AS vendor_name, " + " COALESCE(ut.usertype, e.user_type) AS user_type, " + diff --git a/src/main/resources/templates/fragments/navbar.html b/src/main/resources/templates/fragments/navbar.html index da8cde7..5d2a223 100644 --- a/src/main/resources/templates/fragments/navbar.html +++ b/src/main/resources/templates/fragments/navbar.html @@ -52,6 +52,12 @@ Deleted Work Orders +