diff --git a/pom.xml b/pom.xml index 4bd30e2..aa8247d 100644 --- a/pom.xml +++ b/pom.xml @@ -43,8 +43,8 @@ spring-boot-starter-jdbc - org.springframework.security - spring-security-crypto + org.springframework.boot + spring-boot-starter-security diff --git a/src/main/java/com/gcc_manpower/config/AppUserDetailsService.java b/src/main/java/com/gcc_manpower/config/AppUserDetailsService.java new file mode 100644 index 0000000..ab5b5b3 --- /dev/null +++ b/src/main/java/com/gcc_manpower/config/AppUserDetailsService.java @@ -0,0 +1,66 @@ +package com.gcc_manpower.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import javax.sql.DataSource; +import java.util.List; +import java.util.Map; + +@Service +public class AppUserDetailsService implements UserDetailsService { + + private JdbcTemplate jdbcTemplate; + + @Autowired + public void setDataSource(@Qualifier("mysqlManpowerDataSource") DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + String sql = "SELECT usr_name, usr_pass, usr_role, is_active FROM app_user WHERE usr_name = ?"; + List> users; + try { + users = jdbcTemplate.queryForList(sql, username); + } catch (Exception e) { + throw new UsernameNotFoundException("Database error during user retrieval", e); + } + + if (users == null || users.isEmpty()) { + throw new UsernameNotFoundException("Invalid username or password!"); + } + + Map user = users.get(0); + + // Check if user is active + int isActive = 1; + Object activeObj = user.get("is_active"); + if (activeObj instanceof Number) { + isActive = ((Number) activeObj).intValue(); + } else if (activeObj instanceof Boolean) { + isActive = (Boolean) activeObj ? 1 : 0; + } + + if (isActive == 0) { + throw new UsernameNotFoundException("User account is inactive!"); + } + + String password = (String) user.get("usr_pass"); + String role = (String) user.get("usr_role"); + if (role == null) { + role = "USER"; + } + + return User.withUsername(username) + .password(password != null ? password : "") + .roles(role.toUpperCase()) // Will be loaded as authority ROLE_ROLE + .build(); + } +} diff --git a/src/main/java/com/gcc_manpower/config/SecurityConfig.java b/src/main/java/com/gcc_manpower/config/SecurityConfig.java new file mode 100644 index 0000000..c60cceb --- /dev/null +++ b/src/main/java/com/gcc_manpower/config/SecurityConfig.java @@ -0,0 +1,123 @@ +package com.gcc_manpower.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.header.writers.XXssProtectionHeaderWriter; + +@Configuration +@EnableWebSecurity +public class SecurityConfig { + + @Bean + public PasswordEncoder passwordEncoder() { + return new PasswordEncoder() { + private final BCryptPasswordEncoder bcrypt = new BCryptPasswordEncoder(); + + @Override + public String encode(CharSequence rawPassword) { + return bcrypt.encode(rawPassword); + } + + @Override + public boolean matches(CharSequence rawPassword, String dbPassword) { + if (dbPassword != null && dbPassword.startsWith("$2a$")) { + return bcrypt.matches(rawPassword, dbPassword); + } + return rawPassword.toString().equals(dbPassword); + } + }; + } + + @Bean + public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { + return config.getAuthenticationManager(); + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http + // Configure headers for clickjacking and XSS protection + .headers(headers -> headers + .frameOptions(frame -> frame.sameOrigin()) + .xssProtection( + xss -> xss.headerValue(XXssProtectionHeaderWriter.HeaderValue.ENABLED_MODE_BLOCK))) + // Configure URL authorization + .authorizeHttpRequests(auth -> auth + // Allow static resources + .requestMatchers( + "/assets/**", + "/css/**", + "/js/**", + "/images/**", + "/favicon.ico", + "/error") + .permitAll() + // Allow login pages and login API endpoints + .requestMatchers( + "/login", + "/api/val-app-usr-login", + "/gcctonermanagement/login", + "/gcctonermanagement/api/login", + "/gccservicepaymenttracker/login", + "/gccservicepaymenttracker/api/login", + "/gccservicedocuments/login", + "/gccservicedocuments/api/login") + .permitAll() + // Allow logout endpoints + .requestMatchers( + "/usr-logout", + "/gcctonermanagement/logout", + "/gccservicepaymenttracker/logout", + "/gccservicedocuments/logout") + .permitAll() + // Require authentication for all other requests + .anyRequest().authenticated()) + // Configure CSRF protection (ignore CSRF on the login endpoints only) + .csrf(csrf -> csrf + .ignoringRequestMatchers( + "/api/val-app-usr-login", + "/gcctonermanagement/api/login", + "/gccservicepaymenttracker/api/login", + "/gccservicedocuments/api/login")) + // Session management configuration with module-aware invalid session + // redirection + .sessionManagement(session -> session + .invalidSessionStrategy((request, response) -> { + // Create a fresh session so requestedSessionIdValid won't cause endless loop + request.getSession(true); + String requestURI = request.getRequestURI(); + if (requestURI.contains("/gccservicepaymenttracker")) { + response.sendRedirect(request.getContextPath() + "/gccservicepaymenttracker/login"); + } else if (requestURI.contains("/gcctonermanagement")) { + response.sendRedirect(request.getContextPath() + "/gcctonermanagement/login"); + } else if (requestURI.contains("/gccservicedocuments")) { + response.sendRedirect(request.getContextPath() + "/gccservicedocuments/login"); + } else { + response.sendRedirect(request.getContextPath() + "/login"); + } + })) + // Exception handling for unauthenticated requests with module-aware redirection + .exceptionHandling(exceptions -> exceptions + .authenticationEntryPoint((request, response, authException) -> { + String requestURI = request.getRequestURI(); + if (requestURI.contains("/gccservicepaymenttracker")) { + response.sendRedirect(request.getContextPath() + "/gccservicepaymenttracker/login"); + } else if (requestURI.contains("/gcctonermanagement")) { + response.sendRedirect(request.getContextPath() + "/gcctonermanagement/login"); + } else if (requestURI.contains("/gccservicedocuments")) { + response.sendRedirect(request.getContextPath() + "/gccservicedocuments/login"); + } else { + response.sendRedirect(request.getContextPath() + "/login"); + } + })); + + return http.build(); + } +} diff --git a/src/main/java/com/gcc_manpower/controller/HomeController.java b/src/main/java/com/gcc_manpower/controller/HomeController.java index ad4e435..67f0ae1 100644 --- a/src/main/java/com/gcc_manpower/controller/HomeController.java +++ b/src/main/java/com/gcc_manpower/controller/HomeController.java @@ -19,6 +19,13 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.web.multipart.MultipartFile; import java.io.File; +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; + @Controller @RequestMapping("/") public class HomeController { @@ -26,6 +33,9 @@ public class HomeController { @Autowired private AppUserService appUserService; + @Autowired + private AuthenticationManager authenticationManager; + @Value("${upload.path:gcc_manpower_uploads}") private String uploadPathConfig; @@ -93,18 +103,29 @@ public class HomeController { @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("usrName", authResult.get("usrName")); - session.setAttribute("usrRole", authResult.get("usrRole")); + 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("usrName", usrName); + session.setAttribute("usrRole", role); session.setMaxInactiveInterval(600); // 10 minutes session timeout response.put("result", true); - response.put("usrName", authResult.get("usrName")); - } else { + response.put("usrName", usrName); + } catch (AuthenticationException e) { response.put("result", false); - response.put("error", authResult.get("error")); + response.put("error", e.getMessage() != null ? e.getMessage() : "Invalid username or password!"); } return response; @@ -634,6 +655,7 @@ public class HomeController { @PostMapping("/usr-logout") public String logout(HttpSession session) { + SecurityContextHolder.clearContext(); session.invalidate(); return "redirect:/login"; } diff --git a/src/main/java/com/gcc_manpower/gccservicedocuments/controller/GccServiceDocumentsController.java b/src/main/java/com/gcc_manpower/gccservicedocuments/controller/GccServiceDocumentsController.java index 5ddd71f..dc150a0 100644 --- a/src/main/java/com/gcc_manpower/gccservicedocuments/controller/GccServiceDocumentsController.java +++ b/src/main/java/com/gcc_manpower/gccservicedocuments/controller/GccServiceDocumentsController.java @@ -10,11 +10,19 @@ import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.HttpServletRequest; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; +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; + @Controller @RequestMapping("/gccservicedocuments") public class GccServiceDocumentsController { @@ -28,6 +36,9 @@ public class GccServiceDocumentsController { @Autowired private AppUserService appUserService; + @Autowired + private AuthenticationManager authenticationManager; + @Value("${document.upload.path:gccservicedocuments}") private String documentUploadPathConfig; @@ -81,27 +92,45 @@ public class GccServiceDocumentsController { @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("doc_usrName", authResult.get("usrName")); - session.setAttribute("doc_usrRole", authResult.get("usrRole")); + 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("doc_usrName", usrName); + session.setAttribute("doc_docRole", role); // keep backward compatibility + session.setAttribute("doc_usrRole", role); session.setMaxInactiveInterval(1800); // 30 minutes session timeout response.put("result", true); - response.put("usrName", authResult.get("usrName")); - } else { + response.put("usrName", usrName); + } catch (AuthenticationException e) { response.put("result", false); - response.put("error", authResult.get("error")); + response.put("error", e.getMessage() != null ? e.getMessage() : "Invalid username or password!"); } return response; } @GetMapping("/logout") - public String logout(HttpSession session) { - session.removeAttribute("doc_usrName"); - session.removeAttribute("doc_usrRole"); + public String logout(HttpSession session, HttpServletRequest request) { + SecurityContextHolder.clearContext(); + if (session != null) { + session.removeAttribute("doc_usrName"); + session.removeAttribute("doc_usrRole"); + session.invalidate(); + } + request.getSession(true); return "redirect:/gccservicedocuments/login"; } diff --git a/src/main/java/com/gcc_manpower/gccservicepaymenttracker/controller/GccServicePaymentTrackerController.java b/src/main/java/com/gcc_manpower/gccservicepaymenttracker/controller/GccServicePaymentTrackerController.java index fb23830..5945854 100644 --- a/src/main/java/com/gcc_manpower/gccservicepaymenttracker/controller/GccServicePaymentTrackerController.java +++ b/src/main/java/com/gcc_manpower/gccservicepaymenttracker/controller/GccServicePaymentTrackerController.java @@ -9,6 +9,7 @@ import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.CacheControl; import org.springframework.http.ResponseEntity; import java.io.File; @@ -16,6 +17,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +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; + @Controller @RequestMapping("/gccservicepaymenttracker") public class GccServicePaymentTrackerController { @@ -26,6 +34,9 @@ public class GccServicePaymentTrackerController { @Autowired private AppUserService appUserService; + @Autowired + private AuthenticationManager authenticationManager; + @Value("${payment.tracker.upload.path:gccpaymenttrackerfiles}") private String paymentTrackerUploadPathConfig; @@ -50,6 +61,23 @@ public class GccServicePaymentTrackerController { return "gccservicepaymenttracker/dashboard"; } + @GetMapping("/details") + public String viewDetails(HttpSession session, Model model) { + String username = (String) session.getAttribute("pay_usrName"); + if (username == null) { + return "redirect:/gccservicepaymenttracker/login"; + } + String usrRole = (String) session.getAttribute("pay_usrRole"); + boolean isAdmin = "ADMIN".equalsIgnoreCase(usrRole); + + model.addAttribute("isLoggedIn", true); + model.addAttribute("isAdmin", isAdmin); + model.addAttribute("usrName", username); + model.addAttribute("curPage", "gccservicepaymenttracker"); + + return "gccservicepaymenttracker/details"; + } + @GetMapping("/login") public String login(HttpSession session) { return "gccservicepaymenttracker/login"; @@ -62,34 +90,55 @@ public class GccServicePaymentTrackerController { @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("pay_usrName", authResult.get("usrName")); - session.setAttribute("pay_usrRole", authResult.get("usrRole")); + 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("pay_usrName", usrName); + session.setAttribute("pay_usrRole", role); session.setMaxInactiveInterval(1800); // 30 minutes session timeout response.put("result", true); - response.put("usrName", authResult.get("usrName")); - } else { + response.put("usrName", usrName); + } catch (AuthenticationException e) { response.put("result", false); - response.put("error", authResult.get("error")); + response.put("error", e.getMessage() != null ? e.getMessage() : "Invalid username or password!"); } return response; } @PostMapping("/logout") - public String logout(HttpSession session) { - session.removeAttribute("pay_usrName"); - session.removeAttribute("pay_usrRole"); + public String logout(HttpSession session, HttpServletRequest request) { + SecurityContextHolder.clearContext(); + if (session != null) { + session.removeAttribute("pay_usrName"); + session.removeAttribute("pay_usrRole"); + session.invalidate(); + } + request.getSession(true); return "redirect:/gccservicepaymenttracker/login"; } @GetMapping("/logout") - public String logoutGet(HttpSession session) { - session.removeAttribute("pay_usrName"); - session.removeAttribute("pay_usrRole"); + public String logoutGet(HttpSession session, HttpServletRequest request) { + SecurityContextHolder.clearContext(); + if (session != null) { + session.removeAttribute("pay_usrName"); + session.removeAttribute("pay_usrRole"); + session.invalidate(); + } + request.getSession(true); return "redirect:/gccservicepaymenttracker/login"; } diff --git a/src/main/java/com/gcc_manpower/gcctonermanagement/controller/TonerController.java b/src/main/java/com/gcc_manpower/gcctonermanagement/controller/TonerController.java index 4751d63..699f342 100644 --- a/src/main/java/com/gcc_manpower/gcctonermanagement/controller/TonerController.java +++ b/src/main/java/com/gcc_manpower/gcctonermanagement/controller/TonerController.java @@ -18,8 +18,15 @@ 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; +import jakarta.servlet.http.HttpServletRequest; + +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; @Controller @RequestMapping("/gcctonermanagement") @@ -31,6 +38,9 @@ public class TonerController { @Autowired private TonerService tonerService; + @Autowired + private AuthenticationManager authenticationManager; + @Value("${toner.upload.path:gcctonermanagementfiles}") private String tonerUploadPathConfig; @@ -68,27 +78,44 @@ public class TonerController { @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")); + 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("toner_usrName", usrName); + session.setAttribute("toner_usrRole", role); session.setMaxInactiveInterval(1800); // 30 minutes session timeout response.put("result", true); - response.put("usrName", authResult.get("usrName")); - } else { + response.put("usrName", usrName); + } catch (AuthenticationException e) { response.put("result", false); - response.put("error", authResult.get("error")); + response.put("error", e.getMessage() != null ? e.getMessage() : "Invalid username or password!"); } return response; } @GetMapping("/logout") - public String logoutGet(HttpSession session) { - session.removeAttribute("toner_usrName"); - session.removeAttribute("toner_usrRole"); + public String logoutGet(HttpSession session, HttpServletRequest request) { + SecurityContextHolder.clearContext(); + if (session != null) { + session.removeAttribute("toner_usrName"); + session.removeAttribute("toner_usrRole"); + session.invalidate(); + } + request.getSession(true); return "redirect:/gcctonermanagement/login"; } @@ -286,6 +313,24 @@ public class TonerController { return tonerService.getPendingRequests(); } + @GetMapping("/api/inward/list") + @ResponseBody + public List> getInwardListData(HttpSession session) { + if (session.getAttribute("toner_usrName") == null) { + return java.util.Collections.emptyList(); + } + return tonerService.getInwardHistory(); + } + + @GetMapping("/api/requests/list") + @ResponseBody + public List> getUserRequestsListData(HttpSession session) { + if (session.getAttribute("toner_usrName") == null) { + return java.util.Collections.emptyList(); + } + return tonerService.getAllUserRequests(); + } + @GetMapping("/api/outward/list") @ResponseBody public List> getOutwardListData(HttpSession session) { diff --git a/src/main/java/com/gcc_manpower/gcctonermanagement/service/TonerService.java b/src/main/java/com/gcc_manpower/gcctonermanagement/service/TonerService.java index 548616b..fda9cd5 100644 --- a/src/main/java/com/gcc_manpower/gcctonermanagement/service/TonerService.java +++ b/src/main/java/com/gcc_manpower/gcctonermanagement/service/TonerService.java @@ -224,12 +224,45 @@ public class TonerService { } } + public List> getInwardHistory() { + String sql = "SELECT s.id, s.company_name, s.qty_registered, s.dc_upload, s.cdate, s.order_by, " + + "p.printer_name, t.model_name " + + "FROM stock_register_details s " + + "LEFT JOIN printer_model_list p ON CAST(s.pid AS SIGNED) = p.id " + + "LEFT JOIN toner_model_list t ON CAST(s.tid AS SIGNED) = t.id " + + "WHERE s.is_active = 1 AND s.is_delete = 0 " + + "ORDER BY s.id DESC"; + try { + return jdbcTemplate.queryForList(sql); + } catch (Exception e) { + System.err.println("Error fetching inward history: " + e.getMessage()); + return new ArrayList<>(); + } + } + + public List> getAllUserRequests() { + String sql = "SELECT r.id, r.req_no, r.itcell_ref_no, r.dept_id, r.qty_requested, r.qty_delivered, " + + "r.user_request_upload, r.cdate, r.updated_date, r.updated_by, " + + "p.printer_name, t.model_name " + + "FROM department_requested_details r " + + "LEFT JOIN printer_model_list p ON CAST(r.pid AS SIGNED) = p.id " + + "LEFT JOIN toner_model_list t ON CAST(r.tid AS SIGNED) = t.id " + + "WHERE r.is_active = 1 AND r.is_delete = 0 " + + "ORDER BY r.id DESC"; + try { + return jdbcTemplate.queryForList(sql); + } catch (Exception e) { + System.err.println("Error fetching user requests: " + e.getMessage()); + return new ArrayList<>(); + } + } + public List> getOutwardHistory() { - String sql = "SELECT r.id, r.req_no, r.itcell_ref_no, r.dept_id, r.qty_requested, r.qty_delivered, r.final_delivered_upload, r.updated_date, " + + String sql = "SELECT r.id, r.req_no, r.itcell_ref_no, r.dept_id, r.qty_requested, r.qty_delivered, r.final_delivered_upload, r.user_request_upload, r.cdate, r.updated_date, " + "p.printer_name, t.model_name " + "FROM department_requested_details r " + - "LEFT JOIN printer_model_list p ON r.pid = p.id " + - "LEFT JOIN toner_model_list t ON r.tid = t.id " + + "LEFT JOIN printer_model_list p ON CAST(r.pid AS SIGNED) = p.id " + + "LEFT JOIN toner_model_list t ON CAST(r.tid AS SIGNED) = t.id " + "WHERE r.is_active = 1 AND r.is_delete = 0 " + "AND r.qty_delivered IS NOT NULL AND CAST(r.qty_delivered AS SIGNED) > 0 " + "ORDER BY r.updated_date DESC"; @@ -241,3 +274,4 @@ public class TonerService { } } } + diff --git a/src/main/resources/templates/gccservicepaymenttracker/dashboard.html b/src/main/resources/templates/gccservicepaymenttracker/dashboard.html index b35a7aa..047177b 100644 --- a/src/main/resources/templates/gccservicepaymenttracker/dashboard.html +++ b/src/main/resources/templates/gccservicepaymenttracker/dashboard.html @@ -1632,11 +1632,7 @@ - - - - - + -
- -
- - - -
- -
- - - -
- -
- -
- -
- - +
+ +
- -
-
+
+
+ 0 Records +
+
+
- - -
- +
+
- - - - - - - - - - + + + + + + + + + + + - + - @@ -1751,6 +1728,10 @@
+ --> + + +