Compare commits

...

1 Commits
main ... master

Author SHA1 Message Date
yoganandhan 7e3561a146 first commit 8 months ago
  1. 6
      pom.xml
  2. 6
      src/main/java/com/gcc/flagpoles_services/FlagpolesApplication.java
  3. 12
      src/main/java/com/gcc/flagpoles_services/configuration/AppConfig.java
  4. 23
      src/main/java/com/gcc/flagpoles_services/configuration/DataSourceConfig.java
  5. 2
      src/main/java/com/gcc/flagpoles_services/configuration/JacksonConfiguration.java
  6. 25
      src/main/java/com/gcc/flagpoles_services/configuration/SecurityConfig.java
  7. 2
      src/main/java/com/gcc/flagpoles_services/configuration/ThymeleafConfig.java
  8. 16
      src/main/java/com/gcc/flagpoles_services/configuration/WebMvcConfig.java
  9. 42
      src/main/java/com/gcc/flagpoles_services/controller/APIController.java
  10. 30
      src/main/java/com/gcc/flagpoles_services/controller/AdminController.java
  11. 4
      src/main/java/com/gcc/flagpoles_services/controller/CustomErrorController.java
  12. 2
      src/main/java/com/gcc/flagpoles_services/controller/DateTimeUtil.java
  13. 6
      src/main/java/com/gcc/flagpoles_services/controller/FileController.java
  14. 6
      src/main/java/com/gcc/flagpoles_services/controller/MainController.java
  15. 36
      src/main/java/com/gcc/flagpoles_services/controller/MenuController.java
  16. 6
      src/main/java/com/gcc/flagpoles_services/controller/login.java
  17. 2
      src/main/java/com/gcc/flagpoles_services/entity/AppModuleAccessEntity.java
  18. 2
      src/main/java/com/gcc/flagpoles_services/entity/AppModuleEntity.java
  19. 2
      src/main/java/com/gcc/flagpoles_services/entity/AppUserEntity.java
  20. 2
      src/main/java/com/gcc/flagpoles_services/entity/AppUserGroupEntity.java
  21. 2
      src/main/java/com/gcc/flagpoles_services/entity/MenuItemAccessEntity.java
  22. 2
      src/main/java/com/gcc/flagpoles_services/entity/MenuItemEntity.java
  23. 2
      src/main/java/com/gcc/flagpoles_services/entity/SubMenuItemAccessEntity.java
  24. 2
      src/main/java/com/gcc/flagpoles_services/entity/SubMenuItemEntity.java
  25. 2
      src/main/java/com/gcc/flagpoles_services/entity/UserActivityLog.java
  26. 2
      src/main/java/com/gcc/flagpoles_services/entity/UserInfoEntity.java
  27. 425
      src/main/java/com/gcc/flagpoles_services/flagpoles/controller/FlagPoleApiController.java
  28. 53
      src/main/java/com/gcc/flagpoles_services/flagpoles/controller/MainController.java
  29. 248
      src/main/java/com/gcc/flagpoles_services/flagpoles/service/FlagpoleSMSService.java
  30. 1356
      src/main/java/com/gcc/flagpoles_services/flagpoles/service/RdoService.java
  31. 41
      src/main/java/com/gcc/flagpoles_services/flagpoles/util/MessageUtility.java
  32. 36
      src/main/java/com/gcc/flagpoles_services/interceptor/AppInterceptor.java
  33. 2
      src/main/java/com/gcc/flagpoles_services/modeldata/ErrorResponse.java
  34. 4
      src/main/java/com/gcc/flagpoles_services/repository/AppModuleAccessRepository.java
  35. 4
      src/main/java/com/gcc/flagpoles_services/repository/AppModuleRepository.java
  36. 4
      src/main/java/com/gcc/flagpoles_services/repository/AppUserGroupRepository.java
  37. 4
      src/main/java/com/gcc/flagpoles_services/repository/AppUserRepository.java
  38. 4
      src/main/java/com/gcc/flagpoles_services/repository/MenuItemAccessRepository.java
  39. 4
      src/main/java/com/gcc/flagpoles_services/repository/MenuItemRepository.java
  40. 4
      src/main/java/com/gcc/flagpoles_services/repository/SubMenuItemAccessRepository.java
  41. 4
      src/main/java/com/gcc/flagpoles_services/repository/SubMenuItemRepository.java
  42. 4
      src/main/java/com/gcc/flagpoles_services/repository/UserActivityLogRepository.java
  43. 2
      src/main/java/com/gcc/flagpoles_services/repository/UserInfoRepository.java
  44. 2
      src/main/java/com/gcc/flagpoles_services/service/Base64Util.java
  45. 2
      src/main/java/com/gcc/flagpoles_services/service/CustomUserDetails.java
  46. 6
      src/main/java/com/gcc/flagpoles_services/service/CustomUserDetailsService.java
  47. 2
      src/main/java/com/gcc/flagpoles_services/service/LoginUserInfo.java
  48. 6
      src/main/java/com/gcc/flagpoles_services/service/UserActivityService.java
  49. 6
      src/main/java/com/gcc/flagpoles_services/service/UserActivityTimelineService.java
  50. 163
      src/main/java/com/gcc/swm_services/swm/controller/AdminController.java
  51. 35
      src/main/java/com/gcc/swm_services/swm/controller/DropDownApiController.java
  52. 71
      src/main/java/com/gcc/swm_services/swm/controller/MainController.java
  53. 145
      src/main/java/com/gcc/swm_services/swm/controller/SwmAdminApiController.java
  54. 202
      src/main/java/com/gcc/swm_services/swm/controller/SwmApiController.java
  55. 510
      src/main/java/com/gcc/swm_services/swm/service/AddDetailsService.java
  56. 37
      src/main/java/com/gcc/swm_services/swm/service/DropDownService.java
  57. 2
      src/main/resources/application-dev.properties
  58. 4
      src/main/resources/application-prod.properties
  59. 4
      src/main/resources/application.properties
  60. 10
      src/main/resources/templates/error-403.html
  61. 2
      src/main/resources/templates/fragments/modules/base/footer.html
  62. 2
      src/main/resources/templates/fragments/modules/base/head.html
  63. 4
      src/main/resources/templates/fragments/modules/base/header.html
  64. 2
      src/main/resources/templates/fragments/modules/base/login-head.html
  65. 2
      src/main/resources/templates/fragments/modules/base/script.html
  66. 6
      src/main/resources/templates/index.html
  67. 6
      src/main/resources/templates/login.html
  68. 4
      src/main/resources/templates/modules/admin/user-group-access.html
  69. 2
      src/main/resources/templates/modules/admin/user-list.html
  70. 458
      src/main/resources/templates/modules/flagpole/approvedandrejectedlist.html
  71. 930
      src/main/resources/templates/modules/flagpole/requestlist.html
  72. 754
      src/main/resources/templates/modules/swm/biogas.html
  73. 416
      src/main/resources/templates/modules/swm/cdwaste.html
  74. 764
      src/main/resources/templates/modules/swm/eachreport.html
  75. 447
      src/main/resources/templates/modules/swm/gwtcwaste.html
  76. 421
      src/main/resources/templates/modules/swm/incinerator.html
  77. 428
      src/main/resources/templates/modules/swm/mcc.html
  78. 424
      src/main/resources/templates/modules/swm/mrf.html
  79. 418
      src/main/resources/templates/modules/swm/plastingbaling.html
  80. 944
      src/main/resources/templates/modules/swm/reports.html
  81. 442
      src/main/resources/templates/modules/swm/requestlist.html
  82. 419
      src/main/resources/templates/modules/swm/windrow.html

6
pom.xml

@ -10,10 +10,10 @@
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<groupId>com.gcc</groupId> <groupId>com.gcc</groupId>
<artifactId>rdo_login</artifactId>
<artifactId>flagpoles_services</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<name>rdo_login</name>
<description>Project for Allocating polling persons</description>
<name>flagpoles_services</name>
<description>Project for Flagpoles Services</description>
<url/> <url/>
<licenses> <licenses>
<license/> <license/>

6
src/main/java/com/gcc/swm_services/SwmApplication.java → src/main/java/com/gcc/flagpoles_services/FlagpolesApplication.java

@ -1,13 +1,13 @@
package com.gcc.swm_services;
package com.gcc.flagpoles_services;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication @SpringBootApplication
public class SwmApplication {
public class FlagpolesApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(SwmApplication.class, args);
SpringApplication.run(FlagpolesApplication.class, args);
} }
} }

12
src/main/java/com/gcc/swm_services/configuration/AppConfig.java → src/main/java/com/gcc/flagpoles_services/configuration/AppConfig.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.configuration;
package com.gcc.flagpoles_services.configuration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -12,4 +12,14 @@ public class AppConfig {
return new RestTemplate(); return new RestTemplate();
} }
public String otpUrl = "https://tmegov.onex-aura.com/api/sms?";
public String getOtpUrl() {
return otpUrl;
}
public void setOtpUrl(String otpUrl) {
this.otpUrl = otpUrl;
}
} }

