Browse Source

newly added rental management and toner management api and reports changes

master
yoganandhank 2 weeks ago
parent
commit
ac2d739cb0
  1. 14
      src/main/java/com/gcc_manpower/config/SecurityConfig.java
  2. 12
      src/main/java/com/gcc_manpower/config/WebConfig.java
  3. 518
      src/main/java/com/gcc_manpower/gccrentalmanagement/controller/RentalController.java
  4. 491
      src/main/java/com/gcc_manpower/gccrentalmanagement/service/RentalService.java
  5. 151
      src/main/java/com/gcc_manpower/gcctonermanagement/controller/TonerController.java
  6. 252
      src/main/java/com/gcc_manpower/gcctonermanagement/service/TonerService.java
  7. 22
      src/main/resources/templates/fragments/rentalheader.html
  8. 3080
      src/main/resources/templates/gccrentalmanagement/dashboard.html
  9. 429
      src/main/resources/templates/gccrentalmanagement/login.html
  10. 3682
      src/main/resources/templates/gcctonermanagement/upload.html

14
src/main/java/com/gcc_manpower/config/SecurityConfig.java

@ -72,7 +72,9 @@ public class SecurityConfig {
"/gccadjustmentmanagement/login", "/gccadjustmentmanagement/login",
"/gccadjustmentmanagement/api/login", "/gccadjustmentmanagement/api/login",
"/gcctapaldetailsmanagement/login", "/gcctapaldetailsmanagement/login",
"/gcctapaldetailsmanagement/api/login")
"/gcctapaldetailsmanagement/api/login",
"/gccrentalmanagement/login",
"/gccrentalmanagement/api/login")
.permitAll() .permitAll()
// Allow logout endpoints // Allow logout endpoints
.requestMatchers( .requestMatchers(
@ -81,7 +83,8 @@ public class SecurityConfig {
"/gccservicepaymenttracker/logout", "/gccservicepaymenttracker/logout",
"/gccservicedocuments/logout", "/gccservicedocuments/logout",
"/gccadjustmentmanagement/logout", "/gccadjustmentmanagement/logout",
"/gcctapaldetailsmanagement/logout")
"/gcctapaldetailsmanagement/logout",
"/gccrentalmanagement/logout")
.permitAll() .permitAll()
// Require authentication for all other requests // Require authentication for all other requests
.anyRequest().authenticated()) .anyRequest().authenticated())
@ -93,7 +96,8 @@ public class SecurityConfig {
"/gccservicepaymenttracker/api/login", "/gccservicepaymenttracker/api/login",
"/gccservicedocuments/api/login", "/gccservicedocuments/api/login",
"/gccadjustmentmanagement/api/login", "/gccadjustmentmanagement/api/login",
"/gcctapaldetailsmanagement/api/login"))
"/gcctapaldetailsmanagement/api/login",
"/gccrentalmanagement/api/login"))
// Session management configuration with module-aware invalid session // Session management configuration with module-aware invalid session
// redirection // redirection
.sessionManagement(session -> session .sessionManagement(session -> session
@ -111,6 +115,8 @@ public class SecurityConfig {
response.sendRedirect(request.getContextPath() + "/gccadjustmentmanagement/login"); response.sendRedirect(request.getContextPath() + "/gccadjustmentmanagement/login");
} else if (requestURI.contains("/gcctapaldetailsmanagement")) { } else if (requestURI.contains("/gcctapaldetailsmanagement")) {
response.sendRedirect(request.getContextPath() + "/gcctapaldetailsmanagement/login"); response.sendRedirect(request.getContextPath() + "/gcctapaldetailsmanagement/login");
} else if (requestURI.contains("/gccrentalmanagement")) {
response.sendRedirect(request.getContextPath() + "/gccrentalmanagement/login");
} else { } else {
response.sendRedirect(request.getContextPath() + "/login"); response.sendRedirect(request.getContextPath() + "/login");
} }
@ -129,6 +135,8 @@ public class SecurityConfig {
response.sendRedirect(request.getContextPath() + "/gccadjustmentmanagement/login"); response.sendRedirect(request.getContextPath() + "/gccadjustmentmanagement/login");
} else if (requestURI.contains("/gcctapaldetailsmanagement")) { } else if (requestURI.contains("/gcctapaldetailsmanagement")) {
response.sendRedirect(request.getContextPath() + "/gcctapaldetailsmanagement/login"); response.sendRedirect(request.getContextPath() + "/gcctapaldetailsmanagement/login");
} else if (requestURI.contains("/gccrentalmanagement")) {
response.sendRedirect(request.getContextPath() + "/gccrentalmanagement/login");
} else { } else {
response.sendRedirect(request.getContextPath() + "/login"); response.sendRedirect(request.getContextPath() + "/login");
} }

12
src/main/java/com/gcc_manpower/config/WebConfig.java

