From ab93f2a9c1cbe1561f03b0662d15e2084834e6fd Mon Sep 17 00:00:00 2001 From: kanimozhi Date: Thu, 5 Feb 2026 17:43:51 +0530 Subject: [PATCH] Officer Portal Updated code --- .../service/QaqcAgentsService.java | 67 +- .../gccoffice/configuration/AppConfig.java | 9 + .../configuration/DataSourceConfig.java | 400 +++--- .../controller/FlagPoleApiController.java | 231 +++- .../flagpole/service/FlagpoleSMSService.java | 133 ++ .../flagpole/service/RdoService.java | 1225 +++++++++-------- .../service/WhatsappServiceFlagPole.java | 45 +- .../flagpole/util/MessageUtility.java | 41 + .../service/PendinglistService.java | 4 + .../nulm/controller/NulmAPIController.java | 3 +- .../gccoffice/nulm/service/NulmService.java | 9 +- .../src/main/resources/application.properties | 4 +- .../callcenterqaqc/socialmediacomplaints.html | 4 +- .../flagpole/approvedandrejectedlist.html | 31 +- .../modules/flagpole/requestlist.html | 549 +++++--- .../modules/m_petition/complaint_list.html | 1 + .../modules/m_petition/petition_list.html | 1 + .../modules/nulm/salary-approve.html | 3 + 18 files changed, 1690 insertions(+), 1070 deletions(-) create mode 100644 gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/service/FlagpoleSMSService.java create mode 100644 gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/util/MessageUtility.java diff --git a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/callcenterqaqc/service/QaqcAgentsService.java b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/callcenterqaqc/service/QaqcAgentsService.java index 6dfa0a9f..556eb2c2 100644 --- a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/callcenterqaqc/service/QaqcAgentsService.java +++ b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/callcenterqaqc/service/QaqcAgentsService.java @@ -239,29 +239,50 @@ public class QaqcAgentsService { public List> getAgentPerformanceData(int agentId, String startDate, String endDate) { - String sql = "SELECT \n" - + " COALESCE(total_data_count, 0) AS total_data_count,\n" // Ensure total_data_count is 0 if null - + " COALESCE(completed_count, 0) AS completed_count,\n" // Ensure completed_count is 0 if null - + " COALESCE((total_data_count - completed_count), 0) AS pending_count,\n" // Ensure pending_count is 0 - + " CASE \n" - + " WHEN COALESCE(total_data_count, 0) > 0 THEN ROUND((COALESCE(completed_count, 0) / total_data_count) * 100, 1)\n" - + " ELSE 0\n" - + " END AS completed_percentage\n" - + "FROM \n" - + " (\n" - + " SELECT \n" - + " (SELECT COALESCE(SUM(aa.data_count), 0) \n" - + " FROM agent_assigned aa \n" - + " WHERE aa.agent_id = ? AND DATE(aa.created_date) BETWEEN ? AND ?) AS total_data_count,\n" - + " \n" - + " (SELECT COALESCE(COUNT(*), 0) \n" - + " FROM qaqc_call_logs cl \n" - + " WHERE cl.agent_id = ?\n" - + " AND DATE(cl.created_date) BETWEEN ? AND ? \n" - + " AND cl.call_status IS NOT NULL) AS completed_count\n" - + " ) AS combined"; - - return jdbcTemplate.queryForList(sql, agentId, startDate, endDate, agentId, startDate, endDate); + // String sql = "SELECT \n" + // + " COALESCE(total_data_count, 0) AS total_data_count,\n" // Ensure total_data_count is 0 if null + // + " COALESCE(completed_count, 0) AS completed_count,\n" // Ensure completed_count is 0 if null + // + " COALESCE((total_data_count - completed_count), 0) AS pending_count,\n" // Ensure pending_count is 0 + // + " CASE \n" + // + " WHEN COALESCE(total_data_count, 0) > 0 THEN ROUND((COALESCE(completed_count, 0) / total_data_count) * 100, 1)\n" + // + " ELSE 0\n" + // + " END AS completed_percentage\n" + // + "FROM \n" + // + " (\n" + // + " SELECT \n" + // + " (SELECT COALESCE(SUM(aa.data_count), 0) \n" + // + " FROM agent_assigned aa \n" + // + " WHERE aa.agent_id = ? AND DATE(aa.created_date) BETWEEN ? AND ?) AS total_data_count,\n" + // + " \n" + // + " (SELECT COALESCE(COUNT(*), 0) \n" + // + " FROM qaqc_call_logs cl \n" + // + " WHERE cl.agent_id = ?\n" + // + " AND DATE(cl.created_date) BETWEEN ? AND ? \n" + // + " AND cl.call_status IS NOT NULL) AS completed_count\n" + // + " ) AS combined"; + + // return jdbcTemplate.queryForList(sql, agentId, startDate, endDate, agentId, startDate, endDate); + + String sql="SELECT " + + " total_data_count," + + " completed_count," + + " (total_data_count - completed_count) AS pending_count," + + " CASE " + + " WHEN total_data_count > 0 " + + " THEN ROUND((completed_count / total_data_count) * 100, 1)" + + " ELSE 0" + + " END AS completed_percentage" + + " FROM (" + + " SELECT " + + " COUNT(*) AS total_data_count," + + " COUNT(call_status) AS completed_count" + + " FROM qaqc_upload_data_history" + + " WHERE created_date >= ? " + + " AND created_date < DATE_ADD( ? , INTERVAL 1 DAY)" + + " AND agent_id = ? " + + ") t"; + + return jdbcTemplate.queryForList(sql, startDate, endDate, agentId); } diff --git a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/configuration/AppConfig.java b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/configuration/AppConfig.java index feafa90e..8693e49d 100644 --- a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/configuration/AppConfig.java +++ b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/configuration/AppConfig.java @@ -25,6 +25,15 @@ public class AppConfig { public String gccappsMysqlPassword = ""; public String domesticurl="https://gccservices.in/gccofficialapp/api/domesticwaste"; + public String otpUrl = "https://tmegov.onex-aura.com/api/sms?"; + + public String getOtpUrl() { + return otpUrl; + } + + public void setOtpUrl(String otpUrl) { + this.otpUrl = otpUrl; + } @Bean public RestTemplate restTemplate() { return new RestTemplate(); diff --git a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/configuration/DataSourceConfig.java b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/configuration/DataSourceConfig.java index bd5ec459..0b0c7de6 100644 --- a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/configuration/DataSourceConfig.java +++ b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/configuration/DataSourceConfig.java @@ -23,386 +23,390 @@ import java.util.Properties; @Configuration @EnableTransactionManagement public class DataSourceConfig { - - //private static String host = "localhost:3306"; - //private static String dbpassword = ""; - + + private static String host = "localhost:3306"; + private static String dbpassword = "root"; + // private static String dbpassword = "gccroot"; - - // AWS - private static String host = "gcc-facial-db-instance-1.cf48eqcciziq.ap-south-1.rds.amazonaws.com:3306"; - private static String dbpassword = "gcc-facial-password"; - - //////////////////////////////(For GCC APP) //////////////////////// - @Configuration - @EnableTransactionManagement - @EnableJpaRepositories( - entityManagerFactoryRef = "appEntityManagerFactory", - transactionManagerRef = "appTransactionManager", - basePackages = {"in.gov.chennaicorporation.gccoffice.repository"}) - - public static class MysqlAppDataSourceConfig { - @Primary - @Bean(name = "mysqlAppDataSource") - public DataSource mysqlAppDataSource() { - DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/gcc_apps"); - dataSource.setUsername("root"); - dataSource.setPassword(dbpassword); - return dataSource; - } -/* - @Bean(name = "mysqlAppJdbcTemplate") - public JdbcTemplate mysqlAppJdbcTemplate(@Qualifier("mysqlAppDataSource") DataSource dataSource) { - return new JdbcTemplate(dataSource); - } -*/ - @Primary - @Bean(name="appEntityManagerFactory") - public LocalContainerEntityManagerFactoryBean entityManagerFactory( - @Qualifier("mysqlAppDataSource") DataSource dataSource) { - LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); - entityManagerFactoryBean.setDataSource(dataSource); - entityManagerFactoryBean.setPackagesToScan("in.gov.chennaicorporation.gccoffice.entity"); - entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class); - Properties properties = new Properties(); - properties.setProperty("hibernate.hbm2ddl.auto", "update"); - entityManagerFactoryBean.setJpaProperties(properties); - - return entityManagerFactoryBean; - } - - @Primary - @Bean(name = "appTransactionManager") - public PlatformTransactionManager transactionManager(@Qualifier("appEntityManagerFactory") EntityManagerFactory entityManagerFactory) { - return new JpaTransactionManager(entityManagerFactory); - } - } - - //////////////////////////////(For Tax Collection 1913) //////////////////////// - @Configuration - @EnableTransactionManagement - @EnableJpaRepositories( - entityManagerFactoryRef = "taxEntityManagerFactory", - transactionManagerRef = "taxTransactionManager", - basePackages = {"in.gov.chennaicorporation.gccoffice.taxcollection.repository"}) - public static class MysqlTaxCollectionDataSourceConfig { - - @Bean(name = "mysqlTaxCollectionDataSource") - public DataSource mysqlTaxCollectionDataSource() { - DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/gcc_tax_collection"); - dataSource.setUsername("root"); - dataSource.setPassword(dbpassword); - return dataSource; - } - - @Bean(name="taxEntityManagerFactory") - public LocalContainerEntityManagerFactoryBean taxEntityManagerFactory( - @Qualifier("mysqlTaxCollectionDataSource") DataSource dataSource) { - LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); - entityManagerFactoryBean.setDataSource(dataSource); - entityManagerFactoryBean.setPackagesToScan("in.gov.chennaicorporation.gccoffice.taxcollection.entity"); - entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class); - Properties properties = new Properties(); - properties.setProperty("hibernate.hbm2ddl.auto", "update"); - entityManagerFactoryBean.setJpaProperties(properties); - - return entityManagerFactoryBean; - } - - @Bean(name = "taxTransactionManager") - public PlatformTransactionManager taxTransactionManager(@Qualifier("taxEntityManagerFactory") EntityManagerFactory taxEntityManagerFactory) { - return new JpaTransactionManager(taxEntityManagerFactory); - } - } - - - - //////////////////////////////(For Mayor Petition) //////////////////////// + + // AWS + // private static String host = + // "gcc-facial-db-instance-1.cf48eqcciziq.ap-south-1.rds.amazonaws.com:3306"; + // private static String dbpassword = "gcc-facial-password"; + + ////////////////////////////// (For GCC APP) //////////////////////// + @Configuration + @EnableTransactionManagement + @EnableJpaRepositories(entityManagerFactoryRef = "appEntityManagerFactory", transactionManagerRef = "appTransactionManager", basePackages = { + "in.gov.chennaicorporation.gccoffice.repository" }) + + public static class MysqlAppDataSourceConfig { + @Primary + @Bean(name = "mysqlAppDataSource") + public DataSource mysqlAppDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_apps"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + + /* + * @Bean(name = "mysqlAppJdbcTemplate") + * public JdbcTemplate mysqlAppJdbcTemplate(@Qualifier("mysqlAppDataSource") + * DataSource dataSource) { + * return new JdbcTemplate(dataSource); + * } + */ + @Primary + @Bean(name = "appEntityManagerFactory") + public LocalContainerEntityManagerFactoryBean entityManagerFactory( + @Qualifier("mysqlAppDataSource") DataSource dataSource) { + LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); + entityManagerFactoryBean.setDataSource(dataSource); + entityManagerFactoryBean.setPackagesToScan("in.gov.chennaicorporation.gccoffice.entity"); + entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class); + Properties properties = new Properties(); + properties.setProperty("hibernate.hbm2ddl.auto", "update"); + entityManagerFactoryBean.setJpaProperties(properties); + + return entityManagerFactoryBean; + } + + @Primary + @Bean(name = "appTransactionManager") + public PlatformTransactionManager transactionManager( + @Qualifier("appEntityManagerFactory") EntityManagerFactory entityManagerFactory) { + return new JpaTransactionManager(entityManagerFactory); + } + } + + ////////////////////////////// (For Tax Collection 1913) + ////////////////////////////// //////////////////////// + @Configuration + @EnableTransactionManagement + @EnableJpaRepositories(entityManagerFactoryRef = "taxEntityManagerFactory", transactionManagerRef = "taxTransactionManager", basePackages = { + "in.gov.chennaicorporation.gccoffice.taxcollection.repository" }) + public static class MysqlTaxCollectionDataSourceConfig { + + @Bean(name = "mysqlTaxCollectionDataSource") + public DataSource mysqlTaxCollectionDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_tax_collection"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + + @Bean(name = "taxEntityManagerFactory") + public LocalContainerEntityManagerFactoryBean taxEntityManagerFactory( + @Qualifier("mysqlTaxCollectionDataSource") DataSource dataSource) { + LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); + entityManagerFactoryBean.setDataSource(dataSource); + entityManagerFactoryBean.setPackagesToScan("in.gov.chennaicorporation.gccoffice.taxcollection.entity"); + entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class); + Properties properties = new Properties(); + properties.setProperty("hibernate.hbm2ddl.auto", "update"); + entityManagerFactoryBean.setJpaProperties(properties); + + return entityManagerFactoryBean; + } + + @Bean(name = "taxTransactionManager") + public PlatformTransactionManager taxTransactionManager( + @Qualifier("taxEntityManagerFactory") EntityManagerFactory taxEntityManagerFactory) { + return new JpaTransactionManager(taxEntityManagerFactory); + } + } + + ////////////////////////////// (For Mayor Petition) //////////////////////// @Bean(name = "mysqlMayorPetitionDataSource") public DataSource mysqlMayorPetitionDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/mayor_petition"); + dataSource.setUrl("jdbc:mysql://" + host + "/mayor_petition"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - //////////////////////////////(For Commissioner Petition) //////////////////////// + ////////////////////////////// (For Commissioner Petition) + ////////////////////////////// //////////////////////// @Bean(name = "mysqlCommissionerPetitionDataSource") public DataSource mysqlCommissionerPetitionDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/commissioner_petition"); + dataSource.setUrl("jdbc:mysql://" + host + "/commissioner_petition"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - //////////////////////////////(For Petition Master) //////////////////////// - @Bean(name = "mysqlPetitionMasterDataSource") - public DataSource mysqlPetitionMasterDataSource() { - DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/petition_master"); - dataSource.setUsername("root"); - dataSource.setPassword(dbpassword); - return dataSource; - } - - //////////////////////////////(For Councillor Petition) //////////////////////// + ////////////////////////////// (For Petition Master) //////////////////////// + @Bean(name = "mysqlPetitionMasterDataSource") + public DataSource mysqlPetitionMasterDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + host + "/petition_master"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; + } + + ////////////////////////////// (For Councillor Petition) + ////////////////////////////// //////////////////////// @Bean(name = "mysqlCouncillorPetitionDataSource") public DataSource mysqlCouncillorPetitionDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/councillor_petition"); + dataSource.setUrl("jdbc:mysql://" + host + "/councillor_petition"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - - //////////////////////////////(For PGR Master) //////////////////////// + + ////////////////////////////// (For PGR Master) //////////////////////// @Bean(name = "mysqlPGRMasterDataSource") public DataSource mysqlPGRMasterDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/erp_pgr"); + dataSource.setUrl("jdbc:mysql://" + host + "/erp_pgr"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - - //////////////////////////////(For Circular Petition) //////////////////////// + + ////////////////////////////// (For Circular Petition) //////////////////////// @Bean(name = "mysqlCircularDataSource") public DataSource mysqlCircularDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/circular"); + dataSource.setUrl("jdbc:mysql://" + host + "/circular"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - - //////////////////////////////(For NULM Staff) //////////////////////// + + ////////////////////////////// (For NULM Staff) //////////////////////// @Bean(name = "mysqlNulmDataSource") public DataSource mysqlNulmDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/gcc_nulm"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_nulm"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - - //////////////////////////////(For Zero Hours Petition) //////////////////////// + + ////////////////////////////// (For Zero Hours Petition) + ////////////////////////////// //////////////////////// @Bean(name = "mysqlZeroHoursDataSource") public DataSource mysqlZeroHoursDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/zerohours_petition"); + dataSource.setUrl("jdbc:mysql://" + host + "/zerohours_petition"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - - //////////////////////////////(For Ward Sabha) //////////////////////// + + ////////////////////////////// (For Ward Sabha) //////////////////////// @Bean(name = "mysqlWardSabhaDataSource") public DataSource mysqlWardSabhaDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/ward_sabha"); + dataSource.setUrl("jdbc:mysql://" + host + "/ward_sabha"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - - //////////////////////////////(For 1913 Campaign) //////////////////////// + + ////////////////////////////// (For 1913 Campaign) //////////////////////// @Bean(name = "mysql1913CampaignDataSource") public DataSource mysql1913CampaignDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/gcc_1913_campaign"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_1913_campaign"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - - //////////////////////////////(For 1913 QAQC) //////////////////////// + + ////////////////////////////// (For 1913 QAQC) //////////////////////// @Bean(name = "mysql1913QAQCDataSource") public DataSource mysql1913QAQCDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/gcc_1913_qaqc"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_1913_qaqc"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - - //////////////////////////////(For SOS) //////////////////////// + + ////////////////////////////// (For SOS) //////////////////////// @Bean(name = "mysqlGccSOSDataSource") public DataSource mysqlGccSOSDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/gcc_sos"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_sos"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - - //////////////////////////////(For Kural) //////////////////////// + + ////////////////////////////// (For Kural) //////////////////////// @Bean(name = "mysqlKuralDataSource") public DataSource mysqlKuralDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/Kural"); + dataSource.setUrl("jdbc:mysql://" + host + "/Kural"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - - //////////////////////////////(For WORKS) //////////////////////// + + ////////////////////////////// (For WORKS) //////////////////////// @Bean(name = "mysqlWorksDataSource") public DataSource mysqlWorksDataSource() { - DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/gcc_works_status"); - dataSource.setUsername("root"); - dataSource.setPassword(dbpassword); - return dataSource; + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_works_status"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; } - - //////////////////////////////(For Ward Sabha) //////////////////////// + + ////////////////////////////// (For Ward Sabha) //////////////////////// @Bean(name = "mysqlWardShabaDataSource") public DataSource mysqlWardShabaDataSource() { - DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/ward_sabha"); - dataSource.setUsername("root"); - dataSource.setPassword(dbpassword); - return dataSource; + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://" + host + "/ward_sabha"); + dataSource.setUsername("root"); + dataSource.setPassword(dbpassword); + return dataSource; } - - //////////////////////////////(For V-Track (jTrack)) //////////////////////// + + ////////////////////////////// (For V-Track (jTrack)) //////////////////////// @Bean(name = "mysqlVehiclTrackingDataSource") public DataSource mysqlVehiclTrackingDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/gcc_vtrack"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_vtrack"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - - //////////////////////////////(For school) //////////////////////// + + ////////////////////////////// (For school) //////////////////////// @Bean(name = "mysqlSchoolDataSource") public DataSource mysqlSchoolDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/gcc_schools_web"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_schools_web"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - - //////////////////////////////(For dump registration) //////////////////////// + + ////////////////////////////// (For dump registration) //////////////////////// @Bean(name = "mysqlFlagPoleManagerSystemDataSource") public DataSource mysqlFlagPoleManagerSystemDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/gcc_flag_pole"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_flag_pole"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); - return dataSource; + return dataSource; } - //////////////////////////////(For gcc_c_d_waste_web) //////////////////////// + ////////////////////////////// (For gcc_c_d_waste_web) //////////////////////// @Bean(name = "mysqlCDManagerSystemDataSource") public DataSource mysqlCDManagerSystemDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/gcc_c_d_waste_web"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_c_d_waste_web"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - - //////////////////////////////(For gcc_c_d_waste_web) //////////////////////// + + ////////////////////////////// (For gcc_c_d_waste_web) //////////////////////// @Bean(name = "mysqlPensionerDataSource") - public DataSource mysqlPensionerDataSource() { + public DataSource mysqlPensionerDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/gcc_pensioner"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_pensioner"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); return dataSource; } - //////////////////////////////(For gcc_c_d_waste_web) //////////////////////// + ////////////////////////////// (For gcc_c_d_waste_web) //////////////////////// @Bean(name = "mysqlGccStreetVendorDataSource") - public DataSource mysqlGccStreetVendorDataSource() { + public DataSource mysqlGccStreetVendorDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/gcc_street_vendor"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_street_vendor"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); - return dataSource; + return dataSource; } - //////////////////////////////(For vending committe) //////////////////////// + + ////////////////////////////// (For vending committe) //////////////////////// @Bean(name = "mysqlVendingCommitteDataSource") public DataSource mysqlVendingCommitteDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/vendingcommitte"); + dataSource.setUrl("jdbc:mysql://" + host + "/vendingcommitte"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); - return dataSource; + return dataSource; } - + /////////////// Domestic Waste ///////////////////// @Bean(name = "mysqlDomesticWasteDataSource") public DataSource mysqlDomesticWasteDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/domestic_waste_management"); + dataSource.setUrl("jdbc:mysql://" + host + "/domestic_waste_management"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); - return dataSource; + return dataSource; } - + /////////////// Green committee ///////////////////// @Bean(name = "mysqlGreenCommitteeDataSource") public DataSource mysqlGreenCommitteeDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/green_committee"); + dataSource.setUrl("jdbc:mysql://" + host + "/green_committee"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); - return dataSource; + return dataSource; } - + /////////////// SCP ///////////////////// @Bean(name = "mysqlScpDataSource") public DataSource mysqlScpDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); - dataSource.setUrl("jdbc:mysql://"+host+"/gcc_1913_siltcatchpit"); + dataSource.setUrl("jdbc:mysql://" + host + "/gcc_1913_siltcatchpit"); dataSource.setUsername("root"); dataSource.setPassword(dbpassword); - return dataSource; + return dataSource; } ////////////////////////////// ORACLE //////////////////////// - @Bean(name = "oracleDataSource") - public DataSource oracleDataSource() { - DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName("oracle.jdbc.OracleDriver"); - dataSource.setUrl("jdbc:oracle:thin:@10.1.0.14:1521:chncorp"); - dataSource.setUsername("FAS"); - dataSource.setPassword("FAS"); - return dataSource; - } + @Bean(name = "oracleDataSource") + public DataSource oracleDataSource() { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("oracle.jdbc.OracleDriver"); + dataSource.setUrl("jdbc:oracle:thin:@10.1.0.14:1521:chncorp"); + dataSource.setUsername("FAS"); + dataSource.setPassword("FAS"); + return dataSource; + } } \ No newline at end of file diff --git a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/controller/FlagPoleApiController.java b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/controller/FlagPoleApiController.java index 3506349c..36733dcb 100644 --- a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/controller/FlagPoleApiController.java +++ b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/controller/FlagPoleApiController.java @@ -1,12 +1,8 @@ package in.gov.chennaicorporation.gccoffice.flagpole.controller; -import java.util.Collections; import java.util.List; import java.util.Map; -import javax.annotation.Generated; -import javax.servlet.http.HttpSession; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -17,8 +13,8 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; -import in.gov.chennaicorporation.gccoffice.cdwaste.service.OfficerService; import in.gov.chennaicorporation.gccoffice.configuration.AppConfig; +import in.gov.chennaicorporation.gccoffice.flagpole.service.FlagpoleSMSService; import in.gov.chennaicorporation.gccoffice.flagpole.service.RdoService; @RestController @@ -28,6 +24,9 @@ public class FlagPoleApiController { @Autowired private RdoService rdoService; + @Autowired + private FlagpoleSMSService flagpoleSMSService; + private final RestTemplate restTemplate; private final AppConfig appConfig; @@ -37,7 +36,7 @@ public class FlagPoleApiController { this.appConfig = appConfig; } - // old + // new // @GetMapping("/getAllDetails") // public ResponseEntity getAllRequestDetails( // @RequestParam String userLogin, @@ -49,6 +48,19 @@ public class FlagPoleApiController { // rdoService.getAllRequestDetailsByUserLogin( // userLogin, startDate, endDate); + // // 🔥 Attach HISTORY per refid + // for (Map record : result) { + // String refid = (String) record.get("refid"); + + // // List> history = + // // rdoService.getRequestHistoryByRefId(refid); + // List> history = + // rdoService.getOfficerFeedbackHistoryByRefId(refid, + // userLogin); + + // record.put("history", history); + // } + // return ResponseEntity.ok( // Map.of( // "status", "success", @@ -58,33 +70,79 @@ public class FlagPoleApiController { // } catch (Exception e) { // e.printStackTrace(); // return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - // .body( + // .body(Map.of( + // "status", "error", + // "message", "Failed to fetch data", + // "error", e.getMessage())); + // } + // } + + // @GetMapping("/getAllDetails") + // public ResponseEntity getAllRequestDetails( + // @RequestParam String gccUserId, + // @RequestParam(required = false) String startDate, + // @RequestParam(required = false) String endDate) { + + // try { + + // // 🔥 Resolve username ONCE (backend trust) + // String username = rdoService.getUsernameByUserId(gccUserId); + // if (username == null) { + // throw new RuntimeException("Invalid gccUserId : " + gccUserId); + // } + + // List> result = + // rdoService.getAllRequestDetailsByUserLogin( + // gccUserId, startDate, endDate); + + // // 🔥 Attach HISTORY per refid (dept-wise) + // for (Map record : result) { + // String refid = (String) record.get("refid"); + + // List> history = + // rdoService.getOfficerFeedbackHistoryByRefId( + // refid, username); + + // record.put("history", history); + // } + + // return ResponseEntity.ok( // Map.of( + // "status", "success", + // "count", result.size(), + // "data", result)); + + // } catch (Exception e) { + // e.printStackTrace(); + // return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + // .body(Map.of( // "status", "error", // "message", "Failed to fetch data", // "error", e.getMessage())); // } // } - // new @GetMapping("/getAllDetails") public ResponseEntity getAllRequestDetails( - @RequestParam String userLogin, + @RequestParam String gccUserId, @RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate) { try { - List> result = rdoService.getAllRequestDetailsByUserLogin( - userLogin, startDate, endDate); - // 🔥 Attach HISTORY per refid + /* 🔥 Normalize input (username OR id → gccuserid) */ + gccUserId = rdoService.resolveGccUserId(gccUserId); + + List> result = rdoService.getAllRequestDetailsByUserLogin(gccUserId, + startDate, endDate); + + /* 🔥 Attach HISTORY per refid */ for (Map record : result) { + String refid = (String) record.get("refid"); - // List> history = - // rdoService.getRequestHistoryByRefId(refid); List> history = rdoService.getOfficerFeedbackHistoryByRefId(refid, - userLogin); + gccUserId); record.put("history", history); } @@ -105,19 +163,41 @@ public class FlagPoleApiController { } } + // old + // @PostMapping("/rdo/updateDecision") + // public ResponseEntity updateRdoDecision( + // @RequestParam String refid, + // @RequestParam String status, + // @RequestParam String remarks, + // @RequestParam String approvedBy) { + + // int count = rdoService.updateRdoDecision(refid, status, remarks, approvedBy); + + // if (count > 0) { + // return ResponseEntity.ok(Map.of( + // "status", "SUCCESS", + // "message", "Decision updated successfully")); + // } else { + // return ResponseEntity.badRequest().body(Map.of( + // "status", "FAILED", + // "message", "Unable to update decision")); + // } + // } + // @PostMapping("/rdo/updateDecision") // public ResponseEntity updateRdoDecision( // @RequestParam String refid, // @RequestParam String status, // @RequestParam String remarks, - // @RequestParam String approvedBy // 🔥 FROM JS - // ) { + // @RequestParam String gccUserId) { + + // try { + + // /* 🔥 Normalize username OR id → gccuserid */ + // gccUserId = rdoService.resolveGccUserId(gccUserId); // int count = rdoService.updateRdoDecision( - // refid, - // status, - // remarks, - // approvedBy); + // refid, status, remarks, gccUserId); // if (count > 0) { // return ResponseEntity.ok(Map.of( @@ -128,25 +208,52 @@ public class FlagPoleApiController { // "status", "FAILED", // "message", "Unable to update decision")); // } + + // } catch (Exception e) { + // e.printStackTrace(); + // return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + // .body(Map.of( + // "status", "ERROR", + // "message", e.getMessage())); + // } // } - @PostMapping("/rdo/updateDecision") - public ResponseEntity updateRdoDecision( + @PostMapping("/officer/updateDecision") + public ResponseEntity updateOfficerDecision( @RequestParam String refid, @RequestParam String status, @RequestParam String remarks, - @RequestParam String approvedBy) { + @RequestParam String gccUserId, + @RequestParam String username) { - int count = rdoService.updateRdoDecision(refid, status, remarks, approvedBy); + try { - if (count > 0) { - return ResponseEntity.ok(Map.of( - "status", "SUCCESS", - "message", "Decision updated successfully")); - } else { - return ResponseEntity.badRequest().body(Map.of( - "status", "FAILED", - "message", "Unable to update decision")); + /* 🔥 Normalize username OR id → gccuserid */ + gccUserId = rdoService.resolveGccUserId(gccUserId); + + int count = rdoService.updateOfficerDecision( + refid, + status, + remarks, + gccUserId, + username); + + if (count > 0) { + return ResponseEntity.ok(Map.of( + "status", "SUCCESS", + "message", "Decision updated successfully")); + } else { + return ResponseEntity.badRequest().body(Map.of( + "status", "FAILED", + "message", "Unable to update decision")); + } + + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of( + "status", "ERROR", + "message", e.getMessage())); } } @@ -219,22 +326,65 @@ public class FlagPoleApiController { // } // } + // @GetMapping("/getApprovedAndRejectedDetails") + // public ResponseEntity getApprovedRequestDetails( + // @RequestParam String userLogin, + // @RequestParam(required = false) String startDate, + // @RequestParam(required = false) String endDate) { + + // try { + // List> result = + // rdoService.getRdoApprovedRequestDetailsByUserLogin( + // userLogin, startDate, endDate, null); + + // for (Map record : result) { + // String refid = (String) record.get("refid"); + + // // 🔥 NEW: officer feedback history + // List> history = + // rdoService.getOfficerFeedbackHistoryByRefId(refid, + // userLogin); + + // record.put("history", history); + // } + + // return ResponseEntity.ok(Map.of( + // "status", "success", + // "count", result.size(), + // "data", result)); + + // } catch (Exception e) { + // e.printStackTrace(); + // return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + // .body(Map.of( + // "status", "error", + // "message", "Failed to fetch data", + // "error", e.getMessage())); + // } + // } + @GetMapping("/getApprovedAndRejectedDetails") public ResponseEntity getApprovedRequestDetails( - @RequestParam String userLogin, + @RequestParam String gccUserId, @RequestParam(required = false) String startDate, @RequestParam(required = false) String endDate) { try { + + /* 🔥 Normalize username OR id → gccuserid */ + gccUserId = rdoService.resolveGccUserId(gccUserId); + + /* 🔥 Fetch approved & rejected records */ List> result = rdoService.getRdoApprovedRequestDetailsByUserLogin( - userLogin, startDate, endDate, null); + gccUserId, startDate, endDate, null); + /* 🔥 Attach officer feedback history per refid */ for (Map record : result) { + String refid = (String) record.get("refid"); - // 🔥 NEW: officer feedback history List> history = rdoService.getOfficerFeedbackHistoryByRefId(refid, - userLogin); + gccUserId); record.put("history", history); } @@ -249,9 +399,14 @@ public class FlagPoleApiController { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(Map.of( "status", "error", - "message", "Failed to fetch data", + "message", "Failed to fetch approved/rejected data", "error", e.getMessage())); } } + @GetMapping("/sendRejectMessage") + public void sendRejectMessage(@RequestParam String mobileNo, @RequestParam String refid) { + flagpoleSMSService.userrequestRejectedsms(mobileNo, refid); + } + } diff --git a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/service/FlagpoleSMSService.java b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/service/FlagpoleSMSService.java new file mode 100644 index 00000000..c1105fc0 --- /dev/null +++ b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/service/FlagpoleSMSService.java @@ -0,0 +1,133 @@ +package in.gov.chennaicorporation.gccoffice.flagpole.service; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import in.gov.chennaicorporation.gccoffice.configuration.AppConfig; +import in.gov.chennaicorporation.gccoffice.flagpole.util.MessageUtility; + +@Service +public class FlagpoleSMSService { + + @Autowired + private AppConfig appConfig; + + @Autowired + private MessageUtility messageUtility; + + private final String key = "pfTEYN6H"; + + public String sendBookingSuccesssms(String mobileNo, String requestId) { + + String message = "Your Flag Pole permission request has been submitted successfully. " + + "Request ID: " + requestId + + ". You will be notified once the status is updated. By GCC"; + + // Encode message and fix colon issue (gateway not decoding %3A) + String encodedMsg = URLEncoder.encode(message, StandardCharsets.UTF_8) + .replace("%3A", ":"); + + String urlString = appConfig.getOtpUrl() + + "from=GCCCRP" + + "&key=" + key + + "&sender=GCCCRP" + + "&to=" + mobileNo + + "&body=" + encodedMsg + + "&entityid=1401572690000011081" + + "&templateid=1407176959297472163"; + + System.out.println("SMS URL:- " + urlString); + + String response = messageUtility.sendSMS(urlString); + System.out.println("SMS RESPONSE:- " + response); + + return response; + } + + public String userrequestApprovedsms(String mobileNo, String requestId) { + + String message = "Your Flag Pole permission request has been approved. " + + "Request ID: " + requestId + + ". Please proceed as per the permitted guidelines. By GCC"; + + // Encode message and fix colon issue (gateway not decoding %3A) + String encodedMsg = URLEncoder.encode(message, StandardCharsets.UTF_8) + .replace("%3A", ":"); + + String urlString = appConfig.getOtpUrl() + + "from=GCCCRP" + + "&key=" + key + + "&sender=GCCCRP" + + "&to=" + mobileNo + + "&body=" + encodedMsg + + "&entityid=1401572690000011081" + + "&templateid=1407176959304753543"; + + System.out.println("SMS URL:- " + urlString); + + String response = messageUtility.sendSMS(urlString); + System.out.println("SMS RESPONSE:- " + response); + + return response; + } + + // public String userrequestRejectedsms(String mobileNo, String requestId) { + + // String message = "Your Flag Pole permission request has been rejected. " + // + "Request ID: " + requestId + ". " + // + "Review the details in the portal + // https://gccservices.in/flagpolesregistration/status\n" + // + "By GCC"; + + // // ONLY encode. Do NOT replace %3A + // String encodedMsg = URLEncoder.encode(message, StandardCharsets.UTF_8); + + // String urlString = appConfig.getOtpUrl() + // + "from=GCCCRP" + // + "&key=" + key + // + "&sender=GCCCRP" + // + "&to=" + mobileNo + // + "&body=" + encodedMsg + // + "&entityid=1401572690000011081" + // + "&templateid=1407176959315374790"; + + // System.out.println("SMS URL:- " + urlString); + + // String response = messageUtility.sendSMS(urlString); + // System.out.println("SMS RESPONSE:- " + response); + + // return response; + // } + + public String userrequestRejectedsms(String mobileNo, String requestId) { + + System.out.println("Rejected Mob Num SMSSSSSSS = " + mobileNo); + String url = "https://gccservices.in/flagpolesregistration/status"; + String message = "Your Flag Pole permission request has been rejected. Request ID: " + requestId + + ". Review the details in the portal " + url + "\r\nBy GCC"; + + String encodedMsg = URLEncoder.encode(message, StandardCharsets.UTF_8); + + System.out.println("encodedMsg:- " + encodedMsg); + + String urlString = appConfig.getOtpUrl() + + "from=GCCCRP" + + "&key=" + key + // + "&sender=GCCCRP" + + "&to=" + mobileNo + + "&body=" + encodedMsg + + "&entityid=1401572690000011081" + + "&templateid=1407176959315374790"; + + System.out.println("SMS URL:- " + urlString); + + String response = messageUtility.sendSMS(urlString); + System.out.println("SMS RESPONSE:- " + response); + + return response; + } + +} diff --git a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/service/RdoService.java b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/service/RdoService.java index 2bb7382a..e9cd564a 100644 --- a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/service/RdoService.java +++ b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/service/RdoService.java @@ -18,8 +18,11 @@ public class RdoService { private JdbcTemplate mysqlAppJdbcTemplate; + // @Autowired + // private WhatsappServiceFlagPole whatsappService; + @Autowired - private WhatsappServiceFlagPole whatsappService; + private FlagpoleSMSService smsService; @Autowired public void setMysqlAppJdbcTemplate( @@ -35,6 +38,22 @@ public class RdoService { this.mysqlFlagPoleJdbcTemplate = new JdbcTemplate(dataSource); } + public Long getAppUserIdByGccUserId(String gccUserId) { + + String sql = """ + SELECT id + FROM appusers + WHERE userid = ? + AND isactive = 1 + AND isdelete = 0 + LIMIT 1 + """; + + List list = mysqlAppJdbcTemplate.queryForList(sql, Long.class, gccUserId); + + return list.isEmpty() ? null : list.get(0); + } + public Long getAppUserIdByUsername(String username) { String sql = """ @@ -74,79 +93,202 @@ public class RdoService { return list.isEmpty() ? null : list.get(0); } + // public List> getOfficerFeedbackHistoryByRefId( + // String refid, + // String username) { + + // Integer deptId = getDepartmentIdByUsername(username); + // String departmentName = getDepartmentNameByUsername(username); + // boolean isRdo = isRdoDepartment(departmentName); + + // StringBuilder sql = new StringBuilder(""" + // SELECT + // ofb.refid, + // dl.department_name, + // ofb.status, + // ofb.remarks, + // ofb.cby, + // DATE_FORMAT(ofb.cdate, '%d-%m-%Y %h:%i %p') AS action_date + // FROM officer_feedback ofb + // JOIN department_login dl + // ON ofb.dept_id = dl.dpid + // WHERE ofb.refid = ? + // AND ofb.is_active = 1 + // AND ofb.is_delete = 0 + // """); + + // List params = new ArrayList<>(); + // params.add(refid); + + // // 🔥 NON-RDO → show ONLY own department history + // if (!isRdo) { + // sql.append(" AND ofb.dept_id = ? "); + // params.add(deptId); + // } + + // sql.append(" ORDER BY ofb.cdate ASC "); + + // return mysqlFlagPoleJdbcTemplate.queryForList(sql.toString(), + // params.toArray()); + // } + + private boolean hasValue(String s) { + return s != null && !s.trim().isEmpty(); + } + + // old public List> getOfficerFeedbackHistoryByRefId( String refid, - String username) { + String gccUserId) { + + /* 🔥 Resolve appuser_id from gccuserid (gcc_apps) */ + Long appUserId = getAppUserIdByGccUserId(gccUserId); + if (appUserId == null) { + throw new RuntimeException("Invalid gccUserId: " + gccUserId); + } + + /* 🔥 Resolve department id (gcc_flag_pole) */ + Integer deptId = getDepartmentIdByUserId(gccUserId); + + /* 🔥 Resolve access (gcc_apps) */ + List> access = getUserAccess(appUserId); + + String zone = null; + String zoneArray = null; + String wardArray = null; + + boolean isRdo = false; + boolean isZonalOfficer = false; - Integer deptId = getDepartmentIdByUsername(username); - String departmentName = getDepartmentNameByUsername(username); - boolean isRdo = isRdoDepartment(departmentName); + if (!access.isEmpty()) { + + Map row = access.get(0); + + zone = row.get("zone") != null ? row.get("zone").toString() : null; + // zoneArray = row.get("zonearray") != null ? row.get("zonearray").toString() : + // null; + // wardArray = row.get("wardarray") != null ? row.get("wardarray").toString() : + // null; + + /* ✅ RDO → zonearray + wardarray */ + // if (hasValue(zoneArray) && hasValue(wardArray)) { + // isRdo = true; + // } + + /* ✅ Zonal Officer → zone 01–15 */ + if (hasValue(zone) && zone.matches("^(0[1-9]|1[0-5])$")) { + isZonalOfficer = true; + } + } StringBuilder sql = new StringBuilder(""" - SELECT - ofb.refid, - dl.department_name, - ofb.status, - ofb.remarks, - ofb.cby, - DATE_FORMAT(ofb.cdate, '%d-%m-%Y %h:%i %p') AS action_date - FROM officer_feedback ofb - JOIN department_login dl - ON ofb.dept_id = dl.dpid - WHERE ofb.refid = ? - AND ofb.is_active = 1 - AND ofb.is_delete = 0 + SELECT + ofb.refid, + dl.department_name, + ofb.status, + ofb.remarks, + ofb.cby, + DATE_FORMAT(ofb.cdate, '%d-%m-%Y %h:%i %p') AS action_date + FROM officer_feedback ofb + JOIN department_login dl + ON ofb.dept_id = dl.dpid + WHERE ofb.refid = ? + AND ofb.is_active = 1 + AND ofb.is_delete = 0 """); List params = new ArrayList<>(); params.add(refid); - // 🔥 NON-RDO → show ONLY own department history - if (!isRdo) { + /* 🔥 Only NON-RDO & NON-ZONAL are restricted */ + if (!isRdo && !isZonalOfficer) { sql.append(" AND ofb.dept_id = ? "); params.add(deptId); } sql.append(" ORDER BY ofb.cdate ASC "); - return mysqlFlagPoleJdbcTemplate.queryForList(sql.toString(), params.toArray()); + return mysqlFlagPoleJdbcTemplate.queryForList(sql.toString(), + params.toArray()); } - public List> getRdoFeedbackHistoryByRefId(String refid) { + // to show for all departments + // public List> getOfficerFeedbackHistoryByRefId( + // String refid, + // String gccUserId) { - String sql = """ - SELECT - ofb.refid, - dl.department_name, - ofb.status, - ofb.remarks, - ofb.cby, - DATE_FORMAT(ofb.cdate, '%d-%m-%Y %h:%i %p') AS action_date - FROM officer_feedback ofb - JOIN department_login dl - ON ofb.dept_id = dl.dpid - WHERE ofb.refid = ? - AND dl.department_name IN ('RDO_CENTRAL','RDO_NORTH','RDO_SOUTH') - AND ofb.is_active = 1 - AND ofb.is_delete = 0 - ORDER BY ofb.cdate ASC - """; + // /* 🔥 Just validate gccUserId exists */ + // Long appUserId = getAppUserIdByGccUserId(gccUserId); + // if (appUserId == null) { + // throw new RuntimeException("Invalid gccUserId: " + gccUserId); + // } - return mysqlFlagPoleJdbcTemplate.queryForList(sql, refid); - } + // String sql = """ + // SELECT + // ofb.refid, + // dl.department_name, + // ofb.status, + // ofb.remarks, + // ofb.cby, + // DATE_FORMAT(ofb.cdate, '%d-%m-%Y %h:%i %p') AS action_date + // FROM officer_feedback ofb + // JOIN department_login dl + // ON ofb.dept_id = dl.dpid + // WHERE ofb.refid = ? + // AND ofb.is_active = 1 + // AND ofb.is_delete = 0 + // ORDER BY ofb.cdate ASC + // """; + + // return mysqlFlagPoleJdbcTemplate.queryForList(sql, refid); + // } + + // public int insertOfficerFeedback( + // String refId, + // Integer deptId, + // String status, + // String remarks, + // String createdBy) { + + // String sql = """ + // INSERT INTO officer_feedback + // ( + // refid, + // dept_id, + // status, + // remarks, + // cby, + // cdate, + // is_active, + // is_delete + // ) + // VALUES (?, ?, ?, ?, ?, NOW(), 1, 0) + // """; + + // return mysqlFlagPoleJdbcTemplate.update( + // sql, + // refId, + // deptId, + // status, + // remarks, + // createdBy); + // } public int insertOfficerFeedback( String refId, Integer deptId, + Integer gccUserId, // login user id String status, String remarks, - String createdBy) { + String username // display username + ) { String sql = """ INSERT INTO officer_feedback ( refid, dept_id, + gcc_user_id, status, remarks, cby, @@ -154,16 +296,17 @@ public class RdoService { is_active, is_delete ) - VALUES (?, ?, ?, ?, ?, NOW(), 1, 0) + VALUES (?, ?, ?, ?, ?, ?, NOW(), 1, 0) """; return mysqlFlagPoleJdbcTemplate.update( sql, refId, deptId, + gccUserId, status, remarks, - createdBy); + username); } // @@ -182,7 +325,7 @@ public class RdoService { public List> getUserAccess(Long appUserId) { String sql = """ - SELECT lmu.zonearray, lmu.wardarray + SELECT lmu.zone,lmu.ward,lmu.zonearray, lmu.wardarray FROM login_mapping_user lmu WHERE lmu.appuser_id = ? """; @@ -190,275 +333,124 @@ public class RdoService { return mysqlAppJdbcTemplate.queryForList(sql, appUserId); } - // public List> getUserAccess(String username) { - - // String sql = """ - // SELECT lmu.zonearray, lmu.wardarray - // FROM login_mapping_user lmu - // WHERE lmu.appuser_id = ( - // SELECT au.id - // FROM appusers au - // WHERE au.username = ? - // ) - // """; + public String resolveGccUserId(String input) { - // return mysqlAppJdbcTemplate.queryForList(sql, username); - // } - - // public List> getAllRequestDetailsByUserLogin(String - // userLogin) { - - // List> rows = mysqlFlagPoleJdbcTemplate.queryForList( - // """ - // SELECT - // urd.id, - // urd.applicant_name, - // urd.mobile_number, - // urd.applicant_address, - // urd.event_desc, - // urd.event_date, - // urd.ae_status, - // urd.rdo_status, - // urd.refid, - // sd.street_name, - // sd.zone, - // sd.ward, - // sd.no_of_poles, - // sd.height, - // sd.street_cost, - // urd.total_cost, - // et.event_name - // FROM user_request_details urd - // LEFT JOIN street_details sd - // ON urd.refid = sd.refid - // AND sd.is_active = 1 - // AND sd.is_delete = 0 - // LEFT JOIN event_type et - // ON urd.event_id = et.id - // WHERE urd.ae_status = 'APPROVED' - // AND (urd.rdo_status IS NULL OR urd.rdo_status = '' OR urd.rdo_status = - // 'NULL') - // AND FIND_IN_SET(sd.zone, ?) - // AND FIND_IN_SET(sd.ward, ?) - // ORDER BY urd.refid, sd.id - // """, - // (String) getUserAccess(userLogin).get(0).get("zonearray"), - // (String) getUserAccess(userLogin).get(0).get("wardarray")); - - // // 🔥 GROUP BY REFID - // Map> resultMap = new LinkedHashMap<>(); - - // for (Map row : rows) { - - // String refid = (String) row.get("refid"); - - // // Create parent object once per refid - // Map request = resultMap.computeIfAbsent(refid, k -> { - // Map map = new LinkedHashMap<>(); - // map.put("refid", row.get("refid")); - // map.put("applicant_name", row.get("applicant_name")); - // map.put("mobile_number", row.get("mobile_number")); - // map.put("applicant_address", row.get("applicant_address")); - // map.put("event_date", row.get("event_date")); - // map.put("ae_status", row.get("ae_status")); - // map.put("rdo_status", row.get("rdo_status")); - // map.put("event_name", row.get("event_name")); - // map.put("total_cost", row.get("total_cost")); - // map.put("streets", new ArrayList>()); - // return map; - // }); - - // // Add street details - // Map street = new LinkedHashMap<>(); - // street.put("street_name", row.get("street_name")); - // street.put("zone", row.get("zone")); - // street.put("ward", row.get("ward")); - // street.put("no_of_poles", row.get("no_of_poles")); - // street.put("street_cost", row.get("street_cost")); - - // ((List>) request.get("streets")).add(street); - // } + // already numeric + if (input.matches("\\d+")) { + return input; + } - // return new ArrayList<>(resultMap.values()); - // } + // username → userid + String sql = """ + SELECT userid + FROM appusers + WHERE username = ? + AND isactive = 1 + AND isdelete = 0 + LIMIT 1 + """; - // for rdo login list - // public List> getAllRequestDetailsByUserLogin( - // String username, - // String startDate, - // String endDate) { + List list = mysqlAppJdbcTemplate.queryForList(sql, Integer.class, input); - // // List> access = getUserAccess(userLogin); + if (list.isEmpty()) { + throw new RuntimeException("Invalid login user: " + input); + } - // // 🔹 1. Get appuser_id from username - // Long appUserId = getAppUserIdByUsername(username); + return String.valueOf(list.get(0)); + } - // if (appUserId == null) { - // throw new RuntimeException("Invalid session user: " + username); - // } + public String getDepartmentNameByUserId(String gccUserId) { - // // 🔹 2. Get zone & ward using appuser_id - // List> access = getUserAccess(appUserId); + String sql = """ + SELECT department_name + FROM department_login + WHERE gcc_user_id = ? + AND is_active = 1 + AND is_delete = 0 + """; - // if (access.isEmpty()) { - // throw new RuntimeException("No zone/ward mapping for userId: " + appUserId); - // } + List list = mysqlFlagPoleJdbcTemplate.queryForList(sql, String.class, gccUserId); - // String zoneArray = (String) access.get(0).get("zonearray"); - // String wardArray = (String) access.get(0).get("wardarray"); + return list.isEmpty() ? null : list.get(0); + } - // StringBuilder sql = new StringBuilder(""" - // SELECT - // urd.id, - // urd.applicant_name, - // urd.mobile_number, - // urd.applicant_address, - // urd.event_desc, - // urd.cdate, - // urd.event_date, - // urd.ae_status, - // urd.rdo_status, - // urd.refid, - // urd.no_of_days, - - // sd.street_name, - // sd.zone, - // sd.ward, - // sd.no_of_poles, - // sd.height, - // sd.street_cost, - - // fm.flag_material_name AS flag_material, - // pm.pole_material_name AS pole_material, - - // urd.total_cost, - // et.event_name - - // FROM user_request_details urd - - // LEFT JOIN street_details sd - // ON urd.refid = sd.refid - // AND sd.is_active = 1 - // AND sd.is_delete = 0 - - // LEFT JOIN event_type et - // ON urd.event_id = et.id - - // LEFT JOIN flag_material fm - // ON sd.flag_material_id = fm.id - - // LEFT JOIN pole_material pm - // ON sd.pole_material_id = pm.id - - // WHERE urd.ae_status = 'APPROVED' - // AND (urd.rdo_status IS NULL OR urd.rdo_status = '' OR urd.rdo_status = - // 'NULL') - // AND FIND_IN_SET(sd.zone, ?) - // AND FIND_IN_SET(sd.ward, ?) - // """); + public Integer getDepartmentIdByUserId(String gccUserId) { - // List params = new ArrayList<>(); - // params.add(zoneArray); - // params.add(wardArray); + String sql = """ + SELECT dpid + FROM department_login + WHERE gcc_user_id = ? + AND is_active = 1 + AND is_delete = 0 + """; - // // 🔹 DATE FILTER - // if (startDate != null && !startDate.isEmpty() - // && endDate != null && !endDate.isEmpty()) { + List list = mysqlFlagPoleJdbcTemplate.queryForList(sql, Integer.class, gccUserId); - // sql.append(" AND DATE(urd.event_date) BETWEEN ? AND ? "); - // params.add(startDate); - // params.add(endDate); + return list.isEmpty() ? null : list.get(0); + } - // } else if (startDate != null && !startDate.isEmpty()) { + public String getUsernameByUserId(String gccUserId) { - // sql.append(" AND DATE(urd.event_date) = ? "); - // params.add(startDate); - // } + String sql = """ + SELECT user_name + FROM department_login + WHERE gcc_user_id = ? + AND is_active = 1 + AND is_delete = 0 + """; - // // sql.append(" ORDER BY urd.refid, sd.id ,cdate ASC"); - // sql.append("ORDER BY " + // - // " urd.event_date ASC, " + // - // " urd.cdate ASC, " + // - // " urd.refid ASC, " + // - // " sd.id ASC"); - - // List> rows = mysqlFlagPoleJdbcTemplate.queryForList( - // sql.toString(), params.toArray()); - - // // 🔥 GROUP BY REFID - // Map> resultMap = new LinkedHashMap<>(); - - // for (Map row : rows) { - - // String refid = (String) row.get("refid"); - - // Map request = resultMap.computeIfAbsent(refid, k -> { - // Map map = new LinkedHashMap<>(); - // map.put("refid", row.get("refid")); - // map.put("applicant_name", row.get("applicant_name")); - // map.put("mobile_number", row.get("mobile_number")); - // map.put("applicant_address", row.get("applicant_address")); - // map.put("event_desc", row.get("event_desc")); - // map.put("event_date", row.get("event_date")); - // map.put("cdate", row.get("cdate")); - // map.put("ae_status", row.get("ae_status")); - // map.put("rdo_status", row.get("rdo_status")); - // map.put("no_of_days", row.get("no_of_days")); - // map.put("event_name", row.get("event_name")); - // map.put("total_cost", row.get("total_cost")); - // map.put("streets", new ArrayList>()); - // return map; - // }); - - // Map street = new LinkedHashMap<>(); - // street.put("street_name", row.get("street_name")); - // street.put("zone", row.get("zone")); - // street.put("ward", row.get("ward")); - // street.put("no_of_poles", row.get("no_of_poles")); - // street.put("height", row.get("height")); - // street.put("street_cost", row.get("street_cost")); - // street.put("flag_material", row.get("flag_material")); - // street.put("pole_material", row.get("pole_material")); - - // ((List>) request.get("streets")).add(street); - // } + List list = mysqlFlagPoleJdbcTemplate.queryForList(sql, String.class, gccUserId); - // return new ArrayList<>(resultMap.values()); - // } + return list.isEmpty() ? null : list.get(0); + } public List> getAllRequestDetailsByUserLogin( - String username, + String gccUserId, String startDate, String endDate) { - // 🔹 1. App user - Long appUserId = getAppUserIdByUsername(username); + /* 🔥 Resolve appuser_id */ + Long appUserId = getAppUserIdByGccUserId(gccUserId); if (appUserId == null) { - throw new RuntimeException("Invalid session user: " + username); + throw new RuntimeException("Invalid gccUserId: " + gccUserId); } - // 🔹 2. Department - String departmentName = getDepartmentNameByUsername(username); - boolean isRdo = isRdoDepartment(departmentName); - Integer deptId = getDepartmentIdByUsername(username); + /* 🔥 Resolve department id */ + Integer deptId = getDepartmentIdByUserId(gccUserId); + if (deptId == null) { + throw new RuntimeException("Department mapping missing for gccUserId: " + gccUserId); + } + /* 🔥 Resolve access */ + List> access = getUserAccess(appUserId); + + String zone = null; String zoneArray = null; String wardArray = null; - // 🔹 3. Zone/Ward ONLY for RDO - if (isRdo) { - List> access = getUserAccess(appUserId); - if (access.isEmpty()) { - throw new RuntimeException("No zone/ward mapping for RDO userId: " + appUserId); - } + boolean isRdo = false; + boolean isZonalOfficer = false; + + if (!access.isEmpty()) { + + zone = (String) access.get(0).get("zone"); zoneArray = (String) access.get(0).get("zonearray"); wardArray = (String) access.get(0).get("wardarray"); + + // RDO → zonearray + wardarray + if (hasValue(zoneArray) && hasValue(wardArray)) { + isRdo = true; + } + // Zonal → single zone + else if (hasValue(zone)) { + isZonalOfficer = true; + } } - // 🔹 4. Base query StringBuilder sql = new StringBuilder(""" SELECT urd.id, + urd.refid, urd.applicant_name, urd.mobile_number, urd.applicant_address, @@ -467,7 +459,7 @@ public class RdoService { urd.event_date, urd.ae_status, urd.rdo_status, - urd.refid, + urd.final_status, urd.no_of_days, sd.street_name, @@ -496,12 +488,11 @@ public class RdoService { List params = new ArrayList<>(); - // 🔥 1. REMOVE IF RDO HAS DECIDED (FINAL AUTHORITY) - sql.append(""" - AND (urd.rdo_status IS NULL OR urd.rdo_status = '') - """); + /* 🔥 1. REMOVE RDO-FINALIZED */ + // sql.append(" AND (urd.rdo_status IS NULL OR urd.rdo_status = '') "); + sql.append(" AND (urd.final_status IS NULL OR urd.final_status = '') "); - // 🔥 2. REMOVE IF LOGGED-IN DEPARTMENT HAS DECIDED + /* 🔥 2. REMOVE ALREADY DECIDED BY SAME DEPT */ sql.append(""" AND urd.refid NOT IN ( SELECT ofb.refid @@ -514,7 +505,7 @@ public class RdoService { """); params.add(deptId); - // 🔹 5. Apply zone/ward filter ONLY for RDO + /* 🔥 3a. RDO → multi zone + ward */ if (isRdo) { sql.append(" AND FIND_IN_SET(sd.zone, ?) "); sql.append(" AND FIND_IN_SET(sd.ward, ?) "); @@ -522,15 +513,21 @@ public class RdoService { params.add(wardArray); } - // 🔹 6. Date filter - if (startDate != null && !startDate.isEmpty() - && endDate != null && !endDate.isEmpty()) { + /* 🔥 3b. ZONAL → single zone */ + else if (isZonalOfficer) { + sql.append(" AND sd.zone = ? "); + params.add(zone); + } + + /* 🔹 DATE FILTER */ + if (hasValue(startDate) && hasValue(endDate)) { sql.append(" AND DATE(urd.event_date) BETWEEN ? AND ? "); params.add(startDate); params.add(endDate); - } else if (startDate != null && !startDate.isEmpty()) { + } else if (hasValue(startDate)) { + sql.append(" AND DATE(urd.event_date) = ? "); params.add(startDate); } @@ -544,7 +541,7 @@ public class RdoService { List> rows = mysqlFlagPoleJdbcTemplate.queryForList(sql.toString(), params.toArray()); - // 🔥 GROUP BY REFID + /* 🔥 GROUP BY REFID */ Map> resultMap = new LinkedHashMap<>(); for (Map row : rows) { @@ -562,6 +559,7 @@ public class RdoService { map.put("cdate", row.get("cdate")); map.put("ae_status", row.get("ae_status")); map.put("rdo_status", row.get("rdo_status")); + map.put("final_status", row.get("final_status")); map.put("no_of_days", row.get("no_of_days")); map.put("event_name", row.get("event_name")); map.put("total_cost", row.get("total_cost")); @@ -585,394 +583,424 @@ public class RdoService { return new ArrayList<>(resultMap.values()); } - public List> getRequestHistoryByRefId(String refid) { + // old with rdo and zonal officer final + // @Transactional + // public int updateOfficerDecision( + // String refId, + // String status, + // String remarks, + // String gccUserId, + // String username) { - String sql = """ - SELECT - DATE_FORMAT(cdate, '%d-%m-%Y %h:%i %p') AS action_date, - event_date, - ae_status, - rdo_status, - rdo_remarks, - booking_status - FROM user_request_details_history - WHERE refid = ? - ORDER BY cdate ASC - """; + // /* 🔹 Resolve appuser_id */ + // Long appUserId = getAppUserIdByGccUserId(gccUserId); + // if (appUserId == null) { + // throw new RuntimeException("Invalid gccUserId"); + // } - return mysqlFlagPoleJdbcTemplate.queryForList(sql, refid); - } + // /* 🔹 Resolve department */ + // Integer deptId = getDepartmentIdByUserId(gccUserId); + // if (deptId == null) { + // throw new RuntimeException("User not mapped to department"); + // } - private boolean isRdoDepartment(String deptName) { - return deptName != null && - (deptName.equalsIgnoreCase("rdo_north") - || deptName.equalsIgnoreCase("rdo_central") - || deptName.equalsIgnoreCase("rdo_south")); - } + // /* 🔹 Access */ + // List> access = getUserAccess(appUserId); - // old - // @Transactional - // public int updateRdoDecision( - // String refId, - // String status, // APPROVED / REJECTED - // String remarks, - // String approvedBy) { + // String zone = null; + // String zoneArray = null; + // String wardArray = null; + + // boolean isRdo = false; + // boolean isZonalOfficer = false; + + // if (!access.isEmpty()) { + + // Map row = access.get(0); + + // zone = row.get("zone") != null ? row.get("zone").toString() : null; + // zoneArray = row.get("zonearray") != null ? row.get("zonearray").toString() : + // null; + // wardArray = row.get("wardarray") != null ? row.get("wardarray").toString() : + // null; + + // /* ✅ RDO → zonearray + wardarray */ + // if (hasValue(zoneArray) && hasValue(wardArray)) { + // isRdo = true; + // } + + // /* ✅ Zonal Officer → zone 01–15 */ + // if (hasValue(zone) && zone.matches("^(0[1-9]|1[0-5])$")) { + // isZonalOfficer = true; + // } + // } + + // /* + // * ===================================================== + // * 🔹 INSERT FEEDBACK (ALL USERS) + // * ===================================================== + // */ + + // insertOfficerFeedback( + // refId, + // deptId, + // Integer.valueOf(gccUserId), + // status, + // remarks, + // username); + + // /* + // * ===================================================== + // * 🔹 RDO FLOW + // * ===================================================== + // */ + + // if (isRdo) { - // // 1️⃣ INSERT HISTORY WITH NEW DECISION // String historySql = """ // INSERT INTO user_request_details_history // ( - // refid, - // applicant_name, - // mobile_number, - // applicant_address, - // event_id, - // event_date, - // no_of_days, - // total_poles, - // total_cost, - // ae_status, - // rdo_status, - // rdo_remarks, - // approved_by, - // approved_date, - // payment_status, - // refund_status, - // booking_status, - // cdate + // refid, applicant_name, mobile_number, applicant_address, + // event_id, event_date, no_of_days, total_poles, total_cost, + // ae_status, rdo_status, rdo_remarks, + // approved_by, approved_date, + // payment_status, refund_status, booking_status, cdate // ) // SELECT - // refid, - // applicant_name, - // mobile_number, - // applicant_address, - // event_id, - // event_date, - // no_of_days, - // total_poles, - // total_cost, - // ae_status, - // ?, -- NEW rdo_status - // ?, -- NEW rdo_remarks - // ?, -- approved_by - // NOW(), -- approved_date - // payment_status, - // refund_status, - // booking_status, - // NOW() + // refid, applicant_name, mobile_number, applicant_address, + // event_id, event_date, no_of_days, total_poles, total_cost, + // ae_status, ?, ?, ?, NOW(), + // payment_status, refund_status, booking_status, NOW() // FROM user_request_details // WHERE refid = ? // """; - // int historyInserted = mysqlFlagPoleJdbcTemplate.update( - // historySql, - // status, - // remarks, - // approvedBy, + // mysqlFlagPoleJdbcTemplate.update(historySql, status, remarks, gccUserId, // refId); - // if (historyInserted == 0) { - // return 0; - // } - - // // 2️⃣ UPDATE MAIN TABLE // String updateSql = """ // UPDATE user_request_details // SET // rdo_status = ?, // rdo_remarks = ?, // approved_by = ?, - // approved_date = NOW() + // rdo_updated_date = NOW() // WHERE refid = ? // """; - // return mysqlFlagPoleJdbcTemplate.update( - // updateSql, - // status, - // remarks, - // approvedBy, + // return mysqlFlagPoleJdbcTemplate.update(updateSql, status, remarks, + // gccUserId, refId); + // } + + // /* + // * ===================================================== + // * 🔹 ZONAL OFFICER FLOW (FINAL) + // * ===================================================== + // */ + + // if (isZonalOfficer) { + + // String historySql = """ + // INSERT INTO user_request_details_history + // ( + // refid, applicant_name, mobile_number, applicant_address, + // event_id, event_date, no_of_days, total_poles, total_cost, + // ae_status, rdo_status, rdo_remarks, + // final_status, final_remarks, final_approved_by, final_approved_date, + // payment_status, refund_status, booking_status, cdate + // ) + // SELECT + // refid, applicant_name, mobile_number, applicant_address, + // event_id, event_date, no_of_days, total_poles, total_cost, + // ae_status, rdo_status, rdo_remarks, + // ?, ?, ?, NOW(), + // payment_status, refund_status, booking_status, NOW() + // FROM user_request_details + // WHERE refid = ? + // """; + + // mysqlFlagPoleJdbcTemplate.update(historySql, status, remarks, gccUserId, // refId); + + // String updateSql = """ + // UPDATE user_request_details + // SET + // final_status = ?, + // final_remarks = ?, + // final_approved_by = ?, + // final_approved_date = NOW() + // WHERE refid = ? + // """; + + // return mysqlFlagPoleJdbcTemplate.update(updateSql, status, remarks, + // gccUserId, refId); + // } + + // /* + // * ===================================================== + // * 🔹 OTHER DEPARTMENTS → FEEDBACK ONLY + // * ===================================================== + // */ + + // return 1; // } @Transactional - public int updateRdoDecision( + public int updateOfficerDecision( String refId, String status, String remarks, - String approvedBy) { + String gccUserId, + String username) { + + /* 🔹 Resolve appuser_id */ + Long appUserId = getAppUserIdByGccUserId(gccUserId); + if (appUserId == null) { + throw new RuntimeException("Invalid gccUserId"); + } - // 🔹 1. Resolve department - Integer deptId = getDepartmentIdByUsername(approvedBy); + /* 🔹 Resolve department */ + Integer deptId = getDepartmentIdByUserId(gccUserId); if (deptId == null) { - throw new RuntimeException("User not mapped to any department"); + throw new RuntimeException("User not mapped to department"); + } + + /* 🔹 Access */ + List> access = getUserAccess(appUserId); + + String zone = null; + String zoneArray = null; + String wardArray = null; + + boolean isRdo = false; + boolean isZonalOfficer = false; + + if (!access.isEmpty()) { + + Map row = access.get(0); + + zone = row.get("zone") != null ? row.get("zone").toString() : null; + zoneArray = row.get("zonearray") != null ? row.get("zonearray").toString() : null; + wardArray = row.get("wardarray") != null ? row.get("wardarray").toString() : null; + + if (hasValue(zoneArray) && hasValue(wardArray)) { + isRdo = true; + } + + if (hasValue(zone) && zone.matches("^(0[1-9]|1[0-5])$")) { + isZonalOfficer = true; + } + } + + /* + * ===================================================== + * 🔐 Check if already FINALIZED + * ===================================================== + */ + + String finalStatus = mysqlFlagPoleJdbcTemplate.queryForObject( + "SELECT final_status FROM user_request_details WHERE refid = ?", + String.class, + refId); + + if (finalStatus != null && !finalStatus.isBlank() && !isZonalOfficer) { + throw new RuntimeException("Request already finalized by Zonal Officer"); } - String departmentName = getDepartmentNameByUsername(approvedBy); - boolean isRdo = isRdoDepartment(departmentName); + /* + * ===================================================== + * 🔹 INSERT FEEDBACK (ALL USERS) + * ===================================================== + */ - // 🔹 2. Insert officer feedback (ALL departments) insertOfficerFeedback( refId, deptId, + Integer.valueOf(gccUserId), status, remarks, - approvedBy); + username); - // 🔹 3. ONLY RDO can update main request table - if (isRdo) { + /* + * ===================================================== + * 🔹 ZONAL OFFICER FLOW (ONLY FINAL AUTHORITY) + * ===================================================== + */ + + if (isZonalOfficer) { - // 🔹 3a. Insert history snapshot String historySql = """ INSERT INTO user_request_details_history ( - refid, - applicant_name, - mobile_number, - applicant_address, - event_id, - event_date, - no_of_days, - total_poles, - total_cost, - ae_status, - rdo_status, - rdo_remarks, - approved_by, - approved_date, - payment_status, - refund_status, - booking_status, - cdate + refid, applicant_name, mobile_number, applicant_address, + event_id, event_date, no_of_days, total_poles, total_cost, + ae_status, rdo_status, rdo_remarks, + final_status, final_remarks, final_approved_by, final_approved_date, + payment_status, refund_status, booking_status, cdate ) SELECT - refid, - applicant_name, - mobile_number, - applicant_address, - event_id, - event_date, - no_of_days, - total_poles, - total_cost, - ae_status, + refid, applicant_name, mobile_number, applicant_address, + event_id, event_date, no_of_days, total_poles, total_cost, + ae_status, rdo_status, rdo_remarks, ?, ?, ?, NOW(), - payment_status, - refund_status, - booking_status, - NOW() + payment_status, refund_status, booking_status, NOW() FROM user_request_details WHERE refid = ? """; - mysqlFlagPoleJdbcTemplate.update( - historySql, - status, - remarks, - approvedBy, - refId); + mysqlFlagPoleJdbcTemplate.update(historySql, status, remarks, gccUserId, refId); - // 🔹 3b. Update final RDO decision String updateSql = """ UPDATE user_request_details SET - rdo_status = ?, - rdo_remarks = ?, - approved_by = ?, - rdo_updated_date = NOW() + final_status = ?, + final_remarks = ?, + final_approved_by = ?, + final_approved_date = NOW() WHERE refid = ? """; - return mysqlFlagPoleJdbcTemplate.update( - updateSql, - status, - remarks, - approvedBy, - refId); - } + // return mysqlFlagPoleJdbcTemplate.update(updateSql, status, remarks, + // gccUserId, refId); - // 🔹 4. Non-RDO users → only feedback saved - return 1; - } + int updated = mysqlFlagPoleJdbcTemplate.update(updateSql, status, remarks, gccUserId, refId); - // public List> getRdoApprovedRequestDetailsByUserLogin( - // String username, - // String startDate, - // String endDate, - // String status) { + // ================= SEND SMS AFTER FINAL APPROVAL ================= + if ("APPROVED".equalsIgnoreCase(status)) { - // // 🔹 USER ACCESS - // // List> access = getUserAccess(userLogin); + try { - // // 🔹 1. Get appuser_id from username - // Long appUserId = getAppUserIdByUsername(username); + String mobileNo = mysqlFlagPoleJdbcTemplate.queryForObject(""" + SELECT mobile_number + FROM user_request_details + WHERE refid = ? + """, String.class, refId); - // if (appUserId == null) { - // throw new RuntimeException("Invalid session user: " + username); - // } + if (mobileNo != null && !mobileNo.isBlank()) { + smsService.userrequestApprovedsms(mobileNo, refId); + } - // // 🔹 2. Get zone & ward using appuser_id - // List> access = getUserAccess(appUserId); + } catch (Exception e) { + System.err.println("Approved SMS failed for requestId: " + refId); + e.printStackTrace(); + } + } - // if (access.isEmpty()) { - // throw new RuntimeException("No zone/ward mapping for userId: " + appUserId); - // } - // String zoneArray = (String) access.get(0).get("zonearray"); - // String wardArray = (String) access.get(0).get("wardarray"); + if ("REJECTED".equalsIgnoreCase(status)) { - // // 🔹 BASE QUERY - // StringBuilder sql = new StringBuilder(""" - // SELECT - // urd.id, - // urd.applicant_name, - // urd.mobile_number, - // urd.applicant_address, - // urd.rdo_remarks, - // urd.event_date, - // urd.event_desc, - // urd.ae_status, - // urd.rdo_status, - // urd.refid, - // urd.no_of_days, - - // sd.street_name, - // sd.zone, - // sd.ward, - // sd.no_of_poles, - // sd.street_cost, - // sd.height, - - // fm.flag_material_name AS flag_material, - // pm.pole_material_name AS pole_material, - - // urd.total_cost, - // et.event_name - - // FROM user_request_details urd - - // LEFT JOIN street_details sd - // ON urd.refid = sd.refid - // AND sd.is_active = 1 - // AND sd.is_delete = 0 - - // LEFT JOIN event_type et - // ON urd.event_id = et.id - - // LEFT JOIN flag_material fm - // ON sd.flag_material_id = fm.id - - // LEFT JOIN pole_material pm - // ON sd.pole_material_id = pm.id - - // WHERE urd.ae_status = 'APPROVED' - // AND FIND_IN_SET(sd.zone, ?) - // AND FIND_IN_SET(sd.ward, ?) - // """); + try { + System.out.println("Rejected RefID = " + refId); - // List params = new ArrayList<>(); - // params.add(zoneArray); - // params.add(wardArray); - - // // 🔹 STATUS FILTER - // if (status != null && !status.isEmpty()) { - // sql.append(" AND urd.rdo_status = ? "); - // params.add(status); - // } else { - // sql.append(" AND urd.rdo_status IN ('APPROVED','REJECTED') "); - // } + String mobileNo = mysqlFlagPoleJdbcTemplate.queryForObject(""" + SELECT mobile_number + FROM user_request_details + WHERE refid = ? + """, String.class, refId); - // // 🔹 DATE FILTER - // if (startDate != null && !startDate.isEmpty() - // && endDate != null && !endDate.isEmpty()) { + if (mobileNo != null && !mobileNo.isBlank()) { + System.out.println("Rejected Mob Num = " + mobileNo); + smsService.userrequestRejectedsms(mobileNo, refId); + } - // sql.append(" AND DATE(urd.event_date) BETWEEN ? AND ? "); - // params.add(startDate); - // params.add(endDate); + } catch (Exception e) { + System.err.println("Approved SMS failed for requestId: " + refId); + e.printStackTrace(); + } + } + // ================================================================ - // } else if (startDate != null && !startDate.isEmpty()) { + return updated; - // sql.append(" AND DATE(urd.event_date) = ? "); - // params.add(startDate); - // } + } - // sql.append(" ORDER BY urd.refid, sd.id "); - - // // 🔹 EXECUTE QUERY - // List> rows = - // mysqlFlagPoleJdbcTemplate.queryForList(sql.toString(), params.toArray()); - - // // 🔥 GROUP BY REFID (INLINE – NO SEPARATE METHOD) - // Map> resultMap = new LinkedHashMap<>(); - - // for (Map row : rows) { - - // String refid = (String) row.get("refid"); - - // Map request = resultMap.computeIfAbsent(refid, k -> { - // Map map = new LinkedHashMap<>(); - // map.put("refid", row.get("refid")); - // map.put("applicant_name", row.get("applicant_name")); - // map.put("mobile_number", row.get("mobile_number")); - // map.put("applicant_address", row.get("applicant_address")); - // map.put("event_desc", row.get("event_desc")); - // map.put("rdo_remarks", row.get("rdo_remarks")); - // map.put("event_date", row.get("event_date")); - // map.put("ae_status", row.get("ae_status")); - // map.put("rdo_status", row.get("rdo_status")); - // map.put("no_of_days", row.get("no_of_days")); - // map.put("event_name", row.get("event_name")); - // map.put("total_cost", row.get("total_cost")); - // map.put("streets", new ArrayList>()); - // return map; - // }); - - // // 🔹 STREET DETAILS - // Map street = new LinkedHashMap<>(); - // street.put("street_name", row.get("street_name")); - // street.put("zone", row.get("zone")); - // street.put("ward", row.get("ward")); - // street.put("no_of_poles", row.get("no_of_poles")); - // street.put("height", row.get("height")); - // street.put("street_cost", row.get("street_cost")); - // street.put("flag_material", row.get("flag_material")); - // street.put("pole_material", row.get("pole_material")); - - // ((List>) request.get("streets")).add(street); - // } + /* + * ===================================================== + * RDO FLOW (ONLY RDO FIELDS) + * ===================================================== + */ - // return new ArrayList<>(resultMap.values()); - // } + if (isRdo) { + + String historySql = """ + INSERT INTO user_request_details_history + ( + refid, applicant_name, mobile_number, applicant_address, + event_id, event_date, no_of_days, total_poles, total_cost, + ae_status, rdo_status, rdo_remarks, + approved_by, approved_date, + payment_status, refund_status, booking_status, cdate + ) + SELECT + refid, applicant_name, mobile_number, applicant_address, + event_id, event_date, no_of_days, total_poles, total_cost, + ae_status, ?, ?, ?, NOW(), + payment_status, refund_status, booking_status, NOW() + FROM user_request_details + WHERE refid = ? + """; + + mysqlFlagPoleJdbcTemplate.update(historySql, status, remarks, gccUserId, refId); + + String updateSql = """ + UPDATE user_request_details + SET + rdo_status = ?, + rdo_remarks = ?, + approved_by = ?, + rdo_updated_date = NOW() + WHERE refid = ? + """; + + return mysqlFlagPoleJdbcTemplate.update(updateSql, status, remarks, gccUserId, refId); + } + + return 1; + } public List> getRdoApprovedRequestDetailsByUserLogin( - String username, + String gccUserId, String startDate, String endDate, String status) { - Long appUserId = getAppUserIdByUsername(username); + /* 🔥 Resolve appuser_id */ + Long appUserId = getAppUserIdByGccUserId(gccUserId); if (appUserId == null) { - throw new RuntimeException("Invalid session user: " + username); + throw new RuntimeException("Invalid gccUserId: " + gccUserId); } - String departmentName = getDepartmentNameByUsername(username); - boolean isRdo = isRdoDepartment(departmentName); - Integer deptId = getDepartmentIdByUsername(username); + /* 🔥 Resolve department */ + Integer deptId = getDepartmentIdByUserId(gccUserId); + if (deptId == null) { + throw new RuntimeException("Department mapping missing for gccUserId: " + gccUserId); + } + + /* 🔥 Resolve access */ + List> access = getUserAccess(appUserId); + String zone = null; String zoneArray = null; String wardArray = null; - if (isRdo) { - List> access = getUserAccess(appUserId); - if (access.isEmpty()) { - throw new RuntimeException("No zone/ward mapping for RDO userId: " + appUserId); - } + boolean isRdo = false; + boolean isZonalOfficer = false; + + if (!access.isEmpty()) { + zone = (String) access.get(0).get("zone"); zoneArray = (String) access.get(0).get("zonearray"); wardArray = (String) access.get(0).get("wardarray"); + + if (hasValue(zoneArray) && hasValue(wardArray)) { + isRdo = true; + } else if (hasValue(zone)) { + isZonalOfficer = true; + } } - // 🔥 IMPORTANT: JOIN officer_feedback StringBuilder sql = new StringBuilder(""" SELECT urd.id, + urd.refid, urd.applicant_name, urd.mobile_number, urd.applicant_address, @@ -982,7 +1010,6 @@ public class RdoService { urd.ae_status, urd.rdo_status, urd.rdo_remarks, - urd.refid, urd.no_of_days, sd.street_name, @@ -998,8 +1025,8 @@ public class RdoService { urd.total_cost, et.event_name, - ofb.status AS my_status, - ofb.remarks AS my_remarks + ofb.status AS officer_status, + ofb.remarks AS officer_remarks FROM officer_feedback ofb JOIN user_request_details urd @@ -1020,29 +1047,34 @@ public class RdoService { List params = new ArrayList<>(); params.add(deptId); - // 🔹 Optional status filter - if (status != null && !status.isEmpty()) { + /* 🔹 Optional status */ + if (hasValue(status)) { sql.append(" AND ofb.status = ? "); params.add(status); } - // 🔹 RDO zone/ward filter + /* 🔹 RDO → zone + ward */ if (isRdo) { sql.append(" AND FIND_IN_SET(sd.zone, ?) "); sql.append(" AND FIND_IN_SET(sd.ward, ?) "); params.add(zoneArray); params.add(wardArray); } + /* 🔹 Zonal → only zone */ + else if (isZonalOfficer) { + sql.append(" AND sd.zone = ? "); + params.add(zone); + } - // 🔹 Date filter - if (startDate != null && !startDate.isEmpty() - && endDate != null && !endDate.isEmpty()) { + /* 🔹 Date */ + if (hasValue(startDate) && hasValue(endDate)) { sql.append(" AND DATE(urd.event_date) BETWEEN ? AND ? "); params.add(startDate); params.add(endDate); - } else if (startDate != null && !startDate.isEmpty()) { + } else if (hasValue(startDate)) { + sql.append(" AND DATE(urd.event_date) = ? "); params.add(startDate); } @@ -1051,7 +1083,7 @@ public class RdoService { List> rows = mysqlFlagPoleJdbcTemplate.queryForList(sql.toString(), params.toArray()); - // 🔥 GROUP BY REFID + /* 🔥 GROUP BY REFID */ Map> resultMap = new LinkedHashMap<>(); for (Map row : rows) { @@ -1073,11 +1105,8 @@ public class RdoService { map.put("no_of_days", row.get("no_of_days")); map.put("event_name", row.get("event_name")); map.put("total_cost", row.get("total_cost")); - - // 🔥 department decision - map.put("my_status", row.get("my_status")); - map.put("my_remarks", row.get("my_remarks")); - + map.put("officer_status", row.get("officer_status")); + map.put("officer_remarks", row.get("officer_remarks")); map.put("streets", new ArrayList<>()); return map; }); diff --git a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/service/WhatsappServiceFlagPole.java b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/service/WhatsappServiceFlagPole.java index c5ccd474..0ebad469 100644 --- a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/service/WhatsappServiceFlagPole.java +++ b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/service/WhatsappServiceFlagPole.java @@ -1,28 +1,31 @@ -package in.gov.chennaicorporation.gccoffice.flagpole.service; +// package in.gov.chennaicorporation.gccoffice.flagpole.service; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; +// import org.springframework.beans.factory.annotation.Autowired; +// import org.springframework.stereotype.Service; -@Service -public class WhatsappServiceFlagPole { +// @Service +// public class WhatsappServiceFlagPole { - @Autowired - private SmsServiceFlagPole smsService; +// @Autowired +// private SMSService smsService; - // c & d waste template after user register - public void sendOfficerApprovedWhatsappMessage(String refId, String mobileNumber) { - try { +// // c & d waste template after user register +// public void sendOfficerApprovedWhatsappMessage(String refId, String +// mobileNumber) { +// try { - String apiUrl = "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to=" - + mobileNumber - + "&v=1.1&format=json&msg_type=IMAGE&method=SENDMEDIAMESSAGE&caption=Welcome+to+Greater+Chennai+Corporation%2C+%0A%0AYour+Registered+ID+is+%2A${registerId}%2A+.%0AYour+C%26D+waste+registration+has+been+approved+successfully.+%0A%0AFor+downloading+your+ID+card%2C+kindly+click+on+the+button+below+%F0%9F%91%87&media_url=https%3A%2F%2Fres.cloudinary.com%2Fdpub5muar%2Fimage%2Fupload%2Fv1729597847%2Fq2ihjs99puhhwkjzajyo.png&isTemplate=true&buttonUrlParam=userdetail%3Fregister_id%3D" - + refId; +// String apiUrl = +// "https://media.smsgupshup.com/GatewayAPI/rest?userid=2000233507&password=h2YjFNcJ&send_to=" +// + mobileNumber +// + +// "&v=1.1&format=json&msg_type=IMAGE&method=SENDMEDIAMESSAGE&caption=Welcome+to+Greater+Chennai+Corporation%2C+%0A%0AYour+Registered+ID+is+%2A${registerId}%2A+.%0AYour+C%26D+waste+registration+has+been+approved+successfully.+%0A%0AFor+downloading+your+ID+card%2C+kindly+click+on+the+button+below+%F0%9F%91%87&media_url=https%3A%2F%2Fres.cloudinary.com%2Fdpub5muar%2Fimage%2Fupload%2Fv1729597847%2Fq2ihjs99puhhwkjzajyo.png&isTemplate=true&buttonUrlParam=userdetail%3Fregister_id%3D" +// + refId; - System.out.println("WhatsApp API URL: " + apiUrl); // Optional debug - smsService.sendMsg(apiUrl); +// System.out.println("WhatsApp API URL: " + apiUrl); // Optional debug +// smsService.sendMsg(apiUrl); - } catch (Exception e) { - e.printStackTrace(); - } - } -} +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } diff --git a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/util/MessageUtility.java b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/util/MessageUtility.java new file mode 100644 index 00000000..09b9aaa7 --- /dev/null +++ b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/flagpole/util/MessageUtility.java @@ -0,0 +1,41 @@ +package in.gov.chennaicorporation.gccoffice.flagpole.util; + +import java.net.HttpURLConnection; +import java.net.URL; + +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +@Service +public class MessageUtility { + + public String sendMsg(String msgUrl) { + System.out.println("Whatsapp URL :-" + msgUrl); + + String response = ""; + try { + HttpURLConnection connection = null; + + URL url = new URL(msgUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + int responseCode = connection.getResponseCode(); + response = responseCode + ""; + System.out.println("Response Code: " + responseCode); + + } catch (Exception e) { + e.printStackTrace(); + } + + return response; + } + + public String sendSMS(String SMS_Url) { + // System.out.println("SMS URL:- " + SMS_Url); + RestTemplate restTemplate = new RestTemplate(); + String response = restTemplate.getForObject(SMS_Url, String.class); + return response; + } + +} diff --git a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/greencommittee/service/PendinglistService.java b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/greencommittee/service/PendinglistService.java index 2c564374..ab8e53fa 100644 --- a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/greencommittee/service/PendinglistService.java +++ b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/greencommittee/service/PendinglistService.java @@ -19,6 +19,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; @Service public class PendinglistService { @@ -405,6 +406,7 @@ public class PendinglistService { } } + @Transactional public Map saveReInspection(String refId, int action, int meetingId, String remarks, int userId) { @@ -433,6 +435,8 @@ public class PendinglistService { // Update reg_details.reinspection_id jdbcTemplate.update("UPDATE reg_details SET reinspection_id=? WHERE ref_id=?",generatedId, refId); + jdbcTemplate.update("UPDATE inspection_data SET isactive=0,isdelete=1 WHERE ref_id=?", refId); + response.put("status", "success"); response.put("message", "Committee decision saved!"); response.put("reinspection_id", generatedId); diff --git a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/nulm/controller/NulmAPIController.java b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/nulm/controller/NulmAPIController.java index 5d303e3a..0be74a99 100644 --- a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/nulm/controller/NulmAPIController.java +++ b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/nulm/controller/NulmAPIController.java @@ -488,10 +488,11 @@ public class NulmAPIController { public ResponseEntity>> getAttendanceWithInitiatedSalaryByGroupId( @RequestParam(value = "inchargeId", required = false) Integer inchargeId, @RequestParam(value = "month", required = false) String month, + @RequestParam(value = "year", required = false) String year, @RequestParam(value = "incharge_name", required = false) String inchargeName, @RequestParam (value = "enrollmentIds", required = false) List enrollmentIds) { - List> staffList = nulmService.getAttendanceWithInitiatedSalary(inchargeId, month, inchargeName, enrollmentIds); + List> staffList = nulmService.getAttendanceWithInitiatedSalary(inchargeId, month, year, inchargeName, enrollmentIds); return ResponseEntity.ok(staffList); } /* diff --git a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/nulm/service/NulmService.java b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/nulm/service/NulmService.java index 3fb6d14d..e65d25ee 100644 --- a/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/nulm/service/NulmService.java +++ b/gcc_officer_portal/src/main/java/in/gov/chennaicorporation/gccoffice/nulm/service/NulmService.java @@ -1176,7 +1176,7 @@ public class NulmService { */ public List> getAttendanceWithInitiatedSalary( - int inchargeId, String month, String inchargeName, List enrollmentIds) { + int inchargeId, String month, String year, String inchargeName, List enrollmentIds) { String sql = "SELECT " + "e.group_id, " + @@ -1207,6 +1207,10 @@ public class NulmService { if (month != null && !month.isEmpty()) { sql += "AND MONTHNAME(COALESCE(a.indatetime, a.leavedatetime, a.oddatetime)) = ? "; } + if (year != null && !year.isEmpty()) { + sql += "AND YEAR(COALESCE(a.indatetime, a.leavedatetime, a.oddatetime)) = ? "; + } + // Assuming enrollmentIds is a List or List StringBuilder placeholders = new StringBuilder(); @@ -1240,6 +1244,9 @@ public class NulmService { if (month != null && !month.isEmpty()) { params.add(month); } + if (year != null && !year.isEmpty()) { + params.add(year); + } params.addAll(enrollmentIds); diff --git a/gcc_officer_portal/src/main/resources/application.properties b/gcc_officer_portal/src/main/resources/application.properties index 0cf69f0e..acd734ca 100644 --- a/gcc_officer_portal/src/main/resources/application.properties +++ b/gcc_officer_portal/src/main/resources/application.properties @@ -1,5 +1,5 @@ -#spring.profiles.active=local -spring.profiles.active=production +spring.profiles.active=local +# spring.profiles.active=production #For Server production #assets.base-url=/gcc/assets/ #For local test diff --git a/gcc_officer_portal/src/main/resources/templates/modules/callcenterqaqc/socialmediacomplaints.html b/gcc_officer_portal/src/main/resources/templates/modules/callcenterqaqc/socialmediacomplaints.html index 37e37119..ea12545b 100644 --- a/gcc_officer_portal/src/main/resources/templates/modules/callcenterqaqc/socialmediacomplaints.html +++ b/gcc_officer_portal/src/main/resources/templates/modules/callcenterqaqc/socialmediacomplaints.html @@ -615,7 +615,7 @@ ` : '-'; @@ -1037,7 +1037,7 @@ return; // Stop execution if no action is selected } - if (actionValue === "REOPENED" && remarksValue.trim() === "") { + if (actionValue === "REOPEN" && remarksValue.trim() === "") { Swal.fire({ icon: 'warning', title: 'Remarks Required', diff --git a/gcc_officer_portal/src/main/resources/templates/modules/flagpole/approvedandrejectedlist.html b/gcc_officer_portal/src/main/resources/templates/modules/flagpole/approvedandrejectedlist.html index d5c60ffc..73eb0afe 100644 --- a/gcc_officer_portal/src/main/resources/templates/modules/flagpole/approvedandrejectedlist.html +++ b/gcc_officer_portal/src/main/resources/templates/modules/flagpole/approvedandrejectedlist.html @@ -141,7 +141,7 @@

Temporary Flag Poles - Approved & Rejected List :

- + @@ -314,11 +314,14 @@ function loadTable() { - let officer_name = $("#userName").val(); + //let officer_name = $("#userName").val(); + let gccUserId = $("#loginuserid").val(); let startDate = $("#startDate").val(); let endDate = $("#endDate").val(); let status = $("#statusFilter").val(); + console.log("gccuserid", gccUserId); + if ($.fn.DataTable.isDataTable('#QaqcDatatable')) { $('#QaqcDatatable').DataTable().clear().destroy(); } @@ -333,7 +336,8 @@ url: "/gcc/api/flagpoleregistration/getApprovedAndRejectedDetails", type: "GET", data: { - userLogin: officer_name, + //userLogin: officer_name, + gccUserId: gccUserId, startDate: startDate, endDate: endDate, status: status @@ -347,9 +351,10 @@ data.forEach(r => { let status = r.history && r.history.length > 0 - ? r.history[0].status + ? r.history[r.history.length - 1].status : null; + if (!status) pending++; else if (status === 'APPROVED') approved++; else if (status === 'REJECTED') rejected++; @@ -423,9 +428,10 @@ render: row => { let status = row.history && row.history.length > 0 - ? row.history[0].status + ? row.history[row.history.length - 1].status : null; + if (!status) return `Pending`; if (status === 'APPROVED') @@ -563,7 +569,7 @@ record.history.forEach((h, index) => { historyHtml += `
-
+
Action Date
${h.action_date}
@@ -574,22 +580,15 @@
-
+
Status
${h.status}
-
-
RDO Status
-
- ${record.rdo_status || "-"} -
-
- - + ${h.remarks ? ` -
+
Remarks
${h.remarks}
` : ""} diff --git a/gcc_officer_portal/src/main/resources/templates/modules/flagpole/requestlist.html b/gcc_officer_portal/src/main/resources/templates/modules/flagpole/requestlist.html index 2757f55c..684932c1 100644 --- a/gcc_officer_portal/src/main/resources/templates/modules/flagpole/requestlist.html +++ b/gcc_officer_portal/src/main/resources/templates/modules/flagpole/requestlist.html @@ -139,6 +139,7 @@

Temporary Flag Poles - Request List :

+
@@ -277,6 +278,20 @@ + + @@ -297,12 +312,132 @@ }); }); + $(document).on("click", ".zoom-img", function () { + + const src = $(this).data("src"); + + $("#previewImage").attr("src", src); + + $("#imagePreviewModal").modal("show"); + }); + + + // function loadTable() { + + // let officer_name = $("#userName").val(); + // let startDate = $("#startDate").val(); + // let endDate = $("#endDate").val(); + + // if ($.fn.DataTable.isDataTable('#QaqcDatatable')) { + // $('#QaqcDatatable').DataTable().clear().destroy(); + // } + + // table = $('#QaqcDatatable').DataTable({ + // processing: true, + // responsive: true, + // scrollY: '50vh', + // dom: 'Bfrtip', // 🔥 ENABLE BUTTONS + + // ajax: { + // url: "/gcc/api/flagpoleregistration/getAllDetails", + // type: "GET", + // data: { + // userLogin: officer_name, + // startDate: startDate, + // endDate: endDate + // }, + // dataSrc: function (json) { + + // const data = json.data || []; + + // // 🔹 Dashboard counts + // let pending = 0, approved = 0, rejected = 0; + + // data.forEach(r => { + // if (!r.rdo_status) pending++; + // else if (r.rdo_status === 'APPROVED') approved++; + // else if (r.rdo_status === 'REJECTED') rejected++; + // }); + + // $("#totalrequest").text(data.length); + // $("#pendingdecision").text(pending); + // $("#approved").text(approved); + // $("#rejected").text(rejected); + + // return data; // ✅ already unique per refid + // } + // }, + + // columns: [ + // { + // data: null, + // className: "text-center", + // render: (d, t, r, m) => m.row + 1 + // }, + // { + // data: "applicant_name", + // className: "text-center" + // }, + // { + // data: "refid", + // className: "text-center" + // }, + // { + // data: null, + // className: "text-center", + // render: row => { + // if (!row.streets || row.streets.length === 0) return "-"; + // return `${row.streets[0].zone} / ${row.streets[0].ward}`; + // } + // }, + // { + // data: "event_name", + // className: "text-center" + // }, + // { + // data: "event_date", + // className: "text-center", + // render: d => new Date(d).toLocaleDateString("en-GB") + // }, + // { + // data: "total_cost", + // className: "text-center", + // render: d => d.toLocaleString("en-GB") + // }, + // { + // data: "rdo_status", + // className: "text-center", + // render: d => { + // if (!d) + // return `Pending`; + // if (d === 'APPROVED') + // return `Approved`; + // return `Rejected`; + // } + // }, + // { + // data: null, + // className: "text-center", + // render: row => + // `` + // } + // ] + // }); + // } + + + function loadTable() { - let officer_name = $("#userName").val(); + let gccUserId = $("#loginuserid").val(); let startDate = $("#startDate").val(); let endDate = $("#endDate").val(); + console.log("gccuserid:" + gccUserId); + if ($.fn.DataTable.isDataTable('#QaqcDatatable')) { $('#QaqcDatatable').DataTable().clear().destroy(); } @@ -311,13 +446,13 @@ processing: true, responsive: true, scrollY: '50vh', - dom: 'Bfrtip', // 🔥 ENABLE BUTTONS + dom: 'Bfrtip', ajax: { url: "/gcc/api/flagpoleregistration/getAllDetails", type: "GET", data: { - userLogin: officer_name, + gccUserId: gccUserId, startDate: startDate, endDate: endDate }, @@ -325,50 +460,47 @@ const data = json.data || []; - // 🔹 Dashboard counts let pending = 0, approved = 0, rejected = 0; + // data.forEach(r => { + // if (!r.rdo_status) pending++; + // else if (r.rdo_status === 'APPROVED') approved++; + // else if (r.rdo_status === 'REJECTED') rejected++; + // }); + data.forEach(r => { - if (!r.rdo_status) pending++; - else if (r.rdo_status === 'APPROVED') approved++; - else if (r.rdo_status === 'REJECTED') rejected++; + + const status = r.final_status; + + if (!status) pending++; + else if (status === 'APPROVED') approved++; + else if (status === 'REJECTED') rejected++; }); + + $("#totalrequest").text(data.length); $("#pendingdecision").text(pending); $("#approved").text(approved); $("#rejected").text(rejected); - return data; // ✅ already unique per refid + return data; } }, columns: [ + { data: null, render: (d, t, r, m) => m.row + 1, className: "text-center" }, + { data: "applicant_name", className: "text-center" }, + { data: "refid", className: "text-center" }, { data: null, className: "text-center", - render: (d, t, r, m) => m.row + 1 - }, - { - data: "applicant_name", - className: "text-center" - }, - { - data: "refid", - className: "text-center" - }, - { - data: null, - className: "text-center", - render: row => { - if (!row.streets || row.streets.length === 0) return "-"; - return `${row.streets[0].zone} / ${row.streets[0].ward}`; - } - }, - { - data: "event_name", - className: "text-center" + render: r => + r.streets?.length + ? `${r.streets[0].zone} / ${r.streets[0].ward}` + : "-" }, + { data: "event_name", className: "text-center" }, { data: "event_date", className: "text-center", @@ -379,31 +511,47 @@ className: "text-center", render: d => d.toLocaleString("en-GB") }, + // { + // data: "rdo_status", + // className: "text-center", + // render: d => + // !d + // ? `Pending` + // : d === 'APPROVED' + // ? `Approved` + // : `Rejected` + // }, { - data: "rdo_status", + data: null, className: "text-center", - render: d => { - if (!d) + render: r => { + + const status = r.final_status; + + if (!status) return `Pending`; - if (d === 'APPROVED') + else if (status === 'APPROVED') return `Approved`; - return `Rejected`; + else + return `Rejected`; } }, + { data: null, className: "text-center", - render: row => + render: r => `` + ` } ] }); } + // 🔹 View button action // Destroy previous instance if exists @@ -429,6 +577,9 @@ }); + + + function populateModal(record) { // HEADER @@ -444,47 +595,47 @@ record.streets.forEach((s, i) => { streetHtml += ` -
-
Street ${i + 1}
+
+
Street ${i + 1}
-
-
-
Street Name
-
${s.street_name}
-
-
-
Zone
-
${s.zone}
-
-
-
Ward
-
${s.ward}
-
-
-
No. of Poles
-
${s.no_of_poles}
-
- - -
-
Height
-
${s.height}
-
+
+
+
Street Name
+
${s.street_name}
+
+
+
Zone
+
${s.zone}
+
+
+
Ward
+
${s.ward}
+
+
+
No. of Poles
+
${s.no_of_poles}
+
+ + +
+
Height
+
${s.height}
+
+ +
+
Flag Material
+
${s.flag_material}
+
+ +
+
Pole Material
+
${s.pole_material}
+
-
-
Flag Material
-
${s.flag_material}
-
- -
-
Pole Material
-
${s.pole_material}
- -
-
`; +
`; }); let historyHtml = ""; @@ -492,46 +643,38 @@ if (record.history && record.history.length > 0) { historyHtml += ` -
-
Application History
- `; +
+
Application History
+ `; record.history.forEach((h, index) => { historyHtml += ` -
-
-
Action Date
-
${h.action_date}
-
- -
-
Department
-
${h.department_name}
-
+
+
+
Action Date
+
${h.action_date}
+
- +
+
Department
+
${h.department_name}
+
-
-
Status
-
${h.status}
-
-
-
RDO Status
-
- ${record.rdo_status || "-"} +
+
Status
+
${h.status}
-
- ${h.remarks ? ` -
-
Remarks
-
${h.remarks}
-
` : ""} -
- `; + ${h.remarks ? ` +
+
Remarks
+
${h.remarks}
+
` : ""} +
+ `; }); historyHtml += `
`; @@ -540,90 +683,90 @@ let decisionHtml = ""; // 🔹 Show decision buttons ONLY if pending - if (!record.rdo_status) { + if (!record.final_status) { decisionHtml = ` -
-
Department Decision
+
+
Department Decision
- + -
- +
+ - -
-
`; + +
+
`; } let html = ` -
-
Applicant Information
+
+
Applicant Information
-
-
-
Applicant Name
-
${record.applicant_name}
-
-
-
Mobile Number
-
${record.mobile_number}
+
+
+
Applicant Name
+
${record.applicant_name}
+
+
+
Mobile Number
+
${record.mobile_number}
+
-
-
-
-
Event Type
-
${record.event_name}
-
-
-
Event Date
-
- ${new Date(record.event_date).toLocaleDateString("en-GB")} +
+
+
Event Type
+
${record.event_name}
-
-
-
Address
-
- ${record.applicant_address} +
+
Event Date
+
+ ${new Date(record.event_date).toLocaleDateString("en-GB")} +
-
-
-
Total Cost
-
- ${record.total_cost.toLocaleString("en-GB")} +
+
Address
+
+ ${record.applicant_address} +
+
+
+
Total Cost
+
+ ${record.total_cost.toLocaleString("en-GB")} +
+
+
+
No. of Days
+
${record.no_of_days}
+
+
+
Event Description
+
${record.event_desc}
-
-
-
No. of Days
-
${record.no_of_days}
-
-
-
Event Description
-
${record.event_desc}
-
-
+
-
-
-
Applied Date
-
${record.cdate}
+
+
+
Applied Date
+
${record.cdate}
+
-
- - ${streetHtml} - ${historyHtml} - ${decisionHtml} - - `; + + ${streetHtml} + ${historyHtml} + ${decisionHtml} + + `; @@ -633,11 +776,76 @@ - function submitRdoDecision(status) { + // function submitRdoDecision(status) { + + // let remarks = ($("#rdoRemarks").val() || "").trim(); + // let refid = $("#detailsModal").data("refid"); + // let gccUserId = $("#loginuserid").val(); // 🔥 ONLY THIS + + // //let approvedBy = $("#userName").val(); // 🔥 FROM HIDDEN INPUT + + // if (!remarks) { + // Swal.fire({ + // icon: 'warning', + // title: 'Remarks Required', + // text: 'Please enter remarks before submitting' + // }); + // return; + // } + + // Swal.fire({ + // title: `Are you sure?`, + // text: `You want to ${status.toLowerCase()} this request`, + // icon: status === 'APPROVED' ? 'success' : 'error', + // showCancelButton: true, + // confirmButtonColor: status === 'APPROVED' ? '#28a745' : '#dc3545', + // cancelButtonColor: '#6c757d', + // confirmButtonText: `Yes, ${status}` + // }).then((result) => { + + // if (!result.isConfirmed) return; + + // $.ajax({ + // url: "/gcc/api/flagpoleregistration/rdo/updateDecision", + // type: "POST", + // data: { + // refid: refid, + // status: status, + // remarks: remarks, + // gccUserId: gccUserId + // //approvedBy: approvedBy // 🔥 PASS TO BACKEND + // }, + // success: function (res) { + + // Swal.fire({ + // icon: 'success', + // title: status === 'APPROVED' ? 'Approved!' : 'Rejected!', + // text: res.message || `Request has been ${status.toLowerCase()}`, + // timer: 2000, + // showConfirmButton: false + // }); + + // $("#detailsModal").modal("hide"); + // $("#QaqcDatatable").DataTable().ajax.reload(null, false); + // }, + // error: function () { + // Swal.fire({ + // icon: 'error', + // title: 'Error', + // text: 'Failed to update decision' + // }); + // } + // }); + // }); + // } + + function submitOfficerDecision(status) { let remarks = ($("#rdoRemarks").val() || "").trim(); let refid = $("#detailsModal").data("refid"); - let approvedBy = $("#userName").val(); // 🔥 FROM HIDDEN INPUT + + let gccUserId = $("#loginuserid").val(); // login user id + let username = $("#userName").val(); // display username if (!remarks) { Swal.fire({ @@ -661,13 +869,14 @@ if (!result.isConfirmed) return; $.ajax({ - url: "/gcc/api/flagpoleregistration/rdo/updateDecision", + url: "/gcc/api/flagpoleregistration/officer/updateDecision", type: "POST", data: { refid: refid, status: status, remarks: remarks, - approvedBy: approvedBy // 🔥 PASS TO BACKEND + gccUserId: gccUserId, + username: username // ✅ NEW }, success: function (res) { diff --git a/gcc_officer_portal/src/main/resources/templates/modules/m_petition/complaint_list.html b/gcc_officer_portal/src/main/resources/templates/modules/m_petition/complaint_list.html index 19d3c994..9504d067 100644 --- a/gcc_officer_portal/src/main/resources/templates/modules/m_petition/complaint_list.html +++ b/gcc_officer_portal/src/main/resources/templates/modules/m_petition/complaint_list.html @@ -74,6 +74,7 @@ + diff --git a/gcc_officer_portal/src/main/resources/templates/modules/nulm/salary-approve.html b/gcc_officer_portal/src/main/resources/templates/modules/nulm/salary-approve.html index 68c09e08..ea39b23b 100644 --- a/gcc_officer_portal/src/main/resources/templates/modules/nulm/salary-approve.html +++ b/gcc_officer_portal/src/main/resources/templates/modules/nulm/salary-approve.html @@ -101,6 +101,7 @@