All GCC vendors and employee details for IT department management
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1053 lines
40 KiB

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. package com.gcc_manpower.gcctonermanagement.controller;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.stereotype.Controller;
  8. import org.springframework.ui.Model;
  9. import org.springframework.web.bind.annotation.GetMapping;
  10. import org.springframework.web.bind.annotation.PostMapping;
  11. import org.springframework.web.bind.annotation.RequestMapping;
  12. import org.springframework.web.bind.annotation.RequestParam;
  13. import org.springframework.web.bind.annotation.ResponseBody;
  14. import org.springframework.beans.factory.annotation.Value;
  15. import org.springframework.web.multipart.MultipartFile;
  16. import java.io.File;
  17. import com.fasterxml.jackson.databind.ObjectMapper;
  18. import com.fasterxml.jackson.core.type.TypeReference;
  19. import com.gcc_manpower.gcctonermanagement.service.TonerService;
  20. import com.gcc_manpower.service.AppUserService;
  21. import jakarta.servlet.http.HttpSession;
  22. import jakarta.servlet.http.HttpServletRequest;
  23. import org.springframework.security.authentication.AuthenticationManager;
  24. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  25. import org.springframework.security.core.Authentication;
  26. import org.springframework.security.core.AuthenticationException;
  27. import org.springframework.security.core.context.SecurityContextHolder;
  28. import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
  29. @Controller
  30. @RequestMapping("/gcctonermanagement")
  31. public class TonerController {
  32. @Autowired
  33. private AppUserService appUserService;
  34. @Autowired
  35. private TonerService tonerService;
  36. @Autowired
  37. private AuthenticationManager authenticationManager;
  38. @Value("${toner.upload.path:gcctonermanagementfiles}")
  39. private String tonerUploadPathConfig;
  40. @GetMapping({ "", "/", "/upload" })
  41. public String viewDashboard(Model model, HttpSession session) {
  42. String username = (String) session.getAttribute("toner_usrName");
  43. if (username == null) {
  44. return "redirect:/gcctonermanagement/login";
  45. }
  46. String usrRole = (String) session.getAttribute("toner_usrRole");
  47. boolean isAdmin = "ADMIN".equalsIgnoreCase(usrRole);
  48. // List<Map<String, Object>> vendorDetails =
  49. // appUserService.getVendorDetailsWithCounts();
  50. model.addAttribute("isLoggedIn", true);
  51. model.addAttribute("isAdmin", isAdmin);
  52. model.addAttribute("usrName", username);
  53. model.addAttribute("curPage", "gcctonermanagement");
  54. // model.addAttribute("vendorDetails", vendorDetails);
  55. return "gcctonermanagement/upload";
  56. }
  57. @GetMapping("/login")
  58. public String login(HttpSession session) {
  59. return "gcctonermanagement/login";
  60. }
  61. @PostMapping("/api/login")
  62. @ResponseBody
  63. public Map<String, Object> validateLogin(
  64. @RequestParam("usrName") String usrName,
  65. @RequestParam("usrPass") String usrPass,
  66. HttpSession session) {
  67. Map<String, Object> response = new HashMap<>();
  68. try {
  69. UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(usrName,
  70. usrPass);
  71. Authentication authentication = authenticationManager.authenticate(authenticationToken);
  72. SecurityContextHolder.getContext().setAuthentication(authentication);
  73. session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
  74. SecurityContextHolder.getContext());
  75. String role = authentication.getAuthorities().stream()
  76. .map(auth -> auth.getAuthority().replace("ROLE_", ""))
  77. .findFirst()
  78. .orElse("USER");
  79. session.setAttribute("toner_usrName", usrName);
  80. session.setAttribute("toner_usrRole", role);
  81. session.setMaxInactiveInterval(1800); // 30 minutes session timeout
  82. response.put("result", true);
  83. response.put("usrName", usrName);
  84. } catch (AuthenticationException e) {
  85. response.put("result", false);
  86. response.put("error", e.getMessage() != null ? e.getMessage() : "Invalid username or password!");
  87. }
  88. return response;
  89. }
  90. @GetMapping("/logout")
  91. public String logoutGet(HttpSession session, HttpServletRequest request) {
  92. SecurityContextHolder.clearContext();
  93. if (session != null) {
  94. session.removeAttribute("toner_usrName");
  95. session.removeAttribute("toner_usrRole");
  96. session.invalidate();
  97. }
  98. request.getSession(true);
  99. return "redirect:/gcctonermanagement/login";
  100. }
  101. @GetMapping("/api/printers")
  102. @ResponseBody
  103. public List<Map<String, Object>> getPrinters(HttpSession session) {
  104. if (session.getAttribute("toner_usrName") == null) {
  105. return java.util.Collections.emptyList();
  106. }
  107. return tonerService.getActivePrinters();
  108. }
  109. @GetMapping("/api/toners")
  110. @ResponseBody
  111. public List<Map<String, Object>> getToners(@RequestParam("pid") int pid, HttpSession session) {
  112. if (session.getAttribute("toner_usrName") == null) {
  113. return java.util.Collections.emptyList();
  114. }
  115. return tonerService.getActiveTonersByPrinter(pid);
  116. }
  117. @GetMapping("/api/departments")
  118. @ResponseBody
  119. public List<Map<String, Object>> getDepartments(HttpSession session) {
  120. if (session.getAttribute("toner_usrName") == null) {
  121. return java.util.Collections.emptyList();
  122. }
  123. return tonerService.getActiveDepartments();
  124. }
  125. @GetMapping("/api/zones")
  126. @ResponseBody
  127. public List<Map<String, Object>> getZones(HttpSession session) {
  128. if (session.getAttribute("toner_usrName") == null) {
  129. return java.util.Collections.emptyList();
  130. }
  131. return tonerService.getActiveZones();
  132. }
  133. @PostMapping("/api/inward")
  134. @ResponseBody
  135. public Map<String, Object> uploadInward(
  136. @RequestParam("refNo") String refNo,
  137. @RequestParam("companyName") String companyName,
  138. @RequestParam("itemsJson") String itemsJson,
  139. @RequestParam(value = "dcFile", required = false) MultipartFile dcFile,
  140. HttpSession session) {
  141. Map<String, Object> response = new HashMap<>();
  142. String username = (String) session.getAttribute("toner_usrName");
  143. if (username == null) {
  144. response.put("success", false);
  145. response.put("error", "Unauthorized access. Please log in.");
  146. return response;
  147. }
  148. String updatedBy = appUserService.getUserIdByName(username);
  149. if (updatedBy == null)
  150. updatedBy = username;
  151. if (dcFile == null || dcFile.isEmpty()) {
  152. response.put("success", false);
  153. response.put("error", "Delivery Challan (DC) PDF file is required.");
  154. return response;
  155. }
  156. if (!isPdfFile(dcFile)) {
  157. response.put("success", false);
  158. response.put("error", "Delivery Challan file must be a PDF.");
  159. return response;
  160. }
  161. try {
  162. ObjectMapper mapper = new ObjectMapper();
  163. List<Map<String, Object>> items = mapper.readValue(itemsJson,
  164. new TypeReference<List<Map<String, Object>>>() {
  165. });
  166. if (items == null || items.isEmpty()) {
  167. response.put("success", false);
  168. response.put("error", "Please enter quantity for at least one model.");
  169. return response;
  170. }
  171. File uploadDir = new File(tonerUploadPathConfig).getAbsoluteFile();
  172. if (!uploadDir.exists()) {
  173. uploadDir.mkdirs();
  174. }
  175. String dcPath = saveUploadedFile(dcFile, "dc", uploadDir);
  176. boolean saved = tonerService.saveInwardRegister(
  177. refNo.trim(), companyName.trim(), items, dcPath, updatedBy);
  178. if (saved) {
  179. response.put("success", true);
  180. response.put("message", "Inward stock registered successfully.");
  181. } else {
  182. deleteFileIfExists(dcPath, uploadDir);
  183. response.put("success", false);
  184. response.put("error", "Failed to save inward details in the database.");
  185. }
  186. } catch (Exception e) {
  187. response.put("success", false);
  188. response.put("error", "An error occurred: " + e.getMessage());
  189. e.printStackTrace();
  190. }
  191. return response;
  192. }
  193. @PostMapping("/api/request")
  194. @ResponseBody
  195. public Map<String, Object> uploadRequest(
  196. @RequestParam("itcellRefNo") String itcellRefNo,
  197. @RequestParam("deptId") String deptId,
  198. @RequestParam(value = "zoneId", required = false) String zoneId,
  199. @RequestParam("itemsJson") String itemsJson,
  200. @RequestParam(value = "userRequestFile", required = false) MultipartFile userRequestFile,
  201. HttpSession session) {
  202. Map<String, Object> response = new HashMap<>();
  203. String username = (String) session.getAttribute("toner_usrName");
  204. if (username == null) {
  205. response.put("success", false);
  206. response.put("error", "Unauthorized access. Please log in.");
  207. return response;
  208. }
  209. String updatedBy = appUserService.getUserIdByName(username);
  210. if (updatedBy == null)
  211. updatedBy = username;
  212. if (userRequestFile == null || userRequestFile.isEmpty()) {
  213. response.put("success", false);
  214. response.put("error", "User Request Letter PDF file is required.");
  215. return response;
  216. }
  217. if (!isPdfFile(userRequestFile)) {
  218. response.put("success", false);
  219. response.put("error", "User Request file must be a PDF.");
  220. return response;
  221. }
  222. try {
  223. ObjectMapper mapper = new ObjectMapper();
  224. List<Map<String, Object>> items = mapper.readValue(itemsJson,
  225. new TypeReference<List<Map<String, Object>>>() {
  226. });
  227. if (items == null || items.isEmpty()) {
  228. response.put("success", false);
  229. response.put("error", "Please add at least one printer/toner model request entry.");
  230. return response;
  231. }
  232. File uploadDir = new File(tonerUploadPathConfig).getAbsoluteFile();
  233. if (!uploadDir.exists()) {
  234. uploadDir.mkdirs();
  235. }
  236. String urPath = saveUploadedFile(userRequestFile, "user_request", uploadDir);
  237. String safeZoneId = (zoneId != null && !zoneId.trim().isEmpty()) ? zoneId.trim() : null;
  238. boolean saved = tonerService.saveUserRequest(
  239. itcellRefNo.trim(), deptId.trim(), safeZoneId, items, urPath, updatedBy);
  240. if (saved) {
  241. response.put("success", true);
  242. response.put("message", "User request saved successfully.");
  243. } else {
  244. deleteFileIfExists(urPath, uploadDir);
  245. response.put("success", false);
  246. response.put("error", "Failed to save request details in the database.");
  247. }
  248. } catch (Exception e) {
  249. response.put("success", false);
  250. response.put("error", "An error occurred: " + e.getMessage());
  251. e.printStackTrace();
  252. }
  253. return response;
  254. }
  255. @PostMapping("/api/request/update")
  256. @ResponseBody
  257. public Map<String, Object> updateRequest(
  258. @RequestParam("id") int id,
  259. @RequestParam("itcellRefNo") String itcellRefNo,
  260. @RequestParam("deptId") String deptId,
  261. @RequestParam(value = "zoneId", required = false) String zoneId,
  262. @RequestParam("pid") int pid,
  263. @RequestParam("tid") int tid,
  264. @RequestParam("qtyRequested") int qtyRequested,
  265. @RequestParam(value = "userRequestFile", required = false) MultipartFile userRequestFile,
  266. HttpSession session) {
  267. Map<String, Object> response = new HashMap<>();
  268. String username = (String) session.getAttribute("toner_usrName");
  269. if (username == null) {
  270. response.put("success", false);
  271. response.put("error", "Unauthorized access. Please log in.");
  272. return response;
  273. }
  274. String updatedBy = appUserService.getUserIdByName(username);
  275. if (updatedBy == null)
  276. updatedBy = username;
  277. if (itcellRefNo == null || itcellRefNo.trim().isEmpty()) {
  278. response.put("success", false);
  279. response.put("error", "IT Cell Reference No. is required.");
  280. return response;
  281. }
  282. if (deptId == null || deptId.trim().isEmpty()) {
  283. response.put("success", false);
  284. response.put("error", "Department is required.");
  285. return response;
  286. }
  287. if (qtyRequested <= 0) {
  288. response.put("success", false);
  289. response.put("error", "Quantity requested must be greater than 0.");
  290. return response;
  291. }
  292. if (userRequestFile != null && !userRequestFile.isEmpty() && !isPdfFile(userRequestFile)) {
  293. response.put("success", false);
  294. response.put("error", "User Request file must be a PDF.");
  295. return response;
  296. }
  297. try {
  298. File uploadDir = new File(tonerUploadPathConfig).getAbsoluteFile();
  299. if (!uploadDir.exists()) {
  300. uploadDir.mkdirs();
  301. }
  302. String urPath = null;
  303. if (userRequestFile != null && !userRequestFile.isEmpty()) {
  304. urPath = saveUploadedFile(userRequestFile, "user_request", uploadDir);
  305. }
  306. String safeZoneId = (zoneId != null && !zoneId.trim().isEmpty()) ? zoneId.trim() : null;
  307. boolean updated = tonerService.updateUserRequest(
  308. id, itcellRefNo.trim(), deptId.trim(), safeZoneId, pid, tid, qtyRequested, urPath, updatedBy);
  309. if (updated) {
  310. response.put("success", true);
  311. response.put("message", "User request details updated successfully.");
  312. } else {
  313. if (urPath != null) {
  314. deleteFileIfExists(urPath, uploadDir);
  315. }
  316. response.put("success", false);
  317. response.put("error", "Failed to update user request details in database.");
  318. }
  319. } catch (Exception e) {
  320. response.put("success", false);
  321. response.put("error", "An error occurred: " + e.getMessage());
  322. e.printStackTrace();
  323. }
  324. return response;
  325. }
  326. @PostMapping("/api/outward")
  327. @ResponseBody
  328. public Map<String, Object> uploadOutward(
  329. @RequestParam("id") int id,
  330. @RequestParam("qtyIssued") String qtyIssued,
  331. @RequestParam(value = "finalDeliveredFile", required = false) MultipartFile finalDeliveredFile,
  332. @RequestParam(value = "userPhotoFile", required = false) MultipartFile userPhotoFile,
  333. @RequestParam(value = "userPhotoBase64", required = false) String userPhotoBase64,
  334. HttpSession session) {
  335. Map<String, Object> response = new HashMap<>();
  336. String username = (String) session.getAttribute("toner_usrName");
  337. if (username == null) {
  338. response.put("success", false);
  339. response.put("error", "Unauthorized access. Please log in.");
  340. return response;
  341. }
  342. String updatedBy = appUserService.getUserIdByName(username);
  343. if (updatedBy == null)
  344. updatedBy = username;
  345. if (finalDeliveredFile != null && !finalDeliveredFile.isEmpty()) {
  346. if (!isPdfFile(finalDeliveredFile)) {
  347. response.put("success", false);
  348. response.put("error", "Final Delivered file must be a PDF.");
  349. return response;
  350. }
  351. boolean hasPhoto = (userPhotoFile != null && !userPhotoFile.isEmpty())
  352. || (userPhotoBase64 != null && !userPhotoBase64.trim().isEmpty());
  353. if (!hasPhoto) {
  354. response.put("success", false);
  355. response.put("error", "Receiver / User photo is mandatory.");
  356. return response;
  357. }
  358. }
  359. if (userPhotoFile != null && !userPhotoFile.isEmpty() && !isImageFile(userPhotoFile)) {
  360. response.put("success", false);
  361. response.put("error", "User photo must be a valid image file (JPG, PNG, WEBP).");
  362. return response;
  363. }
  364. Map<String, Object> req = tonerService.getUserRequestById(id);
  365. if (req == null) {
  366. response.put("success", false);
  367. response.put("error", "Invalid or non-existent request ID: " + id);
  368. return response;
  369. }
  370. boolean isInitialDelivery = (finalDeliveredFile == null || finalDeliveredFile.isEmpty()) &&
  371. (userPhotoFile == null || userPhotoFile.isEmpty()) &&
  372. (userPhotoBase64 == null || userPhotoBase64.trim().isEmpty());
  373. if (isInitialDelivery) {
  374. int issueQty = 0;
  375. try {
  376. issueQty = Integer.parseInt(qtyIssued.trim());
  377. } catch (Exception e) {
  378. response.put("success", false);
  379. response.put("error", "Invalid quantity issued value.");
  380. return response;
  381. }
  382. if (issueQty <= 0) {
  383. response.put("success", false);
  384. response.put("error", "Quantity issued must be greater than zero.");
  385. return response;
  386. }
  387. String pid = String.valueOf(req.get("pid"));
  388. String tid = String.valueOf(req.get("tid"));
  389. String modelName = req.get("model_name") != null ? String.valueOf(req.get("model_name")) : "Toner";
  390. String printerName = req.get("printer_name") != null ? String.valueOf(req.get("printer_name")) : "Printer";
  391. int availableStock = tonerService.getAvailableStockForModel(pid, tid);
  392. if (availableStock <= 0) {
  393. response.put("success", false);
  394. response.put("error", "Cannot issue: No inward stock available for " + printerName + " - " + modelName
  395. + ". Please register inward stock before issuing outward delivery.");
  396. return response;
  397. }
  398. if (issueQty > availableStock) {
  399. response.put("success", false);
  400. response.put("error",
  401. "Cannot issue: Quantity to issue (" + issueQty + ") exceeds available inward stock ("
  402. + availableStock + ") for " + printerName + " - " + modelName + ".");
  403. return response;
  404. }
  405. int requestedQty = 0;
  406. int alreadyDelivered = 0;
  407. try {
  408. if (req.get("qty_requested") != null) {
  409. requestedQty = Integer.parseInt(String.valueOf(req.get("qty_requested")));
  410. }
  411. if (req.get("qty_delivered") != null) {
  412. alreadyDelivered = Integer.parseInt(String.valueOf(req.get("qty_delivered")));
  413. }
  414. } catch (Exception ignored) {
  415. }
  416. int remainingReq = Math.max(0, requestedQty - alreadyDelivered);
  417. if (issueQty > remainingReq) {
  418. response.put("success", false);
  419. response.put("error", "Cannot issue: Quantity to issue (" + issueQty
  420. + ") exceeds remaining requested quantity (" + remainingReq + ").");
  421. return response;
  422. }
  423. }
  424. try {
  425. File uploadDir = new File(tonerUploadPathConfig).getAbsoluteFile();
  426. if (!uploadDir.exists()) {
  427. uploadDir.mkdirs();
  428. }
  429. String fdPath = saveUploadedFile(finalDeliveredFile, "final_delivered", uploadDir);
  430. String photoPath = null;
  431. if (userPhotoFile != null && !userPhotoFile.isEmpty()) {
  432. photoPath = saveUploadedFile(userPhotoFile, "receiver_photo", uploadDir);
  433. } else if (userPhotoBase64 != null && !userPhotoBase64.trim().isEmpty()) {
  434. photoPath = saveBase64Image(userPhotoBase64, "receiver_photo", uploadDir);
  435. }
  436. boolean saved = tonerService.saveOutwardRegister(
  437. id, qtyIssued.trim(), fdPath, photoPath, updatedBy);
  438. if (saved) {
  439. response.put("success", true);
  440. response.put("message", "Outward delivery recorded successfully.");
  441. } else {
  442. deleteFileIfExists(fdPath, uploadDir);
  443. deleteFileIfExists(photoPath, uploadDir);
  444. response.put("success", false);
  445. response.put("error", "Failed to update outward details in the database.");
  446. }
  447. } catch (Exception e) {
  448. response.put("success", false);
  449. response.put("error", "An error occurred: " + e.getMessage());
  450. e.printStackTrace();
  451. }
  452. return response;
  453. }
  454. @PostMapping("/api/workorder")
  455. @ResponseBody
  456. public Map<String, Object> saveWorkorder(
  457. @RequestParam("fileNumber") String fileNumber,
  458. @RequestParam("vendorName") String vendorName,
  459. @RequestParam("startDate") String startDate,
  460. @RequestParam("endDate") String endDate,
  461. @RequestParam("totalQty") String totalQty,
  462. @RequestParam("itemsJson") String itemsJson,
  463. @RequestParam("dcFile") MultipartFile dcFile,
  464. HttpSession session) {
  465. Map<String, Object> response = new HashMap<>();
  466. String username = (String) session.getAttribute("toner_usrName");
  467. if (username == null) {
  468. response.put("success", false);
  469. response.put("error", "Unauthorized access. Please log in.");
  470. return response;
  471. }
  472. String updatedBy = appUserService.getUserIdByName(username);
  473. if (updatedBy == null)
  474. updatedBy = username;
  475. if (dcFile == null || dcFile.isEmpty()) {
  476. response.put("success", false);
  477. response.put("error", "Delivery Challan (DC) PDF upload file is required.");
  478. return response;
  479. }
  480. if (!isPdfFile(dcFile)) {
  481. response.put("success", false);
  482. response.put("error", "Delivery Challan file must be a PDF.");
  483. return response;
  484. }
  485. // Auto-generate refNo: ITCell-YYYY/MM/DD/XXXX
  486. java.time.LocalDate today = java.time.LocalDate.now();
  487. int randomNum = (int) (Math.random() * 9000) + 1000; // 4-digit random number
  488. String refNo = String.format("ITCell-%d/%02d/%02d/%d", today.getYear(), today.getMonthValue(),
  489. today.getDayOfMonth(), randomNum);
  490. try {
  491. ObjectMapper mapper = new ObjectMapper();
  492. List<Map<String, Object>> items = mapper.readValue(itemsJson,
  493. new TypeReference<List<Map<String, Object>>>() {
  494. });
  495. if (items == null || items.isEmpty()) {
  496. response.put("success", false);
  497. response.put("error", "Please add at least one printer/toner model quantity entry.");
  498. return response;
  499. }
  500. File uploadDir = new File(tonerUploadPathConfig).getAbsoluteFile();
  501. if (!uploadDir.exists()) {
  502. uploadDir.mkdirs();
  503. }
  504. String dcPath = saveUploadedFile(dcFile, "workorder_dc", uploadDir);
  505. boolean saved = tonerService.saveWorkorder(
  506. refNo, fileNumber.trim(), vendorName.trim(),
  507. startDate, endDate, dcPath, totalQty.trim(), items, updatedBy);
  508. if (saved) {
  509. response.put("success", true);
  510. response.put("refNo", refNo);
  511. response.put("message", "Workorder registered successfully.");
  512. } else {
  513. deleteFileIfExists(dcPath, uploadDir);
  514. response.put("success", false);
  515. response.put("error", "Failed to save workorder details in the database.");
  516. }
  517. } catch (Exception e) {
  518. response.put("success", false);
  519. response.put("error", "An error occurred: " + e.getMessage());
  520. e.printStackTrace();
  521. }
  522. return response;
  523. }
  524. @GetMapping("/api/report")
  525. @ResponseBody
  526. public Map<String, Object> getReportData(HttpSession session) {
  527. Map<String, Object> response = new HashMap<>();
  528. if (session.getAttribute("toner_usrName") == null) {
  529. response.put("success", false);
  530. return response;
  531. }
  532. response.put("success", true);
  533. response.put("metrics", tonerService.getDashboardMetrics());
  534. response.put("summary", tonerService.getInventorySummary());
  535. return response;
  536. }
  537. @GetMapping("/api/requests/pending")
  538. @ResponseBody
  539. public List<Map<String, Object>> getPendingRequestsData(HttpSession session) {
  540. if (session.getAttribute("toner_usrName") == null) {
  541. return java.util.Collections.emptyList();
  542. }
  543. return tonerService.getPendingRequests();
  544. }
  545. @GetMapping("/api/inward/list")
  546. @ResponseBody
  547. public List<Map<String, Object>> getInwardListData(HttpSession session) {
  548. if (session.getAttribute("toner_usrName") == null) {
  549. return java.util.Collections.emptyList();
  550. }
  551. return tonerService.getInwardHistory();
  552. }
  553. @GetMapping("/api/requests/list")
  554. @ResponseBody
  555. public List<Map<String, Object>> getUserRequestsListData(HttpSession session) {
  556. if (session.getAttribute("toner_usrName") == null) {
  557. return java.util.Collections.emptyList();
  558. }
  559. return tonerService.getAllUserRequests();
  560. }
  561. @GetMapping("/api/outward/list")
  562. @ResponseBody
  563. public List<Map<String, Object>> getOutwardListData(HttpSession session) {
  564. if (session.getAttribute("toner_usrName") == null) {
  565. return java.util.Collections.emptyList();
  566. }
  567. return tonerService.getOutwardHistory();
  568. }
  569. private boolean isPdfFile(MultipartFile file) {
  570. String originalFilename = file.getOriginalFilename();
  571. if (originalFilename == null)
  572. return false;
  573. return originalFilename.toLowerCase().endsWith(".pdf");
  574. }
  575. private boolean isImageFile(MultipartFile file) {
  576. String originalFilename = file.getOriginalFilename();
  577. if (originalFilename == null)
  578. return false;
  579. String lower = originalFilename.toLowerCase();
  580. return lower.endsWith(".jpg") || lower.endsWith(".jpeg") || lower.endsWith(".png") || lower.endsWith(".webp")
  581. || lower.endsWith(".gif");
  582. }
  583. private String saveUploadedFile(MultipartFile file, String prefix, File uploadDir) throws Exception {
  584. if (file == null || file.isEmpty()) {
  585. return null;
  586. }
  587. String originalFilename = file.getOriginalFilename();
  588. String ext = ".pdf";
  589. if (originalFilename != null && originalFilename.lastIndexOf('.') > 0) {
  590. ext = originalFilename.substring(originalFilename.lastIndexOf('.')).toLowerCase();
  591. }
  592. // Clean filename, make it unique
  593. String savedFilename = prefix + "_" + System.currentTimeMillis() + ext;
  594. File destFile = new File(uploadDir, savedFilename).getAbsoluteFile();
  595. file.transferTo(destFile);
  596. return "gcctonermanagementfiles/" + savedFilename;
  597. }
  598. private String saveBase64Image(String base64Data, String prefix, File uploadDir) throws Exception {
  599. if (base64Data == null || base64Data.trim().isEmpty()) {
  600. return null;
  601. }
  602. String cleanData = base64Data.trim();
  603. String ext = ".jpg";
  604. if (cleanData.contains("data:image/png;base64,")) {
  605. ext = ".png";
  606. cleanData = cleanData.replace("data:image/png;base64,", "");
  607. } else if (cleanData.contains("data:image/jpeg;base64,")) {
  608. ext = ".jpg";
  609. cleanData = cleanData.replace("data:image/jpeg;base64,", "");
  610. } else if (cleanData.contains("data:image/webp;base64,")) {
  611. ext = ".webp";
  612. cleanData = cleanData.replace("data:image/webp;base64,", "");
  613. } else if (cleanData.startsWith("data:") && cleanData.contains(";base64,")) {
  614. cleanData = cleanData.substring(cleanData.indexOf(";base64,") + 8);
  615. }
  616. byte[] decodedBytes = java.util.Base64.getDecoder().decode(cleanData);
  617. String savedFilename = prefix + "_" + System.currentTimeMillis() + ext;
  618. File destFile = new File(uploadDir, savedFilename).getAbsoluteFile();
  619. try (java.io.FileOutputStream fos = new java.io.FileOutputStream(destFile)) {
  620. fos.write(decodedBytes);
  621. }
  622. return "gcctonermanagementfiles/" + savedFilename;
  623. }
  624. private void deleteFileIfExists(String webPath, File uploadDir) {
  625. if (webPath == null || webPath.isEmpty())
  626. return;
  627. try {
  628. String filename = webPath.substring(webPath.lastIndexOf('/') + 1);
  629. File file = new File(uploadDir, filename).getAbsoluteFile();
  630. if (file.exists()) {
  631. file.delete();
  632. }
  633. } catch (Exception e) {
  634. System.err.println("Error deleting file: " + e.getMessage());
  635. }
  636. }
  637. @GetMapping("/api/workorders/active")
  638. @ResponseBody
  639. public List<String> getActiveWorkorderRefNos(HttpSession session) {
  640. if (session.getAttribute("toner_usrName") == null) {
  641. return new ArrayList<>();
  642. }
  643. return tonerService.getActiveWorkorderRefNos();
  644. }
  645. @GetMapping("/api/workorders/items")
  646. @ResponseBody
  647. public List<Map<String, Object>> getWorkorderRegisteredItems(
  648. @RequestParam("refNo") String refNo,
  649. HttpSession session) {
  650. if (session.getAttribute("toner_usrName") == null) {
  651. return new ArrayList<>();
  652. }
  653. return tonerService.getWorkorderRegisteredItems(refNo);
  654. }
  655. @GetMapping("/api/workorder/history")
  656. @ResponseBody
  657. public List<Map<String, Object>> getWorkorderRegisterHistory(HttpSession session) {
  658. if (session.getAttribute("toner_usrName") == null) {
  659. return new ArrayList<>();
  660. }
  661. return tonerService.getWorkorderRegisterHistory();
  662. }
  663. @PostMapping("/api/workorder-request")
  664. @ResponseBody
  665. public Map<String, Object> uploadWorkorderModelRequest(
  666. @RequestParam("refNo") String refNo,
  667. @RequestParam("companyName") String companyName,
  668. @RequestParam("pid") String pid,
  669. @RequestParam("itemsJson") String itemsJson,
  670. @RequestParam("emailCopyFile") MultipartFile emailCopyFile,
  671. HttpSession session) {
  672. Map<String, Object> response = new HashMap<>();
  673. String username = (String) session.getAttribute("toner_usrName");
  674. if (username == null) {
  675. response.put("success", false);
  676. response.put("error", "Unauthorized access. Please log in.");
  677. return response;
  678. }
  679. String updatedBy = appUserService.getUserIdByName(username);
  680. if (updatedBy == null)
  681. updatedBy = username;
  682. if (emailCopyFile == null || emailCopyFile.isEmpty()) {
  683. response.put("success", false);
  684. response.put("error", "Email copy PDF upload file is required.");
  685. return response;
  686. }
  687. if (!isPdfFile(emailCopyFile)) {
  688. response.put("success", false);
  689. response.put("error", "Email copy file must be a PDF.");
  690. return response;
  691. }
  692. try {
  693. ObjectMapper mapper = new ObjectMapper();
  694. List<Map<String, Object>> items = mapper.readValue(itemsJson,
  695. new TypeReference<List<Map<String, Object>>>() {
  696. });
  697. if (items == null || items.isEmpty()) {
  698. response.put("success", false);
  699. response.put("error", "Please add at least one toner model quantity entry.");
  700. return response;
  701. }
  702. File uploadDir = new File(tonerUploadPathConfig).getAbsoluteFile();
  703. if (!uploadDir.exists()) {
  704. uploadDir.mkdirs();
  705. }
  706. String ecPath = saveUploadedFile(emailCopyFile, "workorder_request_email",
  707. uploadDir);
  708. boolean saved = tonerService.saveWorkorderModelRequest(
  709. refNo.trim(), companyName.trim(), pid.trim(), items, ecPath, updatedBy);
  710. if (saved) {
  711. response.put("success", true);
  712. response.put("message",
  713. "Workorder model request details saved successfully.");
  714. } else {
  715. deleteFileIfExists(ecPath, uploadDir);
  716. response.put("success", false);
  717. response.put("error",
  718. "Failed to save workorder request details in the database.");
  719. }
  720. } catch (Exception e) {
  721. response.put("success", false);
  722. response.put("error", "An error occurred: " + e.getMessage());
  723. e.printStackTrace();
  724. }
  725. return response;
  726. }
  727. @GetMapping("/api/workorders/active-requests")
  728. @ResponseBody
  729. public List<String> getActiveWorkorderRequestRefNos(HttpSession session) {
  730. if (session.getAttribute("toner_usrName") == null) {
  731. return new ArrayList<>();
  732. }
  733. return tonerService.getActiveWorkorderRequestRefNos();
  734. }
  735. @GetMapping("/api/workorders/requests")
  736. @ResponseBody
  737. public List<Map<String, Object>> getWorkorderRequests(
  738. @RequestParam("refNo") String refNo,
  739. HttpSession session) {
  740. if (session.getAttribute("toner_usrName") == null) {
  741. return new ArrayList<>();
  742. }
  743. return tonerService.getWorkorderRequests(refNo);
  744. }
  745. @GetMapping("/api/workorder-request/history")
  746. @ResponseBody
  747. public List<Map<String, Object>> getWorkorderModelRequestHistory(HttpSession session) {
  748. if (session.getAttribute("toner_usrName") == null) {
  749. return new ArrayList<>();
  750. }
  751. return tonerService.getWorkorderModelRequestHistory();
  752. }
  753. // Save new department for workorder
  754. @PostMapping("/api/savedepartment")
  755. @ResponseBody
  756. public boolean saveNewDepartment(
  757. @RequestParam("department") String department,
  758. HttpSession session) {
  759. if (session.getAttribute("toner_usrName") == null) {
  760. return false;
  761. }
  762. return tonerService.savenewdepartment(department);
  763. }
  764. @PostMapping("/api/savetonermodel")
  765. @ResponseBody
  766. public boolean saveNewTonerModel(
  767. @RequestParam("tonermodel") String tonermodel,
  768. @RequestParam("pid") int pid,
  769. @RequestParam(required = false) String partCode,
  770. HttpSession session) {
  771. if (session.getAttribute("toner_usrName") == null) {
  772. return false;
  773. }
  774. return tonerService.savetonermodel(pid, tonermodel, partCode);
  775. }
  776. @PostMapping("/api/saveprintermodel")
  777. @ResponseBody
  778. public boolean saveNewPrinterModel(
  779. @RequestParam("printermodel") String printermodel,
  780. HttpSession session) {
  781. if (session.getAttribute("toner_usrName") == null) {
  782. return false;
  783. }
  784. return tonerService.saveprintermodel(printermodel);
  785. }
  786. // ================= MASTER UPDATE ENDPOINTS =================
  787. @PostMapping("/api/updateprintermodel")
  788. @ResponseBody
  789. public boolean updatePrinterModel(
  790. @RequestParam("id") int id,
  791. @RequestParam("printermodel") String printermodel,
  792. HttpSession session) {
  793. if (session.getAttribute("toner_usrName") == null) {
  794. return false;
  795. }
  796. return tonerService.updatePrinterModel(id, printermodel);
  797. }
  798. @PostMapping("/api/updatetonermodel")
  799. @ResponseBody
  800. public boolean updateTonerModel(
  801. @RequestParam("id") int id,
  802. @RequestParam("pid") int pid,
  803. @RequestParam("tonermodel") String tonermodel,
  804. @RequestParam(value = "partCode", required = false) String partCode,
  805. HttpSession session) {
  806. if (session.getAttribute("toner_usrName") == null) {
  807. return false;
  808. }
  809. return tonerService.updateTonerModel(id, pid, tonermodel, partCode);
  810. }
  811. @PostMapping("/api/updatedepartment")
  812. @ResponseBody
  813. public boolean updateDepartment(
  814. @RequestParam("id") int id,
  815. @RequestParam("department") String department,
  816. HttpSession session) {
  817. if (session.getAttribute("toner_usrName") == null) {
  818. return false;
  819. }
  820. return tonerService.updateDepartment(id, department);
  821. }
  822. // ================= MASTER DELETE & RESTORE ENDPOINTS =================
  823. @PostMapping("/api/deleteprintermodel")
  824. @ResponseBody
  825. public boolean deletePrinterModel(@RequestParam("id") int id, HttpSession session) {
  826. if (session.getAttribute("toner_usrName") == null) {
  827. return false;
  828. }
  829. return tonerService.deletePrinterModel(id);
  830. }
  831. @PostMapping("/api/restoreprintermodel")
  832. @ResponseBody
  833. public boolean restorePrinterModel(@RequestParam("id") int id, HttpSession session) {
  834. if (session.getAttribute("toner_usrName") == null) {
  835. return false;
  836. }
  837. return tonerService.restorePrinterModel(id);
  838. }
  839. @PostMapping("/api/deletetonermodel")
  840. @ResponseBody
  841. public boolean deleteTonerModel(@RequestParam("id") int id, HttpSession session) {
  842. if (session.getAttribute("toner_usrName") == null) {
  843. return false;
  844. }
  845. return tonerService.deleteTonerModel(id);
  846. }
  847. @PostMapping("/api/restoretonermodel")
  848. @ResponseBody
  849. public boolean restoreTonerModel(@RequestParam("id") int id, HttpSession session) {
  850. if (session.getAttribute("toner_usrName") == null) {
  851. return false;
  852. }
  853. return tonerService.restoreTonerModel(id);
  854. }
  855. @PostMapping("/api/deletedepartment")
  856. @ResponseBody
  857. public boolean deleteDepartment(@RequestParam("id") int id, HttpSession session) {
  858. if (session.getAttribute("toner_usrName") == null) {
  859. return false;
  860. }
  861. return tonerService.deleteDepartment(id);
  862. }
  863. @PostMapping("/api/restoredepartment")
  864. @ResponseBody
  865. public boolean restoreDepartment(@RequestParam("id") int id, HttpSession session) {
  866. if (session.getAttribute("toner_usrName") == null) {
  867. return false;
  868. }
  869. return tonerService.restoreDepartment(id);
  870. }
  871. // ================= MASTER LISTING ENDPOINTS =================
  872. @GetMapping("/api/master/printers")
  873. @ResponseBody
  874. public List<Map<String, Object>> getMasterPrinters(
  875. @RequestParam(value = "status", defaultValue = "active") String status,
  876. HttpSession session) {
  877. if (session.getAttribute("toner_usrName") == null) {
  878. return java.util.Collections.emptyList();
  879. }
  880. return tonerService.getMasterPrinters(status);
  881. }
  882. @GetMapping("/api/master/toners")
  883. @ResponseBody
  884. public List<Map<String, Object>> getMasterToners(
  885. @RequestParam(value = "status", defaultValue = "active") String status,
  886. HttpSession session) {
  887. if (session.getAttribute("toner_usrName") == null) {
  888. return java.util.Collections.emptyList();
  889. }
  890. return tonerService.getMasterToners(status);
  891. }
  892. @GetMapping("/api/master/departments")
  893. @ResponseBody
  894. public List<Map<String, Object>> getMasterDepartments(
  895. @RequestParam(value = "status", defaultValue = "active") String status,
  896. HttpSession session) {
  897. if (session.getAttribute("toner_usrName") == null) {
  898. return java.util.Collections.emptyList();
  899. }
  900. return tonerService.getMasterDepartments(status);
  901. }
  902. @GetMapping("/api/toners/all")
  903. @ResponseBody
  904. public List<Map<String, Object>> getAllToners(HttpSession session) {
  905. if (session.getAttribute("toner_usrName") == null) {
  906. return java.util.Collections.emptyList();
  907. }
  908. return tonerService.getAllActiveToners();
  909. }
  910. }