@ -27,6 +27,9 @@ public class WebConfig implements WebMvcConfigurer {
@Value("${tapal.upload.path:gcctapalfiles}") @Value("${tapal.upload.path:gcctapalfiles}")
private String tapalUploadPathConfig; private String tapalUploadPathConfig;
@Value("${rental.upload.path:gccrentalmanagementfiles}")
private String rentalUploadPathConfig;
@Override @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) { public void addResourceHandlers(ResourceHandlerRegistry registry) {
// Resolve absolute path (supports both relative and absolute paths) // Resolve absolute path (supports both relative and absolute paths)
@ -58,6 +61,15 @@ public class WebConfig implements WebMvcConfigurer {
registry.addResourceHandler("/gcctonermanagementfiles/**") registry.addResourceHandler("/gcctonermanagementfiles/**")
.addResourceLocations(tonerUploadPath); .addResourceLocations(tonerUploadPath);
// Map URL path /gccrentalmanagementfiles/** to the configured rental folder
String rentalUploadPath = Paths.get(rentalUploadPathConfig).toAbsolutePath().toUri()
.toString();
if (!rentalUploadPath.endsWith("/")) {
rentalUploadPath += "/";
}
registry.addResourceHandler("/gccrentalmanagementfiles/**")
.addResourceLocations(rentalUploadPath);
// Map URL path /gccadjustmentmanagementfiles/** to the configured adjustment // Map URL path /gccadjustmentmanagementfiles/** to the configured adjustment
// folder // folder
String adjustmentUploadPath = Paths.get(adjustmentUploadPathConfig).toAbsolutePath().toUri() String adjustmentUploadPath = Paths.get(adjustmentUploadPathConfig).toAbsolutePath().toUri()

518
src/main/java/com/gcc_manpower/gccrentalmanagement/controller/RentalController.java

@ -0,0 +1,518 @@
package com.gcc_manpower.gccrentalmanagement.controller;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
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.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.web.multipart.MultipartFile;
import com.gcc_manpower.gccrentalmanagement.service.RentalService;
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("/gccrentalmanagement")
public class RentalController {
@Autowired
private AppUserService appUserService;
@Autowired
private RentalService rentalService;
@Autowired
private AuthenticationManager authenticationManager;
@Value("${rental.upload.path:gccrentalmanagementfiles}")
private String rentalUploadPathConfig;
@GetMapping({ "", "/", "/dashboard" })
public String viewDashboard(Model model, HttpSession session) {
String username = (String) session.getAttribute("rental_usrName");
if (username == null) {
return "redirect:/gccrentalmanagement/login";
}
String usrRole = (String) session.getAttribute("rental_usrRole");
boolean isAdmin = "ADMIN".equalsIgnoreCase(usrRole);
model.addAttribute("isLoggedIn", true);
model.addAttribute("isAdmin", isAdmin);
model.addAttribute("usrName", username);
model.addAttribute("usrRole", usrRole != null ? usrRole : "USER");
model.addAttribute("curPage", "gccrentalmanagement");
return "gccrentalmanagement/dashboard";
}
@GetMapping("/login")
public String login(HttpSession session) {
String username = (String) session.getAttribute("rental_usrName");
if (username != null) {
return "redirect:/gccrentalmanagement/dashboard";
}
return "gccrentalmanagement/login";
}
@PostMapping("/api/login")
@ResponseBody
public Map<String, Object> validateLogin(
@RequestParam("usrName") String usrName,
@RequestParam("usrPass") String usrPass,
HttpSession session) {
Map<String, Object> 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("rental_usrName", usrName);
session.setAttribute("rental_usrRole", role);
session.setMaxInactiveInterval(1800); // 30 minutes session timeout
response.put("result", true);
response.put("usrName", usrName);
response.put("usrRole", role);
} 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 logoutGet(HttpSession session, HttpServletRequest request) {
SecurityContextHolder.clearContext();
if (session != null) {
session.removeAttribute("rental_usrName");
session.removeAttribute("rental_usrRole");
session.invalidate();
}
request.getSession(true);
return "redirect:/gccrentalmanagement/login";
}
@PostMapping("/logout")
public String logoutPost(HttpSession session, HttpServletRequest request) {
return logoutGet(session, request);
}
// =========================================================================
// MASTER LOOKUPS APIS
// =========================================================================
@GetMapping("/api/departments")
@ResponseBody
public List<Map<String, Object>> getDepartments(HttpSession session) {
return rentalService.getActiveDepartments();
}
@GetMapping("/api/zones")
@ResponseBody
public List<Map<String, Object>> getZones(HttpSession session) {
return rentalService.getActiveZones();
}
@GetMapping("/api/vendors")
@ResponseBody
public List<Map<String, Object>> getVendors(HttpSession session) {
return rentalService.getActiveVendors();
}
@GetMapping("/api/statuses")
@ResponseBody
public List<Map<String, Object>> getStatuses(
@RequestParam(value = "type", required = false) String type,
HttpSession session) {
return rentalService.getMasterStatuses(type);
}
// =========================================================================
// 1. WORK ORDER (WO) APIS
// =========================================================================
@GetMapping("/api/workorders")
@ResponseBody
public List<Map<String, Object>> getWorkOrders(HttpSession session) {
return rentalService.getAllWorkOrders();
}
@PostMapping("/api/workorders/save")
@ResponseBody
public Map<String, Object> saveWorkOrder(
@RequestParam("woFileNo") String woFileNo,
@RequestParam("fileSubject") String fileSubject,
@RequestParam("periodFromDate") String periodFromDate,
@RequestParam("periodToDate") String periodToDate,
@RequestParam("vendorName") String vendorName,
@RequestParam(value = "systemsQty", defaultValue = "0") Integer systemsQty,
@RequestParam(value = "systemsModel", defaultValue = "") String systemsModel,
@RequestParam(value = "printersQty", defaultValue = "0") Integer printersQty,
@RequestParam(value = "printersModel", defaultValue = "") String printersModel,
@RequestParam(value = "laptopsQty", defaultValue = "0") Integer laptopsQty,
@RequestParam(value = "laptopsModel", defaultValue = "") String laptopsModel,
@RequestParam(value = "woCopyFile", required = false) MultipartFile woCopyFile,
@RequestParam(value = "remarks", defaultValue = "") String remarks,
HttpSession session) {
Map<String, Object> response = new HashMap<>();
String username = (String) session.getAttribute("rental_usrName");
if (username == null) {
response.put("success", false);
response.put("error", "Unauthorized access. Please log in.");
return response;
}
try {
File uploadDir = new File(rentalUploadPathConfig).getAbsoluteFile();
if (!uploadDir.exists()) uploadDir.mkdirs();
String woCopyPath = null;
if (woCopyFile != null && !woCopyFile.isEmpty()) {
woCopyPath = saveUploadedFile(woCopyFile, "wo", uploadDir);
}
boolean saved = rentalService.saveWorkOrder(
woFileNo, fileSubject, periodFromDate, periodToDate, vendorName,
systemsQty, systemsModel, printersQty, printersModel,
laptopsQty, laptopsModel, woCopyPath, remarks, username);
if (saved) {
response.put("success", true);
response.put("message", "Work order registered successfully.");
} else {
response.put("success", false);
response.put("error", "Failed to save work order to database.");
}
} catch (Exception e) {
response.put("success", false);
response.put("error", "Error: " + e.getMessage());
}
return response;
}
// =========================================================================
// 2. DEPARTMENT USER REQUEST APIS
// =========================================================================
@GetMapping("/api/requests")
@ResponseBody
public List<Map<String, Object>> getRequests(HttpSession session) {
return rentalService.getAllUserRequests();
}
@PostMapping("/api/requests/save")
@ResponseBody
public Map<String, Object> saveUserRequest(
@RequestParam("tapalNo") String tapalNo,
@RequestParam("tapalDate") String tapalDate,
@RequestParam("deptId") Integer deptId,
@RequestParam(value = "zoneId", required = false) Integer zoneId,
@RequestParam(value = "reqSystemsQty", defaultValue = "0") Integer reqSystemsQty,
@RequestParam(value = "reqPrintersQty", defaultValue = "0") Integer reqPrintersQty,
@RequestParam(value = "reqLaptopsQty", defaultValue = "0") Integer reqLaptopsQty,
@RequestParam("requiredFromDate") String requiredFromDate,
@RequestParam("requiredToDate") String requiredToDate,
@RequestParam(value = "mailCopyFile", required = false) MultipartFile mailCopyFile,
@RequestParam(value = "reqStatusId", defaultValue = "1") Integer reqStatusId,
@RequestParam(value = "requestingOfficer", defaultValue = "") String requestingOfficer,
@RequestParam(value = "contactNo", defaultValue = "") String contactNo,
@RequestParam(value = "purpose", defaultValue = "") String purpose,
HttpSession session) {
Map<String, Object> response = new HashMap<>();
String username = (String) session.getAttribute("rental_usrName");
if (username == null) {
response.put("success", false);
response.put("error", "Unauthorized access. Please log in.");
return response;
}
try {
File uploadDir = new File(rentalUploadPathConfig).getAbsoluteFile();
if (!uploadDir.exists()) uploadDir.mkdirs();
String mailCopyPath = null;
if (mailCopyFile != null && !mailCopyFile.isEmpty()) {
mailCopyPath = saveUploadedFile(mailCopyFile, "request_mail", uploadDir);
}
boolean saved = rentalService.saveUserRequest(
tapalNo, tapalDate, deptId, zoneId,
reqSystemsQty, reqPrintersQty, reqLaptopsQty,
requiredFromDate, requiredToDate, mailCopyPath, reqStatusId,
requestingOfficer, contactNo, purpose, username);
if (saved) {
response.put("success", true);
response.put("message", "Department request registered successfully.");
} else {
response.put("success", false);
response.put("error", "Failed to save department request.");
}
} catch (Exception e) {
response.put("success", false);
response.put("error", "Error: " + e.getMessage());
}
return response;
}
// =========================================================================
// 3. INWARD DELIVERY CHALLAN (DC) APIS
// =========================================================================
@GetMapping("/api/inward-challans")
@ResponseBody
public List<Map<String, Object>> getInwardChallans(HttpSession session) {
return rentalService.getAllInwardChallans();
}
@PostMapping("/api/inward-challans/save")
@ResponseBody
public Map<String, Object> saveInwardChallan(
@RequestParam("woId") Integer woId,
@RequestParam("dcNo") String dcNo,
@RequestParam("dcDate") String dcDate,
@RequestParam(value = "vendorName", defaultValue = "") String vendorName,
@RequestParam(value = "inSystemsQty", defaultValue = "0") Integer inSystemsQty,
@RequestParam(value = "inPrintersQty", defaultValue = "0") Integer inPrintersQty,
@RequestParam(value = "inLaptopsQty", defaultValue = "0") Integer inLaptopsQty,
@RequestParam(value = "dcFile", required = false) MultipartFile dcFile,
@RequestParam(value = "vehicleNo", defaultValue = "") String vehicleNo,
@RequestParam(value = "receivedBy", defaultValue = "") String receivedBy,
@RequestParam(value = "remarks", defaultValue = "") String remarks,
HttpSession session) {
Map<String, Object> response = new HashMap<>();
String username = (String) session.getAttribute("rental_usrName");
if (username == null) {
response.put("success", false);
response.put("error", "Unauthorized access. Please log in.");
return response;
}
try {
File uploadDir = new File(rentalUploadPathConfig).getAbsoluteFile();
if (!uploadDir.exists()) uploadDir.mkdirs();
String dcFilePath = null;
if (dcFile != null && !dcFile.isEmpty()) {
dcFilePath = saveUploadedFile(dcFile, "inward_dc", uploadDir);
}
boolean saved = rentalService.saveInwardChallan(
woId, dcNo, dcDate, vendorName,
inSystemsQty, inPrintersQty, inLaptopsQty,
dcFilePath, vehicleNo, receivedBy, remarks, username);
if (saved) {
response.put("success", true);
response.put("message", "Inward Delivery Challan registered successfully.");
} else {
response.put("success", false);
response.put("error", "Failed to save inward Delivery Challan.");
}
} catch (Exception e) {
response.put("success", false);
response.put("error", "Error: " + e.getMessage());
}
return response;
}
// =========================================================================
// 4. ISSUED DETAILS APIS
// =========================================================================
@GetMapping("/api/issued-assets")
@ResponseBody
public List<Map<String, Object>> getIssuedAssets(HttpSession session) {
return rentalService.getAllIssuedDetails();
}
@PostMapping("/api/issued-assets/save")
@ResponseBody
public Map<String, Object> saveIssuedDetails(
@RequestParam("requestId") Integer requestId,
@RequestParam(value = "inwardDcId", required = false) Integer inwardDcId,
@RequestParam(value = "woId", required = false) Integer woId,
@RequestParam("issuedDate") String issuedDate,
@RequestParam(value = "issuedSystemsQty", defaultValue = "0") Integer issuedSystemsQty,
@RequestParam(value = "issuedPrintersQty", defaultValue = "0") Integer issuedPrintersQty,
@RequestParam(value = "issuedLaptopsQty", defaultValue = "0") Integer issuedLaptopsQty,
@RequestParam(value = "assetSerialDetails", defaultValue = "") String assetSerialDetails,
@RequestParam("issuedFromDate") String issuedFromDate,
@RequestParam("issuedToDate") String issuedToDate,
@RequestParam(value = "stockCopyFile", required = false) MultipartFile stockCopyFile,
@RequestParam(value = "custodianOfficer", defaultValue = "") String custodianOfficer,
@RequestParam(value = "contactNo", defaultValue = "") String contactNo,
@RequestParam(value = "issuedBy", defaultValue = "") String issuedBy,
HttpSession session) {
Map<String, Object> response = new HashMap<>();
String username = (String) session.getAttribute("rental_usrName");
if (username == null) {
response.put("success", false);
response.put("error", "Unauthorized access. Please log in.");
return response;
}
try {
File uploadDir = new File(rentalUploadPathConfig).getAbsoluteFile();
if (!uploadDir.exists()) uploadDir.mkdirs();
String stockCopyPath = null;
if (stockCopyFile != null && !stockCopyFile.isEmpty()) {
stockCopyPath = saveUploadedFile(stockCopyFile, "issue_stock", uploadDir);
}
boolean saved = rentalService.saveIssuedDetails(
requestId, inwardDcId, woId, issuedDate,
issuedSystemsQty, issuedPrintersQty, issuedLaptopsQty,
assetSerialDetails, issuedFromDate, issuedToDate, stockCopyPath,
custodianOfficer, contactNo, issuedBy, username);
if (saved) {
response.put("success", true);
response.put("message", "Asset issued successfully.");
} else {
response.put("success", false);
response.put("error", "Failed to register issued details.");
}
} catch (Exception e) {
response.put("success", false);
response.put("error", "Error: " + e.getMessage());
}
return response;
}
// =========================================================================
// 5. RETURN DETAILS APIS
// =========================================================================
@GetMapping("/api/returns")
@ResponseBody
public List<Map<String, Object>> getReturns(HttpSession session) {
return rentalService.getAllReturnDetails();
}
@PostMapping("/api/returns/save")
@ResponseBody
public Map<String, Object> saveReturnDetails(
@RequestParam("issueId") Integer issueId,
@RequestParam("requestId") Integer requestId,
@RequestParam("returnDate") String returnDate,
@RequestParam(value = "retSystemsQty", defaultValue = "0") Integer retSystemsQty,
@RequestParam(value = "retPrintersQty", defaultValue = "0") Integer retPrintersQty,
@RequestParam(value = "retLaptopsQty", defaultValue = "0") Integer retLaptopsQty,
@RequestParam(value = "stockCopyFile", required = false) MultipartFile stockCopyFile,
@RequestParam(value = "postReturnStatusId", defaultValue = "6") Integer postReturnStatusId,
@RequestParam(value = "conditionGrade", defaultValue = "Good") String conditionGrade,
@RequestParam(value = "penaltyCharges", defaultValue = "0.0") Double penaltyCharges,
@RequestParam(value = "receivedBy", defaultValue = "") String receivedBy,
@RequestParam(value = "remarks", defaultValue = "") String remarks,
HttpSession session) {
Map<String, Object> response = new HashMap<>();
String username = (String) session.getAttribute("rental_usrName");
if (username == null) {
response.put("success", false);
response.put("error", "Unauthorized access. Please log in.");
return response;
}
try {
File uploadDir = new File(rentalUploadPathConfig).getAbsoluteFile();
if (!uploadDir.exists()) uploadDir.mkdirs();
String stockCopyPath = null;
if (stockCopyFile != null && !stockCopyFile.isEmpty()) {
stockCopyPath = saveUploadedFile(stockCopyFile, "return_stock", uploadDir);
}
boolean saved = rentalService.saveReturnDetails(
issueId, requestId, returnDate,
retSystemsQty, retPrintersQty, retLaptopsQty,
stockCopyPath, postReturnStatusId, conditionGrade,
penaltyCharges, receivedBy, remarks, username);
if (saved) {
response.put("success", true);
response.put("message", "Asset return intake processed successfully.");
} else {
response.put("success", false);
response.put("error", "Failed to register return details.");
}
} catch (Exception e) {
response.put("success", false);
response.put("error", "Error: " + e.getMessage());
}
return response;
}
// =========================================================================
// 6. REMINDERS & DUE ALERTS API
// =========================================================================
@GetMapping("/api/reminders")
@ResponseBody
public List<Map<String, Object>> getReminders(HttpSession session) {
return rentalService.getOverdueAndDueSoonReminders();
}
// =========================================================================
// FILE UPLOAD HELPER METHODS
// =========================================================================
private String saveUploadedFile(MultipartFile file, String prefix, File uploadDir) throws Exception {
String originalFilename = file.getOriginalFilename();
String extension = "";
if (originalFilename != null && originalFilename.contains(".")) {
extension = originalFilename.substring(originalFilename.lastIndexOf("."));
}
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss_SSS").format(new Date());
String newFilename = prefix + "_" + timestamp + extension;
File targetFile = new File(uploadDir, newFilename);
try (InputStream in = file.getInputStream(); OutputStream out = new FileOutputStream(targetFile)) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
return newFilename;
}
}

491
src/main/java/com/gcc_manpower/gccrentalmanagement/service/RentalService.java

@ -0,0 +1,491 @@
package com.gcc_manpower.gccrentalmanagement.service;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
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.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class RentalService {
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(@Qualifier("mysqlItcellManagementDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public JdbcTemplate getJdbcTemplate() {
return this.jdbcTemplate;
}
// =========================================================================
// 1. MASTER LOOKUPS (Departments, Zones, Vendors, Master Statuses)
// =========================================================================
public List<Map<String, Object>> getActiveDepartments() {
String sql = "SELECT id, dept_name FROM toner_department_list WHERE (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0) ORDER BY dept_name ASC";
try {
return jdbcTemplate.queryForList(sql);
} catch (Exception e) {
return new ArrayList<>();
}
}
public List<Map<String, Object>> getActiveZones() {
String sql = "SELECT id, zone_name FROM toner_zone_list WHERE (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0) ORDER BY id ASC";
try {
return jdbcTemplate.queryForList(sql);
} catch (Exception e) {
return new ArrayList<>();
}
}
public List<Map<String, Object>> getActiveVendors() {
String sql = "SELECT id, vendor_name FROM payment_vendors_list WHERE (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0) ORDER BY vendor_name ASC";
try {
return jdbcTemplate.queryForList(sql);
} catch (Exception e) {
return new ArrayList<>();
}
}
public List<Map<String, Object>> getMasterStatuses(String statusType) {
String sql;
try {
if (statusType != null && !statusType.trim().isEmpty() && !"ALL".equalsIgnoreCase(statusType)) {
sql = "SELECT id, status_name, status_type, badge_color FROM rental_master_status_list " +
"WHERE (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0) " +
"AND status_type = ? ORDER BY id ASC";
return jdbcTemplate.queryForList(sql, statusType.toUpperCase().trim());
} else {
sql = "SELECT id, status_name, status_type, badge_color FROM rental_master_status_list " +
"WHERE (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0) ORDER BY id ASC";
return jdbcTemplate.queryForList(sql);
}
} catch (Exception e) {
return getDefaultStatusFallback(statusType);
}
}
private List<Map<String, Object>> getDefaultStatusFallback(String type) {
List<Map<String, Object>> list = new ArrayList<>();
if ("REQUEST".equalsIgnoreCase(type) || type == null) {
list.add(Map.of("id", 1, "status_name", "Pending Sanction", "status_type", "REQUEST", "badge_color",
"warning"));
list.add(Map.of("id", 2, "status_name", "Sanctioned & Approved", "status_type", "REQUEST", "badge_color",
"info"));
list.add(Map.of("id", 3, "status_name", "Issued to Dept", "status_type", "REQUEST", "badge_color",
"primary"));
list.add(Map.of("id", 4, "status_name", "Completed & Returned", "status_type", "REQUEST", "badge_color",
"success"));
list.add(Map.of("id", 5, "status_name", "Rejected", "status_type", "REQUEST", "badge_color", "danger"));
}
if ("RETURN".equalsIgnoreCase(type) || type == null) {
list.add(Map.of("id", 6, "status_name", "Completed", "status_type", "RETURN", "badge_color", "success"));
list.add(Map.of("id", 7, "status_name", "Partially Returned", "status_type", "RETURN", "badge_color",
"warning"));
list.add(
Map.of("id", 8, "status_name", "Pending Return", "status_type", "RETURN", "badge_color", "danger"));
}
return list;
}
// =========================================================================
// 2. WORK ORDER (WO) FILE CREATION & REGISTRY
// =========================================================================
@Transactional
public boolean saveWorkOrder(String woFileNo, String fileSubject, String fromDate, String toDate,
String vendorName, Integer systemsQty, String systemsModel,
Integer printersQty, String printersModel, Integer laptopsQty,
String laptopsModel, String woCopyPath, String remarks, String updatedBy) {
String sql = "INSERT INTO rental_workorder_register " +
"(wo_file_no, file_subject, period_from_date, period_to_date, vendor_name, " +
"systems_qty, systems_model_name, printers_qty, printers_model_name, " +
"laptops_qty, laptops_model_name, wo_copy_file, status, remarks, created_by, is_active, is_delete) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'Active', ?, ?, 1, 0)";
try {
int rows = jdbcTemplate.update(sql,
woFileNo != null ? woFileNo.trim() : null,
fileSubject != null ? fileSubject.trim() : null,
fromDate, toDate,
vendorName != null ? vendorName.trim() : null,
systemsQty != null ? systemsQty : 0,
systemsModel != null ? systemsModel.trim() : "",
printersQty != null ? printersQty : 0,
printersModel != null ? printersModel.trim() : "",
laptopsQty != null ? laptopsQty : 0,
laptopsModel != null ? laptopsModel.trim() : "",
woCopyPath, remarks, updatedBy);
return rows > 0;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public List<Map<String, Object>> getAllWorkOrders() {
String sql = "SELECT id, wo_file_no, file_subject, period_from_date, period_to_date, vendor_name, " +
"systems_qty, systems_model_name, printers_qty, printers_model_name, " +
"laptops_qty, laptops_model_name, (systems_qty + printers_qty + laptops_qty) AS total_units, " +
"wo_copy_file, status, remarks, created_by, created_at " +
"FROM rental_workorder_register " +
"WHERE (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0) " +
"ORDER BY id DESC";
try {
return jdbcTemplate.queryForList(sql);
} catch (Exception e) {
return new ArrayList<>();
}
}
public Map<String, Object> getWorkOrderById(int id) {
String sql = "SELECT * FROM rental_workorder_register WHERE id = ?";
try {
return jdbcTemplate.queryForMap(sql, id);
} catch (Exception e) {
return null;
}
}
// =========================================================================
// 3. DEPARTMENT USER REQUEST CREATION (Tapal, Dept, Zone, Qty, Dates)
// =========================================================================
@Transactional
public boolean saveUserRequest(String tapalNo, String tapalDate, Integer deptId, Integer zoneId,
Integer reqSystemsQty, Integer reqPrintersQty, Integer reqLaptopsQty,
String fromDate, String toDate, String mailCopyPath, Integer statusId,
String requestingOfficer, String contactNo, String purpose, String updatedBy) {
int calculatedDays = calculateDaysBetween(fromDate, toDate);
int finalStatusId = (statusId != null && statusId > 0) ? statusId : 1; // Default to 'Pending Sanction'
String sql = "INSERT INTO rental_user_request " +
"(tapal_no, tapal_date, department_id, zone_id, " +
"req_systems_qty, req_printers_qty, req_laptops_qty, " +
"required_from_date, required_to_date, calculated_days, " +
"mail_copy_file, req_status_id, requesting_officer, contact_no, purpose, " +
"created_by, is_active, is_delete) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 0)";
try {
int rows = jdbcTemplate.update(sql,
tapalNo != null ? tapalNo.trim() : null,
tapalDate,
deptId, zoneId,
reqSystemsQty != null ? reqSystemsQty : 0,
reqPrintersQty != null ? reqPrintersQty : 0,
reqLaptopsQty != null ? reqLaptopsQty : 0,
fromDate, toDate, calculatedDays,
mailCopyPath, finalStatusId,
requestingOfficer != null ? requestingOfficer.trim() : null,
contactNo != null ? contactNo.trim() : null,
purpose, updatedBy);
return rows > 0;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public List<Map<String, Object>> getAllUserRequests() {
String sql = "SELECT r.id, r.tapal_no, r.tapal_date, r.department_id, d.dept_name, " +
"r.zone_id, z.zone_name, r.req_systems_qty, r.req_printers_qty, r.req_laptops_qty, " +
"(r.req_systems_qty + r.req_printers_qty + r.req_laptops_qty) AS total_req_qty, " +
"r.required_from_date, r.required_to_date, r.calculated_days, r.mail_copy_file, " +
"r.req_status_id, COALESCE(s.status_name, 'Pending') AS status_name, " +
"COALESCE(s.badge_color, 'warning') AS badge_color, " +
"r.requesting_officer, r.contact_no, r.purpose, r.created_by, r.created_at " +
"FROM rental_user_request r " +
"LEFT JOIN toner_department_list d ON r.department_id = d.id " +
"LEFT JOIN toner_zone_list z ON r.zone_id = z.id " +
"LEFT JOIN rental_master_status_list s ON r.req_status_id = s.id " +
"WHERE (r.is_active IS NULL OR r.is_active = 1) AND (r.is_delete IS NULL OR r.is_delete = 0) " +
"ORDER BY r.id DESC";
try {
return jdbcTemplate.queryForList(sql);
} catch (Exception e) {
return new ArrayList<>();
}
}
@Transactional
public boolean updateUserRequestStatus(int requestId, int statusId, String updatedBy) {
String sql = "UPDATE rental_user_request SET req_status_id = ? WHERE id = ?";
try {
return jdbcTemplate.update(sql, statusId, requestId) > 0;
} catch (Exception e) {
return false;
}
}
// =========================================================================
// 4. DELIVERY CHALLAN (DC) - INWARD STOCK AGAINST REGISTERED WORK ORDER
// =========================================================================
@Transactional
public boolean saveInwardChallan(Integer woId, String dcNo, String dcDate, String vendorName,
Integer inSystemsQty, Integer inPrintersQty, Integer inLaptopsQty,
String dcFilePath, String vehicleNo, String receivedBy,
String remarks, String updatedBy) {
String sql = "INSERT INTO rental_inward_delivery_challan " +
"(wo_id, dc_no, dc_date, vendor_name, " +
"inward_systems_qty, inward_printers_qty, inward_laptops_qty, " +
"dc_file_path, vehicle_no, received_by, remarks, created_by, is_active, is_delete) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 0)";
try {
int rows = jdbcTemplate.update(sql,
woId,
dcNo != null ? dcNo.trim() : null,
dcDate,
vendorName != null ? vendorName.trim() : null,
inSystemsQty != null ? inSystemsQty : 0,
inPrintersQty != null ? inPrintersQty : 0,
inLaptopsQty != null ? inLaptopsQty : 0,
dcFilePath,
vehicleNo != null ? vehicleNo.trim() : null,
receivedBy != null ? receivedBy.trim() : null,
remarks, updatedBy);
return rows > 0;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public List<Map<String, Object>> getAllInwardChallans() {
String sql = "SELECT c.id, c.wo_id, w.wo_file_no, w.file_subject, c.dc_no, c.dc_date, " +
"COALESCE(c.vendor_name, w.vendor_name) AS vendor_name, " +
"c.inward_systems_qty, c.inward_printers_qty, c.inward_laptops_qty, " +
"(c.inward_systems_qty + c.inward_printers_qty + c.inward_laptops_qty) AS total_inward_qty, " +
"c.dc_file_path, c.vehicle_no, c.received_by, c.remarks, c.created_by, c.created_at " +
"FROM rental_inward_delivery_challan c " +
"LEFT JOIN rental_workorder_register w ON c.wo_id = w.id " +
"WHERE (c.is_active IS NULL OR c.is_active = 1) AND (c.is_delete IS NULL OR c.is_delete = 0) " +
"ORDER BY c.id DESC";
try {
return jdbcTemplate.queryForList(sql);
} catch (Exception e) {
return new ArrayList<>();
}
}
// =========================================================================
// 5. ISSUED DETAILS (From Inward Stock & User Request)
// =========================================================================
@Transactional
public boolean saveIssuedDetails(Integer requestId, Integer inwardDcId, Integer woId,
String issuedDate, Integer issuedSystemsQty, Integer issuedPrintersQty,
Integer issuedLaptopsQty, String assetSerialDetails,
String issuedFromDate, String issuedToDate, String stockCopyPath,
String custodianOfficer, String contactNo, String issuedBy, String updatedBy) {
int periodDays = calculateDaysBetween(issuedFromDate, issuedToDate);
String sql = "INSERT INTO rental_issued_details " +
"(request_id, inward_dc_id, wo_id, issued_date, " +
"issued_systems_qty, issued_printers_qty, issued_laptops_qty, " +
"asset_serial_details, issued_from_date, issued_to_date, issued_period_days, " +
"stock_copy_path, custodian_officer, contact_no, issued_by, status, " +
"created_by, is_active, is_delete) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'Issued', ?, 1, 0)";
try {
int rows = jdbcTemplate.update(sql,
requestId, inwardDcId, woId, issuedDate,
issuedSystemsQty != null ? issuedSystemsQty : 0,
issuedPrintersQty != null ? issuedPrintersQty : 0,
issuedLaptopsQty != null ? issuedLaptopsQty : 0,
assetSerialDetails, issuedFromDate, issuedToDate, periodDays,
stockCopyPath,
custodianOfficer != null ? custodianOfficer.trim() : null,
contactNo != null ? contactNo.trim() : null,
issuedBy != null ? issuedBy.trim() : null,
updatedBy);
if (rows > 0 && requestId != null) {
// Automatically update request status to 'Issued' (status_id = 3)
jdbcTemplate.update("UPDATE rental_user_request SET req_status_id = 3 WHERE id = ?", requestId);
}
return rows > 0;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public List<Map<String, Object>> getAllIssuedDetails() {
String sql = "SELECT i.id, i.request_id, r.tapal_no, d.dept_name, z.zone_name, " +
"i.inward_dc_id, dc.dc_no, i.wo_id, w.wo_file_no, i.issued_date, " +
"i.issued_systems_qty, i.issued_printers_qty, i.issued_laptops_qty, " +
"(i.issued_systems_qty + i.issued_printers_qty + i.issued_laptops_qty) AS total_issued_qty, " +
"i.asset_serial_details, i.issued_from_date, i.issued_to_date, i.issued_period_days, " +
"i.stock_copy_path, i.custodian_officer, i.contact_no, i.issued_by, i.status, " +
"i.created_by, i.created_at, " +
"COALESCE(ret.total_returned_qty, 0) AS total_returned_qty " +
"FROM rental_issued_details i " +
"LEFT JOIN rental_user_request r ON i.request_id = r.id " +
"LEFT JOIN toner_department_list d ON r.department_id = d.id " +
"LEFT JOIN toner_zone_list z ON r.zone_id = z.id " +
"LEFT JOIN rental_inward_delivery_challan dc ON i.inward_dc_id = dc.id " +
"LEFT JOIN rental_workorder_register w ON i.wo_id = w.id " +
"LEFT JOIN (SELECT issue_id, SUM(returned_systems_qty + returned_printers_qty + returned_laptops_qty) AS total_returned_qty "
+
" FROM rental_return_details WHERE is_delete = 0 GROUP BY issue_id) ret ON i.id = ret.issue_id "
+
"WHERE (i.is_active IS NULL OR i.is_active = 1) AND (i.is_delete IS NULL OR i.is_delete = 0) " +
"ORDER BY i.id DESC";
try {
return jdbcTemplate.queryForList(sql);
} catch (Exception e) {
return new ArrayList<>();
}
}
// =========================================================================
// 6. RETURN DETAILS (Return Date, Returned Qty, Stock Copy, Status)
// =========================================================================
@Transactional
public boolean saveReturnDetails(Integer issueId, Integer requestId, String returnDate,
Integer retSystemsQty, Integer retPrintersQty, Integer retLaptopsQty,
String stockCopyPath, Integer postReturnStatusId, String conditionGrade,
Double penaltyCharges, String receivedBy, String remarks, String updatedBy) {
int finalStatusId = (postReturnStatusId != null && postReturnStatusId > 0) ? postReturnStatusId : 6; // Default
// to
// 'Completed'
String sql = "INSERT INTO rental_return_details " +
"(issue_id, request_id, return_date, " +
"returned_systems_qty, returned_printers_qty, returned_laptops_qty, " +
"stock_copy_path, post_return_status_id, condition_grade, penalty_charges, " +
"received_by, remarks, created_by, is_active, is_delete) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 0)";
try {
int rows = jdbcTemplate.update(sql,
issueId, requestId, returnDate,
retSystemsQty != null ? retSystemsQty : 0,
retPrintersQty != null ? retPrintersQty : 0,
retLaptopsQty != null ? retLaptopsQty : 0,
stockCopyPath, finalStatusId,
conditionGrade != null ? conditionGrade.trim() : "Good",
penaltyCharges != null ? penaltyCharges : 0.0,
receivedBy != null ? receivedBy.trim() : null,
remarks, updatedBy);
if (rows > 0) {
// Update issued details status
String postStatusText = (finalStatusId == 6) ? "Returned - Completed" : "Partially Returned";
if (issueId != null) {
jdbcTemplate.update("UPDATE rental_issued_details SET status = ? WHERE id = ?", postStatusText,
issueId);
}
if (requestId != null && finalStatusId == 6) {
jdbcTemplate.update("UPDATE rental_user_request SET req_status_id = 4 WHERE id = ?", requestId); // 4
// =
// Completed
}
}
return rows > 0;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public List<Map<String, Object>> getAllReturnDetails() {
String sql = "SELECT rt.id, rt.issue_id, rt.request_id, r.tapal_no, d.dept_name, z.zone_name, " +
"iss.custodian_officer, iss.issued_to_date, rt.return_date, " +
"rt.returned_systems_qty, rt.returned_printers_qty, rt.returned_laptops_qty, " +
"(rt.returned_systems_qty + rt.returned_printers_qty + rt.returned_laptops_qty) AS total_returned_qty, "
+
"rt.stock_copy_path, rt.post_return_status_id, " +
"COALESCE(s.status_name, 'Completed') AS post_return_status_name, " +
"COALESCE(s.badge_color, 'success') AS badge_color, " +
"rt.condition_grade, rt.penalty_charges, rt.received_by, rt.remarks, " +
"rt.created_by, rt.created_at " +
"FROM rental_return_details rt " +
"LEFT JOIN rental_issued_details iss ON rt.issue_id = iss.id " +
"LEFT JOIN rental_user_request r ON rt.request_id = r.id " +
"LEFT JOIN toner_department_list d ON r.department_id = d.id " +
"LEFT JOIN toner_zone_list z ON r.zone_id = z.id " +
"LEFT JOIN rental_master_status_list s ON rt.post_return_status_id = s.id " +
"WHERE (rt.is_active IS NULL OR rt.is_active = 1) AND (rt.is_delete IS NULL OR rt.is_delete = 0) " +
"ORDER BY rt.id DESC";
try {
return jdbcTemplate.queryForList(sql);
} catch (Exception e) {
return new ArrayList<>();
}
}
// =========================================================================
// 7. REAL-TIME DATE MATH & REMINDERS CALCULATION
// =========================================================================
public List<Map<String, Object>> getOverdueAndDueSoonReminders() {
List<Map<String, Object>> issuedList = getAllIssuedDetails();
List<Map<String, Object>> result = new ArrayList<>();
LocalDate today = LocalDate.now();
for (Map<String, Object> item : issuedList) {
Object dueDateObj = item.get("issued_to_date");
if (dueDateObj == null)
continue;
try {
LocalDate dueDate = LocalDate.parse(dueDateObj.toString());
long daysDiff = ChronoUnit.DAYS.between(today, dueDate);
Map<String, Object> alert = new HashMap<>(item);
alert.put("daysDiff", daysDiff);
if (daysDiff < 0) {
alert.put("calculated_status", "OVERDUE");
alert.put("overdue_days", Math.abs(daysDiff));
alert.put("badge_class", "status-overdue");
alert.put("status_label", "OVERDUE by " + Math.abs(daysDiff) + " Days");
result.add(alert);
} else if (daysDiff <= 7) {
alert.put("calculated_status", "DUE_SOON");
alert.put("due_days", daysDiff);
alert.put("badge_class", "status-due-soon");
alert.put("status_label", "Due in " + daysDiff + " Days");
result.add(alert);
}
} catch (Exception ignored) {
}
}
return result;
}
private int calculateDaysBetween(String fromDateStr, String toDateStr) {
if (fromDateStr == null || toDateStr == null)
return 0;
try {
LocalDate from = LocalDate.parse(fromDateStr);
LocalDate to = LocalDate.parse(toDateStr);
long days = ChronoUnit.DAYS.between(from, to) + 1;
return (int) Math.max(days, 0);
} catch (Exception e) {
return 0;
}
}
}

151
src/main/java/com/gcc_manpower/gcctonermanagement/controller/TonerController.java

@ -164,6 +164,8 @@ public class TonerController {
@RequestParam("refNo") String refNo, @RequestParam("refNo") String refNo,
@RequestParam("companyName") String companyName, @RequestParam("companyName") String companyName,
@RequestParam("itemsJson") String itemsJson, @RequestParam("itemsJson") String itemsJson,
@RequestParam(value = "dcNo", required = false) String dcNo,
@RequestParam(value = "dcDate", required = false) String dcDate,
@RequestParam(value = "dcFile", required = false) MultipartFile dcFile, @RequestParam(value = "dcFile", required = false) MultipartFile dcFile,
HttpSession session) { HttpSession session) {
@ -211,7 +213,7 @@ public class TonerController {
String dcPath = saveUploadedFile(dcFile, "dc", uploadDir); String dcPath = saveUploadedFile(dcFile, "dc", uploadDir);
boolean saved = tonerService.saveInwardRegister( boolean saved = tonerService.saveInwardRegister(
refNo.trim(), companyName.trim(), items, dcPath, updatedBy);
refNo.trim(), companyName.trim(), items, dcPath, dcNo, dcDate, updatedBy);
if (saved) { if (saved) {
response.put("success", true); response.put("success", true);
@ -236,6 +238,7 @@ public class TonerController {
@RequestParam("deptId") String deptId, @RequestParam("deptId") String deptId,
@RequestParam(value = "zoneId", required = false) String zoneId, @RequestParam(value = "zoneId", required = false) String zoneId,
@RequestParam("itemsJson") String itemsJson, @RequestParam("itemsJson") String itemsJson,
@RequestParam(value = "requestDate", required = false) String requestDate,
@RequestParam(value = "userRequestFile", required = false) MultipartFile userRequestFile, @RequestParam(value = "userRequestFile", required = false) MultipartFile userRequestFile,
HttpSession session) { HttpSession session) {
@ -284,7 +287,7 @@ public class TonerController {
String safeZoneId = (zoneId != null && !zoneId.trim().isEmpty()) ? zoneId.trim() : null; String safeZoneId = (zoneId != null && !zoneId.trim().isEmpty()) ? zoneId.trim() : null;
boolean saved = tonerService.saveUserRequest( boolean saved = tonerService.saveUserRequest(
itcellRefNo.trim(), deptId.trim(), safeZoneId, items, urPath, updatedBy);
itcellRefNo.trim(), deptId.trim(), safeZoneId, items, urPath, requestDate, updatedBy);
if (saved) { if (saved) {
response.put("success", true); response.put("success", true);
@ -312,6 +315,7 @@ public class TonerController {
@RequestParam("pid") int pid, @RequestParam("pid") int pid,
@RequestParam("tid") int tid, @RequestParam("tid") int tid,
@RequestParam("qtyRequested") int qtyRequested, @RequestParam("qtyRequested") int qtyRequested,
@RequestParam(value = "requestDate", required = false) String requestDate,
@RequestParam(value = "userRequestFile", required = false) MultipartFile userRequestFile, @RequestParam(value = "userRequestFile", required = false) MultipartFile userRequestFile,
HttpSession session) { HttpSession session) {
@ -364,7 +368,8 @@ public class TonerController {
String safeZoneId = (zoneId != null && !zoneId.trim().isEmpty()) ? zoneId.trim() : null; String safeZoneId = (zoneId != null && !zoneId.trim().isEmpty()) ? zoneId.trim() : null;
boolean updated = tonerService.updateUserRequest( boolean updated = tonerService.updateUserRequest(
id, itcellRefNo.trim(), deptId.trim(), safeZoneId, pid, tid, qtyRequested, urPath, updatedBy);
id, itcellRefNo.trim(), deptId.trim(), safeZoneId, pid, tid, qtyRequested, urPath, requestDate,
updatedBy);
if (updated) { if (updated) {
response.put("success", true); response.put("success", true);
@ -387,8 +392,11 @@ public class TonerController {
@PostMapping("/api/outward") @PostMapping("/api/outward")
@ResponseBody @ResponseBody
public Map<String, Object> uploadOutward( public Map<String, Object> uploadOutward(
@RequestParam("id") int id,
@RequestParam("qtyIssued") String qtyIssued,
@RequestParam(value = "id", required = false) Integer id,
@RequestParam(value = "ids", required = false) String idsJson,
@RequestParam(value = "qtyIssued", required = false) String qtyIssued,
@RequestParam(value = "itemsJson", required = false) String itemsJson,
@RequestParam(value = "outwardDate", required = false) String outwardDate,
@RequestParam(value = "finalDeliveredFile", required = false) MultipartFile finalDeliveredFile, @RequestParam(value = "finalDeliveredFile", required = false) MultipartFile finalDeliveredFile,
@RequestParam(value = "userPhotoFile", required = false) MultipartFile userPhotoFile, @RequestParam(value = "userPhotoFile", required = false) MultipartFile userPhotoFile,
@RequestParam(value = "userPhotoBase64", required = false) String userPhotoBase64, @RequestParam(value = "userPhotoBase64", required = false) String userPhotoBase64,
@ -412,13 +420,6 @@ public class TonerController {
response.put("error", "Final Delivered file must be a PDF."); response.put("error", "Final Delivered file must be a PDF.");
return response; return response;
} }
boolean hasPhoto = (userPhotoFile != null && !userPhotoFile.isEmpty())
|| (userPhotoBase64 != null && !userPhotoBase64.trim().isEmpty());
if (!hasPhoto) {
response.put("success", false);
response.put("error", "Receiver / User photo is mandatory.");
return response;
}
} }
if (userPhotoFile != null && !userPhotoFile.isEmpty() && !isImageFile(userPhotoFile)) { if (userPhotoFile != null && !userPhotoFile.isEmpty() && !isImageFile(userPhotoFile)) {
@ -427,51 +428,62 @@ public class TonerController {
return response; return response;
} }
Map<String, Object> req = tonerService.getUserRequestById(id);
if (req == null) {
response.put("success", false);
response.put("error", "Invalid or non-existent request ID: " + id);
return response;
}
ObjectMapper mapper = new ObjectMapper();
boolean isInitialDelivery = (finalDeliveredFile == null || finalDeliveredFile.isEmpty()) && boolean isInitialDelivery = (finalDeliveredFile == null || finalDeliveredFile.isEmpty()) &&
(userPhotoFile == null || userPhotoFile.isEmpty()) && (userPhotoFile == null || userPhotoFile.isEmpty()) &&
(userPhotoBase64 == null || userPhotoBase64.trim().isEmpty()); (userPhotoBase64 == null || userPhotoBase64.trim().isEmpty());
if (isInitialDelivery) {
int issueQty = 0;
try { try {
issueQty = Integer.parseInt(qtyIssued.trim());
} catch (Exception e) {
if (isInitialDelivery) {
List<Map<String, Object>> items = new ArrayList<>();
if (itemsJson != null && !itemsJson.trim().isEmpty()) {
items = mapper.readValue(itemsJson, new TypeReference<List<Map<String, Object>>>() {
});
} else if (id != null && qtyIssued != null) {
Map<String, Object> single = new HashMap<>();
single.put("id", id);
single.put("qtyIssued", qtyIssued);
items.add(single);
}
if (items == null || items.isEmpty()) {
response.put("success", false); response.put("success", false);
response.put("error", "Invalid quantity issued value.");
response.put("error", "Please enter quantity to issue for at least one model.");
return response; return response;
} }
if (issueQty <= 0) {
// Validate each item
for (Map<String, Object> itm : items) {
Integer itmId = parseIntegerSafely(itm.get("id"));
Integer itmQty = parseIntegerSafely(itm.get("qtyIssued"));
if (itmId == null || itmQty == null || itmQty <= 0)
continue;
Map<String, Object> req = tonerService.getUserRequestById(itmId);
if (req == null) {
response.put("success", false); response.put("success", false);
response.put("error", "Quantity issued must be greater than zero.");
response.put("error", "Invalid or non-existent request ID: " + itmId);
return response; return response;
} }
String pid = String.valueOf(req.get("pid")); String pid = String.valueOf(req.get("pid"));
String tid = String.valueOf(req.get("tid")); String tid = String.valueOf(req.get("tid"));
String modelName = req.get("model_name") != null ? String.valueOf(req.get("model_name")) : "Toner"; String modelName = req.get("model_name") != null ? String.valueOf(req.get("model_name")) : "Toner";
String printerName = req.get("printer_name") != null ? String.valueOf(req.get("printer_name")) : "Printer";
String printerName = req.get("printer_name") != null ? String.valueOf(req.get("printer_name"))
: "Printer";
int availableStock = tonerService.getAvailableStockForModel(pid, tid); int availableStock = tonerService.getAvailableStockForModel(pid, tid);
if (availableStock <= 0) { if (availableStock <= 0) {
response.put("success", false); response.put("success", false);
response.put("error", "Cannot issue: No inward stock available for " + printerName + " - " + modelName
+ ". Please register inward stock before issuing outward delivery.");
response.put("error",
"Cannot issue: No inward stock available for " + printerName + " - " + modelName + ".");
return response; return response;
} }
if (issueQty > availableStock) {
if (itmQty > availableStock) {
response.put("success", false); response.put("success", false);
response.put("error", response.put("error",
"Cannot issue: Quantity to issue (" + issueQty + ") exceeds available inward stock ("
"Cannot issue: Quantity to issue (" + itmQty + ") exceeds available inward stock ("
+ availableStock + ") for " + printerName + " - " + modelName + "."); + availableStock + ") for " + printerName + " - " + modelName + ".");
return response; return response;
} }
@ -479,25 +491,60 @@ public class TonerController {
int requestedQty = 0; int requestedQty = 0;
int alreadyDelivered = 0; int alreadyDelivered = 0;
try { try {
if (req.get("qty_requested") != null) {
if (req.get("qty_requested") != null)
requestedQty = Integer.parseInt(String.valueOf(req.get("qty_requested"))); requestedQty = Integer.parseInt(String.valueOf(req.get("qty_requested")));
}
if (req.get("qty_delivered") != null) {
if (req.get("qty_delivered") != null)
alreadyDelivered = Integer.parseInt(String.valueOf(req.get("qty_delivered"))); alreadyDelivered = Integer.parseInt(String.valueOf(req.get("qty_delivered")));
}
} catch (Exception ignored) { } catch (Exception ignored) {
} }
int remainingReq = Math.max(0, requestedQty - alreadyDelivered); int remainingReq = Math.max(0, requestedQty - alreadyDelivered);
if (issueQty > remainingReq) {
if (itmQty > remainingReq) {
response.put("success", false); response.put("success", false);
response.put("error", "Cannot issue: Quantity to issue (" + issueQty
+ ") exceeds remaining requested quantity (" + remainingReq + ").");
response.put("error",
"Cannot issue: Quantity to issue (" + itmQty
+ ") exceeds remaining requested quantity (" + remainingReq + ") for "
+ printerName + " - " + modelName + ".");
return response; return response;
} }
} }
boolean saved = tonerService.saveOutwardRegisterBulk(items, outwardDate, updatedBy);
if (saved) {
response.put("success", true);
response.put("message", "Outward delivery recorded successfully.");
} else {
response.put("success", false);
response.put("error", "Failed to update outward details in database.");
}
return response;
} else {
// Uploading Proof / Acknowledgement / Photo
List<Integer> targetIds = new ArrayList<>();
if (idsJson != null && !idsJson.trim().isEmpty()) {
try { try {
if (idsJson.trim().startsWith("[")) {
targetIds = mapper.readValue(idsJson, new TypeReference<List<Integer>>() {
});
} else {
for (String s : idsJson.split(",")) {
if (!s.trim().isEmpty())
targetIds.add(Integer.parseInt(s.trim()));
}
}
} catch (Exception ignored) {
}
}
if (targetIds.isEmpty() && id != null) {
targetIds.add(id);
}
if (targetIds.isEmpty()) {
response.put("success", false);
response.put("error", "No request ID specified for uploading proof.");
return response;
}
File uploadDir = new File(tonerUploadPathConfig).getAbsoluteFile(); File uploadDir = new File(tonerUploadPathConfig).getAbsoluteFile();
if (!uploadDir.exists()) { if (!uploadDir.exists()) {
uploadDir.mkdirs(); uploadDir.mkdirs();
@ -511,25 +558,25 @@ public class TonerController {
photoPath = saveBase64Image(userPhotoBase64, "receiver_photo", uploadDir); photoPath = saveBase64Image(userPhotoBase64, "receiver_photo", uploadDir);
} }
boolean saved = tonerService.saveOutwardRegister(
id, qtyIssued.trim(), fdPath, photoPath, updatedBy);
boolean saved = tonerService.updateOutwardDeliveryFiles(targetIds, fdPath, photoPath, updatedBy);
if (saved) { if (saved) {
response.put("success", true); response.put("success", true);
response.put("message", "Outward delivery recorded successfully.");
response.put("message", "Outward delivery proof uploaded successfully.");
} else { } else {
deleteFileIfExists(fdPath, uploadDir); deleteFileIfExists(fdPath, uploadDir);
deleteFileIfExists(photoPath, uploadDir); deleteFileIfExists(photoPath, uploadDir);
response.put("success", false); response.put("success", false);
response.put("error", "Failed to update outward details in the database.");
response.put("error", "Failed to update outward delivery proof.");
}
return response;
} }
} catch (Exception e) { } catch (Exception e) {
response.put("success", false); response.put("success", false);
response.put("error", "An error occurred: " + e.getMessage()); response.put("error", "An error occurred: " + e.getMessage());
e.printStackTrace(); e.printStackTrace();
}
return response; return response;
} }
}
@PostMapping("/api/workorder") @PostMapping("/api/workorder")
@ResponseBody @ResponseBody
@ -663,6 +710,16 @@ public class TonerController {
return tonerService.getOutwardHistory(); return tonerService.getOutwardHistory();
} }
private Integer parseIntegerSafely(Object val) {
if (val == null)
return null;
try {
return Integer.parseInt(String.valueOf(val).trim());
} catch (Exception e) {
return null;
}
}
private boolean isPdfFile(MultipartFile file) { private boolean isPdfFile(MultipartFile file) {
String originalFilename = file.getOriginalFilename(); String originalFilename = file.getOriginalFilename();
if (originalFilename == null) if (originalFilename == null)
@ -741,11 +798,11 @@ public class TonerController {
@GetMapping("/api/workorders/active") @GetMapping("/api/workorders/active")
@ResponseBody @ResponseBody
public List<String> getActiveWorkorderRefNos(HttpSession session) {
public List<Map<String, Object>> getActiveWorkorderRefNos(HttpSession session) {
if (session.getAttribute("toner_usrName") == null) { if (session.getAttribute("toner_usrName") == null) {
return new ArrayList<>(); return new ArrayList<>();
} }
return tonerService.getActiveWorkorderRefNos();
return tonerService.getActiveWorkorders();
} }
@GetMapping("/api/workorders/items") @GetMapping("/api/workorders/items")

252
src/main/java/com/gcc_manpower/gcctonermanagement/service/TonerService.java

@ -12,6 +12,7 @@ import java.util.Map;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.GeneratedKeyHolder;
@ -61,6 +62,21 @@ public class TonerService {
return map; return map;
} }
private Map<String, String> getTonerPartCodeMap() {
Map<String, String> map = new HashMap<>();
try {
List<Map<String, Object>> list = jdbcTemplate.queryForList(
"SELECT id, part_code FROM toner_model_list WHERE (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0)");
for (Map<String, Object> row : list) {
if (row.get("id") != null && row.get("part_code") != null) {
map.put(String.valueOf(row.get("id")).trim(), String.valueOf(row.get("part_code")).trim());
}
}
} catch (Exception ignored) {
}
return map;
}
private Map<String, String> getDepartmentMap() { private Map<String, String> getDepartmentMap() {
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
try { try {
@ -225,7 +241,8 @@ public class TonerService {
// ================ Adding department & toners & printers ================ // ================ Adding department & toners & printers ================
public boolean savenewdepartment(String department) { public boolean savenewdepartment(String department) {
if (department == null || department.trim().isEmpty()) return false;
if (department == null || department.trim().isEmpty())
return false;
String cleanDept = department.trim(); String cleanDept = department.trim();
try { try {
String sql = "INSERT INTO toner_department_list (dept_name, is_active, is_delete) VALUES (?, 1, 0)"; String sql = "INSERT INTO toner_department_list (dept_name, is_active, is_delete) VALUES (?, 1, 0)";
@ -250,7 +267,8 @@ public class TonerService {
} }
public boolean savetonermodel(int pid, String modelname, String partcode) { public boolean savetonermodel(int pid, String modelname, String partcode) {
if (pid <= 0 || modelname == null || modelname.trim().isEmpty()) return false;
if (pid <= 0 || modelname == null || modelname.trim().isEmpty())
return false;
String cleanModel = modelname.trim(); String cleanModel = modelname.trim();
String cleanPart = (partcode != null && !partcode.trim().isEmpty()) ? partcode.trim() : null; String cleanPart = (partcode != null && !partcode.trim().isEmpty()) ? partcode.trim() : null;
try { try {
@ -270,7 +288,8 @@ public class TonerService {
} }
public boolean saveprintermodel(String printermodel) { public boolean saveprintermodel(String printermodel) {
if (printermodel == null || printermodel.trim().isEmpty()) return false;
if (printermodel == null || printermodel.trim().isEmpty())
return false;
String cleanPrinter = printermodel.trim(); String cleanPrinter = printermodel.trim();
try { try {
String sql = "INSERT INTO toner_printer_model_list (printer_name, is_active, is_delete) VALUES (?, 1, 0)"; String sql = "INSERT INTO toner_printer_model_list (printer_name, is_active, is_delete) VALUES (?, 1, 0)";
@ -289,7 +308,8 @@ public class TonerService {
} }
public boolean updatePrinterModel(int id, String printermodel) { public boolean updatePrinterModel(int id, String printermodel) {
if (id <= 0 || printermodel == null || printermodel.trim().isEmpty()) return false;
if (id <= 0 || printermodel == null || printermodel.trim().isEmpty())
return false;
String cleanPrinter = printermodel.trim(); String cleanPrinter = printermodel.trim();
try { try {
String sql = "UPDATE toner_printer_model_list SET printer_name = ? WHERE id = ?"; String sql = "UPDATE toner_printer_model_list SET printer_name = ? WHERE id = ?";
@ -301,7 +321,8 @@ public class TonerService {
} }
public boolean updateTonerModel(int id, int pid, String modelname, String partcode) { public boolean updateTonerModel(int id, int pid, String modelname, String partcode) {
if (id <= 0 || pid <= 0 || modelname == null || modelname.trim().isEmpty()) return false;
if (id <= 0 || pid <= 0 || modelname == null || modelname.trim().isEmpty())
return false;
String cleanModel = modelname.trim(); String cleanModel = modelname.trim();
String cleanPart = (partcode != null && !partcode.trim().isEmpty()) ? partcode.trim() : null; String cleanPart = (partcode != null && !partcode.trim().isEmpty()) ? partcode.trim() : null;
try { try {
@ -314,7 +335,8 @@ public class TonerService {
} }
public boolean updateDepartment(int id, String department) { public boolean updateDepartment(int id, String department) {
if (id <= 0 || department == null || department.trim().isEmpty()) return false;
if (id <= 0 || department == null || department.trim().isEmpty())
return false;
String cleanDept = department.trim(); String cleanDept = department.trim();
try { try {
String sql = "UPDATE toner_department_list SET dept_name = ? WHERE id = ?"; String sql = "UPDATE toner_department_list SET dept_name = ? WHERE id = ?";
@ -331,7 +353,8 @@ public class TonerService {
} }
public boolean deletePrinterModel(int id) { public boolean deletePrinterModel(int id) {
if (id <= 0) return false;
if (id <= 0)
return false;
try { try {
String sql = "UPDATE toner_printer_model_list SET is_active = 0, is_delete = 1 WHERE id = ?"; String sql = "UPDATE toner_printer_model_list SET is_active = 0, is_delete = 1 WHERE id = ?";
return jdbcTemplate.update(sql, id) > 0; return jdbcTemplate.update(sql, id) > 0;
@ -342,7 +365,8 @@ public class TonerService {
} }
public boolean restorePrinterModel(int id) { public boolean restorePrinterModel(int id) {
if (id <= 0) return false;
if (id <= 0)
return false;
try { try {
String sql = "UPDATE toner_printer_model_list SET is_active = 1, is_delete = 0 WHERE id = ?"; String sql = "UPDATE toner_printer_model_list SET is_active = 1, is_delete = 0 WHERE id = ?";
return jdbcTemplate.update(sql, id) > 0; return jdbcTemplate.update(sql, id) > 0;
@ -353,7 +377,8 @@ public class TonerService {
} }
public boolean deleteTonerModel(int id) { public boolean deleteTonerModel(int id) {
if (id <= 0) return false;
if (id <= 0)
return false;
try { try {
String sql = "UPDATE toner_model_list SET is_active = 0, is_delete = 1 WHERE id = ?"; String sql = "UPDATE toner_model_list SET is_active = 0, is_delete = 1 WHERE id = ?";
return jdbcTemplate.update(sql, id) > 0; return jdbcTemplate.update(sql, id) > 0;
@ -364,7 +389,8 @@ public class TonerService {
} }
public boolean restoreTonerModel(int id) { public boolean restoreTonerModel(int id) {
if (id <= 0) return false;
if (id <= 0)
return false;
try { try {
String sql = "UPDATE toner_model_list SET is_active = 1, is_delete = 0 WHERE id = ?"; String sql = "UPDATE toner_model_list SET is_active = 1, is_delete = 0 WHERE id = ?";
return jdbcTemplate.update(sql, id) > 0; return jdbcTemplate.update(sql, id) > 0;
@ -375,7 +401,8 @@ public class TonerService {
} }
public boolean deleteDepartment(int id) { public boolean deleteDepartment(int id) {
if (id <= 0) return false;
if (id <= 0)
return false;
try { try {
String sql = "UPDATE toner_department_list SET is_active = 0, is_delete = 1 WHERE id = ?"; String sql = "UPDATE toner_department_list SET is_active = 0, is_delete = 1 WHERE id = ?";
return jdbcTemplate.update(sql, id) > 0; return jdbcTemplate.update(sql, id) > 0;
@ -386,7 +413,8 @@ public class TonerService {
} }
public boolean restoreDepartment(int id) { public boolean restoreDepartment(int id) {
if (id <= 0) return false;
if (id <= 0)
return false;
try { try {
String sql = "UPDATE toner_department_list SET is_active = 1, is_delete = 0 WHERE id = ?"; String sql = "UPDATE toner_department_list SET is_active = 1, is_delete = 0 WHERE id = ?";
return jdbcTemplate.update(sql, id) > 0; return jdbcTemplate.update(sql, id) > 0;
@ -417,14 +445,17 @@ public class TonerService {
try { try {
String sql; String sql;
if ("deleted".equalsIgnoreCase(status)) { if ("deleted".equalsIgnoreCase(status)) {
sql = "SELECT t.id, t.pid, t.model_name, t.part_code, p.printer_name, t.is_active, t.is_delete FROM toner_model_list t " +
sql = "SELECT t.id, t.pid, t.model_name, t.part_code, p.printer_name, t.is_active, t.is_delete FROM toner_model_list t "
+
"LEFT JOIN toner_printer_model_list p ON t.pid = p.id " + "LEFT JOIN toner_printer_model_list p ON t.pid = p.id " +
"WHERE (t.is_delete = 1 OR t.is_active = 0) ORDER BY t.id DESC"; "WHERE (t.is_delete = 1 OR t.is_active = 0) ORDER BY t.id DESC";
} else if ("all".equalsIgnoreCase(status)) { } else if ("all".equalsIgnoreCase(status)) {
sql = "SELECT t.id, t.pid, t.model_name, t.part_code, p.printer_name, t.is_active, t.is_delete FROM toner_model_list t " +
sql = "SELECT t.id, t.pid, t.model_name, t.part_code, p.printer_name, t.is_active, t.is_delete FROM toner_model_list t "
+
"LEFT JOIN toner_printer_model_list p ON t.pid = p.id ORDER BY p.printer_name ASC, t.model_name ASC"; "LEFT JOIN toner_printer_model_list p ON t.pid = p.id ORDER BY p.printer_name ASC, t.model_name ASC";
} else { } else {
sql = "SELECT t.id, t.pid, t.model_name, t.part_code, p.printer_name, t.is_active, t.is_delete FROM toner_model_list t " +
sql = "SELECT t.id, t.pid, t.model_name, t.part_code, p.printer_name, t.is_active, t.is_delete FROM toner_model_list t "
+
"LEFT JOIN toner_printer_model_list p ON t.pid = p.id " + "LEFT JOIN toner_printer_model_list p ON t.pid = p.id " +
"WHERE (t.is_active IS NULL OR t.is_active = 1) AND (t.is_delete IS NULL OR t.is_delete = 0) " + "WHERE (t.is_active IS NULL OR t.is_active = 1) AND (t.is_delete IS NULL OR t.is_delete = 0) " +
"ORDER BY p.printer_name ASC, t.model_name ASC"; "ORDER BY p.printer_name ASC, t.model_name ASC";
@ -535,12 +566,14 @@ public class TonerService {
// ================= INWARD STOCK REGISTER ================= // ================= INWARD STOCK REGISTER =================
@Transactional @Transactional
public boolean saveInwardRegister(String refNo, String companyName, List<Map<String, Object>> items, public boolean saveInwardRegister(String refNo, String companyName, List<Map<String, Object>> items,
String dcUpload, String username) {
String dcUpload, String dcNo, String dcDate, String username) {
String sql = "INSERT INTO toner_stock_register_details " + String sql = "INSERT INTO toner_stock_register_details " +
"(ref_no, company_name, pid, tid, qty_registered, dc_upload, cdate, updated_date, updated_by, is_active, is_delete, request_id) "
"(ref_no, company_name, pid, tid, qty_registered, dc_upload, dc_no, dc_date, cdate, updated_date, updated_by, is_active, is_delete, request_id) "
+ +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 0, ?)";
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 0, ?)";
Timestamp now = new Timestamp(System.currentTimeMillis()); Timestamp now = new Timestamp(System.currentTimeMillis());
String finalDcNo = (dcNo != null && !dcNo.trim().isEmpty()) ? dcNo.trim() : null;
String finalDcDate = (dcDate != null && !dcDate.trim().isEmpty()) ? dcDate.trim() : null;
try { try {
for (Map<String, Object> item : items) { for (Map<String, Object> item : items) {
Integer pidVal = parseIntegerSafely(item.get("pid")); Integer pidVal = parseIntegerSafely(item.get("pid"));
@ -558,7 +591,7 @@ public class TonerService {
Integer requestId = parseIntegerSafely(item.get("requestId")); Integer requestId = parseIntegerSafely(item.get("requestId"));
jdbcTemplate.update(sql, refNo, companyName, String.valueOf(pid), String.valueOf(tid), jdbcTemplate.update(sql, refNo, companyName, String.valueOf(pid), String.valueOf(tid),
String.valueOf(qtyVal), dcUpload, now, now, username, requestId);
String.valueOf(qtyVal), dcUpload, finalDcNo, finalDcDate, now, now, username, requestId);
} }
return true; return true;
} catch (Exception e) { } catch (Exception e) {
@ -566,6 +599,18 @@ public class TonerService {
} }
} }
@Transactional
public boolean saveInwardRegister(String refNo, String companyName, List<Map<String, Object>> items,
String dcUpload, String dcDate, String username) {
return saveInwardRegister(refNo, companyName, items, dcUpload, null, dcDate, username);
}
@Transactional
public boolean saveInwardRegister(String refNo, String companyName, List<Map<String, Object>> items,
String dcUpload, String username) {
return saveInwardRegister(refNo, companyName, items, dcUpload, null, null, username);
}
public List<Map<String, Object>> getInwardHistory() { public List<Map<String, Object>> getInwardHistory() {
try { try {
String sql = "SELECT * FROM toner_stock_register_details WHERE (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0) ORDER BY id DESC"; String sql = "SELECT * FROM toner_stock_register_details WHERE (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0) ORDER BY id DESC";
@ -581,22 +626,22 @@ public class TonerService {
Map<String, String> fileNumberMap = getWorkorderFileNumberMap(); Map<String, String> fileNumberMap = getWorkorderFileNumberMap();
Map<String, Integer> woQtyMap = getWorkorderRegisteredQtyMap(); Map<String, Integer> woQtyMap = getWorkorderRegisteredQtyMap();
Map<String, Map<String, Object>> grouped = new HashMap<>();
List<Map<String, Object>> result = new ArrayList<>();
for (Map<String, Object> raw : list) { for (Map<String, Object> raw : list) {
String refNo = raw.get("ref_no") != null ? String.valueOf(raw.get("ref_no")).trim() : ""; String refNo = raw.get("ref_no") != null ? String.valueOf(raw.get("ref_no")).trim() : "";
String pid = raw.get("pid") != null ? String.valueOf(raw.get("pid")).trim() : ""; String pid = raw.get("pid") != null ? String.valueOf(raw.get("pid")).trim() : "";
String tid = raw.get("tid") != null ? String.valueOf(raw.get("tid")).trim() : ""; String tid = raw.get("tid") != null ? String.valueOf(raw.get("tid")).trim() : "";
String key = refNo + "_" + pid + "_" + tid;
Integer qtyIn = parseIntegerSafely(raw.get("qty_registered")); Integer qtyIn = parseIntegerSafely(raw.get("qty_registered"));
int qty = qtyIn != null ? qtyIn : 0; int qty = qtyIn != null ? qtyIn : 0;
String dc = raw.get("dc_upload") != null ? String.valueOf(raw.get("dc_upload")).trim() : ""; String dc = raw.get("dc_upload") != null ? String.valueOf(raw.get("dc_upload")).trim() : "";
String dcNo = raw.get("dc_no") != null ? String.valueOf(raw.get("dc_no")).trim() : "";
String dcDate = raw.get("dc_date") != null ? String.valueOf(raw.get("dc_date")).trim() : "";
String updatedBy = raw.get("updated_by") != null ? String.valueOf(raw.get("updated_by")).trim() : ""; String updatedBy = raw.get("updated_by") != null ? String.valueOf(raw.get("updated_by")).trim() : "";
String companyName = raw.get("company_name") != null ? String.valueOf(raw.get("company_name")).trim() String companyName = raw.get("company_name") != null ? String.valueOf(raw.get("company_name")).trim()
: ""; : "";
if (!grouped.containsKey(key)) {
Map<String, Object> row = new HashMap<>(raw); Map<String, Object> row = new HashMap<>(raw);
row.put("printer_name", printerMap.getOrDefault(pid, pid)); row.put("printer_name", printerMap.getOrDefault(pid, pid));
row.put("model_name", tonerMap.getOrDefault(tid, tid)); row.put("model_name", tonerMap.getOrDefault(tid, tid));
@ -604,24 +649,16 @@ public class TonerService {
row.put("file_number", fileNumberMap.getOrDefault(refNo, "")); row.put("file_number", fileNumberMap.getOrDefault(refNo, ""));
row.put("vendor_name", vendorMap.getOrDefault(companyName, companyName)); row.put("vendor_name", vendorMap.getOrDefault(companyName, companyName));
row.put("qty_registered", qty); row.put("qty_registered", qty);
row.put("inward_qty", qty);
row.put("qty_workorder_registered", woQtyMap.getOrDefault(refNo + "_" + pid + "_" + tid, 0)); row.put("qty_workorder_registered", woQtyMap.getOrDefault(refNo + "_" + pid + "_" + tid, 0));
row.put("qty_workorder_requested", 0); row.put("qty_workorder_requested", 0);
row.put("dc_upload", dc);
row.put("dc_uploads", dc); row.put("dc_uploads", dc);
grouped.put(key, row);
} else {
Map<String, Object> existing = grouped.get(key);
Integer curQ = parseIntegerSafely(existing.get("qty_registered"));
int currentQty = curQ != null ? curQ : 0;
existing.put("qty_registered", currentQty + qty);
String currentDcs = existing.get("dc_uploads") != null ? String.valueOf(existing.get("dc_uploads"))
: "";
if (!dc.isEmpty() && !currentDcs.contains(dc)) {
existing.put("dc_uploads", currentDcs.isEmpty() ? dc : (currentDcs + "," + dc));
}
}
row.put("dc_no", dcNo);
row.put("dc_date", dcDate);
result.add(row);
} }
return new ArrayList<>(grouped.values());
return result;
} catch (Exception e) { } catch (Exception e) {
return new ArrayList<>(); return new ArrayList<>();
} }
@ -639,12 +676,13 @@ public class TonerService {
@Transactional @Transactional
public boolean saveUserRequest(String itCellRefNo, String deptId, String zoneId, List<Map<String, Object>> items, public boolean saveUserRequest(String itCellRefNo, String deptId, String zoneId, List<Map<String, Object>> items,
String userRequestUpload, String username) {
String userRequestUpload, String requestDate, String username) {
Timestamp now = new Timestamp(System.currentTimeMillis()); Timestamp now = new Timestamp(System.currentTimeMillis());
String finalRequestDate = (requestDate != null && !requestDate.trim().isEmpty()) ? requestDate.trim() : null;
String sql = "INSERT INTO toner_department_requested_details " + String sql = "INSERT INTO toner_department_requested_details " +
"(req_no, itcell_ref_no, dept_id, zone_id, pid, tid, qty_requested, qty_delivered, user_request_upload, cdate, updated_date, updated_by, is_active, is_delete) "
"(req_no, itcell_ref_no, dept_id, zone_id, pid, tid, qty_requested, qty_delivered, user_request_upload, request_date, cdate, updated_date, updated_by, is_active, is_delete) "
+ +
"VALUES (?, ?, ?, ?, ?, ?, ?, '0', ?, ?, ?, ?, 1, 0)";
"VALUES (?, ?, ?, ?, ?, ?, ?, '0', ?, ?, ?, ?, ?, 1, 0)";
try { try {
int baseMaxId = getMaxRequestId(); int baseMaxId = getMaxRequestId();
int year = Calendar.getInstance().get(Calendar.YEAR); int year = Calendar.getInstance().get(Calendar.YEAR);
@ -675,7 +713,7 @@ public class TonerService {
String reqNo = String.format("%s-%d-%04d", cleanModel, year, seqNum); String reqNo = String.format("%s-%d-%04d", cleanModel, year, seqNum);
jdbcTemplate.update(sql, reqNo, itCellRefNo, deptId, zoneId, String.valueOf(pid), String.valueOf(tid), jdbcTemplate.update(sql, reqNo, itCellRefNo, deptId, zoneId, String.valueOf(pid), String.valueOf(tid),
String.valueOf(qtyRequested), userRequestUpload, now, now, username);
String.valueOf(qtyRequested), userRequestUpload, finalRequestDate, now, now, username);
} }
return true; return true;
} catch (Exception e) { } catch (Exception e) {
@ -683,31 +721,40 @@ public class TonerService {
} }
} }
@Transactional
public boolean saveUserRequest(String itCellRefNo, String deptId, String zoneId, List<Map<String, Object>> items,
String userRequestUpload, String username) {
return saveUserRequest(itCellRefNo, deptId, zoneId, items, userRequestUpload, null, username);
}
@Transactional @Transactional
public boolean updateUserRequest(int id, String itcellRefNo, String deptId, String zoneId, public boolean updateUserRequest(int id, String itcellRefNo, String deptId, String zoneId,
int pid, int tid, int qtyRequested, String newUploadPath, String username) {
int pid, int tid, int qtyRequested, String newUploadPath, String requestDate, String username) {
Timestamp now = new Timestamp(System.currentTimeMillis()); Timestamp now = new Timestamp(System.currentTimeMillis());
try { try {
String safeZoneId = (zoneId != null && !zoneId.trim().isEmpty() && !"null".equalsIgnoreCase(zoneId)) String safeZoneId = (zoneId != null && !zoneId.trim().isEmpty() && !"null".equalsIgnoreCase(zoneId))
? zoneId.trim() ? zoneId.trim()
: null; : null;
String finalRequestDate = (requestDate != null && !requestDate.trim().isEmpty()) ? requestDate.trim()
: null;
if (newUploadPath != null && !newUploadPath.trim().isEmpty()) { if (newUploadPath != null && !newUploadPath.trim().isEmpty()) {
String sql = "UPDATE toner_department_requested_details SET " + String sql = "UPDATE toner_department_requested_details SET " +
"itcell_ref_no = ?, dept_id = ?, zone_id = ?, pid = ?, tid = ?, " + "itcell_ref_no = ?, dept_id = ?, zone_id = ?, pid = ?, tid = ?, " +
"qty_requested = ?, user_request_upload = ?, updated_date = ?, updated_by = ? " +
"qty_requested = ?, user_request_upload = ?, request_date = ?, updated_date = ?, updated_by = ? "
+
"WHERE id = ?"; "WHERE id = ?";
int rows = jdbcTemplate.update(sql, itcellRefNo.trim(), deptId.trim(), safeZoneId, int rows = jdbcTemplate.update(sql, itcellRefNo.trim(), deptId.trim(), safeZoneId,
String.valueOf(pid), String.valueOf(tid), String.valueOf(qtyRequested), String.valueOf(pid), String.valueOf(tid), String.valueOf(qtyRequested),
newUploadPath, now, username, id);
newUploadPath, finalRequestDate, now, username, id);
return rows > 0; return rows > 0;
} else { } else {
String sql = "UPDATE toner_department_requested_details SET " + String sql = "UPDATE toner_department_requested_details SET " +
"itcell_ref_no = ?, dept_id = ?, zone_id = ?, pid = ?, tid = ?, " + "itcell_ref_no = ?, dept_id = ?, zone_id = ?, pid = ?, tid = ?, " +
"qty_requested = ?, updated_date = ?, updated_by = ? " +
"qty_requested = ?, request_date = ?, updated_date = ?, updated_by = ? " +
"WHERE id = ?"; "WHERE id = ?";
int rows = jdbcTemplate.update(sql, itcellRefNo.trim(), deptId.trim(), safeZoneId, int rows = jdbcTemplate.update(sql, itcellRefNo.trim(), deptId.trim(), safeZoneId,
String.valueOf(pid), String.valueOf(tid), String.valueOf(qtyRequested), String.valueOf(pid), String.valueOf(tid), String.valueOf(qtyRequested),
now, username, id);
finalRequestDate, now, username, id);
return rows > 0; return rows > 0;
} }
} catch (Exception e) { } catch (Exception e) {
@ -716,6 +763,13 @@ public class TonerService {
} }
} }
@Transactional
public boolean updateUserRequest(int id, String itcellRefNo, String deptId, String zoneId,
int pid, int tid, int qtyRequested, String newUploadPath, String username) {
return updateUserRequest(id, itcellRefNo, deptId, zoneId, pid, tid, qtyRequested, newUploadPath, null,
username);
}
public List<Map<String, Object>> getAllUserRequests() { public List<Map<String, Object>> getAllUserRequests() {
try { try {
String sql = "SELECT * FROM toner_department_requested_details WHERE (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0) ORDER BY id DESC"; String sql = "SELECT * FROM toner_department_requested_details WHERE (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0) ORDER BY id DESC";
@ -739,12 +793,15 @@ public class TonerService {
String deptId = raw.get("dept_id") != null ? String.valueOf(raw.get("dept_id")).trim() : ""; String deptId = raw.get("dept_id") != null ? String.valueOf(raw.get("dept_id")).trim() : "";
String zoneId = raw.get("zone_id") != null ? String.valueOf(raw.get("zone_id")).trim() : ""; String zoneId = raw.get("zone_id") != null ? String.valueOf(raw.get("zone_id")).trim() : "";
String updatedBy = raw.get("updated_by") != null ? String.valueOf(raw.get("updated_by")).trim() : ""; String updatedBy = raw.get("updated_by") != null ? String.valueOf(raw.get("updated_by")).trim() : "";
String requestDate = raw.get("request_date") != null ? String.valueOf(raw.get("request_date")).trim()
: "";
row.put("printer_name", printerMap.getOrDefault(pid, pid)); row.put("printer_name", printerMap.getOrDefault(pid, pid));
row.put("model_name", tonerMap.getOrDefault(tid, tid)); row.put("model_name", tonerMap.getOrDefault(tid, tid));
row.put("dept_name", deptMap.getOrDefault(deptId, deptId)); row.put("dept_name", deptMap.getOrDefault(deptId, deptId));
row.put("zone_name", zoneMap.getOrDefault(zoneId, zoneId)); row.put("zone_name", zoneMap.getOrDefault(zoneId, zoneId));
row.put("updated_by", userMap.getOrDefault(updatedBy, updatedBy)); row.put("updated_by", userMap.getOrDefault(updatedBy, updatedBy));
row.put("request_date", requestDate);
result.add(row); result.add(row);
} }
@ -788,6 +845,7 @@ public class TonerService {
Map<String, String> printerMap = getPrinterMap(); Map<String, String> printerMap = getPrinterMap();
Map<String, String> tonerMap = getTonerMap(); Map<String, String> tonerMap = getTonerMap();
Map<String, String> partCodeMap = getTonerPartCodeMap();
Map<String, String> deptMap = getDepartmentMap(); Map<String, String> deptMap = getDepartmentMap();
Map<String, String> zoneMap = getZoneMap(); Map<String, String> zoneMap = getZoneMap();
Map<String, Integer> availStockMap = getAvailableStockMap(); Map<String, Integer> availStockMap = getAvailableStockMap();
@ -806,9 +864,6 @@ public class TonerService {
String pid = raw.get("pid") != null ? String.valueOf(raw.get("pid")).trim() : ""; String pid = raw.get("pid") != null ? String.valueOf(raw.get("pid")).trim() : "";
String tid = raw.get("tid") != null ? String.valueOf(raw.get("tid")).trim() : ""; String tid = raw.get("tid") != null ? String.valueOf(raw.get("tid")).trim() : "";
int availStock = availStockMap.getOrDefault(pid + "_" + tid, 0); int availStock = availStockMap.getOrDefault(pid + "_" + tid, 0);
if (availStock <= 0) {
continue; // Cannot issue without available stock
}
Map<String, Object> row = new HashMap<>(raw); Map<String, Object> row = new HashMap<>(raw);
String deptId = raw.get("dept_id") != null ? String.valueOf(raw.get("dept_id")).trim() : ""; String deptId = raw.get("dept_id") != null ? String.valueOf(raw.get("dept_id")).trim() : "";
@ -816,6 +871,7 @@ public class TonerService {
row.put("printer_name", printerMap.getOrDefault(pid, pid)); row.put("printer_name", printerMap.getOrDefault(pid, pid));
row.put("model_name", tonerMap.getOrDefault(tid, tid)); row.put("model_name", tonerMap.getOrDefault(tid, tid));
row.put("part_code", partCodeMap.getOrDefault(tid, "N/A"));
row.put("dept_name", deptMap.getOrDefault(deptId, deptId)); row.put("dept_name", deptMap.getOrDefault(deptId, deptId));
row.put("zone_name", zoneMap.getOrDefault(zoneId, zoneId)); row.put("zone_name", zoneMap.getOrDefault(zoneId, zoneId));
row.put("available_stock", availStock); row.put("available_stock", availStock);
@ -829,6 +885,60 @@ public class TonerService {
} }
// ================= OUTWARD REGISTER ================= // ================= OUTWARD REGISTER =================
@Transactional
public boolean saveOutwardRegisterBulk(List<Map<String, Object>> items, String outwardDate, String username) {
Timestamp now = new Timestamp(System.currentTimeMillis());
String finalOutDate = (outwardDate != null && !outwardDate.trim().isEmpty()) ? outwardDate.trim() : null;
try {
for (Map<String, Object> item : items) {
Integer idVal = parseIntegerSafely(item.get("id"));
Integer qtyVal = parseIntegerSafely(item.get("qtyIssued"));
if (idVal == null)
continue;
int id = idVal;
int qtyIssued = (qtyVal != null) ? qtyVal : 0;
if (qtyIssued <= 0)
continue;
String sql = "UPDATE toner_department_requested_details SET " +
"qty_delivered = CAST(COALESCE(qty_delivered, 0) AS SIGNED) + ?, " +
"outward_date = COALESCE(?, outward_date), " +
"updated_date = ?, updated_by = ? " +
"WHERE id = ?";
jdbcTemplate.update(sql, qtyIssued, finalOutDate, now, username, id);
}
return true;
} catch (Exception e) {
throw new RuntimeException("Rollback saveOutwardRegisterBulk due to: " + e.getMessage());
}
}
@Transactional
public boolean updateOutwardDeliveryFiles(List<Integer> ids, String finalDeliveredUpload, String userPhotoUpload,
String username) {
Timestamp now = new Timestamp(System.currentTimeMillis());
try {
for (int id : ids) {
String sql = "UPDATE toner_department_requested_details SET " +
"final_delivered_upload = CASE WHEN ? IS NULL OR ? = '' THEN final_delivered_upload " +
" WHEN final_delivered_upload IS NULL OR final_delivered_upload = '' THEN ? " +
" ELSE CONCAT(final_delivered_upload, ',', ?) END, " +
"receiver_photo = CASE WHEN ? IS NULL OR ? = '' THEN receiver_photo " +
" WHEN receiver_photo IS NULL OR receiver_photo = '' THEN ? " +
" ELSE CONCAT(receiver_photo, ',', ?) END, " +
"updated_date = ?, updated_by = ? " +
"WHERE id = ?";
jdbcTemplate.update(sql,
finalDeliveredUpload, finalDeliveredUpload, finalDeliveredUpload, finalDeliveredUpload,
userPhotoUpload, userPhotoUpload, userPhotoUpload, userPhotoUpload,
now, username, id);
}
return true;
} catch (Exception e) {
throw new RuntimeException("Rollback updateOutwardDeliveryFiles due to: " + e.getMessage());
}
}
public boolean saveOutwardRegister(int id, String qtyIssued, String finalDeliveredUpload, String userPhotoUpload, public boolean saveOutwardRegister(int id, String qtyIssued, String finalDeliveredUpload, String userPhotoUpload,
String username) { String username) {
String sql; String sql;
@ -878,6 +988,7 @@ public class TonerService {
Map<String, String> printerMap = getPrinterMap(); Map<String, String> printerMap = getPrinterMap();
Map<String, String> tonerMap = getTonerMap(); Map<String, String> tonerMap = getTonerMap();
Map<String, String> partCodeMap = getTonerPartCodeMap();
Map<String, String> deptMap = getDepartmentMap(); Map<String, String> deptMap = getDepartmentMap();
Map<String, String> zoneMap = getZoneMap(); Map<String, String> zoneMap = getZoneMap();
Map<String, String> userMap = getUserMap(); Map<String, String> userMap = getUserMap();
@ -894,6 +1005,7 @@ public class TonerService {
row.put("printer_name", printerMap.getOrDefault(pid, pid)); row.put("printer_name", printerMap.getOrDefault(pid, pid));
row.put("model_name", tonerMap.getOrDefault(tid, tid)); row.put("model_name", tonerMap.getOrDefault(tid, tid));
row.put("part_code", partCodeMap.getOrDefault(tid, "N/A"));
row.put("dept_name", deptMap.getOrDefault(deptId, deptId)); row.put("dept_name", deptMap.getOrDefault(deptId, deptId));
row.put("zone_name", zoneMap.getOrDefault(zoneId, zoneId)); row.put("zone_name", zoneMap.getOrDefault(zoneId, zoneId));
row.put("updated_by", userMap.getOrDefault(updatedBy, updatedBy)); row.put("updated_by", userMap.getOrDefault(updatedBy, updatedBy));
@ -1034,6 +1146,30 @@ public class TonerService {
} }
} }
public List<Map<String, Object>> getActiveWorkorders() {
String sql = "SELECT id, ref_no, file_number, vendor_name FROM toner_workorder_register_details WHERE (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0) ORDER BY id DESC";
try {
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
if (list == null || list.isEmpty())
return new ArrayList<>();
Map<String, Map<String, Object>> seen = new HashMap<>();
List<Map<String, Object>> distinct = new ArrayList<>();
for (Map<String, Object> row : list) {
String refNo = row.get("ref_no") != null ? String.valueOf(row.get("ref_no")).trim() : "";
String fileNo = row.get("file_number") != null ? String.valueOf(row.get("file_number")).trim() : "";
String key = refNo + "_" + fileNo;
if (!seen.containsKey(key)) {
seen.put(key, row);
distinct.add(row);
}
}
return distinct;
} catch (Exception e) {
System.err.println("Error fetching active workorders: " + e.getMessage());
return new ArrayList<>();
}
}
public List<String> getActiveWorkorderRefNos() { public List<String> getActiveWorkorderRefNos() {
String sql = "SELECT ref_no FROM toner_workorder_register_details WHERE (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0) ORDER BY id DESC"; String sql = "SELECT ref_no FROM toner_workorder_register_details WHERE (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0) ORDER BY id DESC";
try { try {
@ -1045,8 +1181,18 @@ public class TonerService {
public List<Map<String, Object>> getWorkorderRegisteredItems(String refNo) { public List<Map<String, Object>> getWorkorderRegisteredItems(String refNo) {
try { try {
String sql = "SELECT * FROM toner_workorder_printermodel_qty WHERE TRIM(ref_no) = TRIM(?) AND (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0)";
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, refNo);
String resolvedRef = refNo != null ? refNo.trim() : "";
try {
String findSql = "SELECT ref_no FROM toner_workorder_register_details WHERE (TRIM(ref_no) = TRIM(?) OR TRIM(file_number) = TRIM(?)) AND (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0) LIMIT 1";
List<String> refs = jdbcTemplate.queryForList(findSql, String.class, refNo, refNo);
if (refs != null && !refs.isEmpty() && refs.get(0) != null) {
resolvedRef = refs.get(0).trim();
}
} catch (Exception ignored) {
}
String sql = "SELECT * FROM toner_workorder_printermodel_qty WHERE (TRIM(ref_no) = TRIM(?) OR TRIM(ref_no) = TRIM(?)) AND (is_active IS NULL OR is_active = 1) AND (is_delete IS NULL OR is_delete = 0)";
List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, refNo, resolvedRef);
if (list == null || list.isEmpty()) { if (list == null || list.isEmpty()) {
return new ArrayList<>(); return new ArrayList<>();
} }
@ -1059,8 +1205,8 @@ public class TonerService {
String vendorId = ""; String vendorId = "";
try { try {
String vSql = "SELECT vendor_name FROM toner_workorder_register_details WHERE TRIM(ref_no) = TRIM(?) LIMIT 1";
vendorId = jdbcTemplate.queryForObject(vSql, String.class, refNo);
String vSql = "SELECT vendor_name FROM toner_workorder_register_details WHERE (TRIM(ref_no) = TRIM(?) OR TRIM(ref_no) = TRIM(?)) LIMIT 1";
vendorId = jdbcTemplate.queryForObject(vSql, String.class, refNo, resolvedRef);
} catch (Exception ignored) { } catch (Exception ignored) {
} }
@ -1068,7 +1214,7 @@ public class TonerService {
for (Map<String, Object> raw : list) { for (Map<String, Object> raw : list) {
Map<String, Object> row = new HashMap<>(raw); Map<String, Object> row = new HashMap<>(raw);
String cleanRef = refNo != null ? refNo.trim() : "";
String cleanRef = resolvedRef;
String pid = raw.get("pid") != null ? String.valueOf(raw.get("pid")).trim() : ""; String pid = raw.get("pid") != null ? String.valueOf(raw.get("pid")).trim() : "";
String tid = raw.get("tid") != null ? String.valueOf(raw.get("tid")).trim() : ""; String tid = raw.get("tid") != null ? String.valueOf(raw.get("tid")).trim() : "";

22
src/main/resources/templates/fragments/rentalheader.html

@ -0,0 +1,22 @@
<th:block th:fragment="rentalheader">
<!-- Awesome Font -->
<link rel="stylesheet" th:href="@{/assets/font-awesome-6.5.2/css/all.min.css}" type="text/css">
<!-- Bootstrap CSS -->
<link rel="stylesheet" th:href="@{/assets/bootstrap-5.3.2/css/bootstrap.min.css}" type="text/css">
<!-- CSS for Header -->
<link rel="stylesheet" th:href="@{/assets/css/header-styles.css}" type="text/css">
<div class="header">
<div class="logo-left">
<img th:src="@{/assets/header-images/gcc1.png}" alt="Greater Chennai Corporation Logo">
<div class="logo-text">
<h2>GREATER</h2>
<h2>CHENNAI</h2>
<h2>CORPORATION</h2>
<p>பெருநகர சென்னை மாநகராட்சி</p>
</div>
</div>
<div class="title">
<h2>GCC IT Cell Rental Asset & Material Management System</h2>
</div>
</div>
</th:block>

3080
src/main/resources/templates/gccrentalmanagement/dashboard.html
File diff suppressed because it is too large
View File

429
src/main/resources/templates/gccrentalmanagement/login.html

@ -0,0 +1,429 @@
<!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 IT Cell Rental Asset Management - 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}" />
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700;800&family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<!-- Bootstrap CSS -->
<link rel="stylesheet" th:href="@{/assets/bootstrap-5.3.2/css/bootstrap.min.css}" type="text/css">
<!-- Awesome Font -->
<link th:href="@{/assets/font-awesome-6.5.2/css/all.min.css}" rel="stylesheet" type="text/css">
<style>
:root {
--primary-brand: #0d4b68;
--primary-dark: #072e41;
--accent-cyan: #06b6d4;
--accent-amber: #f59e0b;
--gradient-bg: linear-gradient(135deg, #072e41 0%, #0d4b68 50%, #155e75 100%);
--card-bg: rgba(255, 255, 255, 0.96);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Poppins', sans-serif;
background: var(--gradient-bg);
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20px;
position: relative;
overflow-x: hidden;
}
/* Decorative ambient glow circles */
.ambient-glow {
position: absolute;
border-radius: 50%;
filter: blur(80px);
opacity: 0.25;
pointer-events: none;
z-index: 0;
}
.glow-1 {
width: 350px;
height: 350px;
background: #06b6d4;
top: -50px;
left: -50px;
}
.glow-2 {
width: 400px;
height: 400px;
background: #f59e0b;
bottom: -80px;
right: -80px;
}
.login-card {
position: relative;
z-index: 1;
width: 100%;
max-width: 460px;
background: var(--card-bg);
backdrop-filter: blur(12px);
border-radius: 24px;
padding: 40px 36px;
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.2);
animation: slideUp 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(25px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.header-branding {
text-align: center;
margin-bottom: 28px;
}
.logo-wrap {
width: 84px;
height: 84px;
margin: 0 auto 16px;
border-radius: 20px;
background: #ffffff;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8px 20px rgba(13, 75, 104, 0.15);
padding: 10px;
transition: transform 0.3s ease;
}
.logo-wrap:hover {
transform: scale(1.05) rotate(2deg);
}
.logo-wrap img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
.brand-title-en {
font-family: 'Outfit', sans-serif;
font-size: 1.15rem;
font-weight: 800;
letter-spacing: 0.8px;
color: #0d4b68;
text-transform: uppercase;
margin-bottom: 2px;
}
.brand-title-ta {
font-size: 0.82rem;
color: #475569;
font-weight: 600;
margin-bottom: 12px;
}
.badge-module {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 14px;
background: linear-gradient(135deg, #e0f2fe, #e2e8f0);
color: #0369a1;
border: 1px solid #bae6fd;
border-radius: 30px;
font-size: 0.78rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.badge-module i {
color: #0284c7;
}
.form-title {
font-family: 'Outfit', sans-serif;
font-size: 1.4rem;
font-weight: 700;
color: #0f172a;
margin: 18px 0 6px;
text-align: center;
}
.form-subtitle {
font-size: 0.85rem;
color: #64748b;
text-align: center;
margin-bottom: 24px;
}
.form-floating-custom {
position: relative;
margin-bottom: 20px;
}
.form-floating-custom .input-icon {
position: absolute;
left: 16px;
top: 50%;
transform: translateY(-50%);
color: #94a3b8;
font-size: 1.1rem;
transition: color 0.3s ease;
pointer-events: none;
}
.form-floating-custom input {
width: 100%;
height: 52px;
padding: 12px 16px 12px 46px;
font-size: 0.92rem;
color: #1e293b;
background: #f8fafc;
border: 1.5px solid #e2e8f0;
border-radius: 12px;
outline: none;
transition: all 0.3s ease;
}
.form-floating-custom input:focus {
background: #ffffff;
border-color: #0284c7;
box-shadow: 0 0 0 4px rgba(2, 132, 199, 0.12);
}
.form-floating-custom input:focus + .input-icon {
color: #0284c7;
}
.btn-submit {
width: 100%;
height: 52px;
background: linear-gradient(135deg, #0d4b68 0%, #0284c7 100%);
color: #ffffff;
border: none;
border-radius: 12px;
font-family: 'Outfit', sans-serif;
font-size: 1rem;
font-weight: 700;
letter-spacing: 0.5px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
transition: all 0.3s ease;
box-shadow: 0 8px 20px rgba(13, 75, 104, 0.25);
margin-top: 10px;
}
.btn-submit:hover:not(:disabled) {
background: linear-gradient(135deg, #093448 0%, #0369a1 100%);
box-shadow: 0 12px 25px rgba(13, 75, 104, 0.35);
transform: translateY(-2px);
}
.btn-submit:disabled {
opacity: 0.7;
cursor: not-allowed;
}
#error-box {
background: #fef2f2;
border: 1px solid #fecaca;
color: #b91c1c;
padding: 12px 16px;
border-radius: 10px;
font-size: 0.84rem;
font-weight: 500;
margin-bottom: 20px;
display: none;
align-items: center;
gap: 10px;
animation: shake 0.4s ease;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-5px); }
75% { transform: translateX(5px); }
}
.system-badge-footer {
margin-top: 25px;
text-align: center;
font-size: 0.76rem;
color: #94a3b8;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.system-badge-footer span {
display: inline-block;
width: 6px;
height: 6px;
background: #22c55e;
border-radius: 50%;
box-shadow: 0 0 8px #22c55e;
}
.back-portal-link {
display: block;
text-align: center;
margin-top: 18px;
color: #0284c7;
text-decoration: none;
font-size: 0.85rem;
font-weight: 600;
transition: color 0.2s;
}
.back-portal-link:hover {
color: #0369a1;
text-decoration: underline;
}
</style>
</head>
<body>
<div class="ambient-glow glow-1"></div>
<div class="ambient-glow glow-2"></div>
<div class="login-card">
<div class="header-branding">
<div class="logo-wrap">
<img th:src="@{/assets/header-images/gcc1.png}" alt="Greater Chennai Corporation Logo">
</div>
<h2 class="brand-title-en">Greater Chennai Corporation</h2>
<p class="brand-title-ta">பெருநகர சென்னை மாநகராட்சி</p>
<div class="badge-module">
<i class="fa-solid fa-boxes-packing"></i>
<span>Rental Management System</span>
</div>
</div>
<h3 class="form-title">Portal Sign In</h3>
<p class="form-subtitle">Work Orders • Requests • Challans • Issue & Return</p>
<div id="error-box">
<i class="fa-solid fa-circle-exclamation fs-5"></i>
<span id="error-text">Invalid username or password!</span>
</div>
<form id="rentalLoginForm" onsubmit="handleRentalLogin(event)">
<div class="form-floating-custom">
<input type="text" name="usrName" id="usrName" placeholder="Enter Username / Employee ID" required autocomplete="username">
<i class="fa-solid fa-user input-icon"></i>
</div>
<div class="form-floating-custom">
<input type="password" name="usrPass" id="usrPass" placeholder="Enter Password" required autocomplete="current-password">
<i class="fa-solid fa-lock input-icon"></i>
</div>
<button type="submit" id="submit-btn" class="btn-submit">
<span>Sign In to Rental System</span>
<i class="fa-solid fa-arrow-right-to-bracket"></i>
</button>
</form>
<a th:href="@{/}" class="back-portal-link">
<i class="fa-solid fa-arrow-left me-1"></i> Return to Main GCC Home
</a>
<div class="system-badge-footer">
<span></span>
<span>GCC IT Cell Secured System &bull; Active Version 2.0</span>
</div>
</div>
<!-- Custom JS -->
<script th:inline="javascript">
const contextPath = /*[[@{/}]]*/ '/';
</script>
<script>
function handleRentalLogin(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.innerHTML = '<i class="fa-solid fa-circle-notch fa-spin"></i> Authenticating...';
const username = document.getElementById("usrName").value.trim();
const password = document.getElementById("usrPass").value;
const urlParams = new URLSearchParams();
urlParams.append('usrName', username);
urlParams.append('usrPass', password);
// Fetch CSRF tokens if available
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 + 'gccrentalmanagement/api/login', {
method: 'POST',
headers: headers,
body: urlParams
})
.then(response => response.json())
.then(data => {
if (data.result) {
sessionStorage.setItem("rental_usrName", data.usrName);
sessionStorage.setItem("rental_usrRole", data.usrRole || "USER");
window.location.href = contextPath + 'gccrentalmanagement/dashboard';
} else {
submitBtn.disabled = false;
submitBtn.innerHTML = '<span>Sign In to Rental System</span> <i class="fa-solid fa-arrow-right-to-bracket"></i>';
errorText.textContent = data.error || "Authentication failed. Check your username and password.";
errorBox.style.display = "flex";
}
})
.catch(err => {
console.error("Login Error:", err);
submitBtn.disabled = false;
submitBtn.innerHTML = '<span>Sign In to Rental System</span> <i class="fa-solid fa-arrow-right-to-bracket"></i>';
errorText.textContent = "Network error. Please try again later.";
errorBox.style.display = "flex";
});
}
</script>
</body>
</html>

3682
src/main/resources/templates/gcctonermanagement/upload.html
File diff suppressed because it is too large
View File

Loading…
Cancel
Save