diff --git a/.DS_Store b/.DS_Store index 94309ab..7ce37ec 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/mobileservice/.DS_Store b/mobileservice/.DS_Store index 8e2c6fe..2321e6a 100644 Binary files a/mobileservice/.DS_Store and b/mobileservice/.DS_Store differ diff --git a/mobileservice/src/.DS_Store b/mobileservice/src/.DS_Store index 87dbb0d..f10f98a 100644 Binary files a/mobileservice/src/.DS_Store and b/mobileservice/src/.DS_Store differ diff --git a/mobileservice/src/main/.DS_Store b/mobileservice/src/main/.DS_Store index a2d343b..175747f 100644 Binary files a/mobileservice/src/main/.DS_Store and b/mobileservice/src/main/.DS_Store differ diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/configuration/DataSourceConfig.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/configuration/DataSourceConfig.java index 45618e6..65fd050 100644 --- a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/configuration/DataSourceConfig.java +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/configuration/DataSourceConfig.java @@ -390,6 +390,117 @@ public class DataSourceConfig { dataSource.setPassword(dbpassword); return dataSource; } + + /////////////////////////////(For ManHole) //////////////////////// + @Bean(name = "mysqlGccManHoleSource") + public DataSource mysqlGccManHoleSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://"+host+"/gcc_manholes"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + + /////////////////////////////(For Disposal Point) //////////////////////// + @Bean(name = "mysqlGccDisposalPointSource") + public DataSource mysqlGccDisposalPointSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://"+host+"/gcc_disposalpoint"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + + /////////////////////////////(For Street Cleaning) //////////////////////// + @Bean(name = "mysqlGccStreetCleaningSource") + public DataSource mysqlGccStreetCleaningSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://"+host+"/gcc_street_cleaning"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + + /////////////////////////////(For Pumps & Sumps) //////////////////////// + @Bean(name = "mysqlGccPumpSource") + public DataSource mysqlGccPumpSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://"+host+"/gcc_pumps"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + + /////////////////////////////(For Special Vehicles) //////////////////////// + @Bean(name = "mysqlGccSpecialVehicleSource") + public DataSource mysqlGccSpecialVehicleSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://"+host+"/gcc_special_vehicle"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + + /////////////////////////////(For Sluice Point) //////////////////////// + @Bean(name = "mysqlGccSluicePointSource") + public DataSource mysqlGccSluicePointSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://"+host+"/gcc_sluicepoint"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + + /////////////////////////////(For Railway Culverts) //////////////////////// + @Bean(name = "mysqlGccRailwayCulvertSource") + public DataSource mysqlGccRailwayCulvertSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://"+host+"/gcc_railway_culvert"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + + /////////////////////////////(For Food Distribution) //////////////////////// + @Bean(name = "mysqlGccFoodDistributionSource") + public DataSource mysqlGccFoodDistributionSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://"+host+"/gcc_food_distribution"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + + //////////////////////////////(For FlagPole) //////////////////////// + @Bean(name = "mysqlGccFlagPoleDataSource") + public DataSource mysqlGccFlagPoleDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://"+host+"/gcc_flag_pole"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + + //////////////////////////////For Medical Camp //////////////////////// + @Bean(name = "mysqlGccMedicalCampDataSource") + public DataSource mysqlGccMedicalCampDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://"+host+"/gcc_health_camp"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + ////////////////////////////// ORACLE //////////////////////// @Bean(name = "oracleERPDataSource") diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/controller/FileController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/controller/FileController.java index 811dddf..c1bbaa5 100644 --- a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/controller/FileController.java +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/controller/FileController.java @@ -33,7 +33,9 @@ public class FileController { String relativePath = fullPath.replace("/gccofficialapp/files", ""); String filePath = uploadDirectory + "/" + relativePath; Path path = Paths.get(filePath).normalize(); - System.out.println(path.toString()); + + //System.out.println(path.toString()); + Resource resource; try { resource = new UrlResource(path.toUri()); diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/disposalPoint/controller/DisposalPointController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/disposalPoint/controller/DisposalPointController.java new file mode 100644 index 0000000..1e2e524 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/disposalPoint/controller/DisposalPointController.java @@ -0,0 +1,111 @@ +package in.gov.chennaicorporation.mobileservice.disposalPoint.controller; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +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.RestController; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.disposalPoint.service.DisposalPointService; + +@RequestMapping("/gccofficialapp/api/disposalpoint/") +@RestController("gccofficialappsdisposalpoint") +public class DisposalPointController { + + @Autowired + private DisposalPointService disposalPointService; + + @GetMapping(value="/getDisposalPointListForMap") + public List getDisposalPointListFormap( + @RequestParam(value="loginId", required = true) String cby + ){ + return disposalPointService.getDisposalPointListForMap(cby); + } + + @GetMapping(value="/getDisposalPointList") + public List getDisposalPointList( + @RequestParam(value="loginId", required = true) String cby + ){ + return disposalPointService.getDisposalPointList(cby); + } + + @PostMapping("/saveDisposalPoint") + public List saveDisposalPoint( + @RequestParam(value = "zone", required = true) String zone, + @RequestParam(value = "ward", required = true) String ward, + @RequestParam(value = "street_name", required = false) String street_name, + @RequestParam(value = "street_id", required = false) String street_id, + @RequestParam(value = "latitude", required = true) String latitude, + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "loginId", required = true) String loginId, + @RequestParam(value = "file", required = true) MultipartFile file + ) { + return disposalPointService.saveDisposalPoint( + zone, + ward, + street_name, + street_id, + latitude, + longitude, + loginId, + file + ); + } + + @PostMapping("/saveActivity") + public List saveActivity( + @RequestParam(value = "disposalpoint_id", required = true) String disposalpoint_id, + @RequestParam(value = "file", required = true) MultipartFile file, + @RequestParam(value = "video", required = true) MultipartFile video, + @RequestParam(value = "zone", required = true) String zone, + @RequestParam(value = "ward", required = true) String ward, + @RequestParam(value = "street_name", required = false) String street_name, + @RequestParam(value = "street_id", required = false) String street_id, + @RequestParam(value = "latitude", required = true) String latitude, + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "loginId", required = true) String loginId + ) { + return disposalPointService.saveActivity( + disposalpoint_id, + file, + video, + zone, + ward, + street_name, + street_id, + latitude, + longitude, + loginId, + "before" + ); + } + + @GetMapping(value="/getZoneSummary") + public List getZoneSummary( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate + ){ + return disposalPointService.getZoneSummary(fromDate, toDate); + } + + @GetMapping(value="/getWardSummary") + public List getWardSummary( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate, + @RequestParam(value="zone", required = true) String zone + ){ + return disposalPointService.getWardSummary(fromDate, toDate, zone); + } + + @GetMapping(value="/getDisposalPointSummary") + public List getDisposalPointSummary( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate, + @RequestParam(value="ward", required = true) String ward + ){ + return disposalPointService.getDisposalPointSummary(fromDate, toDate, ward); + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/disposalPoint/service/DisposalPointService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/disposalPoint/service/DisposalPointService.java new file mode 100644 index 0000000..19ee091 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/disposalPoint/service/DisposalPointService.java @@ -0,0 +1,773 @@ +package in.gov.chennaicorporation.mobileservice.disposalPoint.service; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.SecureRandom; +import java.sql.PreparedStatement; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.env.Environment; +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; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; + +import in.gov.chennaicorporation.mobileservice.gccactivity.service.DateTimeUtil; + +@Service +public class DisposalPointService { + +private JdbcTemplate jdbcDisposalPointTemplate; + + private final Environment environment; + private String fileBaseUrl; + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int STRING_LENGTH = 15; + private static final Random RANDOM = new SecureRandom(); + + @Autowired + public void setDataSource(@Qualifier("mysqlGccDisposalPointSource") DataSource DisposalPointDataSource) { + this.jdbcDisposalPointTemplate = new JdbcTemplate(DisposalPointDataSource); + } + + @Autowired + public DisposalPointService(Environment environment) { + this.environment = environment; + this.fileBaseUrl=environment.getProperty("fileBaseUrl"); + } + + public static String generateRandomString() { + StringBuilder result = new StringBuilder(STRING_LENGTH); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + public static String generateRandomFileString(int lenthval) { + StringBuilder result = new StringBuilder(lenthval); + for (int i = 0; i < lenthval; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + private byte[] compressImage(BufferedImage image, float quality) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream); + + ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next(); + writer.setOutput(imageOutputStream); + + ImageWriteParam param = writer.getDefaultWriteParam(); + if (param.canWriteCompressed()) { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(quality); + } + + writer.write(null, new javax.imageio.IIOImage(image, null, null), param); + + writer.dispose(); + imageOutputStream.close(); + + return byteArrayOutputStream.toByteArray(); + } + + // Function to convert date string from dd-MM-yyyy to yyyy-MM-dd + public static String convertDateFormat(String inputDate, int add) { + // Check if the inputDate is not null or blank + if (inputDate != null && !inputDate.isBlank()) { + try { + // Define the input and output date formats + DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + // Parse the input date string to LocalDate + LocalDate date = LocalDate.parse(inputDate, inputFormatter); + + // Add the specified number of days to the date if 'add' is greater than 0 + if (add > 0) { + date = date.plusDays(add); + } + + // Format the date to the new format + return date.format(outputFormatter); + + } catch (DateTimeParseException e) { + // Handle the case where the input date is invalid + System.out.println("Invalid date format: " + inputDate); + return ""; + } + } else { + return ""; + } + } + + public String fileUpload(String name, String id, MultipartFile file, String filetype) { + + int lastInsertId = 0; + // Set the file path where you want to save it + String uploadDirectory = environment.getProperty("file.upload.directory"); + String serviceFolderName = environment.getProperty("disposalpoint_foldername"); + var year = DateTimeUtil.getCurrentYear(); + var month = DateTimeUtil.getCurrentMonth(); + var date = DateTimeUtil.getCurrentDay(); + + uploadDirectory = uploadDirectory + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date; + + try { + // Create directory if it doesn't exist + Path directoryPath = Paths.get(uploadDirectory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Datetime string + String datetimetxt = DateTimeUtil.getCurrentDateTime(); + + datetimetxt = datetimetxt + "_"+ generateRandomFileString(6); // Attached Random text + + // File name + String fileName = name + "_" + id + "_" + datetimetxt + "_" + file.getOriginalFilename(); + fileName = fileName.replaceAll("\\s+", ""); // Remove space on filename + + String filePath = uploadDirectory + "/" + fileName; + + String filepath_txt = "/" + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date + "/" + fileName; + + // Create a new Path object + Path path = Paths.get(filePath); + + // Get the bytes of the file + byte[] bytes = file.getBytes(); + + if(filetype.equalsIgnoreCase("image")) + { + // Compress the image + BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); + byte[] compressedBytes = compressImage(image, 0.5f); // Compress with 50% quality + // Write the bytes to the file + Files.write(path, compressedBytes); + } + else { + // Write the bytes to the file + Files.write(path, bytes); + } + // Get current date & time + LocalDateTime now = LocalDateTime.now(); + + // Format date-time (optional) + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + System.out.println("Date: "+ now.format(formatter)); + System.out.println("Activity: DisposalPoint"); + System.out.println("File Type: " + filetype); + System.out.println("File Upload Path: " + filePath); + System.out.println("File Path: " + filepath_txt); + + return filepath_txt; + + } catch (IOException e) { + e.printStackTrace(); + System.out.println("Failed to save file " + file.getOriginalFilename()); + return "error"; + } + } + + public String getWardByLoginId(String loginid, String type) { + String sqlQuery = "SELECT `ward` FROM gcc_penalty_hoardings.`hoading_user_list` WHERE `userid` = ? AND `type` = ? LIMIT 1"; + + // Query the database using queryForList + List> results = jdbcDisposalPointTemplate.queryForList(sqlQuery, loginid, type); + + // Check if results is not empty and extract the ward value + if (!results.isEmpty()) { + // Extract the ward value from the first result + return (String) results.get(0).get("ward"); + } + + // Handle the case where no result is found + return "000"; // or return null based on your needs + } + + @Transactional + public List> saveDisposalPoint( + String zone, + String ward, + String street_name, + String street_id, + String latitude, + String longitude, + String inby, + MultipartFile file + ) { + + String filetxt = inby; + + String action = "new_mapping"; + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // For Image + String filetype = "image"; + String activityimg = fileUpload(action, filetxt, file, filetype); + + if ("error".equalsIgnoreCase(activityimg)) { + response.put("status", "error"); + response.put("message", "Disposal Point new mapping image insert failed."); + result.add(response); + return result; + } + + String insertSqltxt = "INSERT INTO disposalpoint_mapped_master(`zone`, `ward`, `road_name`, `road_gisid`, `latitude`, `longitude`, `inby`, `file`) " + + "VALUES (?,?,?,?,?,?,?,?)"; + + String insertSql = insertSqltxt; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcDisposalPointTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"disposalpoint_id"}); + int i = 1; + ps.setString(i++, zone); + ps.setString(i++, ward); + ps.setString(i++, street_name); + ps.setString(i++, street_id); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, inby); + ps.setString(i++, activityimg); + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Disposal Point", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", "Disposal Point " + action + " data inserted successfully."); + } else { + response.put("Disposal Point", action + " insertId error!"); + response.put("status", "error"); + response.put("message", "Disposal Point " + action + " data insert failed."); + } + + result.add(response); + return result; + } + + public List> getDisposalPointListForMap(String loginid) { + + String ward = getWardByLoginId(loginid,"ae"); + + String sqlManhole = "SELECT " + + " d.zone," + + " d.ward," + + " COUNT(*) AS total_disposal_points," + + " (SELECT COUNT(*) " + + " FROM disposalpoint_mapped_master m" + + " WHERE m.isactive = 1 AND m.isdelete = 0 AND m.ward = d.ward) AS total_mapped_points," + + " (COUNT(*) - " + + " (SELECT COUNT(*) " + + " FROM disposalpoint_mapped_master m" + + " WHERE m.isactive = 1 AND m.isdelete = 0 AND m.ward = d.ward)" + + " ) AS total_pending_points " + + "FROM disposalpoint_master d " + + "WHERE d.isactive = 1 AND d.isdelete = 0" + + " AND d.ward = ? " + + "GROUP BY d.ward " + + "ORDER BY d.ward"; + List> disposalpoints = jdbcDisposalPointTemplate.queryForList(sqlManhole, ward); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Dispoasl Map List."); + response.put("data", disposalpoints); + + return Collections.singletonList(response); + } + + public List> getDisposalPointList(String loginid) { + + String ward = getWardByLoginId(loginid,"ae"); + + // 1. Fetch all Disposal Points for the given SWDID + String sqlManhole = "SELECT *, " + + "CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `file`) AS img_file_url " + + " FROM disposalpoint_mapped_master WHERE ward = ? AND `isactive`=1 AND `isdelete`=0"; + List> disposalpoints = jdbcDisposalPointTemplate.queryForList(sqlManhole, ward); + + List> finalList = new ArrayList<>(); + + for (Map disposalpoint : disposalpoints) { + Map disposalpointResponse = new HashMap<>(); + disposalpointResponse.putAll(disposalpoint); // add all Disposal point columns + + // 2. Fetch before activity + String sqlBefore = "SELECT *," + + "CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `img_file`) AS img_file_url," + + "CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `video_file`) AS video_file_url " + + "FROM before_activity WHERE disposalpoint_id = ? " + + "AND indate >= CURDATE() " + + "AND indate < CURDATE() + INTERVAL 1 DAY " + + "AND isactive=1 AND isdelete=0"; + List> beforeActivities = jdbcDisposalPointTemplate.queryForList(sqlBefore, + disposalpoint.get("disposalpoint_id")); + + Map beforeData = new HashMap<>(); + if (!beforeActivities.isEmpty()) { + beforeData.put("status", "Completed"); + beforeData.put("details", beforeActivities); + } else { + beforeData.put("status", "Pending"); + beforeData.put("details", Collections.emptyList()); + } + + // 4. Overall Disposal Point status + String overallStatus = (!beforeActivities.isEmpty()) ? "Completed" : "Pending"; + disposalpointResponse.put("status", overallStatus); + disposalpointResponse.put("before", beforeData); + + finalList.add(disposalpointResponse); + } + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Dispoasl List."); + response.put("data", finalList); + + return Collections.singletonList(response); + } + + @Transactional + public List> saveActivity( + String disposalpoint_id, + MultipartFile file, + MultipartFile video, + String zone, + String ward, + String street_name, + String street_id, + String latitude, + String longitude, + String inby, + String action + ) { + + String filetxt =disposalpoint_id; + + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // For Image + String filetype = "image"; + String activityimg = fileUpload(action, filetxt, file, filetype); + + if ("error".equalsIgnoreCase(activityimg)) { + response.put("status", "error"); + response.put("message", "Disposal Point activity image insert failed."); + result.add(response); + return result; + } + + // For Video + filetype = "video"; + String activityvideo = fileUpload(action, filetxt, video, filetype); + + if ("error".equalsIgnoreCase(activityvideo)) { + response.put("status", "error"); + response.put("message", "Disposal Point activity video insert failed."); + result.add(response); + return result; + } + + String insertBeforeSql = "INSERT INTO before_activity(disposalpoint_id, img_file, video_file, zone, ward, street_name, street_id, latitude, longitude, inby) " + + "VALUES (?,?,?,?,?,?,?,?,?,?)"; + + /* + String insertAfterSql = "INSERT INTO after_activity(disposalpoint_id, file, zone, ward, street_name, street_id, latitude, longitude, inby, before_activity_id, clean_type) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"; + + String insertSql = "before".equalsIgnoreCase(action) ? insertBeforeSql : insertAfterSql; + */ + + String insertSql = insertBeforeSql; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcDisposalPointTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"activity_id"}); + int i = 1; + ps.setString(i++, disposalpoint_id); + ps.setString(i++, activityimg); + ps.setString(i++, activityvideo); + ps.setString(i++, zone); + ps.setString(i++, ward); + ps.setString(i++, street_name); + ps.setString(i++, street_id); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, inby); +/* + if ("after".equalsIgnoreCase(action)) { + ps.setString(i++, beforeActivityId); + ps.setString(i++, clean_type); + } +*/ + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Disposal Point", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", "Disposal Point " + action + " activity inserted successfully."); + } else { + response.put("Disposal Point", action + " insertId error!"); + response.put("status", "error"); + response.put("message", "Disposal Point " + action + " activity insert failed."); + } + + result.add(response); + return result; + } + /* + public List> getZoneSummary(String fromDate, String toDate) { + + fromDate = convertDateFormat(fromDate,0); + toDate = convertDateFormat(toDate,0); + + // SQL: count completed days per zone + String sql = "SELECT d.zone, COUNT(DISTINCT DATE(b.indate)) AS completedDays " + + "FROM disposalpoint_mapped_master d " + + "LEFT JOIN before_activity b ON d.disposalpoint_id = b.disposalpoint_id " + + "AND b.indate >= ? AND b.indate < DATE_ADD(?, INTERVAL 1 DAY) " + + "AND b.isactive=1 AND b.isdelete=0 " + + "WHERE d.isactive=1 AND d.isdelete=0 " + + "GROUP BY d.zone ORDER BY d.zone"; + + List> results = jdbcDisposalPointTemplate.queryForList(sql, fromDate, toDate); + + long totalDays = ChronoUnit.DAYS.between( + LocalDate.parse(fromDate), + LocalDate.parse(toDate) + ) + 1; + + List> finalList = new ArrayList<>(); + for (Map row : results) { + Map Report = new HashMap<>(); + long completed = ((Number) row.get("completedDays")).longValue(); + Report.put("zone", row.get("zone")); + Report.put("totalDays", totalDays); + Report.put("completed", completed); + Report.put("pending", totalDays - completed); + finalList.add(Report); + } + + return finalList; + } + */ + + @Transactional(readOnly = true) + public List> getZoneSummary(String fromDate, String toDate) { + + fromDate = convertDateFormat(fromDate, 0); + toDate = convertDateFormat(toDate, 0); + + String sql = + "SELECT " + + " z.zone, " + + " COALESCE(dm.total_disposal_points, 0) AS total_disposal_points, " + + " COALESCE(mm.total_mapped_points, 0) AS total_mapped_points, " + + " COALESCE(COUNT(DISTINCT (b.disposalpoint_id), 0)) AS completed_days " + + "FROM (" + + " SELECT DISTINCT zone FROM disposalpoint_master WHERE isactive=1 AND isdelete=0" + + ") z " + + "LEFT JOIN (" + + " SELECT zone, COUNT(*) AS total_disposal_points " + + " FROM disposalpoint_master " + + " WHERE isactive=1 AND isdelete=0 " + + " GROUP BY zone" + + ") dm ON z.zone = dm.zone " + + "LEFT JOIN (" + + " SELECT zone, COUNT(*) AS total_mapped_points " + + " FROM disposalpoint_mapped_master " + + " WHERE isactive=1 AND isdelete=0 " + + " GROUP BY zone" + + ") mm ON z.zone = mm.zone " + + "LEFT JOIN disposalpoint_mapped_master dmm ON dmm.zone = z.zone AND dmm.isactive=1 AND dmm.isdelete=0 " + + "LEFT JOIN before_activity b ON dmm.disposalpoint_id = b.disposalpoint_id " + + " AND b.isactive=1 AND b.isdelete=0 " + + " AND b.indate >= ? AND b.indate < DATE_ADD(?, INTERVAL 1 DAY) " + + "GROUP BY z.zone, dm.total_disposal_points, mm.total_mapped_points " + + "ORDER BY z.zone"; + + List> results = jdbcDisposalPointTemplate.queryForList(sql, fromDate, toDate); + + long totalDays = ChronoUnit.DAYS.between( + LocalDate.parse(fromDate), + LocalDate.parse(toDate) + ) + 1; + + List> finalList = new ArrayList<>(); + + long grandTotalDisposalPoints = 0; + long grandTotalMappedPoints = 0; + long grandCompletedDays = 0; + long grandPendingDays = 0; + + + for (Map row : results) { + Map report = new LinkedHashMap<>(); + long completed = ((Number) row.get("completed_days")).longValue(); + long totalDisposalPoints = ((Number) row.get("total_disposal_points")).longValue(); + long totalMappedPoints = ((Number) row.get("total_mapped_points")).longValue(); + + long totalDays_final = (totalDays*totalMappedPoints); + + report.put("zone", row.get("zone")); + report.put("totalDisposalPoints", totalDisposalPoints); + report.put("totalMappedPoints", totalMappedPoints); + report.put("totalDays", totalDays_final); + report.put("completedDays", completed); + report.put("pendingDays", (totalDays_final - completed)); + + finalList.add(report); + + // accumulate grand totals + grandTotalDisposalPoints += totalDisposalPoints; + grandTotalMappedPoints += totalMappedPoints; + grandCompletedDays += completed; + grandPendingDays +=(totalDays_final - completed); + } + + // add grand total row + Map grandTotalRow = new LinkedHashMap<>(); + grandTotalRow.put("zone", "TOTAL"); + grandTotalRow.put("totalDisposalPoints", grandTotalDisposalPoints); + grandTotalRow.put("totalMappedPoints", grandTotalMappedPoints); + grandTotalRow.put("totalDays", totalDays); + grandTotalRow.put("completedDays", grandCompletedDays); + grandTotalRow.put("pendingDays", grandPendingDays); // total pending across all wards + + finalList.add(grandTotalRow); + + return finalList; + } + /* + public List> getWardSummary(String fromDate, String toDate, String zone) { + + fromDate = convertDateFormat(fromDate,0); + toDate = convertDateFormat(toDate,0); + + // SQL: count completed days per ward + String sql = "SELECT d.ward, COUNT(DISTINCT DATE(b.indate)) AS completedDays " + + "FROM disposalpoint_mapped_master d " + + "LEFT JOIN before_activity b ON d.disposalpoint_id = b.disposalpoint_id " + + "AND b.indate >= ? AND b.indate < DATE_ADD(?, INTERVAL 1 DAY) " + + "AND b.isactive=1 AND b.isdelete=0 " + + "WHERE d.isactive=1 AND d.isdelete=0 AND d.zone=?" + + "GROUP BY d.ward ORDER BY d.ward"; + + List> results = jdbcDisposalPointTemplate.queryForList(sql, fromDate, toDate, zone); + + long totalDays = ChronoUnit.DAYS.between( + LocalDate.parse(fromDate), + LocalDate.parse(toDate) + ) + 1; + + List> finalList = new ArrayList<>(); + for (Map row : results) { + Map Report = new HashMap<>(); + long completed = ((Number) row.get("completedDays")).longValue(); + Report.put("ward", row.get("ward")); + Report.put("totalDays", totalDays); + Report.put("completed", completed); + Report.put("pending", totalDays - completed); + finalList.add(Report); + } + + return finalList; + } + */ + + @Transactional(readOnly = true) + public List> getWardSummary(String fromDate, String toDate, String zone) { + + fromDate = convertDateFormat(fromDate, 0); + toDate = convertDateFormat(toDate, 0); + + String sql = + "SELECT " + + " w.ward, " + + " COALESCE(dm.total_disposal_points, 0) AS total_disposal_points, " + + " COALESCE(mm.total_mapped_points, 0) AS total_mapped_points, " + + " COALESCE(COUNT(DISTINCT (b.disposalpoint_id), 0)) AS completed_days " + + "FROM (" + + " SELECT DISTINCT ward FROM disposalpoint_master WHERE isactive=1 AND isdelete=0 AND zone=?" + + ") w " + + "LEFT JOIN (" + + " SELECT ward, COUNT(*) AS total_disposal_points " + + " FROM disposalpoint_master " + + " WHERE isactive=1 AND isdelete=0 AND zone=? " + + " GROUP BY ward" + + ") dm ON w.ward = dm.ward " + + "LEFT JOIN (" + + " SELECT ward, COUNT(*) AS total_mapped_points " + + " FROM disposalpoint_mapped_master " + + " WHERE isactive=1 AND isdelete=0 AND zone=? " + + " GROUP BY ward" + + ") mm ON w.ward = mm.ward " + + "LEFT JOIN disposalpoint_mapped_master dmm ON dmm.ward = w.ward AND dmm.isactive=1 AND dmm.isdelete=0 " + + "LEFT JOIN before_activity b ON dmm.disposalpoint_id = b.disposalpoint_id " + + " AND b.isactive=1 AND b.isdelete=0 " + + " AND b.indate >= ? AND b.indate < DATE_ADD(?, INTERVAL 1 DAY) " + + "GROUP BY w.ward, dm.total_disposal_points, mm.total_mapped_points " + + "ORDER BY w.ward"; + + List> results = jdbcDisposalPointTemplate.queryForList( + sql, zone, zone, zone, fromDate, toDate + ); + + long totalDays = ChronoUnit.DAYS.between( + LocalDate.parse(fromDate), + LocalDate.parse(toDate) + ) + 1; + + List> finalList = new ArrayList<>(); + + long grandTotalDisposalPoints = 0; + long grandTotalMappedPoints = 0; + long grandCompletedDays = 0; + long grandPendingDays = 0; + + for (Map row : results) { + Map report = new LinkedHashMap<>(); + long completed = ((Number) row.get("completed_days")).longValue(); + long totalDisposalPoints = ((Number) row.get("total_disposal_points")).longValue(); + long totalMappedPoints = ((Number) row.get("total_mapped_points")).longValue(); + long totalDays_final = (totalDays*totalMappedPoints); + + report.put("ward", row.get("ward")); + report.put("totalDisposalPoints", totalDisposalPoints); + report.put("totalMappedPoints", totalMappedPoints); + report.put("totalDays", totalDays_final); + report.put("completedDays", completed); + report.put("pendingDays", (totalDays_final - completed)); + + finalList.add(report); + + // accumulate grand totals + grandTotalDisposalPoints += totalDisposalPoints; + grandTotalMappedPoints += totalMappedPoints; + grandCompletedDays += completed; + grandPendingDays +=(totalDays_final - completed); + } + + // add grand total row + Map grandTotalRow = new LinkedHashMap<>(); + grandTotalRow.put("ward", "TOTAL"); + grandTotalRow.put("totalDisposalPoints", grandTotalDisposalPoints); + grandTotalRow.put("totalMappedPoints", grandTotalMappedPoints); + grandTotalRow.put("totalDays", totalDays); + grandTotalRow.put("completedDays", grandCompletedDays); + grandTotalRow.put("pendingDays", grandPendingDays); // total pending across all wards + + finalList.add(grandTotalRow); + + return finalList; + } + + public List> getDisposalPointSummary(String fromDate, String toDate, String ward) { + + fromDate = convertDateFormat(fromDate,0); + toDate = convertDateFormat(toDate,0); + + // SQL: count completed days per Disposal point + String sql = "SELECT d.road_name, d.disposalpoint_id, COUNT(DISTINCT DATE(b.indate)) AS completedDays " + + "FROM disposalpoint_mapped_master d " + + "LEFT JOIN before_activity b ON d.disposalpoint_id = b.disposalpoint_id " + + "AND b.indate >= ? AND b.indate < DATE_ADD(?, INTERVAL 1 DAY) " + + "AND b.isactive=1 AND b.isdelete=0 " + + "WHERE d.isactive=1 AND d.isdelete=0 AND d.ward=? " + + "GROUP BY d.road_name, d.disposalpoint_id ORDER BY d.road_name"; + + List> results = jdbcDisposalPointTemplate.queryForList(sql, fromDate, toDate, ward); + + long totalDays = ChronoUnit.DAYS.between( + LocalDate.parse(fromDate), + LocalDate.parse(toDate) + ) + 1; + + List> finalList = new ArrayList<>(); + + //long grandTotalDisposalPoints = 0; + //long grandTotalMappedPoints = 0; + long grandCompletedDays = 0; + long grandPendingDays = 0; + + for (Map row : results) { + Map Report = new HashMap<>(); + long completed = ((Number) row.get("completedDays")).longValue(); + //long totalDisposalPoints = ((Number) row.get("total_disposal_points")).longValue(); + //long totalMappedPoints = ((Number) row.get("total_mapped_points")).longValue(); + long totalDays_final = (totalDays*1); + + Report.put("road_name", row.get("road_name")); + Report.put("disposalpoint_id", row.get("disposalpoint_id")); + Report.put("totalDays", totalDays_final); + Report.put("completed", completed); + Report.put("pending", totalDays_final - completed); + finalList.add(Report); + + // accumulate grand totals + //grandTotalDisposalPoints += totalDisposalPoints; + //grandTotalMappedPoints += totalMappedPoints; + grandCompletedDays += completed; + grandPendingDays +=(totalDays_final - completed); + } + + // add grand total row + Map grandTotalRow = new LinkedHashMap<>(); + grandTotalRow.put("road_name", "TOTAL"); + //grandTotalRow.put("totalDisposalPoints", grandTotalDisposalPoints); + //grandTotalRow.put("totalMappedPoints", grandTotalMappedPoints); + grandTotalRow.put("disposalpoint_id", 0); + grandTotalRow.put("totalDays", totalDays); + grandTotalRow.put("completed", grandCompletedDays); + grandTotalRow.put("pending", grandPendingDays); // total pending across all wards + + //finalList.add(grandTotalRow); + + return finalList; + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/foodDistribution/controller/DistributionController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/foodDistribution/controller/DistributionController.java new file mode 100644 index 0000000..eee030d --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/foodDistribution/controller/DistributionController.java @@ -0,0 +1,160 @@ +package in.gov.chennaicorporation.mobileservice.foodDistribution.controller; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +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.RestController; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.foodDistribution.service.DistributionService; + +@RequestMapping("/gccofficialapp/api/fooddistribution/") +@RestController("gccofficialappsfooddistribution") +public class DistributionController { + + @Autowired + private DistributionService distributionService; + + + // -------------------- GET CONFIG -------------------- + @GetMapping("/getConfig") + public List getConfig(@RequestParam("loginId") String loginId) { + return distributionService.getConfig(loginId); + } + + + // -------------------- GET SHIFT COUNT -------------------- + @GetMapping("/getShiftCount") + public List getShiftCount( + @RequestParam("loginId") String loginId, + @RequestParam("shiftid") String shiftid + ) { + return distributionService.getShiftCount(loginId, shiftid); + } + + + // -------------------- SAVE DAILY REQUEST -------------------- + @PostMapping("/saveRequest") + public List saveRequest( + @RequestParam String ward, + @RequestParam String required_date, + @RequestParam String permanent, + @RequestParam String nulm, + @RequestParam String private_, + @RequestParam String others, + @RequestParam(value = "nmr", required = false) String nmr, + @RequestParam String weeklyoff_permanent, + @RequestParam String weeklyoff_nulm, + @RequestParam String weeklyoff_private, + @RequestParam String weeklyoff_others, + @RequestParam(value = "weeklyoff_nmr", required = false) String weeklyoff_nmr, + @RequestParam String absentees_permanent, + @RequestParam String absentees_nulm, + @RequestParam String absentees_private, + @RequestParam String absentees_others, + @RequestParam(value = "absentees_nmr", required = false) String absentees_nmr, + @RequestParam String shiftid, + @RequestParam String request_by + ) { + return distributionService.saveRequest( + ward, + required_date, + permanent, + nulm, + private_, + others, + nmr, + weeklyoff_permanent, + weeklyoff_nulm, + weeklyoff_private, + weeklyoff_others, + weeklyoff_nmr, + absentees_permanent, + absentees_nulm, + absentees_private, + absentees_others, + absentees_nmr, + shiftid, + request_by + ); + } + + + // -------------------- GET PENDING LIST -------------------- + @GetMapping("/getPending") + public List getPending(@RequestParam("loginId") String loginId) { + return distributionService.getPending(loginId); + } + + + // -------------------- GET PENDING DETAILS -------------------- + @GetMapping("/getPendingDetails") + public List getPendingDetails( + @RequestParam("loginId") String loginId, + @RequestParam("requestid") String requestid, + @RequestParam("shiftid") String shiftid + ) { + return distributionService.getPendingDetails(loginId, requestid, shiftid); + } + + // -------------------- SAVE FEEDBACK AND RECEVIED INFORMATION -------------------- + @PostMapping("/saveFeedbackAndReceived") + public List saveFeedbackAndReceived( + @RequestParam String requestid, + @RequestParam String shiftid, + + // Feedback + @RequestParam String q1, + @RequestParam(value = "q1_img", required = false) MultipartFile q1_img, + @RequestParam String q2, + @RequestParam(value = "q2_img", required = false) MultipartFile q2_img, + @RequestParam String q3, + @RequestParam(value = "q3_img", required = false) MultipartFile q3_img, + @RequestParam String feedback_by, + + // Received Update + @RequestParam String total_box_shortfall, + @RequestParam String return_today, + @RequestParam String total_food_requested, + @RequestParam String total_food_received, + @RequestParam String today_absentees_permanent, + @RequestParam String today_absentees_nulm, + @RequestParam String today_absentees_private, + @RequestParam String today_absentees_others, + @RequestParam String received_by, + @RequestParam(value = "today_absentees_nmr", required = false) String today_absentees_nmr, + @RequestParam(value = "remarks", required = false) String remarks + ) { + return distributionService.saveFullFeedbackAndReceived( + requestid, shiftid, + q1, q1_img, q2, q2_img, q3, q3_img, feedback_by, + total_box_shortfall, return_today, total_food_requested, total_food_received, + today_absentees_permanent, today_absentees_nulm, + today_absentees_private, today_absentees_others, + received_by,today_absentees_nmr,remarks + + ); + } + + // For Reports + @GetMapping("/getZoneSummary") + public List getZoneSummary( + @RequestParam("fromDate") String fromDate, + @RequestParam("toDate") String toDate + ) { + return distributionService.getZoneSummary(fromDate, toDate); + } + + @GetMapping("/getWardSummary") + public List getWardSummary( + @RequestParam("fromDate") String fromDate, + @RequestParam("toDate") String toDate, + @RequestParam("zone") String zone + ) { + return distributionService.getWardSummary(fromDate, toDate, zone); + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/foodDistribution/controller/DriverController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/foodDistribution/controller/DriverController.java new file mode 100644 index 0000000..8a860a1 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/foodDistribution/controller/DriverController.java @@ -0,0 +1,143 @@ +package in.gov.chennaicorporation.mobileservice.foodDistribution.controller; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +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.RestController; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.foodDistribution.service.DriverService; + +@RequestMapping("/gccofficialapp/api/fooddistribution/driver") +@RestController("gccofficialappsfooddistributiondriver") +public class DriverController { + @Autowired + private DriverService driverService; + + @GetMapping({"/versionCheck"}) // Template + public List versionCheck() { + return driverService.versionCheck(); + } + + @GetMapping(value="login") + public List login(@RequestParam("username") String username, @RequestParam("password") String Password, @RequestParam("usertype") String usertype) { + return driverService.getloginList(username, Password, usertype); + } + // --------------------------------------------------------- + //️⃣ GET LIVE TRACK + // --------------------------------------------------------- + @GetMapping("/getDeliveryLocation") + public List getDeliveryLocation( + @RequestParam String loginid + ) { + return driverService.getDeliveryLocation(loginid); + } + + // --------------------------------------------------------- + // GET LIVE TRACK OF Driver BY SI Login + // --------------------------------------------------------- + @GetMapping("/getDriverStatus") + public List getDriverStatus( + @RequestParam String siloginid + ) { + return driverService.getDriverStatus(siloginid); + } + + // --------------------------------------------------------- + // 1️⃣ GET LIVE TRACK BY SI Login + // --------------------------------------------------------- + @GetMapping("/getLiveTrack") + public List getLiveTrack( + @RequestParam String siloginid, + @RequestParam String date + ) { + return driverService.getLiveTrack(siloginid, date); + } + + + // --------------------------------------------------------- + // 2️⃣ GET DRIVER LAST START/STOP STATUS + // --------------------------------------------------------- + @GetMapping("/getDriverLastStartStop") + public List getDriverLastStartStop( + @RequestParam String loginid + ) { + return driverService.getDriverLastStartStop(loginid); + } + + + // --------------------------------------------------------- + // 3️⃣ SAVE DRIVER START / STOP WITH IMAGE + // --------------------------------------------------------- + @PostMapping(value = "/saveStartStop", consumes = {"multipart/form-data"}) + public List saveStartStop( + @RequestParam String loginid, + @RequestParam String latitude, + @RequestParam String longitude, + @RequestParam String action, + @RequestParam String startid, + @RequestParam String driver_live_mobile, + @RequestParam(required = false) MultipartFile image, + @RequestParam(required = false) String address, + @RequestParam(required = false) String driver_name + ) { + return driverService.saveStartStop( + loginid, latitude, longitude, + action, startid, driver_live_mobile, image, address, driver_name + ); + } + + // --------------------------------------------------------- + // 4️⃣ SAVE LIVE LOCATION POINT + // --------------------------------------------------------- + @PostMapping("/saveLiveLocation") + public List saveLiveLocation( + @RequestParam String loginid, + @RequestParam String latitude, + @RequestParam String longitude, + @RequestParam(required = false) String address + ) { + return driverService.saveLiveLocation(loginid, latitude, longitude, address); + } + + // Vendor + @GetMapping("/getMenuDetails") + public List getMenuDetails( + @RequestParam String loginid + ) { + return driverService.getMenuDetails(loginid); + } + + @GetMapping("/getPendingDetails") + public List getPendingDetails( + @RequestParam String loginid, + @RequestParam String shiftid, + @RequestParam String date + ) { + return driverService.getPendingDetails(loginid, shiftid, date); + } + + @GetMapping("/getRequestUpdated") + public List getRequestUpdated( + @RequestParam String loginid, + @RequestParam String shiftid, + @RequestParam String date + ) { + return driverService.getRequestUpdated(loginid, shiftid, date); + } + + @PostMapping("/saveRequestUpadte") + public List saveRequestUpadte( + @RequestParam String loginid, + @RequestParam String shiftid, + @RequestParam String total_food_request_recived, + @RequestParam String total_food_transported, + @RequestParam String foodid + ) { + return driverService.saveRequestUpadte(loginid, shiftid, total_food_request_recived, total_food_transported, foodid); + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/foodDistribution/service/DistributionService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/foodDistribution/service/DistributionService.java new file mode 100644 index 0000000..19cf5e4 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/foodDistribution/service/DistributionService.java @@ -0,0 +1,1214 @@ +package in.gov.chennaicorporation.mobileservice.foodDistribution.service; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.SecureRandom; +import java.sql.PreparedStatement; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.env.Environment; +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; +import org.springframework.web.multipart.MultipartFile; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import in.gov.chennaicorporation.mobileservice.gccactivity.service.DateTimeUtil; + +@Service +public class DistributionService { +private JdbcTemplate jdbcFoodTemplate; + + private final Environment environment; + private String fileBaseUrl; + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int STRING_LENGTH = 15; + private static final Random RANDOM = new SecureRandom(); + + @Autowired + public void setDataSource(@Qualifier("mysqlGccFoodDistributionSource") DataSource FoodDistributionSource) { + this.jdbcFoodTemplate = new JdbcTemplate(FoodDistributionSource); + } + + @Autowired + public DistributionService(Environment environment) { + this.environment = environment; + this.fileBaseUrl=environment.getProperty("fileBaseUrl"); + } + + public static String generateRandomString() { + StringBuilder result = new StringBuilder(STRING_LENGTH); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + public static String generateRandomFileString(int lenthval) { + StringBuilder result = new StringBuilder(lenthval); + for (int i = 0; i < lenthval; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + private byte[] compressImage(BufferedImage image, float quality) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream); + + ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next(); + writer.setOutput(imageOutputStream); + + ImageWriteParam param = writer.getDefaultWriteParam(); + if (param.canWriteCompressed()) { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(quality); + } + + writer.write(null, new javax.imageio.IIOImage(image, null, null), param); + + writer.dispose(); + imageOutputStream.close(); + + return byteArrayOutputStream.toByteArray(); + } + + // Function to convert date string from dd-MM-yyyy to yyyy-MM-dd + public static String convertDateFormat(String inputDate, int add) { + // Check if the inputDate is not null or blank + if (inputDate != null && !inputDate.isBlank()) { + try { + // Define the input and output date formats + DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + // Parse the input date string to LocalDate + LocalDate date = LocalDate.parse(inputDate, inputFormatter); + + // Add the specified number of days to the date if 'add' is greater than 0 + if (add > 0) { + date = date.plusDays(add); + } + + // Format the date to the new format + return date.format(outputFormatter); + + } catch (DateTimeParseException e) { + // Handle the case where the input date is invalid + System.out.println("Invalid date format: " + inputDate); + return ""; + } + } else { + return ""; + } + } + + public String fileUpload(String name, String id, MultipartFile file, String filetype) { + + int lastInsertId = 0; + // Set the file path where you want to save it + String uploadDirectory = environment.getProperty("file.upload.directory"); + String serviceFolderName = environment.getProperty("fooddistribution_foldername"); + var year = DateTimeUtil.getCurrentYear(); + var month = DateTimeUtil.getCurrentMonth(); + var date = DateTimeUtil.getCurrentDay(); + + uploadDirectory = uploadDirectory + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date; + + try { + // Create directory if it doesn't exist + Path directoryPath = Paths.get(uploadDirectory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Datetime string + String datetimetxt = DateTimeUtil.getCurrentDateTime(); + + datetimetxt = datetimetxt + "_"+ generateRandomFileString(6); // Attached Random text + + // File name + String fileName = name + "_" + id + "_" + datetimetxt + "_" + file.getOriginalFilename(); + fileName = fileName.replaceAll("\\s+", ""); // Remove space on filename + + String filePath = uploadDirectory + "/" + fileName; + + String filepath_txt = "/" + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date + "/" + fileName; + + // Create a new Path object + Path path = Paths.get(filePath); + + // Get the bytes of the file + byte[] bytes = file.getBytes(); + + if(filetype.equalsIgnoreCase("image")) + { + // Compress the image + BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); + byte[] compressedBytes = compressImage(image, 0.5f); // Compress with 50% quality + // Write the bytes to the file + Files.write(path, compressedBytes); + } + else { + // Write the bytes to the file + Files.write(path, bytes); + } + // Get current date & time + LocalDateTime now = LocalDateTime.now(); + + // Format date-time (optional) + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + System.out.println("Date: "+ now.format(formatter)); + System.out.println("Activity: SluicePoint"); + System.out.println("File Type: " + filetype); + System.out.println("File Upload Path: " + filePath); + System.out.println("File Path: " + filepath_txt); + + return filepath_txt; + + } catch (IOException e) { + e.printStackTrace(); + System.out.println("Failed to save file " + file.getOriginalFilename()); + return "error"; + } + } + + public String getWardByLoginId(String loginid) { + String sqlQuery = "SELECT `ward` FROM `location_mapping` WHERE `siloginid` = ? AND `isactive`=1 AND `isdelete`=0 LIMIT 1"; + + // Query the database using queryForList + List> results = jdbcFoodTemplate.queryForList(sqlQuery, loginid); + + // Check if results is not empty and extract the ward value + if (!results.isEmpty()) { + // Extract the ward value from the first result + return (String) results.get(0).get("ward"); + } + + // Handle the case where no result is found + return "000"; // or return null based on your needs + } + + public List> getConfig(String loginid) { + + // String ward = getWardByLoginId(loginid,"ae"); + + String sql = "SELECT * FROM `shift_master` WHERE `isactive`=1 AND `isdelete`=0 ORDER BY orderby"; + List> configDetails = jdbcFoodTemplate.queryForList(sql); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Configuration Details."); + response.put("data", configDetails); + + return Collections.singletonList(response); + } + + public List> getShiftCount(String loginid, String shiftid) { + String ward = getWardByLoginId(loginid); + + String sql = "SELECT * FROM `count_master` WHERE (`isactive`=1 AND `isdelete`=0) AND (`ward`=? AND `shiftid`=?)"; + List> shiftcount = jdbcFoodTemplate.queryForList(sql, ward, shiftid); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Count Details."); + response.put("data", shiftcount); + + return Collections.singletonList(response); + } + + + @Transactional + public List> saveRequest( + String ward, + String required_date, + String permanent, + String nulm, + String private_, + String others, + String nmr, + String weeklyoff_permanent, + String weeklyoff_nulm, + String weeklyoff_private, + String weeklyoff_others, + String weeklyoff_nmr, + String absentees_permanent, + String absentees_nulm, + String absentees_private, + String absentees_others, + String absentees_nmr, + String shiftid, + String request_by + ) { + + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // ----------------------------------------------- + // 1️⃣ CHECK IF Request ALREADY EXISTS + // ----------------------------------------------- + String chkSql = "SELECT requestid FROM daily_request WHERE ward=? AND shiftid=? AND required_date=? AND isactive=1 AND isdelete=0"; + + List> exists = jdbcFoodTemplate.queryForList(chkSql, ward, shiftid, convertDateFormat(required_date,0)); + if (!exists.isEmpty()) { + response.put("status", "error"); + response.put("message", "Food Request exists for this ward:"+ ward+" Shift ID:"+shiftid+" Required Date:"+required_date+"."); + result.add(response); + return result; + } + + String action = "New Request"; + + String insertSqltxt = "INSERT INTO `daily_request`(`ward`, `required_date`, `permanent`, `nulm`, `private`, " + + " `others`, `weeklyoff_permanent`, `weeklyoff_nulm`, `weeklyoff_private`, `weeklyoff_others`, " + + " `absentees_permanent`, `absentees_nulm`, `absentees_private`, `absentees_others`, `shiftid`, " + + " `request_by`,`nmr`,`weeklyoff_nmr`,`absentees_nmr`) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + String insertSql = insertSqltxt; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcFoodTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"requestid"}); + int i = 1; + ps.setString(i++, ward); + ps.setString(i++, convertDateFormat(required_date,0)); + ps.setString(i++, permanent); + ps.setString(i++, nulm); + ps.setString(i++, private_); + ps.setString(i++, others); + ps.setString(i++, weeklyoff_permanent); + ps.setString(i++, weeklyoff_nulm); + ps.setString(i++, weeklyoff_private); + ps.setString(i++, weeklyoff_others); + ps.setString(i++, absentees_permanent); + ps.setString(i++, absentees_nulm); + ps.setString(i++, absentees_private); + ps.setString(i++, absentees_others); + ps.setString(i++, shiftid); + ps.setString(i++, request_by); + ps.setString(i++, nmr); + ps.setString(i++, weeklyoff_nmr); + ps.setString(i++, absentees_nmr); + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Sluice Point", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", action + " data inserted successfully."); + } else { + response.put("Sluice Point", action + " insertId error!"); + response.put("status", "error"); + response.put("message", action + " data insert failed."); + } + + result.add(response); + return result; + } + + public List> getPending(String loginid) { + + String ward = getWardByLoginId(loginid); + + String sql = "SELECT " + + "dr.*, " + + "sm.Code AS shift_code, " + + "sm.name AS shift_name, " + + "sm.hint AS shift_hint, " + + "sm.time AS shift_time, " + + "sm.enable_time AS shift_enable_time, " + + "sm.disable_time AS shift_disable_time, " + + "DATE_FORMAT(dr.required_date, '%d-%m-%Y') AS required_date_fmt, " + + "DATE_FORMAT(dr.request_date, '%d-%m-%Y %H:%i:%s') AS request_date_fmt, " + + "(dr.permanent-(weeklyoff_permanent+absentees_permanent)) as current_permanent, " + + "(dr.nulm-(weeklyoff_nulm+absentees_nulm)) as current_nulm, " + + "(dr.private-(weeklyoff_private+absentees_private)) as current_private, " + + "(dr.others-(weeklyoff_others+absentees_others)) as current_others, " + + "(dr.nmr-(weeklyoff_nmr+absentees_nmr)) as current_nmr " + + "FROM daily_request dr " + + "LEFT JOIN shift_master sm ON dr.shiftid = sm.shiftid " + + "WHERE dr.isactive = 1 AND dr.isdelete = 0 AND dr.feedbackid = 0 AND dr.required_date <= CURDATE() " + + "AND dr.ward = ?"; + + List> pendingList = jdbcFoodTemplate.queryForList(sql, ward); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Pending Details."); + response.put("data", pendingList); + + return Collections.singletonList(response); + } + + public List> getPendingDetails(String loginid, String requestid, String shiftid) { + + // 1. Get shortfall details + String sql = "SELECT SUM(total_food_received) - SUM(return_today) AS total_shortfall " + + "FROM gcc_received_update WHERE shiftid=? AND (isactive = 1 AND isdelete = 0) "; + + List> shortfallDetails = jdbcFoodTemplate.queryForList(sql, shiftid); + + // 2. Get requested food details + sql = "SELECT (permanent + nulm + private + others+ nmr) - " + + "((weeklyoff_permanent + weeklyoff_nulm + weeklyoff_private + weeklyoff_others + weeklyoff_nmr) + " + + "(absentees_permanent + absentees_nulm + absentees_private + absentees_others + absentees_nmr)) " + + "AS total_food_requested " + + "FROM daily_request WHERE requestid=? AND (isactive = 1 AND isdelete = 0)"; + + List> requestedInfo = jdbcFoodTemplate.queryForList(sql, requestid); + + // 3. Get Feedback Questions + //sql = "SELECT * FROM `feedback_questions` WHERE isactive=1 and isdelete=0 ORDER BY orderby"; + sql = "SELECT " + + " ql.*, " + + " CASE " + + " WHEN ql.qtype IN ('select', 'radio') THEN " + + " JSON_ARRAYAGG( " + + " JSON_OBJECT( " + + " 'option_id', qov.id, " + + " 'qid', qov.qid, " + + " 'english_name', qov.name, " + + " 'value', qov.id, " + + " 'orderby', qov.orderby " + + " ) " + + " ) " + + " ELSE NULL " + + " END AS options " + + "FROM feedback_questions ql " + + "LEFT JOIN feedback_option_values qov " + + " ON qov.qid = ql.qid " + + " AND qov.isactive = 1 " + + " AND qov.isdelete = 0 " + + "WHERE ql.isactive = 1 " + + "GROUP BY ql.qid"; + + //List> questionInfo = jdbcFoodTemplate.queryForList(sql); + + List> questionInfo = jdbcFoodTemplate.queryForList(sql); + Iterator> iterator = questionInfo.iterator(); + ObjectMapper mapper = new ObjectMapper(); + while (iterator.hasNext()) { + Map row = iterator.next(); + Object optionsRaw = row.get("options"); + if (optionsRaw != null && optionsRaw instanceof String) { + try { + List> optionsParsed = mapper.readValue((String) optionsRaw, List.class); + + // Sort options by 'orderby' + optionsParsed.sort(Comparator.comparing(opt -> { + Object order = opt.get("orderby"); + return (order instanceof Number) ? ((Number) order).intValue() : 0; + })); + + row.put("options", optionsParsed); + } catch (Exception e) { + row.put("options", null); // fallback if malformed + } + } + } + + // 3. Combine both list results + List> pendingDetails = new ArrayList<>(); + pendingDetails.addAll(shortfallDetails); + pendingDetails.addAll(requestedInfo); + pendingDetails.addAll(questionInfo); + + // Combine request info (shortfall + requested) + List> requestInfo = new ArrayList<>(); + requestInfo.addAll(shortfallDetails); + requestInfo.addAll(requestedInfo); + + // Final response structure + Map data = new HashMap<>(); + data.put("request_info", requestInfo); + data.put("feedback_question", questionInfo); + + // 4. Create final response + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Pending Details."); + response.put("data", data); + + return Collections.singletonList(response); + } + + @Transactional + public List> saveRecivedUpdate( + String requestid, + String shiftid, + String total_box_shortfall, + String return_today, + String total_food_requested, + String total_food_received, + String today_absentees_permanent, + String today_absentees_nulm, + String today_absentees_private, + String today_absentees_others, + String received_by, + String today_absentees_nmr + ){ + + String action = "New Request"; + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + String insertSqltxt = "INSERT INTO `gcc_received_update`(`requestid`, `shiftid`, `total_box_shortfall`, `return_today`, " + + " `total_food_requested`, `total_food_received`, `today_absentees_permanent`, " + + " `today_absentees_nulm`, `today_absentees_private`, `today_absentees_others`, `received_by`, `today_absentees_nmr`) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"; + + String insertSql = insertSqltxt; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcFoodTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"receivedid"}); + int i = 1; + ps.setString(i++, requestid); + ps.setString(i++, shiftid); + ps.setString(i++, total_box_shortfall); + ps.setString(i++, return_today); + ps.setString(i++, total_food_requested); + ps.setString(i++, total_food_received); + ps.setString(i++, today_absentees_permanent); + ps.setString(i++, today_absentees_nulm); + ps.setString(i++, today_absentees_private); + ps.setString(i++, today_absentees_others); + ps.setString(i++, received_by); + ps.setString(i++, today_absentees_nmr); + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Sluice Point", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", action + " data inserted successfully."); + } else { + response.put("Sluice Point", action + " insertId error!"); + response.put("status", "error"); + response.put("message", action + " data insert failed."); + } + + result.add(response); + return result; + } + + @Transactional + public List> saveFullFeedbackAndReceived( + String requestid, String shiftid, + + // Feedback + String q1, MultipartFile q1_img, + String q2, MultipartFile q2_img, + String q3, MultipartFile q3_img, + String feedback_by, + + // Received Update + String total_box_shortfall, + String return_today, + String total_food_requested, + String total_food_received, + String today_absentees_permanent, + String today_absentees_nulm, + String today_absentees_private, + String today_absentees_others, + String received_by, + String today_absentees_nmr, + String remarks + ) { + + List> result = new ArrayList<>(); + Map response = new HashMap<>(); + + + // ----------------------------------------------- + // 1️⃣ CHECK IF FEEDBACK ALREADY EXISTS + // ----------------------------------------------- + String chkSql = "SELECT feedbackid FROM feedback_data WHERE requestid=? AND isactive=1 AND isdelete=0"; + + List> exists = jdbcFoodTemplate.queryForList(chkSql, requestid); + if (!exists.isEmpty()) { + response.put("status", "error"); + response.put("message", "Feedback already exists for this request."); + result.add(response); + return result; + } + + String filetype = "image"; + + // Q1 Image + final String[] q1_img_path = { null }; + if (q1_img != null && !q1_img.isEmpty()) { + q1_img_path[0] = fileUpload(requestid, shiftid, q1_img, filetype); + if ("error".equalsIgnoreCase(q1_img_path[0])) { + response.put("status", "error"); + response.put("message", "Q1 feedback image upload failed."); + result.add(response); + return result; + } + } + + // Q2 Image + final String[] q2_img_path = { null }; + if (q2_img != null && !q2_img.isEmpty()) { + q2_img_path[0] = fileUpload(requestid, shiftid, q2_img, filetype); + if ("error".equalsIgnoreCase(q2_img_path[0])) { + response.put("status", "error"); + response.put("message", "Q2 feedback image upload failed."); + result.add(response); + return result; + } + } + + // Q3 Image + final String[] q3_img_path = { null }; + if (q3_img != null && !q3_img.isEmpty()) { + q3_img_path[0] = fileUpload(requestid, shiftid, q3_img, filetype); + if ("error".equalsIgnoreCase(q3_img_path[0])) { + response.put("status", "error"); + response.put("message", "Q3 feedback image upload failed."); + result.add(response); + return result; + } + } + + // ----------------------------------------------- + // 2️⃣ INSERT FEEDBACK FIRST + // ----------------------------------------------- + String feedbackSql = """ + INSERT INTO feedback_data + (requestid, q1, q1_img, q2, q2_img, q3, q3_img, feedback_by,remarks) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + """; + + KeyHolder feedbackKeyHolder = new GeneratedKeyHolder(); + + jdbcFoodTemplate.update(conn -> { + PreparedStatement ps = conn.prepareStatement(feedbackSql, new String[]{"feedbackid"}); + int i = 1; + ps.setString(i++, requestid); + ps.setString(i++, q1); + ps.setString(i++, q1_img_path[0]); + ps.setString(i++, q2); + ps.setString(i++, q2_img_path[0]); + ps.setString(i++, q3); + ps.setString(i++, q3_img_path[0]); + ps.setString(i++, feedback_by); + ps.setString(i++, remarks); + return ps; + }, feedbackKeyHolder); + + int feedbackId = feedbackKeyHolder.getKey().intValue(); + + try { + // ----------------------------------------------- + // 3️⃣ SAVE RECEIVED UPDATE (Existing Code Reused) + // ----------------------------------------------- + String receivedSql = """ + INSERT INTO gcc_received_update + (requestid, shiftid, total_box_shortfall, return_today, total_food_requested, + total_food_received, today_absentees_permanent, today_absentees_nulm, + today_absentees_private, today_absentees_others, received_by, today_absentees_nmr) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + """; + + KeyHolder receivedKeyHolder = new GeneratedKeyHolder(); + + jdbcFoodTemplate.update(conn -> { + PreparedStatement ps = conn.prepareStatement(receivedSql, new String[]{"receivedid"}); + int i = 1; + ps.setString(i++, requestid); + ps.setString(i++, shiftid); + ps.setString(i++, total_box_shortfall); + ps.setString(i++, return_today); + ps.setString(i++, total_food_requested); + ps.setString(i++, total_food_received); + ps.setString(i++, today_absentees_permanent); + ps.setString(i++, today_absentees_nulm); + ps.setString(i++, today_absentees_private); + ps.setString(i++, today_absentees_others); + ps.setString(i++, received_by); + ps.setString(i++, today_absentees_nmr); + return ps; + }, receivedKeyHolder); + + int receivedId = receivedKeyHolder.getKey().intValue(); + + // ------------------------------ + // UPDATE DAILY_REQUEST + // ------------------------------ + String updateDailyRequestSql = """ + UPDATE daily_request + SET feedbackid = ? + WHERE requestid = ? + """; + + int updated = jdbcFoodTemplate.update( + updateDailyRequestSql, + feedbackId, + requestid + ); + + if (updated == 0) { + throw new RuntimeException("Failed to update daily_request"); + } + + // ------------------------------ + // SUCCESS RESPONSE + // ------------------------------ + response.put("status", "success"); + response.put("feedbackid", feedbackId); + response.put("receivedid", receivedId); + response.put("message", "Feedback and received update saved successfully."); + + result.add(response); + return result; + + } catch (Exception e) { + chkSql = "UPDATE feedback_data SET isactive=0, isdelete=1 WHERE requestid=?"; + int updated = jdbcFoodTemplate.update(chkSql,requestid); + // ❌ VERY IMPORTANT → rethrow exception + // This forces Spring to rollback feedbackSql + throw new RuntimeException("Transaction failed. Rolling back ("+requestid+").", e); + } + } + + // For Reports + public List> getZoneSummary(String fromDate, String toDate) { + + fromDate = convertDateFormat(fromDate,0); + toDate = convertDateFormat(toDate,0); + + // SQL: count completed days per Disposal point + String sql = "SELECT * " + + "FROM ( " + + " " + + " /* ================= ZONE-WISE SUMMARY ================= */ " + + " SELECT " + + " z.zone AS zone, " + + " " + + " /* TOTAL COMPLEMENT */ " + + " ( " + + " SELECT IFNULL(SUM(dr.permanent + dr.nulm + dr.private + dr.nmr + dr.others), 0) " + + " FROM daily_request dr " + + " WHERE dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND dr.request_by IN ( " + + " SELECT lm.siloginid " + + " FROM location_mapping lm " + + " WHERE lm.zone = z.zone " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " ) " + + " ) AS total_complement, " + + " " + + " /* WEEKLY OFF */ " + + " ( " + + " SELECT IFNULL(SUM(dr.weeklyoff_permanent + dr.weeklyoff_private + " + + " dr.weeklyoff_nulm + dr.weeklyoff_others + dr.weeklyoff_nmr), 0) " + + " FROM daily_request dr " + + " WHERE dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND dr.request_by IN ( " + + " SELECT lm.siloginid " + + " FROM location_mapping lm " + + " WHERE lm.zone = z.zone " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " ) " + + " ) AS weekly_off, " + + " " + + " /* PLANNED LEAVE */ " + + " ( " + + " SELECT IFNULL(SUM(dr.absentees_permanent + dr.absentees_private + " + + " dr.absentees_nulm + dr.absentees_others + dr.absentees_nmr), 0) " + + " FROM daily_request dr " + + " WHERE dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND dr.request_by IN ( " + + " SELECT lm.siloginid " + + " FROM location_mapping lm " + + " WHERE lm.zone = z.zone " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " ) " + + " ) AS planned_leave, " + + " " + + " /* PRESENT COUNT */ " + + " ( " + + " ( " + + " SELECT IFNULL(SUM(dr.permanent + dr.nulm + dr.private + dr.nmr + dr.others), 0) " + + " FROM daily_request dr " + + " WHERE dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND dr.request_by IN ( " + + " SELECT lm.siloginid " + + " FROM location_mapping lm " + + " WHERE lm.zone = z.zone " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " ) " + + " ) " + + " - " + + " ( " + + " SELECT IFNULL(SUM(dr.weeklyoff_permanent + dr.weeklyoff_private + " + + " dr.weeklyoff_nulm + dr.weeklyoff_others + dr.weeklyoff_nmr), 0) " + + " FROM daily_request dr " + + " WHERE dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND dr.request_by IN ( " + + " SELECT lm.siloginid " + + " FROM location_mapping lm " + + " WHERE lm.zone = z.zone " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " ) " + + " ) " + + " - " + + " ( " + + " SELECT IFNULL(SUM(dr.absentees_permanent + dr.absentees_private + " + + " dr.absentees_nulm + dr.absentees_others + dr.absentees_nmr), 0) " + + " FROM daily_request dr " + + " WHERE dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND dr.request_by IN ( " + + " SELECT lm.siloginid " + + " FROM location_mapping lm " + + " WHERE lm.zone = z.zone " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " ) " + + " ) " + + " ) AS present_count, " + + " " + + " /* FOOD REQUESTED (same as present) */ " + + " ( " + + " ( " + + " SELECT IFNULL(SUM(dr.permanent + dr.nulm + dr.private + dr.nmr + dr.others), 0) " + + " FROM daily_request dr " + + " WHERE dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND dr.request_by IN ( " + + " SELECT lm.siloginid " + + " FROM location_mapping lm " + + " WHERE lm.zone = z.zone " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " ) " + + " ) " + + " - " + + " ( " + + " SELECT IFNULL(SUM(dr.weeklyoff_permanent + dr.weeklyoff_private + " + + " dr.weeklyoff_nulm + dr.weeklyoff_others + dr.weeklyoff_nmr), 0) " + + " FROM daily_request dr " + + " WHERE dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND dr.request_by IN ( " + + " SELECT lm.siloginid " + + " FROM location_mapping lm " + + " WHERE lm.zone = z.zone " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " ) " + + " ) " + + " - " + + " ( " + + " SELECT IFNULL(SUM(dr.absentees_permanent + dr.absentees_private + " + + " dr.absentees_nulm + dr.absentees_others + dr.absentees_nmr), 0) " + + " FROM daily_request dr " + + " WHERE dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND dr.request_by IN ( " + + " SELECT lm.siloginid " + + " FROM location_mapping lm " + + " WHERE lm.zone = z.zone " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " ) " + + " ) " + + " ) AS food_requested, " + + " " + + " /* FOOD DELIVERED */ " + + " ( " + + " SELECT IFNULL(SUM(gru.total_food_received), 0) " + + " FROM gcc_received_update gru " + + " WHERE gru.shiftid = 1 " + + " AND gru.isactive = 1 " + + " AND gru.isdelete = 0 " + + " AND gru.requestid IN ( " + + " SELECT dr.requestid " + + " FROM daily_request dr " + + " WHERE dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND dr.request_by IN ( " + + " SELECT lm.siloginid " + + " FROM location_mapping lm " + + " WHERE lm.zone = z.zone " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " ) " + + " ) " + + " ) AS food_delivered, " + + " " + + " /* FOOD SHORTFALL */ " + + " ( " + + " ( " + + " ( " + + " SELECT IFNULL(SUM(dr.permanent + dr.nulm + dr.private + dr.nmr + dr.others), 0) " + + " FROM daily_request dr " + + " WHERE dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND dr.request_by IN ( " + + " SELECT lm.siloginid " + + " FROM location_mapping lm " + + " WHERE lm.zone = z.zone " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " ) " + + " ) " + + " - " + + " ( " + + " SELECT IFNULL(SUM(dr.weeklyoff_permanent + dr.weeklyoff_private + " + + " dr.weeklyoff_nulm + dr.weeklyoff_others + dr.weeklyoff_nmr), 0) " + + " FROM daily_request dr " + + " WHERE dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND dr.request_by IN ( " + + " SELECT lm.siloginid " + + " FROM location_mapping lm " + + " WHERE lm.zone = z.zone " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " ) " + + " ) " + + " - " + + " ( " + + " SELECT IFNULL(SUM(dr.absentees_permanent + dr.absentees_private + " + + " dr.absentees_nulm + dr.absentees_others + dr.absentees_nmr), 0) " + + " FROM daily_request dr " + + " WHERE dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND dr.request_by IN ( " + + " SELECT lm.siloginid " + + " FROM location_mapping lm " + + " WHERE lm.zone = z.zone " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " ) " + + " ) " + + " ) " + + " - " + + " ( " + + " SELECT IFNULL(SUM(gru.total_food_received), 0) " + + " FROM gcc_received_update gru " + + " WHERE gru.shiftid = 1 " + + " AND gru.isactive = 1 " + + " AND gru.isdelete = 0 " + + " AND gru.requestid IN ( " + + " SELECT dr.requestid " + + " FROM daily_request dr " + + " WHERE dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND dr.request_by IN ( " + + " SELECT lm.siloginid " + + " FROM location_mapping lm " + + " WHERE lm.zone = z.zone " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " ) " + + " ) " + + " ) " + + " ) AS food_shortfall " + + " " + + " FROM ( " + + " SELECT DISTINCT zone " + + " FROM location_mapping " + + " WHERE zone IS NOT NULL " + + " AND isactive = 1 " + + " AND isdelete = 0 " + + " ORDER BY CAST(zone AS UNSIGNED) " + + " ) z " + + " " + + " UNION ALL " + + " " + + " /* ================= GRAND TOTAL ================= */ " + + " SELECT " + + " 'TOTAL' AS zone, " + + " " + + " IFNULL(SUM(dr.permanent + dr.nulm + dr.private + dr.nmr + dr.others), 0), " + + " IFNULL(SUM(dr.weeklyoff_permanent + dr.weeklyoff_private + dr.weeklyoff_nulm + " + + " dr.weeklyoff_others + dr.weeklyoff_nmr), 0), " + + " IFNULL(SUM(dr.absentees_permanent + dr.absentees_private + dr.absentees_nulm + " + + " dr.absentees_others + dr.absentees_nmr), 0), " + + " " + + " ( " + + " IFNULL(SUM(dr.permanent + dr.nulm + dr.private + dr.nmr + dr.others), 0) " + + " - " + + " IFNULL(SUM(dr.weeklyoff_permanent + dr.weeklyoff_private + dr.weeklyoff_nulm + " + + " dr.weeklyoff_others + dr.weeklyoff_nmr), 0) " + + " - " + + " IFNULL(SUM(dr.absentees_permanent + dr.absentees_private + dr.absentees_nulm + " + + " dr.absentees_others + dr.absentees_nmr), 0) " + + " ), " + + " " + + " ( " + + " IFNULL(SUM(dr.permanent + dr.nulm + dr.private + dr.nmr + dr.others), 0) " + + " - " + + " IFNULL(SUM(dr.weeklyoff_permanent + dr.weeklyoff_private + dr.weeklyoff_nulm + " + + " dr.weeklyoff_others + dr.weeklyoff_nmr), 0) " + + " - " + + " IFNULL(SUM(dr.absentees_permanent + dr.absentees_private + dr.absentees_nulm + " + + " dr.absentees_others + dr.absentees_nmr), 0) " + + " ), " + + " " + + " IFNULL(SUM(gru.total_food_received), 0), " + + " " + + " ( " + + " ( " + + " IFNULL(SUM(dr.permanent + dr.nulm + dr.private + dr.nmr + dr.others), 0) " + + " - " + + " IFNULL(SUM(dr.weeklyoff_permanent + dr.weeklyoff_private + dr.weeklyoff_nulm + " + + " dr.weeklyoff_others + dr.weeklyoff_nmr), 0) " + + " - " + + " IFNULL(SUM(dr.absentees_permanent + dr.absentees_private + dr.absentees_nulm + " + + " dr.absentees_others + dr.absentees_nmr), 0) " + + " ) " + + " - " + + " IFNULL(SUM(gru.total_food_received), 0) " + + " ) " + + " " + + " FROM daily_request dr " + + " LEFT JOIN gcc_received_update gru " + + " ON gru.requestid = dr.requestid " + + " AND gru.isactive = 1 " + + " AND gru.isdelete = 0 " + + " AND dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " " + + ") final_output " + + " " + + "ORDER BY " + + " CASE WHEN zone = 'TOTAL' THEN 1 ELSE 0 END, " + + " CAST(zone AS UNSIGNED)"; + + List> results = jdbcFoodTemplate.queryForList(sql); + + return results; + } + public List> getWardSummary(String fromDate, String toDate, String zone) { + + fromDate = convertDateFormat(fromDate,0); + toDate = convertDateFormat(toDate,0); + + // SQL: count completed days per Disposal point + String sql = "WITH ward_data AS ( " + + " SELECT " + + " w.ward, " + + " " + + " /* TOTAL COMPLEMENT */ " + + " IFNULL(SUM(dr.permanent + dr.nulm + dr.private + dr.nmr + dr.others), 0) AS total_complement, " + + " " + + " /* WEEKLY OFF */ " + + " IFNULL(SUM( " + + " dr.weeklyoff_permanent + dr.weeklyoff_private + " + + " dr.weeklyoff_nulm + dr.weeklyoff_others + dr.weeklyoff_nmr " + + " ), 0) AS weekly_off, " + + " " + + " /* PLANNED LEAVE */ " + + " IFNULL(SUM( " + + " dr.absentees_permanent + dr.absentees_private + " + + " dr.absentees_nulm + dr.absentees_others + dr.absentees_nmr " + + " ), 0) AS planned_leave, " + + " " + + " /* PRESENT COUNT */ " + + " ( " + + " IFNULL(SUM(dr.permanent + dr.nulm + dr.private + dr.nmr + dr.others), 0) " + + " - " + + " IFNULL(SUM( " + + " dr.weeklyoff_permanent + dr.weeklyoff_private + " + + " dr.weeklyoff_nulm + dr.weeklyoff_others + dr.weeklyoff_nmr " + + " ), 0) " + + " - " + + " IFNULL(SUM( " + + " dr.absentees_permanent + dr.absentees_private + " + + " dr.absentees_nulm + dr.absentees_others + dr.absentees_nmr " + + " ), 0) " + + " ) AS present_count, " + + " " + + " /* FOOD REQUESTED */ " + + " ( " + + " IFNULL(SUM(dr.permanent + dr.nulm + dr.private + dr.nmr + dr.others), 0) " + + " - " + + " IFNULL(SUM( " + + " dr.weeklyoff_permanent + dr.weeklyoff_private + " + + " dr.weeklyoff_nulm + dr.weeklyoff_others + dr.weeklyoff_nmr " + + " ), 0) " + + " - " + + " IFNULL(SUM( " + + " dr.absentees_permanent + dr.absentees_private + " + + " dr.absentees_nulm + dr.absentees_others + dr.absentees_nmr " + + " ), 0) " + + " ) AS food_requested, " + + " " + + " /* FOOD DELIVERED */ " + + " IFNULL(SUM(gru.total_food_received), 0) AS food_delivered, " + + " " + + " /* FOOD SHORTFALL (NO NEGATIVE) */ " + + " CASE " + + " WHEN IFNULL(SUM(gru.total_food_received), 0) >= " + + " ( " + + " IFNULL(SUM(dr.permanent + dr.nulm + dr.private + dr.nmr + dr.others), 0) " + + " - " + + " IFNULL(SUM( " + + " dr.weeklyoff_permanent + dr.weeklyoff_private + " + + " dr.weeklyoff_nulm + dr.weeklyoff_others + dr.weeklyoff_nmr " + + " ), 0) " + + " - " + + " IFNULL(SUM( " + + " dr.absentees_permanent + dr.absentees_private + " + + " dr.absentees_nulm + dr.absentees_others + dr.absentees_nmr " + + " ), 0) " + + " ) " + + " THEN 0 " + + " ELSE " + + " ( " + + " ( " + + " IFNULL(SUM(dr.permanent + dr.nulm + dr.private + dr.nmr + dr.others), 0) " + + " - " + + " IFNULL(SUM( " + + " dr.weeklyoff_permanent + dr.weeklyoff_private + " + + " dr.weeklyoff_nulm + dr.weeklyoff_others + dr.weeklyoff_nmr " + + " ), 0) " + + " - " + + " IFNULL(SUM( " + + " dr.absentees_permanent + dr.absentees_private + " + + " dr.absentees_nulm + dr.absentees_others + dr.absentees_nmr " + + " ), 0) " + + " ) " + + " - " + + " IFNULL(SUM(gru.total_food_received), 0) " + + " ) " + + " END AS food_shortfall " + + " " + + " FROM ( " + + " SELECT DISTINCT ward " + + " FROM location_mapping " + + " WHERE zone = '"+zone+"' " + + " AND ward IS NOT NULL " + + " AND isactive = 1 " + + " AND isdelete = 0 " + + " ) w " + + " " + + " LEFT JOIN location_mapping lm " + + " ON lm.ward = w.ward " + + " AND lm.zone = '"+zone+"' " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0 " + + " " + + " LEFT JOIN daily_request dr " + + " ON dr.request_by = lm.siloginid " + + " AND dr.required_date >= '"+fromDate+"' AND dr.required_date<='"+toDate+"'" + + " AND dr.shiftid = 1 " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " " + + " LEFT JOIN gcc_received_update gru " + + " ON gru.requestid = dr.requestid " + + " AND gru.isactive = 1 " + + " AND gru.isdelete = 0 " + + " " + + " GROUP BY w.ward " + + ") " + + " " + + "SELECT * FROM ward_data " + + " " + + "UNION ALL " + + " " + + "SELECT " + + " 'TOTAL' AS ward, " + + " SUM(total_complement), " + + " SUM(weekly_off), " + + " SUM(planned_leave), " + + " SUM(present_count), " + + " SUM(food_requested), " + + " SUM(food_delivered), " + + " SUM(food_shortfall) " + + "FROM ward_data " + + " " + + "ORDER BY " + + " CASE WHEN ward = 'TOTAL' THEN 1 ELSE 0 END, " + + " ward"; + + List> results = jdbcFoodTemplate.queryForList(sql); + + return results; + } +} \ No newline at end of file diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/foodDistribution/service/DriverService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/foodDistribution/service/DriverService.java new file mode 100644 index 0000000..7339ebe --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/foodDistribution/service/DriverService.java @@ -0,0 +1,723 @@ +package in.gov.chennaicorporation.mobileservice.foodDistribution.service; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.SecureRandom; +import java.sql.PreparedStatement; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.env.Environment; +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; +import org.springframework.web.multipart.MultipartFile; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import in.gov.chennaicorporation.mobileservice.gccactivity.service.DateTimeUtil; + +@Service +public class DriverService { + private JdbcTemplate jdbcFoodTemplate; + + private final Environment environment; + private String fileBaseUrl; + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int STRING_LENGTH = 15; + private static final Random RANDOM = new SecureRandom(); + + @Autowired + public void setDataSource(@Qualifier("mysqlGccFoodDistributionSource") DataSource FoodDistributionSource) { + this.jdbcFoodTemplate = new JdbcTemplate(FoodDistributionSource); + } + + @Autowired + public DriverService(Environment environment) { + this.environment = environment; + this.fileBaseUrl=environment.getProperty("fileBaseUrl"); + } + + public static String generateRandomString() { + StringBuilder result = new StringBuilder(STRING_LENGTH); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + public static String generateRandomFileString(int lenthval) { + StringBuilder result = new StringBuilder(lenthval); + for (int i = 0; i < lenthval; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + private byte[] compressImage(BufferedImage image, float quality) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream); + + ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next(); + writer.setOutput(imageOutputStream); + + ImageWriteParam param = writer.getDefaultWriteParam(); + if (param.canWriteCompressed()) { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(quality); + } + + writer.write(null, new javax.imageio.IIOImage(image, null, null), param); + + writer.dispose(); + imageOutputStream.close(); + + return byteArrayOutputStream.toByteArray(); + } + + // Function to convert date string from dd-MM-yyyy to yyyy-MM-dd + public static String convertDateFormat(String inputDate, int add) { + // Check if the inputDate is not null or blank + if (inputDate != null && !inputDate.isBlank()) { + try { + // Define the input and output date formats + DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + // Parse the input date string to LocalDate + LocalDate date = LocalDate.parse(inputDate, inputFormatter); + + // Add the specified number of days to the date if 'add' is greater than 0 + if (add > 0) { + date = date.plusDays(add); + } + + // Format the date to the new format + return date.format(outputFormatter); + + } catch (DateTimeParseException e) { + // Handle the case where the input date is invalid + System.out.println("Invalid date format: " + inputDate); + return ""; + } + } else { + return ""; + } + } + + public String fileUpload(String name, String id, MultipartFile file, String filetype) { + + int lastInsertId = 0; + // Set the file path where you want to save it + String uploadDirectory = environment.getProperty("file.upload.directory"); + String serviceFolderName = environment.getProperty("fooddistribution_foldername"); + var year = DateTimeUtil.getCurrentYear(); + var month = DateTimeUtil.getCurrentMonth(); + var date = DateTimeUtil.getCurrentDay(); + + uploadDirectory = uploadDirectory + serviceFolderName + "driver/" + filetype + "/" + year + "/" + month + "/" + date; + + try { + // Create directory if it doesn't exist + Path directoryPath = Paths.get(uploadDirectory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Datetime string + String datetimetxt = DateTimeUtil.getCurrentDateTime(); + + datetimetxt = datetimetxt + "_"+ generateRandomFileString(6); // Attached Random text + + // File name + String fileName = name + "_" + id + "_" + datetimetxt + "_" + file.getOriginalFilename(); + fileName = fileName.replaceAll("\\s+", ""); // Remove space on filename + + String filePath = uploadDirectory + "/" + fileName; + + String filepath_txt = "/" + serviceFolderName + "driver/" + filetype + "/" + year + "/" + month + "/" + date + "/" + fileName; + + // Create a new Path object + Path path = Paths.get(filePath); + + // Get the bytes of the file + byte[] bytes = file.getBytes(); + + if(filetype.equalsIgnoreCase("image")) + { + // Compress the image + BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); + byte[] compressedBytes = compressImage(image, 0.5f); // Compress with 50% quality + // Write the bytes to the file + Files.write(path, compressedBytes); + } + else { + // Write the bytes to the file + Files.write(path, bytes); + } + // Get current date & time + LocalDateTime now = LocalDateTime.now(); + + // Format date-time (optional) + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + System.out.println("Date: "+ now.format(formatter)); + System.out.println("Activity: SluicePoint"); + System.out.println("File Type: " + filetype); + System.out.println("File Upload Path: " + filePath); + System.out.println("File Path: " + filepath_txt); + + return filepath_txt; + + } catch (IOException e) { + e.printStackTrace(); + System.out.println("Failed to save file " + file.getOriginalFilename()); + return "error"; + } + } + + @Transactional + public List> versionCheck() { + String sqlQuery = "SELECT * FROM `app_version` WHERE `isactive`=1 LIMIT 1"; + List> result = jdbcFoodTemplate.queryForList(sqlQuery); + return result; + } + + public String getWardByLoginId(String loginid) { + String sqlQuery = "SELECT `ward` FROM `location_mapping` WHERE `siloginid` = ? AND `isactive`=1 AND `isdelete`=0 LIMIT 1"; + + // Query the database using queryForList + List> results = jdbcFoodTemplate.queryForList(sqlQuery, loginid); + + // Check if results is not empty and extract the ward value + if (!results.isEmpty()) { + // Extract the ward value from the first result + return (String) results.get(0).get("ward"); + } + + // Handle the case where no result is found + return "000"; // or return null based on your needs + } + + @Transactional + public List> getloginList(String username, String password, String usertype) { + + String sqlQuery = ""; + List> result=null; + try { + switch (usertype) { + case "driver": + sqlQuery = "SELECT `loginid`, `name`, `username` FROM `driver_login` WHERE (`username`=? AND `password`=?) AND (`isactive`=1 AND `isdelete`=0) LIMIT 1"; + result = jdbcFoodTemplate.queryForList(sqlQuery, username, password); + break; + case "vendor": + sqlQuery = "SELECT `loginid`, `name`, `username` FROM `driver_login` WHERE (`username`=? AND `password`=?) AND (`isactive`=1 AND `isdelete`=0) LIMIT 1"; + result = jdbcFoodTemplate.queryForList(sqlQuery, username, password); + break; + // additional cases can be added here + default: + sqlQuery = "SELECT `loginid`, `name`, `username` FROM `driver_login` WHERE (`username`=? AND `password`=?) AND (`isactive`=1 AND `isdelete`=0) LIMIT 1"; + result = jdbcFoodTemplate.queryForList(sqlQuery, username, password); + //result = Collections.emptyList(); + break; + } + } catch (Exception e) { + // Log the error + e.printStackTrace(); + // Return an error message as part of the result list + return Collections.singletonList(Collections.singletonMap("error", "An error occurred while fetching data.")); + } + + // If no records found, return a status and message indicating no user found + if (result == null || result.isEmpty()) { + Map response = Map.of( + "status", 404, + "message", "User not found." + ); + return Collections.singletonList(response); + } + + // Add a success status and message to the result + Map successResponse = Map.of( + "status", 200, + "message", "login successfuly.", + "data", result + ); + return Collections.singletonList(successResponse); + } + + public List> getDeliveryLocation(String loginid) { + + //String searchDate = convertDateFormat(date,0); + + String sql = "SELECT * FROM `location_mapping` WHERE `driverid`=? AND `isactive`=1 AND `isdelete`=0"; + List> DeliveryLocation = jdbcFoodTemplate.queryForList(sql, loginid); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Delivery Location Details."); + response.put("data", DeliveryLocation); + + return Collections.singletonList(response); + } + + public List> getDriverStatus(String siloginid) { + + Map response = new HashMap<>(); + + // 1. Get driverid using siloginid + String sql1 = "SELECT driverid FROM location_mapping " + + "WHERE siloginid = ? AND isactive = 1 AND isdelete = 0"; + + List> driverList = jdbcFoodTemplate.queryForList(sql1, siloginid); + + if (driverList.isEmpty()) { + response.put("status", "Failed"); + response.put("message", "No driver found"); + response.put("data", Collections.emptyList()); + return Collections.singletonList(response); + } + + // Extract driverid + Object driverIdObj = driverList.get(0).get("driverid"); + + if (driverIdObj == null) { + response.put("status", "Failed"); + response.put("message", "DriverID is null"); + response.put("data", Collections.emptyList()); + return Collections.singletonList(response); + } + + String driverId = driverIdObj.toString(); + + // 2. Get latest start/stop entry + String sql = + "SELECT dss.*, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', dss.image) AS photourl, " + + "lm.id AS mapping_id, lm.zone, lm.zone_name, lm.ward, lm.location, " + + "lm.latitude, lm.logitude, lm.si_name, lm.si_number " + + "FROM driver_start_stop dss " + + "JOIN location_mapping lm ON lm.driverid = dss.loginid " + + "WHERE dss.loginid = ? AND dss.isactive = 1 AND dss.isdelete = 0 " + + "ORDER BY dss.locationid DESC LIMIT 1"; + + List> driverStatus = jdbcFoodTemplate.queryForList(sql, driverId); + + response.put("status", "Success"); + response.put("message", "Driver Status & Last Delivery Location Details"); + response.put("data", driverStatus); + + return Collections.singletonList(response); + } + + public List> getLiveTrack(String siloginid, String date) { + + Map response = new HashMap<>(); + + try { + // 1. Get driverid using siloginid + String sql1 = "SELECT driverid FROM location_mapping " + + "WHERE siloginid = ? AND isactive = 1 AND isdelete = 0"; + + List> deliveryLocation = jdbcFoodTemplate.queryForList(sql1, siloginid); + + if (deliveryLocation.isEmpty()) { + response.put("status", "Failed"); + response.put("message", "No driver found"); + response.put("data", Collections.emptyList()); + return Collections.singletonList(response); + } + + // Extract driverid + Object driverIdObj = deliveryLocation.get(0).get("driverid"); + + if (driverIdObj == null) { + response.put("status", "Failed"); + response.put("message", "DriverID is null"); + response.put("data", Collections.emptyList()); + return Collections.singletonList(response); + } + + String loginid = driverIdObj.toString(); + + // 2. Convert Date + String searchDate = convertDateFormat(date, 0); + + // 3. Fetch Live Track + String sql2 = "SELECT * FROM driver_live_track " + + "WHERE loginid = ? AND DATE(datetime) = ? AND isactive = 1 AND isdelete = 0 " + + "ORDER BY datetime"; + + List> liveTrack = + jdbcFoodTemplate.queryForList(sql2, loginid, searchDate); + + // 4. Prepare Response + response.put("status", "Success"); + response.put("message", "Live Track Details."); + response.put("data", liveTrack); + + } catch (Exception e) { + response.put("status", "Failed"); + response.put("message", "Error: " + e.getMessage()); + response.put("data", Collections.emptyList()); + } + + return Collections.singletonList(response); + } + + public List> getDriverLastStartStop(String loginid) { + + String sql = "SELECT * FROM `driver_start_stop` WHERE `loginid`=? ORDER BY locationid DESC LIMIT 1"; + List> liveTrack = jdbcFoodTemplate.queryForList(sql, loginid); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Driver Status Details."); + response.put("data", liveTrack); + + return Collections.singletonList(response); + } + + @Transactional + public List> saveStartStop( + String loginid, + String latitude, + String longitude, + String action, + String startid, + String driver_live_mobile, + MultipartFile image, + String address, + String driver_name + ) { + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + String filetype = "image"; + + // Q1 Image + final String[] image_path = { null }; + if (image != null && !image.isEmpty()) { + image_path[0] = fileUpload(loginid, action, image, filetype); + if ("error".equalsIgnoreCase(image_path[0])) { + response.put("status", "error"); + response.put("message", "Feedback image upload failed."); + result.add(response); + return result; + } + } + + String insertSqltxt = "INSERT INTO `driver_start_stop`(`latitude`, `longitude`, `image`,`loginid`,`action`,`startid`,`driver_live_mobile`,`address`,`driver_name`) " + + "VALUES (?,?,?,?,?,?,?,?,?)"; + + String insertSql = insertSqltxt; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcFoodTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"requestid"}); + int i = 1; + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, image_path[0]); + ps.setString(i++, loginid); + ps.setString(i++, action); + ps.setString(i++, startid); + ps.setString(i++, driver_live_mobile); + ps.setString(i++, address); + ps.setString(i++, driver_name); + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Driver Point", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", action + " data inserted successfully."); + + saveLiveLocation(loginid,latitude,longitude,address); // Save location In Live Track on start and stop + + } else { + response.put("Driver Point", action + " insertId error!"); + response.put("status", "error"); + response.put("message", action + " data insert failed."); + } + + result.add(response); + return result; + } + + @Transactional + public List> saveLiveLocation( + String loginid, + String latitude, + String longitude, + String address + ) { + String action = "Live Location"; + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + String insertSqltxt = "INSERT INTO `driver_live_track`(`loginid`, `latitude`, `longitude`, `address`) " + + "VALUES (?,?,?,?)"; + + String insertSql = insertSqltxt; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcFoodTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"requestid"}); + int i = 1; + ps.setString(i++, loginid); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, address); + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Driver", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", action + " data inserted successfully."); + } else { + response.put("Driver", action + " insertId error!"); + response.put("status", "error"); + response.put("message", action + " data insert failed."); + } + + result.add(response); + return result; + } + + // Vendor + public List> getPendingDetails(String loginid, String shiftid, String date) { + + String searchDate = convertDateFormat(date, 0); + /* + // 1. Get shortfall details + String sql = "SELECT " + + " dr.required_date, " + + " dr.shiftid, " + + " sm.Code, " + + " sm.name, " + + " sm.hint, " + + " sm.time, " + + " sm.enable_time, " + + " sm.disable_time, " + + " (dr.permanent + dr.nulm + dr.private + dr.others + dr.nmr) - " + + " (" + + " (dr.weeklyoff_permanent + dr.weeklyoff_nulm + dr.weeklyoff_private + dr.weeklyoff_others + dr.weeklyoff_nmr) + " + + " (dr.absentees_permanent + dr.absentees_nulm + dr.absentees_private + dr.absentees_others + dr.absentees_nmr) " + + " ) AS sum_total_food_requested " + + "FROM daily_request dr " + + "JOIN shift_master sm " + + " ON sm.shiftid = dr.shiftid " + + "WHERE dr.required_date = ? " + + " AND dr.shiftid = ? " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0" + + " GROUP BY dr.required_date, dr.shiftid"; + */ + // 1. Get shortfall details + String sql = + "SELECT " + + " dr.required_date, " + + " dr.shiftid, " + + " sm.Code, " + + " sm.name, " + + " sm.hint, " + + " sm.time, " + + " sm.enable_time, " + + " sm.disable_time, " + + " SUM( " + + " (dr.permanent + dr.nulm + dr.private + dr.others + dr.nmr) - " + + " ( " + + " (dr.weeklyoff_permanent + dr.weeklyoff_nulm + dr.weeklyoff_private + dr.weeklyoff_others + dr.weeklyoff_nmr) + " + + " (dr.absentees_permanent + dr.absentees_nulm + dr.absentees_private + dr.absentees_others + dr.absentees_nmr) " + + " ) " + + " ) AS sum_total_food_requested " + + "FROM daily_request dr " + + "JOIN shift_master sm " + + " ON sm.shiftid = dr.shiftid " + + "WHERE dr.required_date = ? " + + " AND dr.shiftid = ? " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + "GROUP BY dr.required_date, dr.shiftid"; + + List> shortfallDetails = jdbcFoodTemplate.queryForList(sql, searchDate, shiftid); + + // 2. Get requested food details + sql = "SELECT " + + " dr.requestid, " + + " dr.request_by, " + + " dr.request_date, " + + " (dr.permanent + dr.nulm + dr.private + dr.others + dr.nmr) - " + + " ( " + + " (dr.weeklyoff_permanent + dr.weeklyoff_nulm + dr.weeklyoff_private + dr.weeklyoff_others + dr.weeklyoff_nmr) + " + + " (dr.absentees_permanent + dr.absentees_nulm + dr.absentees_private + dr.absentees_others + dr.absentees_nmr) " + + " ) AS total_food_requested, " + + " lm.id AS mapping_id, " + + " lm.zone, " + + " lm.zone_name, " + + " lm.ward, " + + " lm.location, " + + " lm.Latitude, " + + " lm.logitude, " + + " lm.si_name, " + + " lm.si_number, " + + " lm.driverid, " + + " lm.siloginid " + + "FROM daily_request dr " + + "JOIN location_mapping lm " + + " ON dr.request_by = lm.siloginid " + + "WHERE " + + " dr.required_date = ? " + + " AND dr.shiftid = ? " + + " AND dr.isactive = 1 " + + " AND dr.isdelete = 0 " + + " AND lm.isactive = 1 " + + " AND lm.isdelete = 0"; + + List> requestedInfo = jdbcFoodTemplate.queryForList(sql, searchDate, shiftid); + + + /* + // 2. Get requested food details + sql = "SELECT `foodid`, `type`, `name`, `isactive`, `isdelete` FROM `food_list_master` WHERE `isactive`=1 AND `isdelete`=0"; + + List> foodInfo = jdbcFoodTemplate.queryForList(sql); + + // 2. Combine both list results + // Combine request info (shortfall + requested) + //List> requestInfo = new ArrayList<>(); + //requestInfo.addAll(shortfallDetails); + //requestInfo.addAll(requestedInfo); + */ + // Final response structure + Map data = new HashMap<>(); + data.put("request_info", requestedInfo); + data.put("summary_info", shortfallDetails); + + // 3. Create final response + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Pending Details."); + response.put("data", data); + + return Collections.singletonList(response); + } + + + public List> getMenuDetails(String loginid) { + + // Get requested food details + String sql = "SELECT `foodid`, `type`, `name`, `isactive`, `isdelete` FROM `food_list_master` WHERE `isactive`=1 AND `isdelete`=0"; + + List> foodInfo = jdbcFoodTemplate.queryForList(sql); + + // 3. Create final response + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Food Menu Details."); + response.put("data", foodInfo); + + return Collections.singletonList(response); + } + + + public List> getRequestUpdated(String loginid, String shiftid, String date) { + + String searchDate = convertDateFormat(date, 0); + + // Get requested food details + String sql = "SELECT `uid`, `shiftid`, `total_food_request_recived`, `total_food_transported`, `foodid`, `indate`, `inby`" + + " FROM `vendor_food_update` WHERE `shiftid`=? AND DATE(`indate`)=? AND `isactive`=1 AND `isdelete`=0"; + + List> requestUpadteInfo = jdbcFoodTemplate.queryForList(sql,shiftid, searchDate); + + // 3. Create final response + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Request Update Details."); + response.put("data", requestUpadteInfo); + + return Collections.singletonList(response); + } + + @Transactional + public List> saveRequestUpadte( + String loginid, + String shiftid, + String total_food_request_recived, + String total_food_transported, + String foodid + ) { + String action = "Food Request Status update"; + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + String insertSqltxt = "INSERT INTO `vendor_food_update`(`shiftid`, `total_food_request_recived`, `total_food_transported`, `foodid`,`inby`) " + + "VALUES (?,?,?,?,?)"; + + String insertSql = insertSqltxt; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcFoodTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"requestid"}); + int i = 1; + + ps.setString(i++, shiftid); + ps.setString(i++, total_food_request_recived); + ps.setString(i++, total_food_transported); + ps.setString(i++, foodid); + ps.setString(i++, loginid); + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Driver", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", action + " data inserted successfully."); + } else { + response.put("Driver", action + " insertId error!"); + response.put("status", "error"); + response.put("message", action + " data insert failed."); + } + + result.add(response); + return result; + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccDomesticWaste/Controller/DomesticWasteController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccDomesticWaste/Controller/DomesticWasteController.java index 4715cb0..c9bb9d8 100644 --- a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccDomesticWaste/Controller/DomesticWasteController.java +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccDomesticWaste/Controller/DomesticWasteController.java @@ -15,8 +15,6 @@ public class DomesticWasteController { @Autowired DomesticWasteService domesticWasteService; - - @PostMapping("/save-request") public ResponseEntity saveRequest( @RequestParam String user_name, @@ -27,18 +25,19 @@ public class DomesticWasteController { @RequestParam String zone, @RequestParam String division, @RequestParam String street_name, - @RequestParam String street_id, + @RequestParam(value="street_id", required = false) String street_id, @RequestParam String remarks, @RequestParam(value="sofa_type", required = false) String sofa_type, @RequestParam("items") String itemsJson, - @RequestParam (name = "image") MultipartFile imageFile) { + @RequestParam (name = "image") MultipartFile imageFile, + @RequestParam(value="is_app", required = false) String is_app) { try { Map result = domesticWasteService.saveMultipleWasteRequests( user_name, mobile, address, latitude, longitude, zone, division, street_name, street_id, remarks, - imageFile, itemsJson,sofa_type + imageFile, itemsJson, sofa_type, is_app ); return ResponseEntity.ok(result); @@ -94,13 +93,13 @@ public class DomesticWasteController { @PostMapping("/action-taken") public ResponseEntity saveActionTaken( - @RequestParam int reqid, + @RequestParam String reqid, @RequestParam(value = "image") MultipartFile image, @RequestParam("created_by") int createdBy, @RequestParam String latitude, @RequestParam String longitude ) { - Map result = domesticWasteService.actionTaken(String.valueOf(reqid), image, createdBy,latitude,longitude); + Map result = domesticWasteService.actionTaken(reqid, image, createdBy,latitude,longitude); if ((boolean) result.get("status")) { return ResponseEntity.ok(result); @@ -143,4 +142,31 @@ public class DomesticWasteController { Map result = domesticWasteService.rejectuserreqofficer(requestId, officer_remark, rejecttype, cancelled_by,latitude,longitude); return ResponseEntity.ok(result); } + + @GetMapping(value="/getZoneReport") + public List getZoneReport( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate + ){ + return domesticWasteService.getZoneReport(fromDate, toDate); + } + + @GetMapping(value="/getWardReport") + public List getWardReport( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate, + @RequestParam(value="zone", required = true) String zone + ){ + return domesticWasteService.getWardReport(fromDate, toDate, zone); + } + + @GetMapping(value="/getWardStatusDetails") + public List getWardStatusDetails( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate, + @RequestParam(value="ward", required = true) String ward, + @RequestParam(value="status", required = true) String status + ){ + return domesticWasteService.getWardStatusDetails(fromDate, toDate, ward, status); + } } diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccDomesticWaste/Service/DomesticWasteService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccDomesticWaste/Service/DomesticWasteService.java index cc5a7de..17e96dd 100644 --- a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccDomesticWaste/Service/DomesticWasteService.java +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccDomesticWaste/Service/DomesticWasteService.java @@ -8,6 +8,7 @@ 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; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; @@ -17,6 +18,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; @@ -96,8 +98,10 @@ public class DomesticWasteService { public Map saveMultipleWasteRequests(String user_name, String mobile, String address, String latitude, String longitude, String zone, String division, String street_name, String street_id, String remarks, - MultipartFile imageFile, String itemsJson, String sofa_type) { - + MultipartFile imageFile, String itemsJson, String sofa_type, String is_app) { + + final String is_app_value = (is_app == null || is_app.trim().isEmpty()) ? "1" : is_app; + String imagePath = fileUpload(imageFile, "domestic_waste_photo"); if (imagePath == null) { return Map.of("status", false, "message", "Image upload failed"); @@ -106,8 +110,8 @@ public class DomesticWasteService { try { // Step 1: Insert main request (one time) String insertMainSql = "INSERT INTO user_request_table " + - "(request_id, user_name, mobile, address, latitude, longitude, zone, division, street_name, street_id, remarks, image_url, sofa_type) " + - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + "(request_id, user_name, mobile, address, latitude, longitude, zone, division, street_name, street_id, remarks, image_url, sofa_type, is_app) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcDomesticWasteTemplate.update(con -> { @@ -125,6 +129,7 @@ public class DomesticWasteService { ps.setString(11, remarks); ps.setString(12, imagePath); ps.setString(13, sofa_type); + ps.setString(14, is_app_value); return ps; }, keyHolder); @@ -188,7 +193,24 @@ public class DomesticWasteService { return groupRequestsWithItems(rawData); } + public String getWardByLoginId(String loginid) { + String sqlQuery = "SELECT `ward` FROM gcc_penalty_hoardings.`hoading_user_list` WHERE `userid` = ? LIMIT 1"; + + // Query the database using queryForList + List> results = jdbcDomesticWasteTemplate.queryForList(sqlQuery, loginid); + + // Check if results is not empty and extract the ward value + if (!results.isEmpty()) { + // Extract the ward value from the first result + return (String) results.get(0).get("ward"); + } + + // Handle the case where no result is found + return "000"; // or return null based on your needs + } + public List> getAllWasteRequestsbylogin(String loginId) { + /* String zoneSql = "SELECT zone, division FROM officer_master WHERE loginId = ? AND is_active = 1 AND is_delete = 0"; List> zoneList = jdbcDomesticWasteTemplate.queryForList(zoneSql, loginId); @@ -210,6 +232,11 @@ public class DomesticWasteService { params.add(row.get("zone")); params.add(row.get("division")); } + */ + List params = new ArrayList<>(); + StringBuilder zoneCondition = new StringBuilder("("); + zoneCondition.append("(u.division = ?)"); + params.add(getWardByLoginId(loginId)); zoneCondition.append(") ORDER BY u.cdate DESC"); /* String sql = "SELECT " + @@ -236,6 +263,9 @@ public class DomesticWasteService { "WHERE u.status IN(1,3) " + "AND u.is_active = 1 AND " + zoneCondition; + System.err.println(sql); + System.err.println(Arrays.toString(params.toArray())); + System.err.println(loginId); List> rawData = jdbcDomesticWasteTemplate.queryForList(sql, params.toArray()); return groupRequestsWithItems(rawData); } @@ -317,7 +347,8 @@ public class DomesticWasteService { } public List> getuserAE2(String loginId) { - String zoneSql = "SELECT zone, division FROM officer_master WHERE loginId = ? AND is_active = 1 AND is_delete = 0"; + /* + String zoneSql = "SELECT zone, division FROM officer_master WHERE loginId = ? AND is_active = 1 AND is_delete = 0"; List> zoneList = jdbcDomesticWasteTemplate.queryForList(zoneSql, loginId); //if (zoneList.isEmpty()) return List.of(); @@ -339,7 +370,13 @@ public class DomesticWasteService { params.add(row.get("division")); } zoneCondition.append(")"); - +*/ + List params = new ArrayList<>(); + StringBuilder zoneCondition = new StringBuilder("("); + zoneCondition.append("(u.division = ?)"); + params.add(getWardByLoginId(loginId)); + zoneCondition.append(") ORDER BY u.cdate DESC"); + String sql = "SELECT " + "u.id, u.request_id, u.user_name, u.mobile, u.address, u.latitude, u.longitude, " + "u.zone, u.division, u.street_name, u.quantity AS main_quantity, u.remarks, " + @@ -363,7 +400,8 @@ public class DomesticWasteService { public List> getuserZonal(String loginId) { - String zoneSql = "SELECT zone, division FROM officer_master WHERE loginId = ? AND is_active = 1 AND is_delete = 0"; + /* + String zoneSql = "SELECT zone, division FROM officer_master WHERE loginId = ? AND is_active = 1 AND is_delete = 0"; List> zoneList = jdbcDomesticWasteTemplate.queryForList(zoneSql, loginId); //if (zoneList.isEmpty()) return List.of(); @@ -385,7 +423,13 @@ public class DomesticWasteService { params.add(row.get("division")); } zoneCondition.append(")"); - +*/ + List params = new ArrayList<>(); + StringBuilder zoneCondition = new StringBuilder("("); + zoneCondition.append("(u.division = ?)"); + params.add(getWardByLoginId(loginId)); + zoneCondition.append(") ORDER BY u.cdate DESC"); + String sql = "SELECT " + "u.id, u.request_id, u.user_name, u.mobile, u.address, u.latitude, u.longitude, " + "u.zone, u.division, u.street_name, u.remarks, " + @@ -484,8 +528,8 @@ public class DomesticWasteService { // Step 2: Insert into officer_data String insertSql = "INSERT INTO officer_data (request_id, image_url, cdate, is_active, created_by,latitude,longitude) " + - "VALUES (?, ?, NOW(), ?, ?,?,?)"; - jdbcDomesticWasteTemplate.update(insertSql, requestId, imagePath, true, createdBy,latitude,longitude); + "VALUES (?, ?, NOW(), ?, ?, ?, ?)"; + jdbcDomesticWasteTemplate.update(insertSql, requestId, imagePath, true, createdBy, latitude, longitude); // Step 3: Update user_request_table - status, officer_upload_url, and close_date from officer_data String updateSql = "UPDATE user_request_table u " + @@ -629,4 +673,125 @@ public class DomesticWasteService { return Map.of("status", false, "message", "Error: " + e.getMessage()); } } + + @Transactional + public List> getZoneReport(String fromDate, String toDate) { + // 1. Fetch all active streets for the ward (with zone info) + String sqlStreet = "(" + + " SELECT " + + " ur.zone," + + " COUNT(*) AS total_request," + + " SUM(CASE WHEN ur.status = 1 THEN 1 ELSE 0 END) AS open," + + " SUM(CASE WHEN ur.status = 2 THEN 1 ELSE 0 END) AS completed," + + " SUM(CASE WHEN ur.status = 3 THEN 1 ELSE 0 END) AS pending," + + " SUM(CASE WHEN ur.status = 4 THEN 1 ELSE 0 END) AS user_cancel," + + " SUM(CASE WHEN ur.status = 5 THEN 1 ELSE 0 END) AS officer_cancel" + + " FROM user_request_table ur" + + " WHERE ur.is_active = 1 AND ur.is_delete = 0" + + " GROUP BY ur.zone" + + ")" + + + "UNION ALL" + + + "(" + + " SELECT " + + " 'TOTAL' AS zone," + + " COUNT(*) AS total_request," + + " SUM(CASE WHEN ur.status = 1 THEN 1 ELSE 0 END) AS open," + + " SUM(CASE WHEN ur.status = 2 THEN 1 ELSE 0 END) AS completed," + + " SUM(CASE WHEN ur.status = 3 THEN 1 ELSE 0 END) AS pending," + + " SUM(CASE WHEN ur.status = 4 THEN 1 ELSE 0 END) AS user_cancel," + + " SUM(CASE WHEN ur.status = 5 THEN 1 ELSE 0 END) AS officer_cancel" + + " FROM user_request_table ur" + + " WHERE ur.is_active = 1 AND ur.is_delete = 0" + + ") " + + "ORDER BY " + + " CASE WHEN zone = 'TOTAL' THEN 999 ELSE zone END"; + + List> reportList = jdbcDomesticWasteTemplate.queryForList(sqlStreet); + + Map response = new LinkedHashMap<>(); + response.put("status", "Success"); + response.put("message", "Zone wise Report"); + response.put("data", reportList); + + return Collections.singletonList(response); + } + + @Transactional(readOnly = true) + public List> getWardReport(String fromDate, String toDate, String zone) { + String sql = + "(" + + " SELECT " + + " ur.division AS division, " + + " COUNT(*) AS total_request, " + + " SUM(CASE WHEN ur.status = 1 THEN 1 ELSE 0 END) AS open, " + + " SUM(CASE WHEN ur.status = 2 THEN 1 ELSE 0 END) AS completed, " + + " SUM(CASE WHEN ur.status = 3 THEN 1 ELSE 0 END) AS pending, " + + " SUM(CASE WHEN ur.status = 4 THEN 1 ELSE 0 END) AS user_cancel, " + + " SUM(CASE WHEN ur.status = 5 THEN 1 ELSE 0 END) AS officer_cancel " + + " FROM user_request_table ur " + + " WHERE ur.is_active = 1 AND ur.is_delete = 0 AND ur.zone = ? " + + " GROUP BY ur.division " + + ") " + + "UNION ALL " + + "(" + + " SELECT " + + " 'TOTAL' AS division, " + + " COUNT(*) AS total_request, " + + " SUM(CASE WHEN ur.status = 1 THEN 1 ELSE 0 END) AS open, " + + " SUM(CASE WHEN ur.status = 2 THEN 1 ELSE 0 END) AS completed, " + + " SUM(CASE WHEN ur.status = 3 THEN 1 ELSE 0 END) AS pending, " + + " SUM(CASE WHEN ur.status = 4 THEN 1 ELSE 0 END) AS user_cancel, " + + " SUM(CASE WHEN ur.status = 5 THEN 1 ELSE 0 END) AS officer_cancel " + + " FROM user_request_table ur " + + " WHERE ur.is_active = 1 AND ur.is_delete = 0 AND ur.zone = ? " + + ") " + + "ORDER BY " + + " CASE WHEN division = 'TOTAL' THEN 999 ELSE CAST(division AS UNSIGNED) END"; + + List> reportList = jdbcDomesticWasteTemplate.queryForList(sql, zone, zone); + + Map response = new LinkedHashMap<>(); + response.put("status", "Success"); + response.put("message", "Ward-wise Report"); + response.put("data", reportList); + + return Collections.singletonList(response); + } + + @Transactional(readOnly = true) + public List> getWardStatusDetails( + String fromDate, String toDate, + String ward, String status) { + + // ✅ Base URL for images + String fileBaseUrl = "https://gccservices.in"; // or your configured value + + // ✅ SQL query with ward + status filters + String sql = + "SELECT " + + " u.id, u.request_id, u.user_name, u.mobile, u.address, " + + " u.latitude, u.longitude, u.zone, u.division, u.street_name, " + + " u.quantity AS main_quantity, u.remarks, " + + " CONCAT('" + fileBaseUrl + "/gccofficialapp/files', u.image_url) AS image_url, " + + " DATE_FORMAT(u.cdate, '%d-%m-%Y') AS cdate, " + + " sm.status_master AS status, " + + " DATE_FORMAT(u.close_date, '%d-%m-%Y') AS close_date, " + + " CONCAT('" + fileBaseUrl + "/gccofficialapp/files', u.officer_upload_url) AS officer_upload_url, " + + " im.item_name, itm.quantity " + + "FROM user_request_table u " + + "LEFT JOIN items itm ON u.id = itm.req_table_id " + + "LEFT JOIN item_master im ON itm.iteam_id = im.id AND im.is_active = 1 " + + "LEFT JOIN status_master sm ON sm.id = u.status AND sm.is_active = 1 AND sm.is_delete = 0 " + + "WHERE u.is_active = 1 AND u.is_delete = 0 " + + " AND u.division = ? " + + " AND u.status = ? " + + "ORDER BY u.cdate DESC"; + + // ✅ Execute query + List> reportList = jdbcDomesticWasteTemplate.queryForList(sql, ward, status); + return groupRequestsWithItems(reportList); + + } } diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccHealthCamp/controller/HealthCampController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccHealthCamp/controller/HealthCampController.java new file mode 100644 index 0000000..44f3e20 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccHealthCamp/controller/HealthCampController.java @@ -0,0 +1,157 @@ +package in.gov.chennaicorporation.mobileservice.gccHealthCamp.controller; + +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +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.RestController; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.gccHealthCamp.service.HealthCampService; + +@RequestMapping("/gccofficialapp/api/healthcamp") +@RestController("gccofficialapphealthcamp") + +public class HealthCampController { + + @Autowired + private HealthCampService healthCampService; + + // get all camptypes + + @GetMapping("/camptypes") + public List> getAllHealthCamp() { + return healthCampService.getAllHealthCamp(); + } + + // get all disease category + + @GetMapping("/diseasecategory") + public List> getAllDisease() { + return healthCampService.getAlldisease(); + } + + // get all gender + + @GetMapping("/gender") + public List> getAllGender() { + return healthCampService.getAllgender(); + } + + @GetMapping("/getcampbydate") + public List> getCampByDate(@RequestParam String userid) { + return healthCampService.getCampByDate(userid); + } + + + // save the camp details + + @PostMapping("/savecampdetails") + public ResponseEntity> saveHealthCampDetails( + + @RequestParam("camptypeId") int camptypeId, + @RequestParam("latitude") String latitude, + @RequestParam("longitude") String longitude, + @RequestParam("zone") String zone, + @RequestParam("ward") String ward, + @RequestParam("address") String address, + @RequestParam("campName") String campName, + //@RequestParam("noofpamphlets") int noofpamphlets, + @RequestParam("camp_photo") MultipartFile campPhoto, + @RequestParam("userid") String userid, + @RequestParam("streetName") String streetName, + @RequestParam("doc_name") String doc_name, + @RequestParam("mo_name") String mo_name, + @RequestParam("si_name") String si_name) { + + // File upload paths + + String campPhotoPath = (campPhoto != null) ? healthCampService.fileUpload(campPhoto, "camp_photo") : ""; + + // Save to DB + String saveStatus = healthCampService.saveHealthCampDetails(camptypeId, latitude, longitude, zone, ward, + address, campName, campPhotoPath, userid,streetName,doc_name,mo_name,si_name + + ); + + if (saveStatus == null || saveStatus.isEmpty()) { + return ResponseEntity + .ok(Map.of("status", false, "message", "failed", "description", "Failed to save the details")); + } + + return ResponseEntity + .ok(Map.of("status", true, "message", "success", "description", "Details saved successfully")); + + } + + // save the patient details + + @PostMapping("/savepatientdetails") + public ResponseEntity> savePatientDetails( + + @RequestParam("campId") int campId, + @RequestParam("pat_name") String pat_name, + @RequestParam("pat_age") String pat_age, + @RequestParam("genderId") int genderId, + @RequestParam("mobileNo") String mobileNo, + @RequestParam("pat_address") String pat_address, + @RequestParam(required = false, name = "otherDisease") String otherDisease, + @RequestParam("remarks") String remarks, + @RequestParam("userid") String userid, + @RequestParam("diseaseIds") List diseaseIds) { + + // Save to DB + String saveStatus = healthCampService.savePatientDetails( + + campId, pat_name, pat_age, genderId, mobileNo, pat_address, otherDisease, remarks, userid, diseaseIds + + ); + + if (saveStatus == null || saveStatus.isEmpty()) { + return ResponseEntity + .ok(Map.of("status", false, "message", "failed", "description", "Failed to save the details")); + } + + return ResponseEntity + .ok(Map.of("status", true, "message", "success", "description", "Details saved successfully")); + + } + + // Reports + + @GetMapping("/campsummary") + public Map getCampSummary(@RequestParam("date") String date) { + + return healthCampService.getCampSummary(date); + + } + + @GetMapping("/zonewisedetails") + + public Map getWardwiseDetails(@RequestParam("date") String date, + @RequestParam("zoneId") String zoneId) { + return healthCampService.getWardwiseDetails(date, zoneId); + + } + + @GetMapping("/wardwisedetails") + + public List> getCampwiseDetails(@RequestParam("date") String date, + @RequestParam("ward") String ward) { + return healthCampService.getCampwiseDetails(date, ward); + + } + + @GetMapping("/campwisedetails") + + public List> getCampDetails(@RequestParam("campId") String campId) { + return healthCampService.getCampDetails(campId); + + } + +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccHealthCamp/service/HealthCampService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccHealthCamp/service/HealthCampService.java new file mode 100644 index 0000000..00a46c6 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccHealthCamp/service/HealthCampService.java @@ -0,0 +1,385 @@ +package in.gov.chennaicorporation.mobileservice.gccHealthCamp.service; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.sql.PreparedStatement; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.env.Environment; +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.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.gccactivity.service.DateTimeUtil; + +@Service +public class HealthCampService { + + @Autowired + private JdbcTemplate jdbcHealthCampTemplate; + + private final Environment environment; + private String fileBaseUrl; + + @Autowired + public void setDataSource(@Qualifier("mysqlGccMedicalCampDataSource") DataSource healthCampDataSource) { + this.jdbcHealthCampTemplate = new JdbcTemplate(healthCampDataSource); + } + + public HealthCampService(Environment environment) { + this.environment = environment; + this.fileBaseUrl = environment.getProperty("fileBaseUrl"); + } + + public List> getAllHealthCamp() { + String sql = " select id,name from camp_type where is_active=1 AND is_delete=0 "; + return jdbcHealthCampTemplate.queryForList(sql); + } + + public List> getAlldisease() { + String sql = " select id,disease_name from disease_master where is_active=1 AND is_delete=0 "; + return jdbcHealthCampTemplate.queryForList(sql); + } + + public List> getAllgender() { + String sql = " select id,gender from gender_master where is_active=1 AND is_delete=0 "; + return jdbcHealthCampTemplate.queryForList(sql); + } + + public String getWardByLoginId(String loginid, String type) { + String sqlQuery = "SELECT ward FROM gcc_penalty_hoardings.hoading_user_list WHERE userid = ? AND type = ? LIMIT 1"; + + List> results = jdbcHealthCampTemplate.queryForList(sqlQuery, loginid, type); + + if (!results.isEmpty()) { + System.out.println("Ward....." + results); + // Extract the ward value from the first result + return (String) results.get(0).get("ward"); + } + + return "000"; + } + + public List> getCampByDate(String userid) { + String ward = getWardByLoginId(userid, "si"); + String sql = "select id,camp_name from camp_details WHERE ward = ? AND DATE(cdate) = CURDATE() AND is_active=1 AND is_delete=0 "; + return jdbcHealthCampTemplate.queryForList(sql,ward); + } + + public String fileUpload(MultipartFile file, String name) { + + // Set the file path where you want to save it + String uploadDirectory = environment.getProperty("file.upload.directory"); + String serviceFolderName = environment.getProperty("healthcamp_folder"); + + var year = DateTimeUtil.getCurrentYear(); + var month = DateTimeUtil.getCurrentMonth(); + + uploadDirectory = uploadDirectory + serviceFolderName + year + "/" + month; + + try { + // Create directory if it doesn't exist + Path directoryPath = Paths.get(uploadDirectory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Datetime string + String datetimetxt = DateTimeUtil.getCurrentDateTime(); + // File name + String fileName = name + "_" + datetimetxt + "_" + file.getOriginalFilename(); + fileName = fileName.replaceAll("\\s+", ""); // Remove space on filename + + String filePath = uploadDirectory + "/" + fileName; + + String filepath_txt = "/" + serviceFolderName + year + "/" + month + "/" + fileName; + + // Create a new Path object + Path path = Paths.get(filePath); + + // Get the bytes of the file + byte[] bytes = file.getBytes(); + + // Compress the image + BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); + byte[] compressedBytes = compressImage(image, 0.5f); // Compress with 50% quality + + // Write the bytes to the file + Files.write(path, compressedBytes); + + System.out.println(filePath); + return filepath_txt; + + } catch (IOException e) { + e.printStackTrace(); + return "Failed to save file " + file.getOriginalFilename(); + } + } + + private byte[] compressImage(BufferedImage image, float quality) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream); + + ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next(); + writer.setOutput(imageOutputStream); + + ImageWriteParam param = writer.getDefaultWriteParam(); + if (param.canWriteCompressed()) { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(quality); + } + + writer.write(null, new javax.imageio.IIOImage(image, null, null), param); + + writer.dispose(); + imageOutputStream.close(); + + return byteArrayOutputStream.toByteArray(); + } + + // Function to convert date string from dd-MM-yyyy to yyyy-MM-dd + public static String convertDateFormat(String inputDate, int add) { + // Check if the inputDate is not null or blank + if (inputDate != null && !inputDate.isBlank()) { + try { + // Define the input and output date formats + DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + // Parse the input date string to LocalDate + LocalDate date = LocalDate.parse(inputDate, inputFormatter); + + // Add the specified number of days to the date if 'add' is greater than 0 + if (add > 0) { + date = date.plusDays(add); + } + + // Format the date to the new format + return date.format(outputFormatter); + + } catch (DateTimeParseException e) { + // Handle the case where the input date is invalid + System.out.println("Invalid date format: " + inputDate); + return ""; + } + } else { + return ""; + } + } + + public String saveHealthCampDetails(int camptypeId, String latitude, String longitude, String zone, String ward, + String address, String campName, String campPhotoPath, String userid, + String streetName,String doc_name,String mo_name,String si_name) { + + String sql = "INSERT INTO camp_details (" + + + "camp_type_id, latitude, longitude, zone, ward, address, camp_name, camp_img, cby," + + "street_name, doc_name, mo_name, si_name " + + + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + try { + int result = jdbcHealthCampTemplate.update(sql, camptypeId, latitude, longitude, zone, ward, address, + campName, campPhotoPath, userid, streetName, doc_name, mo_name, si_name); + + return result > 0 ? "success" : "failed"; + } catch (Exception e) { + e.printStackTrace(); + return "failed"; + } + } + + public String savePatientDetails(int campId, String pat_name, String pat_age, int genderId, String mobileNo, + String pat_address, + + String otherDisease, String remarks, String userid, List diseaseIds) { + + String sql = "INSERT INTO patient_details (" + + + " camp_id, pt_name, pt_age, pt_gender_id, pt_mob_no, pt_address, pt_other_disease, remarks, cby" + + + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + try { + int result = jdbcHealthCampTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(sql, new String[] { "id" }); + ps.setInt(1, campId); + ps.setString(2, pat_name); + ps.setString(3, pat_age); + ps.setInt(4, genderId); + ps.setString(5, mobileNo); + ps.setString(6, pat_address); +// ps.setInt(7, diseaseId); + ps.setString(7, otherDisease); + ps.setString(8, remarks); + ps.setString(9, userid); + + return ps; + }, keyHolder); + // return keyHolder.getKey().intValue(); + if (result > 0) { + int generatedId = keyHolder.getKey().intValue(); + String prefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); + String patientId = prefix + generatedId; + + String updateSql = " UPDATE patient_details SET patient_id = ? WHERE id = ? "; + jdbcHealthCampTemplate.update(updateSql, patientId, generatedId); + + // INSERT MULTIPLE DISEASES + String diseaseSql = "INSERT INTO diseases_details (patient_id, disease_id) VALUES (?, ?)"; + + for (String id : (diseaseIds)) { + int diseaseId = Integer.parseInt(id); + jdbcHealthCampTemplate.update(diseaseSql, patientId, diseaseId); + } + + return patientId; + } + // return "error"; + } catch (Exception e) { + e.printStackTrace(); + } + return "error"; + } + + + // report related + + public Map getCampSummary(String date) { + + String datetxt = convertDateFormat(date,0); + + try { + + // Total Counts + String totalSql = "SELECT COUNT(DISTINCT cd.id) AS total_camp_count, " + "COUNT(pd.id) AS total_pat_count " + + "FROM camp_details cd " + "LEFT JOIN patient_details pd ON cd.id = pd.camp_id " + + "WHERE DATE(cd.cdate) = ?"; + + Map totalCounts = jdbcHealthCampTemplate.queryForMap(totalSql, datetxt); + + // Zone-wise Counts + String zoneSql = "SELECT cd.zone, COUNT(DISTINCT cd.id) AS total_camp_count, " + + "COUNT(pd.id) AS total_pat_count " + "FROM camp_details cd " + + "LEFT JOIN patient_details pd ON cd.id = pd.camp_id " + "WHERE DATE(cd.cdate) = ? " + + "GROUP BY cd.zone"; + + List> zoneList = jdbcHealthCampTemplate.queryForList(zoneSql, datetxt); + totalCounts.put("zoneList", zoneList); + + return totalCounts; + } catch (Exception ex) { + ex.printStackTrace(); + Map response = new HashMap<>(); + response.put("status", "No data found"); + return Collections.singletonMap("status", "No data found"); + + } + + } + + public Map getWardwiseDetails(String date, String zoneId) { + + String datetxt = convertDateFormat(date,0); + + try { + + // Total Counts + String totalSql = "SELECT COUNT(DISTINCT cd.id) AS total_camp_count, " + "COUNT(pd.id) AS total_pat_count " + + "FROM camp_details cd " + "LEFT JOIN patient_details pd ON cd.id = pd.camp_id " + + "WHERE DATE(cd.cdate) = ? AND cd.zone=?"; + + Map totalCounts = jdbcHealthCampTemplate.queryForMap(totalSql, datetxt, zoneId); + + // Zone-wise Counts + String zoneSql = "SELECT cd.ward, COUNT(DISTINCT cd.id) AS total_camp_count, " + + "COUNT(pd.id) AS total_pat_count " + "FROM camp_details cd " + + "LEFT JOIN patient_details pd ON cd.id = pd.camp_id " + "WHERE DATE(cd.cdate) = ? " + + "AND cd.zone=? GROUP BY cd.ward"; + + List> wardList = jdbcHealthCampTemplate.queryForList(zoneSql, datetxt, zoneId); + totalCounts.put("wardList", wardList); + + return totalCounts; + } catch (Exception ex) { + ex.printStackTrace(); + Map response = new HashMap<>(); + response.put("status", "No data found"); + return Collections.singletonMap("status", "No data found"); + + } + + } + + public List> getCampwiseDetails(String date, String ward) { + + String datetxt = convertDateFormat(date,0); + + String sql = " Select cd.id, cd.zone, cd.ward, cd.camp_name,count(pd.id) as total_pat_count " + " FROM camp_details cd " + + " LEFT JOIN patient_details pd " + " ON cd.id = pd.camp_id " + + " WHERE DATE(cd.cdate) = ? and cd.ward = ? Group by cd.id "; + + return jdbcHealthCampTemplate.queryForList(sql, datetxt, ward); + + } + +/* + public List> getWardwiseDetails(String date, String zoneId) { + + String datetxt = convertDateFormat(date,0); + + String sql = "select cd.ward,count(pd.id) as pat_count " + + + "from camp_details cd " + + + "left join patient_details pd on pd.camp_id = cd.id " + + + "where cd.zone=? AND DATE(cd.cdate)=? AND cd.is_active=1 AND cd.is_delete=0 " + + + "group by cd.ward "; + + return jdbcHealthCampTemplate.queryForList(sql,zoneId,datetxt ); + + } + */ + public List> getCampDetails(String campId) { + + String sql = " select pd.id, pd.patient_id, pd.pt_name, pd.pt_mob_no, " + + " gm.gender, pd.pt_age, pd.pt_address, ct.name as camp_type, " + + " cd.camp_name, cd.address,pd.remarks, " + " DATE_FORMAT(cd.cdate, '%d-%m-%Y') AS regDate, " + + " DATE_FORMAT(cd.cdate, '%h:%i %p') AS Time, " + + " GROUP_CONCAT(dm.disease_name SEPARATOR ', ') AS diseases " + " FROM patient_details pd " + + " LEFT JOIN camp_details cd ON pd.camp_id = cd.id " + + " LEFT JOIN gender_master gm on pd.pt_gender_id = gm.id " + + " LEFT JOIN camp_type ct on cd.camp_type_id = ct.id " + + " LEFT JOIN diseases_details dd ON pd.patient_id = dd.patient_id " + + " LEFT JOIN disease_master dm ON dd.disease_id = dm.id " + " WHERE cd.id = ? " + " GROUP BY pd.id "; + + return jdbcHealthCampTemplate.queryForList(sql, campId); + + } + +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccSCP/controller/SCPController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccSCP/controller/SCPController.java new file mode 100644 index 0000000..a31563d --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccSCP/controller/SCPController.java @@ -0,0 +1,80 @@ +package in.gov.chennaicorporation.mobileservice.gccSCP.controller; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +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.RestController; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.gccSCP.service.SCPService; + +@RequestMapping("/gccofficialapp/api/scp/") +@RestController("gccofficialappsscp") +public class SCPController { + @Autowired + private SCPService scpService; + + @GetMapping(value="/getSCPListForMap") + public List getSCPListForMap( + @RequestParam(value="loginId", required = true) String cby, + @RequestParam(value="streetid", required = true) String streetid + ){ + return scpService.getSCPListForMap(cby,streetid); + } + + @PostMapping("/saveActivity") + public List saveActivity( + @RequestParam(value = "asset_id", required = true) String asset_id, + @RequestParam(value = "grating", required = true) String grating, + @RequestParam(value = "file", required = true) MultipartFile file, + @RequestParam(value = "zone", required = true) String zone, + @RequestParam(value = "ward", required = true) String ward, + @RequestParam(value = "street_name", required = false) String street_name, + @RequestParam(value = "street_id", required = false) String street_id, + @RequestParam(value = "latitude", required = true) String latitude, + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "loginId", required = true) String loginId, + @RequestParam(value = "road_type", required = true) String road_type + ) { + return scpService.saveActivity( + asset_id, + grating, + file, + zone, + ward, + street_name, + street_id, + latitude, + longitude, + loginId, + road_type + ); + } + + @GetMapping(value="/getZoneReport") + public List getZoneReport( + @RequestParam(value="loginId", required = true) String cby + ){ + return scpService.getZoneReport(cby); + } + + @GetMapping(value="/getWardReport") + public List getWardReport( + @RequestParam(value="loginId", required = true) String cby, + @RequestParam(value="zone", required = true) String zone + ){ + return scpService.getWardReport(cby,zone); + } + + @GetMapping(value="/getStreetReport") + public List getStreetReport( + @RequestParam(value="loginId", required = true) String cby, + @RequestParam(value="ward", required = true) String ward + ){ + return scpService.getStreetReport(cby,ward); + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccSCP/service/SCPService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccSCP/service/SCPService.java new file mode 100644 index 0000000..9908b83 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccSCP/service/SCPService.java @@ -0,0 +1,461 @@ +package in.gov.chennaicorporation.mobileservice.gccSCP.service; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.SecureRandom; +import java.sql.PreparedStatement; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.env.Environment; +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; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; + +import in.gov.chennaicorporation.mobileservice.gccactivity.service.DateTimeUtil; + +@Service +public class SCPService { + + private JdbcTemplate jdbcSCPTemplate; + + private final Environment environment; + private String fileBaseUrl; + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int STRING_LENGTH = 15; + private static final Random RANDOM = new SecureRandom(); + + @Autowired + public void setDataSource(@Qualifier("mysqlActivityDataSource") DataSource SCPDataSource) { + this.jdbcSCPTemplate = new JdbcTemplate(SCPDataSource); + } + + @Autowired + public SCPService(Environment environment) { + this.environment = environment; + this.fileBaseUrl=environment.getProperty("fileBaseUrl"); + } + + public static String generateRandomString() { + StringBuilder result = new StringBuilder(STRING_LENGTH); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + public static String generateRandomFileString(int lenthval) { + StringBuilder result = new StringBuilder(lenthval); + for (int i = 0; i < lenthval; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + private byte[] compressImage(BufferedImage image, float quality) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream); + + ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next(); + writer.setOutput(imageOutputStream); + + ImageWriteParam param = writer.getDefaultWriteParam(); + if (param.canWriteCompressed()) { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(quality); + } + + writer.write(null, new javax.imageio.IIOImage(image, null, null), param); + + writer.dispose(); + imageOutputStream.close(); + + return byteArrayOutputStream.toByteArray(); + } + + // Function to convert date string from dd-MM-yyyy to yyyy-MM-dd + public static String convertDateFormat(String inputDate, int add) { + // Check if the inputDate is not null or blank + if (inputDate != null && !inputDate.isBlank()) { + try { + // Define the input and output date formats + DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + // Parse the input date string to LocalDate + LocalDate date = LocalDate.parse(inputDate, inputFormatter); + + // Add the specified number of days to the date if 'add' is greater than 0 + if (add > 0) { + date = date.plusDays(add); + } + + // Format the date to the new format + return date.format(outputFormatter); + + } catch (DateTimeParseException e) { + // Handle the case where the input date is invalid + System.out.println("Invalid date format: " + inputDate); + return ""; + } + } else { + return ""; + } + } + + public String fileUpload(String name, String id, MultipartFile file, String filetype) { + + int lastInsertId = 0; + // Set the file path where you want to save it + String uploadDirectory = environment.getProperty("file.upload.directory"); + String serviceFolderName = environment.getProperty("scp_foldername"); + var year = DateTimeUtil.getCurrentYear(); + var month = DateTimeUtil.getCurrentMonth(); + var date = DateTimeUtil.getCurrentDay(); + + uploadDirectory = uploadDirectory + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date; + + try { + // Create directory if it doesn't exist + Path directoryPath = Paths.get(uploadDirectory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Datetime string + String datetimetxt = DateTimeUtil.getCurrentDateTime(); + + datetimetxt = datetimetxt + "_"+ generateRandomFileString(6); // Attached Random text + + // File name + String fileName = name + "_" + id + "_" + datetimetxt + "_" + file.getOriginalFilename(); + fileName = fileName.replaceAll("\\s+", ""); // Remove space on filename + + String filePath = uploadDirectory + "/" + fileName; + + String filepath_txt = "/" + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date + "/" + fileName; + + // Create a new Path object + Path path = Paths.get(filePath); + + // Get the bytes of the file + byte[] bytes = file.getBytes(); + + if(filetype.equalsIgnoreCase("image")) + { + // Compress the image + BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); + byte[] compressedBytes = compressImage(image, 0.5f); // Compress with 50% quality + // Write the bytes to the file + Files.write(path, compressedBytes); + } + else { + // Write the bytes to the file + Files.write(path, bytes); + } + // Get current date & time + LocalDateTime now = LocalDateTime.now(); + + // Format date-time (optional) + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + System.out.println("Date: "+ now.format(formatter)); + System.out.println("Activity: Pump"); + System.out.println("File Type: " + filetype); + System.out.println("File Upload Path: " + filePath); + System.out.println("File Path: " + filepath_txt); + + return filepath_txt; + + } catch (IOException e) { + e.printStackTrace(); + System.out.println("Failed to save file " + file.getOriginalFilename()); + return "error"; + } + } + + public String getWardByLoginId(String loginid, String type) { + String sqlQuery = "SELECT `ward` FROM gcc_penalty_hoardings.`hoading_user_list` WHERE `userid` = ? AND `type` = ? LIMIT 1"; + + // Query the database using queryForList + List> results = jdbcSCPTemplate.queryForList(sqlQuery, loginid, type); + + // Check if results is not empty and extract the ward value + if (!results.isEmpty()) { + // Extract the ward value from the first result + return (String) results.get(0).get("ward"); + } + + // Handle the case where no result is found + return "000"; // or return null based on your needs + } + + public List> getSCPListForMap(String loginid, String streetid) { + + //String ward = getWardByLoginId(loginid,"ae"); + /* + String sqlQuery ="SELECT " + + " al.*, " + + " CONCAT('" + fileBaseUrl + "/gccofficialapp/files/asset_images/2/', al.image) AS imageUrl, " + + " EXISTS (" + + " SELECT 1 FROM `scp_grating_activity` aa " + + " WHERE aa.asset_id = al.id " + + " ) AS `activity_completed` " + + "FROM asset_list al " + + "WHERE al.category_id = 2 AND al.streetid = ? AND al.isactive=1 AND isdelete=0 "; + */ + String sqlQuery = + "SELECT " + + " al.*, " + + " CONCAT('" + fileBaseUrl + "/gccofficialapp/files/asset_images/2/', al.image) AS imageUrl, " + + " CONCAT('" + fileBaseUrl + "/gccofficialapp/files', aa.file) AS fileUrl, " + + " aa.activity_id, " + + " aa.grating, " + + " aa.inby AS activity_by, " + + " DATE_FORMAT(aa.indate, '%d-%m-%Y') AS activity_date, " + + " aa.road_type, " + + " CASE WHEN aa.activity_id IS NOT NULL THEN 1 ELSE 0 END AS activity_completed " + + "FROM asset_list al " + + "LEFT JOIN ( " + + " SELECT a1.* " + + " FROM scp_grating_activity a1 " + + " INNER JOIN ( " + + " SELECT asset_id, MAX(indate) AS latest_indate " + + " FROM scp_grating_activity " + + " WHERE isactive=1 AND isdelete=0 " + + " GROUP BY asset_id " + + " ) a2 ON a1.asset_id = a2.asset_id AND a1.indate = a2.latest_indate " + + " WHERE a1.isactive=1 AND a1.isdelete=0 " + + ") aa ON aa.asset_id = al.id " + + "WHERE al.category_id = 2 " + + " AND al.streetid = ? " + + " AND al.isactive=1 " + + " AND al.isdelete=0"; + + List> Pumps = jdbcSCPTemplate.queryForList(sqlQuery, streetid); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Pump & Sump Map List."); + response.put("data", Pumps); + + return Collections.singletonList(response); + } + + @Transactional + public List> saveActivity( + String asset_id, + String grating, + MultipartFile file, + String zone, + String ward, + String street_name, + String street_id, + String latitude, + String longitude, + String inby, + String road_type + ) { + + String filetxt =asset_id; + + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // For Image + String filetype = "image"; + String activityimg = fileUpload(grating, filetxt, file, filetype); + + if ("error".equalsIgnoreCase(activityimg)) { + response.put("status", "error"); + response.put("message", "SCP activity image insert failed."); + result.add(response); + return result; + } + + + String insertBeforeSql = "INSERT INTO `scp_grating_activity` (asset_id, grating, file, zone, ward, street_name, street_id, latitude, longitude, inby, road_type) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?)"; + + String insertSql = insertBeforeSql; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcSCPTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"activity_id"}); + int i = 1; + ps.setString(i++, asset_id); + ps.setString(i++, grating); + ps.setString(i++, activityimg); + ps.setString(i++, zone); + ps.setString(i++, ward); + ps.setString(i++, street_name); + ps.setString(i++, street_id); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, inby); + ps.setString(i++, road_type); + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("SCP", " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", "SCP activity inserted successfully."); + } else { + response.put("SCP", " insertId error!"); + response.put("status", "error"); + response.put("message", "SCP activity insert failed."); + } + + result.add(response); + return result; + } + + public List> getZoneReport(String loginid) { + + String sqlQuery ="SELECT " + + " al.zone," + + " COUNT(DISTINCT al.id) AS total_scp," + + " COUNT(DISTINCT CASE WHEN aa.activity_id IS NOT NULL THEN al.id END) AS Completed," + + " COUNT(DISTINCT CASE WHEN aa.activity_id IS NULL THEN al.id END) AS Pending," + + " COUNT(DISTINCT CASE WHEN aa.grating = 'yes' THEN al.id END) AS yes," + + " COUNT(DISTINCT CASE WHEN aa.grating = 'no' THEN al.id END) AS no" + + " " + + "FROM asset_list al" + + " " + + "LEFT JOIN (" + + " SELECT a1.*" + + " FROM scp_grating_activity a1" + + " INNER JOIN (" + + + " SELECT asset_id, MAX(indate) AS latest_indate" + + " FROM scp_grating_activity" + + " WHERE isactive=1 AND isdelete=0" + + " GROUP BY asset_id" + + " ) a2 ON a1.asset_id = a2.asset_id AND a1.indate = a2.latest_indate" + + " WHERE a1.isactive=1 AND a1.isdelete=0" + + ") aa ON aa.asset_id = al.id" + + " " + + "WHERE al.category_id = 2 AND al.isactive=1 AND al.isdelete=0" + + " " + + "GROUP BY al.zone " + + "ORDER BY al.zone"; + + List> Pumps = jdbcSCPTemplate.queryForList(sqlQuery); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Zone SCP List."); + response.put("data", Pumps); + + return Collections.singletonList(response); + } + + public List> getWardReport(String loginid, String zone) { + + String sqlQuery ="SELECT " + + " al.zone,al.ward," + + " COUNT(DISTINCT al.id) AS total_scp," + + " COUNT(DISTINCT CASE WHEN aa.activity_id IS NOT NULL THEN al.id END) AS Completed," + + " COUNT(DISTINCT CASE WHEN aa.activity_id IS NULL THEN al.id END) AS Pending," + + " COUNT(DISTINCT CASE WHEN aa.grating = 'yes' THEN al.id END) AS yes," + + " COUNT(DISTINCT CASE WHEN aa.grating = 'no' THEN al.id END) AS no" + + " " + + "FROM asset_list al" + + " " + + "LEFT JOIN (" + + " SELECT a1.*" + + " FROM scp_grating_activity a1" + + " INNER JOIN (" + + + " SELECT asset_id, MAX(indate) AS latest_indate" + + " FROM scp_grating_activity" + + " WHERE isactive=1 AND isdelete=0" + + " GROUP BY asset_id" + + " ) a2 ON a1.asset_id = a2.asset_id AND a1.indate = a2.latest_indate" + + " WHERE a1.isactive=1 AND a1.isdelete=0" + + ") aa ON aa.asset_id = al.id" + + " " + + "WHERE al.category_id = 2 AND al.isactive=1 AND al.isdelete=0 AND al.zone=?" + + " " + + "GROUP BY al.zone,al.ward " + + "ORDER BY al.zone,al.ward"; + + List> Pumps = jdbcSCPTemplate.queryForList(sqlQuery,zone); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Ward SCP List."); + response.put("data", Pumps); + + return Collections.singletonList(response); + } + + public List> getStreetReport(String loginid, String ward) { + + String sqlQuery = + "SELECT " + + " al.streetid, " + + " al.streetname, " + + " COUNT(DISTINCT al.id) AS total_scp, " + + " COUNT(DISTINCT CASE WHEN aa.activity_id IS NOT NULL THEN al.id END) AS Completed, " + + " COUNT(DISTINCT CASE WHEN aa.activity_id IS NULL THEN al.id END) AS Pending, " + + " COUNT(DISTINCT CASE WHEN aa.grating = 'yes' THEN al.id END) AS yes, " + + " COUNT(DISTINCT CASE WHEN aa.grating = 'no' THEN al.id END) AS no " + + "FROM asset_list al " + + "LEFT JOIN ( " + + " SELECT a1.* " + + " FROM scp_grating_activity a1 " + + " INNER JOIN ( " + + " SELECT asset_id, MAX(indate) AS latest_indate " + + " FROM scp_grating_activity " + + " WHERE isactive=1 AND isdelete=0 " + + " GROUP BY asset_id " + + " ) a2 ON a1.asset_id = a2.asset_id AND a1.indate = a2.latest_indate " + + " WHERE a1.isactive=1 AND a1.isdelete=0 " + + ") aa ON aa.asset_id = al.id " + + "WHERE al.category_id = 2 AND al.isactive=1 AND al.isdelete=0 AND al.ward=? " + + "GROUP BY al.streetid, al.streetname " + + "ORDER BY al.streetname"; + + List> streetReport = jdbcSCPTemplate.queryForList(sqlQuery, ward); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Street-level SCP List."); + response.put("data", streetReport); + + return Collections.singletonList(response); + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccSpecialVehicle/controller/VehicleController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccSpecialVehicle/controller/VehicleController.java new file mode 100644 index 0000000..11989c8 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccSpecialVehicle/controller/VehicleController.java @@ -0,0 +1,72 @@ +package in.gov.chennaicorporation.mobileservice.gccSpecialVehicle.controller; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +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.RestController; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.gccSpecialVehicle.service.VehicleService; + +@RequestMapping("/gccofficialapp/api/specialvehicle/") +@RestController("gccofficialappsspecialvehicle") +public class VehicleController { + + @Autowired + private VehicleService vehicleService; + + @GetMapping("/getVehicleList") + public List getVehicleList(@RequestParam("loginId") String loginId){ + return vehicleService.getVehicleList(loginId); + } + + @PostMapping("/saveActivity") + public List saveActivity( + @RequestParam("vehicle_id") String vehicle_id, + @RequestParam("file") MultipartFile file, + @RequestParam("video")MultipartFile video, + @RequestParam("zone") String zone, + @RequestParam("ward") String ward, + @RequestParam(value = "street_name", required = false) String street_name, + @RequestParam(value = "street_id", required = false) String street_id, + @RequestParam("latitude") String latitude, + @RequestParam("longitude") String longitude, + @RequestParam("loginId") String loginId, + @RequestParam("action") String action, + @RequestParam(value = "beforeActivityId", required = false) String beforeActivityId, + @RequestParam(value = "clean_weight", required = false) String clean_weight + + ) { + return vehicleService.saveActivity( + vehicle_id, + file, + video, + zone, + ward, + street_name, + street_id, + latitude, + longitude, + loginId, + action, + beforeActivityId, + clean_weight + ); + } + + @GetMapping("/getVehicleReport") + public List getVehicleReport(@RequestParam("loginId") String loginId){ + return vehicleService.getVehicleReport(loginId); + } + + @GetMapping("/getVehicleSummaryReport") + public List getVehicleSummaryReport( + @RequestParam("loginId") String loginId, + @RequestParam("vehicle_id") String vehicle_id + ){ + return vehicleService.getVehicleSummaryReport(loginId,vehicle_id); + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccSpecialVehicle/service/VehicleService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccSpecialVehicle/service/VehicleService.java new file mode 100644 index 0000000..0761119 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccSpecialVehicle/service/VehicleService.java @@ -0,0 +1,494 @@ +package in.gov.chennaicorporation.mobileservice.gccSpecialVehicle.service; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.SecureRandom; +import java.sql.PreparedStatement; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.env.Environment; +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; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; + +import in.gov.chennaicorporation.mobileservice.gccactivity.service.DateTimeUtil; + +@Service +public class VehicleService { + +private JdbcTemplate jdbcVehicleTemplate; + + private final Environment environment; + private String fileBaseUrl; + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int STRING_LENGTH = 15; + private static final Random RANDOM = new SecureRandom(); + + @Autowired + public void setDataSource(@Qualifier("mysqlGccSpecialVehicleSource") DataSource VehicleDataSource) { + this.jdbcVehicleTemplate = new JdbcTemplate(VehicleDataSource); + } + + @Autowired + public VehicleService(Environment environment) { + this.environment = environment; + this.fileBaseUrl=environment.getProperty("fileBaseUrl"); + } + + public static String generateRandomString() { + StringBuilder result = new StringBuilder(STRING_LENGTH); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + public static String generateRandomFileString(int lenthval) { + StringBuilder result = new StringBuilder(lenthval); + for (int i = 0; i < lenthval; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + private byte[] compressImage(BufferedImage image, float quality) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream); + + ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next(); + writer.setOutput(imageOutputStream); + + ImageWriteParam param = writer.getDefaultWriteParam(); + if (param.canWriteCompressed()) { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(quality); + } + + writer.write(null, new javax.imageio.IIOImage(image, null, null), param); + + writer.dispose(); + imageOutputStream.close(); + + return byteArrayOutputStream.toByteArray(); + } + + // Function to convert date string from dd-MM-yyyy to yyyy-MM-dd + public static String convertDateFormat(String inputDate, int add) { + // Check if the inputDate is not null or blank + if (inputDate != null && !inputDate.isBlank()) { + try { + // Define the input and output date formats + DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + // Parse the input date string to LocalDate + LocalDate date = LocalDate.parse(inputDate, inputFormatter); + + // Add the specified number of days to the date if 'add' is greater than 0 + if (add > 0) { + date = date.plusDays(add); + } + + // Format the date to the new format + return date.format(outputFormatter); + + } catch (DateTimeParseException e) { + // Handle the case where the input date is invalid + System.out.println("Invalid date format: " + inputDate); + return ""; + } + } else { + return ""; + } + } + + public String fileUpload(String name, String id, MultipartFile file, String filetype) { + + int lastInsertId = 0; + // Set the file path where you want to save it + String uploadDirectory = environment.getProperty("file.upload.directory"); + String serviceFolderName = environment.getProperty("Vehicle_foldername"); + var year = DateTimeUtil.getCurrentYear(); + var month = DateTimeUtil.getCurrentMonth(); + var date = DateTimeUtil.getCurrentDay(); + + uploadDirectory = uploadDirectory + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date; + + try { + // Create directory if it doesn't exist + Path directoryPath = Paths.get(uploadDirectory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Datetime string + String datetimetxt = DateTimeUtil.getCurrentDateTime(); + + datetimetxt = datetimetxt + "_"+ generateRandomFileString(6); // Attached Random text + + // File name + String fileName = name + "_" + id + "_" + datetimetxt + "_" + file.getOriginalFilename(); + fileName = fileName.replaceAll("\\s+", ""); // Remove space on filename + + String filePath = uploadDirectory + "/" + fileName; + + String filepath_txt = "/" + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date + "/" + fileName; + + // Create a new Path object + Path path = Paths.get(filePath); + + // Get the bytes of the file + byte[] bytes = file.getBytes(); + + if(filetype.equalsIgnoreCase("image")) + { + // Compress the image + BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); + byte[] compressedBytes = compressImage(image, 0.5f); // Compress with 50% quality + // Write the bytes to the file + Files.write(path, compressedBytes); + } + else { + // Write the bytes to the file + Files.write(path, bytes); + } + // Get current date & time + LocalDateTime now = LocalDateTime.now(); + + // Format date-time (optional) + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + System.out.println("Date: "+ now.format(formatter)); + System.out.println("Activity: Special Vehicle"); + System.out.println("File Type: " + filetype); + System.out.println("File Upload Path: " + filePath); + System.out.println("File Path: " + filepath_txt); + + return filepath_txt; + + } catch (IOException e) { + e.printStackTrace(); + System.out.println("Failed to save file " + file.getOriginalFilename()); + return "error"; + } + } + + public String getWardByLoginId(String loginid, String type) { + String sqlQuery = "SELECT `ward` FROM gcc_penalty_hoardings.`hoading_user_list` WHERE `userid` = ? AND `type` = ? LIMIT 1"; + + // Query the database using queryForList + List> results = jdbcVehicleTemplate.queryForList(sqlQuery, loginid, type); + + // Check if results is not empty and extract the ward value + if (!results.isEmpty()) { + // Extract the ward value from the first result + return (String) results.get(0).get("ward"); + } + + // Handle the case where no result is found + return "000"; // or return null based on your needs + } + + public List> getVehicleList(String loginid) { + String sqlVehicle = "SELECT * FROM vehicle_master WHERE isactive = 1 AND isdelete=0"; + List> vehicles = jdbcVehicleTemplate.queryForList(sqlVehicle); + + List> finalList = new ArrayList<>(); + + for (Map vehicle : vehicles) { + Map vehicleResponse = new HashMap<>(vehicle); + + String vehicleId = vehicle.get("vehicle_id").toString(); + String beforeActivityId = "0"; + + // === 1. BEFORE ACTIVITY === + String sqlBefore = "SELECT *, " + + "DATE_FORMAT(indate, '%d-%m-%Y') AS formatted_indate," + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', `img_file`) AS img_file_url, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', `video_file`) AS video_file_url " + + "FROM before_activity WHERE vehicle_id = ? AND isactive=1 AND isdelete=0 " + + "ORDER BY activity_id DESC LIMIT 1"; + + List> beforeActivities = jdbcVehicleTemplate.queryForList(sqlBefore, vehicleId); + + Map beforeData = new HashMap<>(); + if (!beforeActivities.isEmpty()) { + beforeActivityId = beforeActivities.get(0).get("activity_id").toString(); + beforeData.put("status", "Completed"); + beforeData.put("details", beforeActivities); + } else { + beforeData.put("status", "Pending"); + beforeData.put("details", Collections.emptyList()); + } + + // === 2. AFTER ACTIVITY === + String sqlAfter = "SELECT *, " + + "DATE_FORMAT(indate, '%d-%m-%Y') AS formatted_indate, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', `img_file`) AS img_file_url, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', `video_file`) AS video_file_url " + + "FROM after_activity WHERE vehicle_id = ? AND before_activity_id = ? AND isactive=1 AND isdelete=0 " + + "ORDER BY activity_id DESC LIMIT 1"; + + List> afterActivities = jdbcVehicleTemplate.queryForList(sqlAfter, vehicleId, beforeActivityId); + + Map afterData = new HashMap<>(); + if (!afterActivities.isEmpty()) { + afterData.put("status", "Completed"); + afterData.put("details", afterActivities); + } else { + afterData.put("status", "Pending"); + afterData.put("details", Collections.emptyList()); + } + + // === 3. OVERALL STATUS === + String overallStatus = (!beforeActivities.isEmpty() && !afterActivities.isEmpty()) + ? "Completed" + : "Pending"; + + vehicleResponse.put("status", overallStatus); + vehicleResponse.put("before", beforeData); + vehicleResponse.put("after", afterData); + + finalList.add(vehicleResponse); + } + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Vehicle List."); + response.put("data", finalList); + + return Collections.singletonList(response); + } + + + @Transactional + public List> saveActivity( + String vehicle_id, + MultipartFile file, + MultipartFile video, + String zone, + String ward, + String street_name, + String street_id, + String latitude, + String longitude, + String inby, + String action, + String beforeActivityId, + String clean_weight + ) { + + String filetxt =vehicle_id; + + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // For Image + String filetype = "image"; + String activityimg = fileUpload(action, filetxt, file, filetype); + + if ("error".equalsIgnoreCase(activityimg)) { + response.put("status", "error"); + response.put("message", "Special vehicle activity image insert failed."); + result.add(response); + return result; + } + + // For Video + filetype = "video"; + String activityvideo = fileUpload(action, filetxt, video, filetype); + + if ("error".equalsIgnoreCase(activityvideo)) { + response.put("status", "error"); + response.put("message", "Special vehicle activity video insert failed."); + result.add(response); + return result; + } + + String insertBeforeSql = "INSERT INTO before_activity(vehicle_id, img_file, video_file, zone, ward, street_name, street_id, latitude, longitude, inby) " + + "VALUES (?,?,?,?,?,?,?,?,?,?)"; + + + String insertAfterSql = "INSERT INTO after_activity(vehicle_id, img_file, video_file, zone, ward, street_name, street_id, latitude, longitude, inby, before_activity_id, clean_weight) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"; + + String insertSql = "before".equalsIgnoreCase(action) ? insertBeforeSql : insertAfterSql; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcVehicleTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"activity_id"}); + int i = 1; + ps.setString(i++, vehicle_id); + ps.setString(i++, activityimg); + ps.setString(i++, activityvideo); + ps.setString(i++, zone); + ps.setString(i++, ward); + ps.setString(i++, street_name); + ps.setString(i++, street_id); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, inby); + + if ("after".equalsIgnoreCase(action)) { + ps.setString(i++, beforeActivityId); + ps.setString(i++, clean_weight); + } + + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Special vehicle", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", "Pump & Sump " + action + " activity inserted successfully."); + } else { + response.put("Special vehicle", action + " insertId error!"); + response.put("status", "error"); + response.put("message", "Special vehicle " + action + " activity insert failed."); + } + + result.add(response); + return result; + } + + public List> getVehicleReport(String loginid) { + + String sqlQuery = + "SELECT " + + " vm.vehicle_id," + + " vm.vehicle_type," + + " vm.vehicle_no," + + " vm.vehicle_zone," + + " vm.vehicle_ward," + + " " + + + " COALESCE(COUNT(DISTINCT ba.activity_id), 0) AS Started_Count," + + " " + + + " COALESCE(COUNT(DISTINCT aa.activity_id), 0) AS End_Count," + + " " + + + " COALESCE(SUM(aa.clean_weight), 0) AS Total_Clean_Weight" + + " " + + "FROM vehicle_master vm " + + "LEFT JOIN before_activity ba " + + " ON ba.vehicle_id = vm.vehicle_id " + + " AND ba.isactive = 1 " + + " AND ba.isdelete = 0 " + + "LEFT JOIN after_activity aa " + + " ON aa.vehicle_id = vm.vehicle_id " + + " AND aa.isactive = 1 " + + " AND aa.isdelete = 0" + + " " + + "WHERE vm.isactive = 1" + + " AND vm.isdelete = 0" + + " " + + "GROUP BY " + + " vm.vehicle_id," + + " vm.vehicle_type," + + " vm.vehicle_no," + + " vm.vehicle_zone," + + " vm.vehicle_ward " + + "ORDER BY " + + " vm.vehicle_zone, vm.vehicle_ward, vm.vehicle_no"; + + List> vechicleReport = jdbcVehicleTemplate.queryForList(sqlQuery); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Special Vehicle List."); + response.put("data", vechicleReport); + + return Collections.singletonList(response); + } + + public List> getVehicleSummaryReport(String loginid, String vehicle_id) { + + String sqlQuery = + "SELECT " + + " vm.vehicle_id, " + + " vm.vehicle_type, " + + " vm.vehicle_no, " + + " vm.vehicle_zone, " + + " vm.vehicle_ward, " + + + " ba.activity_id AS start_activity_id, " + + " ba.indate AS start_date, " + + " ba.img_file AS start_img, " + + " CONCAT('" + fileBaseUrl + "/gccofficialapp/files', ba.img_file) AS start_img_file_url, " + + " ba.video_file AS start_video, " + + " CONCAT('" + fileBaseUrl + "/gccofficialapp/files', ba.video_file) AS start_video_file_url, " + + + " aa.activity_id AS end_activity_id, " + + " aa.indate AS end_date, " + + " aa.img_file AS end_img, " + + " CONCAT('" + fileBaseUrl + "/gccofficialapp/files', aa.img_file) AS end_img_file_url, " + + " aa.video_file AS end_video, " + + " CONCAT('" + fileBaseUrl + "/gccofficialapp/files', aa.video_file) AS end_video_file_url, " + + " COALESCE(aa.clean_weight, 0) AS clean_weight " + + + "FROM vehicle_master vm " + + "LEFT JOIN before_activity ba " + + " ON ba.vehicle_id = vm.vehicle_id " + + " AND ba.isactive = 1 " + + " AND ba.isdelete = 0 " + + "LEFT JOIN after_activity aa " + + " ON aa.before_activity_id = ba.activity_id " + + " AND aa.vehicle_id = vm.vehicle_id " + + " AND aa.isactive = 1 " + + " AND aa.isdelete = 0 " + + "WHERE vm.isactive = 1 " + + " AND vm.isdelete = 0 " + + (vehicle_id != null && !vehicle_id.isBlank() ? " AND vm.vehicle_id = ? " : "") + + "ORDER BY vm.vehicle_zone, vm.vehicle_ward, vm.vehicle_no, ba.indate"; + + List> vehicleReport; + + if (vehicle_id != null && !vehicle_id.isBlank()) { + vehicleReport = jdbcVehicleTemplate.queryForList(sqlQuery, vehicle_id); + } else { + vehicleReport = jdbcVehicleTemplate.queryForList(sqlQuery); + } + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Vehicle Start-End Activity Report"); + response.put("data", vehicleReport); + + return Collections.singletonList(response); + } + + + +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccactivity/controller/APIActivityController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccactivity/controller/APIActivityController.java index 8a1fe0a..17e0146 100644 --- a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccactivity/controller/APIActivityController.java +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccactivity/controller/APIActivityController.java @@ -167,4 +167,15 @@ public class APIActivityController { System.out.println(activity.getApiResponse()); return "test"; } + + @GetMapping(value="/asset/encroachment_vendor_type") + public List encroachment_vendor_type(){ + return activity.encroachment_vendor_type(); + } + + @GetMapping(value="/asset/encroachment_vendor_items") + public List encroachment_vendor_items(){ + return activity.encroachment_vendor_items(); + } + } diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccactivity/service/Activity.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccactivity/service/Activity.java index cf570d5..83b7191 100644 --- a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccactivity/service/Activity.java +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccactivity/service/Activity.java @@ -257,7 +257,8 @@ public class Activity { List> result; if ("2".equals(assetTypeId)) { - String startdate = "2025-05-18"; + //String startdate = "2025-05-18"; + String startdate = "2025-10-22"; String sqlQuery ="SELECT " + " al.*, " @@ -1527,6 +1528,7 @@ public class Activity { return finalResult; } */ + @Transactional public Map scpfilterReports( String assetType, @@ -1668,6 +1670,7 @@ public class Activity { "GROUP BY al.id, al.zone, al.ward, al.streetid, al.streetname, al.latitude, al.longitude " ); */ + /* StringBuilder sqlQuery = new StringBuilder( "SELECT " + " al.id, " @@ -1702,6 +1705,53 @@ public class Activity { + "GROUP BY al.id, al.zone, al.ward, al.streetid, al.streetname, al.latitude, al.longitude " ); + */ + StringBuilder sqlQuery = new StringBuilder( + "SELECT " + + " al.id, " + + " al.zone, " + + " al.ward, " + + " al.streetid, " + + " al.streetname, " + + " al.latitude, " + + " al.longitude, " + + " DATE_FORMAT(MAX(af.feedback_date), '%d-%m-%Y %H:%i') AS last_feedback_date, " + + " CASE " + + " WHEN " + + " SUM(CASE WHEN aff.fileaction = 'before' THEN 1 ELSE 0 END) > 0 " + + " AND SUM(CASE WHEN aff.fileaction = 'after' THEN 1 ELSE 0 END) > 0 " + + " THEN 'Cleaned' " + + " ELSE 'Pending' " + + " END AS Status, " + + + " (SELECT CONCAT('" + fileBaseUrl + "/gccofficialapp/files/', '" + filePath + "', aff2.filename) " + + " FROM activity_feedback_file aff2 " + + " INNER JOIN activity_feedback af2 ON af2.id = aff2.feedback_id " + + " WHERE af2.asset_id = al.id AND aff2.fileaction = 'before' " + + " AND af2.feedback_date >=? AND af2.feedback_date < DATE_ADD(?, INTERVAL 1 DAY) " + + " ORDER BY af2.feedback_date DESC LIMIT 1) AS before_filepath, " + + + " (SELECT CONCAT('" + fileBaseUrl + "/gccofficialapp/files/', '" + filePath + "', aff3.filename) " + + " FROM activity_feedback_file aff3 " + + " INNER JOIN activity_feedback af3 ON af3.id = aff3.feedback_id " + + " WHERE af3.asset_id = al.id AND aff3.fileaction = 'after' " + + " AND af3.feedback_date >=? AND af3.feedback_date < DATE_ADD(?, INTERVAL 1 DAY) " + + " ORDER BY af3.feedback_date DESC LIMIT 1) AS after_filepath " + + + "FROM asset_list al " + + "LEFT JOIN activity_feedback af " + + " ON af.asset_id = al.id " + + " AND af.feedback_date >= ? " + + " AND af.feedback_date < DATE_ADD(?, INTERVAL 1 DAY) " + + "LEFT JOIN activity_feedback_file aff " + + " ON aff.feedback_id = af.id " + + "WHERE al.category_id = 2 " + + " AND al.streetid = ? " + + " AND al.isactive = 1 " + + " AND al.isdelete = 0 " + + "GROUP BY al.id, al.zone, al.ward, al.streetid, al.streetname, al.latitude, al.longitude " + ); + if (status != null && !status.isBlank()) { sqlQuery.append("HAVING Status = ? "); } @@ -1709,6 +1759,10 @@ public class Activity { List params = new ArrayList<>(); params.add(fromDate); params.add(toDate); + params.add(fromDate); + params.add(toDate); + params.add(fromDate); + params.add(toDate); params.add(streetid); if (status != null && !status.isBlank()) { params.add(status); @@ -1718,6 +1772,7 @@ public class Activity { for (Object param : params) { finalSql = finalSql.replaceFirst("\\?", "'" + String.valueOf(param) + "'"); } + System.out.println("Final SQL: " + finalSql); List> result = jdbcActivityTemplate.queryForList(sqlQuery.toString(), params.toArray()); @@ -1743,5 +1798,20 @@ public class Activity { return "failure"; } } - + + // Encrochmanet + @Transactional + public List> encroachment_vendor_type(){ + String sqlQuery = "SELECT * FROM `encroachment_vendor_type` WHERE (`isactive`=1 AND `isdelete`=0) ORDER BY `name` ASC"; + List> result = jdbcActivityTemplate.queryForList(sqlQuery); + return result; + } + + // Encrochmanet + @Transactional + public List> encroachment_vendor_items(){ + String sqlQuery = "SELECT * FROM `encroachment_vendor_items` WHERE (`isactive`=1 AND `isdelete`=0) ORDER BY `name` ASC"; + List> result = jdbcActivityTemplate.queryForList(sqlQuery); + return result; + } } diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccflagpole/controller/FlagPoleController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccflagpole/controller/FlagPoleController.java new file mode 100644 index 0000000..f261d0e --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccflagpole/controller/FlagPoleController.java @@ -0,0 +1,130 @@ +package in.gov.chennaicorporation.mobileservice.gccflagpole.controller; + +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +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.RestController; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.gccflagpole.service.FlagPoleService; + +@RequestMapping("/gccofficialapp/api/flagpole") +@RestController("gccofficialappflagpole") +public class FlagPoleController { + + @Autowired + FlagPoleService flagPoleService; + + @GetMapping("/getEventDetails") + public List> getEventDetails() { + + return flagPoleService.getEventDetails(); + + } + + @GetMapping("/getAllFlagPoleRequest") + public List> getAllFlagPoleRequest(@RequestParam("userid") String userid) { + + return flagPoleService.getAllFlagPoleRequest(userid); + + } + + @GetMapping("/getRequestDetails") + public Map getRequestDetailsById(@RequestParam String reqId) { + + return flagPoleService.getRequestDetailsById(reqId); + } + + @PostMapping("/approveFlagPoleRequest") + public Map approveFlagPoleRequest(@RequestParam String reqId, @RequestParam String approvedBy) { + + return flagPoleService.approveFlagPoleRequestByAE(reqId, approvedBy); + } + + @GetMapping("/getRDOApprovedRequests") + public List> getRDOApprovedRequests(@RequestParam("userid") String userid) { + + return flagPoleService.getRDOApprovedRequests(userid); + + } + + @GetMapping("/getRDOApprovedRequestsDetails") + public Map getRDOApprovedRequestsDetails(@RequestParam("reqId") String reqId) { + + return flagPoleService.getRDOApprovedRequestsDetails(reqId); + + } + + @PostMapping("/submitRestorationDetails") + public String submitRestorationDetails(@RequestParam("refid") String refid, + @RequestParam("amount") String amount, + @RequestParam("restorimg") MultipartFile restorImg, + @RequestParam("remarks") String remarks, + @RequestParam("userid") String userid) { + + String restorImgPath = flagPoleService.fileUpload(restorImg, "restorationImages"); + + return flagPoleService.submitRestorationDetails(refid, amount, restorImgPath, remarks, userid); + + } + + @GetMapping("/getRestorationList") + public List> getRestorationList(@RequestParam("userid") String userid) { + + return flagPoleService.getRestorationList(userid); + + } + + @GetMapping("/getRestorationDetails") + public Map getRestorationDetails(@RequestParam("reqId") String reqId) { + + return flagPoleService.getRestorationDetailsById(reqId); + + } + + @PostMapping("/saveFineDetails") + public String saveFineDetails(@RequestParam MultipartFile fineImg, + @RequestParam String address, + @RequestParam String latitude, + @RequestParam String longitude, + @RequestParam String zone, + @RequestParam String ward, + @RequestParam String vName, + @RequestParam String mobNo, + @RequestParam String noofflagpoles, + @RequestParam String fineAmount, + @RequestParam String remarks, + @RequestParam String userid, + @RequestParam String eventType) { + + String fineImgPath = flagPoleService.fileUpload(fineImg, "fineImages"); + + return flagPoleService.saveFineDetails(vName, mobNo, fineImgPath, address, zone, ward, latitude, longitude, noofflagpoles, fineAmount, remarks, userid, eventType); + + } + + @GetMapping("/getFineList") + public List> getFineList(@RequestParam("userid") String userid) { + + return flagPoleService.getFineList(userid); + + } + + @PostMapping("/submitFIRDetails") + public String submitFIRDetails(@RequestParam("refid") String refid, + @RequestParam("firimg") MultipartFile firImg, + @RequestParam("userid") String userid, + @RequestParam("fir_remarks") String fir_remarks) { + + String firImgPath = flagPoleService.fileUpload(firImg, "firImages"); + + return flagPoleService.submitFIRDetails(refid, firImgPath, userid, fir_remarks); + + } + +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccflagpole/service/FlagPoleService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccflagpole/service/FlagPoleService.java new file mode 100644 index 0000000..a08d321 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccflagpole/service/FlagPoleService.java @@ -0,0 +1,507 @@ +package in.gov.chennaicorporation.mobileservice.gccflagpole.service; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.SecureRandom; +import java.sql.PreparedStatement; +import java.sql.Statement; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.env.Environment; +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; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.gccactivity.service.DateTimeUtil; + +@Service +public class FlagPoleService { + + @Autowired + JdbcTemplate jdbcFlagPoleTemplate; + + private final Environment environment; + + private String fileBaseUrl; + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + private static final int STRING_LENGTH = 15; + + private static final Random RANDOM = new SecureRandom(); + + @Autowired + public void setDataSource(@Qualifier("mysqlGccFlagPoleDataSource") DataSource flagPoleDataSource) { + this.jdbcFlagPoleTemplate = new JdbcTemplate(flagPoleDataSource); + } + + public FlagPoleService(Environment environment) { + this.environment = environment; + this.fileBaseUrl = environment.getProperty("fileBaseUrl"); + } + + public static String generateRandomString() { + StringBuilder result = new StringBuilder(STRING_LENGTH); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + private byte[] compressImage(BufferedImage image, float quality) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream); + + ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next(); + writer.setOutput(imageOutputStream); + + ImageWriteParam param = writer.getDefaultWriteParam(); + if (param.canWriteCompressed()) { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(quality); + } + + writer.write(null, new javax.imageio.IIOImage(image, null, null), param); + + writer.dispose(); + imageOutputStream.close(); + + return byteArrayOutputStream.toByteArray(); + } + + public String fileUpload(MultipartFile file, String name) { + + // Set the file path where you want to save it + String uploadDirectory = environment.getProperty("file.upload.directory"); + String serviceFolderName = environment.getProperty("flagpole_foldername"); + var year = DateTimeUtil.getCurrentYear(); + var month = DateTimeUtil.getCurrentMonth(); + + uploadDirectory = uploadDirectory + serviceFolderName + year + "/" + month; + + try { + // Create directory if it doesn't exist + Path directoryPath = Paths.get(uploadDirectory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Datetime string + String datetimetxt = DateTimeUtil.getCurrentDateTime(); + // File name + String fileName = name + "_" + datetimetxt + "_" + file.getOriginalFilename(); + fileName = fileName.replaceAll("\s+", ""); // Remove space on filename + + String filePath = uploadDirectory + "/" + fileName; + + String filepath_txt = "/" + serviceFolderName + year + "/" + month + "/" + fileName; + + // Create a new Path object + Path path = Paths.get(filePath); + + // Get the bytes of the file + byte[] bytes = file.getBytes(); + + // Compress the image + BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); + byte[] compressedBytes = compressImage(image, 0.5f); // Compress with 50% quality + + // Write the bytes to the file + Files.write(path, compressedBytes); + + System.out.println(filePath); + return filepath_txt; + + } catch (IOException e) { + e.printStackTrace(); + return "Failed to save file " + file.getOriginalFilename(); + } + } + + public List> getEventDetails() { + try{ + String sql = "select * from event_type where is_active = 1 and is_delete = 0"; + List> eventList = jdbcFlagPoleTemplate.queryForList(sql); + return eventList; + + }catch(Exception ex){ + ex.printStackTrace(); + return Collections.emptyList(); + } + } + + public List> getAllFlagPoleRequest(String loginid) { + + String ward = getWardByLoginId(loginid, "ae"); + + try { + String sql = "select urd.id, urd.refid, urd.applicant_name, urd.mobile_number, urd.total_poles, " + + "date_format(urd.cdate,'%d-%m-%Y %l:%i %p') as req_rec_date, count(sd.id) as streetCount " + + "from user_request_details urd " + + "left join street_details sd on urd.refid = sd.refid " + + "where urd.payment_status = 'COMPLETED' and sd.ward =? and urd.ae_status IS NOT NULL " + + " AND sd.is_active =1 and sd.is_delete =0 "+ + "group by urd.id, urd.refid, urd.applicant_name, urd.mobile_number,urd.total_poles, urd.cdate "; + List> requestList = jdbcFlagPoleTemplate.queryForList(sql, new Object[] { ward }); + return requestList; + } catch (Exception ex) { + ex.printStackTrace(); + Map response = new HashMap<>(); + response.put("status", "No data found"); + return Collections.singletonList(response); + + } + + } + + public Map getRequestDetailsById(String reqId) { + if (reqId == null || reqId.isEmpty()) { + return Collections.singletonMap("status", "Incorrect Request ID"); + + } + try { + String applicantsql = "select urd.id, urd.refid, urd.applicant_name, urd.mobile_number, urd.total_poles, "+ + "date_format(urd.cdate,'%d-%m-%Y %l:%i %p') as req_rec_date, count(sd.id) as streetCount, " + + // " case when urd.ae_status is null and urd.ae_status !='APPROVED' THEN + // 'PENDING' ELSE 'APPROVED' END AS status, "+ + "urd.applicant_address as address, urd.event_desc as eventDetails " + + "from user_request_details urd " + + "left join street_details sd on urd.refid = sd.refid " + + "where urd.payment_status = 'COMPLETED' and urd.id = ? " + + "group by urd.id, urd.refid, urd.applicant_name, urd.mobile_number,urd.total_poles, urd.cdate"; + Map requestDetails = jdbcFlagPoleTemplate.queryForMap(applicantsql, new Object[] { reqId }); + + String streetSql = "select sd.id as streetDetailsId, urd.id as reqid, sd.street_name, sd.zone, sd.ward, sd.no_of_poles, "+ + "sd.height, pm.pole_material_name, fm.flag_material_name, sd.pole_space, sd.no_of_days " + + "from street_details sd " + + "left join user_request_details urd on urd.refid = sd.refid " + + "left join pole_material pm on sd.pole_material_id = pm.id " + + "left join flag_material fm on sd.flag_material_id = fm.id " + + "where urd.id = ? AND sd.is_active =1 and sd.is_delete =0 "; + List> streetDetails = jdbcFlagPoleTemplate.queryForList(streetSql, + new Object[] { reqId }); + + requestDetails.put("streetDetails", streetDetails); + + return requestDetails; + } catch (Exception ex) { + ex.printStackTrace(); + return Collections.singletonMap("status", "No data found"); + + } + } + + public String getWardByLoginId(String loginid, String type) { + String sqlQuery = "SELECT ward FROM gcc_penalty_hoardings.hoading_user_list WHERE userid = ? AND type = ? LIMIT 1"; + + List> results = jdbcFlagPoleTemplate.queryForList(sqlQuery, loginid, type); + + if (!results.isEmpty()) { + System.out.println("Ward....." + results); + // Extract the ward value from the first result + return (String) results.get(0).get("ward"); + } + + return "000"; + } + + public Map approveFlagPoleRequestByAE(String reqId, String approvedBy) { + if (reqId == null || reqId.isEmpty()) { + return Collections.singletonMap("status", "Incorrect Request ID"); + + } + try { + + String detailsSql = "select applicant_name,mobile_number, applicant_address, event_id, event_date, event_desc, no_of_days, "+ + "total_poles, deposit, total_cost, approved_by, approved_date, ae_status, rdo_status, rdo_remarks, cdate, refid, "+ + "payment_status, refund_status, booking_status from user_request_details where id = ?"; + Map requestDetails = jdbcFlagPoleTemplate.queryForMap(detailsSql, new Object[] { reqId }); + + String historyInsertSql = "INSERT INTO user_request_details_history ( applicant_name, mobile_number, applicant_address, "+ + " event_id, event_date, event_desc, no_of_days, total_poles, deposit, total_cost, approved_by, " + + " approved_date, ae_status, rdo_status, rdo_remarks, cdate, refid, payment_status, refund_status, booking_status) "+ + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + jdbcFlagPoleTemplate.update(historyInsertSql, requestDetails.get("applicant_name"), + requestDetails.get("mobile_number"), requestDetails.get("applicant_address"), + requestDetails.get("event_id"), requestDetails.get("event_date"), requestDetails.get("event_desc"), + requestDetails.get("no_of_days"), requestDetails.get("total_poles"), requestDetails.get("deposit"), + requestDetails.get("total_cost"), requestDetails.get("approved_by"), + requestDetails.get("approved_date"), + requestDetails.get("ae_status"), requestDetails.get("rdo_status"), + requestDetails.get("rdo_remarks"), requestDetails.get("cdate"), + requestDetails.get("refid"), requestDetails.get("payment_status"), + requestDetails.get("refund_status"), + requestDetails.get("booking_status")); + + String updateSql = "UPDATE user_request_details SET ae_status = 'APPROVED', approved_by = ?, approved_date = NOW() WHERE id = ?"; + int rowsAffected = jdbcFlagPoleTemplate.update(updateSql, approvedBy, reqId); + + if (rowsAffected > 0) { + return Collections.singletonMap("status", "Request approved successfully"); + } else { + return Collections.singletonMap("status", "No request found with the given ID"); + } + } catch (Exception ex) { + ex.printStackTrace(); + return Collections.singletonMap("status", "Error occurred while approving the request"); + + } + } + + public List> getRDOApprovedRequests(String userid) { + String ward = getWardByLoginId(userid, "ae"); + + try { + String sql = "select urd.id, urd.refid, urd.applicant_name, urd.mobile_number, urd.total_poles, " + + "date_format(urd.cdate,'%d-%m-%Y %l:%i %p') as req_rec_date, count(sd.id) as streetCount, " + + "DATE_FORMAT(urd.event_date,'%d-%m-%Y') AS eventStartDate, DATE_FORMAT(DATE_ADD(urd.event_date, INTERVAL urd.no_of_days DAY),'%d-%m-%Y') AS eventEndDate "+ + "from user_request_details urd " + + "left join street_details sd on urd.refid = sd.refid " + + "where urd.payment_status = 'COMPLETED' and sd.ward =? and urd.rdo_status = 'APPROVED' "+ + " AND sd.is_active =1 and sd.is_delete =0 "+ + "and urd.ae_status IS NOT NULL and urd.id not in (select ref_id from restoration) "+ + "group by urd.id, urd.refid, urd.applicant_name, urd.mobile_number,urd.total_poles, urd.cdate "; + List> requestList = jdbcFlagPoleTemplate.queryForList(sql, new Object[] { ward }); + return requestList; + } catch (Exception ex) { + ex.printStackTrace(); + Map response = new HashMap<>(); + response.put("status", "No data found"); + return Collections.singletonList(response); + + } + } + + public Map getRDOApprovedRequestsDetails(String reqId) { + + try { + String sql = "select urd.id, urd.refid, urd.applicant_name, urd.mobile_number, urd.total_poles, " + + "date_format(urd.cdate,'%d-%m-%Y %l:%i %p') as req_rec_date, urd.applicant_address, urd.event_desc, " + + + "count(sd.id) as streetCount, DATE_FORMAT(urd.event_date,'%d-%m-%Y') AS eventStartDate, " + + "DATE_FORMAT(DATE_ADD(urd.event_date, INTERVAL urd.no_of_days DAY),'%d-%m-%Y') AS eventEndDate, " + + "ifnull (urd.rdo_status,'') as rdo_status, ifnull(urd.rdo_remarks,'') as rdo_remarks " + + "from user_request_details urd " + + "left join street_details sd on urd.refid = sd.refid " + + "where urd.payment_status = 'COMPLETED' and urd.id = ? and urd.rdo_status = 'APPROVED' and urd.ae_status IS NOT NULL "+ + "group by urd.id, urd.refid, urd.applicant_name, urd.mobile_number,urd.total_poles, urd.cdate "; + Map requestList = jdbcFlagPoleTemplate.queryForMap(sql, reqId); + + String streetSql = "select sd.id as streetDetailsId, urd.id as reqid, sd.street_name, sd.zone, sd.ward, sd.no_of_poles, "+ + "sd.height, pm.pole_material_name, fm.flag_material_name, sd.pole_space, sd.no_of_days " + + "from street_details sd " + + "left join user_request_details urd on urd.refid = sd.refid " + + "left join pole_material pm on sd.pole_material_id = pm.id " + + "left join flag_material fm on sd.flag_material_id = fm.id " + + "where urd.id = ? AND sd.is_active =1 and sd.is_delete =0 "; + List> streetDetails = jdbcFlagPoleTemplate.queryForList(streetSql, + new Object[] { reqId }); + + requestList.put("streetDetails", streetDetails); + + return requestList; + } catch (Exception ex) { + ex.printStackTrace(); + Map response = new HashMap<>(); + response.put("status", "No data found"); + return Collections.singletonMap("status", "No data found"); + + } + } + + public String submitRestorationDetails(String reqId, String amount, String restorImgPath, String remarks, + String userid) { + try { + String sql = "Insert into restoration (ref_id, amount, image_path, remarks, created_by) values(?,?,?,?,?)"; + int rows = jdbcFlagPoleTemplate.update(sql, reqId, amount, restorImgPath, remarks, userid); + if (rows > 0) { + return "Restoration details submitted successfully"; + } else { + return "Failed to submit restoration details"; + } + + } catch (Exception ex) { + ex.printStackTrace(); + return "Error occurred while submitting restoration details"; + } + + } + + public List> getRestorationList(String userid) { + + String ward = getWardByLoginId(userid, "ae"); + + try { + String sql = "select urd.id, urd.refid, urd.applicant_name, urd.mobile_number, urd.total_poles, " + + "date_format(urd.cdate,'%d-%m-%Y %l:%i %p') as req_rec_date, count(sd.id) as streetCount, " + + "DATE_FORMAT(urd.event_date,'%d-%m-%Y') AS eventStartDate, DATE_FORMAT(DATE_ADD(urd.event_date, INTERVAL urd.no_of_days DAY),'%d-%m-%Y') AS eventEndDate, "+ + "r.amount as restorationAmount "+ + "from user_request_details urd " + + "left join street_details sd on urd.refid = sd.refid " + + "left join restoration r on urd.id = r.ref_id "+ + "where urd.payment_status = 'COMPLETED' and sd.ward =? and urd.rdo_status = 'APPROVED' "+ + "and urd.ae_status IS NOT NULL and urd.id in (select ref_id from restoration) "+ + " AND sd.is_active =1 and sd.is_delete =0 AND r.is_active = 1 "+ + "group by urd.id, urd.refid, urd.applicant_name, urd.mobile_number,urd.total_poles, urd.cdate, r.amount "; + List> requestList = jdbcFlagPoleTemplate.queryForList(sql, new Object[] { ward }); + return requestList; + } catch (Exception ex) { + ex.printStackTrace(); + Map response = new HashMap<>(); + response.put("status", "No data found"); + return Collections.singletonList(response); + + } + + + } + + public Map getRestorationDetailsById(String reqId) { + + try { + String sql = "select urd.id, urd.refid, urd.applicant_name, urd.mobile_number, urd.total_poles, " + + "date_format(urd.cdate,'%d-%m-%Y %l:%i %p') as req_rec_date, urd.applicant_address, urd.event_desc, "+ + "count(sd.id) as streetCount, DATE_FORMAT(urd.event_date,'%d-%m-%Y') AS eventStartDate, " + + "DATE_FORMAT(DATE_ADD(urd.event_date, INTERVAL urd.no_of_days DAY),'%d-%m-%Y') AS eventEndDate, " + + "ifnull (urd.rdo_status,'') as rdo_status, ifnull(urd.rdo_remarks,'') as rdo_remarks, " + + "r.amount as restorationAmount, r.payment_status as restoration_pay_status, r.remarks as restorationRemarks, "+ + "CONCAT('"+fileBaseUrl+"/gccofficialapp/files', r.image_path) AS restoration_image_url " + + "from user_request_details urd " + + "left join street_details sd on urd.refid = sd.refid " + + "left join restoration r on urd.id = r.ref_id "+ + "where urd.payment_status = 'COMPLETED' and urd.id = ? and urd.rdo_status = 'APPROVED' and "+ + "urd.ae_status IS NOT NULL AND r.is_active = 1 "+ + "group by urd.id, urd.refid, urd.applicant_name, urd.mobile_number,urd.total_poles, urd.cdate, r.amount, "+ + "r.payment_status, r.remarks, r.image_path "; + Map requestList = jdbcFlagPoleTemplate.queryForMap(sql, reqId); + + String streetSql = "select sd.id as streetDetailsId, urd.id as reqid, sd.street_name, sd.zone, sd.ward, sd.no_of_poles, "+ + "sd.height, pm.pole_material_name, fm.flag_material_name, sd.pole_space, sd.no_of_days " + + "from street_details sd " + + "left join user_request_details urd on urd.refid = sd.refid " + + "left join pole_material pm on sd.pole_material_id = pm.id " + + "left join flag_material fm on sd.flag_material_id = fm.id " + + "where urd.id = ? AND sd.is_active =1 and sd.is_delete =0 "; + List> streetDetails = jdbcFlagPoleTemplate.queryForList(streetSql, + new Object[] { reqId }); + + requestList.put("streetDetails", streetDetails); + + return requestList; + } catch (Exception ex) { + ex.printStackTrace(); + Map response = new HashMap<>(); + response.put("status", "No data found"); + return Collections.singletonMap("status", "No data found"); + + } + + + } + + @Transactional + public String saveFineDetails(String vName, String mobNo, String fineImgPath, String address, String zone, + String ward, String latitude, String longitude, String noofflagpoles, String fineAmount, String remarks, + String userid, String eventType) { + try { + + String sql = "Insert into fine_collection (user_name, mob_no, image_path, street_name, zone, ward, latitude, longitude, "+ + "no_of_poles, fine_amount, total_amount, remarks, created_by, event_id) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + jdbcFlagPoleTemplate.update(con -> { + PreparedStatement ps = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); + ps.setString(1, vName); + ps.setLong(2, Long.parseLong(mobNo)); + ps.setString(3, fineImgPath); + ps.setString(4, address); + ps.setString(5, zone); + ps.setString(6, ward); + ps.setString(7, latitude); + ps.setString(8, longitude); + ps.setInt(9, Integer.parseInt(noofflagpoles)); + ps.setString(10, fineAmount); + ps.setString(11, fineAmount); + ps.setString(12, remarks); + ps.setString(13, userid); + ps.setString(14, eventType); + return ps; + }, keyHolder); + + int generatedId = keyHolder.getKey().intValue(); + String requestId = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + generatedId; + + jdbcFlagPoleTemplate.update("UPDATE fine_collection SET ref_id = ? WHERE id = ?", requestId, generatedId); + + return "Fine details saved successfully with Request ID: " + requestId; + + } catch (Exception ex) { + ex.printStackTrace(); + return "Error occurred while saving fine details"+ex.getMessage(); + } + } + + public List> getFineList(String userid) { + String ward = getWardByLoginId(userid, "ae"); + + try { + String sql = "select fc.id, fc.ref_id, fc.user_name, fc.mob_no, fc.no_of_poles, " + + "CONCAT('"+fileBaseUrl+"/gccofficialapp/files', fc.image_path) AS fine_image_url, " + + "ifnull(CONCAT('"+fileBaseUrl+"/gccofficialapp/files', fc.fir_image_path),'N/A') AS FIR_image_url, " + + "date_format(fc.cdate,'%d-%m-%Y %l:%i %p') as fine_rec_date, fc.fine_amount, fc.total_amount, "+ + "fc.street_name, fc.zone, fc.ward, fc.remarks, fc.payment_status "+ + "from fine_collection fc " + + "where fc.ward =? and isactive =1 and isdelete =0 "+ + "group by fc.id, fc.ref_id, fc.user_name, fc.mob_no,fc.no_of_poles, fc.cdate, fc.fine_amount, fc.total_amount "; + List> fineList = jdbcFlagPoleTemplate.queryForList(sql, new Object[] { ward }); + return fineList; + } catch (Exception ex) { + ex.printStackTrace(); + Map response = new HashMap<>(); + response.put("status", "No data found"); + return Collections.singletonList(response); + + } + } + + public String submitFIRDetails(String refid, String firImgPath, String userid, String fir_remarks) { + try { + String sql = "Update fine_collection set fir_image_path = ?, fir_by = ?, fir_date = NOW(), fir_remarks = ? "+ + "where id = ?"; + int rows = jdbcFlagPoleTemplate.update(sql, firImgPath, userid, refid, fir_remarks); + System.out.println("rows..."+rows); + if (rows > 0) { + return "FIR details submitted successfully"; + } else { + return "Failed to submit FIR details"; + } + + } catch (Exception ex) { + ex.printStackTrace(); + return "Error occurred while submitting FIR details"; + } + } + +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccpothole/service/PotholeService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccpothole/service/PotholeService.java index 1f6bd36..3b365f9 100644 --- a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccpothole/service/PotholeService.java +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/gccpothole/service/PotholeService.java @@ -162,7 +162,7 @@ public class PotholeService { "SIN(RADIANS(?)) * SIN(RADIANS(pcd.latitude))" + ")) < 3"; - Integer count = jdbcPotHoleTemplate.queryForObject(checkSql, new Object[]{streetId, latitude, longitude, latitude}, Integer.class); + Integer count = jdbcPotHoleTemplate.queryForObject(checkSql, Integer.class, new Object[]{streetId, latitude, longitude, latitude}); if (count != null && count > 0) { return "duplicate"; // ✅ Return "duplicate" if at least one match found @@ -289,7 +289,7 @@ public class PotholeService { " WHERE image_flag = 'vendor' " + " GROUP BY complaint_no " + ") vi ON vi.complaint_no = cd.complaint_no " + - "WHERE cd.ward = ? AND cd.status_id IN (1, 2, 4, 6)"; + "WHERE cd.ward = ? AND cd.status_id IN (1, 2, 4, 6) AND cd.isactive=1"; return jdbcPotHoleTemplate.queryForList(complaintSql, ward); } @@ -316,7 +316,7 @@ public class PotholeService { "FROM pothole_complaint_details cd " + "LEFT JOIN complaint_images ci ON ci.complaint_no = cd.complaint_no " + "LEFT JOIN status_master sm ON sm.id = cd.status_id " + - "WHERE cd.ward = ? AND cd.status_id IN (1,3,7)"; + "WHERE cd.ward = ? AND cd.status_id IN (1,3,7) AND cd.isactive=1"; return jdbcPotHoleTemplate.queryForList(complaintSql, ward); } @@ -334,7 +334,7 @@ public class PotholeService { "FROM pothole_complaint_details pcd " + "JOIN complaint_images ci ON pcd.complaint_no = ci.complaint_no " + "LEFT JOIN status_master sm ON pcd.status_id = sm.id " + - "WHERE pcd.login_id = ?"; + "WHERE pcd.login_id = ? AND pcd.isactive=1"; return jdbcPotHoleTemplate.queryForList(sql, loginId); } @@ -393,7 +393,7 @@ public class PotholeService { public boolean checkLocation(String latitude, String longitude) { String sql = "select count(*) from pothole_complaint_details pcd " + - "where ((6371008.8 * acos(ROUND(cos(radians(?)) * cos(radians(pcd.latitude)) * cos(radians(pcd.longitude) - radians(?)) +" + + "where pcd.isactive=1 AND ((6371008.8 * acos(ROUND(cos(radians(?)) * cos(radians(pcd.latitude)) * cos(radians(pcd.longitude) - radians(?)) +" + "sin(radians(?)) * sin(radians(pcd.latitude)), 9))) )< 3 "; int count = jdbcPotHoleTemplate.queryForObject(sql, Integer.class, Double.parseDouble(latitude), Double.parseDouble(longitude), Double.parseDouble(latitude)); @@ -564,7 +564,7 @@ public class PotholeService { "SUM(CASE WHEN pcd.status_id = '5' THEN 1 ELSE 0 END) AS ae_completed " + "FROM pothole_complaint_details pcd " + "LEFT JOIN status_master st ON st.id = pcd.status_id " + - "WHERE DATE(pcd.cdate) BETWEEN ? AND ? " + where + + "WHERE pcd.isactive=1 AND DATE(pcd.cdate) BETWEEN ? AND ? " + where + "GROUP BY pcd.zone " + "ORDER BY pcd.zone "; @@ -587,7 +587,7 @@ public class PotholeService { + "SUM(CASE WHEN pcd.status_id = '5' THEN 1 ELSE 0 END) AS ae_completed " + "FROM pothole_complaint_details pcd " + "LEFT JOIN status_master st ON st.id = pcd.status_id " - + "WHERE DATE(pcd.cdate) BETWEEN ? AND ? AND pcd.zone= ? " + where + + "WHERE pcd.isactive=1 AND DATE(pcd.cdate) BETWEEN ? AND ? AND pcd.zone= ? " + where + "GROUP BY pcd.ward " + "ORDER BY pcd.ward "; @@ -609,7 +609,7 @@ public class PotholeService { + "SUM(CASE WHEN pcd.status_id IN ('2','4') THEN 1 ELSE 0 END) AS vendor_completed " + "FROM pothole_complaint_details pcd " + "LEFT JOIN status_master st ON st.id = pcd.status_id " - + "WHERE DATE(pcd.cdate) BETWEEN ? AND ? " + where + + "WHERE pcd.isactive=1 AND DATE(pcd.cdate) BETWEEN ? AND ? " + where + "GROUP BY pcd.zone " + "ORDER BY pcd.zone "; @@ -632,7 +632,7 @@ public class PotholeService { + "SUM(CASE WHEN pcd.status_id IN ('2','4') THEN 1 ELSE 0 END) AS vendor_completed " + "FROM pothole_complaint_details pcd " + "LEFT JOIN status_master st ON st.id = pcd.status_id " - + "WHERE DATE(pcd.cdate) BETWEEN ? AND ? AND pcd.zone=? " + where + + "WHERE pcd.isactive=1 AND DATE(pcd.cdate) BETWEEN ? AND ? AND pcd.zone=? " + where + "GROUP BY pcd.ward " + "ORDER BY pcd.ward "; @@ -654,7 +654,7 @@ public class PotholeService { + "from pothole_complaint_details pcd " + "LEFT JOIN complaint_images ci on ci.complaint_no=pcd.complaint_no " + "LEFT JOIN status_master st on st.id=pcd.status_id " - + "WHERE pcd.complaint_no= ? "; + + "WHERE pcd.complaint_no= ? AND pcd.isactive=1 "; return jdbcPotHoleTemplate.queryForList(sql, complaintNo); } @@ -742,7 +742,7 @@ public class PotholeService { + "from pothole_complaint_details pcd " + "LEFT JOIN complaint_images ci on ci.complaint_no=pcd.complaint_no " + "LEFT JOIN status_master st on st.id=pcd.status_id " - + "WHERE DATE(pcd.cdate) BETWEEN ? AND ? AND pcd.zone = ? AND pcd.ward= ? and pcd.street_id = ? "+ where; + + "WHERE DATE(pcd.cdate) BETWEEN ? AND ? AND pcd.zone = ? AND pcd.ward= ? and pcd.street_id = ? AND pcd.isactive=1"+ where; return jdbcPotHoleTemplate.queryForList(sql, formattedFrom, formattedTo, zone, ward, streetId); } @@ -838,7 +838,7 @@ public class PotholeService { + "SUM(CASE WHEN pcd.status_id IN (1, 2, 4, 6) THEN 1 ELSE 0 END) AS ae_pending, " + "SUM(CASE WHEN pcd.status_id = '5' THEN 1 ELSE 0 END) AS ae_completed " + "FROM pothole_complaint_details pcd " - + "WHERE DATE(pcd.cdate) BETWEEN ? AND ? AND pcd.zone = ? AND pcd.ward= ? " + where + + "WHERE pcd.isactive=1 AND DATE(pcd.cdate) BETWEEN ? AND ? AND pcd.zone = ? AND pcd.ward= ? " + where + "GROUP BY pcd.street_id,pcd.zone,pcd.ward " + "ORDER BY pcd.street_id "; System.err.println(sql); @@ -861,7 +861,7 @@ public class PotholeService { + "SUM(CASE WHEN pcd.status_id IN ('1','3') THEN 1 ELSE 0 END) AS vendor_pending," + "SUM(CASE WHEN pcd.status_id IN ('2','4') THEN 1 ELSE 0 END) AS vendor_completed " + "FROM pothole_complaint_details pcd " - + "WHERE DATE(pcd.cdate) BETWEEN ? AND ? AND pcd.zone = ? AND pcd.ward= ? " + where + + "WHERE pcd.isactive=1 AND DATE(pcd.cdate) BETWEEN ? AND ? AND pcd.zone = ? AND pcd.ward= ? " + where + "GROUP BY pcd.street_id,pcd.zone,pcd.ward " + "ORDER BY pcd.street_id "; return jdbcPotHoleTemplate.queryForList(sql, formattedFrom, formattedTo, zone, ward); @@ -874,7 +874,7 @@ public class PotholeService { String checkSql = "SELECT count(*) FROM pothole_complaint_details pcd " + "left join status_master sm on pcd.status_id = sm.id " + - "WHERE pcd.street_id =? and sm.status!='Completed' and (6371008.8 * ACOS(ROUND(COS(RADIANS(?)) * COS(RADIANS(pcd.latitude)) * COS(RADIANS(pcd.longitude) - RADIANS(?)) + SIN(RADIANS(?)) * SIN(RADIANS(pcd.latitude)), 9))) <50"; + "WHERE pcd.isactive=1 AND pcd.street_id =? and sm.status!='Completed' and (6371008.8 * ACOS(ROUND(COS(RADIANS(?)) * COS(RADIANS(pcd.latitude)) * COS(RADIANS(pcd.longitude) - RADIANS(?)) + SIN(RADIANS(?)) * SIN(RADIANS(pcd.latitude)), 9))) <50"; Integer count = jdbcPotHoleTemplate.queryForObject(checkSql, new Object[]{streetId, latitude, longitude, latitude}, Integer.class); @@ -976,7 +976,7 @@ public class PotholeService { " WHERE image_flag = 'vendor' " + " GROUP BY complaint_no " + ") vi ON vi.complaint_no = cd.complaint_no " + - "WHERE cd.ward = ? AND cd.request_by ='Others' and status_id not in (7,8) "); + "WHERE cd.isactive=1 AND cd.ward = ? AND cd.request_by ='Others' and status_id not in (7,8) "); List params = new ArrayList<>(); params.add(ward); diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/manhole/controller/ManHoleController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/manhole/controller/ManHoleController.java new file mode 100644 index 0000000..8050b86 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/manhole/controller/ManHoleController.java @@ -0,0 +1,167 @@ +package in.gov.chennaicorporation.mobileservice.manhole.controller; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +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.RestController; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.manhole.service.ManHoleActivity; + +@RequestMapping("/gccofficialapp/api/manhole/") +@RestController("gccofficialappsmanhole") +public class ManHoleController { + @Autowired + private ManHoleActivity manHoleActivity; + + @GetMapping(value="/duplicateDrainCheck") + public String duplicateDrainCheck( + @RequestParam(value="street_id", required = true) String street_id, + @RequestParam(value="drain_side", required = true) String drain_side + ){ + return manHoleActivity.duplicateDrainCheck(street_id,drain_side); + } + + @PostMapping("/saveDrain") + public List saveDrain( + @RequestParam("drain_side") String drain_side, + @RequestParam("drain_type") String drain_type, + @RequestParam("drain_length") String drain_length, + @RequestParam("drain_width") String drain_width, + @RequestParam("drain_depth") String drain_depth, + @RequestParam(value="manhole_count", required = false) String manhole_count, + @RequestParam("zone") String zone, + @RequestParam("ward") String ward, + @RequestParam("street_name") String street_name, + @RequestParam("street_id") String street_id, + @RequestParam("road_type") String road_type, + @RequestParam("latitude") String latitude, + @RequestParam("longitude") String longitude, + @RequestParam("loginId") String inby, + @RequestParam("file") MultipartFile file + ) + { + return manHoleActivity.saveDrain( + drain_side, + drain_type, + drain_length, + drain_width, + drain_depth, + manhole_count, + zone, + ward, + street_name, + street_id, + road_type, + latitude, + longitude, + inby, + file + ); + } + + @GetMapping(value="/getDrainList") + public List getDrainList(@RequestParam(value="loginId", required = true) String cby){ + return manHoleActivity.getDrainList(cby); + } + + @PostMapping("/saveManHole") + public List saveManHole( + @RequestParam("drain_id") String drain_id, + @RequestParam("zone") String zone, + @RequestParam("ward") String ward, + @RequestParam("street_name") String street_name, + @RequestParam("street_id") String street_id, + @RequestParam("latitude") String latitude, + @RequestParam("longitude") String longitude, + @RequestParam("loginId") String inby + ) + { + return manHoleActivity.saveManHole( + drain_id, + zone, + ward, + street_name, + street_id, + latitude, + longitude, + inby + ); + } + + @GetMapping(value="/getManHoleList") + public List getManHoleList( + @RequestParam(value="loginId", required = true) String cby, + @RequestParam(value="drain_id", required = true) String drain_id + ){ + return manHoleActivity.getManHoleList(cby, drain_id); + } + + @GetMapping(value="/manHoleLocationCheck") + public String manHoleLocationCheck( + @RequestParam(value="loginId", required = true) String cby, + @RequestParam("manhole_id") String manhole_id, + @RequestParam("latitude") String latitude, + @RequestParam("longitude") String longitude + ){ + return manHoleActivity.manHoleLocationCheck(cby, manhole_id,latitude, longitude); + } + + @PostMapping("/saveActivity") + public List saveActivity( + @RequestParam("manhole_id") String manhole_id, + @RequestParam("drain_id") String drain_id, + @RequestParam("file") MultipartFile file, + @RequestParam("zone") String zone, + @RequestParam("ward") String ward, + @RequestParam("street_name") String street_name, + @RequestParam("street_id") String street_id, + @RequestParam("latitude") String latitude, + @RequestParam("longitude") String longitude, + @RequestParam("loginId") String loginId, + @RequestParam("action") String action, + @RequestParam(value = "beforeActivityId", required = false) String beforeActivityId, + @RequestParam(value = "clean_type", required = false) String clean_type, + @RequestParam(value = "case_id", required = true) String case_id + + ) { + return manHoleActivity.saveActivity( + manhole_id, + drain_id, + file, + zone, + ward, + street_name, + street_id, + latitude, + longitude, + loginId, + action, + beforeActivityId, + clean_type, + case_id + ); + } + + @GetMapping(value="/getZoneReport") + public List getZoneReport(){ + return manHoleActivity.getZoneReport(); + } + + @GetMapping(value="/getWardReport") + public List getWardReport( + @RequestParam(value="zone", required = true) String zone + ){ + return manHoleActivity.getWardReport(zone); + } + @GetMapping(value="/getDrainReport") + public List getDrainReport( + @RequestParam(value="ward", required = true) String ward + ){ + return manHoleActivity.getDrainReport(ward); + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/manhole/service/ManHoleActivity.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/manhole/service/ManHoleActivity.java new file mode 100644 index 0000000..4967625 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/manhole/service/ManHoleActivity.java @@ -0,0 +1,845 @@ +package in.gov.chennaicorporation.mobileservice.manhole.service; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.SecureRandom; +import java.sql.PreparedStatement; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.env.Environment; +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; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +import in.gov.chennaicorporation.mobileservice.gccactivity.service.DateTimeUtil; + +@Service +public class ManHoleActivity { + private JdbcTemplate jdbcManHoleTemplate; + + private final Environment environment; + private String fileBaseUrl; + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int STRING_LENGTH = 15; + private static final Random RANDOM = new SecureRandom(); + + @Autowired + public void setDataSource(@Qualifier("mysqlGccManHoleSource") DataSource ManHoleDataSource) { + this.jdbcManHoleTemplate = new JdbcTemplate(ManHoleDataSource); + } + + @Autowired + public ManHoleActivity(Environment environment) { + this.environment = environment; + this.fileBaseUrl=environment.getProperty("fileBaseUrl"); + } + + + public static String generateRandomString() { + StringBuilder result = new StringBuilder(STRING_LENGTH); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + public static String generateRandomFileString(int lenthval) { + StringBuilder result = new StringBuilder(lenthval); + for (int i = 0; i < lenthval; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + private byte[] compressImage(BufferedImage image, float quality) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream); + + ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next(); + writer.setOutput(imageOutputStream); + + ImageWriteParam param = writer.getDefaultWriteParam(); + if (param.canWriteCompressed()) { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(quality); + } + + writer.write(null, new javax.imageio.IIOImage(image, null, null), param); + + writer.dispose(); + imageOutputStream.close(); + + return byteArrayOutputStream.toByteArray(); + } + + public String fileUpload(String name, String id, MultipartFile file, String filetype) { + + int lastInsertId = 0; + // Set the file path where you want to save it + String uploadDirectory = environment.getProperty("file.upload.directory"); + String serviceFolderName = environment.getProperty("manhole_foldername"); + var year = DateTimeUtil.getCurrentYear(); + var month = DateTimeUtil.getCurrentMonth(); + var date = DateTimeUtil.getCurrentDay(); + + uploadDirectory = uploadDirectory + serviceFolderName + year + "/" + month + "/" + date; + + try { + // Create directory if it doesn't exist + Path directoryPath = Paths.get(uploadDirectory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Datetime string + String datetimetxt = DateTimeUtil.getCurrentDateTime(); + + datetimetxt = datetimetxt + "_"+ generateRandomFileString(6); // Attached Random text + + // File name + String fileName = name + "_" + id + "_" + datetimetxt + "_" + file.getOriginalFilename(); + fileName = fileName.replaceAll("\\s+", ""); // Remove space on filename + + String filePath = uploadDirectory + "/" + fileName; + + String filepath_txt = "/" + serviceFolderName + year + "/" + month + "/" + date + "/" + fileName; + + // Create a new Path object + Path path = Paths.get(filePath); + + // Get the bytes of the file + byte[] bytes = file.getBytes(); + + if(filetype.equalsIgnoreCase("image")) + { + // Compress the image + BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); + byte[] compressedBytes = compressImage(image, 0.5f); // Compress with 50% quality + // Write the bytes to the file + Files.write(path, compressedBytes); + } + else { + // Write the bytes to the file + Files.write(path, bytes); + } + // Get current date & time + LocalDateTime now = LocalDateTime.now(); + + // Format date-time (optional) + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + System.out.println("Date: "+ now.format(formatter)); + System.out.println("Activity: ManHole"); + System.out.println("File Type: " + filetype); + System.out.println("File Upload Path: " + filePath); + System.out.println("File Path: " + filepath_txt); + + return filepath_txt; + + } catch (IOException e) { + e.printStackTrace(); + System.out.println("Failed to save file " + file.getOriginalFilename()); + return "error"; + } + } + + public String getWardByLoginId(String loginid, String type) { + String sqlQuery = "SELECT `ward` FROM gcc_penalty_hoardings.`hoading_user_list` WHERE `userid` = ? AND `type` = ? LIMIT 1"; + + // Query the database using queryForList + List> results = jdbcManHoleTemplate.queryForList(sqlQuery, loginid, type); + + // Check if results is not empty and extract the ward value + if (!results.isEmpty()) { + // Extract the ward value from the first result + return (String) results.get(0).get("ward"); + } + + // Handle the case where no result is found + return "000"; // or return null based on your needs + } + + /* + public List> getDrainList(String loginid) { + + String ward = getWardByLoginId(loginid,"ae"); + + String sql = "SELECT *, " + + " CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `file`) AS file_url " + + "FROM `drain_master` WHERE `ward`= ? AND isactive = 1 AND isdelete = 0 "; + List> result = jdbcManHoleTemplate.queryForList(sql, ward); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Drain List."); + response.put("data", result); + + return Collections.singletonList(response); + } + */ + + public List> getDrainList(String loginid) { + String ward = getWardByLoginId(loginid, "ae"); + + // 1. Fetch all drains for this ward + String sqlDrain = "SELECT *, " + + " CONCAT('" + fileBaseUrl + "/gccofficialapp/files', `file`) AS file_url " + + " FROM `drain_master` WHERE `ward`= ? AND isactive = 1 AND isdelete = 0"; + + List> drains = jdbcManHoleTemplate.queryForList(sqlDrain, ward); + List> finalList = new ArrayList<>(); + + for (Map drain : drains) { + Map drainResponse = new HashMap<>(); + drainResponse.putAll(drain); // add drain fields + + String drainId = drain.get("drain_id").toString(); + + // 2. Fetch manholes for this drain + String sqlManhole = "SELECT manhole_id FROM manhole_master WHERE drain_id = ? AND isactive=1 AND isdelete=0"; + List> manholes = jdbcManHoleTemplate.queryForList(sqlManhole, drainId); + + int totalManholes = manholes.size(); + int completedCount = 0; + int pendingCount = 0; + + // 3. Check before & after activities for each manhole + for (Map manhole : manholes) { + Object manholeId = manhole.get("manhole_id"); + + // Before + String sqlBefore = "SELECT COUNT(*) FROM before_activity " + + "WHERE manhole_id = ? AND drain_id = ? AND isactive=1 AND isdelete=0"; + int beforeCount = jdbcManHoleTemplate.queryForObject(sqlBefore, Integer.class, manholeId, drainId); + + // After + String sqlAfter = "SELECT COUNT(*) FROM after_activity " + + "WHERE manhole_id = ? AND drain_id = ? AND isactive=1 AND isdelete=0"; + int afterCount = jdbcManHoleTemplate.queryForObject(sqlAfter, Integer.class, manholeId, drainId); + + if (beforeCount > 0 && afterCount > 0) { + completedCount++; + } else { + pendingCount++; + } + } + + // 4. Percentages + double percentCompleted = (totalManholes > 0) ? (completedCount * 100.0 / totalManholes) : 0.0; + double percentPending = (totalManholes > 0) ? (pendingCount * 100.0 / totalManholes) : 0.0; + + // 5. Drain status + String drainStatus = (completedCount == totalManholes && totalManholes > 0) ? "Completed" : "Pending"; + + // 6. Add stats + drainResponse.put("total_manholes", totalManholes); + drainResponse.put("completed", completedCount); + drainResponse.put("pending", pendingCount); + drainResponse.put("percent_completed", String.format("%.2f", percentCompleted)); + drainResponse.put("percent_pending", String.format("%.2f", percentPending)); + drainResponse.put("status", drainStatus); + + finalList.add(drainResponse); + } + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Drain List."); + response.put("data", finalList); + + return Collections.singletonList(response); + } + + @Transactional + public String duplicateDrainCheck(String street_id, String drain_side) { + try { + + String checkSql = "SELECT COUNT(*) FROM drain_master WHERE street_id = ? AND `drain_side`= ? AND isactive = 1 AND isdelete = 0 "; + + Integer count = jdbcManHoleTemplate.queryForObject( + checkSql, + Integer.class, + new Object[]{street_id, drain_side} + ); + + return (count != null && count > 0) ? "true" : "false"; + + } catch (NumberFormatException e) { + return "false"; + } + } + + public List> saveDrain( + String drain_side, + String drain_type, + String drain_length, + String drain_width, + String drain_depth, + String manhole_count, + String zone, + String ward, + String street_name, + String street_id, + String road_type, + String latitude, + String longitude, + String inby, + MultipartFile file + ) { + + String action = "New Drain"; + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // Check Duplicate + if(duplicateDrainCheck(street_id,drain_side).equalsIgnoreCase("true")) { + response.put("status", "error"); + response.put("message", "Duplicate drain identified!"); + result.add(response); + return result; // stop execution, don’t insert + } + + String filetxt = street_id+"_SWD"; + + String filetype = "image"; + + String drainIMG = fileUpload("Drain", filetxt, file, filetype); + + if ("error".equalsIgnoreCase(drainIMG)) { + response.put("Drain", "upload image"); + response.put("status", "error"); + response.put("message", "Drain image upload failed."); + result.add(response); + return result; + } + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + String insertSql = "INSERT INTO `drain_master` (`drain_side`,`drain_type`,`drain_length`,`drain_width`,`drain_depth`," + + "`manhole_count`,`zone`,`ward`,`street_name`,`street_id`,`road_type`,`latitude`,`longitude`,`inby`,`file`) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + int affectedRows = jdbcManHoleTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"drain_id"}); + int i = 1; + ps.setString(i++, drain_side); + ps.setString(i++, drain_type); + ps.setString(i++, drain_length); + ps.setString(i++, drain_width); + ps.setString(i++, drain_depth); + ps.setInt(i++, (manhole_count == null || manhole_count.trim().isEmpty()) + ? 1 + : Integer.parseInt(manhole_count)); + ps.setString(i++, zone); + ps.setString(i++, ward); + ps.setString(i++, street_name); + ps.setString(i++, street_id); + ps.setString(i++, road_type); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, inby); + ps.setString(i++, drainIMG); + + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("ManHole", action + " insertId: " + lastInsertId); + response.put("status", "success"); + response.put("message", action + " inserted successfully."); + } else { + response.put("ManHole", action + " insertId error!"); + response.put("status", "error"); + response.put("message", action + " insert failed."); + } + + result.add(response); + return result; + } + + /* + public List> getManHoleList(String loginid, String swdid) { + + String sql = "SELECT * FROM `manhole_master` WHERE `swdid`= ?"; + List> result = jdbcManHoleTemplate.queryForList(sql, swdid); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "ManHole List."); + response.put("data", result); + + return Collections.singletonList(response); + } + + public List> getManHoleBeforeStatus(String manhole_id) { + + String sql = "SELECT *," + + " CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `file`) AS file_url " + + " FROM `before_activity` WHERE `manhole_id`= ?"; + List> result = jdbcManHoleTemplate.queryForList(sql, manhole_id); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "ManHole before activity list."); + response.put("data", result); + + return Collections.singletonList(response); + } + + public List> getManHoleAfterStatus(String manhole_id) { + + String sql = "SELECT *," + + " CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `file`) AS file_url " + + " FROM `after_activity` WHERE `manhole_id`= ?"; + List> result = jdbcManHoleTemplate.queryForList(sql, manhole_id); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "ManHole before activity list."); + response.put("data", result); + + return Collections.singletonList(response); + } + */ + + @Transactional + public boolean manHoleDuplicateCheck(String latitudeStr, String longitudeStr) { + try { + double latitude = Double.parseDouble(latitudeStr); + double longitude = Double.parseDouble(longitudeStr); + + System.out.println("Duplicate check latlong:"+ latitude + " | " + longitude); + + String checkSql = "SELECT COUNT(*) FROM manhole_master " + + "WHERE isactive = 1 AND isdelete = 0 " + // fixed delete flag + "AND (6371008.8 * ACOS(" + + "COS(RADIANS(?)) * COS(RADIANS(latitude)) * " + + "COS(RADIANS(longitude) - RADIANS(?)) + " + + "SIN(RADIANS(?)) * SIN(RADIANS(latitude))" + + ")) < 0.5"; + + Integer count = jdbcManHoleTemplate.queryForObject( + checkSql, + Integer.class, + latitude, longitude, latitude + ); + /* + String checkSqlstr = "SELECT COUNT(*) FROM manhole_master " + + "WHERE isactive = 1 AND isdelete = 0 " + // fixed delete flag + "AND (6371008.8 * ACOS(" + + "COS(RADIANS("+latitude+")) * COS(RADIANS(latitude)) * " + + "COS(RADIANS(longitude) - RADIANS("+longitude+")) + " + + "SIN(RADIANS("+latitude+")) * SIN(RADIANS(latitude))" + + ")) < 0.5"; + + System.out.println("Duplicate check sql:"+ checkSqlstr); + */ + return (count != null && count > 0); + + } catch (NumberFormatException e) { + return false; // invalid lat/lon input + } + } + + @Transactional + public boolean manHoleStreetCheck(String drain_id, String street_id) { + try { + String checkSql = "SELECT COUNT(*) FROM `drain_master` " + + "WHERE isactive = 1 AND isdelete = 0 " + // fixed delete flag + "AND drain_id = ? AND street_id = ? "; + + Integer count = jdbcManHoleTemplate.queryForObject( + checkSql, + Integer.class, + drain_id, + street_id + ); + + return (count != null && count == 1); + + } catch (NumberFormatException e) { + return false; // invalid lat/lon input + } + } + + @Transactional + public List> saveManHole( + String drain_id, + String zone, + String ward, + String street_name, + String street_id, + String latitude, + String longitude, + String inby + ) { + String action = "Save"; + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // 1. Duplicate check + if (manHoleDuplicateCheck(latitude, longitude)) { + response.put("status", "error"); + response.put("message", "Duplicate ManHole identified within 3 meters!"); + result.add(response); + return result; // stop execution, don’t insert + } + + // 2. Drain Street Check + if (!manHoleStreetCheck(drain_id, street_id)) { + response.put("status", "error"); + response.put("message", "Drain Street not mached with current Street!"); + result.add(response); + return result; // stop execution, don’t insert + } + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + String insertSql = "INSERT INTO manhole_master " + + "(drain_id, zone, ward, street_name, street_id, latitude, longitude, inby) " + + "VALUES (?,?,?,?,?,?,?,?)"; + + int affectedRows = jdbcManHoleTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"manhole_id"}); + int i = 1; + ps.setString(i++, drain_id); + ps.setString(i++, zone); + ps.setString(i++, ward); + ps.setString(i++, street_name); + ps.setString(i++, street_id); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, inby); + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("ManHole", action + " insertId: " + lastInsertId); + response.put("status", "success"); + response.put("message", action + " inserted successfully."); + } else { + response.put("ManHole", action + " insertId error!"); + response.put("status", "error"); + response.put("message", action + " insert failed."); + } + + result.add(response); + return result; + } + + public List> getManHoleList(String loginid, String drain_id) { + // 1. Fetch all manholes for the given drain_id + String sqlManhole = "SELECT * FROM manhole_master WHERE drain_id = ?"; + List> manholes = jdbcManHoleTemplate.queryForList(sqlManhole, drain_id); + + List> finalList = new ArrayList<>(); + + for (Map manhole : manholes) { + Map manholeResponse = new HashMap<>(); + manholeResponse.putAll(manhole); // add all manhole columns + + // 2. Fetch before activity + String sqlBefore = "SELECT *, " + + " CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `file`) AS file_url " + + "FROM before_activity WHERE manhole_id = ? AND drain_id = ? AND isactive=1 AND isdelete=0"; + List> beforeActivities = jdbcManHoleTemplate.queryForList(sqlBefore, + manhole.get("manhole_id"), drain_id); + + Map beforeData = new HashMap<>(); + if (!beforeActivities.isEmpty()) { + beforeData.put("status", "Completed"); + beforeData.put("details", beforeActivities); + } else { + beforeData.put("status", "Pending"); + beforeData.put("details", Collections.emptyList()); + } + + // 3. Fetch after activity + String sqlAfter = "SELECT *," + + " CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `file`) AS file_url " + + " FROM after_activity WHERE manhole_id = ? AND drain_id = ? AND isactive=1 AND isdelete=0"; + List> afterActivities = jdbcManHoleTemplate.queryForList(sqlAfter, + manhole.get("manhole_id"), drain_id); + + Map afterData = new HashMap<>(); + if (!afterActivities.isEmpty()) { + afterData.put("status", "Completed"); + afterData.put("details", afterActivities); + } else { + afterData.put("status", "Pending"); + afterData.put("details", Collections.emptyList()); + } + + // 4. Overall manhole status + String overallStatus = (!beforeActivities.isEmpty() && !afterActivities.isEmpty()) ? "Completed" : "Pending"; + manholeResponse.put("status", overallStatus); + manholeResponse.put("before", beforeData); + manholeResponse.put("after", afterData); + + finalList.add(manholeResponse); + } + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "ManHole List."); + response.put("data", finalList); + + return Collections.singletonList(response); + } + + @Transactional + public String manHoleLocationCheck(String cby, String manhole_id, String latitudeStr, String longitudeStr) { + try { + double latitude = Double.parseDouble(latitudeStr); + double longitude = Double.parseDouble(longitudeStr); + + String checkSql = "SELECT COUNT(*) FROM manhole_master " + + "WHERE manhole_id = ? " + + "AND (6371008.8 * ACOS(" + + "COS(RADIANS(?)) * COS(RADIANS(latitude)) * " + + "COS(RADIANS(longitude) - RADIANS(?)) + " + + "SIN(RADIANS(?)) * SIN(RADIANS(latitude))" + + ")) < 1"; + + Integer count = jdbcManHoleTemplate.queryForObject( + checkSql, + Integer.class, + new Object[]{manhole_id, latitude, longitude, latitude} + ); + + return (count != null && count > 0) ? "true" : "false"; + + } catch (NumberFormatException e) { + return "false"; // invalid lat/lon input + } + } + + @Transactional + public List> saveActivity( + String manhole_id, + String drain_id, + MultipartFile file, + String zone, + String ward, + String street_name, + String street_id, + String latitude, + String longitude, + String inby, + String action, + String beforeActivityId, + String clean_type, + String case_id + ) { + + String filetxt =manhole_id+"_"+drain_id; + + String filetype = "image"; + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // 1. Drain Street Check + if (!manHoleStreetCheck(drain_id, street_id)) { + response.put("status", "error"); + response.put("message", "Drain Street not mached with current Street!"); + result.add(response); + return result; // stop execution, don’t insert + } + + String activityimg = fileUpload(action, filetxt, file, filetype); + // 2. Check file uploaded + if ("error".equalsIgnoreCase(activityimg)) { + response.put("status", "error"); + response.put("message", "ManHole activity insert failed."); + result.add(response); + return result; + } + + String insertBeforeSql = "INSERT INTO before_activity(manhole_id, drain_id, file, zone, ward, street_name, street_id, latitude, longitude, inby, case_id) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?)"; + + String insertAfterSql = "INSERT INTO after_activity(manhole_id, drain_id, file, zone, ward, street_name, street_id, latitude, longitude, inby, case_id, before_activity_id, clean_type) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + String insertSql = "before".equalsIgnoreCase(action) ? insertBeforeSql : insertAfterSql; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcManHoleTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"activity_id"}); + int i = 1; + ps.setString(i++, manhole_id); + ps.setString(i++, drain_id); + ps.setString(i++, activityimg); + ps.setString(i++, zone); + ps.setString(i++, ward); + ps.setString(i++, street_name); + ps.setString(i++, street_id); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, inby); + ps.setString(i++, case_id); + + if ("after".equalsIgnoreCase(action)) { + ps.setString(i++, beforeActivityId); + ps.setString(i++, clean_type); + } + + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("ManHole", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", "ManHole " + action + " activity inserted successfully."); + } else { + response.put("ManHole", action + " insertId error!"); + response.put("status", "error"); + response.put("message", "ManHole " + action + " activity insert failed."); + } + + result.add(response); + return result; + } + + public List> getZoneReport() { + String sql = + "SELECT " + + " z.zone," + + " COUNT(t.drain_id) AS total_drain," + + " SUM(CASE WHEN t.total_manhole = t.completed_manhole THEN 1 ELSE 0 END) AS total_drain_completed," + + " SUM(CASE WHEN t.total_manhole > t.completed_manhole THEN 1 ELSE 0 END) AS total_drain_pending," + + " ROUND(SUM(CASE WHEN t.total_manhole = t.completed_manhole THEN 1 ELSE 0 END) * 100.0 / COUNT(t.drain_id), 2) AS drain_completed_percentage," + + " ROUND(SUM(CASE WHEN t.total_manhole > t.completed_manhole THEN 1 ELSE 0 END) * 100.0 / COUNT(t.drain_id), 2) AS drain_pending_percentage " + + "FROM (" + + " SELECT '01' AS zone UNION ALL" + + " SELECT '02' UNION ALL" + + " SELECT '03' UNION ALL" + + " SELECT '04' UNION ALL" + + " SELECT '05' UNION ALL" + + " SELECT '06' UNION ALL" + + " SELECT '07' UNION ALL" + + " SELECT '08' UNION ALL" + + " SELECT '09' UNION ALL" + + " SELECT '10' UNION ALL" + + " SELECT '11' UNION ALL" + + " SELECT '12' UNION ALL" + + " SELECT '13' UNION ALL" + + " SELECT '14' UNION ALL" + + " SELECT '15'" + + ") z " + + "LEFT JOIN (" + + " SELECT " + + " d.drain_id," + + " d.zone," + + " SUM(d.manhole_count) AS total_manhole," + + " COUNT(DISTINCT CASE " + + " WHEN ba.activity_id IS NOT NULL AND aa.activity_id IS NOT NULL THEN m.manhole_id " + + " END) AS completed_manhole" + + " FROM drain_master d" + + " LEFT JOIN manhole_master m ON d.drain_id = m.drain_id AND m.isactive=1 AND m.isdelete=0" + + " LEFT JOIN before_activity ba ON m.manhole_id = ba.manhole_id AND ba.isactive=1 AND ba.isdelete=0" + + " LEFT JOIN after_activity aa ON m.manhole_id = aa.manhole_id AND aa.isactive=1 AND aa.isdelete=0" + + " WHERE d.isactive = 1 AND d.isdelete = 0" + + " GROUP BY d.drain_id, d.zone" + + ") t ON z.zone = t.zone " + + "GROUP BY z.zone " + + "ORDER BY z.zone"; + + return jdbcManHoleTemplate.queryForList(sql); + } + + public List> getWardReport(String zone) { + String sql = + "SELECT " + + " t.zone," + + " t.ward," + + " COUNT(t.drain_id) AS total_drain," + + " SUM(CASE WHEN t.total_manhole = t.completed_manhole THEN 1 ELSE 0 END) AS total_drain_completed," + + " SUM(CASE WHEN t.total_manhole > t.completed_manhole THEN 1 ELSE 0 END) AS total_drain_pending," + + " ROUND(SUM(CASE WHEN t.total_manhole = t.completed_manhole THEN 1 ELSE 0 END) * 100.0 / COUNT(t.drain_id), 2) AS drain_completed_percentage," + + " ROUND(SUM(CASE WHEN t.total_manhole > t.completed_manhole THEN 1 ELSE 0 END) * 100.0 / COUNT(t.drain_id), 2) AS drain_pending_percentage " + + "FROM (" + + " SELECT " + + " d.drain_id," + + " d.zone," + + " d.ward," + + " SUM(d.manhole_count) AS total_manhole," + + " COUNT(DISTINCT CASE " + + " WHEN ba.activity_id IS NOT NULL AND aa.activity_id IS NOT NULL THEN m.manhole_id " + + " END) AS completed_manhole" + + " FROM drain_master d" + + " LEFT JOIN manhole_master m ON d.drain_id = m.drain_id AND m.isactive=1 AND m.isdelete=0" + + " LEFT JOIN before_activity ba ON m.manhole_id = ba.manhole_id AND ba.isactive=1 AND ba.isdelete=0" + + " LEFT JOIN after_activity aa ON m.manhole_id = aa.manhole_id AND aa.isactive=1 AND aa.isdelete=0" + + " WHERE d.isactive = 1 AND d.isdelete = 0" + + " AND d.zone = ?" + + " GROUP BY d.drain_id, d.zone, d.ward" + + ") t " + + "GROUP BY t.zone, t.ward " + + "ORDER BY t.ward"; + + return jdbcManHoleTemplate.queryForList(sql,zone); + } + + public List> getDrainReport(String ward) { + String sql = + "SELECT " + + " t.drain_name AS drain, " + + " t.total_manhole AS total_manhole, " + + " t.completed_manhole AS manhole_completed, " + + " (t.total_manhole - t.completed_manhole) AS manhole_pending, " + + " ROUND(t.completed_manhole * 100.0 / t.total_manhole, 2) AS completed_percentage, " + + " ROUND((t.total_manhole - t.completed_manhole) * 100.0 / t.total_manhole, 2) AS pending_percentage " + + "FROM ( " + + " SELECT " + + " CONCAT(d.street_name, '-', d.drain_side) AS drain_name, " + + " d.drain_id, " + + " SUM(d.manhole_count) AS total_manhole, " + + " COUNT(DISTINCT CASE " + + " WHEN ba.activity_id IS NOT NULL AND aa.activity_id IS NOT NULL THEN m.manhole_id " + + " END) AS completed_manhole " + + " FROM drain_master d " + + " LEFT JOIN manhole_master m ON d.drain_id = m.drain_id AND m.isactive=1 AND m.isdelete=0 " + + " LEFT JOIN before_activity ba ON m.manhole_id = ba.manhole_id AND ba.isactive=1 AND ba.isdelete=0 " + + " LEFT JOIN after_activity aa ON m.manhole_id = aa.manhole_id AND aa.isactive=1 AND aa.isdelete=0 " + + " WHERE d.isactive = 1 AND d.isdelete = 0 " + + " AND d.ward = ? " + + " GROUP BY drain_name, d.drain_id " + + ") t " + + "ORDER BY t.drain_name"; + + return jdbcManHoleTemplate.queryForList(sql, ward); + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/controller/API_FoggingController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/controller/API_FoggingController.java index d461220..4fe8c7c 100644 --- a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/controller/API_FoggingController.java +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/controller/API_FoggingController.java @@ -46,9 +46,10 @@ public class API_FoggingController { @RequestParam(value = "zone", required = true) String zone, @RequestParam(value = "ward", required = true) String ward, @RequestParam(value = "latitude", required = true) String latitude, - @RequestParam(value = "longitude", required = true) String longitude + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "address", required = false) String address ) { - return foggingService.saveCanalFlow(cid,scid,maintainedby,canalid,q4,q5,file,remarks,cby,zone,ward,latitude,longitude,"pending"); + return foggingService.saveCanalFlow(cid,scid,maintainedby,canalid,q4,q5,file,remarks,cby,zone,ward,latitude,longitude,"pending",address); } @GetMapping("/checkHasCanalPending") @@ -107,9 +108,10 @@ public class API_FoggingController { @RequestParam(value = "zone", required = true) String zone, @RequestParam(value = "ward", required = true) String ward, @RequestParam(value = "latitude", required = true) String latitude, - @RequestParam(value = "longitude", required = true) String longitude + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "address", required = false) String address ) { - return foggingService.saveSWDFlow(cid,scid,streetname,streetid,q2,q4,file,remarks,cby,zone,ward,latitude,longitude,"pending"); + return foggingService.saveSWDFlow(cid,scid,streetname,streetid,q2,q4,file,remarks,cby,zone,ward,latitude,longitude,"pending",address); } @GetMapping("/checkHasSWDPending") @@ -166,9 +168,10 @@ public class API_FoggingController { @RequestParam(value = "zone", required = true) String zone, @RequestParam(value = "ward", required = true) String ward, @RequestParam(value = "latitude", required = true) String latitude, - @RequestParam(value = "longitude", required = true) String longitude + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "address", required = false) String address ) { - return foggingService.saveStreetData(cid, scid, streetid, streetname, file, remarks, cby, zone, ward, latitude, longitude, "close"); + return foggingService.saveStreetData(cid, scid, streetid, streetname, file, remarks, cby, zone, ward, latitude, longitude, "close",address); } @PostMapping(value="/saveVacantLandData") @@ -184,9 +187,10 @@ public class API_FoggingController { @RequestParam(value = "zone", required = true) String zone, @RequestParam(value = "ward", required = true) String ward, @RequestParam(value = "latitude", required = true) String latitude, - @RequestParam(value = "longitude", required = true) String longitude + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "address", required = false) String address ) { - return foggingService.saveVacantLandData(cid, scid, name, q2, q3, file, remarks, cby, zone, ward, latitude, longitude, "close"); + return foggingService.saveVacantLandData(cid, scid, name, q2, q3, file, remarks, cby, zone, ward, latitude, longitude, "close",address); } // SAMPLE COLLECTION @@ -204,10 +208,11 @@ public class API_FoggingController { @RequestParam(value = "zone", required = true) String zone, @RequestParam(value = "ward", required = true) String ward, @RequestParam(value = "latitude", required = true) String latitude, - @RequestParam(value = "longitude", required = true) String longitude + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "address", required = false) String address ) { return foggingService.saveLarvalAdultCollectionFlow(cid,maintainedby,canalid,q2,q6,q7, - file,remarks,cby,zone,ward,latitude,longitude,"close"); + file,remarks,cby,zone,ward,latitude,longitude,"close",address); } } diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/controller/API_MosquitoController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/controller/API_MosquitoController.java index 474cf08..290880a 100644 --- a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/controller/API_MosquitoController.java +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/controller/API_MosquitoController.java @@ -60,6 +60,7 @@ public class API_MosquitoController { @RequestParam(value = "visitstatus", required = true) String visitstatus, @RequestParam(value = "feverfound", required = true) String q1, @RequestParam(value = "treatment", required = false) String treatment, + @RequestParam(value = "noofsource", required = false) String noofsource, @RequestParam(value = "breedfound", required = true) String q2, @RequestParam(value = "sourcetype", required = false) String sourcetype, @RequestParam(value = "loginId", required = true) String cby, @@ -67,11 +68,11 @@ public class API_MosquitoController { @RequestParam(value = "zone", required = true) String zone, @RequestParam(value = "ward", required = true) String ward, @RequestParam(value = "latitude", required = true) String latitude, - @RequestParam(value = "longitude", required = true) String longitude + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "address", required = false) String address //@RequestParam(value = "file", required = true) MultipartFile file, - ) { - return mosquitoService.saveSurveyFlow1(cid,scid,q1,treatment,q2,sourcetype,cby,name,zone,ward,latitude,longitude,visitstatus); + return mosquitoService.saveSurveyFlow1(cid,scid,q1,treatment,q2,sourcetype,cby,name,zone,ward,latitude,longitude,visitstatus,noofsource,address); } @GetMapping("/checkHasPending") @@ -101,6 +102,7 @@ public class API_MosquitoController { public List updatePendingStatus(@RequestParam MultiValueMap formData, @RequestParam(value = "sid", required = true) String sid, @RequestParam(value = "action", required = true) String q3, + @RequestParam(value = "file_before", required = false) MultipartFile file_before, @RequestParam(value = "file", required = true) MultipartFile file, @RequestParam(value = "remarks", required = true) String remarks, @RequestParam(value = "loginId", required = true) String cby, @@ -109,7 +111,7 @@ public class API_MosquitoController { @RequestParam(value = "latitude", required = true) String latitude, @RequestParam(value = "longitude", required = true) String longitude ) { - return mosquitoService.updateFlow1PendingStatus("close", q3, file, remarks, cby, zone, ward, latitude, longitude, sid); + return mosquitoService.updateFlow1PendingStatus("close", q3, file, remarks, cby, zone, ward, latitude, longitude, sid,file_before); } // ************************************************************************************************************************* // @@ -129,8 +131,76 @@ public class API_MosquitoController { @RequestParam(value = "zone", required = true) String zone, @RequestParam(value = "ward", required = true) String ward, @RequestParam(value = "latitude", required = true) String latitude, - @RequestParam(value = "longitude", required = true) String longitude + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "address", required = false) String address + ) { + return mosquitoService.saveSurveyFlow2(cid, scid, name, q2, q3, file, remarks, cby, zone, ward, latitude, longitude, "close", address); + } + + // FOR REPORTS + + @GetMapping(value="/breedingCheck/reports/zone") + public List breedingZoneReports( + @RequestParam(value = "loginId", required = true) String cby, + @RequestParam(value = "fromDate", required = true) String fromDate, + @RequestParam(value = "toDate", required = true) String toDate + ) { + return mosquitoService.breedingZoneReports(cby,fromDate,toDate); + } + + @GetMapping(value="/breedingCheck/reports/breedingWardReports") + public List breedingWardReports( + @RequestParam(value = "loginId", required = true) String cby, + @RequestParam(value = "fromDate", required = true) String fromDate, + @RequestParam(value = "toDate", required = true) String toDate, + @RequestParam(value = "zone", required = true) String zone + ) { + return mosquitoService.breedingWardReports(cby,fromDate,toDate,zone); + } + + @GetMapping(value="/breedingCheck/reports/breedinglistReports") + public List breedinglistReports( + @RequestParam(value = "loginId", required = true) String cby, + @RequestParam(value = "fromDate", required = true) String fromDate, + @RequestParam(value = "toDate", required = true) String toDate, + @RequestParam(value = "ward", required = true) String ward + ) { + return mosquitoService.breedinglistReports(cby,fromDate,toDate,ward); + } + + @GetMapping(value="/breedingCheck/reports/getBreedingDetails") + public List getBreedingDetails( + @RequestParam(value = "id", required = true) String id + ) { + return mosquitoService.getBreedingDetails(id); + } + + @GetMapping(value="/breedingCheck/reports/userReports") + public List userReports( + @RequestParam(value = "loginId", required = true) String cby, + @RequestParam(value = "fromDate", required = true) String fromDate, + @RequestParam(value = "toDate", required = true) String toDate, + @RequestParam(value = "ward", required = true) String ward + ) { + return mosquitoService.userReports(cby,fromDate,toDate,ward); + } + + @GetMapping(value="/breedingCheck/reports/userDayReports") + public List userDayReports( + @RequestParam(value = "cby", required = true) String cby, + @RequestParam(value = "fromDate", required = true) String fromDate, + @RequestParam(value = "toDate", required = true) String toDate, + @RequestParam(value = "ward", required = true) String ward + ) { + return mosquitoService.userDayReports(cby,fromDate,toDate,ward); + } + + @GetMapping(value="/breedingCheck/reports/userBreedinglistReports") + public List userBreedinglistReports( + @RequestParam(value = "cby", required = true) String cby, + @RequestParam(value = "selectDate", required = true) String selectedDate, + @RequestParam(value = "ward", required = true) String ward ) { - return mosquitoService.saveSurveyFlow2(cid, scid, name, q2, q3, file, remarks, cby, zone, ward, latitude, longitude, "close"); + return mosquitoService.userBreedinglistReports(cby,selectedDate,ward); } } diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/service/FoggingService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/service/FoggingService.java index 64fdf50..8dd1804 100644 --- a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/service/FoggingService.java +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/service/FoggingService.java @@ -182,7 +182,8 @@ public class FoggingService { String ward, String latitude, String longitude, - String status) { + String status, + String address) { List> result = null; Map response = new HashMap<>(); @@ -199,8 +200,8 @@ public class FoggingService { String sqlQuery = "INSERT INTO `fogging_of_canal` " + "(`cid`, `scid`, `maintainedby`, `canalid`, `q4`, `q5`, `treatedfile`, " - + "`remarks`, `cby`, `zone`, `ward`, `latitude`, `longitude`, `status`) " - + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + "`remarks`, `cby`, `zone`, `ward`, `latitude`, `longitude`, `status`,`address`) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; KeyHolder keyHolder = new GeneratedKeyHolder(); @@ -227,6 +228,7 @@ public class FoggingService { ps.setString(12, latitude); ps.setString(13, longitude); ps.setString(14, status); + ps.setString(15, address); return ps; } }, keyHolder); @@ -618,7 +620,8 @@ public class FoggingService { String ward, String latitude, String longitude, - String status) { + String status, + String address) { List> result = null; Map response = new HashMap<>(); @@ -635,8 +638,8 @@ public class FoggingService { String sqlQuery = "INSERT INTO `fogging_of_swd` " + "(`cid`, `scid`, `streetname`, `streetid`, `q2`, `q4`, `treatedfile`, " - + "`remarks`, `cby`, `zone`, `ward`, `latitude`, `longitude`, `status`) " - + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + "`remarks`, `cby`, `zone`, `ward`, `latitude`, `longitude`, `status`,`address`) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; KeyHolder keyHolder = new GeneratedKeyHolder(); @@ -663,6 +666,7 @@ public class FoggingService { ps.setString(12, latitude); ps.setString(13, longitude); ps.setString(14, status); + ps.setString(15, address); return ps; } }, keyHolder); @@ -922,6 +926,7 @@ public class FoggingService { + "swd.`ward`, " + "swd.`latitude`, " + "swd.`longitude`, " + + "swd.`address`, " + "swd.`status` " + "FROM `fogging_of_swd` swd " + "WHERE swd.`isactive` = 1 AND swd.`status`='pending' AND swd.cby = ?"; @@ -1093,7 +1098,8 @@ public class FoggingService { String ward, String latitude, String longitude, - String status) { + String status, + String address) { List> result = null; Map response = new HashMap<>(); @@ -1110,8 +1116,8 @@ public class FoggingService { String sqlQuery = "INSERT INTO `fogging_of_street_data` " + "(`cid`, `scid`, `streetid`, `streetname`, `treatedfile`, " - + "`remarks`, `cby`, `zone`, `ward`, `latitude`, `longitude`, `status`) " - + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"; + + "`remarks`, `cby`, `zone`, `ward`, `latitude`, `longitude`, `status`,`address`) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"; KeyHolder keyHolder = new GeneratedKeyHolder(); @@ -1136,6 +1142,7 @@ public class FoggingService { ps.setString(10, latitude); ps.setString(11, longitude); ps.setString(12, status); + ps.setString(13, address); return ps; } }, keyHolder); @@ -1190,7 +1197,8 @@ public class FoggingService { String ward, String latitude, String longitude, - String status) { + String status, + String address) { List> result = null; Map response = new HashMap<>(); @@ -1207,8 +1215,8 @@ public class FoggingService { String sqlQuery = "INSERT INTO `fogging_of_vacantland_data` " + "(`cid`, `scid`, `name`, `q2`, `q3`, `treatedfile`, " - + "`remarks`, `cby`, `zone`, `ward`, `latitude`, `longitude`, `status`) " - + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + "`remarks`, `cby`, `zone`, `ward`, `latitude`, `longitude`, `status`,`address`) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; KeyHolder keyHolder = new GeneratedKeyHolder(); @@ -1234,6 +1242,7 @@ public class FoggingService { ps.setString(11, latitude); ps.setString(12, longitude); ps.setString(13, status); + ps.setString(14, address); return ps; } }, keyHolder); @@ -1292,7 +1301,8 @@ public class FoggingService { String ward, String latitude, String longitude, - String status) { + String status, + String address) { List> result = null; Map response = new HashMap<>(); @@ -1309,8 +1319,8 @@ public class FoggingService { String sqlQuery = "INSERT INTO `larval_adult_collection_data` " + "(`cid`, `maintainedby`, `canalid`, `q2`, `q6`, `q7`, `treatedfile`, " - + "`remarks`, `cby`, `zone`, `ward`, `latitude`, `longitude`, `status`) " - + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + "`remarks`, `cby`, `zone`, `ward`, `latitude`, `longitude`, `status`,`address`) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; KeyHolder keyHolder = new GeneratedKeyHolder(); @@ -1337,6 +1347,7 @@ public class FoggingService { ps.setString(12, latitude); ps.setString(13, longitude); ps.setString(14, status); + ps.setString(15, address); return ps; } }, keyHolder); diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/service/MosquitoService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/service/MosquitoService.java index 91308e1..251a10b 100644 --- a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/service/MosquitoService.java +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/mosquitosurvey/service/MosquitoService.java @@ -11,6 +11,7 @@ import java.security.SecureRandom; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Collections; @@ -195,7 +196,9 @@ public class MosquitoService { String ward, String latitude, String longitude, - String visitstatus) { + String visitstatus, + String noofsource, + String address) { List> result = null; Map response = new HashMap<>(); @@ -214,8 +217,8 @@ public class MosquitoService { */ String sqlQuery = "INSERT INTO `survey_of_house`" + "(`cid`, `scid`, `q1`, `treatment`, `q2`, `sourcetype`, `cby`, " - + "`name`, `zone`, `ward`, `latitude`, `longitude`,`visitstatus`) " - + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + "`name`, `zone`, `ward`, `latitude`, `longitude`,`visitstatus`,`noofsource`,`address`) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; KeyHolder keyHolder = new GeneratedKeyHolder(); @@ -241,6 +244,8 @@ public class MosquitoService { ps.setString(11, latitude); ps.setString(12, longitude); ps.setString(13, visitstatus); + ps.setString(14, noofsource); + ps.setString(15, address); return ps; } }, keyHolder); @@ -396,7 +401,9 @@ public class MosquitoService { public List> getHousePendingList(String cby) { - String sql = "SELECT shd.sid, sh.id, sh.name, bs.name AS sourcetype, sc.name AS sitetype, " + String sql = "SELECT shd.sid, sh.id, sh.name, " + + "bs.name AS sourcetype, bs.display_name AS sourcetype_tamil, " + + "sc.name AS sitetype, sc.display_name AS sitetype_tamil, " + "sh.zone, sh.ward, sh.latitude, sh.longitude, " + "bsc.actiontype AS actionrequired, " + "DATE_FORMAT(sh.`cdate`, '%d-%m-%Y %r') AS createddate " @@ -429,10 +436,12 @@ public class MosquitoService { MultipartFile file, String remarks, String cby, String zone, String ward, String latitude, String longitude, - String sid + String sid, + MultipartFile file_before ) { String treatedfile =""; + String beforefile =""; // Handle file upload if a file is provided if (file != null && !file.isEmpty()) { @@ -441,18 +450,24 @@ public class MosquitoService { String finaltreatedfile = treatedfile; + // Handle file upload if a file is provided + if (file_before != null && !file_before.isEmpty()) { + beforefile = fileUpload(sid+"_before", cby, file_before); + } + String finaltbeforefile = beforefile; + LocalDateTime approvedDate = LocalDateTime.now(); String formattedDate = approvedDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); String sqlQuery = "UPDATE `survey_of_house_data` SET " + "`status`=?, `q3`=?, `treatedfile`=?, `remarks`=?, `cby`=?, " - + "`zone`=?, `ward`=?, `latitude`=?, `longitude`=? ,`updatedate`=? " + + "`zone`=?, `ward`=?, `latitude`=?, `longitude`=? ,`updatedate`=? ,`file_before`=?" + "WHERE `sid`=?"; // Execute the update query int rowsAffected = jdbcMosquitoTemplate.update(sqlQuery, new Object[]{ - status, q3, finaltreatedfile, remarks, cby, zone, ward, latitude, longitude,formattedDate, sid + status, q3, finaltreatedfile, remarks, cby, zone, ward, latitude, longitude,formattedDate, finaltbeforefile, sid }); // Create a response map @@ -483,7 +498,8 @@ public class MosquitoService { String ward, String latitude, String longitude, - String status) { + String status, + String address) { List> result = null; Map response = new HashMap<>(); @@ -500,8 +516,8 @@ public class MosquitoService { String sqlQuery = "INSERT INTO `survey_of_construction_land_data` " + "(`cid`, `scid`, `name`, `q2`, `q3`, `treatedfile`, " - + "`remarks`, `cby`, `zone`, `ward`, `latitude`, `longitude`, `status`) " - + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"; + + "`remarks`, `cby`, `zone`, `ward`, `latitude`, `longitude`, `status`,`address`) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; KeyHolder keyHolder = new GeneratedKeyHolder(); @@ -527,6 +543,7 @@ public class MosquitoService { ps.setString(11, latitude); ps.setString(12, longitude); ps.setString(13, status); + ps.setString(14, address); return ps; } }, keyHolder); @@ -567,4 +584,254 @@ public class MosquitoService { return Collections.singletonList(response); } + + // For Reports + + @Transactional + public List> breedingZoneReports(String cby, String fromDate, String toDate){ + + DateTimeFormatter inputFmt = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter dbFmt = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + String fromDateDB = LocalDate.parse(fromDate, inputFmt).format(dbFmt); + String toDateDB = LocalDate.parse(toDate, inputFmt).format(dbFmt); + + Map response = new HashMap<>(); + + String sqlQuery = "SELECT " + + " zone, " + + " COUNT(*) AS Inspected, " + + " SUM( LENGTH(sourcetype) - LENGTH(REPLACE(sourcetype, ',', '')) + 1 ) AS NoOfBreedingSourceIdentified " + + "FROM survey_of_house " + + "WHERE isactive = 1 AND zone BETWEEN '01' AND '15' " + + "AND DATE(`cdate`) BETWEEN ? AND ? " + + "GROUP BY zone " + + "ORDER BY zone"; + + List> result = jdbcMosquitoTemplate.queryForList(sqlQuery, fromDateDB, toDateDB); + response.put("status", 200); + response.put("message", "Zone report."); + if(result.isEmpty()) { + response.put("message", "No data found."); + } + response.put("data", result); + return Collections.singletonList(response); + } + + @Transactional + public List> breedingWardReports(String cby, String fromDate, String toDate, String zone){ + + DateTimeFormatter inputFmt = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter dbFmt = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + String fromDateDB = LocalDate.parse(fromDate, inputFmt).format(dbFmt); + String toDateDB = LocalDate.parse(toDate, inputFmt).format(dbFmt); + + Map response = new HashMap<>(); + + String sqlQuery = "SELECT " + + " ward, " + + " COUNT(*) AS Inspected, " + + " SUM( LENGTH(sourcetype) - LENGTH(REPLACE(sourcetype, ',', '')) + 1 ) AS NoOfBreedingSourceIdentified " + + "FROM survey_of_house " + + "WHERE isactive = 1 " + + "AND DATE(`cdate`) BETWEEN ? AND ? " + + "AND `zone` = ? " + + "GROUP BY ward " + + "ORDER BY ward"; + + List> result = jdbcMosquitoTemplate.queryForList(sqlQuery, fromDateDB, toDateDB, zone); + response.put("status", 200); + response.put("message", "Ward report."); + if(result.isEmpty()) { + response.put("message", "No data found."); + } + response.put("data", result); + return Collections.singletonList(response); + } + + @Transactional + public List> breedinglistReports(String cby, String fromDate, String toDate, String ward){ + + Map response = new HashMap<>(); + DateTimeFormatter inputFmt = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter dbFmt = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + String fromDateDB = LocalDate.parse(fromDate, inputFmt).format(dbFmt); + String toDateDB = LocalDate.parse(toDate, inputFmt).format(dbFmt); + + String sqlQuery = "SELECT " + + " sh.*, " + + " SUM( LENGTH(sh.sourcetype) - LENGTH(REPLACE(sh.sourcetype, ',', '')) + 1 ) AS NoOfBreedingSourceIdentified, " + + "CASE " + + " WHEN COALESCE(SUM(CASE WHEN shd.status <> 'close' THEN 1 ELSE 0 END),0) = 0 " + + " THEN 'Completed'" + + " ELSE 'Pending'" + + " END AS final_status " + + "FROM survey_of_house sh " + + "LEFT JOIN survey_of_house_data shd ON sh.id = shd.surveyid " + + "WHERE sh.isactive = 1 " + + "AND DATE(sh.`cdate`) BETWEEN ? AND ? " + + "AND sh.`ward` = ? " + + "GROUP BY sh.id " + + "ORDER BY id"; + + List> result = jdbcMosquitoTemplate.queryForList(sqlQuery, fromDateDB, toDateDB, ward); + response.put("status", 200); + response.put("message", "Ward based list."); + if(result.isEmpty()) { + response.put("message", "No data found."); + } + response.put("data", result); + return Collections.singletonList(response); + } + + @Transactional + public List> getBreedingDetails(String surveyId) { + Map response = new HashMap<>(); + String sql = "SELECT " + + "shd.sid, sh.id, sh.name, " + + "bs.name AS sourcetype, bs.display_name AS sourcetype_tamil, " + + "sc.name AS sitetype, sc.display_name AS sitetype_tamil, " + + "sh.zone, sh.ward, sh.latitude, sh.longitude, sh.address," + + "bsc.actiontype AS actionrequired, " + + "CONCAT(?, '/gccofficialapp/files', shd.file_before) AS file_before, " + + "CONCAT(?, '/gccofficialapp/files', shd.treatedfile) AS treatedfile, " + + "shd.status, shd.remarks, " + + "DATE_FORMAT(sh.cdate, '%d-%m-%Y %r') AS createddate " + + "FROM survey_of_house_data AS shd " + + "JOIN survey_of_house AS sh ON shd.surveyid = sh.id " + + "JOIN breadingsource AS bs ON shd.sourceid = bs.sid " + + "JOIN breadingsource_category AS bsc ON bs.scid = bsc.scid " + + "JOIN subcategory AS sc ON sc.scid = sh.scid " + + "WHERE shd.isactive = 1 " + + "AND sh.id = ? " + + "ORDER BY shd.sid"; + + List> result = jdbcMosquitoTemplate.queryForList(sql, fileBaseUrl, fileBaseUrl, surveyId); + response.put("status", 200); + response.put("message", "Ward based list."); + if(result.isEmpty()) { + response.put("message", "No data found."); + } + response.put("data", result); + return Collections.singletonList(response); + } + + // USER Based Report + + @Transactional + public List> userReports(String cby, String fromDate, String toDate, String ward){ + + Map response = new HashMap<>(); + DateTimeFormatter inputFmt = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter dbFmt = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + String fromDateDB = LocalDate.parse(fromDate, inputFmt).format(dbFmt); + String toDateDB = LocalDate.parse(toDate, inputFmt).format(dbFmt); + + String sqlQuery = "SELECT " + + " sh.cby," + + " eu.FIRST_NAME," + + " eu.USER_NAME," + + " eu.EXTRAFIELD1," + + " eu.EXTRAFIELD2," + + " eu.EXTRAFIELD3," + + " eu.EXTRAFIELD4," + + " COUNT(*) AS Inspected," + + " SUM( LENGTH(sh.sourcetype) - LENGTH(REPLACE(sh.sourcetype, ',', '')) + 1 ) AS NoOfBreedingSourceIdentified " + + " FROM survey_of_house sh " + + " LEFT JOIN erp_pgr.EG_USER eu ON sh.cby = eu.id " + + " WHERE sh.isactive = 1 " + + " AND DATE(sh.cdate) BETWEEN ? AND ? " + + " AND sh.ward = ? " + + " GROUP BY sh.cby, eu.FIRST_NAME, eu.USER_NAME, eu.EXTRAFIELD1, eu.EXTRAFIELD2, eu.EXTRAFIELD3, eu.EXTRAFIELD4 " + + " ORDER BY sh.cby"; + + List> result = jdbcMosquitoTemplate.queryForList(sqlQuery, fromDateDB, toDateDB, ward); + response.put("status", 200); + response.put("message", "Ward based list."); + if(result.isEmpty()) { + response.put("message", "No data found."); + } + response.put("data", result); + return Collections.singletonList(response); + } + + @Transactional + public List> userDayReports(String cby, String fromDate, String toDate, String ward){ + + Map response = new HashMap<>(); + DateTimeFormatter inputFmt = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter dbFmt = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + String fromDateDB = LocalDate.parse(fromDate, inputFmt).format(dbFmt); + String toDateDB = LocalDate.parse(toDate, inputFmt).format(dbFmt); + + String sqlQuery = "SELECT" + + " DATE_FORMAT(sh.cdate, '%d-%m-%Y') as inspectedDate," + + " sh.cby," + + " eu.FIRST_NAME," + + " eu.USER_NAME," + + " eu.EXTRAFIELD1," + + " eu.EXTRAFIELD2," + + " eu.EXTRAFIELD3," + + " eu.EXTRAFIELD4," + + " COUNT(*) AS Inspected," + + " SUM( LENGTH(sh.sourcetype) - LENGTH(REPLACE(sh.sourcetype, ',', '')) + 1 ) AS NoOfBreedingSourceIdentified" + + " FROM survey_of_house sh" + + " LEFT JOIN erp_pgr.EG_USER eu ON sh.cby = eu.id" + + " WHERE sh.isactive = 1" + + " AND DATE(sh.cdate) BETWEEN ? AND ?" + + " AND sh.ward = ?" + + " AND sh.cby = ?" + + " GROUP BY DATE_FORMAT(sh.cdate, '%d-%m-%Y'), sh.cby, eu.FIRST_NAME, eu.USER_NAME, eu.EXTRAFIELD1, eu.EXTRAFIELD2, eu.EXTRAFIELD3, eu.EXTRAFIELD4" + + " ORDER BY sh.cby;"; + + List> result = jdbcMosquitoTemplate.queryForList(sqlQuery, fromDateDB, toDateDB, ward, cby); + response.put("status", 200); + response.put("message", "Ward based list."); + if(result.isEmpty()) { + response.put("message", "No data found."); + } + response.put("data", result); + return Collections.singletonList(response); + } + + @Transactional + public List> userBreedinglistReports(String cby, String selectedDate, String ward){ + + Map response = new HashMap<>(); + DateTimeFormatter inputFmt = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter dbFmt = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + String DateDB = LocalDate.parse(selectedDate, inputFmt).format(dbFmt); + //String toDateDB = LocalDate.parse(toDate, inputFmt).format(dbFmt); + + String sqlQuery = "SELECT " + + " sh.*, " + + " SUM( LENGTH(sh.sourcetype) - LENGTH(REPLACE(sh.sourcetype, ',', '')) + 1 ) AS NoOfBreedingSourceIdentified, " + + "CASE " + + " WHEN COALESCE(SUM(CASE WHEN shd.status <> 'close' THEN 1 ELSE 0 END),0) = 0 " + + " THEN 'Completed'" + + " ELSE 'Pending'" + + " END AS final_status " + + "FROM survey_of_house sh " + + "LEFT JOIN survey_of_house_data shd ON sh.id = shd.surveyid " + + "WHERE sh.isactive = 1 " + + "AND DATE(sh.`cdate`) = ? " + + "AND sh.`ward` = ? " + + "AND sh.`cby` = ? " + + "GROUP BY sh.id " + + "ORDER BY id"; + + List> result = jdbcMosquitoTemplate.queryForList(sqlQuery, DateDB, ward, cby); + response.put("status", 200); + response.put("message", "User based list."); + if(result.isEmpty()) { + response.put("message", "No data found."); + } + response.put("data", result); + return Collections.singletonList(response); + } } diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/pump/controller/PumpsController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/pump/controller/PumpsController.java new file mode 100644 index 0000000..c306515 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/pump/controller/PumpsController.java @@ -0,0 +1,111 @@ +package in.gov.chennaicorporation.mobileservice.pump.controller; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +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.RestController; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.pump.service.PumpsService; + +@RequestMapping("/gccofficialapp/api/pump/") +@RestController("gccofficialappspumps") +public class PumpsController { + + @Autowired + private PumpsService pumpsService; + + @GetMapping(value="/getPumpListForMap") + public List getPumpListFormap( + @RequestParam(value="loginId", required = true) String cby + ){ + return pumpsService.getPumpListForMap(cby); + } + + @GetMapping(value="/getPumpList") + public List getPumpList( + @RequestParam(value="loginId", required = true) String cby + ){ + return pumpsService.getPumpList(cby); + } + + @PostMapping("/savePump") + public List savePump( + @RequestParam(value = "zone", required = true) String zone, + @RequestParam(value = "ward", required = true) String ward, + @RequestParam(value = "street_name", required = false) String street_name, + @RequestParam(value = "street_id", required = false) String street_id, + @RequestParam(value = "latitude", required = true) String latitude, + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "loginId", required = true) String loginId, + @RequestParam(value = "file", required = true) MultipartFile file + ) { + return pumpsService.savePump( + zone, + ward, + street_name, + street_id, + latitude, + longitude, + loginId, + file + ); + } + + @PostMapping("/saveActivity") + public List saveActivity( + @RequestParam(value = "Pump_id", required = true) String Pump_id, + @RequestParam(value = "file", required = true) MultipartFile file, + @RequestParam(value = "video", required = true) MultipartFile video, + @RequestParam(value = "zone", required = true) String zone, + @RequestParam(value = "ward", required = true) String ward, + @RequestParam(value = "street_name", required = false) String street_name, + @RequestParam(value = "street_id", required = false) String street_id, + @RequestParam(value = "latitude", required = true) String latitude, + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "loginId", required = true) String loginId + ) { + return pumpsService.saveActivity( + Pump_id, + file, + video, + zone, + ward, + street_name, + street_id, + latitude, + longitude, + loginId, + "before" + ); + } + + @GetMapping(value="/getZoneSummary") + public List getZoneSummary( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate + ){ + return pumpsService.getZoneSummary(fromDate, toDate); + } + + @GetMapping(value="/getWardSummary") + public List getWardSummary( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate, + @RequestParam(value="zone", required = true) String zone + ){ + return pumpsService.getWardSummary(fromDate, toDate, zone); + } + + @GetMapping(value="/getPumpSummary") + public List getPumpSummary( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate, + @RequestParam(value="ward", required = true) String ward + ){ + return pumpsService.getPumpSummary(fromDate, toDate, ward); + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/pump/service/PumpsService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/pump/service/PumpsService.java new file mode 100644 index 0000000..29b79fd --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/pump/service/PumpsService.java @@ -0,0 +1,701 @@ +package in.gov.chennaicorporation.mobileservice.pump.service; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.SecureRandom; +import java.sql.PreparedStatement; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.env.Environment; +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; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; + +import in.gov.chennaicorporation.mobileservice.gccactivity.service.DateTimeUtil; + +@Service +public class PumpsService { + + private JdbcTemplate jdbcPumpTemplate; + + private final Environment environment; + private String fileBaseUrl; + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int STRING_LENGTH = 15; + private static final Random RANDOM = new SecureRandom(); + + @Autowired + public void setDataSource(@Qualifier("mysqlGccPumpSource") DataSource PumpDataSource) { + this.jdbcPumpTemplate = new JdbcTemplate(PumpDataSource); + } + + @Autowired + public PumpsService(Environment environment) { + this.environment = environment; + this.fileBaseUrl=environment.getProperty("fileBaseUrl"); + } + + public static String generateRandomString() { + StringBuilder result = new StringBuilder(STRING_LENGTH); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + public static String generateRandomFileString(int lenthval) { + StringBuilder result = new StringBuilder(lenthval); + for (int i = 0; i < lenthval; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + private byte[] compressImage(BufferedImage image, float quality) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream); + + ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next(); + writer.setOutput(imageOutputStream); + + ImageWriteParam param = writer.getDefaultWriteParam(); + if (param.canWriteCompressed()) { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(quality); + } + + writer.write(null, new javax.imageio.IIOImage(image, null, null), param); + + writer.dispose(); + imageOutputStream.close(); + + return byteArrayOutputStream.toByteArray(); + } + + // Function to convert date string from dd-MM-yyyy to yyyy-MM-dd + public static String convertDateFormat(String inputDate, int add) { + // Check if the inputDate is not null or blank + if (inputDate != null && !inputDate.isBlank()) { + try { + // Define the input and output date formats + DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + // Parse the input date string to LocalDate + LocalDate date = LocalDate.parse(inputDate, inputFormatter); + + // Add the specified number of days to the date if 'add' is greater than 0 + if (add > 0) { + date = date.plusDays(add); + } + + // Format the date to the new format + return date.format(outputFormatter); + + } catch (DateTimeParseException e) { + // Handle the case where the input date is invalid + System.out.println("Invalid date format: " + inputDate); + return ""; + } + } else { + return ""; + } + } + + public String fileUpload(String name, String id, MultipartFile file, String filetype) { + + int lastInsertId = 0; + // Set the file path where you want to save it + String uploadDirectory = environment.getProperty("file.upload.directory"); + String serviceFolderName = environment.getProperty("pump_foldername"); + var year = DateTimeUtil.getCurrentYear(); + var month = DateTimeUtil.getCurrentMonth(); + var date = DateTimeUtil.getCurrentDay(); + + uploadDirectory = uploadDirectory + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date; + + try { + // Create directory if it doesn't exist + Path directoryPath = Paths.get(uploadDirectory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Datetime string + String datetimetxt = DateTimeUtil.getCurrentDateTime(); + + datetimetxt = datetimetxt + "_"+ generateRandomFileString(6); // Attached Random text + + // File name + String fileName = name + "_" + id + "_" + datetimetxt + "_" + file.getOriginalFilename(); + fileName = fileName.replaceAll("\\s+", ""); // Remove space on filename + + String filePath = uploadDirectory + "/" + fileName; + + String filepath_txt = "/" + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date + "/" + fileName; + + // Create a new Path object + Path path = Paths.get(filePath); + + // Get the bytes of the file + byte[] bytes = file.getBytes(); + + if(filetype.equalsIgnoreCase("image")) + { + // Compress the image + BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); + byte[] compressedBytes = compressImage(image, 0.5f); // Compress with 50% quality + // Write the bytes to the file + Files.write(path, compressedBytes); + } + else { + // Write the bytes to the file + Files.write(path, bytes); + } + // Get current date & time + LocalDateTime now = LocalDateTime.now(); + + // Format date-time (optional) + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + System.out.println("Date: "+ now.format(formatter)); + System.out.println("Activity: Pump"); + System.out.println("File Type: " + filetype); + System.out.println("File Upload Path: " + filePath); + System.out.println("File Path: " + filepath_txt); + + return filepath_txt; + + } catch (IOException e) { + e.printStackTrace(); + System.out.println("Failed to save file " + file.getOriginalFilename()); + return "error"; + } + } + + public String getWardByLoginId(String loginid, String type) { + String sqlQuery = "SELECT `ward` FROM gcc_penalty_hoardings.`hoading_user_list` WHERE `userid` = ? AND `type` = ? LIMIT 1"; + + // Query the database using queryForList + List> results = jdbcPumpTemplate.queryForList(sqlQuery, loginid, type); + + // Check if results is not empty and extract the ward value + if (!results.isEmpty()) { + // Extract the ward value from the first result + return (String) results.get(0).get("ward"); + } + + // Handle the case where no result is found + return "000"; // or return null based on your needs + } + + @Transactional + public List> savePump( + String zone, + String ward, + String street_name, + String street_id, + String latitude, + String longitude, + String inby, + MultipartFile file + ) { + + String filetxt = inby; + + String action = "new_mapping"; + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // For Image + String filetype = "image"; + String activityimg = fileUpload(action, filetxt, file, filetype); + + if ("error".equalsIgnoreCase(activityimg)) { + response.put("status", "error"); + response.put("message", "Pump & Sump new mapping image insert failed."); + result.add(response); + return result; + } + + String insertSqltxt = "INSERT INTO pump_mapped_master(`zone`, `ward`, `road_name`, `road_gisid`, `latitude`, `longitude`, `inby`, `file`) " + + "VALUES (?,?,?,?,?,?,?,?)"; + + String insertSql = insertSqltxt; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcPumpTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"pump_id"}); + int i = 1; + ps.setString(i++, zone); + ps.setString(i++, ward); + ps.setString(i++, street_name); + ps.setString(i++, street_id); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, inby); + ps.setString(i++, activityimg); + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Pump & Sump", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", "Pump & Sump " + action + " data inserted successfully."); + } else { + response.put("Pump & Sump", action + " insertId error!"); + response.put("status", "error"); + response.put("message", "Pump & Sump " + action + " data insert failed."); + } + + result.add(response); + return result; + } + + public List> getPumpListForMap(String loginid) { + + String ward = getWardByLoginId(loginid,"ae"); + + String sqlManhole = "SELECT " + + " d.zone," + + " d.ward," + + " COUNT(*) AS total_pumps," + + " (SELECT COUNT(*) " + + " FROM pump_mapped_master m" + + " WHERE m.isactive = 1 AND m.isdelete = 0 AND m.ward = d.ward) AS total_mapped_points," + + " (COUNT(*) - " + + " (SELECT COUNT(*) " + + " FROM pump_mapped_master m" + + " WHERE m.isactive = 1 AND m.isdelete = 0 AND m.ward = d.ward)" + + " ) AS total_pending_points " + + "FROM pump_master d " + + "WHERE d.isactive = 1 AND d.isdelete = 0" + + " AND d.ward = ? " + + "GROUP BY d.ward " + + "ORDER BY d.ward"; + List> Pumps = jdbcPumpTemplate.queryForList(sqlManhole, ward); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Pump & Sump Map List."); + response.put("data", Pumps); + + return Collections.singletonList(response); + } + + public List> getPumpList(String loginid) { + + String ward = getWardByLoginId(loginid,"ae"); + + // 1. Fetch all Pump & Sump for the given SWDID + String sqlManhole = "SELECT *, " + + "CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `file`) AS img_file_url " + + " FROM pump_mapped_master WHERE ward = ? AND `isactive`=1 AND `isdelete`=0"; + List> Pumps = jdbcPumpTemplate.queryForList(sqlManhole, ward); + + List> finalList = new ArrayList<>(); + + for (Map Pump : Pumps) { + Map PumpResponse = new HashMap<>(); + PumpResponse.putAll(Pump); + + // 2. Fetch before activity + String sqlBefore = "SELECT *," + + "CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `img_file`) AS img_file_url," + + "CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `video_file`) AS video_file_url " + + "FROM before_activity WHERE pump_id = ? " + + "AND indate >= CURDATE() " + + "AND indate < CURDATE() + INTERVAL 1 DAY " + + "AND isactive=1 AND isdelete=0"; + List> beforeActivities = jdbcPumpTemplate.queryForList(sqlBefore, + Pump.get("pump_id")); + + Map beforeData = new HashMap<>(); + if (!beforeActivities.isEmpty()) { + beforeData.put("status", "Completed"); + beforeData.put("details", beforeActivities); + } else { + beforeData.put("status", "Pending"); + beforeData.put("details", Collections.emptyList()); + } + + // 4. Overall Pump & Sump Point status + String overallStatus = (!beforeActivities.isEmpty()) ? "Completed" : "Pending"; + PumpResponse.put("status", overallStatus); + PumpResponse.put("before", beforeData); + + finalList.add(PumpResponse); + } + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Dispoasl List."); + response.put("data", finalList); + + return Collections.singletonList(response); + } + + @Transactional + public List> saveActivity( + String pump_id, + MultipartFile file, + MultipartFile video, + String zone, + String ward, + String street_name, + String street_id, + String latitude, + String longitude, + String inby, + String action + ) { + + String filetxt =pump_id; + + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // For Image + String filetype = "image"; + String activityimg = fileUpload(action, filetxt, file, filetype); + + if ("error".equalsIgnoreCase(activityimg)) { + response.put("status", "error"); + response.put("message", "Pump & Sump activity image insert failed."); + result.add(response); + return result; + } + + // For Video + filetype = "video"; + String activityvideo = fileUpload(action, filetxt, video, filetype); + + if ("error".equalsIgnoreCase(activityvideo)) { + response.put("status", "error"); + response.put("message", "Pump & Sump activity video insert failed."); + result.add(response); + return result; + } + + String insertBeforeSql = "INSERT INTO before_activity(pump_id, img_file, video_file, zone, ward, street_name, street_id, latitude, longitude, inby) " + + "VALUES (?,?,?,?,?,?,?,?,?,?)"; + + /* + String insertAfterSql = "INSERT INTO after_activity(pump_id, file, zone, ward, street_name, street_id, latitude, longitude, inby, before_activity_id, clean_type) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"; + + String insertSql = "before".equalsIgnoreCase(action) ? insertBeforeSql : insertAfterSql; + */ + + String insertSql = insertBeforeSql; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcPumpTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"activity_id"}); + int i = 1; + ps.setString(i++, pump_id); + ps.setString(i++, activityimg); + ps.setString(i++, activityvideo); + ps.setString(i++, zone); + ps.setString(i++, ward); + ps.setString(i++, street_name); + ps.setString(i++, street_id); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, inby); +/* + if ("after".equalsIgnoreCase(action)) { + ps.setString(i++, beforeActivityId); + ps.setString(i++, clean_type); + } +*/ + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Pump & Sump", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", "Pump & Sump " + action + " activity inserted successfully."); + } else { + response.put("Pump & Sump", action + " insertId error!"); + response.put("status", "error"); + response.put("message", "Pump & Sump " + action + " activity insert failed."); + } + + result.add(response); + return result; + } + + @Transactional(readOnly = true) + public List> getZoneSummary(String fromDate, String toDate) { + + fromDate = convertDateFormat(fromDate, 0); + toDate = convertDateFormat(toDate, 0); + + String sql = + "SELECT " + + " z.zone, " + + " COALESCE(dm.total_pump_points, 0) AS total_pump_points, " + + " COALESCE(mm.total_mapped_points, 0) AS total_mapped_points, " + + " COALESCE(COUNT(DISTINCT (b.pump_id), 0)) AS completed_days " + + "FROM (" + + " SELECT DISTINCT zone FROM pump_master WHERE isactive=1 AND isdelete=0" + + ") z " + + "LEFT JOIN (" + + " SELECT zone, COUNT(*) AS total_pump_points " + + " FROM pump_master " + + " WHERE isactive=1 AND isdelete=0 " + + " GROUP BY zone" + + ") dm ON z.zone = dm.zone " + + "LEFT JOIN (" + + " SELECT zone, COUNT(*) AS total_mapped_points " + + " FROM pump_mapped_master " + + " WHERE isactive=1 AND isdelete=0 " + + " GROUP BY zone" + + ") mm ON z.zone = mm.zone " + + "LEFT JOIN pump_mapped_master dmm ON dmm.zone = z.zone AND dmm.isactive=1 AND dmm.isdelete=0 " + + "LEFT JOIN before_activity b ON dmm.pump_id = b.pump_id " + + " AND b.isactive=1 AND b.isdelete=0 " + + " AND b.indate >= ? AND b.indate < DATE_ADD(?, INTERVAL 1 DAY) " + + "GROUP BY z.zone, dm.total_pump_points, mm.total_mapped_points " + + "ORDER BY z.zone"; + + List> results = jdbcPumpTemplate.queryForList(sql, fromDate, toDate); + + long totalDays = ChronoUnit.DAYS.between( + LocalDate.parse(fromDate), + LocalDate.parse(toDate) + ) + 1; + + List> finalList = new ArrayList<>(); + + long grandTotalPumps = 0; + long grandTotalMappedPoints = 0; + long grandCompletedDays = 0; + long grandPendingDays = 0; + + + for (Map row : results) { + Map report = new LinkedHashMap<>(); + long completed = ((Number) row.get("completed_days")).longValue(); + long totalPumps = ((Number) row.get("total_pump_points")).longValue(); + long totalMappedPoints = ((Number) row.get("total_mapped_points")).longValue(); + + long totalDays_final = (totalDays*totalMappedPoints); + + report.put("zone", row.get("zone")); + report.put("totalPumps", totalPumps); + report.put("totalMappedPoints", totalMappedPoints); + report.put("totalDays", totalDays_final); + report.put("completedDays", completed); + report.put("pendingDays", (totalDays_final - completed)); + + finalList.add(report); + + // accumulate grand totals + grandTotalPumps += totalPumps; + grandTotalMappedPoints += totalMappedPoints; + grandCompletedDays += completed; + grandPendingDays +=(totalDays_final - completed); + } + + // add grand total row + Map grandTotalRow = new LinkedHashMap<>(); + grandTotalRow.put("zone", "TOTAL"); + grandTotalRow.put("totalPumps", grandTotalPumps); + grandTotalRow.put("totalMappedPoints", grandTotalMappedPoints); + grandTotalRow.put("totalDays", totalDays); + grandTotalRow.put("completedDays", grandCompletedDays); + grandTotalRow.put("pendingDays", grandPendingDays); // total pending across all wards + + finalList.add(grandTotalRow); + + return finalList; + } + + @Transactional(readOnly = true) + public List> getWardSummary(String fromDate, String toDate, String zone) { + + fromDate = convertDateFormat(fromDate, 0); + toDate = convertDateFormat(toDate, 0); + + String sql = + "SELECT " + + " w.ward, " + + " COALESCE(dm.total_pump_points, 0) AS total_pump_points, " + + " COALESCE(mm.total_mapped_points, 0) AS total_mapped_points, " + + " COALESCE(COUNT(DISTINCT (b.pump_id), 0)) AS completed_days " + + "FROM (" + + " SELECT DISTINCT ward FROM pump_master WHERE isactive=1 AND isdelete=0 AND zone=?" + + ") w " + + "LEFT JOIN (" + + " SELECT ward, COUNT(*) AS total_pump_points " + + " FROM pump_master " + + " WHERE isactive=1 AND isdelete=0 AND zone=? " + + " GROUP BY ward" + + ") dm ON w.ward = dm.ward " + + "LEFT JOIN (" + + " SELECT ward, COUNT(*) AS total_mapped_points " + + " FROM pump_mapped_master " + + " WHERE isactive=1 AND isdelete=0 AND zone=? " + + " GROUP BY ward" + + ") mm ON w.ward = mm.ward " + + "LEFT JOIN pump_mapped_master dmm ON dmm.ward = w.ward AND dmm.isactive=1 AND dmm.isdelete=0 " + + "LEFT JOIN before_activity b ON dmm.pump_id = b.pump_id " + + " AND b.isactive=1 AND b.isdelete=0 " + + " AND b.indate >= ? AND b.indate < DATE_ADD(?, INTERVAL 1 DAY) " + + "GROUP BY w.ward, dm.total_pump_points, mm.total_mapped_points " + + "ORDER BY w.ward"; + + List> results = jdbcPumpTemplate.queryForList( + sql, zone, zone, zone, fromDate, toDate + ); + + long totalDays = ChronoUnit.DAYS.between( + LocalDate.parse(fromDate), + LocalDate.parse(toDate) + ) + 1; + + List> finalList = new ArrayList<>(); + + long grandTotalPumps = 0; + long grandTotalMappedPoints = 0; + long grandCompletedDays = 0; + long grandPendingDays = 0; + + for (Map row : results) { + Map report = new LinkedHashMap<>(); + long completed = ((Number) row.get("completed_days")).longValue(); + long totalPumps = ((Number) row.get("total_pump_points")).longValue(); + long totalMappedPoints = ((Number) row.get("total_mapped_points")).longValue(); + long totalDays_final = (totalDays*totalMappedPoints); + + report.put("ward", row.get("ward")); + report.put("totalPumps", totalPumps); + report.put("totalMappedPoints", totalMappedPoints); + report.put("totalDays", totalDays_final); + report.put("completedDays", completed); + report.put("pendingDays", (totalDays_final - completed)); + + finalList.add(report); + + // accumulate grand totals + grandTotalPumps += totalPumps; + grandTotalMappedPoints += totalMappedPoints; + grandCompletedDays += completed; + grandPendingDays +=(totalDays_final - completed); + } + + // add grand total row + Map grandTotalRow = new LinkedHashMap<>(); + grandTotalRow.put("ward", "TOTAL"); + grandTotalRow.put("totalPumps", grandTotalPumps); + grandTotalRow.put("totalMappedPoints", grandTotalMappedPoints); + grandTotalRow.put("totalDays", totalDays); + grandTotalRow.put("completedDays", grandCompletedDays); + grandTotalRow.put("pendingDays", grandPendingDays); // total pending across all wards + + finalList.add(grandTotalRow); + + return finalList; + } + + public List> getPumpSummary(String fromDate, String toDate, String ward) { + + fromDate = convertDateFormat(fromDate,0); + toDate = convertDateFormat(toDate,0); + + // SQL: count completed days per Pump & Sump point + String sql = "SELECT d.road_name, d.pump_id, COUNT(DISTINCT DATE(b.indate)) AS completedDays " + + "FROM pump_mapped_master d " + + "LEFT JOIN before_activity b ON d.pump_id = b.pump_id " + + "AND b.indate >= ? AND b.indate < DATE_ADD(?, INTERVAL 1 DAY) " + + "AND b.isactive=1 AND b.isdelete=0 " + + "WHERE d.isactive=1 AND d.isdelete=0 AND d.ward=? " + + "GROUP BY d.road_name, d.pump_id ORDER BY d.road_name"; + + List> results = jdbcPumpTemplate.queryForList(sql, fromDate, toDate, ward); + + long totalDays = ChronoUnit.DAYS.between( + LocalDate.parse(fromDate), + LocalDate.parse(toDate) + ) + 1; + + List> finalList = new ArrayList<>(); + + //long grandTotalPumps = 0; + //long grandTotalMappedPoints = 0; + long grandCompletedDays = 0; + long grandPendingDays = 0; + + for (Map row : results) { + Map Report = new HashMap<>(); + long completed = ((Number) row.get("completedDays")).longValue(); + //long totalPumps = ((Number) row.get("total_pump_points")).longValue(); + //long totalMappedPoints = ((Number) row.get("total_mapped_points")).longValue(); + long totalDays_final = (totalDays*1); + + Report.put("road_name", row.get("road_name")); + Report.put("pump_id", row.get("pump_id")); + Report.put("totalDays", totalDays_final); + Report.put("completed", completed); + Report.put("pending", totalDays_final - completed); + finalList.add(Report); + + // accumulate grand totals + //grandTotalPumps += totalPumps; + //grandTotalMappedPoints += totalMappedPoints; + grandCompletedDays += completed; + grandPendingDays +=(totalDays_final - completed); + } + + // add grand total row + Map grandTotalRow = new LinkedHashMap<>(); + grandTotalRow.put("road_name", "TOTAL"); + //grandTotalRow.put("totalPumps", grandTotalPumps); + //grandTotalRow.put("totalMappedPoints", grandTotalMappedPoints); + grandTotalRow.put("pump_id", 0); + grandTotalRow.put("totalDays", totalDays); + grandTotalRow.put("completed", grandCompletedDays); + grandTotalRow.put("pending", grandPendingDays); // total pending across all wards + + //finalList.add(grandTotalRow); + + return finalList; + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/railwayCulverts/controller/CulvertsController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/railwayCulverts/controller/CulvertsController.java new file mode 100644 index 0000000..10719ea --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/railwayCulverts/controller/CulvertsController.java @@ -0,0 +1,126 @@ +package in.gov.chennaicorporation.mobileservice.railwayCulverts.controller; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +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.RestController; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.railwayCulverts.service.CulvertsService; + +@RequestMapping("/gccofficialapp/api/railwayculvert/") +@RestController("gccofficialappsrailwayculvert") +public class CulvertsController { + + @Autowired + private CulvertsService culvertsService; + + @GetMapping(value="/getCulvertPointListForMap") + public List getCulvertPointListFormap( + @RequestParam(value="loginId", required = true) String cby + ){ + return culvertsService.getCulvertPointListForMap(cby); + } + + @GetMapping(value="/getCulvertPointList") + public List getCulvertPointList( + @RequestParam(value="loginId", required = true) String cby + ){ + return culvertsService.getCulvertPointList(cby); + } + + @PostMapping("/saveCulvertPoint") + public List saveCulvertPoint( + @RequestParam(value = "zone", required = true) String zone, + @RequestParam(value = "ward", required = true) String ward, + @RequestParam(value = "street_name", required = false) String street_name, + @RequestParam(value = "street_id", required = false) String street_id, + @RequestParam(value = "latitude", required = true) String latitude, + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "loginId", required = true) String loginId, + @RequestParam(value = "file", required = true) MultipartFile file + ) { + return culvertsService.saveCulvertPoint( + zone, + ward, + street_name, + street_id, + latitude, + longitude, + loginId, + file + ); + } + + @PostMapping("/saveActivity") + public List saveActivity( + @RequestParam(value = "culvert_id", required = true) String culvert_id, + //@RequestParam(value = "rust_painting", required = true) String rust_painting, + //@RequestParam(value = "greasing", required = true) String greasing, + @RequestParam(value = "file", required = true) MultipartFile file, + @RequestParam(value = "video", required = true) MultipartFile video, + @RequestParam(value = "zone", required = true) String zone, + @RequestParam(value = "ward", required = true) String ward, + @RequestParam(value = "street_name", required = false) String street_name, + @RequestParam(value = "street_id", required = false) String street_id, + @RequestParam(value = "latitude", required = true) String latitude, + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "loginId", required = true) String loginId + ) { + return culvertsService.saveActivity( + culvert_id, + //rust_painting, + //greasing, + file, + video, + zone, + ward, + street_name, + street_id, + latitude, + longitude, + loginId, + "before" + ); + } + + @GetMapping(value="/getZoneSummary") + public List getZoneSummary( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate + ){ + return culvertsService.getZoneSummary(fromDate, toDate); + } + + @GetMapping(value="/getWardSummary") + public List getWardSummary( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate, + @RequestParam(value="zone", required = true) String zone + ){ + return culvertsService.getWardSummary(fromDate, toDate, zone); + } + + @GetMapping(value="/getCulvertPointSummary") + public List getCulvertPointSummary( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate, + @RequestParam(value="ward", required = true) String ward + ){ + return culvertsService.getCulvertPointSummary(fromDate, toDate, ward); + } + + @PostMapping(value="/saveWhatsAppResponse") + public List saveWhatsAppResponse( + @RequestParam(value="mobilenumber", required = true) String mobilenumber, + @RequestParam(value="response", required = true) String response, + @RequestParam(value="event", required = true) String event + ){ + return culvertsService.saveWhatsAppResponse(mobilenumber, response, event); + } + +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/railwayCulverts/service/CulvertsService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/railwayCulverts/service/CulvertsService.java new file mode 100644 index 0000000..13caf91 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/railwayCulverts/service/CulvertsService.java @@ -0,0 +1,723 @@ +package in.gov.chennaicorporation.mobileservice.railwayCulverts.service; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.SecureRandom; +import java.sql.PreparedStatement; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.env.Environment; +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; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.gccactivity.service.DateTimeUtil; + +@Service +public class CulvertsService { +private JdbcTemplate jdbcCulvertTemplate; + + private final Environment environment; + private String fileBaseUrl; + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int STRING_LENGTH = 15; + private static final Random RANDOM = new SecureRandom(); + + @Autowired + public void setDataSource(@Qualifier("mysqlGccRailwayCulvertSource") DataSource CulvertDataSource) { + this.jdbcCulvertTemplate = new JdbcTemplate(CulvertDataSource); + } + + @Autowired + public CulvertsService(Environment environment) { + this.environment = environment; + this.fileBaseUrl=environment.getProperty("fileBaseUrl"); + } + + public static String generateRandomString() { + StringBuilder result = new StringBuilder(STRING_LENGTH); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + public static String generateRandomFileString(int lenthval) { + StringBuilder result = new StringBuilder(lenthval); + for (int i = 0; i < lenthval; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + private byte[] compressImage(BufferedImage image, float quality) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream); + + ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next(); + writer.setOutput(imageOutputStream); + + ImageWriteParam param = writer.getDefaultWriteParam(); + if (param.canWriteCompressed()) { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(quality); + } + + writer.write(null, new javax.imageio.IIOImage(image, null, null), param); + + writer.dispose(); + imageOutputStream.close(); + + return byteArrayOutputStream.toByteArray(); + } + + // Function to convert date string from dd-MM-yyyy to yyyy-MM-dd + public static String convertDateFormat(String inputDate, int add) { + // Check if the inputDate is not null or blank + if (inputDate != null && !inputDate.isBlank()) { + try { + // Define the input and output date formats + DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + // Parse the input date string to LocalDate + LocalDate date = LocalDate.parse(inputDate, inputFormatter); + + // Add the specified number of days to the date if 'add' is greater than 0 + if (add > 0) { + date = date.plusDays(add); + } + + // Format the date to the new format + return date.format(outputFormatter); + + } catch (DateTimeParseException e) { + // Handle the case where the input date is invalid + System.out.println("Invalid date format: " + inputDate); + return ""; + } + } else { + return ""; + } + } + + public String fileUpload(String name, String id, MultipartFile file, String filetype) { + + int lastInsertId = 0; + // Set the file path where you want to save it + String uploadDirectory = environment.getProperty("file.upload.directory"); + String serviceFolderName = environment.getProperty("culvert_foldername"); + var year = DateTimeUtil.getCurrentYear(); + var month = DateTimeUtil.getCurrentMonth(); + var date = DateTimeUtil.getCurrentDay(); + + uploadDirectory = uploadDirectory + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date; + + try { + // Create directory if it doesn't exist + Path directoryPath = Paths.get(uploadDirectory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Datetime string + String datetimetxt = DateTimeUtil.getCurrentDateTime(); + + datetimetxt = datetimetxt + "_"+ generateRandomFileString(6); // Attached Random text + + // File name + String fileName = name + "_" + id + "_" + datetimetxt + "_" + file.getOriginalFilename(); + fileName = fileName.replaceAll("\\s+", ""); // Remove space on filename + + String filePath = uploadDirectory + "/" + fileName; + + String filepath_txt = "/" + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date + "/" + fileName; + + // Create a new Path object + Path path = Paths.get(filePath); + + // Get the bytes of the file + byte[] bytes = file.getBytes(); + + if(filetype.equalsIgnoreCase("image")) + { + // Compress the image + BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); + byte[] compressedBytes = compressImage(image, 0.5f); // Compress with 50% quality + // Write the bytes to the file + Files.write(path, compressedBytes); + } + else { + // Write the bytes to the file + Files.write(path, bytes); + } + // Get current date & time + LocalDateTime now = LocalDateTime.now(); + + // Format date-time (optional) + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + System.out.println("Date: "+ now.format(formatter)); + System.out.println("Activity: CulvertPoint"); + System.out.println("File Type: " + filetype); + System.out.println("File Upload Path: " + filePath); + System.out.println("File Path: " + filepath_txt); + + return filepath_txt; + + } catch (IOException e) { + e.printStackTrace(); + System.out.println("Failed to save file " + file.getOriginalFilename()); + return "error"; + } + } + + public String getWardByLoginId(String loginid, String type) { + String sqlQuery = "SELECT `ward` FROM gcc_penalty_hoardings.`hoading_user_list` WHERE `userid` = ? AND `type` = ? LIMIT 1"; + + // Query the database using queryForList + List> results = jdbcCulvertTemplate.queryForList(sqlQuery, loginid, type); + + // Check if results is not empty and extract the ward value + if (!results.isEmpty()) { + // Extract the ward value from the first result + return (String) results.get(0).get("ward"); + } + + // Handle the case where no result is found + return "000"; // or return null based on your needs + } + + @Transactional + public List> saveCulvertPoint( + String zone, + String ward, + String street_name, + String street_id, + String latitude, + String longitude, + String inby, + MultipartFile file + ) { + + String filetxt = inby; + + String action = "new_mapping"; + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // For Image + String filetype = "image"; + String activityimg = fileUpload(action, filetxt, file, filetype); + + if ("error".equalsIgnoreCase(activityimg)) { + response.put("status", "error"); + response.put("message", "Culvert Point new mapping image insert failed."); + result.add(response); + return result; + } + + String insertSqltxt = "INSERT INTO culvert_mapped_master(`zone`, `ward`, `road_name`, `road_gisid`, `latitude`, `longitude`, `inby`, `file`) " + + "VALUES (?,?,?,?,?,?,?,?)"; + + String insertSql = insertSqltxt; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcCulvertTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"culvert_id"}); + int i = 1; + ps.setString(i++, zone); + ps.setString(i++, ward); + ps.setString(i++, street_name); + ps.setString(i++, street_id); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, inby); + ps.setString(i++, activityimg); + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Culvert Point", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", "Culvert Point " + action + " data inserted successfully."); + } else { + response.put("Culvert Point", action + " insertId error!"); + response.put("status", "error"); + response.put("message", "Culvert Point " + action + " data insert failed."); + } + + result.add(response); + return result; + } + + public List> getCulvertPointListForMap(String loginid) { + + String ward = getWardByLoginId(loginid,"ae"); + + String sqlManhole = "SELECT " + + " d.zone," + + " d.ward," + + " COUNT(*) AS total_culvert_points," + + " (SELECT COUNT(*) " + + " FROM culvert_mapped_master m" + + " WHERE m.isactive = 1 AND m.isdelete = 0 AND m.ward = d.ward) AS total_mapped_points," + + " (COUNT(*) - " + + " (SELECT COUNT(*) " + + " FROM culvert_mapped_master m" + + " WHERE m.isactive = 1 AND m.isdelete = 0 AND m.ward = d.ward)" + + " ) AS total_pending_points " + + "FROM culvert_master d " + + "WHERE d.isactive = 1 AND d.isdelete = 0" + + " AND d.ward = ? " + + "GROUP BY d.ward " + + "ORDER BY d.ward"; + List> culverts = jdbcCulvertTemplate.queryForList(sqlManhole, ward); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Dispoasl Map List."); + response.put("data", culverts); + + return Collections.singletonList(response); + } + + public List> getCulvertPointList(String loginid) { + + String ward = getWardByLoginId(loginid,"ae"); + + // 1. Fetch all Culvert Points for the given SWDID + String sqlManhole = "SELECT *, " + + "CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `file`) AS img_file_url " + + " FROM culvert_mapped_master WHERE ward = ? AND `isactive`=1 AND `isdelete`=0"; + List> culverts = jdbcCulvertTemplate.queryForList(sqlManhole, ward); + + List> finalList = new ArrayList<>(); + + for (Map culvert : culverts) { + Map culvertResponse = new HashMap<>(); + culvertResponse.putAll(culvert); // add all Culvert point columns + + // 2. Fetch before activity + String sqlBefore = "SELECT *," + + "CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `img_file`) AS img_file_url," + + "CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `video_file`) AS video_file_url " + + "FROM before_activity WHERE culvert_id = ? " + + "AND indate >= CURDATE() " + + "AND indate < CURDATE() + INTERVAL 1 DAY " + + "AND isactive=1 AND isdelete=0"; + List> beforeActivities = jdbcCulvertTemplate.queryForList(sqlBefore, + culvert.get("culvert_id")); + + Map beforeData = new HashMap<>(); + if (!beforeActivities.isEmpty()) { + beforeData.put("status", "Completed"); + beforeData.put("details", beforeActivities); + } else { + beforeData.put("status", "Pending"); + beforeData.put("details", Collections.emptyList()); + } + + // 4. Overall Culvert Point status + String overallStatus = (!beforeActivities.isEmpty()) ? "Completed" : "Pending"; + culvertResponse.put("status", overallStatus); + culvertResponse.put("before", beforeData); + + finalList.add(culvertResponse); + } + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Dispoasl List."); + response.put("data", finalList); + + return Collections.singletonList(response); + } + + @Transactional + public List> saveActivity( + String culvert_id, + //String rust_painting, + //String greasing, + MultipartFile file, + MultipartFile video, + String zone, + String ward, + String street_name, + String street_id, + String latitude, + String longitude, + String inby, + String action + ) { + + String filetxt =culvert_id; + + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // For Image + String filetype = "image"; + String activityimg = fileUpload(action, filetxt, file, filetype); + + if ("error".equalsIgnoreCase(activityimg)) { + response.put("status", "error"); + response.put("message", "Culvert Point activity image insert failed."); + result.add(response); + return result; + } + + // For Video + filetype = "video"; + String activityvideo = fileUpload(action, filetxt, video, filetype); + + if ("error".equalsIgnoreCase(activityvideo)) { + response.put("status", "error"); + response.put("message", "Culvert Point activity video insert failed."); + result.add(response); + return result; + } + + String insertBeforeSql = "INSERT INTO before_activity(culvert_id, img_file, video_file, zone, ward, " + + "street_name, street_id, latitude, longitude, inby) " + + "VALUES (?,?,?,?,?,?,?,?,?,?)"; + + String insertSql = insertBeforeSql; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcCulvertTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"activity_id"}); + int i = 1; + ps.setString(i++, culvert_id); + ps.setString(i++, activityimg); + ps.setString(i++, activityvideo); + ps.setString(i++, zone); + ps.setString(i++, ward); + ps.setString(i++, street_name); + ps.setString(i++, street_id); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, inby); + //ps.setString(i++, rust_painting); + //ps.setString(i++, greasing); + + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Culvert Point", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", "Culvert Point " + action + " activity inserted successfully."); + } else { + response.put("Culvert Point", action + " insertId error!"); + response.put("status", "error"); + response.put("message", "Culvert Point " + action + " activity insert failed."); + } + + result.add(response); + return result; + } + + @Transactional(readOnly = true) + public List> getZoneSummary(String fromDate, String toDate) { + + fromDate = convertDateFormat(fromDate, 0); + toDate = convertDateFormat(toDate, 0); + + String sql = + "SELECT " + + " z.zone, " + + " COALESCE(dm.total_culvert_points, 0) AS total_culvert_points, " + + " COALESCE(mm.total_mapped_points, 0) AS total_mapped_points, " + + " COALESCE(COUNT(DISTINCT (b.culvert_id), 0)) AS completed_days " + + "FROM (" + + " SELECT DISTINCT zone FROM culvert_master WHERE isactive=1 AND isdelete=0" + + ") z " + + "LEFT JOIN (" + + " SELECT zone, COUNT(*) AS total_culvert_points " + + " FROM culvert_master " + + " WHERE isactive=1 AND isdelete=0 " + + " GROUP BY zone" + + ") dm ON z.zone = dm.zone " + + "LEFT JOIN (" + + " SELECT zone, COUNT(*) AS total_mapped_points " + + " FROM culvert_mapped_master " + + " WHERE isactive=1 AND isdelete=0 " + + " GROUP BY zone" + + ") mm ON z.zone = mm.zone " + + "LEFT JOIN culvert_mapped_master dmm ON dmm.zone = z.zone AND dmm.isactive=1 AND dmm.isdelete=0 " + + "LEFT JOIN before_activity b ON dmm.culvert_id = b.culvert_id " + + " AND b.isactive=1 AND b.isdelete=0 " + + " AND b.indate >= ? AND b.indate < DATE_ADD(?, INTERVAL 1 DAY) " + + "GROUP BY z.zone, dm.total_culvert_points, mm.total_mapped_points " + + "ORDER BY z.zone"; + + List> results = jdbcCulvertTemplate.queryForList(sql, fromDate, toDate); + + long totalDays = ChronoUnit.DAYS.between( + LocalDate.parse(fromDate), + LocalDate.parse(toDate) + ) + 1; + + List> finalList = new ArrayList<>(); + + long grandTotalculverts = 0; + long grandTotalMappedPoints = 0; + long grandCompletedDays = 0; + long grandPendingDays = 0; + + + for (Map row : results) { + Map report = new LinkedHashMap<>(); + long completed = ((Number) row.get("completed_days")).longValue(); + long totalculverts = ((Number) row.get("total_culvert_points")).longValue(); + long totalMappedPoints = ((Number) row.get("total_mapped_points")).longValue(); + + long totalDays_final = (totalDays*totalMappedPoints); + + report.put("zone", row.get("zone")); + report.put("totalculverts", totalculverts); + report.put("totalMappedPoints", totalMappedPoints); + report.put("totalDays", totalDays_final); + report.put("completedDays", completed); + report.put("pendingDays", (totalDays_final - completed)); + + finalList.add(report); + + // accumulate grand totals + grandTotalculverts += totalculverts; + grandTotalMappedPoints += totalMappedPoints; + grandCompletedDays += completed; + grandPendingDays +=(totalDays_final - completed); + } + + // add grand total row + Map grandTotalRow = new LinkedHashMap<>(); + grandTotalRow.put("zone", "TOTAL"); + grandTotalRow.put("totalculverts", grandTotalculverts); + grandTotalRow.put("totalMappedPoints", grandTotalMappedPoints); + grandTotalRow.put("totalDays", totalDays); + grandTotalRow.put("completedDays", grandCompletedDays); + grandTotalRow.put("pendingDays", grandPendingDays); // total pending across all wards + + finalList.add(grandTotalRow); + + return finalList; + } + + @Transactional(readOnly = true) + public List> getWardSummary(String fromDate, String toDate, String zone) { + + fromDate = convertDateFormat(fromDate, 0); + toDate = convertDateFormat(toDate, 0); + + String sql = + "SELECT " + + " w.ward, " + + " COALESCE(dm.total_culvert_points, 0) AS total_culvert_points, " + + " COALESCE(mm.total_mapped_points, 0) AS total_mapped_points, " + + " COALESCE(COUNT(DISTINCT (b.culvert_id), 0)) AS completed_days " + + "FROM (" + + " SELECT DISTINCT ward FROM culvert_master WHERE isactive=1 AND isdelete=0 AND zone=?" + + ") w " + + "LEFT JOIN (" + + " SELECT ward, COUNT(*) AS total_culvert_points " + + " FROM culvert_master " + + " WHERE isactive=1 AND isdelete=0 AND zone=? " + + " GROUP BY ward" + + ") dm ON w.ward = dm.ward " + + "LEFT JOIN (" + + " SELECT ward, COUNT(*) AS total_mapped_points " + + " FROM culvert_mapped_master " + + " WHERE isactive=1 AND isdelete=0 AND zone=? " + + " GROUP BY ward" + + ") mm ON w.ward = mm.ward " + + "LEFT JOIN culvert_mapped_master dmm ON dmm.ward = w.ward AND dmm.isactive=1 AND dmm.isdelete=0 " + + "LEFT JOIN before_activity b ON dmm.culvert_id = b.culvert_id " + + " AND b.isactive=1 AND b.isdelete=0 " + + " AND b.indate >= ? AND b.indate < DATE_ADD(?, INTERVAL 1 DAY) " + + "GROUP BY w.ward, dm.total_culvert_points, mm.total_mapped_points " + + "ORDER BY w.ward"; + + List> results = jdbcCulvertTemplate.queryForList( + sql, zone, zone, zone, fromDate, toDate + ); + + long totalDays = ChronoUnit.DAYS.between( + LocalDate.parse(fromDate), + LocalDate.parse(toDate) + ) + 1; + + List> finalList = new ArrayList<>(); + + long grandTotalculverts = 0; + long grandTotalMappedPoints = 0; + long grandCompletedDays = 0; + long grandPendingDays = 0; + + for (Map row : results) { + Map report = new LinkedHashMap<>(); + long completed = ((Number) row.get("completed_days")).longValue(); + long totalculverts = ((Number) row.get("total_culvert_points")).longValue(); + long totalMappedPoints = ((Number) row.get("total_mapped_points")).longValue(); + long totalDays_final = (totalDays*totalMappedPoints); + + report.put("ward", row.get("ward")); + report.put("totalculverts", totalculverts); + report.put("totalMappedPoints", totalMappedPoints); + report.put("totalDays", totalDays_final); + report.put("completedDays", completed); + report.put("pendingDays", (totalDays_final - completed)); + + finalList.add(report); + + // accumulate grand totals + grandTotalculverts += totalculverts; + grandTotalMappedPoints += totalMappedPoints; + grandCompletedDays += completed; + grandPendingDays +=(totalDays_final - completed); + } + + // add grand total row + Map grandTotalRow = new LinkedHashMap<>(); + grandTotalRow.put("ward", "TOTAL"); + grandTotalRow.put("totalculverts", grandTotalculverts); + grandTotalRow.put("totalMappedPoints", grandTotalMappedPoints); + grandTotalRow.put("totalDays", totalDays); + grandTotalRow.put("completedDays", grandCompletedDays); + grandTotalRow.put("pendingDays", grandPendingDays); // total pending across all wards + + finalList.add(grandTotalRow); + + return finalList; + } + + public List> getCulvertPointSummary(String fromDate, String toDate, String ward) { + + fromDate = convertDateFormat(fromDate,0); + toDate = convertDateFormat(toDate,0); + + // SQL: count completed days per Culvert point + String sql = "SELECT d.road_name, d.culvert_id, COUNT(DISTINCT DATE(b.indate)) AS completedDays " + + "FROM culvert_mapped_master d " + + "LEFT JOIN before_activity b ON d.culvert_id = b.culvert_id " + + "AND b.indate >= ? AND b.indate < DATE_ADD(?, INTERVAL 1 DAY) " + + "AND b.isactive=1 AND b.isdelete=0 " + + "WHERE d.isactive=1 AND d.isdelete=0 AND d.ward=? " + + "GROUP BY d.road_name, d.culvert_id ORDER BY d.road_name"; + + List> results = jdbcCulvertTemplate.queryForList(sql, fromDate, toDate, ward); + + long totalDays = ChronoUnit.DAYS.between( + LocalDate.parse(fromDate), + LocalDate.parse(toDate) + ) + 1; + + List> finalList = new ArrayList<>(); + + //long grandTotalculverts = 0; + //long grandTotalMappedPoints = 0; + long grandCompletedDays = 0; + long grandPendingDays = 0; + + for (Map row : results) { + Map Report = new HashMap<>(); + long completed = ((Number) row.get("completedDays")).longValue(); + long totalDays_final = (totalDays*1); + + Report.put("road_name", row.get("road_name")); + Report.put("culvert_id", row.get("culvert_id")); + Report.put("totalDays", totalDays_final); + Report.put("completed", completed); + Report.put("pending", totalDays_final - completed); + finalList.add(Report); + + grandCompletedDays += completed; + grandPendingDays +=(totalDays_final - completed); + } + + // add grand total row + Map grandTotalRow = new LinkedHashMap<>(); + grandTotalRow.put("road_name", "TOTAL"); + grandTotalRow.put("culvert_id", 0); + grandTotalRow.put("totalDays", totalDays); + grandTotalRow.put("completed", grandCompletedDays); + grandTotalRow.put("pending", grandPendingDays); // total pending across all wards + + //finalList.add(grandTotalRow); + + return finalList; + } + + public List> saveWhatsAppResponse(String mobilenumber, String response, String event) { + + Map apiresponse = new HashMap<>(); + List> result = new ArrayList<>(); + + String insertBeforeSql = "INSERT INTO whatsapp_response(mobilenumber,response,event) " + + "VALUES (?,?,?)"; + + String insertSql = insertBeforeSql; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcCulvertTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"activity_id"}); + int i = 1; + ps.setString(i++, mobilenumber); + ps.setString(i++, response); + ps.setString(i++, event); + + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + apiresponse.put("WhatsApp","InsertId: " +lastInsertId); + apiresponse.put("status", "success"); + apiresponse.put("message", "Activity inserted successfully."); + } else { + apiresponse.put("WhatsApp","InsertId error!"); + apiresponse.put("status", "error"); + apiresponse.put("message", "Activity insert failed."); + } + + result.add(apiresponse); + + return result; + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/service/OfficialAPIService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/service/OfficialAPIService.java index 2c05779..2494f44 100644 --- a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/service/OfficialAPIService.java +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/service/OfficialAPIService.java @@ -81,9 +81,9 @@ public class OfficialAPIService { String generatedToken = "Your OTP is " + OTP + ".OTP is valid for the next 5 minutes.\nBy\nGreater Chennai Corporation."; //String urlString = "https://tmegov.onex-aura.com/api/sms?key=pfTEYN6H&to="+MobileNo+"&from=GCCCRP&body="+generatedToken+"&entityid=1401572690000011081&templateid=1407165856492044436"; String urlString = "https://tmegov.onex-aura.com/api/sms?key=pfTEYN6H&to=" + MobileNo + "&from=GCCCRP&body=" + generatedToken + "&entityid=1401572690000011081&templateid=1407165856492044436"; - System.out.println(urlString); + //System.out.println(urlString); RestTemplate restTemplate = new RestTemplate(); - System.out.println(getUserListByMobileNumber(MobileNo).size()); + //System.out.println(getUserListByMobileNumber(MobileNo).size()); String Response = restTemplate.getForObject(urlString, String.class); //System.out.println(Response); // Add a success status and message to the result @@ -106,16 +106,16 @@ public class OfficialAPIService { switch (usertype) { case "erp": //sqlQuery = "SELECT * FROM `EG_USER` WHERE `ISPORTALUSER` <> 1 AND `ISACTIVE` = 1 AND `EXTRAFIELD2` = ? AND `PIN` = ? LIMIT 1"; - sqlQuery = "SELECT * FROM `EG_USER` WHERE `EXTRAFIELD2` = ? AND `PIN` = ? AND `ISACTIVE`=1 LIMIT 1"; + sqlQuery = "SELECT id, USER_NAME, EXTRAFIELD2 FROM `EG_USER` WHERE `EXTRAFIELD2` = ? AND `PIN` = ? AND `ISACTIVE`=1 LIMIT 1"; result = jdbcOfficalTemplate.queryForList(sqlQuery, username, password); break; case "nonerp": - sqlQuery = "SELECT * FROM `EG_USER` WHERE `EXTRAFIELD2` = ? AND `PIN` = ? AND `ISACTIVE`=1 LIMIT 1"; + sqlQuery = "SELECT id, USER_NAME, EXTRAFIELD2 FROM `EG_USER` WHERE `EXTRAFIELD2` = ? AND `PIN` = ? AND `ISACTIVE`=1 LIMIT 1"; result = jdbcOfficalTemplate.queryForList(sqlQuery, username, password); break; // additional cases can be added here default: - sqlQuery = "SELECT * FROM `EG_USER` WHERE `EXTRAFIELD2` = ? AND `PIN` = ? AND `ISACTIVE`=1 LIMIT 1"; + sqlQuery = "SELECT id, USER_NAME, EXTRAFIELD2 FROM `EG_USER` WHERE `EXTRAFIELD2` = ? AND `PIN` = ? AND `ISACTIVE`=1 LIMIT 1"; result = jdbcOfficalTemplate.queryForList(sqlQuery, username, password); //result = Collections.emptyList(); break; @@ -323,7 +323,7 @@ public class OfficialAPIService { @Transactional public List> getMainMenu(String loginId) { - System.out.println("getMenu LoginID: " + loginId); + //System.out.println("getMenu LoginID: " + loginId); String SqlQuery = ""; String mainmenus ="0"; if(loginId.isBlank() || loginId.isEmpty() || loginId==null || loginId.equals(null) || loginId.equals("null")) { @@ -358,8 +358,8 @@ public class OfficialAPIService { @Transactional public List> getMenu(String loginId, String departmentId) { - System.out.println("getMenu LoginID: " + loginId); - System.out.println("getMenu DepartmentID: " + departmentId); + //System.out.println("getMenu LoginID: " + loginId); + //System.out.println("getMenu DepartmentID: " + departmentId); String SqlQuery = ""; String menus ="0"; if(loginId.isBlank() || loginId.isEmpty() || loginId==null || loginId.equals(null) || loginId.equals("null")) { @@ -431,7 +431,7 @@ public class OfficialAPIService { SqlQuery="SELECT *,CONCAT('https://gccservices.in/gccofficialapp/files/app_icon/menu/', icon_url) " + "AS iconUrl FROM `menuitem` WHERE `ISACTIVE`=1 AND `module_id`=? AND `id` IN ("+menuitem+") ORDER BY `orderby`, `name` ASC"; - System.out.println(SqlQuery); + //System.out.println(SqlQuery); List> result = jdbcActivityTemplate.queryForList(SqlQuery,menuId); return result; } diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/sluice/controller/SluiceController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/sluice/controller/SluiceController.java new file mode 100644 index 0000000..063bc96 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/sluice/controller/SluiceController.java @@ -0,0 +1,116 @@ +package in.gov.chennaicorporation.mobileservice.sluice.controller; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +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.RestController; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.sluice.service.SluiceService; + +@RequestMapping("/gccofficialapp/api/sluicepoint/") +@RestController("gccofficialappssluicepoint") +public class SluiceController { + + @Autowired + private SluiceService sluiceService; + + @GetMapping(value="/getSluicePointListForMap") + public List getSluicePointListFormap( + @RequestParam(value="loginId", required = true) String cby + ){ + return sluiceService.getSluicePointListForMap(cby); + } + + @GetMapping(value="/getSluicePointList") + public List getSluicePointList( + @RequestParam(value="loginId", required = true) String cby + ){ + return sluiceService.getSluicePointList(cby); + } + + @PostMapping("/saveSluicePoint") + public List saveSluicePoint( + @RequestParam(value = "zone", required = true) String zone, + @RequestParam(value = "ward", required = true) String ward, + @RequestParam(value = "street_name", required = false) String street_name, + @RequestParam(value = "street_id", required = false) String street_id, + @RequestParam(value = "latitude", required = true) String latitude, + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "loginId", required = true) String loginId, + @RequestParam(value = "file", required = true) MultipartFile file + ) { + return sluiceService.saveSluicePoint( + zone, + ward, + street_name, + street_id, + latitude, + longitude, + loginId, + file + ); + } + + @PostMapping("/saveActivity") + public List saveActivity( + @RequestParam(value = "sluicepoint_id", required = true) String sluicepoint_id, + @RequestParam(value = "rust_painting", required = true) String rust_painting, + @RequestParam(value = "greasing", required = true) String greasing, + @RequestParam(value = "file", required = true) MultipartFile file, + @RequestParam(value = "video", required = true) MultipartFile video, + @RequestParam(value = "zone", required = true) String zone, + @RequestParam(value = "ward", required = true) String ward, + @RequestParam(value = "street_name", required = false) String street_name, + @RequestParam(value = "street_id", required = false) String street_id, + @RequestParam(value = "latitude", required = true) String latitude, + @RequestParam(value = "longitude", required = true) String longitude, + @RequestParam(value = "loginId", required = true) String loginId + ) { + return sluiceService.saveActivity( + sluicepoint_id, + rust_painting, + greasing, + file, + video, + zone, + ward, + street_name, + street_id, + latitude, + longitude, + loginId, + "before" + ); + } + + @GetMapping(value="/getZoneSummary") + public List getZoneSummary( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate + ){ + return sluiceService.getZoneSummary(fromDate, toDate); + } + + @GetMapping(value="/getWardSummary") + public List getWardSummary( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate, + @RequestParam(value="zone", required = true) String zone + ){ + return sluiceService.getWardSummary(fromDate, toDate, zone); + } + + @GetMapping(value="/getSluicePointSummary") + public List getSluicePointSummary( + @RequestParam(value="fromDate", required = true) String fromDate, + @RequestParam(value="toDate", required = true) String toDate, + @RequestParam(value="ward", required = true) String ward + ){ + return sluiceService.getSluicePointSummary(fromDate, toDate, ward); + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/sluice/service/SluiceService.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/sluice/service/SluiceService.java new file mode 100644 index 0000000..d30c566 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/sluice/service/SluiceService.java @@ -0,0 +1,686 @@ +package in.gov.chennaicorporation.mobileservice.sluice.service; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.SecureRandom; +import java.sql.PreparedStatement; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.env.Environment; +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; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.gccactivity.service.DateTimeUtil; + +@Service +public class SluiceService { + + private JdbcTemplate jdbcSluiceTemplate; + + private final Environment environment; + private String fileBaseUrl; + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int STRING_LENGTH = 15; + private static final Random RANDOM = new SecureRandom(); + + @Autowired + public void setDataSource(@Qualifier("mysqlGccSluicePointSource") DataSource SluiceDataSource) { + this.jdbcSluiceTemplate = new JdbcTemplate(SluiceDataSource); + } + + @Autowired + public SluiceService(Environment environment) { + this.environment = environment; + this.fileBaseUrl=environment.getProperty("fileBaseUrl"); + } + + public static String generateRandomString() { + StringBuilder result = new StringBuilder(STRING_LENGTH); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + public static String generateRandomFileString(int lenthval) { + StringBuilder result = new StringBuilder(lenthval); + for (int i = 0; i < lenthval; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + private byte[] compressImage(BufferedImage image, float quality) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream); + + ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next(); + writer.setOutput(imageOutputStream); + + ImageWriteParam param = writer.getDefaultWriteParam(); + if (param.canWriteCompressed()) { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(quality); + } + + writer.write(null, new javax.imageio.IIOImage(image, null, null), param); + + writer.dispose(); + imageOutputStream.close(); + + return byteArrayOutputStream.toByteArray(); + } + + // Function to convert date string from dd-MM-yyyy to yyyy-MM-dd + public static String convertDateFormat(String inputDate, int add) { + // Check if the inputDate is not null or blank + if (inputDate != null && !inputDate.isBlank()) { + try { + // Define the input and output date formats + DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + // Parse the input date string to LocalDate + LocalDate date = LocalDate.parse(inputDate, inputFormatter); + + // Add the specified number of days to the date if 'add' is greater than 0 + if (add > 0) { + date = date.plusDays(add); + } + + // Format the date to the new format + return date.format(outputFormatter); + + } catch (DateTimeParseException e) { + // Handle the case where the input date is invalid + System.out.println("Invalid date format: " + inputDate); + return ""; + } + } else { + return ""; + } + } + + public String fileUpload(String name, String id, MultipartFile file, String filetype) { + + int lastInsertId = 0; + // Set the file path where you want to save it + String uploadDirectory = environment.getProperty("file.upload.directory"); + String serviceFolderName = environment.getProperty("sluicepoint_foldername"); + var year = DateTimeUtil.getCurrentYear(); + var month = DateTimeUtil.getCurrentMonth(); + var date = DateTimeUtil.getCurrentDay(); + + uploadDirectory = uploadDirectory + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date; + + try { + // Create directory if it doesn't exist + Path directoryPath = Paths.get(uploadDirectory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Datetime string + String datetimetxt = DateTimeUtil.getCurrentDateTime(); + + datetimetxt = datetimetxt + "_"+ generateRandomFileString(6); // Attached Random text + + // File name + String fileName = name + "_" + id + "_" + datetimetxt + "_" + file.getOriginalFilename(); + fileName = fileName.replaceAll("\\s+", ""); // Remove space on filename + + String filePath = uploadDirectory + "/" + fileName; + + String filepath_txt = "/" + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date + "/" + fileName; + + // Create a new Path object + Path path = Paths.get(filePath); + + // Get the bytes of the file + byte[] bytes = file.getBytes(); + + if(filetype.equalsIgnoreCase("image")) + { + // Compress the image + BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); + byte[] compressedBytes = compressImage(image, 0.5f); // Compress with 50% quality + // Write the bytes to the file + Files.write(path, compressedBytes); + } + else { + // Write the bytes to the file + Files.write(path, bytes); + } + // Get current date & time + LocalDateTime now = LocalDateTime.now(); + + // Format date-time (optional) + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + System.out.println("Date: "+ now.format(formatter)); + System.out.println("Activity: SluicePoint"); + System.out.println("File Type: " + filetype); + System.out.println("File Upload Path: " + filePath); + System.out.println("File Path: " + filepath_txt); + + return filepath_txt; + + } catch (IOException e) { + e.printStackTrace(); + System.out.println("Failed to save file " + file.getOriginalFilename()); + return "error"; + } + } + + public String getWardByLoginId(String loginid, String type) { + String sqlQuery = "SELECT `ward` FROM gcc_penalty_hoardings.`hoading_user_list` WHERE `userid` = ? AND `type` = ? LIMIT 1"; + + // Query the database using queryForList + List> results = jdbcSluiceTemplate.queryForList(sqlQuery, loginid, type); + + // Check if results is not empty and extract the ward value + if (!results.isEmpty()) { + // Extract the ward value from the first result + return (String) results.get(0).get("ward"); + } + + // Handle the case where no result is found + return "000"; // or return null based on your needs + } + + @Transactional + public List> saveSluicePoint( + String zone, + String ward, + String street_name, + String street_id, + String latitude, + String longitude, + String inby, + MultipartFile file + ) { + + String filetxt = inby; + + String action = "new_mapping"; + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // For Image + String filetype = "image"; + String activityimg = fileUpload(action, filetxt, file, filetype); + + if ("error".equalsIgnoreCase(activityimg)) { + response.put("status", "error"); + response.put("message", "Sluice Point new mapping image insert failed."); + result.add(response); + return result; + } + + String insertSqltxt = "INSERT INTO sluicepoint_mapped_master(`zone`, `ward`, `road_name`, `road_gisid`, `latitude`, `longitude`, `inby`, `file`) " + + "VALUES (?,?,?,?,?,?,?,?)"; + + String insertSql = insertSqltxt; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcSluiceTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"sluicepoint_id"}); + int i = 1; + ps.setString(i++, zone); + ps.setString(i++, ward); + ps.setString(i++, street_name); + ps.setString(i++, street_id); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, inby); + ps.setString(i++, activityimg); + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Sluice Point", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", "Sluice Point " + action + " data inserted successfully."); + } else { + response.put("Sluice Point", action + " insertId error!"); + response.put("status", "error"); + response.put("message", "Sluice Point " + action + " data insert failed."); + } + + result.add(response); + return result; + } + + public List> getSluicePointListForMap(String loginid) { + + String ward = getWardByLoginId(loginid,"ae"); + + String sqlManhole = "SELECT " + + " d.zone," + + " d.ward," + + " COUNT(*) AS total_sluice_points," + + " (SELECT COUNT(*) " + + " FROM sluicepoint_mapped_master m" + + " WHERE m.isactive = 1 AND m.isdelete = 0 AND m.ward = d.ward) AS total_mapped_points," + + " (COUNT(*) - " + + " (SELECT COUNT(*) " + + " FROM sluicepoint_mapped_master m" + + " WHERE m.isactive = 1 AND m.isdelete = 0 AND m.ward = d.ward)" + + " ) AS total_pending_points " + + "FROM sluicepoint_master d " + + "WHERE d.isactive = 1 AND d.isdelete = 0" + + " AND d.ward = ? " + + "GROUP BY d.ward " + + "ORDER BY d.ward"; + List> sluicepoints = jdbcSluiceTemplate.queryForList(sqlManhole, ward); + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Dispoasl Map List."); + response.put("data", sluicepoints); + + return Collections.singletonList(response); + } + + public List> getSluicePointList(String loginid) { + + String ward = getWardByLoginId(loginid,"ae"); + + // 1. Fetch all Sluice Points for the given SWDID + String sqlManhole = "SELECT *, " + + "CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `file`) AS img_file_url " + + " FROM sluicepoint_mapped_master WHERE ward = ? AND `isactive`=1 AND `isdelete`=0"; + List> sluicepoints = jdbcSluiceTemplate.queryForList(sqlManhole, ward); + + List> finalList = new ArrayList<>(); + + for (Map sluicepoint : sluicepoints) { + Map sluicepointResponse = new HashMap<>(); + sluicepointResponse.putAll(sluicepoint); // add all Sluice point columns + + // 2. Fetch before activity + String sqlBefore = "SELECT *," + + "CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `img_file`) AS img_file_url," + + "CONCAT('"+fileBaseUrl+"/gccofficialapp/files', `video_file`) AS video_file_url " + + "FROM before_activity WHERE sluicepoint_id = ? " + + "AND indate >= CURDATE() " + + "AND indate < CURDATE() + INTERVAL 1 DAY " + + "AND isactive=1 AND isdelete=0"; + List> beforeActivities = jdbcSluiceTemplate.queryForList(sqlBefore, + sluicepoint.get("sluicepoint_id")); + + Map beforeData = new HashMap<>(); + if (!beforeActivities.isEmpty()) { + beforeData.put("status", "Completed"); + beforeData.put("details", beforeActivities); + } else { + beforeData.put("status", "Pending"); + beforeData.put("details", Collections.emptyList()); + } + + // 4. Overall Sluice Point status + String overallStatus = (!beforeActivities.isEmpty()) ? "Completed" : "Pending"; + sluicepointResponse.put("status", overallStatus); + sluicepointResponse.put("before", beforeData); + + finalList.add(sluicepointResponse); + } + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Dispoasl List."); + response.put("data", finalList); + + return Collections.singletonList(response); + } + + @Transactional + public List> saveActivity( + String sluicepoint_id, + String rust_painting, + String greasing, + MultipartFile file, + MultipartFile video, + String zone, + String ward, + String street_name, + String street_id, + String latitude, + String longitude, + String inby, + String action + ) { + + String filetxt =sluicepoint_id; + + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // For Image + String filetype = "image"; + String activityimg = fileUpload(action, filetxt, file, filetype); + + if ("error".equalsIgnoreCase(activityimg)) { + response.put("status", "error"); + response.put("message", "Sluice Point activity image insert failed."); + result.add(response); + return result; + } + + // For Video + filetype = "video"; + String activityvideo = fileUpload(action, filetxt, video, filetype); + + if ("error".equalsIgnoreCase(activityvideo)) { + response.put("status", "error"); + response.put("message", "Sluice Point activity video insert failed."); + result.add(response); + return result; + } + + String insertBeforeSql = "INSERT INTO before_activity(sluicepoint_id, img_file, video_file, zone, ward, " + + "street_name, street_id, latitude, longitude, inby, rust_painting, greasing) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)"; + + String insertSql = insertBeforeSql; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcSluiceTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"activity_id"}); + int i = 1; + ps.setString(i++, sluicepoint_id); + ps.setString(i++, activityimg); + ps.setString(i++, activityvideo); + ps.setString(i++, zone); + ps.setString(i++, ward); + ps.setString(i++, street_name); + ps.setString(i++, street_id); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, inby); + ps.setString(i++, rust_painting); + ps.setString(i++, greasing); + + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Sluice Point", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", "Sluice Point " + action + " activity inserted successfully."); + } else { + response.put("Sluice Point", action + " insertId error!"); + response.put("status", "error"); + response.put("message", "Sluice Point " + action + " activity insert failed."); + } + + result.add(response); + return result; + } + + @Transactional(readOnly = true) + public List> getZoneSummary(String fromDate, String toDate) { + + fromDate = convertDateFormat(fromDate, 0); + toDate = convertDateFormat(toDate, 0); + + String sql = + "SELECT " + + " z.zone, " + + " COALESCE(dm.total_sluice_points, 0) AS total_sluice_points, " + + " COALESCE(mm.total_mapped_points, 0) AS total_mapped_points, " + + " COALESCE(COUNT(DISTINCT (b.sluicepoint_id), 0)) AS completed_days " + + "FROM (" + + " SELECT DISTINCT zone FROM sluicepoint_master WHERE isactive=1 AND isdelete=0" + + ") z " + + "LEFT JOIN (" + + " SELECT zone, COUNT(*) AS total_sluice_points " + + " FROM sluicepoint_master " + + " WHERE isactive=1 AND isdelete=0 " + + " GROUP BY zone" + + ") dm ON z.zone = dm.zone " + + "LEFT JOIN (" + + " SELECT zone, COUNT(*) AS total_mapped_points " + + " FROM sluicepoint_mapped_master " + + " WHERE isactive=1 AND isdelete=0 " + + " GROUP BY zone" + + ") mm ON z.zone = mm.zone " + + "LEFT JOIN sluicepoint_mapped_master dmm ON dmm.zone = z.zone AND dmm.isactive=1 AND dmm.isdelete=0 " + + "LEFT JOIN before_activity b ON dmm.sluicepoint_id = b.sluicepoint_id " + + " AND b.isactive=1 AND b.isdelete=0 " + + " AND b.indate >= ? AND b.indate < DATE_ADD(?, INTERVAL 1 DAY) " + + "GROUP BY z.zone, dm.total_sluice_points, mm.total_mapped_points " + + "ORDER BY z.zone"; + + List> results = jdbcSluiceTemplate.queryForList(sql, fromDate, toDate); + + long totalDays = ChronoUnit.DAYS.between( + LocalDate.parse(fromDate), + LocalDate.parse(toDate) + ) + 1; + + List> finalList = new ArrayList<>(); + + long grandTotalSluicePoints = 0; + long grandTotalMappedPoints = 0; + long grandCompletedDays = 0; + long grandPendingDays = 0; + + + for (Map row : results) { + Map report = new LinkedHashMap<>(); + long completed = ((Number) row.get("completed_days")).longValue(); + long totalSluicePoints = ((Number) row.get("total_sluice_points")).longValue(); + long totalMappedPoints = ((Number) row.get("total_mapped_points")).longValue(); + + long totalDays_final = (totalDays*totalMappedPoints); + + report.put("zone", row.get("zone")); + report.put("totalSluicePoints", totalSluicePoints); + report.put("totalMappedPoints", totalMappedPoints); + report.put("totalDays", totalDays_final); + report.put("completedDays", completed); + report.put("pendingDays", (totalDays_final - completed)); + + finalList.add(report); + + // accumulate grand totals + grandTotalSluicePoints += totalSluicePoints; + grandTotalMappedPoints += totalMappedPoints; + grandCompletedDays += completed; + grandPendingDays +=(totalDays_final - completed); + } + + // add grand total row + Map grandTotalRow = new LinkedHashMap<>(); + grandTotalRow.put("zone", "TOTAL"); + grandTotalRow.put("totalSluicePoints", grandTotalSluicePoints); + grandTotalRow.put("totalMappedPoints", grandTotalMappedPoints); + grandTotalRow.put("totalDays", totalDays); + grandTotalRow.put("completedDays", grandCompletedDays); + grandTotalRow.put("pendingDays", grandPendingDays); // total pending across all wards + + finalList.add(grandTotalRow); + + return finalList; + } + + @Transactional(readOnly = true) + public List> getWardSummary(String fromDate, String toDate, String zone) { + + fromDate = convertDateFormat(fromDate, 0); + toDate = convertDateFormat(toDate, 0); + + String sql = + "SELECT " + + " w.ward, " + + " COALESCE(dm.total_sluice_points, 0) AS total_sluice_points, " + + " COALESCE(mm.total_mapped_points, 0) AS total_mapped_points, " + + " COALESCE(COUNT(DISTINCT (b.sluicepoint_id), 0)) AS completed_days " + + "FROM (" + + " SELECT DISTINCT ward FROM sluicepoint_master WHERE isactive=1 AND isdelete=0 AND zone=?" + + ") w " + + "LEFT JOIN (" + + " SELECT ward, COUNT(*) AS total_sluice_points " + + " FROM sluicepoint_master " + + " WHERE isactive=1 AND isdelete=0 AND zone=? " + + " GROUP BY ward" + + ") dm ON w.ward = dm.ward " + + "LEFT JOIN (" + + " SELECT ward, COUNT(*) AS total_mapped_points " + + " FROM sluicepoint_mapped_master " + + " WHERE isactive=1 AND isdelete=0 AND zone=? " + + " GROUP BY ward" + + ") mm ON w.ward = mm.ward " + + "LEFT JOIN sluicepoint_mapped_master dmm ON dmm.ward = w.ward AND dmm.isactive=1 AND dmm.isdelete=0 " + + "LEFT JOIN before_activity b ON dmm.sluicepoint_id = b.sluicepoint_id " + + " AND b.isactive=1 AND b.isdelete=0 " + + " AND b.indate >= ? AND b.indate < DATE_ADD(?, INTERVAL 1 DAY) " + + "GROUP BY w.ward, dm.total_sluice_points, mm.total_mapped_points " + + "ORDER BY w.ward"; + + List> results = jdbcSluiceTemplate.queryForList( + sql, zone, zone, zone, fromDate, toDate + ); + + long totalDays = ChronoUnit.DAYS.between( + LocalDate.parse(fromDate), + LocalDate.parse(toDate) + ) + 1; + + List> finalList = new ArrayList<>(); + + long grandTotalSluicePoints = 0; + long grandTotalMappedPoints = 0; + long grandCompletedDays = 0; + long grandPendingDays = 0; + + for (Map row : results) { + Map report = new LinkedHashMap<>(); + long completed = ((Number) row.get("completed_days")).longValue(); + long totalSluicePoints = ((Number) row.get("total_sluice_points")).longValue(); + long totalMappedPoints = ((Number) row.get("total_mapped_points")).longValue(); + long totalDays_final = (totalDays*totalMappedPoints); + + report.put("ward", row.get("ward")); + report.put("totalSluicePoints", totalSluicePoints); + report.put("totalMappedPoints", totalMappedPoints); + report.put("totalDays", totalDays_final); + report.put("completedDays", completed); + report.put("pendingDays", (totalDays_final - completed)); + + finalList.add(report); + + // accumulate grand totals + grandTotalSluicePoints += totalSluicePoints; + grandTotalMappedPoints += totalMappedPoints; + grandCompletedDays += completed; + grandPendingDays +=(totalDays_final - completed); + } + + // add grand total row + Map grandTotalRow = new LinkedHashMap<>(); + grandTotalRow.put("ward", "TOTAL"); + grandTotalRow.put("totalSluicePoints", grandTotalSluicePoints); + grandTotalRow.put("totalMappedPoints", grandTotalMappedPoints); + grandTotalRow.put("totalDays", totalDays); + grandTotalRow.put("completedDays", grandCompletedDays); + grandTotalRow.put("pendingDays", grandPendingDays); // total pending across all wards + + finalList.add(grandTotalRow); + + return finalList; + } + + public List> getSluicePointSummary(String fromDate, String toDate, String ward) { + + fromDate = convertDateFormat(fromDate,0); + toDate = convertDateFormat(toDate,0); + + // SQL: count completed days per Sluice point + String sql = "SELECT d.road_name, d.sluicepoint_id, COUNT(DISTINCT DATE(b.indate)) AS completedDays " + + "FROM sluicepoint_mapped_master d " + + "LEFT JOIN before_activity b ON d.sluicepoint_id = b.sluicepoint_id " + + "AND b.indate >= ? AND b.indate < DATE_ADD(?, INTERVAL 1 DAY) " + + "AND b.isactive=1 AND b.isdelete=0 " + + "WHERE d.isactive=1 AND d.isdelete=0 AND d.ward=? " + + "GROUP BY d.road_name, d.sluicepoint_id ORDER BY d.road_name"; + + List> results = jdbcSluiceTemplate.queryForList(sql, fromDate, toDate, ward); + + long totalDays = ChronoUnit.DAYS.between( + LocalDate.parse(fromDate), + LocalDate.parse(toDate) + ) + 1; + + List> finalList = new ArrayList<>(); + + //long grandTotalSluicePoints = 0; + //long grandTotalMappedPoints = 0; + long grandCompletedDays = 0; + long grandPendingDays = 0; + + for (Map row : results) { + Map Report = new HashMap<>(); + long completed = ((Number) row.get("completedDays")).longValue(); + long totalDays_final = (totalDays*1); + + Report.put("road_name", row.get("road_name")); + Report.put("sluicepoint_id", row.get("sluicepoint_id")); + Report.put("totalDays", totalDays_final); + Report.put("completed", completed); + Report.put("pending", totalDays_final - completed); + finalList.add(Report); + + grandCompletedDays += completed; + grandPendingDays +=(totalDays_final - completed); + } + + // add grand total row + Map grandTotalRow = new LinkedHashMap<>(); + grandTotalRow.put("road_name", "TOTAL"); + grandTotalRow.put("sluicepoint_id", 0); + grandTotalRow.put("totalDays", totalDays); + grandTotalRow.put("completed", grandCompletedDays); + grandTotalRow.put("pending", grandPendingDays); // total pending across all wards + + //finalList.add(grandTotalRow); + + return finalList; + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/streetCleaning/controller/StreetCleaningController.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/streetCleaning/controller/StreetCleaningController.java new file mode 100644 index 0000000..4bcf55a --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/streetCleaning/controller/StreetCleaningController.java @@ -0,0 +1,144 @@ +package in.gov.chennaicorporation.mobileservice.streetCleaning.controller; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +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.RestController; +import org.springframework.web.multipart.MultipartFile; + +import in.gov.chennaicorporation.mobileservice.streetCleaning.service.StreetCleaningActivity; + +@RequestMapping("/gccofficialapp/api/streetcleaning/") +@RestController("gccofficialappstreetcleaning") +public class StreetCleaningController { + @Autowired + private StreetCleaningActivity streetCleaningActivity ; + + @GetMapping(value="/checkStreet") + public String checkStreet_id( + @RequestParam(value="ward", required = true) String ward, + @RequestParam(value="street_id", required = true) String street_id, + @RequestParam(value="loginId", required = true) String loginId + ){ + return streetCleaningActivity.checkStreet_id(loginId,street_id, ward); + } + + @GetMapping(value="/getStreetPendingList") + public List getStreetPendingList( + @RequestParam(value="ward", required = true) String ward, + @RequestParam(value="loginId", required = true) String loginId + ){ + return streetCleaningActivity.getStreetPendingList(loginId, ward); + } + + @GetMapping(value="/getStreetList") + public List getStreetList( + @RequestParam(value="ward", required = true) String ward, + @RequestParam(value="street_id", required = true) String street_id, + @RequestParam(value="loginId", required = true) String loginId + ){ + return streetCleaningActivity.getStreetList(loginId,street_id, ward); + } + + @PostMapping("/saveActivity") + public List saveActivity( + @RequestParam("video_file") MultipartFile video_file, + @RequestParam("left_file") MultipartFile left_file, + @RequestParam("right_file") MultipartFile right_file, + @RequestParam("work_status") String work_status, + @RequestParam("cleaned_meter") String cleaned_meter, + @RequestParam("zone") String zone, + @RequestParam("ward") String ward, + @RequestParam("street_id") String gis_street_id, + @RequestParam("street_name") String street_name, + @RequestParam("road_type") String road_type, + @RequestParam("street_length") String street_length, + @RequestParam("latitude") String latitude, + @RequestParam("longitude") String longitude, + @RequestParam("loginId") String inby + + ) { + return streetCleaningActivity.saveActivity( + video_file, + left_file, + right_file, + work_status, + cleaned_meter, + zone, + ward, + gis_street_id, + street_name, + road_type, + street_length, + latitude, + longitude, + inby + ); + } + + @GetMapping(value="/getZoneReport") + public List getZoneReport(String loginId){ + return streetCleaningActivity.getZoneReport(loginId); + } + + @GetMapping(value="/getWardReportByZone") + public List getWardReportByZone( + @RequestParam(value="loginid") String loginId, + @RequestParam(value="zone") String zone ){ + return streetCleaningActivity.getWardReportByZone(loginId, zone); + } + + @GetMapping(value="/getStreetListByWardAndStatus") + public List getStreetListByWardAndStatus( + @RequestParam(value="loginid") String loginid, + @RequestParam(value="ward") String ward, + @RequestParam(value="status", required = false) String status){ + return streetCleaningActivity.getStreetListByWardAndStatus(loginid, ward, status); + } + + // For Rating + @GetMapping(value="/getStreetListForRating") + public List getStreetListForRating( + @RequestParam(value="ward", required = true) String ward, + @RequestParam(value="street_id", required = true) String street_id, + @RequestParam(value="loginId", required = true) String loginId + ){ + return streetCleaningActivity.getStreetListForRating(loginId,street_id, ward); + } + + @PostMapping("/saveRatingActivity") + public List saveRatingActivity( + @RequestParam("video_file") MultipartFile video_file, + @RequestParam("left_file") MultipartFile left_file, + @RequestParam("right_file") MultipartFile right_file, + @RequestParam("work_rating") String work_rating, + @RequestParam("zone") String zone, + @RequestParam("ward") String ward, + @RequestParam("street_id") String gis_street_id, + @RequestParam("street_name") String street_name, + @RequestParam("road_type") String road_type, + @RequestParam("latitude") String latitude, + @RequestParam("longitude") String longitude, + @RequestParam("loginId") String inby + + ) { + return streetCleaningActivity.saveRatingActivity( + video_file, + left_file, + right_file, + work_rating, + zone, + ward, + gis_street_id, + street_name, + road_type, + latitude, + longitude, + inby + ); + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/streetCleaning/service/StreetCleaningActivity.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/streetCleaning/service/StreetCleaningActivity.java new file mode 100644 index 0000000..9381f51 --- /dev/null +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/streetCleaning/service/StreetCleaningActivity.java @@ -0,0 +1,991 @@ +package in.gov.chennaicorporation.mobileservice.streetCleaning.service; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.SecureRandom; +import java.sql.PreparedStatement; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.env.Environment; +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; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +import in.gov.chennaicorporation.mobileservice.gccactivity.service.DateTimeUtil; + +@Service +public class StreetCleaningActivity { + private JdbcTemplate jdbcStreetCleaningTemplate; + + private final Environment environment; + private String fileBaseUrl; + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + private static final int STRING_LENGTH = 15; + private static final Random RANDOM = new SecureRandom(); + + @Autowired + public void setDataSource(@Qualifier("mysqlGccStreetCleaningSource") DataSource StreetCleaningDataSource) { + this.jdbcStreetCleaningTemplate = new JdbcTemplate(StreetCleaningDataSource); + } + + @Autowired + public StreetCleaningActivity(Environment environment) { + this.environment = environment; + this.fileBaseUrl=environment.getProperty("fileBaseUrl"); + } + + + public static String generateRandomString() { + StringBuilder result = new StringBuilder(STRING_LENGTH); + for (int i = 0; i < STRING_LENGTH; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + public static String generateRandomFileString(int lenthval) { + StringBuilder result = new StringBuilder(lenthval); + for (int i = 0; i < lenthval; i++) { + result.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length()))); + } + return result.toString(); + } + + private byte[] compressImage(BufferedImage image, float quality) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(byteArrayOutputStream); + + ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next(); + writer.setOutput(imageOutputStream); + + ImageWriteParam param = writer.getDefaultWriteParam(); + if (param.canWriteCompressed()) { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(quality); + } + + writer.write(null, new javax.imageio.IIOImage(image, null, null), param); + + writer.dispose(); + imageOutputStream.close(); + + return byteArrayOutputStream.toByteArray(); + } + + public String fileUpload(String name, String id, MultipartFile file, String filetype) { + + int lastInsertId = 0; + // Set the file path where you want to save it + String uploadDirectory = environment.getProperty("file.upload.directory"); + String serviceFolderName = environment.getProperty("StreetCleaning_foldername"); + var year = DateTimeUtil.getCurrentYear(); + var month = DateTimeUtil.getCurrentMonth(); + var date = DateTimeUtil.getCurrentDay(); + + uploadDirectory = uploadDirectory + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date; + + try { + // Create directory if it doesn't exist + Path directoryPath = Paths.get(uploadDirectory); + if (!Files.exists(directoryPath)) { + Files.createDirectories(directoryPath); + } + + // Datetime string + String datetimetxt = DateTimeUtil.getCurrentDateTime(); + + datetimetxt = datetimetxt + "_"+ generateRandomFileString(6); // Attached Random text + + // File name + String fileName = name + "_" + id + "_" + datetimetxt + "_" + file.getOriginalFilename(); + fileName = fileName.replaceAll("\\s+", ""); // Remove space on filename + + String filePath = uploadDirectory + "/" + fileName; + + String filepath_txt = "/" + serviceFolderName + filetype + "/" + year + "/" + month + "/" + date + "/" + fileName; + + // Create a new Path object + Path path = Paths.get(filePath); + + // Get the bytes of the file + byte[] bytes = file.getBytes(); + + if(filetype.equalsIgnoreCase("image")) + { + // Compress the image + BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes)); + byte[] compressedBytes = compressImage(image, 0.5f); // Compress with 50% quality + // Write the bytes to the file + Files.write(path, compressedBytes); + } + else { + // Write the bytes to the file + Files.write(path, bytes); + } + // Get current date & time + LocalDateTime now = LocalDateTime.now(); + + // Format date-time (optional) + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + System.out.println("Date: "+ now.format(formatter)); + System.out.println("Activity: StreetCleaning"); + System.out.println("File Type: " + filetype); + System.out.println("File Upload Path: " + filePath); + System.out.println("File Path: " + filepath_txt); + + return filepath_txt; + + } catch (IOException e) { + e.printStackTrace(); + System.out.println("Failed to save file " + file.getOriginalFilename()); + return "error"; + } + } + + public String getWardByLoginId(String loginid, String type) { + String sqlQuery = "SELECT `ward` FROM gcc_penalty_hoardings.`hoading_user_list` WHERE `userid` = ? AND `type` = ? LIMIT 1"; + + // Query the database using queryForList + List> results = jdbcStreetCleaningTemplate.queryForList(sqlQuery, loginid, type); + + // Check if results is not empty and extract the ward value + if (!results.isEmpty()) { + // Extract the ward value from the first result + return (String) results.get(0).get("ward"); + } + + // Handle the case where no result is found + return "000"; // or return null based on your needs + } + + @Transactional + public String checkStreet_id(String inby, String gis_street_id, String ward) { + String checkSql = "Select count(sid) FROM `street_list_master` WHERE `gis_street_id`=? AND `ward`=?"; + Integer count = jdbcStreetCleaningTemplate.queryForObject( + checkSql, + Integer.class, + gis_street_id, + ward + ); + + if(count != null && count > 0) { + return "false"; + } + return "true"; + } + + @Transactional + public List> getStreetPendingList(String loginid, String ward) { + + String sqlStreet = "SELECT sid, zone, ward, gis_street_id, street_name, road_type, " + + "street_length, isactive, isdelete, inby, cdate " + + "FROM street_list_master " + + "WHERE ward = ? AND isactive=1 AND isdelete=0"; + + List> streetList = jdbcStreetCleaningTemplate.queryForList(sqlStreet, ward); + + List> finalList = new ArrayList<>(); + + for (Map street : streetList) { + Map streetResponse = new HashMap<>(street); + + // ✅ latest activity for that street + String sqlActivity = "SELECT activity_id, gis_street_id, work_status " + + "FROM cleaning_activity " + + "WHERE gis_street_id = ? AND ward = ? AND isactive=1 AND isdelete=0 " + + "ORDER BY indate DESC LIMIT 1"; + + List> activities = jdbcStreetCleaningTemplate.queryForList( + sqlActivity, street.get("gis_street_id"), street.get("ward") + ); + + String overallStatus = "Pending"; // default + if (!activities.isEmpty()) { + Map lastActivity = activities.get(0); + String workStatus = (String) lastActivity.get("work_status"); + + if (workStatus != null && !workStatus.equalsIgnoreCase("Partially") + && !workStatus.equalsIgnoreCase("pending")) { + overallStatus = "Completed"; + } + } + + // ✅ only keep Pending streets + if ("Pending".equalsIgnoreCase(overallStatus)) { + streetResponse.put("status", "Pending"); + finalList.add(streetResponse); + } + } + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Pending Street List."); + response.put("data", finalList); + + return Collections.singletonList(response); + } + + @Transactional + public List> getStreetList(String loginid, String street_id, String ward) { + + //String ward = getWardByLoginId(loginid, "ae"); + + // 1. Fetch all streets for the ward + String sqlStreet = "SELECT sid, zone, ward, gis_street_id, street_name, road_type, " + + "street_length, isactive, isdelete, inby, cdate " + + "FROM street_list_master " + + "WHERE gis_street_id = ? AND ward =? AND isactive=1 AND isdelete=0"; + List> streetList = jdbcStreetCleaningTemplate.queryForList(sqlStreet, street_id, ward); + + List> finalList = new ArrayList<>(); + + for (Map street : streetList) { + Map streetResponse = new HashMap<>(); + streetResponse.putAll(street); + + // 2. Fetch activities based on street_id + String sqlActivity = "SELECT activity_id, gis_street_id, video_file, left_file, right_file, " + + "work_status, cleaned_meter, inby, indate, isactive, isdelete, latitude, longitude, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', video_file) AS video_url, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', left_file) AS left_file_url, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', right_file) AS right_file_url " + + "FROM cleaning_activity " + + "WHERE gis_street_id = ? AND ward = ? AND isactive=1 AND isdelete=0 " + + "ORDER BY indate DESC LIMIT 1"; + + System.out.println(sqlActivity); + + List> activities = jdbcStreetCleaningTemplate.queryForList(sqlActivity, street.get("gis_street_id"), street.get("ward")); + + Map activityData = new HashMap<>(); + String overallStatus = "Pending"; + + if (!activities.isEmpty()) { + Map lastActivity = activities.get(0); // latest one + String workStatus = (String) lastActivity.get("work_status"); + + if (workStatus != null && workStatus.equalsIgnoreCase("Partially")) { + overallStatus = "Pending"; + } else { + overallStatus = "Completed"; + } + + activityData.put("status", overallStatus); + activityData.put("details", activities); + } else { + activityData.put("status", "Pending"); + activityData.put("details", Collections.emptyList()); + } + + // 3. Add status + activity info to street response + streetResponse.put("status", overallStatus); + streetResponse.put("activities", activityData); + + finalList.add(streetResponse); + } + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Street List."); + response.put("data", finalList); + + return Collections.singletonList(response); + } + + @Transactional + public boolean getStreet_id(String gis_street_id, String ward) { + String checkSql = "Select count(sid) FROM `street_list_master` WHERE `gis_street_id`=? AND ward=?"; + Integer count = jdbcStreetCleaningTemplate.queryForObject( + checkSql, + Integer.class, + gis_street_id, + ward + ); + return (count != null && count > 0); + } + + @Transactional + public Boolean saveStreet( + String zone, + String ward, + String gis_street_id, + String street_name, + String road_type, + String street_length, + String latitude, + String longitude, + String inby + ) { + // 1. Duplicate check + if (getStreet_id(gis_street_id, ward)) { + return true; // stop execution, street already exists + } + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + String insertSql = "INSERT INTO street_list_master " + + "(zone, ward, gis_street_id, street_name, road_type, street_length, inby) " + + "VALUES (?,?,?,?,?,?,?)"; + + int affectedRows = jdbcStreetCleaningTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"street_id"}); + int i = 1; + ps.setString(i++, zone); + ps.setString(i++, ward); + ps.setString(i++, gis_street_id); + ps.setString(i++, street_name); + ps.setString(i++, road_type); + ps.setString(i++, street_length); + ps.setString(i++, inby); + return ps; + }, keyHolder); + + return affectedRows > 0; + } + + @Transactional + public List> saveActivity( + MultipartFile video_file, + MultipartFile left_file, + MultipartFile right_file, + String work_status, + String cleaned_meter, + String zone, + String ward, + String gis_street_id, + String street_name, + String road_type, + String street_length, + String latitude, + String longitude, + String inby + ) { + + String filetxt =gis_street_id; + String action = inby; + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // 1. Street Check and add + if (!saveStreet(zone, ward, gis_street_id, street_name, road_type, street_length, latitude, longitude, inby)) { + response.put("status", "error"); + response.put("message", "Failed to add current street!"); + result.add(response); + return result; // stop execution, don’t insert + } + + // For Left Image + String filetype = "image"; + String leftIMG = fileUpload(action, filetxt, left_file, filetype); + + if ("error".equalsIgnoreCase(leftIMG)) { + response.put("status", "error"); + response.put("message", "Street cleaning activity left image insert failed."); + result.add(response); + return result; + } + + // For Right Image + String rightIMG = fileUpload(action, filetxt, right_file, filetype); + + if ("error".equalsIgnoreCase(rightIMG)) { + response.put("status", "error"); + response.put("message", "Street cleaning activity right image insert failed."); + result.add(response); + } + + // For Video + filetype = "video"; + String video = fileUpload(action, filetxt, video_file, filetype); + + if ("error".equalsIgnoreCase(video)) { + response.put("status", "error"); + response.put("message", "Street cleaning activity video insert failed."); + result.add(response); + return result; + } + + String insertBeforeSql = "INSERT INTO `cleaning_activity`" + + "(`gis_street_id`, `video_file`, `left_file`, `right_file`, `work_status`, " + + "`cleaned_meter`, `inby`, `latitude`, `longitude`, `zone`, `ward`) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?)"; + + String insertSql = insertBeforeSql; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcStreetCleaningTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"activity_id"}); + int i = 1; + ps.setString(i++, gis_street_id); + ps.setString(i++, video); + ps.setString(i++, leftIMG); + ps.setString(i++, rightIMG); + ps.setString(i++, work_status); + ps.setString(i++, cleaned_meter); + ps.setString(i++, inby); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, zone); + ps.setString(i++, ward); + + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Street Cleaning", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", "Street Cleaning activity inserted successfully."); + } else { + response.put("Street Cleaning", action + " insertId error!"); + response.put("status", "error"); + response.put("message", "Street Cleaning activity insert failed."); + } + + result.add(response); + return result; + } + + /* + @Transactional + public List> getZoneReport(String loginid) { + // 1. Fetch all active streets for the ward (with zone info) + String sqlStreet = "SELECT sid, zone, ward, gis_street_id, street_name, road_type, street_length " + + "FROM street_list_master " + + "WHERE isactive = 1 AND isdelete = 0 ORDER BY zone ASC"; + + List> streetList = jdbcStreetCleaningTemplate.queryForList(sqlStreet); + + // Map> + Map> zoneSummary = new LinkedHashMap<>(); + + for (Map street : streetList) { + String zone = String.valueOf(street.get("zone")); + String gisStreetId = String.valueOf(street.get("gis_street_id")); + String wardNo = String.valueOf(street.get("ward")); + + // Fetch latest activity for this street + String sqlActivity = "SELECT work_status FROM cleaning_activity " + + "WHERE gis_street_id = ? AND zone = ? AND isactive = 1 AND isdelete = 0 " + + "ORDER BY indate DESC LIMIT 1"; + + List> activities = jdbcStreetCleaningTemplate.queryForList(sqlActivity, gisStreetId, zone); + + String status = "Pending"; // default + if (!activities.isEmpty()) { + Map last = activities.get(0); + String workStatus = (String) last.get("work_status"); + if (workStatus != null && !workStatus.equalsIgnoreCase("Partially")) { + status = "Completed"; + } + } + + // Initialize zone counters + zoneSummary.putIfAbsent(zone, new HashMap<>(Map.of( + "Total Street", 0, + "Completed", 0, + "Pending", 0 + ))); + + Map counts = zoneSummary.get(zone); + counts.put("Total Street", counts.get("Total Street") + 1); + if (status.equalsIgnoreCase("Completed")) { + counts.put("Completed", counts.get("Completed") + 1); + } else { + counts.put("Pending", counts.get("Pending") + 1); + } + } + + // Build final list + List> reportList = new ArrayList<>(); + for (var entry : zoneSummary.entrySet()) { + Map zoneReport = new LinkedHashMap<>(); + zoneReport.put("Zone", entry.getKey()); + zoneReport.putAll(entry.getValue()); + reportList.add(zoneReport); + } + + Map response = new LinkedHashMap<>(); + response.put("status", "Success"); + response.put("message", "Zone-wise Street Cleaning Report"); + response.put("data", reportList); + + return Collections.singletonList(response); + } + + @Transactional + public List> getWardReportByZone(String loginid, String zone) { + + // 1️⃣ Fetch all active streets under the given zone + String sqlStreet = "SELECT sid, zone, ward, gis_street_id, street_name, road_type, street_length " + + "FROM street_list_master " + + "WHERE zone = ? AND isactive = 1 AND isdelete = 0"; + + List> streetList = jdbcStreetCleaningTemplate.queryForList(sqlStreet, zone); + + // Map> + Map> wardSummary = new LinkedHashMap<>(); + + for (Map street : streetList) { + String ward = String.valueOf(street.get("ward")); + String gisStreetId = String.valueOf(street.get("gis_street_id")); + + // 2️⃣ Fetch the latest cleaning activity for this street + String sqlActivity = "SELECT work_status FROM cleaning_activity " + + "WHERE gis_street_id = ? AND ward = ? AND isactive = 1 AND isdelete = 0 " + + "ORDER BY indate DESC LIMIT 1"; + + List> activities = + jdbcStreetCleaningTemplate.queryForList(sqlActivity, gisStreetId, ward); + + String status = "Pending"; // Default + + if (!activities.isEmpty()) { + Map last = activities.get(0); + String workStatus = (String) last.get("work_status"); + if (workStatus != null && !workStatus.equalsIgnoreCase("Partially")) { + status = "Completed"; + } + } + + // 3️⃣ Initialize ward counters + wardSummary.putIfAbsent(ward, new HashMap<>(Map.of( + "Total Street", 0, + "Completed", 0, + "Pending", 0 + ))); + + Map counts = wardSummary.get(ward); + counts.put("Total Street", counts.get("Total Street") + 1); + if (status.equalsIgnoreCase("Completed")) { + counts.put("Completed", counts.get("Completed") + 1); + } else { + counts.put("Pending", counts.get("Pending") + 1); + } + } + + // 4️⃣ Build the final report list + List> reportList = new ArrayList<>(); + for (var entry : wardSummary.entrySet()) { + Map wardReport = new LinkedHashMap<>(); + wardReport.put("Ward", entry.getKey()); + wardReport.putAll(entry.getValue()); + reportList.add(wardReport); + } + + // 5️⃣ Prepare response + Map response = new LinkedHashMap<>(); + response.put("status", "Success"); + response.put("zone", zone); + response.put("message", "Ward-wise Street Cleaning Report for Zone " + zone); + response.put("data", reportList); + + return Collections.singletonList(response); + } + */ + + @Transactional + public List> getZoneReport(String loginid) { + // 1. Fetch all active streets for the ward (with zone info) + String sqlStreet = "SELECT" + + " CASE WHEN zone IS NULL THEN 'TOTAL' ELSE zone END AS Zone," + + " SUM(total_road_count) AS `Total Street`," + + " SUM(total_partially_completed) AS Pending," + + " SUM(total_fully_completed) AS Completed," + + " SUM(total_road_count) - (SUM(total_partially_completed) + SUM(total_fully_completed)) AS total_pending " + + "FROM (" + + " SELECT" + + " zone," + + " COUNT(*) AS total_road_count," + + " 0 AS total_partially_completed," + + " 0 AS total_fully_completed" + + " FROM gis_street_list" + + " WHERE isactive = 1 AND isdelete = 0" + + " GROUP BY zone" + + "" + + " UNION ALL" + + "" + + " SELECT" + + " sl.zone," + + " " + + " 0 AS total_road_count," + + " SUM(CASE WHEN ca.work_status = 'partially' THEN 1 ELSE 0 END) AS total_partially_completed," + + " SUM(CASE WHEN ca.work_status = 'completed' THEN 1 ELSE 0 END) AS total_fully_completed" + + " FROM street_list_master sl" + + " LEFT JOIN (" + + " SELECT ca1.*" + + " FROM cleaning_activity ca1" + + " INNER JOIN (" + + " SELECT gis_street_id, MAX(indate) AS last_indate" + + " FROM cleaning_activity" + + " WHERE isactive = 1 AND isdelete = 0" + + " GROUP BY gis_street_id" + + " ) ca2 " + + " ON ca1.gis_street_id = ca2.gis_street_id " + + " AND ca1.indate = ca2.last_indate" + + " WHERE ca1.isactive = 1 AND ca1.isdelete = 0" + + " ) ca ON sl.gis_street_id = ca.gis_street_id" + + " WHERE sl.isactive = 1 AND sl.isdelete = 0" + + " GROUP BY sl.zone" + + ") AS combined " + + "GROUP BY zone WITH ROLLUP " + + "ORDER BY " + + " CASE WHEN zone IS NULL THEN 999 ELSE CAST(zone AS UNSIGNED) END "; + + List> reportList = jdbcStreetCleaningTemplate.queryForList(sqlStreet); + + Map response = new LinkedHashMap<>(); + response.put("status", "Success"); + response.put("message", "Zone-wise Street Cleaning Report"); + response.put("data", reportList); + + return Collections.singletonList(response); + } + + @Transactional + public List> getWardReportByZone(String loginid, String zone) { + + // 1️⃣ Fetch all active streets under the given zone + String sqlStreet = "SELECT" + + " CASE WHEN ward IS NULL THEN 'TOTAL' ELSE ward END AS Ward," + + " SUM(total_road_count) AS `Total Street`," + + " SUM(total_partially_completed) AS Pending," + + " SUM(total_fully_completed) AS Completed," + + " SUM(total_road_count) - (SUM(total_partially_completed) + SUM(total_fully_completed)) AS total_pending " + + "FROM (" + + " SELECT" + + " ward," + + " COUNT(*) AS total_road_count," + + " 0 AS total_partially_completed," + + " 0 AS total_fully_completed" + + " FROM gis_street_list" + + " WHERE isactive = 1 AND isdelete = 0 AND zone = ?" + + " GROUP BY ward" + + "" + + " UNION ALL" + + "" + + " SELECT" + + " sl.ward," + + " 0 AS total_road_count," + + " SUM(CASE WHEN ca.work_status = 'partially' THEN 1 ELSE 0 END) AS total_partially_completed," + + " SUM(CASE WHEN ca.work_status = 'completed' THEN 1 ELSE 0 END) AS total_fully_completed" + + " FROM street_list_master sl" + + " LEFT JOIN (" + + " SELECT ca1.*" + + " FROM cleaning_activity ca1" + + " INNER JOIN (" + + " SELECT gis_street_id, MAX(indate) AS last_indate" + + " FROM cleaning_activity" + + " WHERE isactive = 1 AND isdelete = 0" + + " GROUP BY gis_street_id" + + " ) ca2 ON ca1.gis_street_id = ca2.gis_street_id AND ca1.indate = ca2.last_indate" + + " WHERE ca1.isactive = 1 AND ca1.isdelete = 0" + + " ) ca ON sl.gis_street_id = ca.gis_street_id" + + " WHERE sl.isactive = 1 AND sl.isdelete = 0 AND sl.zone = ?" + + " GROUP BY sl.ward" + + ") AS combined " + + "GROUP BY ward WITH ROLLUP " + + "ORDER BY " + + " CASE WHEN ward IS NULL THEN 999 ELSE CAST(ward AS UNSIGNED) END "; + + List> reportList = jdbcStreetCleaningTemplate.queryForList(sqlStreet, zone, zone); + + // 5️⃣ Prepare response + Map response = new LinkedHashMap<>(); + response.put("status", "Success"); + response.put("zone", zone); + response.put("message", "Ward-wise Street Cleaning Report for Zone " + zone); + response.put("data", reportList); + + return Collections.singletonList(response); + } + @Transactional + public List> getStreetListByWardAndStatus(String loginid, String ward, String status) { + + // 1️⃣ Fetch all streets for the ward + String sqlStreet = "SELECT sid, zone, ward, gis_street_id, street_name, road_type, " + + "street_length, isactive, isdelete, inby, cdate " + + "FROM street_list_master " + + "WHERE ward = ? AND isactive = 1 AND isdelete = 0"; + + List> streetList = jdbcStreetCleaningTemplate.queryForList(sqlStreet, ward); + + List> finalList = new ArrayList<>(); + + for (Map street : streetList) { + Map streetResponse = new HashMap<>(street); + + // 2️⃣ Get latest cleaning activity for the street + String sqlActivity = "SELECT activity_id, gis_street_id, video_file, left_file, right_file, " + + "work_status, cleaned_meter, inby, indate, isactive, isdelete, latitude, longitude, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', video_file) AS video_url, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', left_file) AS left_file_url, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', right_file) AS right_file_url " + + "FROM cleaning_activity " + + "WHERE gis_street_id = ? AND ward = ? AND isactive = 1 AND isdelete = 0 " + + "ORDER BY indate DESC LIMIT 1"; + + List> activities = jdbcStreetCleaningTemplate.queryForList( + sqlActivity, + street.get("gis_street_id"), + street.get("ward") + ); + + String overallStatus = "Pending"; // default + Map activityData = new HashMap<>(); + + if (!activities.isEmpty()) { + Map lastActivity = activities.get(0); + String workStatus = (String) lastActivity.get("work_status"); + + // logic: treat 'Partially' as 'Pending' + if (workStatus != null && !workStatus.equalsIgnoreCase("Partially")) { + overallStatus = "Completed"; + } + + activityData.put("status", overallStatus); + activityData.put("details", activities); + } else { + activityData.put("status", "Pending"); + activityData.put("details", Collections.emptyList()); + } + + // 3️⃣ Add computed status and activity info + streetResponse.put("status", overallStatus); + streetResponse.put("activities", activityData); + + // 4️⃣ Filter based on the requested status (pending/completed) + if (status == null || status.isEmpty() || overallStatus.equalsIgnoreCase(status)) { + finalList.add(streetResponse); + } + } + + // 5️⃣ Build response + Map response = new LinkedHashMap<>(); + response.put("status", "Success"); + response.put("message", "Street List for Ward " + ward + " (" + status + ")"); + response.put("ward", ward); + response.put("filter_status", status); + response.put("total", finalList.size()); + response.put("data", finalList); + + return Collections.singletonList(response); + } + + // For Rating + @Transactional + public List> getStreetListForRating(String loginid, String street_id, String ward) { + + String sqlStreet = "SELECT sid, zone, ward, gis_street_id, street_name, road_type, " + + "street_length, isactive, isdelete, inby, cdate " + + "FROM street_list_master " + + "WHERE gis_street_id = ? AND ward = ? AND isactive=1 AND isdelete=0"; + + List> streetList = jdbcStreetCleaningTemplate.queryForList(sqlStreet, street_id, ward); + List> finalList = new ArrayList<>(); + + for (Map street : streetList) { + Map streetResponse = new HashMap<>(); + streetResponse.putAll(street); + + // 1️⃣ Fetch latest cleaning activity + String sqlActivity = "SELECT activity_id, gis_street_id, video_file, left_file, right_file, " + + "work_status, cleaned_meter, inby, indate, isactive, isdelete, latitude, longitude, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', video_file) AS video_url, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', left_file) AS left_file_url, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', right_file) AS right_file_url " + + "FROM cleaning_activity " + + "WHERE gis_street_id = ? AND ward = ? AND isactive=1 AND isdelete=0 " + + "ORDER BY indate DESC LIMIT 1"; + + List> activities = jdbcStreetCleaningTemplate.queryForList( + sqlActivity, street.get("gis_street_id"), street.get("ward") + ); + + Map activityData = new HashMap<>(); + String overallStatus = "Pending"; + + if (!activities.isEmpty()) { + Map lastActivity = activities.get(0); + String workStatus = (String) lastActivity.get("work_status"); + + if ("Completed".equalsIgnoreCase(workStatus)) { + overallStatus = "Completed"; + } else { + overallStatus = "Pending"; + } + + activityData.put("status", overallStatus); + activityData.put("details", activities); + } else { + activityData.put("status", "Pending"); + activityData.put("details", Collections.emptyList()); + } + + // ❗️Skip if not completed + if (!"Completed".equalsIgnoreCase(overallStatus)) { + continue; + } + + // 2️⃣ Fetch rating info (only for Completed) + Map ratingData = new HashMap<>(); + String sqlRating = "SELECT rating_id, gis_street_id, video_file, left_file, right_file, " + + "work_rating, inby, indate, isactive, isdelete, latitude, longitude, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', video_file) AS video_url, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', left_file) AS left_file_url, " + + "CONCAT('" + fileBaseUrl + "/gccofficialapp/files', right_file) AS right_file_url " + + "FROM cleaning_activity_rating " + + "WHERE gis_street_id = ? AND ward = ? AND isactive=1 AND isdelete=0 " + + "ORDER BY indate DESC LIMIT 1"; + + List> ratings = jdbcStreetCleaningTemplate.queryForList( + sqlRating, street.get("gis_street_id"), street.get("ward") + ); + + if (!ratings.isEmpty()) { + ratingData.put("Rating_status", "Completed"); + ratingData.put("Rating_details", ratings); + } else { + ratingData.put("Rating_status", "Pending"); + ratingData.put("Rating_details", Collections.emptyList()); + } + + // 3️⃣ Merge into final response + streetResponse.put("status", overallStatus); + streetResponse.put("activities", activityData); + streetResponse.put("rating", ratingData); + + finalList.add(streetResponse); + } + + Map response = new HashMap<>(); + response.put("status", "Success"); + response.put("message", "Completed Street List with Ratings."); + response.put("data", finalList); + + return Collections.singletonList(response); + } + + @Transactional + public List> saveRatingActivity( + MultipartFile video_file, + MultipartFile left_file, + MultipartFile right_file, + String work_rating, + String zone, + String ward, + String gis_street_id, + String street_name, + String road_type, + String latitude, + String longitude, + String inby + ) { + + String filetxt =gis_street_id; + String action = "rating_"+inby; + + Map response = new HashMap<>(); + List> result = new ArrayList<>(); + + // For Left Image + String filetype = "image"; + String leftIMG = fileUpload(action, filetxt, left_file, filetype); + + if ("error".equalsIgnoreCase(leftIMG)) { + response.put("status", "error"); + response.put("message", "Street cleaning rating activity left image insert failed."); + result.add(response); + return result; + } + + // For Right Image + String rightIMG = fileUpload(action, filetxt, right_file, filetype); + + if ("error".equalsIgnoreCase(rightIMG)) { + response.put("status", "error"); + response.put("message", "Street cleaning rating activity right image insert failed."); + result.add(response); + } + + // For Video + filetype = "video"; + String video = fileUpload(action, filetxt, video_file, filetype); + + if ("error".equalsIgnoreCase(video)) { + response.put("status", "error"); + response.put("message", "Street cleaning rating activity video insert failed."); + result.add(response); + return result; + } + + String insertBeforeSql = "INSERT INTO `cleaning_activity_rating`" + + "(`gis_street_id`, `video_file`, `left_file`, `right_file`, `work_rating`, " + + " `inby`, `latitude`, `longitude`, `zone`, `ward`) " + + "VALUES (?,?,?,?,?,?,?,?,?,?)"; + + String insertSql = insertBeforeSql; + + KeyHolder keyHolder = new GeneratedKeyHolder(); + + int affectedRows = jdbcStreetCleaningTemplate.update(connection -> { + PreparedStatement ps = connection.prepareStatement(insertSql, new String[]{"rating_id"}); + int i = 1; + ps.setString(i++, gis_street_id); + ps.setString(i++, video); + ps.setString(i++, leftIMG); + ps.setString(i++, rightIMG); + ps.setString(i++, work_rating); + ps.setString(i++, inby); + ps.setString(i++, latitude); + ps.setString(i++, longitude); + ps.setString(i++, zone); + ps.setString(i++, ward); + + return ps; + }, keyHolder); + + if (affectedRows > 0) { + int lastInsertId = keyHolder.getKey().intValue(); + response.put("Street Cleaning rating", action + " insertId: " +lastInsertId); + response.put("status", "success"); + response.put("message", "Street Cleaning rating activity inserted successfully."); + } else { + response.put("Street Cleaning rataing", action + " insertId error!"); + response.put("status", "error"); + response.put("message", "Street Cleaning rating activity insert failed."); + } + + result.add(response); + return result; + } +} diff --git a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/viewCutter/service/viewCutterActivity.java b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/viewCutter/service/viewCutterActivity.java index 25b162c..2051c78 100644 --- a/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/viewCutter/service/viewCutterActivity.java +++ b/mobileservice/src/main/java/in/gov/chennaicorporation/mobileservice/viewCutter/service/viewCutterActivity.java @@ -323,11 +323,11 @@ private JdbcTemplate jdbcViewCutterTemplate; + "FROM `view_cutter_list` vcl " + "LEFT JOIN `view_cutter_undertaken` vcu " + " ON vcu.vcid = vcl.vcid AND vcu.isactive = 1 " - + "WHERE vcl.isactive = 1 "+sqlWhere; + + "WHERE vcl.isactive = 1 AND vcl.cby=? "+sqlWhere; //System.out.println(sql); - List> result = jdbcViewCutterTemplate.queryForList(sql); + List> result = jdbcViewCutterTemplate.queryForList(sql,loginid); ObjectMapper mapper = new ObjectMapper(); for (Map row : result) { diff --git a/mobileservice/src/main/resources/application.properties b/mobileservice/src/main/resources/application.properties index 5bce45c..3bf20ac 100644 --- a/mobileservice/src/main/resources/application.properties +++ b/mobileservice/src/main/resources/application.properties @@ -58,3 +58,14 @@ busshelter_renovation_foldername=bus_shelter_renovation_files/ view_cutter_foldername = view_cutter_files/ buildingdemolition_foldername = building_demolition_files/ roadwar_foldername = roadwar_register_files/ +manhole_foldername = manhole_activity/ +disposalpoint_foldername=disposalpoint_activity/ +StreetCleaning_foldername=streetcleaning_activity/ +pump_foldername=pump_activity/ +vehicle_foldername=special_vehicle_activity/ +scp_foldername=scp_activity/ +sluicepoint_foldername=sluicepoint_activity/ +culvert_foldername=railway_culvert_activity/ +fooddistribution_foldername = food_distribution_file/ +flagpole_foldername=flagpole_images/ +healthcamp_folder=healthcamp_images/