23
src/main/java/com/gcc/swm_services/configuration/DataSourceConfig.java → src/main/java/com/gcc/flagpoles_services/configuration/DataSourceConfig.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.configuration;
package com.gcc.flagpoles_services.configuration;
import org.hibernate.jpa.HibernatePersistenceProvider; import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
@ -23,18 +23,17 @@ import java.util.Properties;
public class DataSourceConfig { public class DataSourceConfig {
// local // local
private static String host = "localhost:3306";
private static String dbpassword = "root";
// private static String host = "localhost:3306";
// private static String dbpassword = "root";
// AWS // 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";
private static String host = "gcc-facial-db-instance-1.cf48eqcciziq.ap-south-1.rds.amazonaws.com:3306";
private static String dbpassword = "gcc-facial-password";
@Configuration @Configuration
@EnableTransactionManagement @EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "appEntityManagerFactory", transactionManagerRef = "appTransactionManager", basePackages = { @EnableJpaRepositories(entityManagerFactoryRef = "appEntityManagerFactory", transactionManagerRef = "appTransactionManager", basePackages = {
"com.gcc.swm_services.repository" })
"com.gcc.flagpoles_services.repository" })
public static class MysqlAppDataSourceConfig { public static class MysqlAppDataSourceConfig {
@Primary @Primary
@ -42,7 +41,7 @@ public class DataSourceConfig {
public DataSource mysqlAppDataSource() { public DataSource mysqlAppDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource(); DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://" + host + "/gcc_swm_services_apps");
dataSource.setUrl("jdbc:mysql://" + host + "/gcc_flagpoles_services_apps");
dataSource.setUsername("root"); dataSource.setUsername("root");
dataSource.setPassword(dbpassword); dataSource.setPassword(dbpassword);
return dataSource; return dataSource;
@ -61,7 +60,7 @@ public class DataSourceConfig {
@Qualifier("mysqlAppDataSource") DataSource dataSource) { @Qualifier("mysqlAppDataSource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource); entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setPackagesToScan("com.gcc.swm_services.entity");
entityManagerFactoryBean.setPackagesToScan("com.gcc.flagpoles_services.entity");
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class); entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
Properties properties = new Properties(); Properties properties = new Properties();
properties.setProperty("hibernate.hbm2ddl.auto", "update"); properties.setProperty("hibernate.hbm2ddl.auto", "update");
@ -79,11 +78,11 @@ public class DataSourceConfig {
} }
//////////////////////////// (For GCC Election) //////////////////////// //////////////////////////// (For GCC Election) ////////////////////////
@Bean(name = "mysqlSwmDataSource")
public DataSource mysqlSwmDataSource() {
@Bean(name = "mysqlFlagPoleManagerSystemDataSource")
public DataSource mysqlFlagPoleManagerSystemDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource(); DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://" + host + "/gcc_swm_facilities");
dataSource.setUrl("jdbc:mysql://" + host + "/gcc_flag_pole");
dataSource.setUsername("root"); dataSource.setUsername("root");
dataSource.setPassword(dbpassword); dataSource.setPassword(dbpassword);
return dataSource; return dataSource;

2
src/main/java/com/gcc/swm_services/configuration/JacksonConfiguration.java → src/main/java/com/gcc/flagpoles_services/configuration/JacksonConfiguration.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.configuration;
package com.gcc.flagpoles_services.configuration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;

25
src/main/java/com/gcc/swm_services/configuration/SecurityConfig.java → src/main/java/com/gcc/flagpoles_services/configuration/SecurityConfig.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.configuration;
package com.gcc.flagpoles_services.configuration;
import javax.persistence.Basic; import javax.persistence.Basic;
@ -12,7 +12,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import com.gcc.swm_services.service.CustomUserDetailsService;
import com.gcc.flagpoles_services.service.CustomUserDetailsService;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@ -28,8 +28,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override @Override
public void configure(WebSecurity web) throws Exception { public void configure(WebSecurity web) throws Exception {
web.ignoring() web.ignoring()
.antMatchers("/static/**", "/assets/**", "/api/**", "/images/**", "/swm/static/**",
"/swm/assets/**", "/swm/api/**", "/swm/images/**", "/swm/files/**", "/.well-known/**",
.antMatchers("/static/**", "/assets/**", "/api/**", "/images/**", "/flagpoles/static/**",
"/flagpoles/assets/**", "/flagpoles/api/**", "/flagpoles/images/**", "/flagpoles/files/**",
"/.well-known/**",
"/favicon.ico", "/favicon.ico",
"/static/**", "/static/**",
"/css/**", "/css/**",
@ -53,20 +54,20 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.cors().and() // Enable CORS .cors().and() // Enable CORS
.csrf().disable() // Disable CSRF protection for simplicity (Enable if needed) .csrf().disable() // Disable CSRF protection for simplicity (Enable if needed)
.authorizeRequests() .authorizeRequests()
.antMatchers("/swm/error").permitAll()
.antMatchers("/swm/login").permitAll() // Add the login URL
.antMatchers("/swm/admin/**").hasRole("ADMIN") // Add the admin URLs
.antMatchers("/swm/**").hasAnyRole("ADMIN", "USER") // Add other URLs
.antMatchers("/flagpoles/error").permitAll()
.antMatchers("/flagpoles/login").permitAll() // Add the login URL
.antMatchers("/flagpoles/admin/**").hasRole("ADMIN") // Add the admin URLs
.antMatchers("/flagpoles/**").hasAnyRole("ADMIN", "USER") // Add other URLs
// .anyRequest().authenticated() // .anyRequest().authenticated()
.and() .and()
.formLogin() .formLogin()
.loginPage("/swm/login") // Customize the login page URL
.defaultSuccessUrl("/swm") // Include the success URL
.loginPage("/flagpoles/login") // Customize the login page URL
.defaultSuccessUrl("/flagpoles") // Include the success URL
.permitAll() .permitAll()
.and() .and()
.logout() .logout()
.logoutUrl("/swm/logout") // Include the logout URL
.logoutSuccessUrl("/swm/login") // Include the success logout URL
.logoutUrl("/flagpoles/logout") // Include the logout URL
.logoutSuccessUrl("/flagpoles/login") // Include the success logout URL
.permitAll() .permitAll()
.and() .and()
.sessionManagement() .sessionManagement()

2
src/main/java/com/gcc/swm_services/configuration/ThymeleafConfig.java → src/main/java/com/gcc/flagpoles_services/configuration/ThymeleafConfig.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.configuration;
package com.gcc.flagpoles_services.configuration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;

16
src/main/java/com/gcc/swm_services/configuration/WebMvcConfig.java → src/main/java/com/gcc/flagpoles_services/configuration/WebMvcConfig.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.configuration;
package com.gcc.flagpoles_services.configuration;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -8,14 +8,14 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.gcc.swm_services.repository.AppModuleAccessRepository;
import com.gcc.swm_services.repository.AppModuleRepository;
import com.gcc.swm_services.repository.MenuItemAccessRepository;
import com.gcc.swm_services.repository.MenuItemRepository;
import com.gcc.swm_services.repository.SubMenuItemAccessRepository;
import com.gcc.swm_services.repository.SubMenuItemRepository;
import com.gcc.flagpoles_services.repository.AppModuleAccessRepository;
import com.gcc.flagpoles_services.repository.AppModuleRepository;
import com.gcc.flagpoles_services.repository.MenuItemAccessRepository;
import com.gcc.flagpoles_services.repository.MenuItemRepository;
import com.gcc.flagpoles_services.repository.SubMenuItemAccessRepository;
import com.gcc.flagpoles_services.repository.SubMenuItemRepository;
import com.gcc.swm_services.interceptor.AppInterceptor;
import com.gcc.flagpoles_services.interceptor.AppInterceptor;
@Configuration @Configuration
public class WebMvcConfig implements WebMvcConfigurer { public class WebMvcConfig implements WebMvcConfigurer {

42
src/main/java/com/gcc/swm_services/controller/APIController.java → src/main/java/com/gcc/flagpoles_services/controller/APIController.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.controller;
package com.gcc.flagpoles_services.controller;
import java.util.Base64; import java.util.Base64;
import java.util.List; import java.util.List;
@ -17,27 +17,27 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.gcc.swm_services.entity.AppModuleAccessEntity;
import com.gcc.swm_services.entity.AppModuleEntity;
import com.gcc.swm_services.entity.AppUserEntity;
import com.gcc.swm_services.entity.MenuItemAccessEntity;
import com.gcc.swm_services.entity.MenuItemEntity;
import com.gcc.swm_services.entity.SubMenuItemAccessEntity;
import com.gcc.swm_services.entity.SubMenuItemEntity;
import com.gcc.swm_services.entity.UserActivityLog;
import com.gcc.swm_services.repository.AppModuleAccessRepository;
import com.gcc.swm_services.repository.AppModuleRepository;
import com.gcc.swm_services.repository.AppUserRepository;
import com.gcc.swm_services.repository.MenuItemAccessRepository;
import com.gcc.swm_services.repository.MenuItemRepository;
import com.gcc.swm_services.repository.SubMenuItemAccessRepository;
import com.gcc.swm_services.repository.SubMenuItemRepository;
import com.gcc.swm_services.repository.UserActivityLogRepository;
import com.gcc.swm_services.service.LoginUserInfo;
import com.gcc.flagpoles_services.entity.AppModuleAccessEntity;
import com.gcc.flagpoles_services.entity.AppModuleEntity;
import com.gcc.flagpoles_services.entity.AppUserEntity;
import com.gcc.flagpoles_services.entity.MenuItemAccessEntity;
import com.gcc.flagpoles_services.entity.MenuItemEntity;
import com.gcc.flagpoles_services.entity.SubMenuItemAccessEntity;
import com.gcc.flagpoles_services.entity.SubMenuItemEntity;
import com.gcc.flagpoles_services.entity.UserActivityLog;
import com.gcc.flagpoles_services.repository.AppModuleAccessRepository;
import com.gcc.flagpoles_services.repository.AppModuleRepository;
import com.gcc.flagpoles_services.repository.AppUserRepository;
import com.gcc.flagpoles_services.repository.MenuItemAccessRepository;
import com.gcc.flagpoles_services.repository.MenuItemRepository;
import com.gcc.flagpoles_services.repository.SubMenuItemAccessRepository;
import com.gcc.flagpoles_services.repository.SubMenuItemRepository;
import com.gcc.flagpoles_services.repository.UserActivityLogRepository;
import com.gcc.flagpoles_services.service.LoginUserInfo;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@RequestMapping("/swm/api")
@RequestMapping("/flagpoles/api")
@RestController @RestController
public class APIController { public class APIController {
@ -296,7 +296,7 @@ public class APIController {
+ " <img src='/assets/images/users/user.jpg' class='rounded' width='150'>\n" + " <img src='/assets/images/users/user.jpg' class='rounded' width='150'>\n"
+ " <h4 class='card-title mt-10'>" + appUserEntity.getUserid().getName() + " <h4 class='card-title mt-10'>" + appUserEntity.getUserid().getName()
+ "</h4>\n" + "</h4>\n"
+ " <p class='text-muted'>Front End Developer</p>\n"
+ " <p class='text-muted'>Officer</p>\n"
+ " </div>\n" + " </div>\n"
+ " </div>" + " </div>"
+ " <hr class='mb-0 mt-0'> \n" + " <hr class='mb-0 mt-0'> \n"
@ -335,7 +335,7 @@ public class APIController {
+ " <img src='/assets/images/users/user.jpg' class='rounded' width='150'>\n" + " <img src='/assets/images/users/user.jpg' class='rounded' width='150'>\n"
+ " <h4 class='card-title mt-10'>" + appUserEntity.getUserid().getName() + " <h4 class='card-title mt-10'>" + appUserEntity.getUserid().getName()
+ "</h4>\n" + "</h4>\n"
+ " <p class='text-muted'>Front End Developer</p>\n"
+ " <p class='text-muted'>Officer</p>\n"
+ " <p class='text-muted'>" + userIp + "</p>\n" + " <p class='text-muted'>" + userIp + "</p>\n"
+ " </div>\n" + " </div>\n"
+ " </div>" + " </div>"

30
src/main/java/com/gcc/swm_services/controller/AdminController.java → src/main/java/com/gcc/flagpoles_services/controller/AdminController.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.controller;
package com.gcc.flagpoles_services.controller;
import java.util.List; import java.util.List;
@ -8,20 +8,20 @@ import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import com.gcc.swm_services.entity.AppModuleEntity;
import com.gcc.swm_services.entity.AppUserEntity;
import com.gcc.swm_services.entity.AppUserGroupEntity;
import com.gcc.swm_services.entity.MenuItemEntity;
import com.gcc.swm_services.entity.SubMenuItemEntity;
import com.gcc.swm_services.repository.AppModuleRepository;
import com.gcc.swm_services.repository.AppUserGroupRepository;
import com.gcc.swm_services.repository.AppUserRepository;
import com.gcc.swm_services.repository.MenuItemRepository;
import com.gcc.swm_services.repository.SubMenuItemRepository;
import com.gcc.swm_services.service.LoginUserInfo;
@RequestMapping("/swm/admin")
@Controller("swmAdminController")
import com.gcc.flagpoles_services.entity.AppModuleEntity;
import com.gcc.flagpoles_services.entity.AppUserEntity;
import com.gcc.flagpoles_services.entity.AppUserGroupEntity;
import com.gcc.flagpoles_services.entity.MenuItemEntity;
import com.gcc.flagpoles_services.entity.SubMenuItemEntity;
import com.gcc.flagpoles_services.repository.AppModuleRepository;
import com.gcc.flagpoles_services.repository.AppUserGroupRepository;
import com.gcc.flagpoles_services.repository.AppUserRepository;
import com.gcc.flagpoles_services.repository.MenuItemRepository;
import com.gcc.flagpoles_services.repository.SubMenuItemRepository;
import com.gcc.flagpoles_services.service.LoginUserInfo;
@RequestMapping("/flagpoles/admin")
@Controller("flagpolesAdminController")
public class AdminController { public class AdminController {
private final AppUserRepository appUserRepository; private final AppUserRepository appUserRepository;

4
src/main/java/com/gcc/swm_services/controller/CustomErrorController.java → src/main/java/com/gcc/flagpoles_services/controller/CustomErrorController.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.controller;
package com.gcc.flagpoles_services.controller;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.gcc.swm_services.modeldata.ErrorResponse;
import com.gcc.flagpoles_services.modeldata.ErrorResponse;
@Controller @Controller
public class CustomErrorController implements ErrorController { public class CustomErrorController implements ErrorController {

2
src/main/java/com/gcc/swm_services/controller/DateTimeUtil.java → src/main/java/com/gcc/flagpoles_services/controller/DateTimeUtil.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.controller;
package com.gcc.flagpoles_services.controller;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.LocalDateTime; import java.time.LocalDateTime;

6
src/main/java/com/gcc/swm_services/controller/FileController.java → src/main/java/com/gcc/flagpoles_services/controller/FileController.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.controller;
package com.gcc.flagpoles_services.controller;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
@ -22,13 +22,13 @@ public class FileController {
@Value("${file.upload.directory}") @Value("${file.upload.directory}")
private String uploadDirectory; private String uploadDirectory;
@GetMapping("/swm/files/{directoryPath}/**")
@GetMapping("/flagpoles/files/{directoryPath}/**")
public ResponseEntity<Resource> serveFile(@PathVariable String directoryPath, HttpServletRequest request) { public ResponseEntity<Resource> serveFile(@PathVariable String directoryPath, HttpServletRequest request) {
String fullPath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); String fullPath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
System.out.println(fullPath.toString() + "\n" + directoryPath.length() + "\n directoryPath:" + directoryPath); System.out.println(fullPath.toString() + "\n" + directoryPath.length() + "\n directoryPath:" + directoryPath);
// String relativePath = fullPath.substring(directoryPath.length() + 1); // // String relativePath = fullPath.substring(directoryPath.length() + 1); //
// Adding 1 for the trailing '/' // Adding 1 for the trailing '/'
String relativePath = fullPath.replace("/swm/files", "");
String relativePath = fullPath.replace("/flagpoles/files", "");
String filePath = uploadDirectory + "/" + relativePath; String filePath = uploadDirectory + "/" + relativePath;
Path path = Paths.get(filePath).normalize(); Path path = Paths.get(filePath).normalize();
System.out.println(path.toString()); System.out.println(path.toString());

6
src/main/java/com/gcc/swm_services/controller/MainController.java → src/main/java/com/gcc/flagpoles_services/controller/MainController.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.controller;
package com.gcc.flagpoles_services.controller;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -6,9 +6,9 @@ import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import com.gcc.swm_services.service.LoginUserInfo;
import com.gcc.flagpoles_services.service.LoginUserInfo;
@RequestMapping("/swm")
@RequestMapping("/flagpoles")
@Controller("MainController") @Controller("MainController")
public class MainController { public class MainController {

36
src/main/java/com/gcc/swm_services/controller/MenuController.java → src/main/java/com/gcc/flagpoles_services/controller/MenuController.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.controller;
package com.gcc.flagpoles_services.controller;
import java.util.List; import java.util.List;
@ -6,19 +6,19 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ModelAttribute;
import com.gcc.swm_services.entity.AppModuleAccessEntity;
import com.gcc.swm_services.entity.AppModuleEntity;
import com.gcc.swm_services.entity.MenuItemAccessEntity;
import com.gcc.swm_services.entity.MenuItemEntity;
import com.gcc.swm_services.entity.SubMenuItemAccessEntity;
import com.gcc.swm_services.entity.SubMenuItemEntity;
import com.gcc.swm_services.repository.AppModuleAccessRepository;
import com.gcc.swm_services.repository.AppModuleRepository;
import com.gcc.swm_services.repository.MenuItemAccessRepository;
import com.gcc.swm_services.repository.MenuItemRepository;
import com.gcc.swm_services.repository.SubMenuItemAccessRepository;
import com.gcc.swm_services.repository.SubMenuItemRepository;
import com.gcc.swm_services.service.LoginUserInfo;
import com.gcc.flagpoles_services.entity.AppModuleAccessEntity;
import com.gcc.flagpoles_services.entity.AppModuleEntity;
import com.gcc.flagpoles_services.entity.MenuItemAccessEntity;
import com.gcc.flagpoles_services.entity.MenuItemEntity;
import com.gcc.flagpoles_services.entity.SubMenuItemAccessEntity;
import com.gcc.flagpoles_services.entity.SubMenuItemEntity;
import com.gcc.flagpoles_services.repository.AppModuleAccessRepository;
import com.gcc.flagpoles_services.repository.AppModuleRepository;
import com.gcc.flagpoles_services.repository.MenuItemAccessRepository;
import com.gcc.flagpoles_services.repository.MenuItemRepository;
import com.gcc.flagpoles_services.repository.SubMenuItemAccessRepository;
import com.gcc.flagpoles_services.repository.SubMenuItemRepository;
import com.gcc.flagpoles_services.service.LoginUserInfo;
@ControllerAdvice @ControllerAdvice
public class MenuController { public class MenuController {
@ -72,7 +72,7 @@ public class MenuController {
} }
String menuHTML = ""; String menuHTML = "";
menuHTML = "<div class=\"nav-item\"><a href=\"/swm\"><i class=\"ik ik-home\"></i><span>Dashboard</span></a></div>";
menuHTML = "<div class=\"nav-item\"><a href=\"/flagpoles\"><i class=\"ik ik-home\"></i><span>Dashboard</span></a></div>";
for (AppModuleEntity moduleName : getAppModuleEntities) { for (AppModuleEntity moduleName : getAppModuleEntities) {
menuHTML = menuHTML + "<div class=\"nav-item has-sub\"><a href=\"javascript:void(0)\"><i class=\"" menuHTML = menuHTML + "<div class=\"nav-item has-sub\"><a href=\"javascript:void(0)\"><i class=\""
@ -110,7 +110,7 @@ public class MenuController {
+ "\" class=\"menu-item\"" + target + "><i class=\"" + subMenuItem.getIcon() + "\" class=\"menu-item\"" + target + "><i class=\"" + subMenuItem.getIcon()
+ "\"></i><span>" + subMenuItem.getName() + "</span></a>"; + "\"></i><span>" + subMenuItem.getName() + "</span></a>";
} else { } else {
subSubMenuHTML = subSubMenuHTML + "<a href=\"/swm/" + subMenuItem.getUrl()
subSubMenuHTML = subSubMenuHTML + "<a href=\"/flagpoles/" + subMenuItem.getUrl()
+ "\" class=\"menu-item\"" + target + "><i class=\"" + subMenuItem.getIcon() + "\" class=\"menu-item\"" + target + "><i class=\"" + subMenuItem.getIcon()
+ "\"></i><span>" + subMenuItem.getName() + "</span></a>"; + "\"></i><span>" + subMenuItem.getName() + "</span></a>";
} }
@ -151,7 +151,7 @@ public class MenuController {
+ "\" class=\"menu-item\"" + target + "><i class=\"" + subMenuItem.getIcon() + "\" class=\"menu-item\"" + target + "><i class=\"" + subMenuItem.getIcon()
+ "\"></i><span>" + subMenuItem.getName() + "</span></a>"; + "\"></i><span>" + subMenuItem.getName() + "</span></a>";
} else { } else {
subSubMenuHTML = subSubMenuHTML + "<a href=\"/swm/" + subMenuItem.getUrl()
subSubMenuHTML = subSubMenuHTML + "<a href=\"/flagpoles/" + subMenuItem.getUrl()
+ "\" class=\"menu-item\"" + target + "><i class=\"" + subMenuItem.getIcon() + "\" class=\"menu-item\"" + target + "><i class=\"" + subMenuItem.getIcon()
+ "\"></i><span>" + subMenuItem.getName() + "</span></a>"; + "\"></i><span>" + subMenuItem.getName() + "</span></a>";
} }
@ -169,7 +169,7 @@ public class MenuController {
} else { } else {
if (menuItem.getOrderby() > 0) { if (menuItem.getOrderby() > 0) {
subMenuHTML = subMenuHTML + "<a href=\"/swm/" + menuItem.getUrl()
subMenuHTML = subMenuHTML + "<a href=\"/flagpoles/" + menuItem.getUrl()
+ "\" class=\"menu-item\"><i class=\"" + menuItem.getIcon() + "\"></i><span>" + "\" class=\"menu-item\"><i class=\"" + menuItem.getIcon() + "\"></i><span>"
+ menuItem.getName() + "</span></a>"; + menuItem.getName() + "</span></a>";
} }

6
src/main/java/com/gcc/swm_services/controller/login.java → src/main/java/com/gcc/flagpoles_services/controller/login.java

@ -1,12 +1,12 @@
package com.gcc.swm_services.controller;
package com.gcc.flagpoles_services.controller;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@RequestMapping("/swm")
@Controller("swmLoginController")
@RequestMapping("/flagpoles")
@Controller("flagpolesLoginController")
public class login { public class login {
@GetMapping("/login") @GetMapping("/login")

2
src/main/java/com/gcc/swm_services/entity/AppModuleAccessEntity.java → src/main/java/com/gcc/flagpoles_services/entity/AppModuleAccessEntity.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.entity;
package com.gcc.flagpoles_services.entity;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;

2
src/main/java/com/gcc/swm_services/entity/AppModuleEntity.java → src/main/java/com/gcc/flagpoles_services/entity/AppModuleEntity.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.entity;
package com.gcc.flagpoles_services.entity;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;

2
src/main/java/com/gcc/swm_services/entity/AppUserEntity.java → src/main/java/com/gcc/flagpoles_services/entity/AppUserEntity.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.entity;
package com.gcc.flagpoles_services.entity;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;

2
src/main/java/com/gcc/swm_services/entity/AppUserGroupEntity.java → src/main/java/com/gcc/flagpoles_services/entity/AppUserGroupEntity.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.entity;
package com.gcc.flagpoles_services.entity;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;

2
src/main/java/com/gcc/swm_services/entity/MenuItemAccessEntity.java → src/main/java/com/gcc/flagpoles_services/entity/MenuItemAccessEntity.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.entity;
package com.gcc.flagpoles_services.entity;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;

2
src/main/java/com/gcc/swm_services/entity/MenuItemEntity.java → src/main/java/com/gcc/flagpoles_services/entity/MenuItemEntity.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.entity;
package com.gcc.flagpoles_services.entity;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;

2
src/main/java/com/gcc/swm_services/entity/SubMenuItemAccessEntity.java → src/main/java/com/gcc/flagpoles_services/entity/SubMenuItemAccessEntity.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.entity;
package com.gcc.flagpoles_services.entity;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;

2
src/main/java/com/gcc/swm_services/entity/SubMenuItemEntity.java → src/main/java/com/gcc/flagpoles_services/entity/SubMenuItemEntity.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.entity;
package com.gcc.flagpoles_services.entity;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;

2
src/main/java/com/gcc/swm_services/entity/UserActivityLog.java → src/main/java/com/gcc/flagpoles_services/entity/UserActivityLog.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.entity;
package com.gcc.flagpoles_services.entity;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import javax.persistence.Entity; import javax.persistence.Entity;

2
src/main/java/com/gcc/swm_services/entity/UserInfoEntity.java → src/main/java/com/gcc/flagpoles_services/entity/UserInfoEntity.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.entity;
package com.gcc.flagpoles_services.entity;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;

425
src/main/java/com/gcc/flagpoles_services/flagpoles/controller/FlagPoleApiController.java

@ -0,0 +1,425 @@
package com.gcc.flagpoles_services.flagpoles.controller;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.gcc.flagpoles_services.configuration.AppConfig;
import com.gcc.flagpoles_services.flagpoles.service.FlagpoleSMSService;
import com.gcc.flagpoles_services.flagpoles.service.RdoService;
@RestController
@RequestMapping("/flagpoles/api/flagpoleregistration")
public class FlagPoleApiController {
@Autowired
private RdoService rdoService;
@Autowired
private FlagpoleSMSService flagpoleSMSService;
private final RestTemplate restTemplate;
private final AppConfig appConfig;
@Autowired
public FlagPoleApiController(RestTemplate restTemplate, AppConfig appConfig) {
this.restTemplate = restTemplate;
this.appConfig = appConfig;
}
// new
// @GetMapping("/getAllDetails")
// public ResponseEntity<?> getAllRequestDetails(
// @RequestParam String userLogin,
// @RequestParam(required = false) String startDate,
// @RequestParam(required = false) String endDate) {
// try {
// List<Map<String, Object>> result =
// rdoService.getAllRequestDetailsByUserLogin(
// userLogin, startDate, endDate);
// // 🔥 Attach HISTORY per refid
// for (Map<String, Object> record : result) {
// String refid = (String) record.get("refid");
// // List<Map<String, Object>> history =
// // rdoService.getRequestHistoryByRefId(refid);
// List<Map<String, Object>> 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("/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<Map<String, Object>> result =
// rdoService.getAllRequestDetailsByUserLogin(
// gccUserId, startDate, endDate);
// // 🔥 Attach HISTORY per refid (dept-wise)
// for (Map<String, Object> record : result) {
// String refid = (String) record.get("refid");
// List<Map<String, Object>> 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()));
// }
// }
@GetMapping("/getAllDetails")
public ResponseEntity<?> getAllRequestDetails(
@RequestParam String gccUserId,
@RequestParam(required = false) String startDate,
@RequestParam(required = false) String endDate) {
try {
/* 🔥 Normalize input (username OR id → gccuserid) */
gccUserId = rdoService.resolveGccUserId(gccUserId);
List<Map<String, Object>> result = rdoService.getAllRequestDetailsByUserLogin(gccUserId,
startDate, endDate);
/* 🔥 Attach HISTORY per refid */
for (Map<String, Object> record : result) {
String refid = (String) record.get("refid");
List<Map<String, Object>> history = rdoService.getOfficerFeedbackHistoryByRefId(refid,
gccUserId);
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()));
}
}
// 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 gccUserId) {
// try {
// /* 🔥 Normalize username OR id → gccuserid */
// gccUserId = rdoService.resolveGccUserId(gccUserId);
// int count = rdoService.updateRdoDecision(
// refid, status, remarks, gccUserId);
// 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()));
// }
// }
@PostMapping("/officer/updateDecision")
public ResponseEntity<?> updateOfficerDecision(
@RequestParam String refid,
@RequestParam String status,
@RequestParam String remarks,
@RequestParam String gccUserId,
@RequestParam String username) {
try {
/* 🔥 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()));
}
}
// old
// @GetMapping("/getApprovedAndRejectedDetails")
// public ResponseEntity<?> getApprovedRequestDetails(
// @RequestParam String userLogin,
// @RequestParam(required = false) String startDate,
// @RequestParam(required = false) String endDate,
// @RequestParam(required = false) String status) {
// try {
// List<Map<String, Object>> result =
// rdoService.getRdoApprovedRequestDetailsByUserLogin(
// userLogin, startDate, endDate, status);
// 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("/getApprovedAndRejectedDetails")
// public ResponseEntity<?> getApprovedRequestDetails(
// @RequestParam String userLogin,
// @RequestParam(required = false) String startDate,
// @RequestParam(required = false) String endDate,
// @RequestParam(required = false) String status) {
// try {
// List<Map<String, Object>> result =
// rdoService.getRdoApprovedRequestDetailsByUserLogin(
// userLogin, startDate, endDate, status);
// // 🔥 Attach HISTORY per refid
// for (Map<String, Object> record : result) {
// String refid = (String) record.get("refid");
// List<Map<String, Object>> history =
// rdoService.getRequestHistoryByRefId(refid);
// 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(required = false) String startDate,
// @RequestParam(required = false) String endDate) {
// try {
// List<Map<String, Object>> result =
// rdoService.getRdoApprovedRequestDetailsByUserLogin(
// userLogin, startDate, endDate, null);
// for (Map<String, Object> record : result) {
// String refid = (String) record.get("refid");
// // 🔥 NEW: officer feedback history
// List<Map<String, Object>> 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 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<Map<String, Object>> result = rdoService.getRdoApprovedRequestDetailsByUserLogin(
gccUserId, startDate, endDate, null);
/* 🔥 Attach officer feedback history per refid */
for (Map<String, Object> record : result) {
String refid = (String) record.get("refid");
List<Map<String, Object>> history = rdoService.getOfficerFeedbackHistoryByRefId(refid,
gccUserId);
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 approved/rejected data",
"error", e.getMessage()));
}
}
@GetMapping("/sendApprovedMessage")
public String sendApprovedMessage(@RequestParam String mobileNo,
@RequestParam String refid) {
return flagpoleSMSService.userrequestApprovedsms(mobileNo, refid);
}
@GetMapping("/sendRejectMessage")
public String sendRejectMessage(@RequestParam String mobileNo, @RequestParam String refid) {
return flagpoleSMSService.userrequestRejectedsms(mobileNo, refid);
}
@GetMapping("/sendUnauthorizedMessage")
public String sendUnauthorizedMessage(@RequestParam String mobileNo, @RequestParam String location,
@RequestParam String fineAmount, @RequestParam String refid) {
return flagpoleSMSService.unauthorizedFlagPoleSms(mobileNo, location, fineAmount, refid);
}
}

53
src/main/java/com/gcc/flagpoles_services/flagpoles/controller/MainController.java

@ -0,0 +1,53 @@
package com.gcc.flagpoles_services.flagpoles.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.gcc.flagpoles_services.service.LoginUserInfo;
@RequestMapping("/flagpoles/list")
@Controller("flagpolesController")
public class MainController {
@GetMapping("/requestlist")
public String home(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String officer_name = LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("officer_name", officer_name);
String UserRole = LoginUserInfo.getUserRole(); // rdo_north / rdo_central
model.addAttribute("UserRole", UserRole);
return "modules/flagpole/requestlist";
}
@GetMapping("/approvedandrejectedlist")
public String batches(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String officer_name = LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("officer_name", officer_name);
String UserRole = LoginUserInfo.getUserRole();
model.addAttribute("UserRole", UserRole);
return "modules/flagpole/approvedandrejectedlist";
}
@GetMapping("/reports")
public String dataentry(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String officer_name = LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("officer_name", officer_name);
String UserRole = LoginUserInfo.getUserRole();
model.addAttribute("UserRole", UserRole);
return "modules/flagpole/reports";
}
}

248
src/main/java/com/gcc/flagpoles_services/flagpoles/service/FlagpoleSMSService.java

@ -0,0 +1,248 @@
package com.gcc.flagpoles_services.flagpoles.service;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.gcc.flagpoles_services.configuration.AppConfig;
import com.gcc.flagpoles_services.flagpoles.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) {
try {
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);
String urlString = appConfig.getOtpUrl()
+ "from=GCCCRP"
+ "&key=" + key
+ "&sender=GCCCRP"
+ "&to=" + mobileNo
+ "&body=" + encodedMsg
+ "&entityid=1401572690000011081"
+ "&templateid=1407176959315374790";
System.out.println("FINAL SMS URL:- " + urlString);
URL apiUrl = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) apiUrl.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(15000);
conn.setReadTimeout(15000);
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuilder content = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
conn.disconnect();
System.out.println("DIRECT SMS RESPONSE:- " + content.toString());
return content.toString();
} catch (Exception e) {
e.printStackTrace();
return "FAILED";
}
}
// public String unauthorizedFlagPoleSms(String mobileNo,
// String location,
// String fineAmount,
// String requestId) {
// String message = "An unauthorized flag pole installation was found at " +
// location + ". "
// + "Fine amount: Rs. " + fineAmount
// + " to be paid at
// https://gccservices.in/flagpolesregistration/paymentform?requestId="
// + requestId + " to avoid further action.\n"
// + "By GCC";
// // Encode full message
// 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=1407176959335259899"; // replace with actual template id
// System.out.println("SMS URL:- " + urlString);
// String response = messageUtility.sendSMS(urlString);
// System.out.println("SMS RESPONSE:- " + response);
// return response;
// }
public String unauthorizedFlagPoleSms(String mobileNo,
String location,
String fineAmount,
String requestId) {
try {
String paymentUrl = "https://gccservices.in/flagpolesregistration/paymentform?requestId="
+ requestId;
String message = "An unauthorized flag pole installation was found at " + location + ". "
+ "Fine amount: Rs. " + fineAmount
+ " to be paid at " + paymentUrl
+ " to avoid further action.\r\n"
+ "By GCC";
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=1407176959335259899";
System.out.println("FINAL SMS URL:- " + urlString);
URL apiUrl = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) apiUrl.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(15000);
conn.setReadTimeout(15000);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuilder content = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
conn.disconnect();
System.out.println("DIRECT SMS RESPONSE:- " + content.toString());
return content.toString();
} catch (Exception e) {
e.printStackTrace();
return "FAILED";
}
}
}

1356
src/main/java/com/gcc/flagpoles_services/flagpoles/service/RdoService.java
File diff suppressed because it is too large
View File

41
src/main/java/com/gcc/flagpoles_services/flagpoles/util/MessageUtility.java

@ -0,0 +1,41 @@
package com.gcc.flagpoles_services.flagpoles.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;
}
}

36
src/main/java/com/gcc/swm_services/interceptor/AppInterceptor.java → src/main/java/com/gcc/flagpoles_services/interceptor/AppInterceptor.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.interceptor;
package com.gcc.flagpoles_services.interceptor;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
@ -10,19 +10,19 @@ import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import com.gcc.swm_services.entity.AppModuleAccessEntity;
import com.gcc.swm_services.entity.AppModuleEntity;
import com.gcc.swm_services.entity.MenuItemAccessEntity;
import com.gcc.swm_services.entity.MenuItemEntity;
import com.gcc.swm_services.entity.SubMenuItemAccessEntity;
import com.gcc.swm_services.entity.SubMenuItemEntity;
import com.gcc.swm_services.repository.AppModuleAccessRepository;
import com.gcc.swm_services.repository.AppModuleRepository;
import com.gcc.swm_services.repository.MenuItemAccessRepository;
import com.gcc.swm_services.repository.MenuItemRepository;
import com.gcc.swm_services.repository.SubMenuItemAccessRepository;
import com.gcc.swm_services.repository.SubMenuItemRepository;
import com.gcc.swm_services.service.LoginUserInfo;
import com.gcc.flagpoles_services.entity.AppModuleAccessEntity;
import com.gcc.flagpoles_services.entity.AppModuleEntity;
import com.gcc.flagpoles_services.entity.MenuItemAccessEntity;
import com.gcc.flagpoles_services.entity.MenuItemEntity;
import com.gcc.flagpoles_services.entity.SubMenuItemAccessEntity;
import com.gcc.flagpoles_services.entity.SubMenuItemEntity;
import com.gcc.flagpoles_services.repository.AppModuleAccessRepository;
import com.gcc.flagpoles_services.repository.AppModuleRepository;
import com.gcc.flagpoles_services.repository.MenuItemAccessRepository;
import com.gcc.flagpoles_services.repository.MenuItemRepository;
import com.gcc.flagpoles_services.repository.SubMenuItemAccessRepository;
import com.gcc.flagpoles_services.repository.SubMenuItemRepository;
import com.gcc.flagpoles_services.service.LoginUserInfo;
import java.util.List; import java.util.List;
@ -70,12 +70,12 @@ public class AppInterceptor implements HandlerInterceptor {
} }
private boolean isLoginPage(HttpServletRequest request) { private boolean isLoginPage(HttpServletRequest request) {
RequestMatcher loginPageMatcher = new AntPathRequestMatcher("/swm/login");
RequestMatcher loginPageMatcher = new AntPathRequestMatcher("/flagpoles/login");
return loginPageMatcher.matches(request); return loginPageMatcher.matches(request);
} }
private boolean isErrorPage(HttpServletRequest request) { private boolean isErrorPage(HttpServletRequest request) {
RequestMatcher errorPageMatcher = new AntPathRequestMatcher("/swm/error");
RequestMatcher errorPageMatcher = new AntPathRequestMatcher("/flagpoles/error");
return errorPageMatcher.matches(request); return errorPageMatcher.matches(request);
} }
@ -270,8 +270,8 @@ public class AppInterceptor implements HandlerInterceptor {
} }
public static String removeStartingString(String input) { public static String removeStartingString(String input) {
if (input.startsWith("swm")) {
return removeLeadingSlash(input.substring(3));
if (input.startsWith("flagpoles")) {
return removeLeadingSlash(input.substring(9));
} }
return input; return input;
} }

2
src/main/java/com/gcc/swm_services/modeldata/ErrorResponse.java → src/main/java/com/gcc/flagpoles_services/modeldata/ErrorResponse.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.modeldata;
package com.gcc.flagpoles_services.modeldata;
public class ErrorResponse { public class ErrorResponse {

4
src/main/java/com/gcc/swm_services/repository/AppModuleAccessRepository.java → src/main/java/com/gcc/flagpoles_services/repository/AppModuleAccessRepository.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.repository;
package com.gcc.flagpoles_services.repository;
import java.util.List; import java.util.List;
@ -10,7 +10,7 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import com.gcc.swm_services.entity.AppModuleAccessEntity;
import com.gcc.flagpoles_services.entity.AppModuleAccessEntity;
@Repository @Repository
@Transactional @Transactional

4
src/main/java/com/gcc/swm_services/repository/AppModuleRepository.java → src/main/java/com/gcc/flagpoles_services/repository/AppModuleRepository.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.repository;
package com.gcc.flagpoles_services.repository;
import java.util.List; import java.util.List;
@ -6,7 +6,7 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import com.gcc.swm_services.entity.AppModuleEntity;
import com.gcc.flagpoles_services.entity.AppModuleEntity;
import javax.transaction.Transactional; import javax.transaction.Transactional;

4
src/main/java/com/gcc/swm_services/repository/AppUserGroupRepository.java → src/main/java/com/gcc/flagpoles_services/repository/AppUserGroupRepository.java

@ -1,10 +1,10 @@
package com.gcc.swm_services.repository;
package com.gcc.flagpoles_services.repository;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import com.gcc.swm_services.entity.AppUserGroupEntity;
import com.gcc.flagpoles_services.entity.AppUserGroupEntity;
import javax.transaction.Transactional; import javax.transaction.Transactional;

4
src/main/java/com/gcc/swm_services/repository/AppUserRepository.java → src/main/java/com/gcc/flagpoles_services/repository/AppUserRepository.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.repository;
package com.gcc.flagpoles_services.repository;
import java.util.List; import java.util.List;
@ -6,7 +6,7 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import com.gcc.swm_services.entity.AppUserEntity;
import com.gcc.flagpoles_services.entity.AppUserEntity;
import javax.transaction.Transactional; import javax.transaction.Transactional;

4
src/main/java/com/gcc/swm_services/repository/MenuItemAccessRepository.java → src/main/java/com/gcc/flagpoles_services/repository/MenuItemAccessRepository.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.repository;
package com.gcc.flagpoles_services.repository;
import java.util.List; import java.util.List;
@ -8,7 +8,7 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import com.gcc.swm_services.entity.MenuItemAccessEntity;
import com.gcc.flagpoles_services.entity.MenuItemAccessEntity;
import javax.transaction.Transactional; import javax.transaction.Transactional;

4
src/main/java/com/gcc/swm_services/repository/MenuItemRepository.java → src/main/java/com/gcc/flagpoles_services/repository/MenuItemRepository.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.repository;
package com.gcc.flagpoles_services.repository;
import java.util.List; import java.util.List;
@ -7,7 +7,7 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import com.gcc.swm_services.entity.MenuItemEntity;
import com.gcc.flagpoles_services.entity.MenuItemEntity;
import javax.transaction.Transactional; import javax.transaction.Transactional;

4
src/main/java/com/gcc/swm_services/repository/SubMenuItemAccessRepository.java → src/main/java/com/gcc/flagpoles_services/repository/SubMenuItemAccessRepository.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.repository;
package com.gcc.flagpoles_services.repository;
import java.util.List; import java.util.List;
@ -8,7 +8,7 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import com.gcc.swm_services.entity.SubMenuItemAccessEntity;
import com.gcc.flagpoles_services.entity.SubMenuItemAccessEntity;
import javax.transaction.Transactional; import javax.transaction.Transactional;

4
src/main/java/com/gcc/swm_services/repository/SubMenuItemRepository.java → src/main/java/com/gcc/flagpoles_services/repository/SubMenuItemRepository.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.repository;
package com.gcc.flagpoles_services.repository;
import java.util.List; import java.util.List;
@ -7,7 +7,7 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import com.gcc.swm_services.entity.SubMenuItemEntity;
import com.gcc.flagpoles_services.entity.SubMenuItemEntity;
import javax.transaction.Transactional; import javax.transaction.Transactional;

4
src/main/java/com/gcc/swm_services/repository/UserActivityLogRepository.java → src/main/java/com/gcc/flagpoles_services/repository/UserActivityLogRepository.java

@ -1,11 +1,11 @@
package com.gcc.swm_services.repository;
package com.gcc.flagpoles_services.repository;
import java.util.List; import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import com.gcc.swm_services.entity.UserActivityLog;
import com.gcc.flagpoles_services.entity.UserActivityLog;
import javax.transaction.Transactional; import javax.transaction.Transactional;

2
src/main/java/com/gcc/swm_services/repository/UserInfoRepository.java → src/main/java/com/gcc/flagpoles_services/repository/UserInfoRepository.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.repository;
package com.gcc.flagpoles_services.repository;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;

2
src/main/java/com/gcc/swm_services/service/Base64Util.java → src/main/java/com/gcc/flagpoles_services/service/Base64Util.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.service;
package com.gcc.flagpoles_services.service;
import java.util.Base64; import java.util.Base64;

2
src/main/java/com/gcc/swm_services/service/CustomUserDetails.java → src/main/java/com/gcc/flagpoles_services/service/CustomUserDetails.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.service;
package com.gcc.flagpoles_services.service;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;

6
src/main/java/com/gcc/swm_services/service/CustomUserDetailsService.java → src/main/java/com/gcc/flagpoles_services/service/CustomUserDetailsService.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.service;
package com.gcc.flagpoles_services.service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -12,8 +12,8 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.gcc.swm_services.entity.AppUserEntity;
import com.gcc.swm_services.repository.AppUserRepository;
import com.gcc.flagpoles_services.entity.AppUserEntity;
import com.gcc.flagpoles_services.repository.AppUserRepository;
@Service @Service
public class CustomUserDetailsService implements UserDetailsService { public class CustomUserDetailsService implements UserDetailsService {

2
src/main/java/com/gcc/swm_services/service/LoginUserInfo.java → src/main/java/com/gcc/flagpoles_services/service/LoginUserInfo.java

@ -1,4 +1,4 @@
package com.gcc.swm_services.service;
package com.gcc.flagpoles_services.service;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;

6
src/main/java/com/gcc/swm_services/service/UserActivityService.java → src/main/java/com/gcc/flagpoles_services/service/UserActivityService.java

@ -1,10 +1,10 @@
package com.gcc.swm_services.service;
package com.gcc.flagpoles_services.service;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.gcc.swm_services.entity.UserActivityLog;
import com.gcc.swm_services.repository.UserActivityLogRepository;
import com.gcc.flagpoles_services.entity.UserActivityLog;
import com.gcc.flagpoles_services.repository.UserActivityLogRepository;
import java.time.LocalDateTime; import java.time.LocalDateTime;

6
src/main/java/com/gcc/swm_services/service/UserActivityTimelineService.java → src/main/java/com/gcc/flagpoles_services/service/UserActivityTimelineService.java

@ -1,10 +1,10 @@
package com.gcc.swm_services.service;
package com.gcc.flagpoles_services.service;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.gcc.swm_services.entity.UserActivityLog;
import com.gcc.swm_services.repository.UserActivityLogRepository;
import com.gcc.flagpoles_services.entity.UserActivityLog;
import com.gcc.flagpoles_services.repository.UserActivityLogRepository;
import java.util.List; import java.util.List;

163
src/main/java/com/gcc/swm_services/swm/controller/AdminController.java

@ -1,163 +0,0 @@
package com.gcc.swm_services.swm.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.gcc.swm_services.service.LoginUserInfo;
@Controller("AdminswmController")
@RequestMapping("/swm/adminfacilities")
public class AdminController {
@GetMapping("/mcc")
public String mcc(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String officer_name = LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("officer_name", officer_name);
String UserRole = LoginUserInfo.getUserRole(); // rdo_north / rdo_central
model.addAttribute("UserRole", UserRole);
int facilityTypeId = 1; // Plastic Baling Centre
model.addAttribute("facilityTypeId", facilityTypeId);
return "modules/swm/mcc";
}
@GetMapping("/windrow")
public String windrow(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String officer_name = LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("officer_name", officer_name);
String UserRole = LoginUserInfo.getUserRole(); // rdo_north / rdo_central
model.addAttribute("UserRole", UserRole);
int facilityTypeId = 2; // Plastic Baling Centre
model.addAttribute("facilityTypeId", facilityTypeId);
return "modules/swm/windrow";
}
@GetMapping("/biocng")
public String biocng(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String officer_name = LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("officer_name", officer_name);
String UserRole = LoginUserInfo.getUserRole(); // rdo_north / rdo_central
model.addAttribute("UserRole", UserRole);
int facilityTypeId = 3; // Plastic Baling Centre
model.addAttribute("facilityTypeId", facilityTypeId);
return "modules/swm/biocng";
}
@GetMapping("/biogas")
public String biogas(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String officer_name = LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("officer_name", officer_name);
String UserRole = LoginUserInfo.getUserRole(); // rdo_north / rdo_central
model.addAttribute("UserRole", UserRole);
int facilityTypeId = 4; // Plastic Baling Centre
model.addAttribute("facilityTypeId", facilityTypeId);
return "modules/swm/biogas";
}
@GetMapping("/gwtcwaste")
public String gwtcwaste(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String officer_name = LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("officer_name", officer_name);
String UserRole = LoginUserInfo.getUserRole(); // rdo_north / rdo_central
model.addAttribute("UserRole", UserRole);
int facilityTypeId = 5; // Plastic Baling Centre
model.addAttribute("facilityTypeId", facilityTypeId);
return "modules/swm/gwtcwaste";
}
@GetMapping("/mrf")
public String mrf(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String officer_name = LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("officer_name", officer_name);
String UserRole = LoginUserInfo.getUserRole(); // rdo_north / rdo_central
model.addAttribute("UserRole", UserRole);
int facilityTypeId = 6; // Plastic Baling Centre
model.addAttribute("facilityTypeId", facilityTypeId);
return "modules/swm/mrf";
}
@GetMapping("/incinerator")
public String incinerator(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String officer_name = LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("officer_name", officer_name);
String UserRole = LoginUserInfo.getUserRole(); // rdo_north / rdo_central
model.addAttribute("UserRole", UserRole);
int facilityTypeId = 7; // Plastic Baling Centre
model.addAttribute("facilityTypeId", facilityTypeId);
return "modules/swm/incinerator";
}
@GetMapping("/plastingbaling")
public String plastingbaling(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
int facilityTypeId = 8; // Plastic Baling Centre
model.addAttribute("facilityTypeId", facilityTypeId);
String officer_name = LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("officer_name", officer_name);
String UserRole = LoginUserInfo.getUserRole(); // rdo_north / rdo_central
model.addAttribute("UserRole", UserRole);
return "modules/swm/plastingbaling";
}
@GetMapping("/cdwaste")
public String cdwaste(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String officer_name = LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("officer_name", officer_name);
String UserRole = LoginUserInfo.getUserRole(); // rdo_north / rdo_central
model.addAttribute("UserRole", UserRole);
int facilityTypeId = 9; // Plastic Baling Centre
model.addAttribute("facilityTypeId", facilityTypeId);
return "modules/swm/cdwaste";
}
@GetMapping("/reports")
public String reports(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String officer_name = LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("officer_name", officer_name);
String UserRole = LoginUserInfo.getUserRole(); // rdo_north / rdo_central
model.addAttribute("UserRole", UserRole);
int facilityTypeId = 9; // Plastic Baling Centre
model.addAttribute("facilityTypeId", facilityTypeId);
return "modules/swm/reports";
}
}

35
src/main/java/com/gcc/swm_services/swm/controller/DropDownApiController.java

@ -1,35 +0,0 @@
package com.gcc.swm_services.swm.controller;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.gcc.swm_services.swm.service.DropDownService;
@RestController
@RequestMapping("/swm/api/dropdown")
public class DropDownApiController {
@Autowired
private DropDownService dropDownService;
@GetMapping("/getfacilitiestypelist")
public List<Map<String, Object>> getFacilitiesTypeList() {
return dropDownService.getFacilitiesTypeList();
}
@GetMapping("/getzoneslist")
public List<Map<String, Object>> getZonesList() {
return dropDownService.getZonesList();
}
}

71
src/main/java/com/gcc/swm_services/swm/controller/MainController.java

@ -1,71 +0,0 @@
package com.gcc.swm_services.swm.controller;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.gcc.swm_services.service.LoginUserInfo;
import com.gcc.swm_services.swm.service.AddDetailsService;
@Controller("swmController")
@RequestMapping("/swm/facilities")
public class MainController {
@Autowired
private AddDetailsService addDetailsService;
@GetMapping("/adddetails")
public String home(Model model, HttpSession session) {
String loginUserId = LoginUserInfo.getLoginUserId(); // String
String officerName = LoginUserInfo.getCurrentUserDetails().getUsername();
String userRole = LoginUserInfo.getUserRole();
// store in session
session.setAttribute("gcc_user_id", loginUserId);
session.setAttribute("username", officerName);
// 🔑 derive facility type
int gccUserId = Integer.parseInt(loginUserId);
int dpid = addDetailsService.getDpidByGccUserId(gccUserId);
// DIRECT MAPPING (as fixed earlier)
int facilityTypeId = dpid;
// 🔑 THIS WAS MISSING
boolean isTwoWeightFacility = (facilityTypeId == 5);
boolean isWeightTypeFacility = (facilityTypeId == 5 || facilityTypeId == 9);
// add to model
model.addAttribute("LoginUserId", loginUserId);
model.addAttribute("officer_name", officerName);
model.addAttribute("UserRole", userRole);
model.addAttribute("facilityTypeId", facilityTypeId);
model.addAttribute("isTwoWeightFacility", isTwoWeightFacility);
model.addAttribute("isWeightTypeFacility", isWeightTypeFacility);
return "modules/swm/requestlist";
}
@GetMapping("/approvelist")
public String batches() {
return "modules/swm/approvelist";
}
@GetMapping("/reports")
public String dataentry(Model model) {
String LoginUserId = LoginUserInfo.getLoginUserId();
model.addAttribute("LoginUserId", LoginUserId);
String officer_name = LoginUserInfo.getCurrentUserDetails().getUsername();
model.addAttribute("officer_name", officer_name);
String UserRole = LoginUserInfo.getUserRole(); // rdo_north / rdo_central
model.addAttribute("UserRole", UserRole);
return "modules/swm/eachreport";
}
}

145
src/main/java/com/gcc/swm_services/swm/controller/SwmAdminApiController.java

@ -1,145 +0,0 @@
package com.gcc.swm_services.swm.controller;
import java.time.LocalDate;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.gcc.swm_services.service.LoginUserInfo;
import com.gcc.swm_services.swm.service.AddDetailsService;
@RestController
@RequestMapping("/swm/api/admin")
public class SwmAdminApiController {
@Autowired
private AddDetailsService addDetailsService;
@PostMapping("/addfacility")
public ResponseEntity<?> addFacilityForAdmin(
@RequestParam int facilityTypeId,
@RequestParam int zoneId,
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate reqDate,
@RequestParam Double weight,
@RequestParam(required = false) Double weight1,
@RequestParam(required = false) String weightType,
@RequestParam String createdBy) {
try {
// 🔴 Validation
if (facilityTypeId < 1 || facilityTypeId > 9) {
throw new IllegalArgumentException("Invalid facility type");
}
if (zoneId <= 0) {
throw new IllegalArgumentException("Invalid zone");
}
if (reqDate == null) {
throw new IllegalArgumentException("Request date is required");
}
if (weight == null) {
throw new IllegalArgumentException("Weight is required");
}
if (facilityTypeId == 5) {
if (weight < 0) {
throw new IllegalArgumentException("Weight cannot be negative");
}
} else {
if (weight <= 0) {
throw new IllegalArgumentException("Weight must be greater than zero");
}
}
// 🔴 Facility type 5 → TWO weights + weightType
if (facilityTypeId == 5) {
if (weight1 == null) {
throw new IllegalArgumentException(
"Second weight is required for GW & TC Waste facility");
}
if (weightType == null || weightType.isBlank()) {
throw new IllegalArgumentException(
"Weight type (KDG / PDG) is required");
}
}
if (facilityTypeId == 9) {
if (weightType == null || weightType.isBlank()) {
throw new IllegalArgumentException(
"Weight type (KDG / PDG) is required");
}
}
// 🔐 Admin username for audit
// String createdBy = LoginUserInfo.getCurrentUserDetails().getUsername();
// 🔵 SAVE
addDetailsService.addFacility(
facilityTypeId,
zoneId,
reqDate,
createdBy,
weight,
weight1,
weightType);
return ResponseEntity.ok(
Map.of("status", "SUCCESS", "message", "Added successfully"));
} catch (IllegalArgumentException ex) {
return ResponseEntity.badRequest().body(
Map.of("status", "ERROR", "message", ex.getMessage()));
} catch (Exception ex) {
ex.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(
Map.of("status", "ERROR", "message", "Internal server error"));
}
}
@GetMapping("/reports")
public ResponseEntity<?> getZoneTargetPercentage(
@RequestParam String fromDate,
@RequestParam String toDate) {
if (fromDate == null || toDate == null ||
fromDate.isBlank() || toDate.isBlank()) {
return ResponseEntity.badRequest().body(
Map.of("status", "ERROR", "message", "Date range is required"));
}
return ResponseEntity.ok(
Map.of(
"status", "SUCCESS",
"data", addDetailsService.getZoneTargetPercentage(fromDate, toDate)));
}
@GetMapping("/singledayreports")
public ResponseEntity<?> getZoneTargetPercentagePerDay(
@RequestParam String Date) {
if (Date == null || Date.isBlank()) {
return ResponseEntity.badRequest().body(
Map.of("status", "ERROR", "message", "Date range is required"));
}
return ResponseEntity.ok(
Map.of(
"status", "SUCCESS",
"data", addDetailsService.getZoneTargetPercentageForOneDay(Date)));
}
}

202
src/main/java/com/gcc/swm_services/swm/controller/SwmApiController.java

@ -1,202 +0,0 @@
package com.gcc.swm_services.swm.controller;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.gcc.swm_services.service.LoginUserInfo;
import com.gcc.swm_services.swm.service.AddDetailsService;
@RestController
@RequestMapping("/swm/api/facilities")
public class SwmApiController {
@Autowired
private AddDetailsService addDetailsService;
// @PostMapping("/addfacility")
// public ResponseEntity<?> addFacility(
// @RequestParam int zoneId,
// @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate
// reqDate,
// @RequestParam Double weight,
// @RequestParam(required = false) Double weight1,
// HttpSession session) {
// try {
// // 🔴 Validation
// if (zoneId <= 0) {
// throw new IllegalArgumentException("Invalid zone");
// }
// if (reqDate == null) {
// throw new IllegalArgumentException("Request date is required");
// }
// if (weight == null || weight <= 0) {
// throw new IllegalArgumentException("Weight must be greater than zero");
// }
// // 🔐 GET LOGIN DATA FROM SESSION (CORRECT WAY)
// Object gccUserIdObj = session.getAttribute("gcc_user_id");
// Object usernameObj = session.getAttribute("username");
// if (gccUserIdObj == null || usernameObj == null) {
// throw new IllegalStateException("User session expired. Please login again.");
// }
// int gccUserId = Integer.parseInt(gccUserIdObj.toString());
// String username = usernameObj.toString();
// // 🔐 DB MAPPING
// int dpid = addDetailsService.getDpidByGccUserId(gccUserId);
// int facilityTypeId = addDetailsService.getFacilityTypeIdByDpid(dpid);
// if (facilityTypeId == 5 && (weight1 == null || weight1 <= 0)) {
// throw new IllegalArgumentException(
// "Second weight is required for GW & TC Waste facility");
// }
// addDetailsService.addFacility(
// facilityTypeId,
// zoneId,
// reqDate,
// username,
// weight,
// weight1);
// return ResponseEntity.ok(
// Map.of("status", "SUCCESS", "message", "Facility added successfully"));
// } catch (IllegalArgumentException | IllegalStateException ex) {
// return ResponseEntity.badRequest().body(
// Map.of("status", "ERROR", "message", ex.getMessage()));
// } catch (Exception ex) {
// ex.printStackTrace();
// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(
// Map.of("status", "ERROR", "message", "Internal server error"));
// }
// }
@PostMapping("/addfacility")
public ResponseEntity<?> addFacility(
@RequestParam int zoneId,
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate reqDate,
@RequestParam Double weight,
@RequestParam(required = false) Double weight1,
@RequestParam(required = false) String weightType, // ✅ ADDED
HttpSession session) {
try {
// 🔐 Session values
Object gccUserIdObj = session.getAttribute("gcc_user_id");
Object usernameObj = session.getAttribute("username");
int gccUserId = Integer.parseInt(gccUserIdObj.toString());
String username = usernameObj.toString();
// 🔐 gcc_user_id → dpid → facilityTypeId
int dpid = addDetailsService.getDpidByGccUserId(gccUserId);
int facilityTypeId = dpid;
// 🔴 Validation
if (zoneId <= 0) {
throw new IllegalArgumentException("Invalid zone");
}
if (reqDate == null) {
throw new IllegalArgumentException("Request date is required");
}
if (weight == null) {
throw new IllegalArgumentException("Weight is required");
}
if (facilityTypeId == 5) {
if (weight < 0) {
throw new IllegalArgumentException("Weight cannot be negative");
}
} else {
if (weight <= 0) {
throw new IllegalArgumentException("Weight must be greater than zero");
}
}
if (gccUserIdObj == null || usernameObj == null) {
throw new IllegalStateException("User session expired. Please login again.");
}
// 🔴 Facility type 5 → TWO weights + weightType
if (facilityTypeId == 5) {
if (weight1 == null) {
throw new IllegalArgumentException(
"Second weight is required for GW & TC Waste facility");
}
if (weightType == null || weightType.isBlank()) {
throw new IllegalArgumentException(
"Location (KDG / PDG) is required");
}
}
if (facilityTypeId == 9) {
if (weightType == null || weightType.isBlank()) {
throw new IllegalArgumentException(
"Location (KDG / PDG) is required");
}
}
// 🔵 SAVE
addDetailsService.addFacility(
facilityTypeId,
zoneId,
reqDate,
username,
weight,
weight1,
weightType // ✅ PASSED
);
return ResponseEntity.ok(
Map.of("status", "SUCCESS", "message", "Added successfully"));
} catch (IllegalArgumentException | IllegalStateException ex) {
return ResponseEntity.badRequest().body(
Map.of("status", "ERROR", "message", ex.getMessage()));
} catch (Exception ex) {
ex.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(
Map.of("status", "ERROR", "message", "Internal server error"));
}
}
@GetMapping("/reports")
public ResponseEntity<?> getZoneWiseByLogin(
@RequestParam String username,
@RequestParam String fromDate,
@RequestParam String toDate) {
List<Map<String, Object>> data = addDetailsService.getZoneWiseFacilityByLogin(
username, fromDate, toDate);
return ResponseEntity.ok(Map.of(
"status", "SUCCESS",
"data", data));
}
}

510
src/main/java/com/gcc/swm_services/swm/service/AddDetailsService.java

@ -1,510 +0,0 @@
package com.gcc.swm_services.swm.service;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@Service
public class AddDetailsService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSourcemysql(@Qualifier("mysqlSwmDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
// // ---------------- SAVE ----------------
// public void addFacility(
// int facilityTypeId,
// int zoneId,
// LocalDate reqDate,
// String createdBy,
// Double weight,
// Double weight1) {
// String sql = """
// INSERT INTO facilities_weight_details
// (ft_id, zone_id, req_date, cby, weight, weight_1)
// VALUES (?, ?, ?, ?, ?, ?)
// """;
// Timestamp reqTimestamp = Timestamp.valueOf(reqDate.atStartOfDay());
// Double dbWeight1 = (facilityTypeId == 5) ? weight1 : null;
// jdbcTemplate.update(
// sql,
// facilityTypeId,
// zoneId,
// reqTimestamp,
// createdBy,
// weight,
// dbWeight1);
// }
// public void addFacility(
// int facilityTypeId,
// int zoneId,
// LocalDate reqDate,
// String createdBy,
// Double weight,
// Double weight1,
// String weightType) {
// String sql = """
// INSERT INTO facilities_weight_details
// (ft_id, zone_id, req_date, cby, weight, weight_1, weight_type)
// VALUES (?, ?, ?, ?, ?, ?, ?)
// """;
// Timestamp reqTimestamp = Timestamp.valueOf(reqDate.atStartOfDay());
// Double dbWeight1 = (facilityTypeId == 5) ? weight1 : null;
// // ✅ weight_type allowed for GW & TC (5) AND PBC / C&D (9)
// String dbWeightType = (facilityTypeId == 5 || facilityTypeId == 9)
// ? weightType
// : null;
// jdbcTemplate.update(
// sql,
// facilityTypeId,
// zoneId,
// reqTimestamp,
// createdBy,
// weight,
// dbWeight1,
// dbWeightType);
// }
private Integer getExistingRecordId(
int facilityTypeId,
int zoneId,
LocalDate reqDate) {
String sql = """
SELECT fid
FROM facilities_weight_details
WHERE ft_id = ?
AND zone_id = ?
AND DATE(req_date) = ?
AND is_delete = 0
LIMIT 1
""";
List<Integer> ids = jdbcTemplate.query(
sql,
ps -> {
ps.setInt(1, facilityTypeId);
ps.setInt(2, zoneId);
ps.setDate(3, java.sql.Date.valueOf(reqDate));
},
(rs, rowNum) -> rs.getInt("fid"));
return ids.isEmpty() ? null : ids.get(0);
}
public void addFacility(
int facilityTypeId,
int zoneId,
LocalDate reqDate,
String officerName,
Double weight,
Double weight1,
String weightType) {
Timestamp reqTimestamp = Timestamp.valueOf(reqDate.atStartOfDay());
Double dbWeight1 = (facilityTypeId == 5) ? weight1 : null;
String dbWeightType = (facilityTypeId == 5 || facilityTypeId == 9)
? weightType
: null;
Integer existingId = getExistingRecordId(
facilityTypeId, zoneId, reqDate);
if (existingId == null) {
// 🟢 INSERT
String insertSql = """
INSERT INTO facilities_weight_details
(ft_id, zone_id, req_date, weight, weight_1, weight_type,
cby, cdate, is_active, is_delete)
VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), 1, 0)
""";
jdbcTemplate.update(
insertSql,
facilityTypeId,
zoneId,
reqTimestamp,
weight,
dbWeight1,
dbWeightType,
officerName);
} else {
// 🔵 UPDATE
String updateSql = """
UPDATE facilities_weight_details
SET weight = ?,
weight_1 = ?,
weight_type = ?,
updated_by = ?,
updated_date = NOW()
WHERE fid = ?
""";
jdbcTemplate.update(
updateSql,
weight,
dbWeight1,
dbWeightType,
officerName,
existingId);
}
}
// ---------------- DPID ----------------
public int getDpidByGccUserId(int gccUserId) {
String sql = """
SELECT dpid
FROM department_login
WHERE gcc_user_id = ?
AND is_active = 1
AND is_delete = 0
""";
List<Integer> list = jdbcTemplate.queryForList(sql, Integer.class, gccUserId);
if (list.isEmpty()) {
throw new IllegalArgumentException(
"Department not mapped for user id: " + gccUserId);
}
return list.get(0);
}
// ---------------- FACILITY TYPE ----------------
public int getFacilityTypeIdByDpid(int dpid) {
String sql = """
SELECT ft.ft_id
FROM department_login dl
JOIN facilities_type ft
ON LOWER(REPLACE(REPLACE(dl.department_name,'swm_',''),'_',' '))
LIKE CONCAT('%', LOWER(ft.facilities_name), '%')
WHERE dl.dpid = ?
AND dl.is_active = 1
AND dl.is_delete = 0
AND ft.is_active = 1
AND ft.is_delete = 0
""";
List<Integer> list = jdbcTemplate.queryForList(sql, Integer.class, dpid);
if (list.isEmpty()) {
throw new IllegalArgumentException(
"Facility type not mapped for department id: " + dpid);
}
return list.get(0);
}
public List<Map<String, Object>> getZoneTargetPercentage(
String fromDate, String toDate) {
String sql = """
SELECT
t.zone,
t.facility,
t.target,
COALESCE(a.achieved, 0) AS achieved,
ROUND(
CASE
WHEN t.target = 0 AND COALESCE(a.achieved, 0) > 0 THEN 100
WHEN t.target = 0 THEN 0
ELSE LEAST((COALESCE(a.achieved, 0) / t.target) * 100, 100)
END,
2
) AS percentage
FROM (
SELECT zone, 1 AS ft_id, 'MCC' AS facility, mcc AS target
FROM zonewise_target WHERE is_active = 1 AND is_delete = 0
UNION ALL
SELECT zone, 2, 'Windrow', windrow FROM zonewise_target
WHERE is_active = 1 AND is_delete = 0
UNION ALL
SELECT zone, 3, 'Bio-CNG', bio_cng FROM zonewise_target
WHERE is_active = 1 AND is_delete = 0
UNION ALL
SELECT zone, 4, 'Bio-GAS', bio_gas FROM zonewise_target
WHERE is_active = 1 AND is_delete = 0
UNION ALL
SELECT zone, 5, 'GW & TC Waste', gw_tc_waste FROM zonewise_target
WHERE is_active = 1 AND is_delete = 0
UNION ALL
SELECT zone, 6, 'MRF OR RRC', mrf_mrr FROM zonewise_target
WHERE is_active = 1 AND is_delete = 0
UNION ALL
SELECT zone, 7, 'Incinerator', incinerator FROM zonewise_target
WHERE is_active = 1 AND is_delete = 0
UNION ALL
SELECT zone, 8, 'Plasting Baling Centre', plasting_baling_centre
FROM zonewise_target WHERE is_active = 1 AND is_delete = 0
) t
LEFT JOIN (
SELECT
fwd.zone_id AS zone,
fwd.ft_id,
SUM(
CASE
WHEN fwd.ft_id = 5
THEN COALESCE(fwd.weight, 0)
+ COALESCE(fwd.weight_1, 0)
ELSE
COALESCE(fwd.weight, 0)
END
) AS achieved
FROM facilities_weight_details fwd
WHERE fwd.is_active = 1
AND fwd.is_delete = 0
AND DATE(fwd.req_date) BETWEEN ? AND ?
GROUP BY fwd.zone_id, fwd.ft_id
) a
ON a.zone = t.zone
AND a.ft_id = t.ft_id
ORDER BY t.zone, t.facility
""";
return jdbcTemplate.queryForList(sql, fromDate, toDate);
}
public List<Map<String, Object>> getZoneTargetPercentageForOneDay(String date) {
String sql = """
SELECT
t.zone,
t.facility,
t.target,
COALESCE(a.achieved, 0) AS achieved,
ROUND(
CASE
WHEN t.target = 0 AND COALESCE(a.achieved, 0) > 0 THEN 100
WHEN t.target = 0 THEN 0
ELSE LEAST((COALESCE(a.achieved, 0) / t.target) * 100, 100)
END,
2
) AS percentage
FROM (
SELECT zone, 1 AS ft_id, 'MCC' AS facility, mcc AS target FROM zonewise_target WHERE is_active = 1 AND is_delete = 0
UNION ALL SELECT zone, 2, 'Windrow', windrow FROM zonewise_target WHERE is_active = 1 AND is_delete = 0
UNION ALL SELECT zone, 3, 'Bio-CNG', bio_cng FROM zonewise_target WHERE is_active = 1 AND is_delete = 0
UNION ALL SELECT zone, 4, 'Bio-GAS', bio_gas FROM zonewise_target WHERE is_active = 1 AND is_delete = 0
UNION ALL SELECT zone, 5, 'GW & TC Waste', gw_tc_waste FROM zonewise_target WHERE is_active = 1 AND is_delete = 0
UNION ALL SELECT zone, 6, 'MRF OR RRC', mrf_mrr FROM zonewise_target WHERE is_active = 1 AND is_delete = 0
UNION ALL SELECT zone, 7, 'Incinerator', incinerator FROM zonewise_target WHERE is_active = 1 AND is_delete = 0
UNION ALL SELECT zone, 8, 'Plasting Baling Centre', plasting_baling_centre FROM zonewise_target WHERE is_active = 1 AND is_delete = 0
) t
LEFT JOIN (
SELECT
fwd.zone_id AS zone,
fwd.ft_id,
SUM(
CASE
WHEN fwd.ft_id = 5
THEN COALESCE(fwd.weight, 0) + COALESCE(fwd.weight_1, 0)
ELSE COALESCE(fwd.weight, 0)
END
) AS achieved
FROM facilities_weight_details fwd
WHERE fwd.is_active = 1
AND fwd.is_delete = 0
AND DATE(fwd.req_date) = ? -- **single‑date filter**
GROUP BY fwd.zone_id, fwd.ft_id
) a
ON a.zone = t.zone
AND a.ft_id = t.ft_id
ORDER BY t.zone, t.facility
""";
// Only one parameter (the date) is bound now.
return jdbcTemplate.queryForList(sql, date);
}
// public List<Map<String, Object>> getZoneWiseFacilityByLogin(
// String username,
// String fromDate,
// String toDate) {
// String sql = """
// SELECT
// t.zone,
// t.facility,
// t.target,
// COALESCE(a.achieved, 0) AS achieved,
// ROUND(
// CASE
// WHEN t.target = 0 AND COALESCE(a.achieved, 0) > 0 THEN 100
// WHEN t.target = 0 AND COALESCE(a.achieved, 0) = 0 THEN 0
// ELSE LEAST((COALESCE(a.achieved, 0) / t.target) * 100, 100)
// END, 2
// ) AS percentage
// FROM (
// /* 🔹 TARGET – ONLY FACILITY FROM LOGIN */
// SELECT
// zt.zone,
// ft.facilities_name AS facility,
// CASE ft.ft_id
// WHEN 1 THEN zt.mcc
// WHEN 2 THEN zt.windrow
// WHEN 3 THEN zt.bio_cng
// WHEN 4 THEN zt.bio_gas
// WHEN 5 THEN zt.gw_tc_waste
// WHEN 6 THEN zt.mrf_mrr
// WHEN 7 THEN zt.incinerator
// WHEN 8 THEN zt.plasting_baling_centre
// ELSE 0
// END AS target
// FROM department_login dl
// JOIN facilities_type ft ON ft.ft_id = dl.dpid
// JOIN zonewise_target zt ON zt.is_active = 1 AND zt.is_delete = 0
// WHERE dl.user_name = ?
// ) t
// LEFT JOIN (
// /* 🔹 ACHIEVED – SAME FT_ID + LOGIN */
// SELECT
// fwd.zone_id AS zone,
// ft.facilities_name AS facility,
// SUM(COALESCE(fwd.weight, 0) + COALESCE(fwd.weight_1, 0)) AS achieved
// FROM facilities_weight_details fwd
// JOIN facilities_type ft ON ft.ft_id = fwd.ft_id
// WHERE fwd.is_active = 1
// AND fwd.is_delete = 0
// AND fwd.cby = ?
// AND DATE(fwd.req_date) BETWEEN ? AND ?
// GROUP BY fwd.zone_id, ft.facilities_name
// ) a
// ON a.zone = t.zone AND a.facility = t.facility
// ORDER BY t.zone
// """;
// return jdbcTemplate.queryForList(
// sql,
// username,
// username,
// fromDate,
// toDate);
// }
private String normalizeDate(String date) {
if (date == null || date.isBlank()) {
return date;
}
// If browser format yyyy-MM-dd → convert to dd-MM-yyyy
if (date.matches("\\d{4}-\\d{2}-\\d{2}")) {
String[] p = date.split("-");
return p[2] + "-" + p[1] + "-" + p[0];
}
// Already dd-MM-yyyy
return date;
}
public List<Map<String, Object>> getZoneWiseFacilityByLogin(
String username,
String fromDate,
String toDate) {
// 🔥 Normalize date format (supports yyyy-MM-dd and dd-MM-yyyy)
fromDate = normalizeDate(fromDate);
toDate = normalizeDate(toDate);
String sql = """
SELECT
t.zone,
t.facility,
t.target,
COALESCE(a.achieved, 0) AS achieved,
ROUND(
CASE
WHEN t.target = 0 AND COALESCE(a.achieved, 0) > 0 THEN 100
WHEN t.target = 0 AND COALESCE(a.achieved, 0) = 0 THEN 0
ELSE LEAST((COALESCE(a.achieved, 0) / t.target) * 100, 100)
END, 2
) AS percentage
FROM (
/* TARGET */
SELECT
zt.zone,
ft.ft_id,
ft.facilities_name AS facility,
CASE ft.ft_id
WHEN 1 THEN zt.mcc
WHEN 2 THEN zt.windrow
WHEN 3 THEN zt.bio_cng
WHEN 4 THEN zt.bio_gas
WHEN 5 THEN zt.gw_tc_waste
WHEN 6 THEN zt.mrf_mrr
WHEN 7 THEN zt.incinerator
WHEN 8 THEN zt.plasting_baling_centre
ELSE 0
END AS target
FROM department_login dl
JOIN facilities_type ft ON ft.ft_id = dl.dpid
JOIN zonewise_target zt
ON zt.is_active = 1
AND zt.is_delete = 0
WHERE TRIM(dl.user_name) = ?
) t
LEFT JOIN (
/* ACHIEVED */
SELECT
fwd.zone_id AS zone,
fwd.ft_id,
SUM(COALESCE(fwd.weight, 0) + COALESCE(fwd.weight_1, 0)) AS achieved
FROM facilities_weight_details fwd
WHERE fwd.is_active = 1
AND fwd.is_delete = 0
AND TRIM(fwd.cby) = ?
AND fwd.req_date >= STR_TO_DATE(CONCAT(?, ' 00:00:00'), '%d-%m-%Y %H:%i:%s')
AND fwd.req_date <= STR_TO_DATE(CONCAT(?, ' 23:59:59'), '%d-%m-%Y %H:%i:%s')
AND fwd.ft_id = (
SELECT dpid
FROM department_login
WHERE TRIM(user_name) = ?
)
GROUP BY fwd.zone_id, fwd.ft_id
) a
ON a.zone = t.zone
AND a.ft_id = t.ft_id
ORDER BY t.zone
""";
return jdbcTemplate.queryForList(
sql,
username,
username,
fromDate,
toDate,
username);
}
}

37
src/main/java/com/gcc/swm_services/swm/service/DropDownService.java

@ -1,37 +0,0 @@
package com.gcc.swm_services.swm.service;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;
@Service
public class DropDownService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSourcemysql(@Qualifier("mysqlSwmDataSource") DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public List<Map<String, Object>> getFacilitiesTypeList() {
String sql = " SELECT * FROM facilities_type where is_active = '1' and is_delete ='0' ";
return jdbcTemplate.queryForList(sql);
}
public List<Map<String, Object>> getZonesList() {
String sql = " SELECT * FROM zones where is_active = '1' and is_delete ='0' ";
return jdbcTemplate.queryForList(sql);
}
}

2
src/main/resources/application-dev.properties

@ -1,5 +1,5 @@
assets.base-url=/assets/ assets.base-url=/assets/
fileBaseUrl=http://localhost:8060
fileBaseUrl=http://localhost:8061
#fileBaseUrl = D:/Projects/Election_Project/election_v1/gcc_election_uploads #fileBaseUrl = D:/Projects/Election_Project/election_v1/gcc_election_uploads

4
src/main/resources/application-prod.properties

@ -1,3 +1,3 @@
assets.base-url=/swm/assets/
assets.base-url=/flagpoles/assets/
fileBaseUrl=https://gccservices.in/files
fileBaseUrl=https://gccservices.in/flagpoles

4
src/main/resources/application.properties

@ -2,7 +2,7 @@ spring.profiles.active=dev
#spring.profiles.active=prod #spring.profiles.active=prod
# Spring properties # Spring properties
spring.application.name=swm_login
spring.application.name=flagpoles_login
spring.datasource.hikari.connection-timeout=30000 spring.datasource.hikari.connection-timeout=30000
@ -15,7 +15,7 @@ spring.servlet.multipart.max-file-size=20MB
spring.servlet.multipart.max-request-size=20MB spring.servlet.multipart.max-request-size=20MB
# HTTP Server # HTTP Server
server.port = 8060
server.port = 8061
#server.servlet.context-path=/gccoffice #server.servlet.context-path=/gccoffice
server.error.include-stacktrace= on_param server.error.include-stacktrace= on_param
# Hibernate logging # Hibernate logging

10
src/main/resources/templates/error-403.html

@ -1,7 +1,9 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" dir=""> <html lang="en" dir="">
<html xmlns:th="http://www.thymeleaf.org"> <html xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head> <head th:replace="~{fragments/modules/base/head :: head}"></head>
<body> <body>
<!--[if lt IE 8]> <!--[if lt IE 8]>
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p> <p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
@ -19,9 +21,12 @@
<div class="col-xl-6 col-lg-6 col-md-7 my-auto p-0"> <div class="col-xl-6 col-lg-6 col-md-7 my-auto p-0">
<div class="authentication-form mx-auto text-center"> <div class="authentication-form mx-auto text-center">
<div class="logo-centered"> <div class="logo-centered">
<a href="/"><img src="images/logo.png" alt="Greater Chennai Corporation" class="header-brand-img" width="100%"></a>
<a href="/"><img src="images/logo.png" alt="Greater Chennai Corporation" class="header-brand-img"
width="100%"></a>
</div> </div>
<h3>Greater Chennai Corporation</h3>
<h3>Greater Chennai Corporation
Flagpoles Officer Login
</h3>
<!-- Content --> <!-- Content -->
<div class="flex-grow-1 d-flex align-items-center p-5 bg-body-light"> <div class="flex-grow-1 d-flex align-items-center p-5 bg-body-light">
<div class="w-100"> <div class="w-100">
@ -54,4 +59,5 @@
} }
</script> </script>
</body> </body>
</html> </html>

2
src/main/resources/templates/fragments/modules/base/footer.html

@ -1,5 +1,5 @@
<footer class="footer"> <footer class="footer">
<form id="logout-form" th:action="@{/swm/logout}" method="post" style="display: none;"></form>
<form id="logout-form" th:action="@{/flagpoles/logout}" method="post" style="display: none;"></form>
<div class="w-100 clearfix text-center"> <div class="w-100 clearfix text-center">
<span class="text-center">Copyright &copy; Greater Chennai Corporation | All rights reserved</span> <span class="text-center">Copyright &copy; Greater Chennai Corporation | All rights reserved</span>
<!-- <span class="float-none float-sm-right mt-1 mt-sm-0 text-center">Coded By BonTon Softwares Pvt Ltd</span> --> <!-- <span class="float-none float-sm-right mt-1 mt-sm-0 text-center">Coded By BonTon Softwares Pvt Ltd</span> -->

2
src/main/resources/templates/fragments/modules/base/head.html

@ -1,7 +1,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge"> <meta http-equiv="x-ua-compatible" content="ie=edge">
<title>GCC SWM_LOGIN APP</title>
<title>GCC Flagpoles_LOGIN APP</title>
<meta name="description" content=""> <meta name="description" content="">
<meta name="keywords" content=""> <meta name="keywords" content="">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">

4
src/main/resources/templates/fragments/modules/base/header.html

@ -16,7 +16,7 @@
</div> </div>
<div id="headings_center"> <div id="headings_center">
Solid Waste Management System
Flagpoles Officer Services Portal
</div> </div>
<div class="top-menu d-flex align-items-center"> <div class="top-menu d-flex align-items-center">
@ -71,7 +71,7 @@
<a class="dropdown-item" href="#"><i class="ik ik-settings dropdown-icon"></i> Settings</a> <a class="dropdown-item" href="#"><i class="ik ik-settings dropdown-icon"></i> Settings</a>
<a class="dropdown-item" href="#"><span class="float-right"><span class="badge badge-primary">6</span></span><i class="ik ik-mail dropdown-icon"></i> Inbox</a> <a class="dropdown-item" href="#"><span class="float-right"><span class="badge badge-primary">6</span></span><i class="ik ik-mail dropdown-icon"></i> Inbox</a>
<a class="dropdown-item" href="#"><i class="ik ik-navigation dropdown-icon"></i> Message</a> --> <a class="dropdown-item" href="#"><i class="ik ik-navigation dropdown-icon"></i> Message</a> -->
<a class="dropdown-item" th:href="@{/swm/logout}"
<a class="dropdown-item" th:href="@{/flagpoles/logout}"
onclick="event.preventDefault(); document.getElementById('logout-form').submit();"><i onclick="event.preventDefault(); document.getElementById('logout-form').submit();"><i
class="ik ik-power dropdown-icon"></i> Logout</a> class="ik ik-power dropdown-icon"></i> Logout</a>
<a class="dropdown-item" th:href="@{#}" onclick="event.preventDefault();passwordReset();"><i <a class="dropdown-item" th:href="@{#}" onclick="event.preventDefault();passwordReset();"><i

2
src/main/resources/templates/fragments/modules/base/login-head.html

@ -1,7 +1,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge"> <meta http-equiv="x-ua-compatible" content="ie=edge">
<title>GCC RDO_LOGIN APP</title>
<title>GCC Flagpoles_LOGIN APP</title>
<meta name="description" content=""> <meta name="description" content="">
<meta name="keywords" content=""> <meta name="keywords" content="">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">

2
src/main/resources/templates/fragments/modules/base/script.html

@ -332,7 +332,7 @@
// Send AJAX request to reset password // Send AJAX request to reset password
$.ajax({ $.ajax({
url: '/swm/api/resetPassword', // Update with the actual endpoint URL
url: '/flagpoles/api/resetPassword', // Update with the actual endpoint URL
type: 'POST', type: 'POST',
data: formData, data: formData,
contentType: false, // Required for FormData contentType: false, // Required for FormData

6
src/main/resources/templates/index.html

@ -35,7 +35,7 @@
<nav class="breadcrumb-container" aria-label="breadcrumb"> <nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="/swm"><i class="ik ik-home"></i></a>
<a href="/flagpoles"><i class="ik ik-home"></i></a>
</li> </li>
<li class="breadcrumb-item active" aria-current="page">Dashboard</li> <li class="breadcrumb-item active" aria-current="page">Dashboard</li>
</ol> </ol>
@ -137,7 +137,7 @@
/* Get Complaints Data */ /* Get Complaints Data */
function get_user_basic_data() { function get_user_basic_data() {
var apiUrl = '/swm/api/getUserProfileBasic?userId=' + createdBy;
var apiUrl = '/flagpoles/api/getUserProfileBasic?userId=' + createdBy;
//alert(apiUrl); //alert(apiUrl);
// Return a Promise // Return a Promise
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
@ -174,7 +174,7 @@
/* Get Complaints Data */ /* Get Complaints Data */
function get_user_data() { function get_user_data() {
var apiUrl = '/swm/api/getUserProfile?userId=' + createdBy;
var apiUrl = '/flagpoles/api/getUserProfile?userId=' + createdBy;
//alert(apiUrl); //alert(apiUrl);
// Return a Promise // Return a Promise
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {

6
src/main/resources/templates/login.html

@ -20,15 +20,15 @@
<div class="col-xl-4 col-lg-6 col-md-7 my-auto p-0"> <div class="col-xl-4 col-lg-6 col-md-7 my-auto p-0">
<div class="authentication-form mx-auto text-center"> <div class="authentication-form mx-auto text-center">
<div class="logo-centered"> <div class="logo-centered">
<a href="/swm"><img src="images/logo.png" alt="Greater Chennai Corporation"
<a href="/flagpoles"><img src="images/logo.png" alt="Greater Chennai Corporation"
class="header-brand-img" width="100%"></a> class="header-brand-img" width="100%"></a>
</div> </div>
<h3>Greater Chennai Corporation</h3>
<h3>Greater Chennai Corporation Flagpoles Officer Login</h3>
<p>Happy to see you again!</p> <p>Happy to see you again!</p>
<div th:if="${param.error}"> <div th:if="${param.error}">
<p style="color: red;">Invalid credentials.</p> <p style="color: red;">Invalid credentials.</p>
</div> </div>
<form th:action="@{/swm/login}" method="post">
<form th:action="@{/flagpoles/login}" method="post">
<div class="form-group"> <div class="form-group">
<input type="text" class="form-control" id="username" name="username" <input type="text" class="form-control" id="username" name="username"
placeholder="Username" required="" value=""> placeholder="Username" required="" value="">

4
src/main/resources/templates/modules/admin/user-group-access.html

@ -151,7 +151,7 @@
const loadaccesstree = $("#loadaccesstree"); const loadaccesstree = $("#loadaccesstree");
const searchBtn = $("#groupSearchbtn"); const searchBtn = $("#groupSearchbtn");
const savebtn = $("#savebtn"); const savebtn = $("#savebtn");
const apiUrl = "/swm/api/getAccessTree?groupId=" + groupId + "&groupName=" + groupName;
const apiUrl = "/flagpoles/api/getAccessTree?groupId=" + groupId + "&groupName=" + groupName;
$.ajax({ $.ajax({
url: apiUrl, url: apiUrl,
@ -244,7 +244,7 @@
var submitCheckedData = function (checkedData, groupId) { var submitCheckedData = function (checkedData, groupId) {
// Perform your AJAX request here using checkedData // Perform your AJAX request here using checkedData
// Replace the URL and other options with your actual API endpoint and data // Replace the URL and other options with your actual API endpoint and data
const apiUrl = "/swm/api/saveGroupAccessData";
const apiUrl = "/flagpoles/api/saveGroupAccessData";
const selectedGroup = $('#search_groupid'); const selectedGroup = $('#search_groupid');
const selectedGroupName = selectedGroup.find('option:selected').text(); const selectedGroupName = selectedGroup.find('option:selected').text();

2
src/main/resources/templates/modules/admin/user-list.html

@ -215,7 +215,7 @@
} }
function getUserDetails(userid) { function getUserDetails(userid) {
const apiUrl = "/swm/api/getUserProfile";
const apiUrl = "/flagpoles/api/getUserProfile";
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
$.ajax({ $.ajax({
url: apiUrl, url: apiUrl,

458
src/main/resources/templates/modules/swm/biocng.html → src/main/resources/templates/modules/flagpole/approvedandrejectedlist.html

@ -73,8 +73,8 @@
.badge-status { .badge-status {
background: #ffd9b3;
color: #a65c00;
background: #2dce89;
color: #212121;
padding: 6px 10px; padding: 6px 10px;
border-radius: 5px; border-radius: 5px;
font-size: 13px; font-size: 13px;
@ -94,7 +94,7 @@
} }
</style> </style>
<body th:attr="data-two-weight=${isTwoWeightFacility}">
<body>
<div class="wrapper"> <div class="wrapper">
<!-- header top menu Start --> <!-- header top menu Start -->
@ -112,8 +112,8 @@
<div class="page-header-title"> <div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i> <i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline"> <div class="d-inline">
<h5>SWD BioCNG Facilities Add Details List</h5>
<span>BioCNG Add Details</span>
<h5>Approved & Rejected List</h5>
<span>Flag Pole Approved & Rejected List</span>
</div> </div>
</div> </div>
</div> </div>
@ -121,12 +121,12 @@
<nav class="breadcrumb-container" aria-label="breadcrumb"> <nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="breadcrumb-item"> <li class="breadcrumb-item">
<a href="/swm/index"><i class="ik ik-home"></i></a>
<a href="/flagpoles/index"><i class="ik ik-home"></i></a>
</li> </li>
<li class="breadcrumb-item" aria-current="page">SWD BioCNG Facilities Add
Details List
<li class="breadcrumb-item" aria-current="page">Flag Pole Approved & Rejected
List</li>
<li class="breadcrumb-item active" aria-current="page">Approved & Rejected List
</li> </li>
<li class="breadcrumb-item active" aria-current="page">BioCNG Add Details</li>
</ol> </ol>
</nav> </nav>
</div> </div>
@ -138,49 +138,101 @@
<div class="col-md-12"> <div class="col-md-12">
<div class="card"> <div class="card">
<div class="card-header d-flex justify-content-between align-items-center fw-bold"> <div class="card-header d-flex justify-content-between align-items-center fw-bold">
<h3 class="mb-0"> SWM BioCNG Add Details : <span th:text="${officer_name}"></span>
</h3>
<h3 class="mb-0">Temporary Flag Poles - Approved & Rejected List : <span
th:text="${officer_name}"></span></h3>
<input type="hidden" id="userName" th:value="${officer_name}"> <input type="hidden" id="userName" th:value="${officer_name}">
<input type="hidden" id="loginuserid" th:value="${LoginUserId}">
</div> </div>
<div class="card-body">
<div class="row">
<div class="row mt-3 ml-2">
<div class="col-md-3"> <div class="col-md-3">
<label for="date" class="form-label"
style="font-size: medium;">Date:</label><span
class="text-danger">*</span>
<input type="date" id="date" class="form-control">
<label for="startDate" class="form-label" style="font-size: medium;">From
Date:</label>
<input type="date" id="startDate" class="form-control" placeholder="Start Date">
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<label for="zones" class="form-label">Zones <span
class="text-danger">*</span>
</label> <select id="zones" class="form-control">
<option value="">Select zones</option>
<label for="endDate" class="form-label" style="font-size: medium;">To
Date:</label>
<input type="date" id="endDate" class="form-control" placeholder="End Date">
</div>
<div class="col-md-3">
<label class="form-label">Status:</label>
<select id="statusFilter" class="form-control">
<option value="">All</option>
<option value="APPROVED">Approved</option>
<option value="REJECTED">Rejected</option>
</select> </select>
</div> </div>
<div class="col-md-3" style="margin-top: 30px;">
<button id="searchBtn" class="btn btn-primary">Search</button>
<button id="resetBtn" class="btn btn-secondary">Reset</button>
</div>
</div>
<div class="card-body">
<div>
<div class="row mt-2">
<div class="col-md-3">
<label for="weight" class="form-label">Enter Weight:(in MT)</label><span
class="text-danger">*</span>
<input type="number" class="form-control" id="weight">
<div class="col-xl-3 col-md-3 col-sm-12">
<div class="card card-box p-4">
<h6 class="text-facebook mb-20 mt-2 text-center fw-bold"><b>Total
Request</b>
</h6>
<h4 class="text-twitter fw-700 text-center" id="totalrequest">10
</h4>
</div>
</div>
<div class="col-xl-3 col-md-3 col-sm-12" style="display: none;">
<div class="card card-box p-4">
<h6 class="text-facebook mb-20 mt-2 text-center"><b>Pending Decision
</b></h6>
<h4 class="text-twitter fw-700 text-center" id="pendingdecision">9
</h4>
</div>
</div>
<div class="col-xl-3 col-md-3 col-sm-12">
<div class="card card-box p-4">
<h6 class="text-facebook mb-20 mt-2 text-center"><b>Approved</b>
</h6>
<h4 class="text-twitter fw-700 text-center" id="approved">1</h4>
</div>
</div>
<div class="col-xl-3 col-md-3 col-sm-12">
<div class="card card-box p-4">
<h6 class="text-facebook mb-20 mt-2 text-center"><b>Rejected</b>
</h6>
<h4 class="text-twitter fw-700 text-center" id="rejected">0</h4>
</div>
</div>
</div> </div>
<input type="hidden" id="facilityTypeId" th:value="${facilityTypeId}">
<div>
<table id="QaqcDatatable"
class="table table-striped table-bordered table-hover dataTable"
role="grid">
<thead class="thead-dark">
<tr role="row">
<th class="text-center">S.No</th>
<th class="text-center no-sort">Applicant Name</th>
<th class="text-center">RequestId</th>
<th class="text-center">Zone/Ward</th>
<th class="text-center">Event Type</th>
<th class="text-center">Event Date</th>
<th class="text-center">Total Cost</th>
<th class="text-center">Status</th>
<th class="text-center">Action</th>
</tr>
<!-- SECOND WEIGHT (TC) -->
<div class="col-md-3" id="weight2Div" style="display:none;">
<label for="weight1">Enter Weight (TC)</label><span
class="text-danger">*</span>
<input type="number" class="form-control" id="weight1">
</div>
</thead>
<tbody>
<div class="col-md-3" style="margin-top: 30px;">
<button id="submitBtn" class="btn btn-primary">Submit</button>
<button id="resetBtn" class="btn btn-secondary">Reset</button>
</tbody>
</table>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@ -206,6 +258,7 @@
</div> </div>
</div> </div>
<!-- Details Modal --> <!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" aria-hidden="true"> <div class="modal fade" id="detailsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable"> <div class="modal-dialog modal-xl modal-dialog-scrollable">
@ -242,184 +295,32 @@
<script th:replace="~{fragments/modules/base/script :: script}"></script> <script th:replace="~{fragments/modules/base/script :: script}"></script>
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function () {
const today = new Date();
const day = today.getDay(); // 0=Sun, 1=Mon, ..., 6=Sat
/* =============================
LAST SATURDAY
============================= */
const lastSaturday = new Date(today);
// If today is Saturday (6) → today
// Else → go back to previous Saturday
const diffToLastSaturday = (day >= 6)
? day - 6
: day + 1;
lastSaturday.setDate(today.getDate() - diffToLastSaturday);
/* =============================
THIS WEEK FRIDAY
============================= */
const thisFriday = new Date(today);
// Friday = 5
const diffToFriday = (5 - day + 7) % 7;
thisFriday.setDate(today.getDate() + diffToFriday);
/* =============================
FORMAT YYYY-MM-DD
============================= */
const formatDate = (d) => d.toISOString().split("T")[0];
const minDate = formatDate(lastSaturday);
const maxDate = formatDate(thisFriday);
/* =============================
APPLY LIMITS
============================= */
$("#date")
.attr("min", minDate)
.attr("max", maxDate)
.val(formatDate(today));
// 🔒 BLOCK MANUAL TYPING (BUT ALLOW CALENDAR)
$("#date").on("keydown paste", function (e) {
e.preventDefault();
});
});
$(document).ready(function () {
const isTwoWeightFacility =
$("body").data("two-weight") === true ||
$("body").data("two-weight") === "true";
console.log($("body").data("two-weight"));
let table;
if (isTwoWeightFacility) {
$("#weight2Div").show();
} else {
$("#weight2Div").hide();
$("#weight1").val("");
}
});
$(document).ready(function () {
const today = new Date().toISOString().split('T')[0];
$("#date").val(today);
});
$("#resetBtn").on("click", function () {
location.reload();
});
// Load zones when page loads
$(document).ready(function () { $(document).ready(function () {
loadTable();
$.ajax({
url: "/swm/api/dropdown/getzoneslist",
type: "GET",
dataType: "json",
success: function (data) {
let zoneDropdown = $("#zones");
zoneDropdown.empty();
zoneDropdown.append("<option value=''>Select Zone</option>");
$.each(data, function (index, item) {
zoneDropdown.append(
`<option value="${item.id}">${item.zone_name}</option>`
);
});
},
error: function (xhr, status, error) {
console.error("Error fetching zones:", error);
}
});
});
$("#submitBtn").on("click", function (e) {
e.preventDefault();
const facilityTypeId = $("#facilityTypeId").val(); // ✅ dynamic
const zoneId = $("#zones").val();
const reqDate = $("#date").val();
const weight = $("#weight").val();
const weight1 = $("#weight1").val();
const createdBy = $("#userName").val();
$("#searchBtn").on("click", loadTable);
// 🔴 Client-side validations
if (!zoneId) {
Swal.fire("Validation Error", "Please select zone", "warning");
return;
}
if (!reqDate) {
Swal.fire("Validation Error", "Date is required", "warning");
return;
}
if (!weight || weight <= 0) {
Swal.fire("Validation Error", "Weight must be greater than zero", "warning");
return;
}
// ⚠️ Note:
// Facility type 5 validation is done in BACKEND
// because facilityTypeId is derived after login
$.ajax({
url: "/swm/api/admin/addfacility",
type: "POST",
data: {
facilityTypeId: facilityTypeId,
zoneId: zoneId,
reqDate: reqDate,
weight: weight,
weight1: weight,
createdBy: createdBy // backend will ignore if not needed
},
beforeSend: function () {
Swal.fire({
title: "Saving...",
text: "Please wait",
allowOutsideClick: false,
didOpen: () => Swal.showLoading()
});
},
success: function (response) {
Swal.fire("Success", response.message, "success");
// Reset fields
$("#weight").val("");
$("#weight1").val("");
},
error: function (xhr) {
let msg = "Something went wrong";
if (xhr.responseJSON && xhr.responseJSON.message) {
msg = xhr.responseJSON.message;
}
Swal.fire("Error", msg, "error");
}
$("#resetBtn").on("click", function () {
$("#startDate").val("");
$("#endDate").val("");
$("#statusFilter").val("");
loadTable();
}); });
}); });
function loadTable() { function loadTable() {
let officer_name = $("#userName").val();
//let officer_name = $("#userName").val();
let gccUserId = $("#loginuserid").val();
let startDate = $("#startDate").val(); let startDate = $("#startDate").val();
let endDate = $("#endDate").val(); let endDate = $("#endDate").val();
let status = $("#statusFilter").val();
console.log("gccuserid", gccUserId);
if ($.fn.DataTable.isDataTable('#QaqcDatatable')) { if ($.fn.DataTable.isDataTable('#QaqcDatatable')) {
$('#QaqcDatatable').DataTable().clear().destroy(); $('#QaqcDatatable').DataTable().clear().destroy();
@ -429,15 +330,17 @@
processing: true, processing: true,
responsive: true, responsive: true,
scrollY: '50vh', scrollY: '50vh',
dom: 'Bfrtip', // 🔥 ENABLE BUTTONS
dom: 'Bfrtip',
ajax: { ajax: {
//url: "/gcc/api/flagpoleregistration/getAllDetails",
url: "/flagpoles/api/flagpoleregistration/getApprovedAndRejectedDetails",
type: "GET", type: "GET",
data: { data: {
userLogin: officer_name,
//userLogin: officer_name,
gccUserId: gccUserId,
startDate: startDate, startDate: startDate,
endDate: endDate
endDate: endDate,
status: status
}, },
dataSrc: function (json) { dataSrc: function (json) {
@ -447,11 +350,22 @@
let pending = 0, approved = 0, rejected = 0; let pending = 0, approved = 0, rejected = 0;
data.forEach(r => { data.forEach(r => {
if (!r.rdo_status) pending++;
else if (r.rdo_status === 'APPROVED') approved++;
else if (r.rdo_status === 'REJECTED') rejected++;
let status = r.history && r.history.length > 0
? r.history[r.history.length - 1].status
: null;
if (!status) pending++;
else if (status === 'APPROVED') approved++;
else if (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++;
// });
$("#totalrequest").text(data.length); $("#totalrequest").text(data.length);
$("#pendingdecision").text(pending); $("#pendingdecision").text(pending);
$("#approved").text(approved); $("#approved").text(approved);
@ -497,17 +411,52 @@
className: "text-center", className: "text-center",
render: d => d.toLocaleString("en-GB") render: d => d.toLocaleString("en-GB")
}, },
// {
// data: "rdo_status",
// className: "text-center",
// render: d => {
// if (!d)
// return `<span class="badge bg-warning text-dark">Pending</span>`;
// if (d === 'APPROVED')
// return `<span class="badge bg-success">Approved</span>`;
// return `<span class="badge bg-danger">Rejected</span>`;
// }
// },
{ {
data: "rdo_status",
data: null,
className: "text-center", className: "text-center",
render: d => {
if (!d)
render: row => {
let status = row.history && row.history.length > 0
? row.history[row.history.length - 1].status
: null;
if (!status)
return `<span class="badge bg-warning text-dark">Pending</span>`; return `<span class="badge bg-warning text-dark">Pending</span>`;
if (d === 'APPROVED')
if (status === 'APPROVED')
return `<span class="badge bg-success">Approved</span>`; return `<span class="badge bg-success">Approved</span>`;
return `<span class="badge bg-danger">Rejected</span>`; return `<span class="badge bg-danger">Rejected</span>`;
} }
}, },
// {
// data: "remarks",
// className: "text-center"
// },
// {
// data: null,
// className: "text-center",
// render: function (row) {
// if (!row.history || row.history.length === 0)
// return "-";
// // history already filtered by backend for login dept
// return row.history[0].remarks || "-";
// }
// },
{ {
data: null, data: null,
className: "text-center", className: "text-center",
@ -522,7 +471,6 @@
} }
// 🔹 View button action
// Destroy previous instance if exists // Destroy previous instance if exists
if ($.fn.DataTable.isDataTable('#QaqcDatatable')) { if ($.fn.DataTable.isDataTable('#QaqcDatatable')) {
@ -532,21 +480,44 @@
// $('#QaqcDatatable').on("click", ".viewBtn", function () {
// // 🔹 Get row data directly from DataTable
// const rowData = table.row($(this).closest('tr')).data();
// if (!rowData) {
// alert("No details found");
// return;
// }
// populateModal(rowData);
// $("#detailsModal").modal("show");
// });
$('#QaqcDatatable').on("click", ".viewBtn", function () { $('#QaqcDatatable').on("click", ".viewBtn", function () {
// 🔹 Get full row data from DataTable
const record = table.row($(this).closest('tr')).data();
let tr = $(this).closest('tr');
if (!record) {
// ✅ If responsive child row, get previous row
if (tr.hasClass('child')) {
tr = tr.prev();
}
const rowData = table.row(tr).data();
if (!rowData) {
alert("No details found"); alert("No details found");
return; return;
} }
populateModal(record);
populateModal(rowData);
$("#detailsModal").modal("show"); $("#detailsModal").modal("show");
}); });
// -----------------------------
// VIEW BUTTON → OPEN MODAL
// -----------------------------
function populateModal(record) { function populateModal(record) {
// HEADER // HEADER
@ -560,10 +531,10 @@
// 🔹 Streets // 🔹 Streets
let streetHtml = ""; let streetHtml = "";
record.streets.forEach((s, i) => {
record.streets.forEach((s, index) => {
streetHtml += ` streetHtml += `
<div class="card-section"> <div class="card-section">
<div class="section-title">Street ${i + 1}</div>
<div class="section-title">Street ${index + 1}</div>
<div class="row mb-2"> <div class="row mb-2">
<div class="col-md-4"> <div class="col-md-4">
@ -602,9 +573,11 @@
</div> </div>
</div>`; </div>`;
}); });
let historyHtml = ""; let historyHtml = "";
if (record.history && record.history.length > 0) { if (record.history && record.history.length > 0) {
@ -617,7 +590,7 @@
record.history.forEach((h, index) => { record.history.forEach((h, index) => {
historyHtml += ` historyHtml += `
<div class="row mb-2 border-bottom pb-2"> <div class="row mb-2 border-bottom pb-2">
<div class="col-md-4">
<div class="col-md-3">
<div class="label-text">Action Date</div> <div class="label-text">Action Date</div>
<div class="value-text">${h.action_date}</div> <div class="value-text">${h.action_date}</div>
</div> </div>
@ -628,23 +601,15 @@
</div> </div>
<div class="col-md-2">
<div class="col-md-3">
<div class="label-text">Status</div> <div class="label-text">Status</div>
<div class="value-text">${h.status}</div> <div class="value-text">${h.status}</div>
</div> </div>
<div class="col-md-2">
<div class="label-text">RDO Status</div>
<div class="value-text">
${record.rdo_status || "-"}
</div>
</div>
${h.remarks ? ` ${h.remarks ? `
<div class="col-md-12 mt-1">
<div class="col-md-3">
<div class="label-text">Remarks</div> <div class="label-text">Remarks</div>
<div class="value-text">${h.remarks}</div> <div class="value-text">${h.remarks}</div>
</div>` : ""} </div>` : ""}
@ -655,30 +620,8 @@
historyHtml += `</div>`; historyHtml += `</div>`;
} }
let decisionHtml = "";
// 🔹 Show decision buttons ONLY if pending
if (!record.rdo_status) {
decisionHtml = `
<div class="rdo-box">
<div class="section-title">Department Decision</div>
<textarea id="rdoRemarks" class="form-control mb-3"
rows="4" placeholder="Enter remarks..."></textarea>
<div class="d-flex justify-content-between">
<button class="btn btn-success btn-big"
onclick="submitRdoDecision('APPROVED')">Approve</button>
<button class="btn btn-danger btn-big"
onclick="submitRdoDecision('REJECTED')">Reject</button>
</div>
</div>`;
}
let html = ` let html = `
<!-- APPLICANT INFO -->
<div class="card-section"> <div class="card-section">
<div class="section-title">Applicant Information</div> <div class="section-title">Applicant Information</div>
@ -724,9 +667,7 @@
<div class="label-text">Event Description</div> <div class="label-text">Event Description</div>
<div class="value-text">${record.event_desc}</div> <div class="value-text">${record.event_desc}</div>
</div> </div>
</div> </div>
<div class="row mb-2"> <div class="row mb-2">
<div class="col-md-6"> <div class="col-md-6">
<div class="label-text">Applied Date</div> <div class="label-text">Applied Date</div>
@ -735,16 +676,10 @@
</div> </div>
</div> </div>
${streetHtml} ${streetHtml}
${historyHtml} ${historyHtml}
${decisionHtml}
`; `;
$("#modalContent").html(html); $("#modalContent").html(html);
} }
@ -753,7 +688,6 @@
</script> </script>
</body> </body>

930
src/main/resources/templates/modules/flagpole/requestlist.html

@ -0,0 +1,930 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>
.width1 {
width: 120px;
}
.width2 {
width: 150px;
}
.modal-label {
font-weight: 600;
color: #333;
}
.modal-value {
color: #444;
}
.modal-section-title {
font-size: 1.2rem;
font-weight: bold;
margin-top: 20px;
margin-bottom: 10px;
border-bottom: 2px solid #dee2e6;
padding-bottom: 5px;
}
.modal-title-big {
font-size: 20px;
font-weight: 700;
}
.modal-subtext {
color: #b4c5d3;
font-size: 13px;
}
.card-section {
background: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 25px;
border: 1px solid #eee;
}
.section-title {
font-weight: 700;
color: #333;
margin-bottom: 15px;
font-size: 16px;
}
.label-text {
font-size: 13px;
color: #6c757d;
}
.value-text {
font-size: 15px;
font-weight: 600;
color: #333;
}
.info-block {
display: flex;
flex-direction: column;
}
.badge-status {
background: #ffd9b3;
color: #a65c00;
padding: 6px 10px;
border-radius: 5px;
font-size: 13px;
}
.btn-big {
padding: 12px 25px;
border-radius: 8px;
width: 200px;
}
.rdo-box {
border: 1px solid #eee;
border-radius: 10px;
padding: 20px;
}
</style>
<body>
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header">
<div class="row align-items-end">
<div class="col-lg-6">
<div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline">
<h5>Request List</h5>
<span>Flag Pole Request List</span>
</div>
</div>
</div>
<div class="col-lg-6">
<nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/flagpoles/index"><i class="ik ik-home"></i></a>
</li>
<li class="breadcrumb-item" aria-current="page">Flag Pole Request List</li>
<li class="breadcrumb-item active" aria-current="page">Request List</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center fw-bold">
<h3 class="mb-0">Temporary Flag Poles - Request List : <span
th:text="${officer_name}"></span></h3>
<input type="hidden" id="userName" th:value="${officer_name}">
<input type="hidden" id="loginuserid" th:value="${LoginUserId}">
</div>
<div class="row mt-3 ml-2">
<div class="col-md-3">
<label for="startDate" class="form-label" style="font-size: medium;">From
Date:</label>
<input type="date" id="startDate" class="form-control" placeholder="Start Date">
</div>
<div class="col-md-3">
<label for="endDate" class="form-label" style="font-size: medium;">To
Date:</label>
<input type="date" id="endDate" class="form-control" placeholder="End Date">
</div>
<div class="col-md-3" style="margin-top: 30px;">
<button id="searchBtn" class="btn btn-primary">Search</button>
<button id="resetBtn" class="btn btn-secondary">Reset</button>
</div>
</div>
<div class="card-body">
<div>
<div class="row mt-2">
<div class="col-xl-3 col-md-3 col-sm-12">
<div class="card card-box p-4">
<h6 class="text-facebook mb-20 mt-2 text-center fw-bold"><b>Total
Request</b>
</h6>
<h4 class="text-twitter fw-700 text-center" id="totalrequest">
</h4>
</div>
</div>
<div class="col-xl-3 col-md-3 col-sm-12">
<div class="card card-box p-4">
<h6 class="text-facebook mb-20 mt-2 text-center"><b>Pending Decision
</b></h6>
<h4 class="text-twitter fw-700 text-center" id="pendingdecision">
</h4>
</div>
</div>
<div class="col-xl-3 col-md-3 col-sm-12" style="display: none;">
<div class="card card-box p-4">
<h6 class="text-facebook mb-20 mt-2 text-center"><b>Approved</b>
</h6>
<h4 class="text-twitter fw-700 text-center" id="approved"></h4>
</div>
</div>
<div class="col-xl-3 col-md-3 col-sm-12" style="display: none;">
<div class="card card-box p-4">
<h6 class="text-facebook mb-20 mt-2 text-center"><b>Rejected</b>
</h6>
<h4 class="text-twitter fw-700 text-center" id="rejected"></h4>
</div>
</div>
</div>
<div>
<table id="QaqcDatatable"
class="table table-striped table-bordered table-hover dataTable"
role="grid">
<thead class="thead-dark">
<tr role="row">
<th class="text-center">S.No</th>
<th class="text-center no-sort">Applicant Name</th>
<th class="text-center">RequestId</th>
<th class="text-center">Zone/Ward</th>
<th class="text-center">Event Type</th>
<th class="text-center">Event Date</th>
<th class="text-center">Total Cost</th>
<th class="text-center">Status</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" style="background:#2f3e54; color:white;">
<div>
<h4 class="modal-title-big" id="modalTitle"></h4>
<div id="modalSubTitle" class="modal-subtext"></div>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div id="modalContent"></div>
<div class="text-center mt-4">
<button type="button" class="btn btn-primary btn-big" data-dismiss="modal"
style="background:#2f3e54;">Close</button>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="imagePreviewModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Document Preview</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body text-center">
<img id="previewImage" class="img-fluid">
</div>
</div>
</div>
</div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script type="text/javascript">
let table;
$(document).ready(function () {
loadTable();
$("#searchBtn").on("click", loadTable);
$("#resetBtn").on("click", function () {
$("#startDate").val("");
$("#endDate").val("");
loadTable();
});
});
$(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 `<span class="badge bg-warning text-dark">Pending</span>`;
// if (d === 'APPROVED')
// return `<span class="badge bg-success">Approved</span>`;
// return `<span class="badge bg-danger">Rejected</span>`;
// }
// },
// {
// data: null,
// className: "text-center",
// render: row =>
// `<button class="btn btn-primary btn-sm viewBtn"
// data-refid="${row.refid}">
// View
// </button>`
// }
// ]
// });
// }
function loadTable() {
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();
}
table = $('#QaqcDatatable').DataTable({
processing: true,
responsive: true,
scrollY: '50vh',
dom: 'Bfrtip',
ajax: {
url: "/flagpoles/api/flagpoleregistration/getAllDetails",
type: "GET",
data: {
gccUserId: gccUserId,
startDate: startDate,
endDate: endDate
},
dataSrc: function (json) {
const data = json.data || [];
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 => {
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;
}
},
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: r =>
r.streets?.length
? `${r.streets[0].zone} / ${r.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 =>
// !d
// ? `<span class="badge bg-warning text-dark">Pending</span>`
// : d === 'APPROVED'
// ? `<span class="badge bg-success">Approved</span>`
// : `<span class="badge bg-danger">Rejected</span>`
// },
{
data: null,
className: "text-center",
render: r => {
const status = r.final_status;
if (!status)
return `<span class="badge bg-warning text-dark">Pending</span>`;
else if (status === 'APPROVED')
return `<span class="badge bg-success">Approved</span>`;
else
return `<span class="badge bg-danger">Rejected</span>`;
}
},
{
data: null,
className: "text-center",
render: r =>
`<button class="btn btn-primary btn-sm viewBtn"
data-refid="${r.refid}">
View
</button>`
}
]
});
}
// 🔹 View button action
// Destroy previous instance if exists
if ($.fn.DataTable.isDataTable('#QaqcDatatable')) {
$('#QaqcDatatable').DataTable().clear().destroy();
}
// $('#QaqcDatatable').on("click", ".viewBtn", function () {
// // 🔹 Get full row data from DataTable
// const record = table.row($(this).closest('tr')).data();
// if (!record) {
// alert("No details found");
// return;
// }
// populateModal(record);
// $("#detailsModal").modal("show");
// });
$('#QaqcDatatable').on("click", ".viewBtn", function () {
let tr = $(this).closest('tr');
// ✅ Handle responsive child rows (mobile view)
if (tr.hasClass('child')) {
tr = tr.prev();
}
// 🔹 Get full row data from DataTable
const record = table.row(tr).data();
if (!record) {
alert("No details found");
return;
}
populateModal(record);
$("#detailsModal").modal("show");
});
function populateModal(record) {
// HEADER
$("#modalTitle").html(`Application Details - ${record.applicant_name}`);
$("#modalSubTitle").html(
`Ref ID: ${record.refid} - ${record.streets.length} Streets`
);
$("#detailsModal").data("refid", record.refid);
// 🔹 Streets
let streetHtml = "";
record.streets.forEach((s, i) => {
streetHtml += `
<div class="card-section">
<div class="section-title">Street ${i + 1}</div>
<div class="row mb-2">
<div class="col-md-4">
<div class="label-text">Street Name</div>
<div class="value-text">${s.street_name}</div>
</div>
<div class="col-md-4">
<div class="label-text">Zone</div>
<div class="value-text">${s.zone}</div>
</div>
<div class="col-md-4">
<div class="label-text">Ward</div>
<div class="value-text">${s.ward}</div>
</div>
<div class="col-md-4">
<div class="label-text">No. of Poles</div>
<div class="value-text">${s.no_of_poles}</div>
</div>
<div class="col-md-4">
<div class="label-text">Height</div>
<div class="value-text">${s.height}</div>
</div>
<div class="col-md-4">
<div class="label-text">Flag Material</div>
<div class="value-text">${s.flag_material}</div>
</div>
<div class="col-md-4">
<div class="label-text">Pole Material</div>
<div class="value-text">${s.pole_material}</div>
</div>
</div>
</div>`;
});
let historyHtml = "";
if (record.history && record.history.length > 0) {
historyHtml += `
<div class="card-section">
<div class="section-title">Application History</div>
`;
record.history.forEach((h, index) => {
historyHtml += `
<div class="row mb-2 border-bottom pb-2">
<div class="col-md-3">
<div class="label-text">Action Date</div>
<div class="value-text">${h.action_date}</div>
</div>
<div class="col-md-3">
<div class="label-text">Department</div>
<div class="value-text">${h.department_name}</div>
</div>
<div class="col-md-3">
<div class="label-text">Status</div>
<div class="value-text">${h.status}</div>
</div>
${h.remarks ? `
<div class="col-md-3">
<div class="label-text">Remarks</div>
<div class="value-text">${h.remarks}</div>
</div>` : ""}
</div>
`;
});
historyHtml += `</div>`;
}
let decisionHtml = "";
// 🔹 Show decision buttons ONLY if pending
if (!record.final_status) {
decisionHtml = `
<div class="rdo-box">
<div class="section-title">Department Decision</div>
<textarea id="rdoRemarks" class="form-control mb-3"
rows="4" placeholder="Enter remarks..."></textarea>
<div class="d-flex justify-content-between">
<button class="btn btn-success btn-big"
onclick="submitOfficerDecision('APPROVED')">Approve</button>
<button class="btn btn-danger btn-big"
onclick="submitOfficerDecision('REJECTED')">Reject</button>
</div>
</div>`;
}
let html = `
<div class="card-section">
<div class="section-title">Applicant Information</div>
<div class="row mb-2">
<div class="col-md-6">
<div class="label-text">Applicant Name</div>
<div class="value-text">${record.applicant_name}</div>
</div>
<div class="col-md-6">
<div class="label-text">Mobile Number</div>
<div class="value-text">${record.mobile_number}</div>
</div>
</div>
<div class="row mb-2">
<div class="col-md-6">
<div class="label-text">Event Type</div>
<div class="value-text">${record.event_name}</div>
</div>
<div class="col-md-6">
<div class="label-text">Event Date</div>
<div class="value-text">
${new Date(record.event_date).toLocaleDateString("en-GB")}
</div>
</div>
<div class="col-md-6">
<div class="label-text">Address</div>
<div class="value-text">
${record.applicant_address}
</div>
</div>
<div class="col-md-6">
<div class="label-text">Total Cost</div>
<div class="value-text">
${record.total_cost.toLocaleString("en-GB")}
</div>
</div>
<div class="col-md-6">
<div class="label-text">No. of Days</div>
<div class="value-text">${record.no_of_days}</div>
</div>
<div class="col-md-6">
<div class="label-text">Event Description</div>
<div class="value-text">${record.event_desc}</div>
</div>
</div>
<div class="row mb-2">
<div class="col-md-6">
<div class="label-text">Applied Date</div>
<div class="value-text">${record.cdate}</div>
</div>
</div>
</div>
${streetHtml}
${historyHtml}
${decisionHtml}
`;
$("#modalContent").html(html);
}
// 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 gccUserId = $("#loginuserid").val(); // login user id
let username = $("#userName").val(); // display username
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: "/flagpoles/api/flagpoleregistration/officer/updateDecision",
type: "POST",
data: {
refid: refid,
status: status,
remarks: remarks,
gccUserId: gccUserId,
username: username // ✅ NEW
},
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'
});
}
});
});
}
</script>
</body>
</html>

754
src/main/resources/templates/modules/swm/biogas.html

@ -1,754 +0,0 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>
.width1 {
width: 120px;
}
.width2 {
width: 150px;
}
.modal-label {
font-weight: 600;
color: #333;
}
.modal-value {
color: #444;
}
.modal-section-title {
font-size: 1.2rem;
font-weight: bold;
margin-top: 20px;
margin-bottom: 10px;
border-bottom: 2px solid #dee2e6;
padding-bottom: 5px;
}
.modal-title-big {
font-size: 20px;
font-weight: 700;
}
.modal-subtext {
color: #b4c5d3;
font-size: 13px;
}
.card-section {
background: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 25px;
border: 1px solid #eee;
}
.section-title {
font-weight: 700;
color: #333;
margin-bottom: 15px;
font-size: 16px;
}
.label-text {
font-size: 13px;
color: #6c757d;
}
.value-text {
font-size: 15px;
font-weight: 600;
color: #333;
}
.info-block {
display: flex;
flex-direction: column;
}
.badge-status {
background: #ffd9b3;
color: #a65c00;
padding: 6px 10px;
border-radius: 5px;
font-size: 13px;
}
.btn-big {
padding: 12px 25px;
border-radius: 8px;
width: 200px;
}
.rdo-box {
border: 1px solid #eee;
border-radius: 10px;
padding: 20px;
}
</style>
<body th:attr="data-two-weight=${isTwoWeightFacility}">
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header">
<div class="row align-items-end">
<div class="col-lg-6">
<div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline">
<h5>SWD Biogas Facilities Add Details List</h5>
<span>Biogas Add Details</span>
</div>
</div>
</div>
<div class="col-lg-6">
<nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/swm/index"><i class="ik ik-home"></i></a>
</li>
<li class="breadcrumb-item" aria-current="page">SWD Biogas Facilities Add
Details List
</li>
<li class="breadcrumb-item active" aria-current="page">Biogas Add Details</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center fw-bold">
<h3 class="mb-0"> SWM Biogas Add Details : <span th:text="${officer_name}"></span>
</h3>
<input type="hidden" id="userName" th:value="${officer_name}">
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3">
<label for="date" class="form-label"
style="font-size: medium;">Date:</label><span
class="text-danger">*</span>
<input type="date" id="date" class="form-control">
</div>
<div class="col-md-3">
<label for="zones" class="form-label">Zones <span
class="text-danger">*</span>
</label> <select id="zones" class="form-control">
<option value="">Select zones</option>
</select>
</div>
<div class="col-md-3">
<label for="weight" class="form-label">Enter Weight:(in MT)</label><span
class="text-danger">*</span>
<input type="number" class="form-control" id="weight">
</div>
<input type="hidden" id="facilityTypeId" th:value="${facilityTypeId}">
<!-- SECOND WEIGHT (TC) -->
<div class="col-md-3" id="weight2Div" style="display:none;">
<label for="weight1">Enter Weight:</label><span class="text-danger">*</span>
<input type="number" class="form-control" id="weight1">
</div>
<div class="col-md-3" style="margin-top: 30px;">
<button id="submitBtn" class="btn btn-primary">Submit</button>
<button id="resetBtn" class="btn btn-secondary">Reset</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" style="background:#2f3e54; color:white;">
<div>
<h4 class="modal-title-big" id="modalTitle"></h4>
<div id="modalSubTitle" class="modal-subtext"></div>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div id="modalContent"></div>
<div class="text-center mt-4">
<button type="button" class="btn btn-primary btn-big" data-dismiss="modal"
style="background:#2f3e54;">Close</button>
</div>
</div>
</div>
</div>
</div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script type="text/javascript">
$(document).ready(function () {
const today = new Date();
const day = today.getDay(); // 0=Sun, 1=Mon, ..., 6=Sat
/* =============================
LAST SATURDAY
============================= */
const lastSaturday = new Date(today);
// If today is Saturday (6) → today
// Else → go back to previous Saturday
const diffToLastSaturday = (day >= 6)
? day - 6
: day + 1;
lastSaturday.setDate(today.getDate() - diffToLastSaturday);
/* =============================
THIS WEEK FRIDAY
============================= */
const thisFriday = new Date(today);
// Friday = 5
const diffToFriday = (5 - day + 7) % 7;
thisFriday.setDate(today.getDate() + diffToFriday);
/* =============================
FORMAT YYYY-MM-DD
============================= */
const formatDate = (d) => d.toISOString().split("T")[0];
const minDate = formatDate(lastSaturday);
const maxDate = formatDate(thisFriday);
/* =============================
APPLY LIMITS
============================= */
$("#date")
.attr("min", minDate)
.attr("max", maxDate)
.val(formatDate(today));
// 🔒 BLOCK MANUAL TYPING (BUT ALLOW CALENDAR)
$("#date").on("keydown paste", function (e) {
e.preventDefault();
});
});
$(document).ready(function () {
const isTwoWeightFacility =
$("body").data("two-weight") === true ||
$("body").data("two-weight") === "true";
console.log($("body").data("two-weight"));
if (isTwoWeightFacility) {
$("#weight2Div").show();
} else {
$("#weight2Div").hide();
$("#weight1").val("");
}
});
$(document).ready(function () {
const today = new Date().toISOString().split('T')[0];
$("#date").val(today);
});
$("#resetBtn").on("click", function () {
location.reload();
});
// Load zones when page loads
$(document).ready(function () {
$.ajax({
url: "/swm/api/dropdown/getzoneslist",
type: "GET",
dataType: "json",
success: function (data) {
let zoneDropdown = $("#zones");
zoneDropdown.empty();
zoneDropdown.append("<option value=''>Select Zone</option>");
$.each(data, function (index, item) {
zoneDropdown.append(
`<option value="${item.id}">${item.zone_name}</option>`
);
});
},
error: function (xhr, status, error) {
console.error("Error fetching zones:", error);
}
});
});
$("#submitBtn").on("click", function (e) {
e.preventDefault();
const facilityTypeId = $("#facilityTypeId").val(); // ✅ dynamic
const zoneId = $("#zones").val();
const reqDate = $("#date").val();
const weight = $("#weight").val();
const weight1 = $("#weight1").val();
const createdBy = $("#userName").val();
// 🔴 Client-side validations
if (!zoneId) {
Swal.fire("Validation Error", "Please select zone", "warning");
return;
}
if (!reqDate) {
Swal.fire("Validation Error", "Date is required", "warning");
return;
}
if (!weight || weight <= 0) {
Swal.fire("Validation Error", "Weight must be greater than zero", "warning");
return;
}
// ⚠️ Note:
// Facility type 5 validation is done in BACKEND
// because facilityTypeId is derived after login
$.ajax({
url: "/swm/api/admin/addfacility",
type: "POST",
data: {
facilityTypeId: facilityTypeId,
zoneId: zoneId,
reqDate: reqDate,
weight: weight,
weight1: weight1, // backend will ignore if not needed
createdBy: createdBy
},
beforeSend: function () {
Swal.fire({
title: "Saving...",
text: "Please wait",
allowOutsideClick: false,
didOpen: () => Swal.showLoading()
});
},
success: function (response) {
Swal.fire("Success", response.message, "success");
// Reset fields
$("#weight").val("");
$("#weight1").val("");
},
error: function (xhr) {
let msg = "Something went wrong";
if (xhr.responseJSON && xhr.responseJSON.message) {
msg = xhr.responseJSON.message;
}
Swal.fire("Error", msg, "error");
}
});
});
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 `<span class="badge bg-warning text-dark">Pending</span>`;
if (d === 'APPROVED')
return `<span class="badge bg-success">Approved</span>`;
return `<span class="badge bg-danger">Rejected</span>`;
}
},
{
data: null,
className: "text-center",
render: row =>
`<button class="btn btn-primary btn-sm viewBtn"
data-refid="${row.refid}">
View
</button>`
}
]
});
}
// 🔹 View button action
// Destroy previous instance if exists
if ($.fn.DataTable.isDataTable('#QaqcDatatable')) {
$('#QaqcDatatable').DataTable().clear().destroy();
}
$('#QaqcDatatable').on("click", ".viewBtn", function () {
// 🔹 Get full row data from DataTable
const record = table.row($(this).closest('tr')).data();
if (!record) {
alert("No details found");
return;
}
populateModal(record);
$("#detailsModal").modal("show");
});
function populateModal(record) {
// HEADER
$("#modalTitle").html(`Application Details - ${record.applicant_name}`);
$("#modalSubTitle").html(
`Ref ID: ${record.refid} - ${record.streets.length} Streets`
);
$("#detailsModal").data("refid", record.refid);
// 🔹 Streets
let streetHtml = "";
record.streets.forEach((s, i) => {
streetHtml += `
<div class="card-section">
<div class="section-title">Street ${i + 1}</div>
<div class="row mb-2">
<div class="col-md-4">
<div class="label-text">Street Name</div>
<div class="value-text">${s.street_name}</div>
</div>
<div class="col-md-4">
<div class="label-text">Zone</div>
<div class="value-text">${s.zone}</div>
</div>
<div class="col-md-4">
<div class="label-text">Ward</div>
<div class="value-text">${s.ward}</div>
</div>
<div class="col-md-4">
<div class="label-text">No. of Poles</div>
<div class="value-text">${s.no_of_poles}</div>
</div>
<div class="col-md-4">
<div class="label-text">Height</div>
<div class="value-text">${s.height}</div>
</div>
<div class="col-md-4">
<div class="label-text">Flag Material</div>
<div class="value-text">${s.flag_material}</div>
</div>
<div class="col-md-4">
<div class="label-text">Pole Material</div>
<div class="value-text">${s.pole_material}</div>
</div>
</div>
</div>`;
});
let historyHtml = "";
if (record.history && record.history.length > 0) {
historyHtml += `
<div class="card-section">
<div class="section-title">Application History</div>
`;
record.history.forEach((h, index) => {
historyHtml += `
<div class="row mb-2 border-bottom pb-2">
<div class="col-md-4">
<div class="label-text">Action Date</div>
<div class="value-text">${h.action_date}</div>
</div>
<div class="col-md-3">
<div class="label-text">Department</div>
<div class="value-text">${h.department_name}</div>
</div>
<div class="col-md-2">
<div class="label-text">Status</div>
<div class="value-text">${h.status}</div>
</div>
<div class="col-md-2">
<div class="label-text">RDO Status</div>
<div class="value-text">
${record.rdo_status || "-"}
</div>
</div>
${h.remarks ? `
<div class="col-md-12 mt-1">
<div class="label-text">Remarks</div>
<div class="value-text">${h.remarks}</div>
</div>` : ""}
</div>
`;
});
historyHtml += `</div>`;
}
let decisionHtml = "";
// 🔹 Show decision buttons ONLY if pending
if (!record.rdo_status) {
decisionHtml = `
<div class="rdo-box">
<div class="section-title">Department Decision</div>
<textarea id="rdoRemarks" class="form-control mb-3"
rows="4" placeholder="Enter remarks..."></textarea>
<div class="d-flex justify-content-between">
<button class="btn btn-success btn-big"
onclick="submitRdoDecision('APPROVED')">Approve</button>
<button class="btn btn-danger btn-big"
onclick="submitRdoDecision('REJECTED')">Reject</button>
</div>
</div>`;
}
let html = `
<div class="card-section">
<div class="section-title">Applicant Information</div>
<div class="row mb-2">
<div class="col-md-6">
<div class="label-text">Applicant Name</div>
<div class="value-text">${record.applicant_name}</div>
</div>
<div class="col-md-6">
<div class="label-text">Mobile Number</div>
<div class="value-text">${record.mobile_number}</div>
</div>
</div>
<div class="row mb-2">
<div class="col-md-6">
<div class="label-text">Event Type</div>
<div class="value-text">${record.event_name}</div>
</div>
<div class="col-md-6">
<div class="label-text">Event Date</div>
<div class="value-text">
${new Date(record.event_date).toLocaleDateString("en-GB")}
</div>
</div>
<div class="col-md-6">
<div class="label-text">Address</div>
<div class="value-text">
${record.applicant_address}
</div>
</div>
<div class="col-md-6">
<div class="label-text">Total Cost</div>
<div class="value-text">
${record.total_cost.toLocaleString("en-GB")}
</div>
</div>
<div class="col-md-6">
<div class="label-text">No. of Days</div>
<div class="value-text">${record.no_of_days}</div>
</div>
<div class="col-md-6">
<div class="label-text">Event Description</div>
<div class="value-text">${record.event_desc}</div>
</div>
</div>
<div class="row mb-2">
<div class="col-md-6">
<div class="label-text">Applied Date</div>
<div class="value-text">${record.cdate}</div>
</div>
</div>
</div>
${streetHtml}
${historyHtml}
${decisionHtml}
`;
$("#modalContent").html(html);
}
</script>
</body>
</html>

416
src/main/resources/templates/modules/swm/cdwaste.html

@ -1,416 +0,0 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>
.width1 {
width: 120px;
}
.width2 {
width: 150px;
}
.modal-label {
font-weight: 600;
color: #333;
}
.modal-value {
color: #444;
}
.modal-section-title {
font-size: 1.2rem;
font-weight: bold;
margin-top: 20px;
margin-bottom: 10px;
border-bottom: 2px solid #dee2e6;
padding-bottom: 5px;
}
.modal-title-big {
font-size: 20px;
font-weight: 700;
}
.modal-subtext {
color: #b4c5d3;
font-size: 13px;
}
.card-section {
background: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 25px;
border: 1px solid #eee;
}
.section-title {
font-weight: 700;
color: #333;
margin-bottom: 15px;
font-size: 16px;
}
.label-text {
font-size: 13px;
color: #6c757d;
}
.value-text {
font-size: 15px;
font-weight: 600;
color: #333;
}
.info-block {
display: flex;
flex-direction: column;
}
.badge-status {
background: #ffd9b3;
color: #a65c00;
padding: 6px 10px;
border-radius: 5px;
font-size: 13px;
}
.btn-big {
padding: 12px 25px;
border-radius: 8px;
width: 200px;
}
.rdo-box {
border: 1px solid #eee;
border-radius: 10px;
padding: 20px;
}
</style>
<body th:attr="data-two-weight=${isTwoWeightFacility}">
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header">
<div class="row align-items-end">
<div class="col-lg-6">
<div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline">
<h5>SWD CDWaste Facilities Add Details List</h5>
<span> CDWaste Add Details</span>
</div>
</div>
</div>
<div class="col-lg-6">
<nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/swm/index"><i class="ik ik-home"></i></a>
</li>
<li class="breadcrumb-item" aria-current="page">SWD CDWaste Facilities Add
Details List
</li>
<li class="breadcrumb-item active" aria-current="page">CDWaste Add Details</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center fw-bold">
<h3 class="mb-0"> SWD CDWaste Add Details : <span th:text="${officer_name}"></span>
</h3>
<input type="hidden" id="userName" th:value="${officer_name}">
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3">
<label for="date" class="form-label"
style="font-size: medium;">Date:</label><span class="text-danger">*</span>
<input type="date" id="date" class="form-control">
</div>
<div class="col-md-3">
<label for="zones" class="form-label">Zones <span
class="text-danger">*</span>
</label> <select id="zones" class="form-control">
<option value="">Select days</option>
</select>
</div>
<div class="col-md-3">
<label for="weight" class="form-label">Enter Weight:(in MT)</label><span class="text-danger">*</span>
<input type="number" class="form-control" id="weight">
</div>
<input type="hidden" id="facilityTypeId" th:value="${facilityTypeId}">
<!-- SECOND WEIGHT (TC) -->
<div class="col-md-3" id="weight2Div" style="display:none;">
<label for="weight1">Enter Weight (TC)</label><span
class="text-danger">*</span>
<input type="number" class="form-control" id="weight1">
</div>
<div class="col-md-3" id="weightTypeDiv">
<label class="form-label">Location<span class="text-danger">*</span></label>
<select id="facilitytype" class="form-control">
<option value="">Select</option>
<option value="KDG">KDG</option>
<option value="PDG">PDG</option>
</select>
</div>
<div class="col-md-3" style="margin-top: 30px;">
<button id="submitBtn" class="btn btn-primary">Submit</button>
<button id="resetBtn" class="btn btn-secondary">Reset</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" style="background:#2f3e54; color:white;">
<div>
<h4 class="modal-title-big" id="modalTitle"></h4>
<div id="modalSubTitle" class="modal-subtext"></div>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div id="modalContent"></div>
<div class="text-center mt-4">
<button type="button" class="btn btn-primary btn-big" data-dismiss="modal"
style="background:#2f3e54;">Close</button>
</div>
</div>
</div>
</div>
</div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script type="text/javascript">
$(document).ready(function () {
const today = new Date();
const day = today.getDay(); // 0=Sun, 1=Mon, ..., 6=Sat
/* =============================
LAST SATURDAY
============================= */
const lastSaturday = new Date(today);
const diffToLastSaturday = (day >= 6) ? day - 6 : day + 1;
lastSaturday.setDate(today.getDate() - diffToLastSaturday);
/* =============================
THIS WEEK FRIDAY
============================= */
const thisFriday = new Date(today);
const diffToFriday = (5 - day + 7) % 7;
thisFriday.setDate(today.getDate() + diffToFriday);
/* =============================
FORMAT YYYY-MM-DD
============================= */
const formatDate = d => d.toISOString().split("T")[0];
$("#date")
.attr("min", formatDate(lastSaturday))
.attr("max", formatDate(thisFriday))
.val(formatDate(today))
// 🔒 BLOCK MANUAL TYPING (BUT ALLOW CALENDAR)
$("#date").on("keydown paste", function (e) {
e.preventDefault();
});
});
$(document).ready(function () {
const isTwoWeightFacility =
$("body").data("two-weight") === true ||
$("body").data("two-weight") === "true";
console.log($("body").data("two-weight"));
if (isTwoWeightFacility) {
$("#weight2Div").show();
} else {
$("#weight2Div").hide();
$("#weight1").val("");
}
});
$(document).ready(function () {
const today = new Date().toISOString().split('T')[0];
$("#date").val(today);
});
$("#resetBtn").on("click", function () {
location.reload();
});
// Load zones when page loads
$(document).ready(function () {
$.ajax({
url: "/swm/api/dropdown/getzoneslist",
type: "GET",
dataType: "json",
success: function (data) {
let zoneDropdown = $("#zones");
zoneDropdown.empty();
zoneDropdown.append("<option value=''>Select Zone</option>");
$.each(data, function (index, item) {
zoneDropdown.append(
`<option value="${item.id}">${item.zone_name}</option>`
);
});
},
error: function (xhr, status, error) {
console.error("Error fetching zones:", error);
}
});
});
$("#submitBtn").on("click", function (e) {
e.preventDefault();
const facilityTypeId = $("#facilityTypeId").val(); // ✅ dynamic
const zoneId = $("#zones").val();
const reqDate = $("#date").val();
const weight = $("#weight").val();
const weight1 = $("#weight1").val();
const weightType = $("#facilitytype").val();
const createdBy = $("#userName").val();
// 🔴 Client-side validations
if (!zoneId) {
Swal.fire("Validation Error", "Please select zone", "warning");
return;
}
if (!reqDate) {
Swal.fire("Validation Error", "Date is required", "warning");
return;
}
if (!weight || weight <= 0) {
Swal.fire("Validation Error", "Weight must be greater than zero", "warning");
return;
}
// ⚠️ Note:
// Facility type 5 validation is done in BACKEND
// because facilityTypeId is derived after login
$.ajax({
url: "/swm/api/admin/addfacility",
type: "POST",
data: {
facilityTypeId: facilityTypeId,
zoneId: zoneId,
reqDate: reqDate,
weight: weight,
weight1: weight1,
weightType: weightType,
createdBy: createdBy // backend will ignore if not needed
},
beforeSend: function () {
Swal.fire({
title: "Saving...",
text: "Please wait",
allowOutsideClick: false,
didOpen: () => Swal.showLoading()
});
},
success: function (response) {
Swal.fire("Success", response.message, "success");
// Reset fields
$("#weight").val("");
$("#weight1").val("");
},
error: function (xhr) {
let msg = "Something went wrong";
if (xhr.responseJSON && xhr.responseJSON.message) {
msg = xhr.responseJSON.message;
}
Swal.fire("Error", msg, "error");
}
});
});
</script>
</body>
</html>

764
src/main/resources/templates/modules/swm/eachreport.html

@ -1,764 +0,0 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>
.width1 {
width: 120px;
}
.width2 {
width: 150px;
}
.modal-label {
font-weight: 600;
color: #333;
}
.modal-value {
color: #444;
}
.modal-section-title {
font-size: 1.2rem;
font-weight: bold;
margin-top: 20px;
margin-bottom: 10px;
border-bottom: 2px solid #dee2e6;
padding-bottom: 5px;
}
.modal-title-big {
font-size: 20px;
font-weight: 700;
}
.modal-subtext {
color: #b4c5d3;
font-size: 13px;
}
.card-section {
background: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 25px;
border: 1px solid #eee;
}
.section-title {
font-weight: 700;
color: #333;
margin-bottom: 15px;
font-size: 16px;
}
.label-text {
font-size: 13px;
color: #6c757d;
}
.value-text {
font-size: 15px;
font-weight: 600;
color: #333;
}
.info-block {
display: flex;
flex-direction: column;
}
.badge-status {
background: #ffd9b3;
color: #a65c00;
padding: 6px 10px;
border-radius: 5px;
font-size: 13px;
}
.btn-big {
padding: 12px 25px;
border-radius: 8px;
width: 200px;
}
.rdo-box {
border: 1px solid #eee;
border-radius: 10px;
padding: 20px;
}
</style>
<body>
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header">
<div class="row align-items-end">
<div class="col-lg-6">
<div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline">
<h5>SWD Facilities Reports</h5>
<span>Reports</span>
</div>
</div>
</div>
<div class="col-lg-6">
<nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/swm/index"><i class="ik ik-home"></i></a>
</li>
<li class="breadcrumb-item" aria-current="page">SWD Facilities Reports</li>
<li class="breadcrumb-item active" aria-current="page">Reports</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card shadow-sm">
<!-- CARD HEADER -->
<div class="card-header d-flex justify-content-between align-items-center fw-bold">
<h3 class="mb-0"> SWD Facilities Reports : <span th:text="${officer_name}"></span>
</h3>
<input type="hidden" id="userName" th:value="${officer_name}">
</div>
<!-- FILTER SECTION -->
<div class="card-body pb-0">
<div class="row align-items-end g-3 mb-3">
<div class="col-md-3">
<label class="form-label">From Date</label><span
class="text-danger">*</span>
<input type="date" id="fromDate" class="form-control">
</div>
<div class="col-md-3">
<label class="form-label">To Date</label><span class="text-danger">*</span>
<input type="date" id="toDate" class="form-control">
</div>
<div class="col-md-3">
<button id="searchBtn" class="btn btn-primary w-100">
Search
</button>
</div>
</div>
</div>
<!-- TABLE SECTION -->
<div class="card-body pt-0">
<div class="table-responsive">
<!-- Logged-in username -->
<input type="hidden" id="userName" th:value="${officer_name}">
<table id="QaqcDatatable"
class="table table-striped table-bordered table-hover dataTable"
width="100%">
<thead class="thead-dark">
<!-- MAIN GROUP HEADERS -->
<tr class="text-center">
<th rowspan="2">S.No</th>
<th rowspan="2">Zone</th>
<th colspan="3" class="grp-mcc">MCC</th>
<th colspan="3" class="grp-windrow">Windrow</th>
<th colspan="3" class="grp-biocng">Bio-CNG</th>
<th colspan="3" class="grp-biogas">Bio-GAS</th>
<th colspan="3" class="grp-incinerator">Incinerator</th>
<th colspan="3" class="grp-baling">Plasting Baling Centre</th>
<th colspan="3" class="grp-gwtc">GW &amp; TC Waste</th>
<th colspan="3" class="grp-cd">C&amp;D Waste Processing Centre</th>
</tr>
<!-- SUB HEADERS -->
<tr class="text-center">
<th class="mcc">Target</th>
<th class="mcc">Achieved</th>
<th class="mcc">%</th>
<th class="windrow">Target</th>
<th class="windrow">Achieved</th>
<th class="windrow">%</th>
<th class="biocng">Target</th>
<th class="biocng">Achieved</th>
<th class="biocng">%</th>
<th class="biogas">Target</th>
<th class="biogas">Achieved</th>
<th class="biogas">%</th>
<th class="gwtc">Target</th>
<th class="gwtc">Achieved</th>
<th class="gwtc">%</th>
<th class="incinerator">Target</th>
<th class="incinerator">Achieved</th>
<th class="incinerator">%</th>
<th class="baling">Target</th>
<th class="baling">Achieved</th>
<th class="baling">%</th>
<th class="cd">Target</th>
<th class="cd">Achieved</th>
<th class="cd">%</th>
</tr>
</thead>
<tfoot>
<tr class="fw-bold text-center">
<th colspan="2">TOTAL</th>
<!-- MCC -->
<th class="mcc"></th>
<th class="mcc"></th>
<th class="mcc"></th>
<!-- Windrow -->
<th class="windrow"></th>
<th class="windrow"></th>
<th class="windrow"></th>
<!-- Bio-CNG -->
<th class="biocng"></th>
<th class="biocng"></th>
<th class="biocng"></th>
<!-- Bio-GAS -->
<th class="biogas"></th>
<th class="biogas"></th>
<th class="biogas"></th>
<!-- Incinerator -->
<th class="incinerator"></th>
<th class="incinerator"></th>
<th class="incinerator"></th>
<!-- Baling -->
<th class="baling"></th>
<th class="baling"></th>
<th class="baling"></th>
<th class="gwtc"></th>
<th class="gwtc"></th>
<th class="gwtc"></th>
<!-- C&D -->
<th class="cd"></th>
<th class="cd"></th>
<th class="cd"></th>
</tr>
</tfoot>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" style="background:#2f3e54; color:white;">
<div>
<h4 class="modal-title-big" id="modalTitle"></h4>
<div id="modalSubTitle" class="modal-subtext"></div>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div id="modalContent"></div>
<div class="text-center mt-4">
<button type="button" class="btn btn-primary btn-big" data-dismiss="modal"
style="background:#2f3e54;">Close</button>
</div>
</div>
</div>
</div>
</div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script type="text/javascript">
let table;
$(document).ready(function () {
table = $('#QaqcDatatable').DataTable({
data: [],
ordering: false,
searching: true,
info: true,
paging: true,
pageLength: 15, // ✅ show 15 rows
lengthMenu: [15, 25, 50, 100], // ✅ optional dropdown
scrollX: true,
responsive: false,
dom: 'Bftip',
buttons: [
{
extend: 'excelHtml5',
text: 'Excel',
title: 'Gcc Swm Report'
},
{
extend: 'pdfHtml5',
orientation: 'landscape',
pageSize: 'A3',
title: 'Gcc Swm Report'
},
{
extend: 'csvHtml5',
text: 'CSV'
}
],
// columns: [
// { data: "sno", defaultContent: "" },
// { data: "zone", defaultContent: "" },
// { data: "MCC_target", defaultContent: 0 },
// { data: "MCC_achieved", defaultContent: 0 },
// { data: "MCC_percentage", defaultContent: "0%" },
// { data: "Windrow_target", defaultContent: 0 },
// { data: "Windrow_achieved", defaultContent: 0 },
// { data: "Windrow_percentage", defaultContent: "0%" },
// { data: "Bio-CNG_target", defaultContent: 0 },
// { data: "Bio-CNG_achieved", defaultContent: 0 },
// { data: "Bio-CNG_percentage", defaultContent: "0%" },
// { data: "Bio-GAS_target", defaultContent: 0 },
// { data: "Bio-GAS_achieved", defaultContent: 0 },
// { data: "Bio-GAS_percentage", defaultContent: "0%" },
// { data: "Incinerator_target", defaultContent: 0 },
// { data: "Incinerator_achieved", defaultContent: 0 },
// { data: "Incinerator_percentage", defaultContent: "0%" },
// { data: "Plasting Baling Centre_target", defaultContent: 0 },
// { data: "Plasting Baling Centre_achieved", defaultContent: 0 },
// { data: "Plasting Baling Centre_percentage", defaultContent: "0%" },
// { data: "GWTC_target", defaultContent: 0 },
// { data: "GWTC_achieved", defaultContent: 0 },
// { data: "GWTC_percentage", defaultContent: "0%" },
// { data: "CD_target", defaultContent: 0 },
// { data: "CD_achieved", defaultContent: 0 },
// { data: "CD_percentage", defaultContent: "0%" }
// ],
columns: [
{ data: "sno" },
{ data: "zone" },
{ data: "mcc_target", defaultContent: 0 },
{ data: "mcc_achieved", defaultContent: 0 },
{ data: "mcc_percentage", defaultContent: "0%" },
{ data: "windrow_target", defaultContent: 0 },
{ data: "windrow_achieved", defaultContent: 0 },
{ data: "windrow_percentage", defaultContent: "0%" },
{ data: "biocng_target", defaultContent: 0 },
{ data: "biocng_achieved", defaultContent: 0 },
{ data: "biocng_percentage", defaultContent: "0%" },
{ data: "biogas_target", defaultContent: 0 },
{ data: "biogas_achieved", defaultContent: 0 },
{ data: "biogas_percentage", defaultContent: "0%" },
{ data: "incinerator_target", defaultContent: 0 },
{ data: "incinerator_achieved", defaultContent: 0 },
{ data: "incinerator_percentage", defaultContent: "0%" },
{ data: "baling_target", defaultContent: 0 },
{ data: "baling_achieved", defaultContent: 0 },
{ data: "baling_percentage", defaultContent: "0%" },
{ data: "gwtc_target", defaultContent: 0 },
{ data: "gwtc_achieved", defaultContent: 0 },
{ data: "gwtc_percentage", defaultContent: "0%" },
{ data: "cd_target", defaultContent: 0 },
{ data: "cd_achieved", defaultContent: 0 },
{ data: "cd_percentage", defaultContent: "0%" }
],
/* ================= FOOTER TOTAL ================= */
footerCallback: function () {
const api = this.api();
function sum(colIdx) {
return api
.column(colIdx, { page: 'current' })
.data()
.reduce((a, b) => {
const x = parseFloat(a) || 0;
const y = parseFloat(String(b).replace('%', '')) || 0;
return x + y;
}, 0)
.toFixed(2);
}
const targetAchievedCols = [
2, 3, // MCC
5, 6, // Windrow
8, 9, // Bio-CNG
11, 12, // Bio-GAS
14, 15, // Incinerator
17, 18, // Baling
20, 21, // gwtc
23, 24 // C&D
];
targetAchievedCols.forEach(idx => {
if (api.column(idx).visible()) {
$(api.column(idx).footer()).html(sum(idx));
}
});
}
});
// 🔥 Hide/Show facility columns based on username
applyFacilityVisibility();
$("#searchBtn").on("click", loadLoginWiseReport);
});
function normalizeFacilityName(facility) {
const map = {
// MCC
"MCC": "mcc",
// Windrow
"Windrow": "windrow",
// Bio-CNG
"Bio-CNG": "biocng",
// Bio-GAS
"Bio-GAS": "biogas",
// Incinerator
"Incinerator": "incinerator",
// Baling
"Plasting Baling Centre": "baling",
"Plastic Baling Centre": "baling",
// 🔥 GW & TC (THIS IS THE FIX)
"GW & TC Waste": "gwtc",
"GW & TC Waste Processing Centre": "gwtc",
"GW TC Waste": "gwtc",
// C&D
"C&D Waste Processing Centre": "cd",
"C & D Waste Processing Centre": "cd",
"C&D Waste": "cd",
"SWM C&D": "cd"
};
return map[facility] || facility.toLowerCase().replace(/[^a-z]/g, "");
}
// function applyFacilityVisibility() {
// const username = $("#userName").val().toLowerCase();
// // hide all facility columns
// table.columns([...Array(26).keys()].slice(2)).visible(false);
// // hide all headers
// $('.grp-mcc,.grp-windrow,.grp-biocng,.grp-biogas,.grp-incinerator,.grp-baling,.grp-gwtc,.grp-cd').hide();
// $('.mcc,.windrow,.biocng,.biogas,.incinerator,.baling,.gwtc,.cd').hide();
// const map = {
// "mcc": { cols: [2, 3, 4], cls: "mcc", grp: "grp-mcc" },
// "windrow": { cols: [5, 6, 7], cls: "windrow", grp: "grp-windrow" },
// "biocng": { cols: [8, 9, 10], cls: "biocng", grp: "grp-biocng" },
// "biogas": { cols: [11, 12, 13], cls: "biogas", grp: "grp-biogas" },
// "incinerator": { cols: [14, 15, 16], cls: "incinerator", grp: "grp-incinerator" },
// "baling": { cols: [17, 18, 19], cls: "baling", grp: "grp-baling" },
// // ✅ ADD THIS (CRITICAL FIX)
// "pbc": { cols: [17, 18, 19], cls: "baling", grp: "grp-baling" },
// // ✅ GW & TC
// "gw": { cols: [20, 21, 22], cls: "gwtc", grp: "grp-gwtc" },
// "tc": { cols: [20, 21, 22], cls: "gwtc", grp: "grp-gwtc" },
// "gwtc": { cols: [20, 21, 22], cls: "gwtc", grp: "grp-gwtc" },
// // ✅ C&D
// "cd": { cols: [23, 24, 25], cls: "cd", grp: "grp-cd" },
// "c&d": { cols: [23, 24, 25], cls: "cd", grp: "grp-cd" }
// };
// Object.keys(map).forEach(key => {
// if (username.includes(key)) {
// table.columns(map[key].cols).visible(true);
// $('.' + map[key].cls).show();
// $('.' + map[key].grp).show();
// }
// });
// table.columns.adjust().draw(false);
// }
function applyFacilityVisibility() {
const username = $("#userName").val().toLowerCase();
// hide all columns except S.No & Zone
table.columns().visible(false);
table.columns([0, 1]).visible(true);
// hide all headers
$('.grp-mcc,.grp-windrow,.grp-biocng,.grp-biogas,.grp-incinerator,.grp-baling,.grp-gwtc,.grp-cd').hide();
$('.mcc,.windrow,.biocng,.biogas,.incinerator,.baling,.gwtc,.cd').hide();
const map = {
"mcc": { cols: [2, 3, 4], cls: "mcc", grp: "grp-mcc" },
"windrow": { cols: [5, 6, 7], cls: "windrow", grp: "grp-windrow" },
// 🔥 FIX: support bio_cng login
"bio_cng": { cols: [8, 9, 10], cls: "biocng", grp: "grp-biocng" },
"biocng": { cols: [8, 9, 10], cls: "biocng", grp: "grp-biocng" },
"bio_gas": { cols: [11, 12, 13], cls: "biogas", grp: "grp-biogas" },
"biogas": { cols: [11, 12, 13], cls: "biogas", grp: "grp-biogas" },
"incinerator": { cols: [14, 15, 16], cls: "incinerator", grp: "grp-incinerator" },
"baling": { cols: [17, 18, 19], cls: "baling", grp: "grp-baling" },
"pbc": { cols: [17, 18, 19], cls: "baling", grp: "grp-baling" },
"gwtc_waste": { cols: [20, 21, 22], cls: "gwtc", grp: "grp-gwtc" },
"gw": { cols: [20, 21, 22], cls: "gwtc", grp: "grp-gwtc" },
"tc": { cols: [20, 21, 22], cls: "gwtc", grp: "grp-gwtc" },
"cd": { cols: [23, 24, 25], cls: "cd", grp: "grp-cd" },
"c&d": { cols: [23, 24, 25], cls: "cd", grp: "grp-cd" }
};
Object.keys(map).forEach(key => {
if (username.includes(key)) {
table.columns(map[key].cols).visible(true);
$('.' + map[key].cls).show();
$('.' + map[key].grp).show();
}
});
table.columns.adjust().draw(false);
}
// function renderZoneTable(data) {
// const zoneMap = {};
// data.forEach(row => {
// const zone = row.zone;
// const facility = row.facility; // MCC / Windrow / etc
// if (!zoneMap[zone]) {
// zoneMap[zone] = {
// zone: zone
// };
// }
// // Target
// zoneMap[zone][facility + "_target"] =
// row.target !== null ? row.target : 0;
// // Achieved
// zoneMap[zone][facility + "_achieved"] =
// row.achieved !== null ? row.achieved : 0;
// // Percentage
// zoneMap[zone][facility + "_percentage"] =
// row.percentage !== null ? row.percentage + "%" : "0%";
// });
// let i = 1;
// const tableData = Object.values(zoneMap).map(row => ({
// sno: i++,
// ...row
// }));
// table.clear().rows.add(tableData).draw();
// }
// function renderZoneTable(data) {
// const zoneMap = {};
// data.forEach(row => {
// const zone = row.zone;
// const facility = normalizeFacilityName(row.facility);
// if (!zoneMap[zone]) {
// zoneMap[zone] = { zone };
// }
// zoneMap[zone][facility + "_target"] = row.target ?? 0;
// zoneMap[zone][facility + "_achieved"] = row.achieved ?? 0;
// zoneMap[zone][facility + "_percentage"] =
// row.percentage != null ? row.percentage + "%" : "0%";
// });
// let i = 1;
// const tableData = Object.values(zoneMap).map(r => ({
// sno: i++,
// ...r
// }));
// table.clear().rows.add(tableData).draw();
// }
function renderZoneTable(data) {
const zoneMap = {};
data.forEach(row => {
const zone = row.zone;
const facilityKey = normalizeFacilityName(row.facility);
if (!zoneMap[zone]) {
zoneMap[zone] = { zone };
}
zoneMap[zone][facilityKey + "_target"] = row.target ?? 0;
zoneMap[zone][facilityKey + "_achieved"] = row.achieved ?? 0;
zoneMap[zone][facilityKey + "_percentage"] =
row.percentage != null ? row.percentage + "%" : "0%";
});
let i = 1;
const tableData = Object.values(zoneMap).map(r => ({
sno: i++,
...r
}));
table.clear().rows.add(tableData).draw();
}
function loadLoginWiseReport() {
const fromDate = $("#fromDate").val();
const toDate = $("#toDate").val();
const username = $("#userName").val();
if (!fromDate || !toDate) {
Swal.fire("Validation", "Select both dates", "warning");
return;
}
$.ajax({
url: "/swm/api/facilities/reports",
type: "GET",
data: {
username: username,
fromDate: fromDate,
toDate: toDate
},
beforeSend: function () {
Swal.fire({
title: "Loading...",
allowOutsideClick: false,
didOpen: () => Swal.showLoading()
});
},
success: function (res) {
console.log(res);
Swal.close();
renderZoneTable(res.data);
},
error: function () {
Swal.fire("Error", "Failed to load report", "error");
}
});
}
</script>
</body>
</html>

447
src/main/resources/templates/modules/swm/gwtcwaste.html

@ -1,447 +0,0 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>
.width1 {
width: 120px;
}
.width2 {
width: 150px;
}
.modal-label {
font-weight: 600;
color: #333;
}
.modal-value {
color: #444;
}
.modal-section-title {
font-size: 1.2rem;
font-weight: bold;
margin-top: 20px;
margin-bottom: 10px;
border-bottom: 2px solid #dee2e6;
padding-bottom: 5px;
}
.modal-title-big {
font-size: 20px;
font-weight: 700;
}
.modal-subtext {
color: #b4c5d3;
font-size: 13px;
}
.card-section {
background: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 25px;
border: 1px solid #eee;
}
.section-title {
font-weight: 700;
color: #333;
margin-bottom: 15px;
font-size: 16px;
}
.label-text {
font-size: 13px;
color: #6c757d;
}
.value-text {
font-size: 15px;
font-weight: 600;
color: #333;
}
.info-block {
display: flex;
flex-direction: column;
}
.badge-status {
background: #ffd9b3;
color: #a65c00;
padding: 6px 10px;
border-radius: 5px;
font-size: 13px;
}
.btn-big {
padding: 12px 25px;
border-radius: 8px;
width: 200px;
}
.rdo-box {
border: 1px solid #eee;
border-radius: 10px;
padding: 20px;
}
</style>
<body>
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header">
<div class="row align-items-end">
<div class="col-lg-6">
<div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline">
<h5>SWD GW&TC Waste Facilities Add Details List</h5>
<span>GW&TC Waste Add Details</span>
</div>
</div>
</div>
<div class="col-lg-6">
<nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/swm/index"><i class="ik ik-home"></i></a>
</li>
<li class="breadcrumb-item" aria-current="page">SWD GW&TC Waste Facilities Add
Details List
</li>
<li class="breadcrumb-item active" aria-current="page">GW&TC Waste Add Details
</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center fw-bold">
<h3 class="mb-0"> SWD GW&TC Waste Add Details : <span
th:text="${officer_name}"></span></h3>
<input type="hidden" id="userName" th:value="${officer_name}">
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3">
<label for="date" class="form-label"
style="font-size: medium;">Date:</label><span
class="text-danger">*</span>
<input type="date" id="date" class="form-control">
</div>
<div class="col-md-3">
<label for="zones" class="form-label">Zones <span
class="text-danger">*</span>
</label> <select id="zones" class="form-control">
<option value="">Select zones</option>
</select>
</div>
<div class="col-md-3">
<label for="weight" class="form-label">Enter Weight for Garden
Waste:(in MT)</label><span class="text-danger">*</span>
<input type="number" class="form-control" id="weight">
</div>
<input type="hidden" id="facilityTypeId" th:value="${facilityTypeId}">
<!-- SECOND WEIGHT (TC) -->
<div class="col-md-3">
<label for="weight1" class="form-label">Enter Weight Tender Coconut:(in
MT)</label><span class="text-danger">*</span>
<input type="number" class="form-control" id="weight1">
</div>
<div class="col-md-3" id="weightTypeDiv">
<label class="form-label">Location<span class="text-danger">*</span></label>
<select id="facilitytype" class="form-control">
<option value="">Select</option>
<option value="KDG">KDG</option>
<option value="PDG">PDG</option>
</select>
</div>
<div class="col-md-3" style="margin-top: 30px;">
<button id="submitBtn" class="btn btn-primary">Submit</button>
<button id="resetBtn" class="btn btn-secondary">Reset</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" style="background:#2f3e54; color:white;">
<div>
<h4 class="modal-title-big" id="modalTitle"></h4>
<div id="modalSubTitle" class="modal-subtext"></div>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div id="modalContent"></div>
<div class="text-center mt-4">
<button type="button" class="btn btn-primary btn-big" data-dismiss="modal"
style="background:#2f3e54;">Close</button>
</div>
</div>
</div>
</div>
</div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script type="text/javascript">
$(document).ready(function () {
const today = new Date();
const day = today.getDay(); // 0=Sun, 1=Mon, ..., 6=Sat
/* =============================
LAST SATURDAY
============================= */
const lastSaturday = new Date(today);
// If today is Saturday (6) → today
// Else → go back to previous Saturday
const diffToLastSaturday = (day >= 6)
? day - 6
: day + 1;
lastSaturday.setDate(today.getDate() - diffToLastSaturday);
/* =============================
THIS WEEK FRIDAY
============================= */
const thisFriday = new Date(today);
// Friday = 5
const diffToFriday = (5 - day + 7) % 7;
thisFriday.setDate(today.getDate() + diffToFriday);
/* =============================
FORMAT YYYY-MM-DD
============================= */
const formatDate = (d) => d.toISOString().split("T")[0];
const minDate = formatDate(lastSaturday);
const maxDate = formatDate(thisFriday);
/* =============================
APPLY LIMITS
============================= */
$("#date")
.attr("min", minDate)
.attr("max", maxDate)
.val(formatDate(today));
// 🔒 BLOCK MANUAL TYPING (BUT ALLOW CALENDAR)
$("#date").on("keydown paste", function (e) {
e.preventDefault();
});
});
$(document).ready(function () {
const isTwoWeightFacility =
$("body").data("two-weight") === true ||
$("body").data("two-weight") === "true";
console.log($("body").data("two-weight"));
if (isTwoWeightFacility) {
$("#weight2Div").show();
} else {
$("#weight2Div").hide();
$("#weight1").val("");
}
});
$(document).ready(function () {
const today = new Date().toISOString().split('T')[0];
$("#date").val(today);
});
$("#resetBtn").on("click", function () {
location.reload();
});
// Load zones when page loads
$(document).ready(function () {
$.ajax({
url: "/swm/api/dropdown/getzoneslist",
type: "GET",
dataType: "json",
success: function (data) {
let zoneDropdown = $("#zones");
zoneDropdown.empty();
zoneDropdown.append("<option value=''>Select Zone</option>");
$.each(data, function (index, item) {
zoneDropdown.append(
`<option value="${item.id}">${item.zone_name}</option>`
);
});
},
error: function (xhr, status, error) {
console.error("Error fetching zones:", error);
}
});
});
$("#submitBtn").on("click", function (e) {
e.preventDefault();
const facilityTypeId = $("#facilityTypeId").val(); // ✅ dynamic
const zoneId = $("#zones").val();
const reqDate = $("#date").val();
const weight = $("#weight").val();
const weight1 = $("#weight1").val();
const createdBy = $("#userName").val();
const weightType = $("#facilitytype").val();
// 🔴 Client-side validations
if (!zoneId) {
Swal.fire("Validation Error", "Please select zone", "warning");
return;
}
if (!reqDate) {
Swal.fire("Validation Error", "Date is required", "warning");
return;
}
if (!weight || weight == "") {
Swal.fire("Validation Error", "Weight is required", "warning");
return;
}
// if (!weight || weight <= 0) {
// Swal.fire("Validation Error", "Weight must be greater than zero", "warning");
// return;
// }
// ⚠️ Note:
// Facility type 5 validation is done in BACKEND
// because facilityTypeId is derived after login
$.ajax({
url: "/swm/api/admin/addfacility",
type: "POST",
data: {
facilityTypeId: facilityTypeId,
zoneId: zoneId,
reqDate: reqDate,
weight: weight,
weight1: weight1,
weightType: weightType,
createdBy: createdBy // backend will ignore if not needed
},
beforeSend: function () {
Swal.fire({
title: "Saving...",
text: "Please wait",
allowOutsideClick: false,
didOpen: () => Swal.showLoading()
});
},
success: function (response) {
Swal.fire("Success", response.message, "success");
// Reset fields
$("#weight").val("");
$("#weight1").val("");
},
error: function (xhr) {
let msg = "Something went wrong";
if (xhr.responseJSON && xhr.responseJSON.message) {
msg = xhr.responseJSON.message;
}
Swal.fire("Error", msg, "error");
}
});
});
</script>
</body>
</html>

421
src/main/resources/templates/modules/swm/incinerator.html

@ -1,421 +0,0 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>
.width1 {
width: 120px;
}
.width2 {
width: 150px;
}
.modal-label {
font-weight: 600;
color: #333;
}
.modal-value {
color: #444;
}
.modal-section-title {
font-size: 1.2rem;
font-weight: bold;
margin-top: 20px;
margin-bottom: 10px;
border-bottom: 2px solid #dee2e6;
padding-bottom: 5px;
}
.modal-title-big {
font-size: 20px;
font-weight: 700;
}
.modal-subtext {
color: #b4c5d3;
font-size: 13px;
}
.card-section {
background: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 25px;
border: 1px solid #eee;
}
.section-title {
font-weight: 700;
color: #333;
margin-bottom: 15px;
font-size: 16px;
}
.label-text {
font-size: 13px;
color: #6c757d;
}
.value-text {
font-size: 15px;
font-weight: 600;
color: #333;
}
.info-block {
display: flex;
flex-direction: column;
}
.badge-status {
background: #ffd9b3;
color: #a65c00;
padding: 6px 10px;
border-radius: 5px;
font-size: 13px;
}
.btn-big {
padding: 12px 25px;
border-radius: 8px;
width: 200px;
}
.rdo-box {
border: 1px solid #eee;
border-radius: 10px;
padding: 20px;
}
</style>
<body th:attr="data-two-weight=${isTwoWeightFacility}">
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header">
<div class="row align-items-end">
<div class="col-lg-6">
<div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline">
<h5>SWD Incinerator Facilities Add Details List</h5>
<span>Incinerator Add Details</span>
</div>
</div>
</div>
<div class="col-lg-6">
<nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/swm/index"><i class="ik ik-home"></i></a>
</li>
<li class="breadcrumb-item" aria-current="page">SWD Incinerator Facilities Add
Details List
</li>
<li class="breadcrumb-item active" aria-current="page">Incinerator Add Details
</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center fw-bold">
<h3 class="mb-0"> SWD Incinerator Add Details : <span
th:text="${officer_name}"></span></h3>
<input type="hidden" id="userName" th:value="${officer_name}">
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3">
<label for="date" class="form-label"
style="font-size: medium;">Date:</label><span
class="text-danger">*</span>
<input type="date" id="date" class="form-control">
</div>
<div class="col-md-3">
<label for="zones" class="form-label">Zones <span
class="text-danger">*</span>
</label> <select id="zones" class="form-control">
<option value="">Select days</option>
</select>
</div>
<div class="col-md-3">
<label for="weight" class="form-label">Enter Weight:(in MT)</label><span
class="text-danger">*</span>
<input type="number" class="form-control" id="weight">
</div>
<input type="hidden" id="facilityTypeId" th:value="${facilityTypeId}">
<!-- SECOND WEIGHT (TC) -->
<div class="col-md-3" id="weight2Div" style="display:none;">
<label for="weight1">Enter Weight (TC)</label><span
class="text-danger">*</span>
<input type="number" class="form-control" id="weight1">
</div>
<div class="col-md-3" style="margin-top: 30px;">
<button id="submitBtn" class="btn btn-primary">Submit</button>
<button id="resetBtn" class="btn btn-secondary">Reset</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" style="background:#2f3e54; color:white;">
<div>
<h4 class="modal-title-big" id="modalTitle"></h4>
<div id="modalSubTitle" class="modal-subtext"></div>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div id="modalContent"></div>
<div class="text-center mt-4">
<button type="button" class="btn btn-primary btn-big" data-dismiss="modal"
style="background:#2f3e54;">Close</button>
</div>
</div>
</div>
</div>
</div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script type="text/javascript">
$(document).ready(function () {
const today = new Date();
const day = today.getDay(); // 0=Sun, 1=Mon, ..., 6=Sat
/* =============================
LAST SATURDAY
============================= */
const lastSaturday = new Date(today);
// If today is Saturday (6) → today
// Else → go back to previous Saturday
const diffToLastSaturday = (day >= 6)
? day - 6
: day + 1;
lastSaturday.setDate(today.getDate() - diffToLastSaturday);
/* =============================
THIS WEEK FRIDAY
============================= */
const thisFriday = new Date(today);
// Friday = 5
const diffToFriday = (5 - day + 7) % 7;
thisFriday.setDate(today.getDate() + diffToFriday);
/* =============================
FORMAT YYYY-MM-DD
============================= */
const formatDate = (d) => d.toISOString().split("T")[0];
const minDate = formatDate(lastSaturday);
const maxDate = formatDate(thisFriday);
/* =============================
APPLY LIMITS
============================= */
$("#date")
.attr("min", minDate)
.attr("max", maxDate)
.val(formatDate(today));
// 🔒 BLOCK MANUAL TYPING (BUT ALLOW CALENDAR)
$("#date").on("keydown paste", function (e) {
e.preventDefault();
});
});
$(document).ready(function () {
const isTwoWeightFacility =
$("body").data("two-weight") === true ||
$("body").data("two-weight") === "true";
console.log($("body").data("two-weight"));
if (isTwoWeightFacility) {
$("#weight2Div").show();
} else {
$("#weight2Div").hide();
$("#weight1").val("");
}
});
$(document).ready(function () {
const today = new Date().toISOString().split('T')[0];
$("#date").val(today);
});
$("#resetBtn").on("click", function () {
location.reload();
});
// Load zones when page loads
$(document).ready(function () {
$.ajax({
url: "/swm/api/dropdown/getzoneslist",
type: "GET",
dataType: "json",
success: function (data) {
let zoneDropdown = $("#zones");
zoneDropdown.empty();
zoneDropdown.append("<option value=''>Select Zone</option>");
$.each(data, function (index, item) {
zoneDropdown.append(
`<option value="${item.id}">${item.zone_name}</option>`
);
});
},
error: function (xhr, status, error) {
console.error("Error fetching zones:", error);
}
});
});
$("#submitBtn").on("click", function (e) {
e.preventDefault();
const facilityTypeId = $("#facilityTypeId").val(); // ✅ dynamic
const zoneId = $("#zones").val();
const reqDate = $("#date").val();
const weight = $("#weight").val();
const weight1 = $("#weight1").val();
const createdBy = $("#userName").val();
// 🔴 Client-side validations
if (!zoneId) {
Swal.fire("Validation Error", "Please select zone", "warning");
return;
}
if (!reqDate) {
Swal.fire("Validation Error", "Date is required", "warning");
return;
}
if (!weight || weight <= 0) {
Swal.fire("Validation Error", "Weight must be greater than zero", "warning");
return;
}
// ⚠️ Note:
// Facility type 5 validation is done in BACKEND
// because facilityTypeId is derived after login
$.ajax({
url: "/swm/api/admin/addfacility",
type: "POST",
data: {
facilityTypeId: facilityTypeId,
zoneId: zoneId,
reqDate: reqDate,
weight: weight,
weight1: weight1,
createdBy: createdBy // backend will ignore if not needed
},
beforeSend: function () {
Swal.fire({
title: "Saving...",
text: "Please wait",
allowOutsideClick: false,
didOpen: () => Swal.showLoading()
});
},
success: function (response) {
Swal.fire("Success", response.message, "success");
// Reset fields
$("#weight").val("");
$("#weight1").val("");
},
error: function (xhr) {
let msg = "Something went wrong";
if (xhr.responseJSON && xhr.responseJSON.message) {
msg = xhr.responseJSON.message;
}
Swal.fire("Error", msg, "error");
}
});
});
</script>
</body>
</html>

428
src/main/resources/templates/modules/swm/mcc.html

@ -1,428 +0,0 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>
.width1 {
width: 120px;
}
.width2 {
width: 150px;
}
.modal-label {
font-weight: 600;
color: #333;
}
.modal-value {
color: #444;
}
.modal-section-title {
font-size: 1.2rem;
font-weight: bold;
margin-top: 20px;
margin-bottom: 10px;
border-bottom: 2px solid #dee2e6;
padding-bottom: 5px;
}
.modal-title-big {
font-size: 20px;
font-weight: 700;
}
.modal-subtext {
color: #b4c5d3;
font-size: 13px;
}
.card-section {
background: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 25px;
border: 1px solid #eee;
}
.section-title {
font-weight: 700;
color: #333;
margin-bottom: 15px;
font-size: 16px;
}
.label-text {
font-size: 13px;
color: #6c757d;
}
.value-text {
font-size: 15px;
font-weight: 600;
color: #333;
}
.info-block {
display: flex;
flex-direction: column;
}
.badge-status {
background: #ffd9b3;
color: #a65c00;
padding: 6px 10px;
border-radius: 5px;
font-size: 13px;
}
.btn-big {
padding: 12px 25px;
border-radius: 8px;
width: 200px;
}
.rdo-box {
border: 1px solid #eee;
border-radius: 10px;
padding: 20px;
}
</style>
<body th:attr="data-two-weight=${isTwoWeightFacility}">
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header">
<div class="row align-items-end">
<div class="col-lg-6">
<div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline">
<h5>SWD MCC Facilities Add Details List</h5>
<span> MCC Add Details</span>
</div>
</div>
</div>
<div class="col-lg-6">
<nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/swm/index"><i class="ik ik-home"></i></a>
</li>
<li class="breadcrumb-item" aria-current="page">SWD MCC Facilities Add Details
List
</li>
<li class="breadcrumb-item active" aria-current="page">MCC Add Details</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center fw-bold">
<h3 class="mb-0"> SWM MCC Add Details : <span th:text="${officer_name}"></span></h3>
<input type="hidden" id="userName" th:value="${officer_name}">
</div>
<div class="card-body">
<div class="row">
<!-- <div class="col-md-3">
<label for="date" class="form-label"
style="font-size: medium;">Date:</label>
<input type="date" id="date" class="form-control" readonly>
</div> -->
<div class="col-md-3">
<label for="date" class="form-label" style="font-size: medium;">
Date:
</label><span class="text-danger">*</span>
<input type="date" id="date" class="form-control">
</div>
<div class="col-md-3">
<label for="zones" class="form-label">Zones <span
class="text-danger">*</span>
</label> <select id="zones" class="form-control">
<option value="">Select zones</option>
</select>
</div>
<div class="col-md-3">
<label for="weight" class="form-label">Enter Weight:(in MT)</label><span
class="text-danger">*</span>
<input type="number" class="form-control" id="weight">
</div>
<input type="hidden" id="facilityTypeId" th:value="${facilityTypeId}">
<!-- SECOND WEIGHT (TC) -->
<div class="col-md-3" id="weight2Div" style="display:none;">
<label for="weight1">Enter Weight (TC)</label><span
class="text-danger">*</span>
<input type="number" class="form-control" id="weight1">
</div>
<div class="col-md-3" style="margin-top: 30px;">
<button id="submitBtn" class="btn btn-primary">Submit</button>
<button id="resetBtn" class="btn btn-secondary">Reset</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" style="background:#2f3e54; color:white;">
<div>
<h4 class="modal-title-big" id="modalTitle"></h4>
<div id="modalSubTitle" class="modal-subtext"></div>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div id="modalContent"></div>
<div class="text-center mt-4">
<button type="button" class="btn btn-primary btn-big" data-dismiss="modal"
style="background:#2f3e54;">Close</button>
</div>
</div>
</div>
</div>
</div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script type="text/javascript">
$(document).ready(function () {
const today = new Date();
const day = today.getDay(); // 0=Sun, 1=Mon, ..., 6=Sat
/* =============================
LAST SATURDAY
============================= */
const lastSaturday = new Date(today);
// If today is Saturday (6) → today
// Else → go back to previous Saturday
const diffToLastSaturday = (day >= 6)
? day - 6
: day + 1;
lastSaturday.setDate(today.getDate() - diffToLastSaturday);
/* =============================
THIS WEEK FRIDAY
============================= */
const thisFriday = new Date(today);
// Friday = 5
const diffToFriday = (5 - day + 7) % 7;
thisFriday.setDate(today.getDate() + diffToFriday);
/* =============================
FORMAT YYYY-MM-DD
============================= */
const formatDate = (d) => d.toISOString().split("T")[0];
const minDate = formatDate(lastSaturday);
const maxDate = formatDate(thisFriday);
/* =============================
APPLY LIMITS
============================= */
$("#date")
.attr("min", minDate)
.attr("max", maxDate)
.val(formatDate(today));
// 🔒 BLOCK MANUAL TYPING (BUT ALLOW CALENDAR)
$("#date").on("keydown paste", function (e) {
e.preventDefault();
});
});
$(document).ready(function () {
const isTwoWeightFacility =
$("body").data("two-weight") === true ||
$("body").data("two-weight") === "true";
console.log($("body").data("two-weight"));
if (isTwoWeightFacility) {
$("#weight2Div").show();
} else {
$("#weight2Div").hide();
$("#weight1").val("");
}
});
$(document).ready(function () {
const today = new Date().toISOString().split('T')[0];
$("#date").val(today);
});
$("#resetBtn").on("click", function () {
location.reload();
});
// Load zones when page loads
$(document).ready(function () {
$.ajax({
url: "/swm/api/dropdown/getzoneslist",
type: "GET",
dataType: "json",
success: function (data) {
let zoneDropdown = $("#zones");
zoneDropdown.empty();
zoneDropdown.append("<option value=''>Select Zone</option>");
$.each(data, function (index, item) {
zoneDropdown.append(
`<option value="${item.id}">${item.zone_name}</option>`
);
});
},
error: function (xhr, status, error) {
console.error("Error fetching zones:", error);
}
});
});
$("#submitBtn").on("click", function (e) {
e.preventDefault();
const facilityTypeId = $("#facilityTypeId").val(); // ✅ dynamic
const zoneId = $("#zones").val();
const reqDate = $("#date").val();
const weight = $("#weight").val();
const weight1 = $("#weight1").val();
const createdBy = $("#userName").val();
// 🔴 Client-side validations
if (!zoneId) {
Swal.fire("Validation Error", "Please select zone", "warning");
return;
}
if (!reqDate) {
Swal.fire("Validation Error", "Date is required", "warning");
return;
}
if (!weight || weight <= 0) {
Swal.fire("Validation Error", "Weight must be greater than zero", "warning");
return;
}
// ⚠️ Note:
// Facility type 5 validation is done in BACKEND
// because facilityTypeId is derived after login
$.ajax({
url: "/swm/api/admin/addfacility",
type: "POST",
data: {
facilityTypeId: facilityTypeId,
zoneId: zoneId,
reqDate: reqDate,
weight: weight,
weight1: weight1,
createdBy: createdBy // backend will ignore if not needed
},
beforeSend: function () {
Swal.fire({
title: "Saving...",
text: "Please wait",
allowOutsideClick: false,
didOpen: () => Swal.showLoading()
});
},
success: function (response) {
Swal.fire("Success", response.message, "success");
// Reset fields
$("#weight").val("");
$("#weight1").val("");
},
error: function (xhr) {
let msg = "Something went wrong";
if (xhr.responseJSON && xhr.responseJSON.message) {
msg = xhr.responseJSON.message;
}
Swal.fire("Error", msg, "error");
}
});
});
</script>
</body>
</html>

424
src/main/resources/templates/modules/swm/mrf.html

@ -1,424 +0,0 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>
.width1 {
width: 120px;
}
.width2 {
width: 150px;
}
.modal-label {
font-weight: 600;
color: #333;
}
.modal-value {
color: #444;
}
.modal-section-title {
font-size: 1.2rem;
font-weight: bold;
margin-top: 20px;
margin-bottom: 10px;
border-bottom: 2px solid #dee2e6;
padding-bottom: 5px;
}
.modal-title-big {
font-size: 20px;
font-weight: 700;
}
.modal-subtext {
color: #b4c5d3;
font-size: 13px;
}
.card-section {
background: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 25px;
border: 1px solid #eee;
}
.section-title {
font-weight: 700;
color: #333;
margin-bottom: 15px;
font-size: 16px;
}
.label-text {
font-size: 13px;
color: #6c757d;
}
.value-text {
font-size: 15px;
font-weight: 600;
color: #333;
}
.info-block {
display: flex;
flex-direction: column;
}
.badge-status {
background: #ffd9b3;
color: #a65c00;
padding: 6px 10px;
border-radius: 5px;
font-size: 13px;
}
.btn-big {
padding: 12px 25px;
border-radius: 8px;
width: 200px;
}
.rdo-box {
border: 1px solid #eee;
border-radius: 10px;
padding: 20px;
}
</style>
<body th:attr="data-two-weight=${isTwoWeightFacility}">
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header">
<div class="row align-items-end">
<div class="col-lg-6">
<div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline">
<h5>SWD MRF OR RRC Facilities Add Details List</h5>
<span> MRF OR RRC Add Details</span>
</div>
</div>
</div>
<div class="col-lg-6">
<nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/swm/index"><i class="ik ik-home"></i></a>
</li>
<li class="breadcrumb-item" aria-current="page">SWD MRF OR RRC Facilities Add
Details List
</li>
<li class="breadcrumb-item active" aria-current="page">MRF OR RRC Add Details
</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center fw-bold">
<h3 class="mb-0"> SWD MRF OR RRC Add Details : <span
th:text="${officer_name}"></span></h3>
<input type="hidden" id="userName" th:value="${officer_name}">
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3">
<label for="date" class="form-label"
style="font-size: medium;">Date:</label>
<input type="date" id="date" class="form-control">
</div>
<div class="col-md-3">
<label for="zones" class="form-label">Zones <span
class="text-danger">*</span>
</label> <select id="zones" class="form-control">
<option value="">Select days</option>
</select>
</div>
<div class="col-md-3">
<label for="weight" class="form-label">Enter Weight:(in MT)</label>
<input type="number" class="form-control" id="weight">
</div>
<input type="hidden" id="facilityTypeId" th:value="${facilityTypeId}">
<!-- SECOND WEIGHT (TC) -->
<div class="col-md-3" id="weight2Div" style="display:none;">
<label for="weight1">Enter Weight (TC)</label>
<input type="number" class="form-control" id="weight1">
</div>
<div class="col-md-3" style="margin-top: 30px;">
<button id="submitBtn" class="btn btn-primary">Submit</button>
<button id="resetBtn" class="btn btn-secondary">Reset</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" style="background:#2f3e54; color:white;">
<div>
<h4 class="modal-title-big" id="modalTitle"></h4>
<div id="modalSubTitle" class="modal-subtext"></div>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div id="modalContent"></div>
<div class="text-center mt-4">
<button type="button" class="btn btn-primary btn-big" data-dismiss="modal"
style="background:#2f3e54;">Close</button>
</div>
</div>
</div>
</div>
</div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script type="text/javascript">
$(document).ready(function () {
const today = new Date();
const day = today.getDay(); // 0=Sun, 1=Mon, ..., 6=Sat
/* =============================
LAST SATURDAY
============================= */
const lastSaturday = new Date(today);
// If today is Saturday (6) → today
// Else → go back to previous Saturday
const diffToLastSaturday = (day >= 6)
? day - 6
: day + 1;
lastSaturday.setDate(today.getDate() - diffToLastSaturday);
/* =============================
THIS WEEK FRIDAY
============================= */
const thisFriday = new Date(today);
// Friday = 5
const diffToFriday = (5 - day + 7) % 7;
thisFriday.setDate(today.getDate() + diffToFriday);
/* =============================
FORMAT YYYY-MM-DD
============================= */
const formatDate = (d) => d.toISOString().split("T")[0];
const minDate = formatDate(lastSaturday);
const maxDate = formatDate(thisFriday);
/* =============================
APPLY LIMITS
============================= */
$("#date")
.attr("min", minDate)
.attr("max", maxDate)
.val(formatDate(today));
// 🔒 BLOCK MANUAL TYPING (BUT ALLOW CALENDAR)
$("#date").on("keydown paste", function (e) {
e.preventDefault();
});
});
$(document).ready(function () {
const isTwoWeightFacility =
$("body").data("two-weight") === true ||
$("body").data("two-weight") === "true";
console.log($("body").data("two-weight"));
if (isTwoWeightFacility) {
$("#weight2Div").show();
} else {
$("#weight2Div").hide();
$("#weight1").val("");
}
});
$(document).ready(function () {
const today = new Date().toISOString().split('T')[0];
$("#date").val(today);
});
$("#resetBtn").on("click", function () {
location.reload();
});
// Load zones when page loads
$(document).ready(function () {
$.ajax({
url: "/swm/api/dropdown/getzoneslist",
type: "GET",
dataType: "json",
success: function (data) {
let zoneDropdown = $("#zones");
zoneDropdown.empty();
zoneDropdown.append("<option value=''>Select Zone</option>");
$.each(data, function (index, item) {
zoneDropdown.append(
`<option value="${item.id}">${item.zone_name}</option>`
);
});
},
error: function (xhr, status, error) {
console.error("Error fetching zones:", error);
}
});
});
$("#submitBtn").on("click", function (e) {
e.preventDefault();
const facilityTypeId = $("#facilityTypeId").val(); // ✅ dynamic
const zoneId = $("#zones").val();
const reqDate = $("#date").val();
const weight = $("#weight").val();
const weight1 = $("#weight1").val();
const createdBy = $("#userName").val();
// 🔴 Client-side validations
if (!zoneId) {
Swal.fire("Validation Error", "Please select zone", "warning");
return;
}
if (!reqDate) {
Swal.fire("Validation Error", "Date is required", "warning");
return;
}
if (!weight || weight <= 0) {
Swal.fire("Validation Error", "Weight must be greater than zero", "warning");
return;
}
// ⚠️ Note:
// Facility type 5 validation is done in BACKEND
// because facilityTypeId is derived after login
$.ajax({
url: "/swm/api/admin/addfacility",
type: "POST",
data: {
facilityTypeId: facilityTypeId,
zoneId: zoneId,
reqDate: reqDate,
weight: weight,
weight1: weight1,
createdBy: createdBy // backend will ignore if not needed
},
beforeSend: function () {
Swal.fire({
title: "Saving...",
text: "Please wait",
allowOutsideClick: false,
didOpen: () => Swal.showLoading()
});
},
success: function (response) {
Swal.fire("Success", response.message, "success");
// Reset fields
$("#weight").val("");
$("#weight1").val("");
},
error: function (xhr) {
let msg = "Something went wrong";
if (xhr.responseJSON && xhr.responseJSON.message) {
msg = xhr.responseJSON.message;
}
Swal.fire("Error", msg, "error");
}
});
});
</script>
</body>
</html>

418
src/main/resources/templates/modules/swm/plastingbaling.html

@ -1,418 +0,0 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>
.width1 {
width: 120px;
}
.width2 {
width: 150px;
}
.modal-label {
font-weight: 600;
color: #333;
}
.modal-value {
color: #444;
}
.modal-section-title {
font-size: 1.2rem;
font-weight: bold;
margin-top: 20px;
margin-bottom: 10px;
border-bottom: 2px solid #dee2e6;
padding-bottom: 5px;
}
.modal-title-big {
font-size: 20px;
font-weight: 700;
}
.modal-subtext {
color: #b4c5d3;
font-size: 13px;
}
.card-section {
background: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 25px;
border: 1px solid #eee;
}
.section-title {
font-weight: 700;
color: #333;
margin-bottom: 15px;
font-size: 16px;
}
.label-text {
font-size: 13px;
color: #6c757d;
}
.value-text {
font-size: 15px;
font-weight: 600;
color: #333;
}
.info-block {
display: flex;
flex-direction: column;
}
.badge-status {
background: #ffd9b3;
color: #a65c00;
padding: 6px 10px;
border-radius: 5px;
font-size: 13px;
}
.btn-big {
padding: 12px 25px;
border-radius: 8px;
width: 200px;
}
.rdo-box {
border: 1px solid #eee;
border-radius: 10px;
padding: 20px;
}
</style>
<body th:attr="data-two-weight=${isTwoWeightFacility}">
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header">
<div class="row align-items-end">
<div class="col-lg-6">
<div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline">
<h5>SWD Plasting Baling Facilities Add Details List</h5>
<span>Plasting Baling Add Details</span>
</div>
</div>
</div>
<div class="col-lg-6">
<nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/swm/index"><i class="ik ik-home"></i></a>
</li>
<li class="breadcrumb-item" aria-current="page">SWD Plasting Baling Facilities
Add Details List
</li>
<li class="breadcrumb-item active" aria-current="page">Plasting Baling Add
Details</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center fw-bold">
<h3 class="mb-0"> SWD Plasting Baling Add Details : <span
th:text="${officer_name}"></span></h3>
<input type="hidden" id="userName" th:value="${officer_name}">
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3">
<label for="date" class="form-label"
style="font-size: medium;">Date:</label><span
class="text-danger">*</span>
<input type="date" id="date" class="form-control">
</div>
<div class="col-md-3">
<label for="zones" class="form-label">Zones <span
class="text-danger">*</span>
</label> <select id="zones" class="form-control">
<option value="">Select days</option>
</select>
</div>
<input type="hidden" id="facilityTypeId" th:value="${facilityTypeId}">
<div class="col-md-3">
<label for="weight" class="form-label">Enter Weight:(in MT)</label><span
class="text-danger">*</span>
<input type="number" class="form-control" id="weight">
</div>
<!-- SECOND WEIGHT (TC) -->
<div class="col-md-3" id="weight2Div" style="display:none;">
<label for="weight1">Enter Weight (TC)</label><span
class="text-danger">*</span>
<input type="number" class="form-control" id="weight1">
</div>
<div class="col-md-3" style="margin-top: 30px;">
<button id="submitBtn" class="btn btn-primary">Submit</button>
<button id="resetBtn" class="btn btn-secondary">Reset</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" style="background:#2f3e54; color:white;">
<div>
<h4 class="modal-title-big" id="modalTitle"></h4>
<div id="modalSubTitle" class="modal-subtext"></div>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div id="modalContent"></div>
<div class="text-center mt-4">
<button type="button" class="btn btn-primary btn-big" data-dismiss="modal"
style="background:#2f3e54;">Close</button>
</div>
</div>
</div>
</div>
</div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script type="text/javascript">
$(document).ready(function () {
const today = new Date();
const day = today.getDay(); // 0=Sun, 1=Mon, ..., 6=Sat
/* =============================
LAST SATURDAY
============================= */
const lastSaturday = new Date(today);
// If today is Saturday (6) → today
// Else → go back to previous Saturday
const diffToLastSaturday = (day >= 6)
? day - 6
: day + 1;
lastSaturday.setDate(today.getDate() - diffToLastSaturday);
/* =============================
THIS WEEK FRIDAY
============================= */
const thisFriday = new Date(today);
// Friday = 5
const diffToFriday = (5 - day + 7) % 7;
thisFriday.setDate(today.getDate() + diffToFriday);
/* =============================
FORMAT YYYY-MM-DD
============================= */
const formatDate = (d) => d.toISOString().split("T")[0];
const minDate = formatDate(lastSaturday);
const maxDate = formatDate(thisFriday);
/* =============================
APPLY LIMITS
============================= */
$("#date")
.attr("min", minDate)
.attr("max", maxDate)
.val(formatDate(today));
// 🔒 BLOCK MANUAL TYPING (BUT ALLOW CALENDAR)
$("#date").on("keydown paste", function (e) {
e.preventDefault();
});
});
$(document).ready(function () {
const isTwoWeightFacility =
$("body").data("two-weight") === true ||
$("body").data("two-weight") === "true";
console.log($("body").data("two-weight"));
if (isTwoWeightFacility) {
$("#weight2Div").show();
} else {
$("#weight2Div").hide();
$("#weight1").val("");
}
});
$(document).ready(function () {
const today = new Date().toISOString().split('T')[0];
$("#date").val(today);
});
$("#resetBtn").on("click", function () {
location.reload();
});
// Load zones when page loads
$(document).ready(function () {
$.ajax({
url: "/swm/api/dropdown/getzoneslist",
type: "GET",
dataType: "json",
success: function (data) {
let zoneDropdown = $("#zones");
zoneDropdown.empty();
zoneDropdown.append("<option value=''>Select Zone</option>");
$.each(data, function (index, item) {
zoneDropdown.append(
`<option value="${item.id}">${item.zone_name}</option>`
);
});
},
error: function (xhr, status, error) {
console.error("Error fetching zones:", error);
}
});
});
$("#submitBtn").on("click", function (e) {
e.preventDefault();
const facilityTypeId = $("#facilityTypeId").val(); // ✅ dynamic
const zoneId = $("#zones").val();
const reqDate = $("#date").val();
const weight = $("#weight").val();
const weight1 = $("#weight1").val();
const createdBy = $("#userName").val();
// 🔴 Client-side validations
if (!zoneId) {
Swal.fire("Validation Error", "Please select zone", "warning");
return;
}
if (!reqDate) {
Swal.fire("Validation Error", "Date is required", "warning");
return;
}
if (!weight || weight <= 0) {
Swal.fire("Validation Error", "Weight must be greater than zero", "warning");
return;
}
// ⚠️ Note:
// Facility type 5 validation is done in BACKEND
// because facilityTypeId is derived after login
$.ajax({
url: "/swm/api/admin/addfacility",
type: "POST",
data: {
facilityTypeId: facilityTypeId,
zoneId: zoneId,
reqDate: reqDate,
weight: weight,
weight1: weight1,
createdBy: createdBy // backend will ignore if not needed
},
beforeSend: function () {
Swal.fire({
title: "Saving...",
text: "Please wait",
allowOutsideClick: false,
didOpen: () => Swal.showLoading()
});
},
success: function (response) {
Swal.fire("Success", response.message, "success");
// Reset fields
$("#weight").val("");
$("#weight1").val("");
},
error: function (xhr) {
let msg = "Something went wrong";
if (xhr.responseJSON && xhr.responseJSON.message) {
msg = xhr.responseJSON.message;
}
Swal.fire("Error", msg, "error");
}
});
});
</script>
</body>
</html>

944
src/main/resources/templates/modules/swm/reports.html

@ -1,944 +0,0 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>
.width1 {
width: 120px;
}
.width2 {
width: 150px;
}
.modal-label {
font-weight: 600;
color: #333;
}
.modal-value {
color: #444;
}
.modal-section-title {
font-size: 1.2rem;
font-weight: bold;
margin-top: 20px;
margin-bottom: 10px;
border-bottom: 2px solid #dee2e6;
padding-bottom: 5px;
}
.modal-title-big {
font-size: 20px;
font-weight: 700;
}
.modal-subtext {
color: #b4c5d3;
font-size: 13px;
}
.card-section {
background: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 25px;
border: 1px solid #eee;
}
.section-title {
font-weight: 700;
color: #333;
margin-bottom: 15px;
font-size: 16px;
}
.label-text {
font-size: 13px;
color: #6c757d;
}
.value-text {
font-size: 15px;
font-weight: 600;
color: #333;
}
.info-block {
display: flex;
flex-direction: column;
}
.badge-status {
background: #ffd9b3;
color: #a65c00;
padding: 6px 10px;
border-radius: 5px;
font-size: 13px;
}
.btn-big {
padding: 12px 25px;
border-radius: 8px;
width: 200px;
}
.rdo-box {
border: 1px solid #eee;
border-radius: 10px;
padding: 20px;
}
</style>
<body>
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header">
<div class="row align-items-end">
<div class="col-lg-6">
<div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline">
<h5>SWD Facilities Reports</h5>
<span>Reports</span>
</div>
</div>
</div>
<div class="col-lg-6">
<nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/swm/index"><i class="ik ik-home"></i></a>
</li>
<li class="breadcrumb-item" aria-current="page">SWD Facilities Reports</li>
<li class="breadcrumb-item active" aria-current="page">Reports</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card shadow-sm">
<!-- CARD HEADER -->
<div class="card-header d-flex justify-content-between align-items-center fw-bold">
<h3 class="mb-0"> SWD Facilities Reports : <span th:text="${officer_name}"></span>
</h3>
<input type="hidden" id="userName" th:value="${officer_name}">
</div>
<!-- FILTER SECTION -->
<!-- <div class="card-body pb-0">
<div class="row align-items-end g-3 mb-3">
<div class="col-md-3">
<label class="form-label">From Date</label>
<input type="date" id="fromDate" class="form-control">
</div>
<div class="col-md-3">
<label class="form-label">To Date</label>
<input type="date" id="toDate" class="form-control">
</div>
<div class="col-md-3">
<label class="form-label">date</label>
<input type="date" id="singleDate" class="form-control">
</div>
<div class="col-md-3">
<label class="form-label">Report type</label>
<select>
< </select>
<option></option>
<input type="date" id="singleDate" class="form-control">
</div>
<div class="col-md-3">
<button id="searchBtn" class="btn btn-primary w-100">
Search
</button>
</div>
</div>
</div> -->
<div class="card-body pb-0">
<div class="row align-items-end g-3 mb-3">
<!-- From Date -->
<div class="col-md-3 d-none" id="fromDateDiv">
<label class="form-label">From Date</label><span
class="text-danger">*</span>
<input type="date" id="fromDate" class="form-control">
</div>
<!-- To Date -->
<div class="col-md-3 d-none" id="toDateDiv">
<label class="form-label">To Date</label><span class="text-danger">*</span>
<input type="date" id="toDate" class="form-control">
</div>
<!-- Single Date -->
<div class="col-md-3 d-none" id="singleDateDiv">
<label class="form-label">Date</label> <span class="text-danger">*</span>
</label>
<input type="date" id="singleDate" class="form-control">
</div>
<!-- Report Type -->
<div class="col-md-3">
<label class="form-label">Report Type</label> <span
class="text-danger">*</span>
</label>
<select id="reportType" class="form-control">
<option value="">Select</option>
<option value="DAY">Day Wise</option>
<option value="MONTH">Month Wise/Date Range</option>
</select>
</div>
<!-- Search -->
<div class="col-md-3">
<button id="searchBtn" class="btn btn-primary w-100">
Search
</button>
</div>
</div>
</div>
<!-- TABLE SECTION -->
<div class="card-body pt-0">
<div class="table-responsive">
<!-- <table id="QaqcDatatable"
class="table table-striped table-bordered table-hover dataTable"
role="grid">
<thead class="thead-dark">
<tr role="row">
<th class="text-center">S.No</th>
<th class="text-center no-sort">Zone Name</th>
<th class="text-center no-sort">MCC (%)</th>
<th class="text-center no-sort">Windrow (%)</th>
<th class="text-center no-sort">BioCng (%)</th>
<th class="text-center no-sort">Horticulture (%)</th>
<th class="text-center no-sort">Incinerator (%)</th>
<th class="text-center no-sort">Baling center (%)</th>
</tr>
</thead>
<tbody> </tbody>
</table> -->
<table id="QaqcDatatable"
class="table table-striped table-bordered table-hover dataTable"
width="100%">
<thead class="thead-dark">
<!-- ROW 1 : MAIN GROUP HEADERS -->
<!-- <tr class="text-center">
<th colspan="23" class="text-center">Average month wise report</th>
</tr> -->
<tr class="text-center">
<th rowspan="2">S.No</th>
<th rowspan="2">Zone</th>
<th colspan="3">MCC</th>
<th colspan="3">Windrow</th>
<th colspan="3">Bio-CNG</th>
<th colspan="3">Bio-GAS</th>
<th colspan="3">Horticulture</th>
<th colspan="3">Incinerator</th>
<th colspan="3">Plasting Baling Centre</th>
</tr>
<!-- ROW 2 : SUB HEADERS -->
<tr class="text-center">
<th>Target</th>
<th>Achieved</th>
<th>%</th>
<th>Target</th>
<th>Achieved</th>
<th>%</th>
<th>Target</th>
<th>Achieved</th>
<th>%</th>
<th>Target</th>
<th>Achieved</th>
<th>%</th>
<th>Target</th>
<th>Achieved</th>
<th>%</th>
<th>Target</th>
<th>Achieved</th>
<th>%</th>
<th>Target</th>
<th>Achieved</th>
<th>%</th>
</tr>
</thead>
<tfoot>
<tr class="text-center fw-bold">
<th colspan="2">TOTAL</th>
<th></th>
<th></th>
<th></th> <!-- MCC -->
<th></th>
<th></th>
<th></th> <!-- Windrow -->
<th></th>
<th></th>
<th></th> <!-- Bio-CNG -->
<th></th>
<th></th>
<th></th> <!-- Bio-GAS -->
<th></th>
<th></th>
<th></th> <!-- Horticulture / GW&TC -->
<th></th>
<th></th>
<th></th> <!-- Incinerator -->
<th></th>
<th></th>
<th></th> <!-- Plastic Baling -->
</tr>
</tfoot>
<tbody></tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" style="background:#2f3e54; color:white;">
<div>
<h4 class="modal-title-big" id="modalTitle"></h4>
<div id="modalSubTitle" class="modal-subtext"></div>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div id="modalContent"></div>
<div class="text-center mt-4">
<button type="button" class="btn btn-primary btn-big" data-dismiss="modal"
style="background:#2f3e54;">Close</button>
</div>
</div>
</div>
</div>
</div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script type="text/javascript">
let table;
$(document).ready(function () {
table = $('#QaqcDatatable').DataTable({
data: [],
ordering: false,
searching: true,
info: true,
paging: true,
pageLength: 15, // show 15 rows
lengthMenu: [15, 25, 50, 100], // optional dropdown
scrollX: true,
responsive: false,
dom: 'Bftip',
buttons: [
/* ===================== EXCEL (SIMPLE & SAFE) ===================== */
{
extend: 'excelHtml5',
text: 'Excel',
title: 'Gcc Swm Report',
filename: 'Gcc Swm Report',
exportOptions: {
format: {
header: function (data, columnIdx) {
const headers = [
'S.No',
'Zone',
'MCC Target',
'MCC Achieved',
'MCC %',
'Windrow Target',
'Windrow Achieved',
'Windrow %',
'Bio-CNG Target',
'Bio-CNG Achieved',
'Bio-CNG %',
'Bio-GAS Target',
'Bio-GAS Achieved',
'Bio-GAS %',
'Incinerator Target',
'Incinerator Achieved',
'Incinerator %',
'GW & TC Waste Target',
'GW & TC Waste Achieved',
'GW & TC Waste %',
'Plasting Baling Centre Target',
'Plasting Baling Centre Achieved',
'Plasting Baling Centre %'
];
return headers[columnIdx];
}
}
},
customize: function (xlsx) {
const sheet = xlsx.xl.worksheets['sheet1.xml'];
const api = $('#QaqcDatatable').DataTable();
// Helper to get footer text safely
function footerVal(colIdx) {
const footer = api.column(colIdx).footer();
return footer ? footer.innerText.trim() : '0';
}
// Build TOTAL row (MUST match column order)
const totalRow = [
'TOTAL', '',
footerVal(2), footerVal(3), footerVal(4),
footerVal(5), footerVal(6), footerVal(7),
footerVal(8), footerVal(9), footerVal(10),
footerVal(11), footerVal(12), footerVal(13),
footerVal(14), footerVal(15), footerVal(16),
footerVal(17), footerVal(18), footerVal(19),
footerVal(20), footerVal(21), footerVal(22)
];
// Convert TOTAL row to Excel XML
let rowXml = '<row>';
totalRow.forEach(val => {
rowXml += `<c t="inlineStr"><is><t>${val}</t></is></c>`;
});
rowXml += '</row>';
// Append TOTAL row at the end of sheet
const sheetData = sheet.getElementsByTagName('sheetData')[0];
sheetData.innerHTML += rowXml;
}
},
/* ===================== PDF ===================== */
{
extend: 'pdfHtml5',
orientation: 'landscape',
pageSize: 'A3',
title: 'Gcc Swm Report'
},
/* ===================== CSV ===================== */
{
extend: 'csvHtml5',
text: 'CSV',
title: ''
}
],
columns: [
{ data: "sno" },
{ data: "zone" },
{ data: "MCC_target" },
{ data: "MCC_achieved" },
{ data: "MCC_percentage" },
{ data: "Windrow_target" },
{ data: "Windrow_achieved" },
{ data: "Windrow_percentage" },
{ data: "Bio-CNG_target" },
{ data: "Bio-CNG_achieved" },
{ data: "Bio-CNG_percentage" },
{ data: "Bio-GAS_target" },
{ data: "Bio-GAS_achieved" },
{ data: "Bio-GAS_percentage" },
{ data: "Incinerator_target" },
{ data: "Incinerator_achieved" },
{ data: "Incinerator_percentage" },
{ data: "GW & TC Waste_target" },
{ data: "GW & TC Waste_achieved" },
{ data: "GW & TC Waste_percentage" },
{ data: "Plasting Baling Centre_target" },
{ data: "Plasting Baling Centre_achieved" },
{ data: "Plasting Baling Centre_percentage" }
],
footerCallback: function () {
const api = this.api();
// Sum helper
function sum(colIdx) {
return api
.column(colIdx, { page: 'current' })
.data()
.reduce((a, b) => {
const x = parseFloat(a) || 0;
const y = parseFloat(b) || 0;
return x + y;
}, 0);
}
// Facility-wise column mapping
const facilities = [
{ target: 2, achieved: 3, percent: 4 }, // MCC
{ target: 5, achieved: 6, percent: 7 }, // Windrow
{ target: 8, achieved: 9, percent: 10 }, // Bio-CNG
{ target: 11, achieved: 12, percent: 13 },// Bio-GAS
{ target: 14, achieved: 15, percent: 16 },// GW & TC Waste
{ target: 17, achieved: 18, percent: 19 },// Incinerator
{ target: 20, achieved: 21, percent: 22 } // Plastic Baling Centre
];
facilities.forEach(f => {
const totalTarget = sum(f.target);
const totalAchieved = sum(f.achieved);
// Write totals
$(api.column(f.target).footer()).html(totalTarget.toFixed(2));
$(api.column(f.achieved).footer()).html(totalAchieved.toFixed(2));
// Percentage calculation
let percent = 0;
if (totalTarget > 0) {
percent = (totalAchieved / totalTarget) * 100;
}
$(api.column(f.percent).footer()).html(percent.toFixed(2) + '%');
});
}
});
$("#searchBtn").on("click", loadReport);
});
$(document).ready(function () {
$("#reportType").on("change", function () {
const type = $(this).val();
// Hide all first
$("#singleDateDiv").addClass("d-none");
$("#fromDateDiv, #toDateDiv").addClass("d-none");
// Clear values
$("#singleDate, #fromDate, #toDate").val("");
if (type === "DAY") {
// Day wise → show single date
$("#singleDateDiv").removeClass("d-none");
}
else if (type === "MONTH") {
// Month wise → show from & to date
$("#fromDateDiv, #toDateDiv").removeClass("d-none");
}
});
});
// function loadReport() {
// const fromDate = $("#fromDate").val();
// const toDate = $("#toDate").val();
// if (!fromDate || !toDate) {
// Swal.fire("Validation Error", "Please select both dates", "warning");
// return;
// }
// $.ajax({
// url: "/swm/api/admin/reports",
// type: "GET",
// data: { fromDate, toDate },
// beforeSend: function () {
// Swal.fire({
// title: "Loading...",
// allowOutsideClick: false,
// didOpen: () => Swal.showLoading()
// });
// },
// success: function (res) {
// Swal.close();
// renderZoneTable(res.data);
// },
// error: function () {
// Swal.fire("Error", "Failed to load report", "error");
// }
// });
// }
function getDateDiffInDays(fromDate, toDate) {
const start = new Date(fromDate);
const end = new Date(toDate);
// +1 because inclusive (01 to 10 = 10 days)
return Math.floor((end - start) / (1000 * 60 * 60 * 24)) + 1;
}
// function renderZoneTableMonthWise(data, fromDate, toDate) {
// const zoneMap = {};
// const dayCount = getDateDiffInDays(fromDate, toDate);
// data.forEach(row => {
// const z = row.zone;
// const f = row.facility;
// if (!zoneMap[z]) {
// zoneMap[z] = { zone: z };
// }
// const dailyTarget = Number(row.target || 0);
// const totalAchieved = Number(row.achieved || 0);
// // Overall target for selected date range
// const overallTarget = dailyTarget * dayCount;
// // Raw percentage
// let percent = 0;
// if (overallTarget > 0) {
// percent = (totalAchieved / overallTarget) * 100;
// }
// // ✅ CAP percentage to max 100
// percent = Math.min(percent, 100);
// // Store values (2 decimal places)
// zoneMap[z][f + "_target"] = overallTarget.toFixed(2);
// zoneMap[z][f + "_achieved"] = totalAchieved.toFixed(2);
// zoneMap[z][f + "_percentage"] = percent.toFixed(2) + "%";
// });
// let i = 1;
// const tableData = Object.values(zoneMap).map(r => ({
// sno: i++,
// ...r
// }));
// table.clear().rows.add(tableData).draw();
// }
function renderZoneTableMonthWise(data, fromDate, toDate) {
const zoneMap = {};
const dayCount = getDateDiffInDays(fromDate, toDate);
data.forEach(row => {
const z = row.zone;
const f = row.facility;
if (!zoneMap[z]) {
zoneMap[z] = { zone: z };
}
const dailyTarget = Number(row.target || 0);
const perDayAchieved = Number(row.achieved || 0);
// 🔹 INTERNAL TOTALS (as per your explanation)
const totalTarget = dailyTarget * dayCount;
const totalAchieved = perDayAchieved * dayCount;
// 🔹 AVERAGES SHOWN IN TABLE
const avgTarget =
dayCount > 0 ? (totalTarget / dayCount) : 0;
const avgAchieved =
dayCount > 0 ? (totalAchieved / dayCount) : 0;
// 🔹 PERCENTAGE (based on averages)
let percent = 0;
if (avgTarget > 0) {
percent = (avgAchieved / avgTarget) * 100;
}
// 🔹 Cap at 100%
percent = Math.min(percent, 100);
// 🔹 Store values (2 decimals)
zoneMap[z][f + "_target"] = avgTarget.toFixed(2);
zoneMap[z][f + "_achieved"] = avgAchieved.toFixed(2);
zoneMap[z][f + "_percentage"] = percent.toFixed(2) + "%";
});
let i = 1;
const tableData = Object.values(zoneMap).map(r => ({
sno: i++,
...r
}));
table.clear().rows.add(tableData).draw();
}
function loadReport() {
const reportType = $("#reportType").val();
if (!reportType) {
Swal.fire("Validation Error", "Please select Report Type", "warning");
return;
}
let url = "";
let data = {};
// ================= DAY WISE =================
if (reportType === "DAY") {
const singleDate = $("#singleDate").val();
if (!singleDate) {
Swal.fire("Validation Error", "Please select Date", "warning");
return;
}
url = "/swm/api/admin/singledayreports";
data = { Date: singleDate };
}
// ================= MONTH / DATE RANGE =================
else if (reportType === "MONTH") {
const fromDate = $("#fromDate").val();
const toDate = $("#toDate").val();
if (!fromDate || !toDate) {
Swal.fire("Validation Error", "Please select From & To Date", "warning");
return;
}
url = "/swm/api/admin/reports";
data = { fromDate, toDate };
}
$.ajax({
url: url,
type: "GET",
data: data,
beforeSend: function () {
Swal.fire({
title: "Loading...",
allowOutsideClick: false,
didOpen: () => Swal.showLoading()
});
},
success: function (res) {
Swal.close();
// ✅ SEPARATE RENDERING BASED ON REPORT TYPE
if (reportType === "MONTH") {
renderZoneTableMonthWise(
res.data,
$("#fromDate").val(),
$("#toDate").val()
);
} else {
renderZoneTable(res.data); // DAY wise (existing)
}
},
error: function () {
Swal.fire("Error", "Failed to load report", "error");
}
});
}
function renderZoneTable(data) {
const zoneMap = {};
data.forEach(row => {
const z = row.zone;
const f = row.facility;
if (!zoneMap[z]) zoneMap[z] = { zone: z };
zoneMap[z][f + "_target"] = row.target ?? 0;
zoneMap[z][f + "_achieved"] = row.achieved ?? 0;
zoneMap[z][f + "_percentage"] =
row.percentage != null ? row.percentage + "%" : "0%";
});
let i = 1;
const tableData = Object.values(zoneMap).map(r => ({
sno: i++,
...r
}));
table.clear().rows.add(tableData).draw();
}
// function renderZoneTable(data) {
// const zoneMap = {};
// data.forEach(row => {
// const z = row.zone;
// const f = row.facility;
// if (!zoneMap[z]) {
// zoneMap[z] = { zone: z };
// }
// // Create facility bucket
// if (!zoneMap[z][f]) {
// zoneMap[z][f] = {
// dailyTarget: 0,
// totalAchieved: 0,
// dayCount: 0
// };
// }
// const fac = zoneMap[z][f];
// // DAILY target from API
// fac.dailyTarget = Number(row.target || 0);
// // EACH ROW = ONE DAY
// fac.dayCount += 1;
// // SUM achieved
// fac.totalAchieved += Number(row.achieved || 0);
// });
// let i = 1;
// const tableData = [];
// Object.values(zoneMap).forEach(z => {
// const row = {
// sno: i++,
// zone: z.zone
// };
// Object.keys(z).forEach(f => {
// if (f === "zone") return;
// const fac = z[f];
// // ✅ MONTH TARGET = daily target × no of days
// const totalTarget = fac.dailyTarget * fac.dayCount;
// const percent =
// totalTarget > 0
// ? ((fac.totalAchieved / totalTarget) * 100).toFixed(2)
// : "0.00";
// row[f + "_target"] = totalTarget.toFixed(2);
// row[f + "_achieved"] = fac.totalAchieved.toFixed(2);
// row[f + "_percentage"] = percent + "%";
// });
// tableData.push(row);
// });
// table.clear().rows.add(tableData).draw();
// }
</script>
</body>
</html>

442
src/main/resources/templates/modules/swm/requestlist.html

@ -1,442 +0,0 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>
.width1 {
width: 120px;
}
.width2 {
width: 150px;
}
.modal-label {
font-weight: 600;
color: #333;
}
.modal-value {
color: #444;
}
.modal-section-title {
font-size: 1.2rem;
font-weight: bold;
margin-top: 20px;
margin-bottom: 10px;
border-bottom: 2px solid #dee2e6;
padding-bottom: 5px;
}
.modal-title-big {
font-size: 20px;
font-weight: 700;
}
.modal-subtext {
color: #b4c5d3;
font-size: 13px;
}
.card-section {
background: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 25px;
border: 1px solid #eee;
}
.section-title {
font-weight: 700;
color: #333;
margin-bottom: 15px;
font-size: 16px;
}
.label-text {
font-size: 13px;
color: #6c757d;
}
.value-text {
font-size: 15px;
font-weight: 600;
color: #333;
}
.info-block {
display: flex;
flex-direction: column;
}
.badge-status {
background: #ffd9b3;
color: #a65c00;
padding: 6px 10px;
border-radius: 5px;
font-size: 13px;
}
.btn-big {
padding: 12px 25px;
border-radius: 8px;
width: 200px;
}
.rdo-box {
border: 1px solid #eee;
border-radius: 10px;
padding: 20px;
}
</style>
<body th:data-two-weight="${isTwoWeightFacility}" th:data-weight-type="${isWeightTypeFacility}">
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header">
<div class="row align-items-end">
<div class="col-lg-6">
<div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline">
<h5>SWD Facilities Add Details List</h5>
<span>Add Details</span>
</div>
</div>
</div>
<div class="col-lg-6">
<nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/swm/index"><i class="ik ik-home"></i></a>
</li>
<li class="breadcrumb-item" aria-current="page">SWD Facilities Add Details List
</li>
<li class="breadcrumb-item active" aria-current="page">Add Details</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center fw-bold">
<h3 class="mb-0"> SWM Add Details : <span th:text="${officer_name}"></span></h3>
<input type="hidden" id="userName" th:value="${officer_name}">
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3">
<label for="date" class="form-label"
style="font-size: medium;">Date:</label><span
class="text-danger">*</span>
<input type="date" id="date" class="form-control">
</div>
<div class="col-md-3">
<label for="zones" class="form-label">Zones <span
class="text-danger">*</span>
</label>
<select id="zones" class="form-control">
<option value="">Select days</option>
</select>
</div>
<input type="hidden" id="facilityTypeId" th:value="${facilityTypeId}">
<div class="col-md-3">
<label for="weight" class="form-label">Enter Weight(in MT):</label><span
class="text-danger">*</span>
<input type="number" class="form-control" id="weight">
</div>
<!-- SECOND WEIGHT (TC) -->
<div class="col-md-3" id="weight2Div" style="display:none;">
<label for="weight1" class="form-label">Enter Weight(Tender
Coconut):</label><span class="text-danger">*</span>
<input type="number" class="form-control" id="weight1">
</div>
<div class="col-md-3" id="facilityTypeDiv" style="display:none;">
<label for="facilitytype" class="form-label">
Location <span class="text-danger">*</span>
</label>
<select id="facilitytype" class="form-control">
<option value="">Select location</option>
<option value="KDG">KDG</option>
<option value="PDG">PDG</option>
</select>
</div>
<div class="col-md-3" style="margin-top: 30px;">
<button id="submitBtn" class="btn btn-primary">Submit</button>
<button id="resetBtn" class="btn btn-secondary">Reset</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" style="background:#2f3e54; color:white;">
<div>
<h4 class="modal-title-big" id="modalTitle"></h4>
<div id="modalSubTitle" class="modal-subtext"></div>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div id="modalContent"></div>
<div class="text-center mt-4">
<button type="button" class="btn btn-primary btn-big" data-dismiss="modal"
style="background:#2f3e54;">Close</button>
</div>
</div>
</div>
</div>
</div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script type="text/javascript">
$(document).ready(function () {
const isTwoWeightFacility =
$("body").data("two-weight") === true ||
$("body").data("two-weight") === "true";
const isWeightTypeFacility =
$("body").data("weight-type") === true ||
$("body").data("weight-type") === "true";
// GW & TC + PBC / C&D → show KDG / PDG
if (isTwoWeightFacility) {
$("#weight2Div").show();
$("#weightTypeDiv").show();
} else {
$("#weight2Div").hide();
$("#weightTypeDiv").hide();
$("#weight1").val("");
$("#facilitytype").val("");
}
if (isWeightTypeFacility) {
$("#facilityTypeDiv").show();
} else {
$("#facilityTypeDiv").hide();
$("#facilitytype").val("");
}
});
//$(document).ready(function () {
// const today = new Date().toISOString().split('T')[0];
//$("#date").val(today);
//});
$(document).ready(function () {
const today = new Date();
const yyyyMmDd = today.toISOString().split('T')[0];
const yesterday = new Date();
yesterday.setDate(today.getDate() - 1);
const yyyMmDdYesterday = yesterday.toISOString().split('T')[0];
const $date = $("#date");
// set default date
$date.val(yyyyMmDd);
// allow only yesterday and today
$date.attr("min", yyyMmDdYesterday);
$date.attr("max", yyyyMmDd);
// 🚫 block manual typing & paste
$date.on("keydown paste", function (e) {
e.preventDefault();
});
});
$("#resetBtn").on("click", function () {
location.reload();
});
// Load zones when page loads
$(document).ready(function () {
$.ajax({
url: "/swm/api/dropdown/getzoneslist",
type: "GET",
dataType: "json",
success: function (data) {
let zoneDropdown = $("#zones");
zoneDropdown.empty();
zoneDropdown.append("<option value=''>Select Zone</option>");
$.each(data, function (index, item) {
zoneDropdown.append(
`<option value="${item.id}">${item.zone_name}</option>`
);
});
},
error: function (xhr, status, error) {
console.error("Error fetching zones:", error);
}
});
});
$("#submitBtn").on("click", function (e) {
e.preventDefault();
const zoneId = $("#zones").val();
const reqDate = $("#date").val();
const weight = $("#weight").val();
const weight1 = $("#weight1").val();
const weightType = $("#facilitytype").val();
const facilityTypeId = $("#facilityTypeId").val();
// 🔴 Client-side validations
if (!zoneId) {
Swal.fire("Validation Error", "Please select zone", "warning");
return;
}
if (!reqDate) {
Swal.fire("Validation Error", "Date is required", "warning");
return;
}
if (weight == null || weight == "") {
Swal.fire("Validation Error", "Weight is required", "warning");
return;
}
if (facilityTypeId == 5) {
if (weight < 0) {
Swal.fire("Validation Error", "Weight cannot be negative", "warning");
return;
}
} else {
if (weight <= 0) {
Swal.fire("Validation Error", "Weight must be greater than zero", "warning");
return;
}
}
// ⚠️ Note:
// Facility type 5 validation is done in BACKEND
// because facilityTypeId is derived after login
$.ajax({
url: "/swm/api/facilities/addfacility",
type: "POST",
data: {
zoneId: zoneId,
reqDate: reqDate,
weight: weight,
weight1: weight1, // backend will ignore if not needed
weightType: weightType
},
beforeSend: function () {
Swal.fire({
title: "Saving...",
text: "Please wait",
allowOutsideClick: false,
didOpen: () => Swal.showLoading()
});
},
success: function (response) {
Swal.fire("Success", response.message, "success");
// Reset fields
$("#weight").val("");
$("#weight1").val("");
},
error: function (xhr) {
let msg = "Something went wrong";
if (xhr.responseJSON && xhr.responseJSON.message) {
msg = xhr.responseJSON.message;
}
Swal.fire("Error", msg, "error");
}
});
});
</script>
</body>
</html>

419
src/main/resources/templates/modules/swm/windrow.html

@ -1,419 +0,0 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>
.width1 {
width: 120px;
}
.width2 {
width: 150px;
}
.modal-label {
font-weight: 600;
color: #333;
}
.modal-value {
color: #444;
}
.modal-section-title {
font-size: 1.2rem;
font-weight: bold;
margin-top: 20px;
margin-bottom: 10px;
border-bottom: 2px solid #dee2e6;
padding-bottom: 5px;
}
.modal-title-big {
font-size: 20px;
font-weight: 700;
}
.modal-subtext {
color: #b4c5d3;
font-size: 13px;
}
.card-section {
background: white;
border-radius: 10px;
padding: 20px;
margin-bottom: 25px;
border: 1px solid #eee;
}
.section-title {
font-weight: 700;
color: #333;
margin-bottom: 15px;
font-size: 16px;
}
.label-text {
font-size: 13px;
color: #6c757d;
}
.value-text {
font-size: 15px;
font-weight: 600;
color: #333;
}
.info-block {
display: flex;
flex-direction: column;
}
.badge-status {
background: #ffd9b3;
color: #a65c00;
padding: 6px 10px;
border-radius: 5px;
font-size: 13px;
}
.btn-big {
padding: 12px 25px;
border-radius: 8px;
width: 200px;
}
.rdo-box {
border: 1px solid #eee;
border-radius: 10px;
padding: 20px;
}
</style>
<body th:attr="data-two-weight=${isTwoWeightFacility}">
<div class="wrapper">
<!-- header top menu Start -->
<header th:replace="~{fragments/modules/base/header :: header}"></header>
<!-- header top menu end -->
<div class="page-wrap">
<!--=============== Left Menu side Start ================-->
<div th:replace="~{fragments/modules/base/menu :: menu}"></div>
<!--=============== Left side End ================-->
<div class="main-content">
<div class="container-fluid">
<div class="page-header">
<div class="row align-items-end">
<div class="col-lg-6">
<div class="page-header-title">
<i class="fa fa-list-alt bg-blue"></i>
<div class="d-inline">
<h5>SWD Windrow Facilities Add Details List</h5>
<span>Windrow Add Details</span>
</div>
</div>
</div>
<div class="col-lg-6">
<nav class="breadcrumb-container" aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/swm/index"><i class="ik ik-home"></i></a>
</li>
<li class="breadcrumb-item" aria-current="page">SWD Windrow Facilities Add
Details List
</li>
<li class="breadcrumb-item active" aria-current="page">Windrow Add Details</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-md-12">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center fw-bold">
<h3 class="mb-0"> SWM Windrow Add Details : <span th:text="${officer_name}"></span>
</h3>
<input type="hidden" id="userName" th:value="${officer_name}">
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3">
<label for="date" class="form-label"
style="font-size: medium;">Date:</label><span
class="text-danger">*</span>
<input type="date" id="date" class="form-control">
</div>
<div class="col-md-3">
<label for="zones" class="form-label">Zones <span
class="text-danger">*</span>
</label> <select id="zones" class="form-control">
<option value="">Select zones</option>
</select>
</div>
<div class="col-md-3">
<label for="weight" class="form-label">Enter Weight:(in MT)</label><span
class="text-danger">*</span>
<input type="number" class="form-control" id="weight">
</div>
<input type="hidden" id="facilityTypeId" th:value="${facilityTypeId}">
<!-- SECOND WEIGHT (TC) -->
<div class="col-md-3" id="weight2Div" style="display:none;">
<label for="weight1">Enter Weight (TC)</label><span
class="text-danger">*</span>
<input type="number" class="form-control" id="weight1">
</div>
<div class="col-md-3" style="margin-top: 30px;">
<button id="submitBtn" class="btn btn-primary">Submit</button>
<button id="resetBtn" class="btn btn-secondary">Reset</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="pageLoader"
style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 9999; text-align: center;">
<div style="position: relative; top: 50%; transform: translateY(-50%);">
<div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>
<!-- Add the 'Please wait' text below the spinner -->
<p style="margin-top: 1rem; font-size: 1.2rem; color: #007bff;">Please wait...</p>
</div>
</div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
</div>
</div>
<!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" style="background:#2f3e54; color:white;">
<div>
<h4 class="modal-title-big" id="modalTitle"></h4>
<div id="modalSubTitle" class="modal-subtext"></div>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="modal-body">
<div id="modalContent"></div>
<div class="text-center mt-4">
<button type="button" class="btn btn-primary btn-big" data-dismiss="modal"
style="background:#2f3e54;">Close</button>
</div>
</div>
</div>
</div>
</div>
<script th:replace="~{fragments/modules/base/script :: script}"></script>
<script type="text/javascript">
$(document).ready(function () {
const today = new Date();
const day = today.getDay(); // 0=Sun, 1=Mon, ..., 6=Sat
/* =============================
LAST SATURDAY
============================= */
const lastSaturday = new Date(today);
// If today is Saturday (6) → today
// Else → go back to previous Saturday
const diffToLastSaturday = (day >= 6)
? day - 6
: day + 1;
lastSaturday.setDate(today.getDate() - diffToLastSaturday);
/* =============================
THIS WEEK FRIDAY
============================= */
const thisFriday = new Date(today);
// Friday = 5
const diffToFriday = (5 - day + 7) % 7;
thisFriday.setDate(today.getDate() + diffToFriday);
/* =============================
FORMAT YYYY-MM-DD
============================= */
const formatDate = (d) => d.toISOString().split("T")[0];
const minDate = formatDate(lastSaturday);
const maxDate = formatDate(thisFriday);
/* =============================
APPLY LIMITS
============================= */
$("#date")
.attr("min", minDate)
.attr("max", maxDate)
.val(formatDate(today));
// 🔒 BLOCK MANUAL TYPING (BUT ALLOW CALENDAR)
$("#date").on("keydown paste", function (e) {
e.preventDefault();
});
});
$(document).ready(function () {
const isTwoWeightFacility =
$("body").data("two-weight") === true ||
$("body").data("two-weight") === "true";
console.log($("body").data("two-weight"));
if (isTwoWeightFacility) {
$("#weight2Div").show();
} else {
$("#weight2Div").hide();
$("#weight1").val("");
}
});
$(document).ready(function () {
const today = new Date().toISOString().split('T')[0];
$("#date").val(today);
});
$("#resetBtn").on("click", function () {
location.reload();
});
// Load zones when page loads
$(document).ready(function () {
$.ajax({
url: "/swm/api/dropdown/getzoneslist",
type: "GET",
dataType: "json",
success: function (data) {
let zoneDropdown = $("#zones");
zoneDropdown.empty();
zoneDropdown.append("<option value=''>Select Zone</option>");
$.each(data, function (index, item) {
zoneDropdown.append(
`<option value="${item.id}">${item.zone_name}</option>`
);
});
},
error: function (xhr, status, error) {
console.error("Error fetching zones:", error);
}
});
});
$("#submitBtn").on("click", function (e) {
e.preventDefault();
const facilityTypeId = $("#facilityTypeId").val(); // ✅ dynamic
const zoneId = $("#zones").val();
const reqDate = $("#date").val();
const weight = $("#weight").val();
const weight1 = $("#weight1").val();
const createdBy = $("#userName").val();
// 🔴 Client-side validations
if (!zoneId) {
Swal.fire("Validation Error", "Please select zone", "warning");
return;
}
if (!reqDate) {
Swal.fire("Validation Error", "Date is required", "warning");
return;
}
if (!weight || weight <= 0) {
Swal.fire("Validation Error", "Weight must be greater than zero", "warning");
return;
}
// ⚠️ Note:
// Facility type 5 validation is done in BACKEND
// because facilityTypeId is derived after login
$.ajax({
url: "/swm/api/admin/addfacility",
type: "POST",
data: {
facilityTypeId: facilityTypeId,
zoneId: zoneId,
reqDate: reqDate,
weight: weight,
weight1: weight1,
createdBy: createdBy // backend will ignore if not needed
},
beforeSend: function () {
Swal.fire({
title: "Saving...",
text: "Please wait",
allowOutsideClick: false,
didOpen: () => Swal.showLoading()
});
},
success: function (response) {
Swal.fire("Success", response.message, "success");
// Reset fields
$("#weight").val("");
$("#weight1").val("");
},
error: function (xhr) {
let msg = "Something went wrong";
if (xhr.responseJSON && xhr.responseJSON.message) {
msg = xhr.responseJSON.message;
}
Swal.fire("Error", msg, "error");
}
});
});
</script>
</body>
</html>
Loading…
Cancel
Save