From 195f8f9e4cc6f31933dc83f7a8958eee40ad4c42 Mon Sep 17 00:00:00 2001 From: lakshmikommalapati <lakshmi.kommalapati@tarento.com> Date: Thu, 27 Jul 2023 11:31:13 +0530 Subject: [PATCH] initial commit for grievance --- Dockerfile | 7 + Jenkinsfile | 4 + pom.xml | 291 +++ public/emails/add-admin-aurora.vm | 318 ++++ public/emails/add-helpdeskadmin-aurora.vm | 318 ++++ public/emails/copied-to-ticket-aurora.vm | 331 ++++ public/emails/email_template.vm | 444 +++++ public/emails/forgot-password.vm | 330 ++++ public/emails/new-ticket-createdby-aurora.vm | 331 ++++ .../emails/remove-copied-to-ticket-aurora.vm | 333 ++++ public/emails/remove_admin.vm | 316 ++++ public/emails/remove_helpdeskadmin.vm | 316 ++++ public/emails/ticket-status-update-aurora.vm | 331 ++++ public/images/9_IMG_5920.jpg | Bin 0 -> 68620 bytes .../java/org/upsmf/grievance/Application.java | 67 + .../upsmf/grievance/config/CORSFilter.java | 46 + .../config/JwtAuthenticationEntryPoint.java | 31 + .../config/JwtAuthenticationFilter.java | 152 ++ .../upsmf/grievance/config/JwtTokenUtil.java | 109 ++ .../grievance/config/MyCustomJwtClaims.java | 32 + .../upsmf/grievance/config/SwaggerConfig.java | 1 + .../grievance/config/WebSecurityConfig.java | 63 + .../constants/RequestContextConstants.java | 25 + .../grievance/constants/package-info.java | 8 + .../controller/ApplicationController.java | 132 ++ .../ControllerRequestValidator.java | 149 ++ .../controller/HelpdeskController.java | 170 ++ .../controller/RoleActionController.java | 123 ++ .../controller/SuperAdminController.java | 140 ++ .../grievance/controller/TagController.java | 79 + .../controller/TicketController.java | 319 ++++ .../grievance/controller/UserController.java | 194 ++ .../upsmf/grievance/dao/ApplicationDao.java | 64 + .../org/upsmf/grievance/dao/HelpdeskDao.java | 66 + .../java/org/upsmf/grievance/dao/RoleDao.java | 51 + .../upsmf/grievance/dao/SuperAdminDao.java | 38 + .../java/org/upsmf/grievance/dao/TagDao.java | 21 + .../org/upsmf/grievance/dao/TicketDao.java | 84 + .../java/org/upsmf/grievance/dao/UserDao.java | 188 ++ .../dao/impl/ApplicationDaoImpl.java | 238 +++ .../grievance/dao/impl/HelpdeskDaoImpl.java | 485 +++++ .../upsmf/grievance/dao/impl/RoleDaoImpl.java | 204 +++ .../grievance/dao/impl/SuperAdminDaoImpl.java | 391 ++++ .../upsmf/grievance/dao/impl/TagDaoImpl.java | 139 ++ .../grievance/dao/impl/TicketDaoImpl.java | 1595 +++++++++++++++++ .../upsmf/grievance/dao/impl/UserDaoImpl.java | 912 ++++++++++ .../grievance/dto/ChangePasswordDto.java | 54 + .../org/upsmf/grievance/dto/HelpdeskDto.java | 44 + .../upsmf/grievance/dto/HelpdeskTypeDto.java | 25 + .../grievance/dto/HelpdeskWorkflowDto.java | 19 + .../org/upsmf/grievance/dto/LoginDto.java | 48 + .../upsmf/grievance/dto/OrgUserRoleDto.java | 52 + .../org/upsmf/grievance/dto/TicketTagDto.java | 74 + .../upsmf/grievance/dto/TicketTypeDto.java | 35 + .../grievance/dto/TicketWorkflowDto.java | 22 + .../java/org/upsmf/grievance/dto/UserDto.java | 144 ++ .../upsmf/grievance/dto/UserProfileDto.java | 49 + .../org/upsmf/grievance/dto/UserRoleDto.java | 34 + .../grievance/exceptions/RbacException.java | 188 ++ .../RequestDataMissingException.java | 34 + .../grievance/exceptions/package-info.java | 8 + .../grievance/executor/MasterDataManager.java | 513 ++++++ .../TicketsRequestInterceptor.java | 498 +++++ .../grievance/interceptor/package-info.java | 8 + .../org/upsmf/grievance/model/Access.java | 25 + .../upsmf/grievance/model/AccessResponse.java | 22 + .../org/upsmf/grievance/model/Action.java | 24 + .../org/upsmf/grievance/model/ActionRole.java | 20 + .../upsmf/grievance/model/ActivityLog.java | 29 + .../org/upsmf/grievance/model/Analytics.java | 22 + .../java/org/upsmf/grievance/model/App.java | 35 + .../upsmf/grievance/model/ChecklistItem.java | 21 + .../org/upsmf/grievance/model/Comment.java | 20 + .../grievance/model/CommonDataModel.java | 79 + .../grievance/model/DeveloperComment.java | 21 + .../upsmf/grievance/model/DeviceMetadata.java | 30 + .../upsmf/grievance/model/HelpDeskApp.java | 21 + .../org/upsmf/grievance/model/Helpdesk.java | 67 + .../upsmf/grievance/model/HelpdeskType.java | 21 + .../grievance/model/HelpdeskWorkflow.java | 22 + .../org/upsmf/grievance/model/KeyFactory.java | 18 + .../upsmf/grievance/model/LastModified.java | 19 + .../org/upsmf/grievance/model/LoginUser.java | 21 + .../org/upsmf/grievance/model/MasterData.java | 20 + .../upsmf/grievance/model/Organization.java | 34 + .../upsmf/grievance/model/ReplyToReviews.java | 19 + .../java/org/upsmf/grievance/model/Rev.java | 19 + .../org/upsmf/grievance/model/Review.java | 23 + .../java/org/upsmf/grievance/model/Role.java | 18 + .../org/upsmf/grievance/model/RolesDto.java | 22 + .../org/upsmf/grievance/model/S3Config.java | 46 + .../upsmf/grievance/model/ServiceRequest.java | 20 + .../upsmf/grievance/model/StatusIdMap.java | 26 + .../java/org/upsmf/grievance/model/Tags.java | 21 + .../java/org/upsmf/grievance/model/Task.java | 20 + .../org/upsmf/grievance/model/Template.java | 22 + .../grievance/model/TemplateVersion.java | 20 + .../org/upsmf/grievance/model/Ticket.java | 82 + .../upsmf/grievance/model/TicketCount.java | 23 + .../upsmf/grievance/model/TicketElastic.java | 31 + .../org/upsmf/grievance/model/TicketTags.java | 24 + .../grievance/model/TicketsTagsList.java | 20 + .../org/upsmf/grievance/model/Updates.java | 24 + .../java/org/upsmf/grievance/model/User.java | 77 + .../grievance/model/UserAuthentication.java | 21 + .../upsmf/grievance/model/UserComment.java | 29 + .../grievance/model/UserIdAndUserName.java | 20 + .../org/upsmf/grievance/model/UserRole.java | 21 + .../grievance/model/contract/RequestInfo.java | 44 + .../model/contract/RoleActionRequest.java | 45 + .../contract/RoleActionResponseInfo.java | 26 + .../grievance/model/contract/RoleRequest.java | 39 + .../grievance/model/contract/StatusInfo.java | 30 + .../model/contract/UserGetRequest.java | 23 + .../grievance/model/enums/AuthTypes.java | 34 + .../grievance/model/enums/PriorityLevels.java | 34 + .../grievance/model/mapper/SqlDataMapper.java | 576 ++++++ .../repository/ElasticSearchRepository.java | 95 + .../grievance/service/ApplicationService.java | 53 + .../grievance/service/HelpdeskService.java | 45 + .../grievance/service/RoleActionService.java | 61 + .../grievance/service/SuperAdminService.java | 34 + .../upsmf/grievance/service/TagService.java | 19 + .../grievance/service/TicketService.java | 82 + .../upsmf/grievance/service/UserService.java | 147 ++ .../service/impl/ApplicationServiceImpl.java | 69 + .../service/impl/HelpdeskServiceImpl.java | 213 +++ .../service/impl/RoleActionServiceImpl.java | 62 + .../service/impl/SuperAdminServiceImpl.java | 102 ++ .../service/impl/TagServiceImpl.java | 53 + .../service/impl/TicketServiceImpl.java | 262 +++ .../service/impl/UserServiceImpl.java | 522 ++++++ .../org/upsmf/grievance/util/Constants.java | 342 ++++ .../upsmf/grievance/util/CustomException.java | 52 + .../grievance/util/CustomListResponse.java | 31 + .../upsmf/grievance/util/CustomResponse.java | 44 + .../upsmf/grievance/util/CustomSuccess.java | 102 ++ .../org/upsmf/grievance/util/DateUtil.java | 391 ++++ .../upsmf/grievance/util/ExecutorManager.java | 32 + .../grievance/util/GMailAuthenticator.java | 36 + .../upsmf/grievance/util/JSONObjectUtil.java | 57 + .../org/upsmf/grievance/util/JsonKey.java | 115 ++ .../upsmf/grievance/util/OneWayHashing.java | 40 + .../org/upsmf/grievance/util/PathRoutes.java | 158 ++ .../org/upsmf/grievance/util/ProjectUtil.java | 451 +++++ .../upsmf/grievance/util/ResponseCode.java | 84 + .../grievance/util/ResponseGenerator.java | 73 + .../grievance/util/ResponseMessages.java | 58 + .../upsmf/grievance/util/ResponseUtil.java | 95 + .../upsmf/grievance/util/S3FileManager.java | 77 + .../org/upsmf/grievance/util/SendMail.java | 209 +++ .../java/org/upsmf/grievance/util/Sql.java | 401 +++++ .../upsmf/grievance/util/SqlConstants.java | 86 + .../util/executor/FetchReviewsWeeklyJob.java | 33 + .../executor/ReviewsSchedulerManager.java | 38 + src/main/resources/accesstokenspec.json | 11 + src/main/resources/application.properties | 38 + src/main/resources/application.properties.j2 | 32 + src/main/resources/reviewspec.json | 43 + .../dao/impl/ApplicatioDaoImplTest.java | 292 +++ .../dao/impl/HelpdeskDaoImplTest.java | 281 +++ .../grievance/dao/impl/RoleDaoImplTest.java | 124 ++ .../dao/impl/SuperAdminDaoImplTest.java | 179 ++ .../grievance/dao/impl/TicketDaoImplTest.java | 337 ++++ .../grievance/dao/impl/UserDaoImplTest.java | 529 ++++++ .../impl/ApplicationServiceImplTest.java | 86 + .../service/impl/HelpdeskServiceImplTest.java | 116 ++ .../service/impl/RoleServiceImplTest.java | 62 + .../service/impl/SuperAdminImplTest.java | 75 + .../service/impl/TicketServiceImplTest.java | 124 ++ 170 files changed, 21078 insertions(+) create mode 100644 Dockerfile create mode 100644 Jenkinsfile create mode 100644 pom.xml create mode 100644 public/emails/add-admin-aurora.vm create mode 100644 public/emails/add-helpdeskadmin-aurora.vm create mode 100644 public/emails/copied-to-ticket-aurora.vm create mode 100644 public/emails/email_template.vm create mode 100644 public/emails/forgot-password.vm create mode 100644 public/emails/new-ticket-createdby-aurora.vm create mode 100644 public/emails/remove-copied-to-ticket-aurora.vm create mode 100644 public/emails/remove_admin.vm create mode 100644 public/emails/remove_helpdeskadmin.vm create mode 100644 public/emails/ticket-status-update-aurora.vm create mode 100644 public/images/9_IMG_5920.jpg create mode 100644 src/main/java/org/upsmf/grievance/Application.java create mode 100644 src/main/java/org/upsmf/grievance/config/CORSFilter.java create mode 100644 src/main/java/org/upsmf/grievance/config/JwtAuthenticationEntryPoint.java create mode 100644 src/main/java/org/upsmf/grievance/config/JwtAuthenticationFilter.java create mode 100644 src/main/java/org/upsmf/grievance/config/JwtTokenUtil.java create mode 100644 src/main/java/org/upsmf/grievance/config/MyCustomJwtClaims.java create mode 100644 src/main/java/org/upsmf/grievance/config/SwaggerConfig.java create mode 100644 src/main/java/org/upsmf/grievance/config/WebSecurityConfig.java create mode 100644 src/main/java/org/upsmf/grievance/constants/RequestContextConstants.java create mode 100644 src/main/java/org/upsmf/grievance/constants/package-info.java create mode 100644 src/main/java/org/upsmf/grievance/controller/ApplicationController.java create mode 100644 src/main/java/org/upsmf/grievance/controller/ControllerRequestValidator.java create mode 100644 src/main/java/org/upsmf/grievance/controller/HelpdeskController.java create mode 100644 src/main/java/org/upsmf/grievance/controller/RoleActionController.java create mode 100644 src/main/java/org/upsmf/grievance/controller/SuperAdminController.java create mode 100644 src/main/java/org/upsmf/grievance/controller/TagController.java create mode 100644 src/main/java/org/upsmf/grievance/controller/TicketController.java create mode 100644 src/main/java/org/upsmf/grievance/controller/UserController.java create mode 100644 src/main/java/org/upsmf/grievance/dao/ApplicationDao.java create mode 100644 src/main/java/org/upsmf/grievance/dao/HelpdeskDao.java create mode 100644 src/main/java/org/upsmf/grievance/dao/RoleDao.java create mode 100644 src/main/java/org/upsmf/grievance/dao/SuperAdminDao.java create mode 100644 src/main/java/org/upsmf/grievance/dao/TagDao.java create mode 100644 src/main/java/org/upsmf/grievance/dao/TicketDao.java create mode 100644 src/main/java/org/upsmf/grievance/dao/UserDao.java create mode 100644 src/main/java/org/upsmf/grievance/dao/impl/ApplicationDaoImpl.java create mode 100644 src/main/java/org/upsmf/grievance/dao/impl/HelpdeskDaoImpl.java create mode 100644 src/main/java/org/upsmf/grievance/dao/impl/RoleDaoImpl.java create mode 100644 src/main/java/org/upsmf/grievance/dao/impl/SuperAdminDaoImpl.java create mode 100644 src/main/java/org/upsmf/grievance/dao/impl/TagDaoImpl.java create mode 100644 src/main/java/org/upsmf/grievance/dao/impl/TicketDaoImpl.java create mode 100644 src/main/java/org/upsmf/grievance/dao/impl/UserDaoImpl.java create mode 100644 src/main/java/org/upsmf/grievance/dto/ChangePasswordDto.java create mode 100644 src/main/java/org/upsmf/grievance/dto/HelpdeskDto.java create mode 100644 src/main/java/org/upsmf/grievance/dto/HelpdeskTypeDto.java create mode 100644 src/main/java/org/upsmf/grievance/dto/HelpdeskWorkflowDto.java create mode 100644 src/main/java/org/upsmf/grievance/dto/LoginDto.java create mode 100644 src/main/java/org/upsmf/grievance/dto/OrgUserRoleDto.java create mode 100644 src/main/java/org/upsmf/grievance/dto/TicketTagDto.java create mode 100644 src/main/java/org/upsmf/grievance/dto/TicketTypeDto.java create mode 100644 src/main/java/org/upsmf/grievance/dto/TicketWorkflowDto.java create mode 100644 src/main/java/org/upsmf/grievance/dto/UserDto.java create mode 100644 src/main/java/org/upsmf/grievance/dto/UserProfileDto.java create mode 100644 src/main/java/org/upsmf/grievance/dto/UserRoleDto.java create mode 100644 src/main/java/org/upsmf/grievance/exceptions/RbacException.java create mode 100644 src/main/java/org/upsmf/grievance/exceptions/RequestDataMissingException.java create mode 100644 src/main/java/org/upsmf/grievance/exceptions/package-info.java create mode 100644 src/main/java/org/upsmf/grievance/executor/MasterDataManager.java create mode 100644 src/main/java/org/upsmf/grievance/interceptor/TicketsRequestInterceptor.java create mode 100644 src/main/java/org/upsmf/grievance/interceptor/package-info.java create mode 100644 src/main/java/org/upsmf/grievance/model/Access.java create mode 100644 src/main/java/org/upsmf/grievance/model/AccessResponse.java create mode 100644 src/main/java/org/upsmf/grievance/model/Action.java create mode 100644 src/main/java/org/upsmf/grievance/model/ActionRole.java create mode 100644 src/main/java/org/upsmf/grievance/model/ActivityLog.java create mode 100644 src/main/java/org/upsmf/grievance/model/Analytics.java create mode 100644 src/main/java/org/upsmf/grievance/model/App.java create mode 100644 src/main/java/org/upsmf/grievance/model/ChecklistItem.java create mode 100644 src/main/java/org/upsmf/grievance/model/Comment.java create mode 100644 src/main/java/org/upsmf/grievance/model/CommonDataModel.java create mode 100644 src/main/java/org/upsmf/grievance/model/DeveloperComment.java create mode 100644 src/main/java/org/upsmf/grievance/model/DeviceMetadata.java create mode 100644 src/main/java/org/upsmf/grievance/model/HelpDeskApp.java create mode 100644 src/main/java/org/upsmf/grievance/model/Helpdesk.java create mode 100644 src/main/java/org/upsmf/grievance/model/HelpdeskType.java create mode 100644 src/main/java/org/upsmf/grievance/model/HelpdeskWorkflow.java create mode 100644 src/main/java/org/upsmf/grievance/model/KeyFactory.java create mode 100644 src/main/java/org/upsmf/grievance/model/LastModified.java create mode 100644 src/main/java/org/upsmf/grievance/model/LoginUser.java create mode 100644 src/main/java/org/upsmf/grievance/model/MasterData.java create mode 100644 src/main/java/org/upsmf/grievance/model/Organization.java create mode 100644 src/main/java/org/upsmf/grievance/model/ReplyToReviews.java create mode 100644 src/main/java/org/upsmf/grievance/model/Rev.java create mode 100644 src/main/java/org/upsmf/grievance/model/Review.java create mode 100644 src/main/java/org/upsmf/grievance/model/Role.java create mode 100644 src/main/java/org/upsmf/grievance/model/RolesDto.java create mode 100644 src/main/java/org/upsmf/grievance/model/S3Config.java create mode 100644 src/main/java/org/upsmf/grievance/model/ServiceRequest.java create mode 100644 src/main/java/org/upsmf/grievance/model/StatusIdMap.java create mode 100644 src/main/java/org/upsmf/grievance/model/Tags.java create mode 100644 src/main/java/org/upsmf/grievance/model/Task.java create mode 100644 src/main/java/org/upsmf/grievance/model/Template.java create mode 100644 src/main/java/org/upsmf/grievance/model/TemplateVersion.java create mode 100644 src/main/java/org/upsmf/grievance/model/Ticket.java create mode 100644 src/main/java/org/upsmf/grievance/model/TicketCount.java create mode 100644 src/main/java/org/upsmf/grievance/model/TicketElastic.java create mode 100644 src/main/java/org/upsmf/grievance/model/TicketTags.java create mode 100644 src/main/java/org/upsmf/grievance/model/TicketsTagsList.java create mode 100644 src/main/java/org/upsmf/grievance/model/Updates.java create mode 100644 src/main/java/org/upsmf/grievance/model/User.java create mode 100644 src/main/java/org/upsmf/grievance/model/UserAuthentication.java create mode 100644 src/main/java/org/upsmf/grievance/model/UserComment.java create mode 100644 src/main/java/org/upsmf/grievance/model/UserIdAndUserName.java create mode 100644 src/main/java/org/upsmf/grievance/model/UserRole.java create mode 100644 src/main/java/org/upsmf/grievance/model/contract/RequestInfo.java create mode 100644 src/main/java/org/upsmf/grievance/model/contract/RoleActionRequest.java create mode 100644 src/main/java/org/upsmf/grievance/model/contract/RoleActionResponseInfo.java create mode 100644 src/main/java/org/upsmf/grievance/model/contract/RoleRequest.java create mode 100644 src/main/java/org/upsmf/grievance/model/contract/StatusInfo.java create mode 100644 src/main/java/org/upsmf/grievance/model/contract/UserGetRequest.java create mode 100644 src/main/java/org/upsmf/grievance/model/enums/AuthTypes.java create mode 100644 src/main/java/org/upsmf/grievance/model/enums/PriorityLevels.java create mode 100644 src/main/java/org/upsmf/grievance/model/mapper/SqlDataMapper.java create mode 100644 src/main/java/org/upsmf/grievance/repository/ElasticSearchRepository.java create mode 100644 src/main/java/org/upsmf/grievance/service/ApplicationService.java create mode 100644 src/main/java/org/upsmf/grievance/service/HelpdeskService.java create mode 100644 src/main/java/org/upsmf/grievance/service/RoleActionService.java create mode 100644 src/main/java/org/upsmf/grievance/service/SuperAdminService.java create mode 100644 src/main/java/org/upsmf/grievance/service/TagService.java create mode 100644 src/main/java/org/upsmf/grievance/service/TicketService.java create mode 100644 src/main/java/org/upsmf/grievance/service/UserService.java create mode 100644 src/main/java/org/upsmf/grievance/service/impl/ApplicationServiceImpl.java create mode 100644 src/main/java/org/upsmf/grievance/service/impl/HelpdeskServiceImpl.java create mode 100644 src/main/java/org/upsmf/grievance/service/impl/RoleActionServiceImpl.java create mode 100644 src/main/java/org/upsmf/grievance/service/impl/SuperAdminServiceImpl.java create mode 100644 src/main/java/org/upsmf/grievance/service/impl/TagServiceImpl.java create mode 100644 src/main/java/org/upsmf/grievance/service/impl/TicketServiceImpl.java create mode 100644 src/main/java/org/upsmf/grievance/service/impl/UserServiceImpl.java create mode 100644 src/main/java/org/upsmf/grievance/util/Constants.java create mode 100644 src/main/java/org/upsmf/grievance/util/CustomException.java create mode 100644 src/main/java/org/upsmf/grievance/util/CustomListResponse.java create mode 100644 src/main/java/org/upsmf/grievance/util/CustomResponse.java create mode 100644 src/main/java/org/upsmf/grievance/util/CustomSuccess.java create mode 100644 src/main/java/org/upsmf/grievance/util/DateUtil.java create mode 100644 src/main/java/org/upsmf/grievance/util/ExecutorManager.java create mode 100644 src/main/java/org/upsmf/grievance/util/GMailAuthenticator.java create mode 100644 src/main/java/org/upsmf/grievance/util/JSONObjectUtil.java create mode 100644 src/main/java/org/upsmf/grievance/util/JsonKey.java create mode 100644 src/main/java/org/upsmf/grievance/util/OneWayHashing.java create mode 100644 src/main/java/org/upsmf/grievance/util/PathRoutes.java create mode 100644 src/main/java/org/upsmf/grievance/util/ProjectUtil.java create mode 100644 src/main/java/org/upsmf/grievance/util/ResponseCode.java create mode 100644 src/main/java/org/upsmf/grievance/util/ResponseGenerator.java create mode 100644 src/main/java/org/upsmf/grievance/util/ResponseMessages.java create mode 100644 src/main/java/org/upsmf/grievance/util/ResponseUtil.java create mode 100644 src/main/java/org/upsmf/grievance/util/S3FileManager.java create mode 100644 src/main/java/org/upsmf/grievance/util/SendMail.java create mode 100644 src/main/java/org/upsmf/grievance/util/Sql.java create mode 100644 src/main/java/org/upsmf/grievance/util/SqlConstants.java create mode 100644 src/main/java/org/upsmf/grievance/util/executor/FetchReviewsWeeklyJob.java create mode 100644 src/main/java/org/upsmf/grievance/util/executor/ReviewsSchedulerManager.java create mode 100644 src/main/resources/accesstokenspec.json create mode 100644 src/main/resources/application.properties create mode 100644 src/main/resources/application.properties.j2 create mode 100644 src/main/resources/reviewspec.json create mode 100644 src/test/java/org/upsmf/grievance/dao/impl/ApplicatioDaoImplTest.java create mode 100644 src/test/java/org/upsmf/grievance/dao/impl/HelpdeskDaoImplTest.java create mode 100644 src/test/java/org/upsmf/grievance/dao/impl/RoleDaoImplTest.java create mode 100644 src/test/java/org/upsmf/grievance/dao/impl/SuperAdminDaoImplTest.java create mode 100644 src/test/java/org/upsmf/grievance/dao/impl/TicketDaoImplTest.java create mode 100644 src/test/java/org/upsmf/grievance/dao/impl/UserDaoImplTest.java create mode 100644 src/test/java/org/upsmf/grievance/service/impl/ApplicationServiceImplTest.java create mode 100644 src/test/java/org/upsmf/grievance/service/impl/HelpdeskServiceImplTest.java create mode 100644 src/test/java/org/upsmf/grievance/service/impl/RoleServiceImplTest.java create mode 100644 src/test/java/org/upsmf/grievance/service/impl/SuperAdminImplTest.java create mode 100644 src/test/java/org/upsmf/grievance/service/impl/TicketServiceImplTest.java diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2420d08 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM openjdk:8 +MAINTAINER haridas <haridas.kakunje@tarento.com> +ADD target/aurora-0.0.1-SNAPSHOT.jar aurora-0.0.1-SNAPSHOT.jar +ADD public/emails emails +ENTRYPOINT ["java", "-jar", "/aurora-0.0.1-SNAPSHOT.jar"] +EXPOSE 8081 + diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..2bbb9c1 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,4 @@ +@Library("centralized-jenkins") _ + springboot_with_encryption_build { + + } diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..a2e75a3 --- /dev/null +++ b/pom.xml @@ -0,0 +1,291 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.upsmf</groupId> + <artifactId>grievance</artifactId> + <version>0.0.1-SNAPSHOT</version> + <packaging>jar</packaging> + + <name>Grievance Desk</name> + <description>Grievance Helpdesk managing and resolving the Service Requests and Feedbacks</description> + + <parent> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-parent</artifactId> + <version>2.3.4.RELEASE</version> + <relativePath /> <!-- lookup parent from repository --> + </parent> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + <java.version>1.8</java.version> + <cxf.version>3.0.1</cxf.version> + <log4j2.version>2.16.0</log4j2.version> + + <base>frolvlad/alpine-oraclejdk8:slim</base> + <tomcat.port>9081</tomcat.port> + <tomcat.ip>127.0.0.1</tomcat.ip> + <file>readme</file> + + </properties> + + <dependencies> + <dependency> + <groupId>com.sun.mail</groupId> + <artifactId>javax.mail</artifactId> + <version>1.6.0</version> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-actuator</artifactId> + </dependency> + + <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-jdbc</artifactId> + <version>3.1.2</version> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-jpa</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-security</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-devtools</artifactId> + <scope>runtime</scope> + </dependency> + + <!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk --> + <dependency> + <groupId>com.amazonaws</groupId> + <artifactId>aws-java-sdk</artifactId> + <version>1.11.170</version> + </dependency> + + + <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> + <dependency> + <groupId>org.apache.poi</groupId> + <artifactId>poi</artifactId> + <version>3.9</version> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-jwt --> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-jwt</artifactId> + <version>1.1.0.RELEASE</version> + </dependency> + + <!-- https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2 --> + <dependency> + <groupId>org.springframework.security.oauth</groupId> + <artifactId>spring-security-oauth2</artifactId> + <version>2.5.0.RELEASE</version> + </dependency> + + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <version>1.7.1</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + <version>1.7.1</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>jsr311-api</artifactId> + <version>1.1.1</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-frontend-jaxws</artifactId> + <version>${cxf.version}</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-transports-http</artifactId> + <version>${cxf.version}</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-frontend-jaxrs</artifactId> + <version>${cxf.version}</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-tools-java2ws</artifactId> + <version>${cxf.version}</version> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + </dependency> + <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql --> + <dependency> + <groupId>org.postgresql</groupId> + <artifactId>postgresql</artifactId> + </dependency> + <dependency> + <groupId>io.jsonwebtoken</groupId> + <artifactId>jjwt</artifactId> + <version>0.6.0</version> + </dependency> + <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 --> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-dbcp2</artifactId> + <version>2.9.0</version> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>2.3</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + <version>3.7</version> + </dependency> + <!-- https://mvnrepository.com/artifact/com.google.api-client/google-api-client --> + <dependency> + <groupId>com.google.api-client</groupId> + <artifactId>google-api-client</artifactId> + <version>1.22.0</version> + </dependency> + + <!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz --> + <dependency> + <groupId>org.quartz-scheduler</groupId> + <artifactId>quartz</artifactId> + <version>2.1.5</version> + </dependency> + + <!-- https://mvnrepository.com/artifact/com.taskadapter/redmine-java-api --> + <dependency> + <groupId>com.taskadapter</groupId> + <artifactId>redmine-java-api</artifactId> + <version>3.0.0</version> + </dependency> + <dependency> + <groupId>org.elasticsearch</groupId> + <artifactId>elasticsearch</artifactId> + <version>6.0.0</version> + </dependency> + <dependency> + <groupId>org.elasticsearch.client</groupId> + <artifactId>elasticsearch-rest-high-level-client</artifactId> + <version>6.2.4</version> + </dependency> + <dependency> + <groupId>org.scala-lang</groupId> + <artifactId>scala-library</artifactId> + <version>2.11.0</version> + </dependency> + <dependency> + <groupId>com.bazaarvoice.jolt</groupId> + <artifactId>jolt-core</artifactId> + <version>0.0.24</version> + </dependency> + <dependency> + <groupId>com.bazaarvoice.jolt</groupId> + <artifactId>json-utils</artifactId> + <version>0.0.24</version> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <configuration> + <executable>true</executable> + <addResources>true</addResources> + </configuration> + <executions> + <execution> + <goals> + <goal>repackage</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>io.fabric8</groupId> + <artifactId>docker-maven-plugin</artifactId> + <extensions>true</extensions> + + <configuration> + <images> + <image> + <name>springboot-jwt</name> + <alias>springboot-jwt</alias> + <build> + <filter>@</filter> + <dockerFileDir>${project.basedir}/src/main/docker</dockerFileDir> + <assembly> + <descriptorRef>artifact</descriptorRef> + </assembly> + </build> + <run> + <namingStrategy>alias</namingStrategy> + <ports> + <port>${tomcat.port}:8080</port> + </ports> + <wait> + <http> + <url>http://${tomcat.ip}:${tomcat.port}/health</url> + </http> + <time>90000</time> + </wait> + </run> + </image> + </images> + </configuration> + + </plugin> + </plugins> + </build> + +</project> \ No newline at end of file diff --git a/public/emails/add-admin-aurora.vm b/public/emails/add-admin-aurora.vm new file mode 100644 index 0000000..7690b73 --- /dev/null +++ b/public/emails/add-admin-aurora.vm @@ -0,0 +1,318 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <title>Aurora Helpdesk</title> + + <style type="text/css"> + /* Take care of image borders and formatting, client hacks */ + img { max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;} + a img { border: none; } + table { border-collapse: collapse !important;} + #outlook a { padding:0; } + .ReadMsgBody { width: 100%; } + .ExternalClass { width: 100%; } + .backgroundTable { margin: 0 auto; padding: 0; width: 100% !important; } + table td { border-collapse: collapse; } + .ExternalClass * { line-height: 115%; } + .container-for-gmail-android { min-width: 600px; } + + + /* General styling */ + * { + font-family: Helvetica, Arial, sans-serif; + } + + body { + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: none; + width: 100% !important; + margin: 0 !important; + height: 100%; + color: #676767; + } + + td { + font-family: Helvetica, Arial, sans-serif; + font-size: 14px; + color: #777777; + text-align: center; + line-height: 21px; + } + + a { + color: #676767; + text-decoration: none !important; + } + + .pull-left { + text-align: left; + } + + .pull-right { + text-align: right; + } + + .header-lg, + .header-md, + .header-sm { + font-size: 32px; + font-weight: 700; + line-height: normal; + padding: 35px 0 0; + color: #4d4d4d; + } + + .header-md { + font-size: 24px; + } + + .header-sm { + padding: 5px 0; + font-size: 18px; + line-height: 1.3; + } + + + .content-padding { + padding: 5px 5px 5px 10px; + } + + .mobile-header-padding-right { + width: 290px; + text-align: right; + padding-left: 10px; + } + + .mobile-header-padding-left { + width: 290px; + text-align: left; + padding-left: 10px; + } + + .free-text { + width: 100% !important; + padding: 10px 60px 0px; + } + + .button { + padding: 30px 0; + } + + + .mini-block { + border: 1px solid #e5e5e5; + border-radius: 5px; + background-color: #ffffff; + padding: 12px 15px 15px; + text-align: left; + width: 253px; + } + + .mini-container-left { + width: 278px; + padding: 10px 0 10px 15px; + } + + .mini-container-right { + width: 278px; + padding: 10px 14px 10px 15px; + } + + .product { + text-align: left; + vertical-align: top; + width: 175px; + } + + .total-space { + padding-bottom: 8px; + display: inline-block; + } + + .item-table { + padding: 50px 20px; + width: 560px; + } + + .item { + width: 300px; + } + + .mobile-hide-img { + text-align: left; + width: 125px; + } + + .mobile-hide-img img { + border: 1px solid #e6e6e6; + border-radius: 4px; + } + + .title-dark { + text-align: left; + border-bottom: 1px solid #cccccc; + color: #4d4d4d; + font-weight: 700; + padding-bottom: 5px; + } + + .item-col { + padding-top: 20px; + text-align: left; + vertical-align: top; + } + + .force-width-gmail { + min-width:600px; + height: 0px !important; + line-height: 1px !important; + font-size: 1px !important; + } + + </style> + + <style type="text/css" media="screen"> + @import url(http://fonts.googleapis.com/css?family=Oxygen:400,700); + </style> + + <style type="text/css" media="screen"> + @media screen { + /* Thanks Outlook 2013! */ + * { + font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; + } + } + </style> + + <style type="text/css" media="only screen and (max-width: 480px)"> + /* Mobile styles */ + @media only screen and (max-width: 480px) { + + table[class*="container-for-gmail-android"] { + min-width: 290px !important; + width: 100% !important; + } + + img[class="force-width-gmail"] { + display: none !important; + width: 0 !important; + height: 0 !important; + } + + table[class="w320"] { + width: 320px !important; + } + + + td[class*="mobile-header-padding-left"] { + width: 160px !important; + padding-left: 0 !important; + } + + td[class*="mobile-header-padding-right"] { + width: 160px !important; + padding-right: 0 !important; + } + + td[class="header-lg"] { + font-size: 24px !important; + padding-bottom: 5px !important; + } + + td[class="content-padding"] { + padding: 5px 0 5px !important; + } + + td[class="button"] { + padding: 5px 5px 30px !important; + } + + td[class*="free-text"] { + padding: 10px 18px 30px !important; + } + + td[class~="mobile-hide-img"] { + display: none !important; + height: 0 !important; + width: 0 !important; + line-height: 0 !important; + } + + td[class~="item"] { + width: 140px !important; + vertical-align: top !important; + } + + td[class~="quantity"] { + width: 50px !important; + } + + td[class~="price"] { + width: 90px !important; + } + + td[class="item-table"] { + padding: 30px 20px !important; + } + + td[class="mini-container-left"], + td[class="mini-container-right"] { + padding: 0 15px 15px !important; + display: block !important; + width: 290px !important; + } + } + </style> +</head> + +<body bgcolor="#f7f7f7"> +<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%"> + <tr> + <td align="left" valign="top" width="100%" style="background:repeat-x url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) #ffffff;"> + <center> + <img src="http://s3.amazonaws.com/swu-filepicker/SBb2fQPrQ5ezxmqUTgCr_transparent.png" class="force-width-gmail"> + <table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="background-color:transparent"> + <tr> + <td width="100%" height="80" valign="top" style="text-align: center; vertical-align:middle;"> + <!--[if gte mso 9]> + <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;"> + <v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" /> + <v:textbox inset="0,0,0,0"> + <![endif]--> + <center> + <!-- #if ($logo_url) --> + <a href="https://aurora-desk.idc.tarento.com/"><img width="50" height="60" src="https://aurora-desk-dev.s3.ap-south-1.amazonaws.com/aurora.png" alt="logo"></a> + <!-- #end --> + </center> + <!--[if gte mso 9]> + </v:textbox> + </v:rect> + <![endif]--> + </td> + </tr> + </table> + </center> + </td> + </tr> + <tr> + <td valign="top" width="100%" style="background-color: #f7f7f7;text-align:left" class="content-padding"> + <center> + <p><b> Hi $firstName,<br> + You are designated as Org Admin for $CompName. You may access Aurora web using <a href="https://aurora-desk.idc.tarento.com/"> this link </a>.<br> + Thank you!</b> + </center> + </td> + </tr> + </table> + + </td> + </tr> + </table> + </center> + </td> + </tr> +</table> +</body> +</html> diff --git a/public/emails/add-helpdeskadmin-aurora.vm b/public/emails/add-helpdeskadmin-aurora.vm new file mode 100644 index 0000000..7a6d95e --- /dev/null +++ b/public/emails/add-helpdeskadmin-aurora.vm @@ -0,0 +1,318 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <title>Aurora Helpdesk</title> + + <style type="text/css"> + /* Take care of image borders and formatting, client hacks */ + img { max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;} + a img { border: none; } + table { border-collapse: collapse !important;} + #outlook a { padding:0; } + .ReadMsgBody { width: 100%; } + .ExternalClass { width: 100%; } + .backgroundTable { margin: 0 auto; padding: 0; width: 100% !important; } + table td { border-collapse: collapse; } + .ExternalClass * { line-height: 115%; } + .container-for-gmail-android { min-width: 600px; } + + + /* General styling */ + * { + font-family: Helvetica, Arial, sans-serif; + } + + body { + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: none; + width: 100% !important; + margin: 0 !important; + height: 100%; + color: #676767; + } + + td { + font-family: Helvetica, Arial, sans-serif; + font-size: 14px; + color: #777777; + text-align: center; + line-height: 21px; + } + + a { + color: #676767; + text-decoration: none !important; + } + + .pull-left { + text-align: left; + } + + .pull-right { + text-align: right; + } + + .header-lg, + .header-md, + .header-sm { + font-size: 32px; + font-weight: 700; + line-height: normal; + padding: 35px 0 0; + color: #4d4d4d; + } + + .header-md { + font-size: 24px; + } + + .header-sm { + padding: 5px 0; + font-size: 18px; + line-height: 1.3; + } + + + .content-padding { + padding: 5px 5px 5px 10px; + } + + .mobile-header-padding-right { + width: 290px; + text-align: right; + padding-left: 10px; + } + + .mobile-header-padding-left { + width: 290px; + text-align: left; + padding-left: 10px; + } + + .free-text { + width: 100% !important; + padding: 10px 60px 0px; + } + + .button { + padding: 30px 0; + } + + + .mini-block { + border: 1px solid #e5e5e5; + border-radius: 5px; + background-color: #ffffff; + padding: 12px 15px 15px; + text-align: left; + width: 253px; + } + + .mini-container-left { + width: 278px; + padding: 10px 0 10px 15px; + } + + .mini-container-right { + width: 278px; + padding: 10px 14px 10px 15px; + } + + .product { + text-align: left; + vertical-align: top; + width: 175px; + } + + .total-space { + padding-bottom: 8px; + display: inline-block; + } + + .item-table { + padding: 50px 20px; + width: 560px; + } + + .item { + width: 300px; + } + + .mobile-hide-img { + text-align: left; + width: 125px; + } + + .mobile-hide-img img { + border: 1px solid #e6e6e6; + border-radius: 4px; + } + + .title-dark { + text-align: left; + border-bottom: 1px solid #cccccc; + color: #4d4d4d; + font-weight: 700; + padding-bottom: 5px; + } + + .item-col { + padding-top: 20px; + text-align: left; + vertical-align: top; + } + + .force-width-gmail { + min-width:600px; + height: 0px !important; + line-height: 1px !important; + font-size: 1px !important; + } + + </style> + + <style type="text/css" media="screen"> + @import url(http://fonts.googleapis.com/css?family=Oxygen:400,700); + </style> + + <style type="text/css" media="screen"> + @media screen { + /* Thanks Outlook 2013! */ + * { + font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; + } + } + </style> + + <style type="text/css" media="only screen and (max-width: 480px)"> + /* Mobile styles */ + @media only screen and (max-width: 480px) { + + table[class*="container-for-gmail-android"] { + min-width: 290px !important; + width: 100% !important; + } + + img[class="force-width-gmail"] { + display: none !important; + width: 0 !important; + height: 0 !important; + } + + table[class="w320"] { + width: 320px !important; + } + + + td[class*="mobile-header-padding-left"] { + width: 160px !important; + padding-left: 0 !important; + } + + td[class*="mobile-header-padding-right"] { + width: 160px !important; + padding-right: 0 !important; + } + + td[class="header-lg"] { + font-size: 24px !important; + padding-bottom: 5px !important; + } + + td[class="content-padding"] { + padding: 5px 0 5px !important; + } + + td[class="button"] { + padding: 5px 5px 30px !important; + } + + td[class*="free-text"] { + padding: 10px 18px 30px !important; + } + + td[class~="mobile-hide-img"] { + display: none !important; + height: 0 !important; + width: 0 !important; + line-height: 0 !important; + } + + td[class~="item"] { + width: 140px !important; + vertical-align: top !important; + } + + td[class~="quantity"] { + width: 50px !important; + } + + td[class~="price"] { + width: 90px !important; + } + + td[class="item-table"] { + padding: 30px 20px !important; + } + + td[class="mini-container-left"], + td[class="mini-container-right"] { + padding: 0 15px 15px !important; + display: block !important; + width: 290px !important; + } + } + </style> +</head> + +<body bgcolor="#f7f7f7"> +<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%"> + <tr> + <td align="left" valign="top" width="100%" style="background:repeat-x url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) #ffffff;"> + <center> + <img src="http://s3.amazonaws.com/swu-filepicker/SBb2fQPrQ5ezxmqUTgCr_transparent.png" class="force-width-gmail"> + <table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="background-color:transparent"> + <tr> + <td width="100%" height="80" valign="top" style="text-align: center; vertical-align:middle;"> + <!--[if gte mso 9]> + <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;"> + <v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" /> + <v:textbox inset="0,0,0,0"> + <![endif]--> + <center> + <!-- #if ($logo_url) --> + <a href="https://aurora-desk.idc.tarento.com/"><img width="50" height="60" src="https://aurora-desk-dev.s3.ap-south-1.amazonaws.com/aurora.png" alt="logo"></a> + <!-- #end --> + </center> + <!--[if gte mso 9]> + </v:textbox> + </v:rect> + <![endif]--> + </td> + </tr> + </table> + </center> + </td> + </tr> + <tr> + <td valign="top" width="100%" style="background-color: #f7f7f7;text-align:left" class="content-padding"> + <center> + <p><b> Hi $firstName,<br> + You are designated as Helpdesk Admin for $HelpdeskName. You may access Aurora web using <a href="https://aurora-desk.idc.tarento.com/"> this link </a>.<br> + Thank you!</b> + </center> + </td> + </tr> + </table> + + </td> + </tr> + </table> + </center> + </td> + </tr> +</table> +</body> +</html> diff --git a/public/emails/copied-to-ticket-aurora.vm b/public/emails/copied-to-ticket-aurora.vm new file mode 100644 index 0000000..b68bbd5 --- /dev/null +++ b/public/emails/copied-to-ticket-aurora.vm @@ -0,0 +1,331 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <title>Aurora Helpdesk</title> + + <style type="text/css"> + /* Take care of image borders and formatting, client hacks */ + img { max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;} + a img { border: none; } + table { border-collapse: collapse !important;} + #outlook a { padding:0; } + .ReadMsgBody { width: 100%; } + .ExternalClass { width: 100%; } + .backgroundTable { margin: 0 auto; padding: 0; width: 100% !important; } + table td { border-collapse: collapse; } + .ExternalClass * { line-height: 115%; } + .container-for-gmail-android { min-width: 600px; } + + + /* General styling */ + * { + font-family: Helvetica, Arial, sans-serif; + } + + body { + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: none; + width: 100% !important; + margin: 0 !important; + height: 100%; + color: #676767; + } + + td { + font-family: Helvetica, Arial, sans-serif; + font-size: 14px; + color: #777777; + text-align: center; + line-height: 21px; + } + + a { + color: #676767; + text-decoration: none !important; + } + + .pull-left { + text-align: left; + } + + .pull-right { + text-align: right; + } + + .header-lg, + .header-md, + .header-sm { + font-size: 32px; + font-weight: 700; + line-height: normal; + padding: 35px 0 0; + color: #4d4d4d; + } + + .header-md { + font-size: 24px; + } + + .header-sm { + padding: 5px 0; + font-size: 18px; + line-height: 1.3; + } + + .content-padding { + padding: 20px 0 5px; + } + + .mobile-header-padding-right { + width: 290px; + text-align: right; + padding-left: 10px; + } + + .mobile-header-padding-left { + width: 290px; + text-align: left; + padding-left: 10px; + } + + .free-text { + width: 100% !important; + padding: 10px 60px 0px; + } + + .button { + padding: 30px 0; + } + + + .mini-block { + border: 1px solid #e5e5e5; + border-radius: 5px; + background-color: #ffffff; + padding: 12px 15px 15px; + text-align: left; + width: 253px; + } + + .mini-container-left { + width: 278px; + padding: 10px 0 10px 15px; + } + + .mini-container-right { + width: 278px; + padding: 10px 14px 10px 15px; + } + + .product { + text-align: left; + vertical-align: top; + width: 175px; + } + + .total-space { + padding-bottom: 8px; + display: inline-block; + } + + .item-table { + padding: 50px 20px; + width: 560px; + } + + .item { + width: 300px; + } + + .mobile-hide-img { + text-align: left; + width: 125px; + } + + .mobile-hide-img img { + border: 1px solid #e6e6e6; + border-radius: 4px; + } + + .title-dark { + text-align: left; + border-bottom: 1px solid #cccccc; + color: #4d4d4d; + font-weight: 700; + padding-bottom: 5px; + } + + .item-col { + padding-top: 20px; + text-align: left; + vertical-align: top; + } + + .force-width-gmail { + min-width:600px; + height: 0px !important; + line-height: 1px !important; + font-size: 1px !important; + } + + </style> + + <style type="text/css" media="screen"> + @import url(http://fonts.googleapis.com/css?family=Oxygen:400,700); + </style> + + <style type="text/css" media="screen"> + @media screen { + /* Thanks Outlook 2013! */ + * { + font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; + } + } + </style> + + <style type="text/css" media="only screen and (max-width: 480px)"> + /* Mobile styles */ + @media only screen and (max-width: 480px) { + + table[class*="container-for-gmail-android"] { + min-width: 290px !important; + width: 100% !important; + } + + img[class="force-width-gmail"] { + display: none !important; + width: 0 !important; + height: 0 !important; + } + + table[class="w320"] { + width: 320px !important; + } + + + td[class*="mobile-header-padding-left"] { + width: 160px !important; + padding-left: 0 !important; + } + + td[class*="mobile-header-padding-right"] { + width: 160px !important; + padding-right: 0 !important; + } + + td[class="header-lg"] { + font-size: 24px !important; + padding-bottom: 5px !important; + } + + td[class="content-padding"] { + padding: 5px 0 5px !important; + } + + td[class="button"] { + padding: 5px 5px 30px !important; + } + + td[class*="free-text"] { + padding: 10px 18px 30px !important; + } + + td[class~="mobile-hide-img"] { + display: none !important; + height: 0 !important; + width: 0 !important; + line-height: 0 !important; + } + + td[class~="item"] { + width: 140px !important; + vertical-align: top !important; + } + + td[class~="quantity"] { + width: 50px !important; + } + + td[class~="price"] { + width: 90px !important; + } + + td[class="item-table"] { + padding: 30px 20px !important; + } + + td[class="mini-container-left"], + td[class="mini-container-right"] { + padding: 0 15px 15px !important; + display: block !important; + width: 290px !important; + } + } + </style> +</head> + +<body bgcolor="#f7f7f7"> +<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%"> + <tr> + <td align="left" valign="top" width="100%" style="background:repeat-x url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) #ffffff;"> + <center> + <img src="http://s3.amazonaws.com/swu-filepicker/SBb2fQPrQ5ezxmqUTgCr_transparent.png" class="force-width-gmail"> + <table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="background-color:transparent"> + <tr> + <td width="100%" height="80" valign="top" style="text-align: center; vertical-align:middle;"> + <!--[if gte mso 9]> + <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;"> + <v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" /> + <v:textbox inset="0,0,0,0"> + <![endif]--> + <center> + <!-- <table cellpadding="0" cellspacing="0" width="600" class="w320"> + <tr> + #if ($logo_url) --> + <!-- <td class="pull-left mobile-header-padding-left" style="vertical-align: middle;"> + <a href=""><img height="47" src='$logo_url' alt="logo"></a> + </td> + #end + </tr> + </table> --> + <a href="https://aurora-desk.idc.tarento.com/"><img width="50" height="60" src="https://aurora-desk-dev.s3.ap-south-1.amazonaws.com/aurora.png" alt="logo"></a> + </center> + <!--[if gte mso 9]> + </v:textbox> + </v:rect> + <![endif]--> + </td> + </tr> + </table> + </center> + </td> + </tr> + <tr> + <td align="center" valign="top" width="100%" style="background-color: #f7f7f7;" class="content-padding"> + <center> + <p> Hi $firstName,</p> + <p>You are copied to ticket <a href="https://aurora-desk.idc.tarento.com/desks/$helpdeskId/tickets/"> $id </a> on helpdesk $HelpdeskName. You may access ticket details using <a href="https://aurora-desk.idc.tarento.com/desks/$helpdeskId/tickets"> this link </a>.</p> + <p>Thank you!</p> + + </center> + </td> + </tr> + <tr> + <td align="center" valign="top" width="100%" style="background-color: #f7f7f7; height: 100px;"> + <center> + <table cellspacing="0" cellpadding="0" width="600" class="w320"> + <tr> + <td style="padding: 25px 0 25px"> + <strong>Aurora Helpdesk</strong><br /> + </td> + </tr> + </table> + </center> + </td> + </tr> +</table> +</div> +</body> +</html> diff --git a/public/emails/email_template.vm b/public/emails/email_template.vm new file mode 100644 index 0000000..5770e3b --- /dev/null +++ b/public/emails/email_template.vm @@ -0,0 +1,444 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <title>Aurora Helpdesk</title> + + <style type="text/css"> + /* Take care of image borders and formatting, client hacks */ + img { max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;} + a img { border: none; } + table { border-collapse: collapse !important;} + #outlook a { padding:0; } + .ReadMsgBody { width: 100%; } + .ExternalClass { width: 100%; } + .backgroundTable { margin: 0 auto; padding: 0; width: 100% !important; } + table td { border-collapse: collapse; } + .ExternalClass * { line-height: 115%; } + .container-for-gmail-android { min-width: 600px; } + + + /* General styling */ + * { + font-family: Helvetica, Arial, sans-serif; + } + + body { + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: none; + width: 100% !important; + margin: 0 !important; + height: 100%; + color: #676767; + } + + td { + font-family: Helvetica, Arial, sans-serif; + font-size: 14px; + color: #777777; + text-align: center; + line-height: 21px; + } + + a { + color: #ff6f6f; + font-weight: bold; + text-decoration: none !important; + } + + .pull-left { + text-align: left; + } + + .pull-right { + text-align: right; + } + + .header-lg, + .header-md, + .header-sm { + font-size: 32px; + font-weight: 700; + line-height: normal; + padding: 35px 0 0; + color: #4d4d4d; + } + + .header-md { + font-size: 24px; + } + + .header-sm { + padding: 5px 0; + font-size: 18px; + line-height: 1.3; + } + + .content-padding { + padding: 20px 0 30px; + } + + .mobile-header-padding-right { + width: 290px; + text-align: right; + padding-left: 10px; + } + + .mobile-header-padding-left { + width: 290px; + text-align: left; + padding-left: 10px; + } + + .free-text { + width: 100% !important; + padding: 10px 60px 0px; + } + + .block-rounded { + border-radius: 5px; + border: 1px solid #e5e5e5; + vertical-align: top; + } + + .button { + padding: 30px 0 0; + } + + .info-block { + padding: 0 20px; + width: 260px; + } + + .mini-block-container { + padding: 30px 50px; + width: 500px; + } + + .mini-block { + background-color: #ffffff; + width: 498px; + border: 1px solid #cccccc; + border-radius: 5px; + padding: 45px 75px; + } + + .block-rounded { + width: 260px; + } + + .info-img { + width: 258px; + border-radius: 5px 5px 0 0; + } + + .force-width-img { + width: 480px; + height: 1px !important; + } + + .force-width-full { + width: 600px; + height: 1px !important; + } + + .user-img img { + width: 130px; + border-radius: 5px; + border: 1px solid #cccccc; + } + + .user-img { + text-align: center; + border-radius: 100px; + color: #ff6f6f; + font-weight: 700; + } + + .user-msg { + padding-top: 10px; + font-size: 14px; + text-align: center; + font-style: italic; + } + + .mini-img { + padding: 5px; + width: 140px; + } + + .mini-img img { + border-radius: 5px; + width: 140px; + } + + .force-width-gmail { + min-width:600px; + height: 0px !important; + line-height: 1px !important; + font-size: 1px !important; + } + + .mini-imgs { + padding: 10px 0 20px; + } + + div.center { + display: table; + } + ul { + text-align: left; + list-style-type:none; + } + </style> + + <style type="text/css" media="screen"> + @import url(http://fonts.googleapis.com/css?family=Oxygen:400,700); + </style> + + <style type="text/css" media="screen"> + @media screen { + /* Thanks Outlook 2013! */ + * { + font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; + } + } + </style> + + <style type="text/css" media="only screen and (max-width: 480px)"> + /* Mobile styles */ + @media only screen and (max-width: 480px) { + + div.center { + margin-right: 1rem; + } + + table[class*="container-for-gmail-android"] { + min-width: 290px !important; + width: 100% !important; + } + + table[class="w320"] { + width: 320px !important; + } + + img[class="force-width-gmail"] { + display: none !important; + width: 0 !important; + height: 0 !important; + } + + td[class*="mobile-header-padding-left"] { + width: 160px !important; + padding-left: 0 !important; + } + + td[class*="mobile-header-padding-right"] { + width: 160px !important; + padding-right: 0 !important; + } + + td[class="mobile-block"] { + display: block !important; + } + + td[class="mini-img"], + td[class="mini-img"] img{ + width: 150px !important; + } + + td[class="header-lg"] { + font-size: 24px !important; + padding-bottom: 5px !important; + } + + td[class="header-md"] { + font-size: 18px !important; + padding-bottom: 5px !important; + } + + td[class="content-padding"] { + padding: 5px 0 30px !important; + } + + td[class="button"] { + padding: 5px !important; + } + + td[class*="free-text"] { + padding: 10px 18px 30px !important; + } + + img[class="force-width-img"], + img[class="force-width-full"] { + display: none !important; + } + + td[class="info-block"] { + display: block !important; + width: 280px !important; + padding-bottom: 40px !important; + } + + td[class="info-img"], + img[class="info-img"] { + width: 278px !important; + } + + td[class="mini-block-container"] { + padding: 8px 20px !important; + width: 280px !important; + } + + td[class="mini-block"] { + padding: 20px !important; + } + + td[class="user-img"] { + display: block !important; + text-align: center !important; + width: 100% !important; + padding-bottom: 10px; + } + + td[class="user-msg"] { + display: block !important; + padding-bottom: 20px; + } + } + </style> +</head> + +<body bgcolor="#f7f7f7"> +<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%"> + <tr> + <td align="left" valign="top" width="100%" style="background:repeat-x url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) #ffffff;"> + <center> + <img src="http://s3.amazonaws.com/swu-filepicker/SBb2fQPrQ5ezxmqUTgCr_transparent.png" class="force-width-gmail"> + <table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="background-color:transparent"> + <tr> + <td width="100%" height="80" valign="top" style="text-align: center; vertical-align:middle;"> + <!--[if gte mso 9]> + <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;"> + <v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" /> + <v:textbox inset="0,0,0,0"> + <![endif]--> + <center> + <!-- #if ($logo_url) --> + <a href="https://aurora-desk.idc.tarento.com/"><img width="50" height="60" src="https://aurora-desk-dev.s3.ap-south-1.amazonaws.com/aurora.png" alt="logo"></a> + <!-- #end --> + </center> + <!--[if gte mso 9]> + </v:textbox> + </v:rect> + <![endif]--> + </td> + </tr> + </table> + </center> + </td> + </tr> + <tr> + <td align="center" valign="top" width="100%" style="background-color: #f7f7f7;" class="content-padding"> + <center> + <table cellspacing="0" cellpadding="0" width="600" class="w320"> + <tr> + <td class="header-lg"> + You've received an invitation! + </td> + </tr> + <tr> + </tr> + <tr> + <td class="mini-block-container"> + <table cellspacing="0" cellpadding="0" width="100%" style="border-collapse:separate !important;"> + <tr> + <td class="mini-block"> + <table cellpadding="0" cellspacing="0" width="100%"> + <tr> + <td> + <table cellspacing="0" cellpadding="0" width="100%"> + + <tr> + <td class="header-lg"> + Hi, $firstName <br> + $mail_subject + </td> + </tr> + <tr> + <td class="user-msg"> + <div id="wrapper" class="center"> + <div id="content" class="center"> + <div id="listDiv" class="center"> + <ul> + <li>Your username is: $username + </li> + <li>Your password is: $password + </li> + </ul> + </div> + </div> + </div> + </td> + </tr> + </table> + </td> + </tr> + <tr> + <td class="button"> + <div><!--[if mso]> + <v:roundrect xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" href="http://" style="height:45px;v-text-anchor:middle;width:155px;" arcsize="15%" strokecolor="#ffffff" fillcolor="#ff6f6f"> + <w:anchorlock/> + <center style="color:#ffffff;font-family:Helvetica, Arial, sans-serif;font-size:14px;font-weight:regular;">Sign Up</center> + </v:roundrect> + <![endif]--><a href="#" + style="background-color:#ff6f6f;border-radius:5px;color:#ffffff;display:inline-block;font-family:'Cabin', Helvetica, Arial, sans-serif;font-size:14px;font-weight:regular;line-height:45px;text-align:center;text-decoration:none;width:155px;-webkit-text-size-adjust:none;mso-hide:all;">Sign In</a></div> + </td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> + </table> + </center> + </td> + </tr> + <tr> + <td align="center" valign="top" width="100%" style="background-color: #ffffff; border-top: 1px solid #e5e5e5; border-bottom: 1px solid #e5e5e5;"> + <center> + <table cellpadding="0" cellspacing="0" width="600" class="w320"> + <tr> + <td class="header-md" style="text-align:center;"> + Welcome aboard! + </td> + </tr> + <tr> + <td class="mini-imgs"> + + </td> + </tr> + </table> + </center> + </td> + </tr> + <tr> + <td align="center" valign="top" width="100%" style="background-color: #f7f7f7; height: 100px;"> + <center> + <table cellspacing="0" cellpadding="0" width="600" class="w320"> + <tr> + <td style="padding: 25px 0 25px"> + <strong>Aurora Helpdesk</strong><br /> + <!-- 1234 Awesome St <br /> + Wonderland <br /><br /> --> + </td> + </tr> + </table> + </center> + </td> + </tr> +</table> +</body> +</html> diff --git a/public/emails/forgot-password.vm b/public/emails/forgot-password.vm new file mode 100644 index 0000000..584063e --- /dev/null +++ b/public/emails/forgot-password.vm @@ -0,0 +1,330 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <title>Aurora Helpdesk</title> + + <style type="text/css"> + /* Take care of image borders and formatting, client hacks */ + img { max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;} + a img { border: none; } + table { border-collapse: collapse !important;} + #outlook a { padding:0; } + .ReadMsgBody { width: 100%; } + .ExternalClass { width: 100%; } + .backgroundTable { margin: 0 auto; padding: 0; width: 100% !important; } + table td { border-collapse: collapse; } + .ExternalClass * { line-height: 115%; } + .container-for-gmail-android { min-width: 600px; } + + + /* General styling */ + * { + font-family: Helvetica, Arial, sans-serif; + } + + body { + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: none; + width: 100% !important; + margin: 0 !important; + height: 100%; + color: #676767; + } + + td { + font-family: Helvetica, Arial, sans-serif; + font-size: 14px; + color: #777777; + text-align: center; + line-height: 21px; + } + + a { + color: #676767; + text-decoration: none !important; + } + + .pull-left { + text-align: left; + } + + .pull-right { + text-align: right; + } + + .header-lg, + .header-md, + .header-sm { + font-size: 32px; + font-weight: 700; + line-height: normal; + padding: 35px 0 0; + color: #4d4d4d; + } + + .header-md { + font-size: 24px; + } + + .header-sm { + padding: 5px 0; + font-size: 18px; + line-height: 1.3; + } + + .content-padding { + padding: 20px 0 5px; + } + + .mobile-header-padding-right { + width: 290px; + text-align: right; + padding-left: 10px; + } + + .mobile-header-padding-left { + width: 290px; + text-align: left; + padding-left: 10px; + } + + .free-text { + width: 100% !important; + padding: 10px 60px 0px; + } + + .button { + padding: 30px 0; + } + + + .mini-block { + border: 1px solid #e5e5e5; + border-radius: 5px; + background-color: #ffffff; + padding: 12px 15px 15px; + text-align: left; + width: 253px; + } + + .mini-container-left { + width: 278px; + padding: 10px 0 10px 15px; + } + + .mini-container-right { + width: 278px; + padding: 10px 14px 10px 15px; + } + + .product { + text-align: left; + vertical-align: top; + width: 175px; + } + + .total-space { + padding-bottom: 8px; + display: inline-block; + } + + .item-table { + padding: 50px 20px; + width: 560px; + } + + .item { + width: 300px; + } + + .mobile-hide-img { + text-align: left; + width: 125px; + } + + .mobile-hide-img img { + border: 1px solid #e6e6e6; + border-radius: 4px; + } + + .title-dark { + text-align: left; + border-bottom: 1px solid #cccccc; + color: #4d4d4d; + font-weight: 700; + padding-bottom: 5px; + } + + .item-col { + padding-top: 20px; + text-align: left; + vertical-align: top; + } + + .force-width-gmail { + min-width:600px; + height: 0px !important; + line-height: 1px !important; + font-size: 1px !important; + } + + </style> + + <style type="text/css" media="screen"> + @import url(http://fonts.googleapis.com/css?family=Oxygen:400,700); + </style> + + <style type="text/css" media="screen"> + @media screen { + /* Thanks Outlook 2013! */ + * { + font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; + } + } + </style> + + <style type="text/css" media="only screen and (max-width: 480px)"> + /* Mobile styles */ + @media only screen and (max-width: 480px) { + + table[class*="container-for-gmail-android"] { + min-width: 290px !important; + width: 100% !important; + } + + img[class="force-width-gmail"] { + display: none !important; + width: 0 !important; + height: 0 !important; + } + + table[class="w320"] { + width: 320px !important; + } + + + td[class*="mobile-header-padding-left"] { + width: 160px !important; + padding-left: 0 !important; + } + + td[class*="mobile-header-padding-right"] { + width: 160px !important; + padding-right: 0 !important; + } + + td[class="header-lg"] { + font-size: 24px !important; + padding-bottom: 5px !important; + } + + td[class="content-padding"] { + padding: 5px 0 5px !important; + } + + td[class="button"] { + padding: 5px 5px 30px !important; + } + + td[class*="free-text"] { + padding: 10px 18px 30px !important; + } + + td[class~="mobile-hide-img"] { + display: none !important; + height: 0 !important; + width: 0 !important; + line-height: 0 !important; + } + + td[class~="item"] { + width: 140px !important; + vertical-align: top !important; + } + + td[class~="quantity"] { + width: 50px !important; + } + + td[class~="price"] { + width: 90px !important; + } + + td[class="item-table"] { + padding: 30px 20px !important; + } + + td[class="mini-container-left"], + td[class="mini-container-right"] { + padding: 0 15px 15px !important; + display: block !important; + width: 290px !important; + } + } + </style> +</head> + +<body bgcolor="#f7f7f7"> +<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%"> + <tr> + <td align="left" valign="top" width="100%" style="background:repeat-x url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) #ffffff;"> + <center> + <img src="http://s3.amazonaws.com/swu-filepicker/SBb2fQPrQ5ezxmqUTgCr_transparent.png" class="force-width-gmail"> + <table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="background-color:transparent"> + <tr> + <td width="100%" height="80" valign="top" style="text-align: center; vertical-align:middle;"> + <!--[if gte mso 9]> + <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;"> + <v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" /> + <v:textbox inset="0,0,0,0"> + <![endif]--> + <center> + <!-- <table cellpadding="0" cellspacing="0" width="600" class="w320"> + <tr> + #if ($logo_url) --> + <!-- <td class="pull-left mobile-header-padding-left" style="vertical-align: middle;"> + <a href=""><img height="47" src='$logo_url' alt="logo"></a> + </td> + #end + </tr> + </table> --> + <a href="https://aurora-desk.idc.tarento.com/"><img width="50" height="60" src="https://aurora-desk-dev.s3.ap-south-1.amazonaws.com/aurora.png" alt="logo"></a> + </center> + <!--[if gte mso 9]> + </v:textbox> + </v:rect> + <![endif]--> + </td> + </tr> + </table> + </center> + </td> + </tr> + <tr> + <td align="center" valign="top" width="100%" style="background-color: #f7f7f7;" class="content-padding"> + <center> + <h2>Here is your new password!</h2> + <p>Your password is: $password</p> + <p>You can change your password from the website <a href="websiteurl">https://aurora-desk.idc.tarento.com/login</a></p> + </center> + </td> + </tr> + <tr> + <td align="center" valign="top" width="100%" style="background-color: #f7f7f7; height: 100px;"> + <center> + <table cellspacing="0" cellpadding="0" width="600" class="w320"> + <tr> + <td style="padding: 25px 0 25px"> + <strong>Aurora Helpdesk</strong><br /> + </td> + </tr> + </table> + </center> + </td> + </tr> +</table> +</div> +</body> +</html> diff --git a/public/emails/new-ticket-createdby-aurora.vm b/public/emails/new-ticket-createdby-aurora.vm new file mode 100644 index 0000000..8a7c65f --- /dev/null +++ b/public/emails/new-ticket-createdby-aurora.vm @@ -0,0 +1,331 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <title>Aurora Helpdesk</title> + + <style type="text/css"> + /* Take care of image borders and formatting, client hacks */ + img { max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;} + a img { border: none; } + table { border-collapse: collapse !important;} + #outlook a { padding:0; } + .ReadMsgBody { width: 100%; } + .ExternalClass { width: 100%; } + .backgroundTable { margin: 0 auto; padding: 0; width: 100% !important; } + table td { border-collapse: collapse; } + .ExternalClass * { line-height: 115%; } + .container-for-gmail-android { min-width: 600px; } + + + /* General styling */ + * { + font-family: Helvetica, Arial, sans-serif; + } + + body { + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: none; + width: 100% !important; + margin: 0 !important; + height: 100%; + color: #676767; + } + + td { + font-family: Helvetica, Arial, sans-serif; + font-size: 14px; + color: #777777; + text-align: center; + line-height: 21px; + } + + a { + color: #676767; + text-decoration: none !important; + } + + .pull-left { + text-align: left; + } + + .pull-right { + text-align: right; + } + + .header-lg, + .header-md, + .header-sm { + font-size: 32px; + font-weight: 700; + line-height: normal; + padding: 35px 0 0; + color: #4d4d4d; + } + + .header-md { + font-size: 24px; + } + + .header-sm { + padding: 5px 0; + font-size: 18px; + line-height: 1.3; + } + + .content-padding { + padding: 20px 0 5px; + } + + .mobile-header-padding-right { + width: 290px; + text-align: right; + padding-left: 10px; + } + + .mobile-header-padding-left { + width: 290px; + text-align: left; + padding-left: 10px; + } + + .free-text { + width: 100% !important; + padding: 10px 60px 0px; + } + + .button { + padding: 30px 0; + } + + + .mini-block { + border: 1px solid #e5e5e5; + border-radius: 5px; + background-color: #ffffff; + padding: 12px 15px 15px; + text-align: left; + width: 253px; + } + + .mini-container-left { + width: 278px; + padding: 10px 0 10px 15px; + } + + .mini-container-right { + width: 278px; + padding: 10px 14px 10px 15px; + } + + .product { + text-align: left; + vertical-align: top; + width: 175px; + } + + .total-space { + padding-bottom: 8px; + display: inline-block; + } + + .item-table { + padding: 50px 20px; + width: 560px; + } + + .item { + width: 300px; + } + + .mobile-hide-img { + text-align: left; + width: 125px; + } + + .mobile-hide-img img { + border: 1px solid #e6e6e6; + border-radius: 4px; + } + + .title-dark { + text-align: left; + border-bottom: 1px solid #cccccc; + color: #4d4d4d; + font-weight: 700; + padding-bottom: 5px; + } + + .item-col { + padding-top: 20px; + text-align: left; + vertical-align: top; + } + + .force-width-gmail { + min-width:600px; + height: 0px !important; + line-height: 1px !important; + font-size: 1px !important; + } + + </style> + + <style type="text/css" media="screen"> + @import url(http://fonts.googleapis.com/css?family=Oxygen:400,700); + </style> + + <style type="text/css" media="screen"> + @media screen { + /* Thanks Outlook 2013! */ + * { + font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; + } + } + </style> + + <style type="text/css" media="only screen and (max-width: 480px)"> + /* Mobile styles */ + @media only screen and (max-width: 480px) { + + table[class*="container-for-gmail-android"] { + min-width: 290px !important; + width: 100% !important; + } + + img[class="force-width-gmail"] { + display: none !important; + width: 0 !important; + height: 0 !important; + } + + table[class="w320"] { + width: 320px !important; + } + + + td[class*="mobile-header-padding-left"] { + width: 160px !important; + padding-left: 0 !important; + } + + td[class*="mobile-header-padding-right"] { + width: 160px !important; + padding-right: 0 !important; + } + + td[class="header-lg"] { + font-size: 24px !important; + padding-bottom: 5px !important; + } + + td[class="content-padding"] { + padding: 5px 0 5px !important; + } + + td[class="button"] { + padding: 5px 5px 30px !important; + } + + td[class*="free-text"] { + padding: 10px 18px 30px !important; + } + + td[class~="mobile-hide-img"] { + display: none !important; + height: 0 !important; + width: 0 !important; + line-height: 0 !important; + } + + td[class~="item"] { + width: 140px !important; + vertical-align: top !important; + } + + td[class~="quantity"] { + width: 50px !important; + } + + td[class~="price"] { + width: 90px !important; + } + + td[class="item-table"] { + padding: 30px 20px !important; + } + + td[class="mini-container-left"], + td[class="mini-container-right"] { + padding: 0 15px 15px !important; + display: block !important; + width: 290px !important; + } + } + </style> +</head> + +<body bgcolor="#f7f7f7"> +<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%"> + <tr> + <td align="left" valign="top" width="100%" style="background:repeat-x url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) #ffffff;"> + <center> + <img src="http://s3.amazonaws.com/swu-filepicker/SBb2fQPrQ5ezxmqUTgCr_transparent.png" class="force-width-gmail"> + <table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="background-color:transparent"> + <tr> + <td width="100%" height="80" valign="top" style="text-align: center; vertical-align:middle;"> + <!--[if gte mso 9]> + <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;"> + <v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" /> + <v:textbox inset="0,0,0,0"> + <![endif]--> + <center> + <!-- <table cellpadding="0" cellspacing="0" width="600" class="w320"> + <tr> + #if ($logo_url) --> + <!-- <td class="pull-left mobile-header-padding-left" style="vertical-align: middle;"> + <a href=""><img height="47" src='$logo_url' alt="logo"></a> + </td> + #end + </tr> + </table> --> + <a href="https://aurora-desk.idc.tarento.com/"><img width="50" height="60" src="https://aurora-desk-dev.s3.ap-south-1.amazonaws.com/aurora.png" alt="logo"></a> + </center> + <!--[if gte mso 9]> + </v:textbox> + </v:rect> + <![endif]--> + </td> + </tr> + </table> + </center> + </td> + </tr> + <tr> + <td align="center" valign="top" width="100%" style="background-color: #f7f7f7;" class="content-padding"> + <center> + <p> Hi $firstName,</p> + <p>You have added a new ticket <a href="https://aurora-desk.idc.tarento.com/desks/$helpdeskId/tickets/"> $id </a> on helpdesk $HelpdeskName. You may access ticket details using <a href="https://aurora-desk.idc.tarento.com/desks/$helpdeskId/tickets"> this link </a>.</p> + <p>Thank you!</p> + + </center> + </td> + </tr> + <tr> + <td align="center" valign="top" width="100%" style="background-color: #f7f7f7; height: 100px;"> + <center> + <table cellspacing="0" cellpadding="0" width="600" class="w320"> + <tr> + <td style="padding: 25px 0 25px"> + <strong>Aurora Helpdesk</strong><br /> + </td> + </tr> + </table> + </center> + </td> + </tr> +</table> +</div> +</body> +</html> diff --git a/public/emails/remove-copied-to-ticket-aurora.vm b/public/emails/remove-copied-to-ticket-aurora.vm new file mode 100644 index 0000000..7c7bb14 --- /dev/null +++ b/public/emails/remove-copied-to-ticket-aurora.vm @@ -0,0 +1,333 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <title>Aurora Helpdesk</title> + + <style type="text/css"> + /* Take care of image borders and formatting, client hacks */ + img { max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;} + a img { border: none; } + table { border-collapse: collapse !important;} + #outlook a { padding:0; } + .ReadMsgBody { width: 100%; } + .ExternalClass { width: 100%; } + .backgroundTable { margin: 0 auto; padding: 0; width: 100% !important; } + table td { border-collapse: collapse; } + .ExternalClass * { line-height: 115%; } + .container-for-gmail-android { min-width: 600px; } + + + /* General styling */ + * { + font-family: Helvetica, Arial, sans-serif; + } + + body { + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: none; + width: 100% !important; + margin: 0 !important; + height: 100%; + color: #676767; + } + + td { + font-family: Helvetica, Arial, sans-serif; + font-size: 14px; + color: #777777; + text-align: center; + line-height: 21px; + } + + a { + color: #676767; + text-decoration: none !important; + } + + .pull-left { + text-align: left; + } + + .pull-right { + text-align: right; + } + + .header-lg, + .header-md, + .header-sm { + font-size: 32px; + font-weight: 700; + line-height: normal; + padding: 35px 0 0; + color: #4d4d4d; + } + + .header-md { + font-size: 24px; + } + + .header-sm { + padding: 5px 0; + font-size: 18px; + line-height: 1.3; + } + + + .content-padding { + padding: 5px 5px 5px 10px; + } + + .mobile-header-padding-right { + width: 290px; + text-align: right; + padding-left: 10px; + } + + .mobile-header-padding-left { + width: 290px; + text-align: left; + padding-left: 10px; + } + + .free-text { + width: 100% !important; + padding: 10px 60px 0px; + } + + .button { + padding: 30px 0; + } + + + .mini-block { + border: 1px solid #e5e5e5; + border-radius: 5px; + background-color: #ffffff; + padding: 12px 15px 15px; + text-align: left; + width: 253px; + } + + .mini-container-left { + width: 278px; + padding: 10px 0 10px 15px; + } + + .mini-container-right { + width: 278px; + padding: 10px 14px 10px 15px; + } + + .product { + text-align: left; + vertical-align: top; + width: 175px; + } + + .total-space { + padding-bottom: 8px; + display: inline-block; + } + + .item-table { + padding: 50px 20px; + width: 560px; + } + + .item { + width: 300px; + } + + .mobile-hide-img { + text-align: left; + width: 125px; + } + + .mobile-hide-img img { + border: 1px solid #e6e6e6; + border-radius: 4px; + } + + .title-dark { + text-align: left; + border-bottom: 1px solid #cccccc; + color: #4d4d4d; + font-weight: 700; + padding-bottom: 5px; + } + + .item-col { + padding-top: 20px; + text-align: left; + vertical-align: top; + } + + .force-width-gmail { + min-width:600px; + height: 0px !important; + line-height: 1px !important; + font-size: 1px !important; + } + + </style> + + <style type="text/css" media="screen"> + @import url(http://fonts.googleapis.com/css?family=Oxygen:400,700); + </style> + + <style type="text/css" media="screen"> + @media screen { + /* Thanks Outlook 2013! */ + * { + font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; + } + } + </style> + + <style type="text/css" media="only screen and (max-width: 480px)"> + /* Mobile styles */ + @media only screen and (max-width: 480px) { + + table[class*="container-for-gmail-android"] { + min-width: 290px !important; + width: 100% !important; + } + + img[class="force-width-gmail"] { + display: none !important; + width: 0 !important; + height: 0 !important; + } + + table[class="w320"] { + width: 320px !important; + } + + + td[class*="mobile-header-padding-left"] { + width: 160px !important; + padding-left: 0 !important; + } + + td[class*="mobile-header-padding-right"] { + width: 160px !important; + padding-right: 0 !important; + } + + td[class="header-lg"] { + font-size: 24px !important; + padding-bottom: 5px !important; + } + + td[class="content-padding"] { + padding: 5px 0 5px !important; + } + + td[class="button"] { + padding: 5px 5px 30px !important; + } + + td[class*="free-text"] { + padding: 10px 18px 30px !important; + } + + td[class~="mobile-hide-img"] { + display: none !important; + height: 0 !important; + width: 0 !important; + line-height: 0 !important; + } + + td[class~="item"] { + width: 140px !important; + vertical-align: top !important; + } + + td[class~="quantity"] { + width: 50px !important; + } + + td[class~="price"] { + width: 90px !important; + } + + td[class="item-table"] { + padding: 30px 20px !important; + } + + td[class="mini-container-left"], + td[class="mini-container-right"] { + padding: 0 15px 15px !important; + display: block !important; + width: 290px !important; + } + } + </style> +</head> + +<body bgcolor="#f7f7f7"> +<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%"> + <tr> + <td align="left" valign="top" width="100%" style="background:repeat-x url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) #ffffff;"> + <center> + <img src="https://aurora-desk-dev.s3.ap-south-1.amazonaws.com/aurora.png" class="force-width-gmail"> + <table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="background-color:transparent"> + <tr> + <td width="100%" height="80" valign="top" style="text-align: center; vertical-align:middle;"> + <!--[if gte mso 9]> + <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;"> + <v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" /> + <v:textbox inset="0,0,0,0"> + <![endif]--> + <center> + <!-- #if ($logo_url) --> + <a href="https://aurora-desk.idc.tarento.com/"><img width="50" height="60" src="https://aurora-desk-dev.s3.ap-south-1.amazonaws.com/aurora.png" alt="logo"></a> + <!-- #end --> + </center> + <!--[if gte mso 9]> + </v:textbox> + </v:rect> + <![endif]--> + </td> + </tr> + </table> + </center> + </td> + </tr> + <tr> + <td valign="top" width="100%" style="background-color: #f7f7f7;text-align:left" class="content-padding"> + <center> + <p> Hi $firstName,<br> + You are removed from ticket <a href="https://aurora-desk.idc.tarento.com/desks/$helpdeskId/tickets/"> $id </a> on helpdesk $HelpdeskName. You may access ticket details using <a href="https://aurora-desk.idc.tarento.com/desks/$helpdeskId/tickets"> this link </a>.<br> + Thank you! + </center> + </td> + </tr> + </table> + + </td> + </tr> + <tr> + <td align="center" valign="top" width="100%" style="background-color: #f7f7f7; height: 100px;"> + <center> + <table cellspacing="0" cellpadding="0" width="600" class="w320"> + <tr> + <td style="padding: 25px 0 25px"> + <strong>Aurora Helpdesk</strong><br /> + </td> + </tr> + </table> + </center> + </td> + </tr> + + </table> + </center> + </td> + </tr> +</table> +</body> +</html> + \ No newline at end of file diff --git a/public/emails/remove_admin.vm b/public/emails/remove_admin.vm new file mode 100644 index 0000000..df42ce0 --- /dev/null +++ b/public/emails/remove_admin.vm @@ -0,0 +1,316 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <title>Aurora Helpdesk</title> + + <style type="text/css"> + /* Take care of image borders and formatting, client hacks */ + img { max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;} + a img { border: none; } + table { border-collapse: collapse !important;} + #outlook a { padding:0; } + .ReadMsgBody { width: 100%; } + .ExternalClass { width: 100%; } + .backgroundTable { margin: 0 auto; padding: 0; width: 100% !important; } + table td { border-collapse: collapse; } + .ExternalClass * { line-height: 115%; } + .container-for-gmail-android { min-width: 600px; } + + + /* General styling */ + * { + font-family: Helvetica, Arial, sans-serif; + } + + body { + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: none; + width: 100% !important; + margin: 0 !important; + height: 100%; + color: #676767; + } + + td { + font-family: Helvetica, Arial, sans-serif; + font-size: 14px; + color: #777777; + text-align: center; + line-height: 21px; + } + + a { + color: #676767; + text-decoration: none !important; + } + + .pull-left { + text-align: left; + } + + .pull-right { + text-align: right; + } + + .header-lg, + .header-md, + .header-sm { + font-size: 32px; + font-weight: 700; + line-height: normal; + padding: 35px 0 0; + color: #4d4d4d; + } + + .header-md { + font-size: 24px; + } + + .header-sm { + padding: 5px 0; + font-size: 18px; + line-height: 1.3; + } + + .content-padding { + padding: 5px 5px 5px 10px; + } + + .mobile-header-padding-right { + width: 290px; + text-align: right; + padding-left: 10px; + } + + .mobile-header-padding-left { + width: 290px; + text-align: left; + padding-left: 10px; + } + + .free-text { + width: 100% !important; + padding: 10px 60px 0px; + } + + .button { + padding: 30px 0; + } + + + .mini-block { + border: 1px solid #e5e5e5; + border-radius: 5px; + background-color: #ffffff; + padding: 12px 15px 15px; + text-align: left; + width: 253px; + } + + .mini-container-left { + width: 278px; + padding: 10px 0 10px 15px; + } + + .mini-container-right { + width: 278px; + padding: 10px 14px 10px 15px; + } + + .product { + text-align: left; + vertical-align: top; + width: 175px; + } + + .total-space { + padding-bottom: 8px; + display: inline-block; + } + + .item-table { + padding: 50px 20px; + width: 560px; + } + + .item { + width: 300px; + } + + .mobile-hide-img { + text-align: left; + width: 125px; + } + + .mobile-hide-img img { + border: 1px solid #e6e6e6; + border-radius: 4px; + } + + .title-dark { + text-align: left; + border-bottom: 1px solid #cccccc; + color: #4d4d4d; + font-weight: 700; + padding-bottom: 5px; + } + + .item-col { + padding-top: 20px; + text-align: left; + vertical-align: top; + } + + .force-width-gmail { + min-width:600px; + height: 0px !important; + line-height: 1px !important; + font-size: 1px !important; + } + + </style> + + <style type="text/css" media="screen"> + @import url(http://fonts.googleapis.com/css?family=Oxygen:400,700); + </style> + + <style type="text/css" media="screen"> + @media screen { + /* Thanks Outlook 2013! */ + * { + font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; + } + } + </style> + + <style type="text/css" media="only screen and (max-width: 480px)"> + /* Mobile styles */ + @media only screen and (max-width: 480px) { + + table[class*="container-for-gmail-android"] { + min-width: 290px !important; + width: 100% !important; + } + + img[class="force-width-gmail"] { + display: none !important; + width: 0 !important; + height: 0 !important; + } + + table[class="w320"] { + width: 320px !important; + } + + + td[class*="mobile-header-padding-left"] { + width: 160px !important; + padding-left: 0 !important; + } + + td[class*="mobile-header-padding-right"] { + width: 160px !important; + padding-right: 0 !important; + } + + td[class="header-lg"] { + font-size: 24px !important; + padding-bottom: 5px !important; + } + + td[class="content-padding"] { + padding: 5px 0 5px !important; + } + + td[class="button"] { + padding: 5px 5px 30px !important; + } + + td[class*="free-text"] { + padding: 10px 18px 30px !important; + } + + td[class~="mobile-hide-img"] { + display: none !important; + height: 0 !important; + width: 0 !important; + line-height: 0 !important; + } + + td[class~="item"] { + width: 140px !important; + vertical-align: top !important; + } + + td[class~="quantity"] { + width: 50px !important; + } + + td[class~="price"] { + width: 90px !important; + } + + td[class="item-table"] { + padding: 30px 20px !important; + } + + td[class="mini-container-left"], + td[class="mini-container-right"] { + padding: 0 15px 15px !important; + display: block !important; + width: 290px !important; + } + } + </style> +</head> + +<body bgcolor="#f7f7f7"> +<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%"> + <tr> + <td align="left" valign="top" width="100%" style="background:repeat-x url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) #ffffff;"> + <center> + <img src="https://aurora-desk-dev.s3.ap-south-1.amazonaws.com/aurora.png" class="force-width-gmail"> + <table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="background-color:transparent"> + <tr> + <td width="100%" height="80" valign="top" style="text-align: center; vertical-align:middle;"> + <!--[if gte mso 9]> + <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;"> + <v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" /> + <v:textbox inset="0,0,0,0"> + <![endif]--> + <center> + <!-- #if ($logo_url) --> + <a href="https://aurora-desk.idc.tarento.com/"><img width="50" height="60" src="https://aurora-desk-dev.s3.ap-south-1.amazonaws.com/aurora.png" alt="logo"></a> + <!-- #end --> + </center> + <!--[if gte mso 9]> + </v:textbox> + </v:rect> + <![endif]--> + </td> + </tr> + </table> + </center> + </td> + </tr> + <tr> + <td valign="top" width="100%" style="background-color: #f7f7f7; text-align:left" class="content-padding"> + <center> + <p><b> Hi $firstName, <br> + You have been revoked with Organization Admin access for $CompName. Please contact your respective admin for further details.<br> + Thank you! </p></b> + </center> + </td> + </tr> + </table> + </td> + </tr> + </table> + </center> + </td> + </tr> +</table> +</body> +</html> diff --git a/public/emails/remove_helpdeskadmin.vm b/public/emails/remove_helpdeskadmin.vm new file mode 100644 index 0000000..d3eadd1 --- /dev/null +++ b/public/emails/remove_helpdeskadmin.vm @@ -0,0 +1,316 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <title>Aurora Helpdesk</title> + + <style type="text/css"> + /* Take care of image borders and formatting, client hacks */ + img { max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;} + a img { border: none; } + table { border-collapse: collapse !important;} + #outlook a { padding:0; } + .ReadMsgBody { width: 100%; } + .ExternalClass { width: 100%; } + .backgroundTable { margin: 0 auto; padding: 0; width: 100% !important; } + table td { border-collapse: collapse; } + .ExternalClass * { line-height: 115%; } + .container-for-gmail-android { min-width: 600px; } + + + /* General styling */ + * { + font-family: Helvetica, Arial, sans-serif; + } + + body { + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: none; + width: 100% !important; + margin: 0 !important; + height: 100%; + color: #676767; + } + + td { + font-family: Helvetica, Arial, sans-serif; + font-size: 14px; + color: #777777; + text-align: center; + line-height: 21px; + } + + a { + color: #676767; + text-decoration: none !important; + } + + .pull-left { + text-align: left; + } + + .pull-right { + text-align: right; + } + + .header-lg, + .header-md, + .header-sm { + font-size: 32px; + font-weight: 700; + line-height: normal; + padding: 35px 0 0; + color: #4d4d4d; + } + + .header-md { + font-size: 24px; + } + + .header-sm { + padding: 5px 0; + font-size: 18px; + line-height: 1.3; + } + + .content-padding { + padding: 5px 5px 5px 10px; + } + + .mobile-header-padding-right { + width: 290px; + text-align: right; + padding-left: 10px; + } + + .mobile-header-padding-left { + width: 290px; + text-align: left; + padding-left: 10px; + } + + .free-text { + width: 100% !important; + padding: 10px 60px 0px; + } + + .button { + padding: 30px 0; + } + + + .mini-block { + border: 1px solid #e5e5e5; + border-radius: 5px; + background-color: #ffffff; + padding: 12px 15px 15px; + text-align: left; + width: 253px; + } + + .mini-container-left { + width: 278px; + padding: 10px 0 10px 15px; + } + + .mini-container-right { + width: 278px; + padding: 10px 14px 10px 15px; + } + + .product { + text-align: left; + vertical-align: top; + width: 175px; + } + + .total-space { + padding-bottom: 8px; + display: inline-block; + } + + .item-table { + padding: 50px 20px; + width: 560px; + } + + .item { + width: 300px; + } + + .mobile-hide-img { + text-align: left; + width: 125px; + } + + .mobile-hide-img img { + border: 1px solid #e6e6e6; + border-radius: 4px; + } + + .title-dark { + text-align: left; + border-bottom: 1px solid #cccccc; + color: #4d4d4d; + font-weight: 700; + padding-bottom: 5px; + } + + .item-col { + padding-top: 20px; + text-align: left; + vertical-align: top; + } + + .force-width-gmail { + min-width:600px; + height: 0px !important; + line-height: 1px !important; + font-size: 1px !important; + } + + </style> + + <style type="text/css" media="screen"> + @import url(http://fonts.googleapis.com/css?family=Oxygen:400,700); + </style> + + <style type="text/css" media="screen"> + @media screen { + /* Thanks Outlook 2013! */ + * { + font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; + } + } + </style> + + <style type="text/css" media="only screen and (max-width: 480px)"> + /* Mobile styles */ + @media only screen and (max-width: 480px) { + + table[class*="container-for-gmail-android"] { + min-width: 290px !important; + width: 100% !important; + } + + img[class="force-width-gmail"] { + display: none !important; + width: 0 !important; + height: 0 !important; + } + + table[class="w320"] { + width: 320px !important; + } + + + td[class*="mobile-header-padding-left"] { + width: 160px !important; + padding-left: 0 !important; + } + + td[class*="mobile-header-padding-right"] { + width: 160px !important; + padding-right: 0 !important; + } + + td[class="header-lg"] { + font-size: 24px !important; + padding-bottom: 5px !important; + } + + td[class="content-padding"] { + padding: 5px 0 5px !important; + } + + td[class="button"] { + padding: 5px 5px 30px !important; + } + + td[class*="free-text"] { + padding: 10px 18px 30px !important; + } + + td[class~="mobile-hide-img"] { + display: none !important; + height: 0 !important; + width: 0 !important; + line-height: 0 !important; + } + + td[class~="item"] { + width: 140px !important; + vertical-align: top !important; + } + + td[class~="quantity"] { + width: 50px !important; + } + + td[class~="price"] { + width: 90px !important; + } + + td[class="item-table"] { + padding: 30px 20px !important; + } + + td[class="mini-container-left"], + td[class="mini-container-right"] { + padding: 0 15px 15px !important; + display: block !important; + width: 290px !important; + } + } + </style> +</head> + +<body bgcolor="#f7f7f7"> +<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%"> + <tr> + <td align="left" valign="top" width="100%" style="background:repeat-x url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) #ffffff;"> + <center> + <img src="https://aurora-desk-dev.s3.ap-south-1.amazonaws.com/aurora.png" class="force-width-gmail"> + <table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="background-color:transparent"> + <tr> + <td width="100%" height="80" valign="top" style="text-align: center; vertical-align:middle;"> + <!--[if gte mso 9]> + <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;"> + <v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" /> + <v:textbox inset="0,0,0,0"> + <![endif]--> + <center> + <!-- #if ($logo_url) --> + <a href="https://aurora-desk.idc.tarento.com/"><img width="50" height="60" src="https://aurora-desk-dev.s3.ap-south-1.amazonaws.com/aurora.png" alt="logo"></a> + <!-- #end --> + </center> + <!--[if gte mso 9]> + </v:textbox> + </v:rect> + <![endif]--> + </td> + </tr> + </table> + </center> + </td> + </tr> + <tr> + <td valign="top" width="100%" style="background-color: #f7f7f7; text-align:left" class="content-padding"> + <center> + <p><b> Hi $firstName, <br> + You have been revoked with Helpdesk Admin access for $HelpdeskName. Please contact your respective admin for further details.<br> + Thank you! </p></b> + </center> + </td> + </tr> + </table> + </td> + </tr> + </table> + </center> + </td> + </tr> +</table> +</body> +</html> diff --git a/public/emails/ticket-status-update-aurora.vm b/public/emails/ticket-status-update-aurora.vm new file mode 100644 index 0000000..dee3a3f --- /dev/null +++ b/public/emails/ticket-status-update-aurora.vm @@ -0,0 +1,331 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <title>Aurora Helpdesk</title> + + <style type="text/css"> + /* Take care of image borders and formatting, client hacks */ + img { max-width: 600px; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;} + a img { border: none; } + table { border-collapse: collapse !important;} + #outlook a { padding:0; } + .ReadMsgBody { width: 100%; } + .ExternalClass { width: 100%; } + .backgroundTable { margin: 0 auto; padding: 0; width: 100% !important; } + table td { border-collapse: collapse; } + .ExternalClass * { line-height: 115%; } + .container-for-gmail-android { min-width: 600px; } + + + /* General styling */ + * { + font-family: Helvetica, Arial, sans-serif; + } + + body { + -webkit-font-smoothing: antialiased; + -webkit-text-size-adjust: none; + width: 100% !important; + margin: 0 !important; + height: 100%; + color: #676767; + } + + td { + font-family: Helvetica, Arial, sans-serif; + font-size: 14px; + color: #777777; + text-align: center; + line-height: 21px; + } + + a { + color: #676767; + text-decoration: none !important; + } + + .pull-left { + text-align: left; + } + + .pull-right { + text-align: right; + } + + .header-lg, + .header-md, + .header-sm { + font-size: 32px; + font-weight: 700; + line-height: normal; + padding: 35px 0 0; + color: #4d4d4d; + } + + .header-md { + font-size: 24px; + } + + .header-sm { + padding: 5px 0; + font-size: 18px; + line-height: 1.3; + } + + .content-padding { + padding: 20px 0 5px; + } + + .mobile-header-padding-right { + width: 290px; + text-align: right; + padding-left: 10px; + } + + .mobile-header-padding-left { + width: 290px; + text-align: left; + padding-left: 10px; + } + + .free-text { + width: 100% !important; + padding: 10px 60px 0px; + } + + .button { + padding: 30px 0; + } + + + .mini-block { + border: 1px solid #e5e5e5; + border-radius: 5px; + background-color: #ffffff; + padding: 12px 15px 15px; + text-align: left; + width: 253px; + } + + .mini-container-left { + width: 278px; + padding: 10px 0 10px 15px; + } + + .mini-container-right { + width: 278px; + padding: 10px 14px 10px 15px; + } + + .product { + text-align: left; + vertical-align: top; + width: 175px; + } + + .total-space { + padding-bottom: 8px; + display: inline-block; + } + + .item-table { + padding: 50px 20px; + width: 560px; + } + + .item { + width: 300px; + } + + .mobile-hide-img { + text-align: left; + width: 125px; + } + + .mobile-hide-img img { + border: 1px solid #e6e6e6; + border-radius: 4px; + } + + .title-dark { + text-align: left; + border-bottom: 1px solid #cccccc; + color: #4d4d4d; + font-weight: 700; + padding-bottom: 5px; + } + + .item-col { + padding-top: 20px; + text-align: left; + vertical-align: top; + } + + .force-width-gmail { + min-width:600px; + height: 0px !important; + line-height: 1px !important; + font-size: 1px !important; + } + + </style> + + <style type="text/css" media="screen"> + @import url(http://fonts.googleapis.com/css?family=Oxygen:400,700); + </style> + + <style type="text/css" media="screen"> + @media screen { + /* Thanks Outlook 2013! */ + * { + font-family: 'Oxygen', 'Helvetica Neue', 'Arial', 'sans-serif' !important; + } + } + </style> + + <style type="text/css" media="only screen and (max-width: 480px)"> + /* Mobile styles */ + @media only screen and (max-width: 480px) { + + table[class*="container-for-gmail-android"] { + min-width: 290px !important; + width: 100% !important; + } + + img[class="force-width-gmail"] { + display: none !important; + width: 0 !important; + height: 0 !important; + } + + table[class="w320"] { + width: 320px !important; + } + + + td[class*="mobile-header-padding-left"] { + width: 160px !important; + padding-left: 0 !important; + } + + td[class*="mobile-header-padding-right"] { + width: 160px !important; + padding-right: 0 !important; + } + + td[class="header-lg"] { + font-size: 24px !important; + padding-bottom: 5px !important; + } + + td[class="content-padding"] { + padding: 5px 0 5px !important; + } + + td[class="button"] { + padding: 5px 5px 30px !important; + } + + td[class*="free-text"] { + padding: 10px 18px 30px !important; + } + + td[class~="mobile-hide-img"] { + display: none !important; + height: 0 !important; + width: 0 !important; + line-height: 0 !important; + } + + td[class~="item"] { + width: 140px !important; + vertical-align: top !important; + } + + td[class~="quantity"] { + width: 50px !important; + } + + td[class~="price"] { + width: 90px !important; + } + + td[class="item-table"] { + padding: 30px 20px !important; + } + + td[class="mini-container-left"], + td[class="mini-container-right"] { + padding: 0 15px 15px !important; + display: block !important; + width: 290px !important; + } + } + </style> +</head> + +<body bgcolor="#f7f7f7"> +<table align="center" cellpadding="0" cellspacing="0" class="container-for-gmail-android" width="100%"> + <tr> + <td align="left" valign="top" width="100%" style="background:repeat-x url(http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg) #ffffff;"> + <center> + <img src="http://s3.amazonaws.com/swu-filepicker/SBb2fQPrQ5ezxmqUTgCr_transparent.png" class="force-width-gmail"> + <table cellspacing="0" cellpadding="0" width="100%" bgcolor="#ffffff" background="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" style="background-color:transparent"> + <tr> + <td width="100%" height="80" valign="top" style="text-align: center; vertical-align:middle;"> + <!--[if gte mso 9]> + <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style="mso-width-percent:1000;height:80px; v-text-anchor:middle;"> + <v:fill type="tile" src="http://s3.amazonaws.com/swu-filepicker/4E687TRe69Ld95IDWyEg_bg_top_02.jpg" color="#ffffff" /> + <v:textbox inset="0,0,0,0"> + <![endif]--> + <center> + <!-- <table cellpadding="0" cellspacing="0" width="600" class="w320"> + <tr> + #if ($logo_url) --> + <!-- <td class="pull-left mobile-header-padding-left" style="vertical-align: middle;"> + <a href=""><img height="47" src='$logo_url' alt="logo"></a> + </td> + #end + </tr> + </table> --> + <a href="https://aurora-desk.idc.tarento.com/"><img width="50" height="60" src="https://aurora-desk-dev.s3.ap-south-1.amazonaws.com/aurora.png" alt="logo"></a> + </center> + <!--[if gte mso 9]> + </v:textbox> + </v:rect> + <![endif]--> + </td> + </tr> + </table> + </center> + </td> + </tr> + <tr> + <td align="center" valign="top" width="100%" style="background-color: #f7f7f7;" class="content-padding"> + <center> + <p> Hi $firstName,</p> + <p>Status of your ticket <a href="https://aurora-desk.idc.tarento.com/desks/$HelpdeskId/tickets/"> $id </a> on helpdesk $helpdeskName is changed from $oldStatus to $newStatus. You may access ticket details using <a href="https://aurora-desk.idc.tarento.com/desks/$helpdeskId/tickets"> this link </a>.</p> + <p>Thank you!</p> + + </center> + </td> + </tr> + <tr> + <td align="center" valign="top" width="100%" style="background-color: #f7f7f7; height: 100px;"> + <center> + <table cellspacing="0" cellpadding="0" width="600" class="w320"> + <tr> + <td style="padding: 25px 0 25px"> + <strong>Aurora Helpdesk</strong><br /> + </td> + </tr> + </table> + </center> + </td> + </tr> +</table> +</div> +</body> +</html> diff --git a/public/images/9_IMG_5920.jpg b/public/images/9_IMG_5920.jpg new file mode 100644 index 0000000000000000000000000000000000000000..eb172585a2b99eaaa6cef55ffc0672e17f8f2343 GIT binary patch literal 68620 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	WGiF3FC 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ⅇ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 I)#twd03>W~9smFU literal 0 HcmV?d00001 diff --git a/src/main/java/org/upsmf/grievance/Application.java b/src/main/java/org/upsmf/grievance/Application.java new file mode 100644 index 0000000..1d4700e --- /dev/null +++ b/src/main/java/org/upsmf/grievance/Application.java @@ -0,0 +1,67 @@ +package org.upsmf.grievance; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.oauth2.provider.token.TokenStore; +import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +import org.upsmf.grievance.config.JwtAuthenticationFilter; +import org.upsmf.grievance.util.Constants; + +import javax.sql.DataSource; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @Bean + public WebMvcConfigurer corsConfigurer() { + return new WebMvcConfigurerAdapter() { + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**").allowedMethods(Constants.GET, Constants.POST, Constants.PUT, + Constants.DELETE, Constants.OPTIONS).allowedOrigins("*").allowedHeaders("*"); + } + }; + } + + @Bean + public JwtAuthenticationFilter authenticationTokenFilterBean() { + return new JwtAuthenticationFilter(); + } + + @Bean + public BCryptPasswordEncoder encoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } + + @Bean + public TokenStore tokenStore() { + return new InMemoryTokenStore(); + } + + //@Bean + /*public JdbcTemplate jdbcTemplate(DataSource dataSource) { + return new JdbcTemplate(dataSource); + }*/ + +} diff --git a/src/main/java/org/upsmf/grievance/config/CORSFilter.java b/src/main/java/org/upsmf/grievance/config/CORSFilter.java new file mode 100644 index 0000000..4a1b018 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/config/CORSFilter.java @@ -0,0 +1,46 @@ +package org.upsmf.grievance.config; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +@Component +@Order(0) +public class CORSFilter implements Filter { + + @Override + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) + throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin")); + response.setHeader("Access-Control-Allow-Credentials", "true"); + response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE"); + response.setHeader("Access-Control-Max-Age", "3600"); + response.setHeader("Access-Control-Allow-Headers", + "X-Requested-With, Content-Type, Authorization, Origin, Accept, Access-Control-Request-Method, Access-Control-Request-Headers"); + + chain.doFilter(req, res); + } + + @Override + public void init(FilterConfig filterConfig) { + + } + + @Override + public void destroy() { + + } + +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/config/JwtAuthenticationEntryPoint.java b/src/main/java/org/upsmf/grievance/config/JwtAuthenticationEntryPoint.java new file mode 100644 index 0000000..ed1f266 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/config/JwtAuthenticationEntryPoint.java @@ -0,0 +1,31 @@ +package org.upsmf.grievance.config; + +import java.io.IOException; +import java.io.Serializable; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +@Component +public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable { + /** + * + */ + private static final long serialVersionUID = 1L; + + @Override + public void commence(javax.servlet.http.HttpServletRequest httpServletRequest, + HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { + ServletContext ctx = httpServletRequest.getServletContext(); + if (!(Boolean) ctx.getAttribute("WhiteList")) { + httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); + } + + } + +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/config/JwtAuthenticationFilter.java b/src/main/java/org/upsmf/grievance/config/JwtAuthenticationFilter.java new file mode 100644 index 0000000..996f7da --- /dev/null +++ b/src/main/java/org/upsmf/grievance/config/JwtAuthenticationFilter.java @@ -0,0 +1,152 @@ +package org.upsmf.grievance.config; + +import static org.upsmf.grievance.util.Constants.HEADER_STRING; +import static org.upsmf.grievance.util.Constants.TOKEN_PREFIX; + +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.FilterChain; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.service.UserService; +import org.upsmf.grievance.util.ResponseGenerator; +import org.upsmf.grievance.util.ResponseMessages; + +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.SignatureException; + +public class JwtAuthenticationFilter extends OncePerRequestFilter { + + @Autowired + private UserService userService; + + @Autowired + private JwtTokenUtil jwtTokenUtil; + + @Value("${urls.whitelist}") + private String whitelistUrls; + + @Override + protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) + throws IOException, ServletException { + + + List<String> whitelistUrlList = Arrays.asList(whitelistUrls.split(",")); + + ServletContext ctx = req.getServletContext(); + Boolean whiteListed; + Boolean authorized = Boolean.FALSE; + String username = null; + String authToken = null; + UserDetails userDetails = null; + Map<String, Object> userInfoObectMap = new HashMap<>(); + + if (whitelistUrlList.contains(req.getRequestURI())) { + whiteListed = Boolean.TRUE; + } else { + whiteListed = Boolean.FALSE; + String header = req.getHeader(HEADER_STRING); + if (StringUtils.isBlank(header)) { + res.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + res.getWriter() + .write(ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.UNAUTHORIZED_ACCESS)); + res.setContentType("application/json"); + res.getWriter().flush(); + return; + } + if (header.startsWith(TOKEN_PREFIX)) { + authToken = header.replace(TOKEN_PREFIX, ""); + username = getUserName(username, authToken); + } else { + logger.warn("couldn't find bearer string, will ignore the header"); + } + if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { + userInfoObectMap = userService.getUserInfoObjects(username); + userDetails = (UserDetails) userInfoObectMap.get("UserDetails"); + if (jwtTokenUtil.validateToken(authToken, userDetails)) { + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( + userDetails, null, Arrays.asList(new SimpleGrantedAuthority("ROLE_ADMIN"))); + authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(req)); + logger.info("authenticated user " + username + ", setting security context"); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + } + + + Boolean userTokenAvailable = userService.findUserByToken(authToken); + authorized = checkForAuthorization(req, ctx, authorized, userDetails, userInfoObectMap, userTokenAvailable); + } + + if (!authorized && !whiteListed) { + res.setStatus(HttpServletResponse.SC_FORBIDDEN); + res.getWriter() + .write(ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.INVALID_ACCESS_ROLE)); + res.setContentType("application/json"); + res.getWriter().flush(); + return; + } + + chain.doFilter(req, res); + } + + public String getUserName(String username, String authToken) { + try { + username = jwtTokenUtil.getUsernameFromToken(authToken); + } catch (IllegalArgumentException e) { + logger.error("an error occured during getting username from token", e); + } catch (ExpiredJwtException e) { + logger.warn("the token is expired and not valid anymore", e); + } catch (SignatureException e) { + logger.error("Authentication Failed. Username or Password not valid."); + } + return username; + } + + public Boolean checkForAuthorization(HttpServletRequest req, ServletContext ctx, Boolean authorized, + UserDetails userDetails, Map<String, Object> userInfoObectMap, Boolean userTokenAvailable) { + if (userTokenAvailable) { + try { + if (userDetails != null) { + User user = (User) userInfoObectMap.get("User"); + req.setAttribute("UserInfo", user); + ctx.setAttribute("UserInfo", user); + List<Long> roleIds = MasterDataManager.getRoleIdsForUserId(user.getId()); + for (Long roleId : roleIds) { + List<String> actionUrlList = MasterDataManager.getActionUrlsForRoleId(roleId); + if (actionUrlList.contains(req.getRequestURI())) { + ctx.setAttribute("Authorized", Boolean.TRUE); + authorized = Boolean.TRUE; + break; + } + } + } + } catch (UsernameNotFoundException e) { + e.getMessage(); + } + } + return authorized; + } +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/config/JwtTokenUtil.java b/src/main/java/org/upsmf/grievance/config/JwtTokenUtil.java new file mode 100644 index 0000000..9c3e546 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/config/JwtTokenUtil.java @@ -0,0 +1,109 @@ +package org.upsmf.grievance.config; + +import static org.upsmf.grievance.util.Constants.ACCESS_TOKEN_VALIDITY_SECONDS; +import static org.upsmf.grievance.util.Constants.JWT_GRANTED_AUTHORITY; +import static org.upsmf.grievance.util.Constants.JWT_ISSUER; +import static org.upsmf.grievance.util.Constants.SIGNING_KEY; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Date; +import java.util.function.Function; + +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.upsmf.grievance.dto.UserDto; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +@Component +public class JwtTokenUtil implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + public static final String CLAIMS_KEY = "scopes"; + public static final String USER_REF = "userReference"; + public static final String ORG_REF = "orgReference"; + + public String getUsernameFromToken(String token) { + return getClaimFromToken(token, Claims::getSubject); + } + + public Long getUserIdFromToken(String token) { + final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, + false); + MyCustomJwtClaims customClaims = null; + try { + customClaims = mapper.convertValue(getAllClaimsFromToken(token), MyCustomJwtClaims.class); + } catch (Exception e) { + e.getMessage(); + } + if (customClaims != null && customClaims.getUserReference() != null) { + return customClaims.getUserReference(); + } + return null; + } + + public Long getOrgIdFromToken(String token) { + final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, + false); + MyCustomJwtClaims customClaims = null; + try { + customClaims = mapper.convertValue(getAllClaimsFromToken(token), MyCustomJwtClaims.class); + } catch (Exception e) { + e.getMessage(); + } + if (customClaims != null && customClaims.getOrgReference() != null) { + return customClaims.getOrgReference(); + } + return null; + } + + public Date getExpirationDateFromToken(String token) { + return getClaimFromToken(token, Claims::getExpiration); + } + + public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) { + final Claims claims = getAllClaimsFromToken(token); + return claimsResolver.apply(claims); + } + + private Claims getAllClaimsFromToken(String token) { + return Jwts.parser().setSigningKey(SIGNING_KEY).parseClaimsJws(token).getBody(); + } + + private Boolean isTokenExpired(String token) { + final Date expiration = getExpirationDateFromToken(token); + return expiration.before(new Date()); + } + + public String generateToken(UserDto user) { + return doGenerateToken(user.getUsername(), user.getId(), user.getOrgId()); + } + + private String doGenerateToken(String subject, Long userId, Long orgId) { + + Claims claims = Jwts.claims().setSubject(subject); + claims.put(CLAIMS_KEY, Arrays.asList(new SimpleGrantedAuthority(JWT_GRANTED_AUTHORITY))); + claims.put(USER_REF, userId); + claims.put(ORG_REF, orgId); + + return Jwts.builder().setClaims(claims).setIssuer(JWT_ISSUER).setIssuedAt(new Date(System.currentTimeMillis())) + .setExpiration(new Date(System.currentTimeMillis() + ACCESS_TOKEN_VALIDITY_SECONDS * 1000)) + .signWith(SignatureAlgorithm.HS256, SIGNING_KEY).compact(); + } + + public Boolean validateToken(String token, UserDetails userDetails) { + final String username = getUsernameFromToken(token); + return (username.equals(userDetails.getUsername()) && !isTokenExpired(token)); + } + +} diff --git a/src/main/java/org/upsmf/grievance/config/MyCustomJwtClaims.java b/src/main/java/org/upsmf/grievance/config/MyCustomJwtClaims.java new file mode 100644 index 0000000..4c305b5 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/config/MyCustomJwtClaims.java @@ -0,0 +1,32 @@ +package org.upsmf.grievance.config; + +public class MyCustomJwtClaims { + private String sub; + private Long userReference; + private Long orgReference; + + public String getSub() { + return sub; + } + + public void setSub(String sub) { + this.sub = sub; + } + + public Long getUserReference() { + return userReference; + } + + public void setUserReference(Long userReference) { + this.userReference = userReference; + } + + public Long getOrgReference() { + return orgReference; + } + + public void setOrgReference(Long orgReference) { + this.orgReference = orgReference; + } + +} diff --git a/src/main/java/org/upsmf/grievance/config/SwaggerConfig.java b/src/main/java/org/upsmf/grievance/config/SwaggerConfig.java new file mode 100644 index 0000000..8b4e39c --- /dev/null +++ b/src/main/java/org/upsmf/grievance/config/SwaggerConfig.java @@ -0,0 +1 @@ +package org.upsmf.grievance.config; \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/config/WebSecurityConfig.java b/src/main/java/org/upsmf/grievance/config/WebSecurityConfig.java new file mode 100644 index 0000000..c74d33c --- /dev/null +++ b/src/main/java/org/upsmf/grievance/config/WebSecurityConfig.java @@ -0,0 +1,63 @@ +package org.upsmf.grievance.config; + +import javax.annotation.Resource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Resource(name = "userService") + private UserDetailsService userDetailsService; + + @Autowired + private JwtAuthenticationEntryPoint unauthorizedHandler; + + @Value("${urls.whitelist}") + private String whiteListUrls; + + @Override + @Bean + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Autowired + public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService).passwordEncoder(encoder()); + } + + @Bean + public JwtAuthenticationFilter authenticationTokenFilterBean() { + return new JwtAuthenticationFilter(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.cors().and().csrf().disable().authorizeRequests().antMatchers("/**").permitAll().anyRequest() + .authenticated().and().exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class); + } + + @Bean + public BCryptPasswordEncoder encoder() { + return new BCryptPasswordEncoder(); + } + +} diff --git a/src/main/java/org/upsmf/grievance/constants/RequestContextConstants.java b/src/main/java/org/upsmf/grievance/constants/RequestContextConstants.java new file mode 100644 index 0000000..55d5dc5 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/constants/RequestContextConstants.java @@ -0,0 +1,25 @@ +package org.upsmf.grievance.constants; + +public class RequestContextConstants { + public static final String AUTH_BOOLEAN_FLAG_NAME = "shouldDoAuth"; + public static final String AUTH_TOKEN_KEY = "authToken"; + public static final String ERROR_MESSAGE_KEY = "error.message"; + public static final String ERROR_CODE_KEY = "error.status_code"; + public static final String GET = "GET"; + public static final String POST = "POST"; + public static final String FILESTORE_REGEX = "^/filestore/.*"; + public static final String REQUEST_INFO_FIELD_NAME_PASCAL_CASE = "RequestInfo"; + public static final String REQUEST_INFO_FIELD_NAME_CAMEL_CASE = "requestInfo"; + public static final String USER_INFO_FIELD_NAME = "userInfo"; + public static final String USER_INFO_KEY = "USER_INFO"; + public static final String CORRELATION_ID_FIELD_NAME = "correlationId"; + public static final String CORRELATION_ID_HEADER_NAME = "x-correlation-id"; + public static final String CORRELATION_ID_KEY = "CORRELATION_ID"; + public static final String RBAC_BOOLEAN_FLAG_NAME = "shouldDoRbac"; + public static final String SKIP_RBAC = "RBAC check skipped"; + public static final String RBAC_AVAILABLE = "RbacAvailable"; + + private RequestContextConstants() { + super(); + } +} diff --git a/src/main/java/org/upsmf/grievance/constants/package-info.java b/src/main/java/org/upsmf/grievance/constants/package-info.java new file mode 100644 index 0000000..524b989 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/constants/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author Juhi Agarwal + * + */ +package org.upsmf.grievance.constants; \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/controller/ApplicationController.java b/src/main/java/org/upsmf/grievance/controller/ApplicationController.java new file mode 100644 index 0000000..76f633e --- /dev/null +++ b/src/main/java/org/upsmf/grievance/controller/ApplicationController.java @@ -0,0 +1,132 @@ +package org.upsmf.grievance.controller; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.model.App; +import org.upsmf.grievance.model.StatusIdMap; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.service.ApplicationService; +import org.upsmf.grievance.util.PathRoutes; +import org.upsmf.grievance.util.ResponseGenerator; +import org.upsmf.grievance.util.ResponseMessages; + +@RestController +@RequestMapping(PathRoutes.APPS_ACTIONS_URL) +public class ApplicationController { + + private static final String KEYWORD = "keyword"; + private static final String ID = "id"; + private static final String ORG_ID = "orgId"; + private static final String USER_INFO = "UserInfo"; + + public static final Logger LOGGER = LoggerFactory.getLogger(ApplicationController.class); + + @Autowired + private ApplicationService applicationService; + + @PostMapping(value = PathRoutes.AppsRoutes.CREATE_APP) + public String createUpdateApp(@RequestAttribute(value = USER_INFO) User user, @RequestBody App app, + BindingResult result) throws JsonProcessingException { + if (result.hasErrors()) { + return ResponseGenerator.failureResponse(HttpStatus.UNPROCESSABLE_ENTITY.toString()); + } + + if (app != null) { + if (StringUtils.isBlank(app.getName())) { + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.ROLE_NAME_UNAVAILABLE); + } + } else { + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.ROLE_DETAILS_UNAVAILABLE); + } + user.setOrgId(app.getOrgId()); + App savedApp = applicationService.createApp(app, user); + if (savedApp != null) { + List<Object> savedApps = new ArrayList<>(); + savedApps.add(savedApp); + MasterDataManager.getAppObjectFromAppName(); + return ResponseGenerator.successResponse(savedApps); + } else { + return ResponseGenerator.failureResponse(HttpStatus.SERVICE_UNAVAILABLE.toString()); + } + } + + /** + * This method will return List of applications + * + * @param id + * Long + * @param keyword + * @param user + * User + * @return String + * @throws JsonProcessingException + */ + @GetMapping(value = PathRoutes.AppsRoutes.GET_APP) + public String getApp(@RequestParam(value = ID, required = false) Long id, + @RequestParam(value = KEYWORD, required = false) String keyword, + @RequestParam(value = ORG_ID, required = false) Long orgId, @RequestAttribute(value = USER_INFO) User user) + throws JsonProcessingException { + if (orgId != null) { + user.setOrgId(orgId); + } else { + user.setOrgId(null); + } + return ResponseGenerator.successResponse(applicationService.getApp(id, "", user)); + } + + @GetMapping(value = PathRoutes.AppsRoutes.GET_APP_BY_ORG_ID) + public String getAppByOrgId(@RequestParam(value = ORG_ID, required = false) Long orgId) + throws JsonProcessingException { + return ResponseGenerator.successResponse(applicationService.getApp(orgId)); + } + + /** + * This method will map an application to a helpdesk + * + * @param statusIdMap + * StatusIdMap + * @return String + * @throws JsonProcessingException + */ + @PostMapping(PathRoutes.AppsRoutes.MAP_APP_TO_HELPDESK) + public String mapAppsToHelpdesk(@RequestBody StatusIdMap statusIdMap) throws JsonProcessingException { + + boolean response = applicationService.mapAppsToHelpdesk(statusIdMap); + + if (response) { + return ResponseGenerator.successResponse(response); + } + + return ResponseGenerator.failureResponse(); + } + + /** + * This API will get the Master Data which has been maintained for the Service + * Request types available in the application + * + * @param user + * @return + * @throws JsonProcessingException + */ + @GetMapping(value = PathRoutes.AppsRoutes.GET_SERVICE_REQUEST) + public String getServiceRequests(@RequestAttribute(value = USER_INFO) User user) throws JsonProcessingException { + return ResponseGenerator.successResponse(applicationService.getServiceRequests()); + } +} diff --git a/src/main/java/org/upsmf/grievance/controller/ControllerRequestValidator.java b/src/main/java/org/upsmf/grievance/controller/ControllerRequestValidator.java new file mode 100644 index 0000000..96dc047 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/controller/ControllerRequestValidator.java @@ -0,0 +1,149 @@ + +package org.upsmf.grievance.controller; + +import java.util.List; + +import org.upsmf.grievance.dto.ChangePasswordDto; +import org.upsmf.grievance.dto.HelpdeskDto; +import org.upsmf.grievance.dto.HelpdeskTypeDto; +import org.upsmf.grievance.dto.UserDto; +import org.upsmf.grievance.exceptions.RequestDataMissingException; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.util.Constants; +import org.upsmf.grievance.util.ProjectUtil; + +/** + * @author Juhi This class will validate controller request. + */ +public class ControllerRequestValidator { + /** + * This method will parse user registration data. + * + * @param user + * UserDto + * @return boolean + * @throws RequestDataMissingException + */ + public static boolean validateRegistrationData(User user) { + boolean response = true; + if (ProjectUtil.isStringNullOrEmpty(user.getUsername())) { + throw new RequestDataMissingException(Constants.USER_NAME_MISSING); + } else if (ProjectUtil.isStringNullOrEmpty(user.getName())) { + throw new RequestDataMissingException(Constants.PHONE_NUMBER_MISSING); + } + return response; + } + + /** + * This method will validate change password data + * + * @param passwordDto + * ChangePasswordDto + * @return boolean + * @throws RequestDataMissingException + */ + public static boolean changePassword(ChangePasswordDto passwordDto) { + boolean response = true; + if (ProjectUtil.isStringNullOrEmpty(passwordDto.getOldPass())) { + throw new RequestDataMissingException(Constants.PSWRD_MISSING); + } else if (ProjectUtil.isStringNullOrEmpty(passwordDto.getNewPass())) { + throw new RequestDataMissingException(Constants.PSWRD_MISSING); + } else if (!passwordDto.getNewPass().equals(passwordDto.getConfirmNewPass())) { + throw new RequestDataMissingException(Constants.PSWRD_MISMATCH); + } else if (passwordDto.getNewPass().equals(passwordDto.getOldPass())) { + throw new RequestDataMissingException(Constants.PSWRD_SAME); + } + return response; + } + + /** + * This method will validate incoming login request data + * + * @param userDto + * ChangePasswordDto + * @return boolean + * @throws RequestDataMissingException + */ + public static boolean login(UserDto userDto) { + boolean response = true; + if (ProjectUtil.isStringNullOrEmpty(userDto.getUsername())) { + throw new RequestDataMissingException(Constants.USER_NAME_MISSING); + } else if (ProjectUtil.isStringNullOrEmpty(userDto.getPassword())) { + throw new RequestDataMissingException(Constants.PSWRD_MISSING); + } + return response; + } + + public static boolean forgotPassword(UserDto userDto) { + boolean response = true; + if (ProjectUtil.isStringNullOrEmpty(userDto.getUsername())) { + throw new RequestDataMissingException(Constants.USER_NAME_MISSING); + } + return response; + } + + /** + * This method validates the user id. + * + * @param userDto + * UserDto + * @return UserDto + * @throws RequestDataMissingException + */ + public static UserDto validateInputId(UserDto userDto) { + if (userDto.getId() == 0L) { + throw new RequestDataMissingException(Constants.USER_NAME_MISSING); + } + return userDto; + } + + /** + * This method validates primary details of the user + * + * @param userDto + * UserDto + * @return boolean + * @throws RequestDataMissingException + */ + public static boolean validateUserPrimaryDetails(UserDto userDto) { + boolean response = true; + if (userDto.getId() == 0L) { + throw new RequestDataMissingException(Constants.ID_MISSING); + } + + User user = new User(); + user.setName(userDto.getName()); + user.setUsername(userDto.getUsername()); + validateRegistrationData(user); + + return response; + } + + /** + * This method validates primary details of the user + * + * @param userDto + * UserDto + * @return boolean + * @throws RequestDataMissingException + */ + public static boolean validateConfigureHelpdeskData(HelpdeskDto helpdeskDto) { + boolean response = true; + if (helpdeskDto.getTypes() != null && !helpdeskDto.getTypes().isEmpty()) { + List<HelpdeskTypeDto> typeDtoList = helpdeskDto.getTypes(); + for (HelpdeskTypeDto dto : typeDtoList) { + if (dto.getWorkflowStages() == null) { + throw new RequestDataMissingException(Constants.HELPDESKTYPE_WITHOUTWORKFLOW); + } else if (dto.getWorkflowStages().isEmpty()) { + throw new RequestDataMissingException(Constants.HELPDESKTYPE_WORKFLOW_EMPTY); + } + } + } + return response; + } + + private ControllerRequestValidator() { + super(); + } + +} diff --git a/src/main/java/org/upsmf/grievance/controller/HelpdeskController.java b/src/main/java/org/upsmf/grievance/controller/HelpdeskController.java new file mode 100644 index 0000000..fabb171 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/controller/HelpdeskController.java @@ -0,0 +1,170 @@ +package org.upsmf.grievance.controller; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.upsmf.grievance.dto.HelpdeskDto; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.model.Helpdesk; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.service.HelpdeskService; +import org.upsmf.grievance.util.PathRoutes; +import org.upsmf.grievance.util.ProjectUtil; +import org.upsmf.grievance.util.ResponseGenerator; +import org.upsmf.grievance.util.Sql; + +/** + * This controller will handle all the helpdesk related API's + * + * @author nivetha + * + */ +@RestController +@RequestMapping(PathRoutes.HELPDESK_URL) +public class HelpdeskController { + + private static final String ID = "id"; + private static final String USER_INFO = "UserInfo"; + private static final String USER_ID = "userId"; + @Autowired + private HelpdeskService helpdeskService; + + /** + * This method will add or update helpdesk of an organization + * + * @param helpdesk + * Helpdesk + * @param user + * User + * @return String + * @throws JsonProcessingException + */ + @PostMapping(PathRoutes.HelpdeskRoutes.CREATE_UPDATE_HELPDESK) + public String createUpdateHelpdesk(@RequestBody HelpdeskDto helpdeskDto, + @RequestAttribute(value = USER_INFO) User user) throws JsonProcessingException { + + boolean response = helpdeskService.createUpdateHelpdesk(helpdeskDto, user); + + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(); + } + + /** + * This method gives all the active helpdesk of an organization + * + * @param user + * User + * @return String + * @throws JsonProcessingException + */ + @GetMapping(PathRoutes.HelpdeskRoutes.GET_HELPDESK) + public String getHelpdesk(@RequestParam(value = "orgId", required = true) Long orgId, + @RequestParam(value = USER_ID, required = false) Long userId, + @RequestAttribute(value = USER_INFO) User user, @RequestParam(value = ID, required = false) Long id) + throws JsonProcessingException { + List<HelpdeskDto> helpdesks; + List<HelpdeskDto> newHelpdesks = new ArrayList<>(); + if (id != null && id > 0) { + helpdesks = helpdeskService.getHelpdeskById(orgId, id); + return ResponseGenerator.successResponse(helpdesks); + } else { + helpdesks = helpdeskService.getHelpdesk(orgId); + } + try { + if (!ProjectUtil.isObjectNull(userId)) { + if (MasterDataManager.getRoleMap().get(MasterDataManager.getUserRoleMap().get(userId)).getName() + .equalsIgnoreCase(Sql.Common.SUPER_ADMIN) + || MasterDataManager.getRoleMap().get(MasterDataManager.getUserRoleMap().get(userId)).getName() + .equalsIgnoreCase(Sql.Common.ORGADMIN)) { + return ResponseGenerator.successResponse(helpdesks); + } else { + return ResponseGenerator.successResponse(checkIfHelpdeskEmpty(user, helpdesks, newHelpdesks)); + } + } else { + return ResponseGenerator.successResponse(checkIfHelpdeskEmpty(user, helpdesks, newHelpdesks)); + } + } catch (Exception e) { + return ResponseGenerator.failureResponse(); + } + } + + private List<HelpdeskDto> checkIfHelpdeskEmpty(User user, List<HelpdeskDto> helpdesks, + List<HelpdeskDto> newHelpdesks) { + helpdeskService.getHelpdeskAdminUser(helpdesks); + for (int i = 0; i < helpdesks.size(); i++) { + HelpdeskDto helpdeskDto = helpdesks.get(i); + List<Long> user2 = helpdeskDto.getAdmins().stream().map(User::getId).collect(Collectors.toList()); + List<Long> user3 = helpdeskDto.getUsers().stream().map(User::getId).collect(Collectors.toList()); + List<Long> combinedList = Stream.of(user2, user3).flatMap(x -> x.stream()).collect(Collectors.toList()); + for (Long u : combinedList) { + if (u.equals(user.getId()) && !newHelpdesks.contains(helpdeskDto)) { + newHelpdesks.add(helpdeskDto); + } + } + } + return newHelpdesks; + } + + /** + * This method sets up the configuration for a helpdesk + * + * @param user + * User + * @return String + * @throws JsonProcessingException + */ + @PostMapping(PathRoutes.HelpdeskRoutes.CONFIGURE_HELPDESK) + public String configureHelpdesk(@RequestBody HelpdeskDto helpdeskDto, + @RequestAttribute(value = USER_INFO) User user) throws JsonProcessingException { + ControllerRequestValidator.validateConfigureHelpdeskData(helpdeskDto); + boolean response = helpdeskService.configureHelpdesk(helpdeskDto, user); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(); + + } + + @PostMapping(PathRoutes.HelpdeskRoutes.ADD_UPDATE_HELPDESK_ADMINS) + public String addUpdateHelpdeskAdmins(@RequestBody Helpdesk helpdesk, + @RequestAttribute(value = USER_INFO) User user) throws JsonProcessingException { + boolean response = helpdeskService.addUpdateHelpdeskAdmins(helpdesk, user); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(); + } + + @GetMapping(PathRoutes.HelpdeskRoutes.GET_HELPDESK_ADMINS) + public String getHelpdeskAdmins(@RequestParam(value = ID, required = true) Long id) throws JsonProcessingException { + + List<Long> admins = helpdeskService.getHelpdeskAdmins(id); + + return ResponseGenerator.successResponse(admins); + } + + @GetMapping(PathRoutes.HelpdeskRoutes.GET_PERFORMANCE_WITH_ACCESSCONTROL) + public String getPerformanceApiWithAccessControl() throws JsonProcessingException { + return ResponseGenerator.successResponse("getPerformanceApiWithAccessControl"); + } + + @GetMapping(PathRoutes.HelpdeskRoutes.GET_PERFORMANCE_WITHOUT_ACCESSCONTROL) + public String getPerformanceApiWithoutAccessControl() throws JsonProcessingException { + return ResponseGenerator.successResponse("getPerformanceApiWithoutAccessControl"); + } + +} diff --git a/src/main/java/org/upsmf/grievance/controller/RoleActionController.java b/src/main/java/org/upsmf/grievance/controller/RoleActionController.java new file mode 100644 index 0000000..3bbc218 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/controller/RoleActionController.java @@ -0,0 +1,123 @@ +package org.upsmf.grievance.controller; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.model.Role; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.service.RoleActionService; +import org.upsmf.grievance.util.PathRoutes; +import org.upsmf.grievance.util.ResponseGenerator; +import org.upsmf.grievance.util.ResponseMessages; + +@RestController +@RequestMapping(PathRoutes.ROLE_ACTIONS_URL) +public class RoleActionController { + + private static final String ORG_ID = "orgId"; + private static final String USER_ID = "userId"; + private static final String USER_INFO = "UserInfo"; + + public static final Logger LOGGER = LoggerFactory.getLogger(RoleActionController.class); + + @Autowired + private RoleActionService roleActionService; + + @GetMapping(value = PathRoutes.RoleActionRoutes.LIST_ROLES_GET) + public String listRoles(@RequestParam(value = ORG_ID, required = true) Long orgId) throws JsonProcessingException { + List<Role> data = roleActionService.getAllRoles(orgId); + if (data != null) { + return ResponseGenerator.successResponse(data); + } else { + return ResponseGenerator.failureResponse(); + } + } + + @PostMapping(value = PathRoutes.RoleActionRoutes.ADD_ROLE_POST) + public String saveRole(@RequestAttribute(value = USER_INFO) User user, @RequestBody Role role, BindingResult result) + throws JsonProcessingException { + if (result.hasErrors()) { + return ResponseGenerator.failureResponse(HttpStatus.UNPROCESSABLE_ENTITY.toString()); + } + + if (role != null) { + if (StringUtils.isBlank(role.getName())) { + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.ROLE_NAME_UNAVAILABLE); + } + } else { + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.ROLE_DETAILS_UNAVAILABLE); + } + role.setOrgId(user.getOrgId()); + Role savedRole = roleActionService.saveRole(role); + if (savedRole != null) { + List<Object> savedRoles = new ArrayList<>(); + savedRoles.add(savedRole); + return ResponseGenerator.successResponse(savedRoles); + } else { + return ResponseGenerator.failureResponse(HttpStatus.SERVICE_UNAVAILABLE.toString()); + } + } + + @PostMapping(value = PathRoutes.RoleActionRoutes.ROLE_BY_ID_GET) + public String getOne(@RequestAttribute(value = USER_INFO) User user, @RequestBody Role role, BindingResult result) + throws JsonProcessingException { + role.setOrgId(user.getOrgId()); + String roles = roleActionService.findById(role); + if (roles != null) { + return ResponseGenerator.successResponse(roles); + } else { + return ResponseGenerator.failureResponse("Couldn't fetch this role"); + } + } + + @PostMapping(value = PathRoutes.RoleActionRoutes.UPDATE_ROLE_POST) + public String update(@RequestAttribute(value = USER_INFO) User user, @RequestBody Role role, BindingResult result) + throws JsonProcessingException { + if (result.hasErrors()) { + return ResponseGenerator.failureResponse(HttpStatus.UNPROCESSABLE_ENTITY.toString()); + } + + if (role != null) { + if (role.getId() == null) { + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.ROLE_ID_UNAVAILABLE); + } + if (StringUtils.isBlank(role.getName())) { + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.ROLE_NAME_UNAVAILABLE); + } + if (role.getId() <= 0) { + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.ROLE_ID_INVALID); + } + role.setOrgId(user.getOrgId()); + Role savedRole = roleActionService.updateRole(role); + if (savedRole != null) { + List<Object> savedRoles = new ArrayList<>(); + savedRoles.add(savedRole); + return ResponseGenerator.successResponse(savedRoles); + } + } + return ResponseGenerator.failureResponse(HttpStatus.SERVICE_UNAVAILABLE.toString()); + } + + @GetMapping(value = PathRoutes.RoleActionRoutes.MDM_CHECK) + public String mdmCheck(@RequestAttribute(value = USER_INFO) User user, + @RequestParam(value = USER_ID, required = false) Long userId) { + return MasterDataManager.getRoleForUser(userId).toString(); + } + +} diff --git a/src/main/java/org/upsmf/grievance/controller/SuperAdminController.java b/src/main/java/org/upsmf/grievance/controller/SuperAdminController.java new file mode 100644 index 0000000..a67e799 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/controller/SuperAdminController.java @@ -0,0 +1,140 @@ +package org.upsmf.grievance.controller; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.model.CommonDataModel; +import org.upsmf.grievance.model.Organization; +import org.upsmf.grievance.model.StatusIdMap; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.model.enums.AuthTypes; +import org.upsmf.grievance.service.SuperAdminService; +import org.upsmf.grievance.util.PathRoutes; +import org.upsmf.grievance.util.ResponseGenerator; +import org.upsmf.grievance.util.ResponseMessages; + +@RestController +@RequestMapping(PathRoutes.SUPERADMIN_ACTIONS_URL) +public class SuperAdminController { + + private static final String USER_ID = "userId"; + private static final String ID = "id"; + private static final String USER_INFO = "UserInfo"; + @Autowired + private SuperAdminService superAdminService; + + @GetMapping(value = PathRoutes.SuperAdminRoutes.GET_ALL_ORG) + public String getAllOrganization(@RequestParam(value = ID, required = false) Long id, + @RequestParam(value = USER_ID, required = false) Long userId) throws JsonProcessingException { + List<Organization> orgList = new ArrayList<>(); + if (id != null && id > 0) { + Organization response = superAdminService.getOrganizationById(id); + orgList.add(response); + } else if (userId != null) { + List<Organization> response = superAdminService.getOrganizationByUserId(userId); + orgList = response; + } else { + orgList = superAdminService.getAllOrganization(); + } + if (!orgList.isEmpty()) { + return ResponseGenerator.successResponse(orgList); + } + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.GETALLORG_FAILED); + } + + @PostMapping(value = PathRoutes.SuperAdminRoutes.ADD_ORGANIZATION) + public String addOrganization(@RequestBody Organization organization) throws JsonProcessingException { + Organization response = superAdminService.addOrganization(organization); + if (response != null) { + MasterDataManager.getAllOrgRoles(); + MasterDataManager.getUserIdAndUserName(); + MasterDataManager.getAllOrgUsers(); + MasterDataManager.getAllUserRoles(); + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.ADD_ORG_FAILED); + } + + @PostMapping(value = PathRoutes.SuperAdminRoutes.DELETE_ORGANIZATION) + public String deleteOrganization(@RequestAttribute(value = USER_INFO) User user, + @RequestBody Organization organization) throws JsonProcessingException { + organization.setUserId(user.getId()); + boolean response = superAdminService.deleteOrganization(organization); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.DELETE_ORG_FAILED); + } + + @PostMapping(value = PathRoutes.SuperAdminRoutes.UPDATE_ORG_BY_ID) + public String updateOrganizationById(@RequestAttribute(value = USER_INFO) User user, + @RequestBody Organization organization) throws JsonProcessingException { + organization.setUserId(user.getId()); + boolean response = superAdminService.updateOrganizationById(organization); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.UPDATE_ORG_FAILED); + } + + @PostMapping(value = PathRoutes.SuperAdminRoutes.ADD_ADMIN) + public String addAdmin(@RequestAttribute(value = USER_INFO) User user, @RequestBody CommonDataModel commonDataModel) + throws JsonProcessingException { + boolean response = superAdminService.addAdmin(commonDataModel.getUserId()); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.UPDATE_ORG_FAILED); + } + + @PostMapping(value = PathRoutes.SuperAdminRoutes.REMOVE_ADMIN) + public String removeAdmin(@RequestAttribute(value = USER_INFO) User user, + @RequestBody CommonDataModel commonDataModel) throws JsonProcessingException { + boolean response = superAdminService.removeAdmin(commonDataModel.getUserId()); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.UPDATE_ORG_FAILED); + } + + /** + * This method will map an application to an organization + * + * @param statusIdMap + * StatusIdMap + * @return String + * @throws JsonProcessingException + */ + @PostMapping(PathRoutes.SuperAdminRoutes.MAP_APPS_TO_ORG) + public String mapAppsToOrg(@RequestBody StatusIdMap statusIdMap) throws JsonProcessingException { + + boolean response = superAdminService.mapAppsToOrg(statusIdMap); + + if (response) { + return ResponseGenerator.successResponse(response); + } + + return ResponseGenerator.failureResponse(); + } + + @GetMapping(value = PathRoutes.SuperAdminRoutes.GET_AUTH_TYPES) + public String getAuthTypes() throws JsonProcessingException { + final List<CommonDataModel> authTypes = new ArrayList<>(); + for (final AuthTypes key : AuthTypes.values()) { + authTypes.add(new CommonDataModel(key)); + } + return ResponseGenerator.successResponse(authTypes); + } + +} diff --git a/src/main/java/org/upsmf/grievance/controller/TagController.java b/src/main/java/org/upsmf/grievance/controller/TagController.java new file mode 100644 index 0000000..ee6e26e --- /dev/null +++ b/src/main/java/org/upsmf/grievance/controller/TagController.java @@ -0,0 +1,79 @@ +package org.upsmf.grievance.controller; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.upsmf.grievance.dto.TicketTagDto; +import org.upsmf.grievance.model.Tags; +import org.upsmf.grievance.model.TicketsTagsList; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.service.TagService; +import org.upsmf.grievance.util.PathRoutes; +import org.upsmf.grievance.util.ResponseGenerator; + +@RestController +@RequestMapping(PathRoutes.TAGS_URL) +public class TagController { + + private static final String ID = "id"; + private static final String ORG_ID = "orgId"; + private static final String USER_INFO = "UserInfo"; + + public static final Logger LOGGER = LoggerFactory.getLogger(TagController.class); + + @Autowired + private TagService tagService; + + @PostMapping(value = PathRoutes.TagRoutes.CREATE_TAG) + public String createUpdateTag(@RequestAttribute(value = USER_INFO) User user, + @RequestBody TicketTagDto ticketTagDto) throws JsonProcessingException { + boolean saved = tagService.saveTags(ticketTagDto, user.getId()); + if (saved) { + return ResponseGenerator.successResponse(saved); + } + return ResponseGenerator.failureResponse(); + + } + + @GetMapping(value = PathRoutes.TagRoutes.GET_TAG_BY_ORG_ID) + public String getOrgTags(@RequestAttribute(value = USER_INFO) User user, + @RequestParam(value = ORG_ID, required = true) Long orgId) throws JsonProcessingException { + TicketsTagsList tags = tagService.getAllOrgTags(orgId); + if (tags != null) { + return ResponseGenerator.successResponse(tags); + } + return ResponseGenerator.failureResponse(); + } + + @GetMapping(value = PathRoutes.TagRoutes.GET_TAG_BY_HELPDESK_ID) + public String getHelpdeskTags(@RequestAttribute(value = USER_INFO) User user, + @RequestParam(value = ID, required = true) Long id) throws JsonProcessingException { + TicketsTagsList tags = tagService.getHelpdeskTags(id, user.getId()); + if (tags.getTags() != null) { + return ResponseGenerator.successResponse(tags); + } + return ResponseGenerator.failureResponse(); + } + + @GetMapping(value = PathRoutes.TagRoutes.GET_ALL_TICKET_TAGS) + public String getAllTicketTags(@RequestAttribute(value = USER_INFO) User user, + @RequestParam(value = ID, required = true) Long id) throws JsonProcessingException { + List<Tags> response = tagService.getAllTicketTags(id); + if (response != null) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(); + } + +} diff --git a/src/main/java/org/upsmf/grievance/controller/TicketController.java b/src/main/java/org/upsmf/grievance/controller/TicketController.java new file mode 100644 index 0000000..ecad792 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/controller/TicketController.java @@ -0,0 +1,319 @@ +package org.upsmf.grievance.controller; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.upsmf.grievance.dao.HelpdeskDao; +import org.upsmf.grievance.dto.TicketTypeDto; +import org.upsmf.grievance.model.ActivityLog; +import org.upsmf.grievance.model.Analytics; +import org.upsmf.grievance.model.CommonDataModel; +import org.upsmf.grievance.model.TemplateVersion; +import org.upsmf.grievance.model.Ticket; +import org.upsmf.grievance.model.TicketCount; +import org.upsmf.grievance.model.TicketElastic; +import org.upsmf.grievance.model.Updates; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.model.enums.PriorityLevels; +import org.upsmf.grievance.service.TicketService; +import org.upsmf.grievance.util.Constants; +import org.upsmf.grievance.util.PathRoutes; +import org.upsmf.grievance.util.ResponseGenerator; + +/** + * This controller contains all the ticket related methods + * + * @author Juhi Agarwal + * + */ +@RestController +@RequestMapping(PathRoutes.TICKET_ACTIONS_URL) +public class TicketController { + + private static final String ID = "id"; + + private static final String USER_INFO = "UserInfo"; + + @Autowired + private TicketService ticketService; + + @Autowired + private HelpdeskDao helpdeskDao; + + @PostMapping(PathRoutes.TicketRoutes.ADD_TICKET) + public String addTicket(@RequestAttribute(value = USER_INFO) User user, @RequestBody Ticket ticket) + throws JsonProcessingException { + ticket = ticketService.addTicket(ticket); + if (ticket != null) { + return ResponseGenerator.successResponse(ticket); + } + return ResponseGenerator.failureResponse(); + + } + + @PostMapping(PathRoutes.TicketRoutes.UPLOAD_ATTACHMENT) + public String uploadAttachment(@RequestAttribute(value = USER_INFO) User user, + @RequestParam(value = "file", required = false) MultipartFile file, @RequestBody Ticket ticket) + throws JsonProcessingException { + ticket.setUserId(user.getId()); + ticket.setOrgId(user.getOrgId()); + boolean response = ticketService.attachmentUpload(file, ticket); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(); + + } + + @PostMapping(PathRoutes.TicketRoutes.UPDATE_TICKET_BASIC) + public String updateTicketBasic(@RequestAttribute(value = USER_INFO) User user, + @RequestParam(value = "file", required = false) MultipartFile file, @RequestBody Ticket ticket) + throws JsonProcessingException { + ticket.setOrgId(user.getOrgId()); + ticket.setUserId(user.getId()); + boolean response = false; + response = ticketService.updateTicketBasic(file, ticket); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(); + + } + + @PostMapping(PathRoutes.TicketRoutes.PINNED_TICKET) + public String pinTicket(@RequestAttribute(value = USER_INFO) User user, @RequestBody Ticket ticket) + throws JsonProcessingException { + ticket.setOrgId(user.getOrgId()); + ticket.setUserId(user.getId()); + boolean response = false; + response = ticketService.pinTicket(ticket); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(); + + } + + @PostMapping(PathRoutes.TicketRoutes.UPDATE_TICKET_TYPE) + public String updateTicketType(@RequestAttribute(value = USER_INFO) User user, + @RequestBody TicketTypeDto ticketTypeDto) throws JsonProcessingException { + ticketTypeDto.setOrgId(user.getOrgId()); + boolean response = ticketService.updateTicketType(ticketTypeDto, user.getId()); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(); + + } + + @PostMapping(PathRoutes.TicketRoutes.UPDATE_TICKET_STATUS) + public String updateTicketStatus(@RequestAttribute(value = USER_INFO) User user, @RequestBody Ticket ticket) + throws JsonProcessingException { + ticket.setRequestedBy(user.getId()); + ticket.setOrgId(user.getOrgId()); + boolean response = ticketService.updateTicketStatus(ticket); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(); + + } + + @PostMapping(PathRoutes.TicketRoutes.UPDATE_TICKET_CHECKLIST) + public String updateTicketChecklist(@RequestAttribute(value = USER_INFO) User user, @RequestBody Ticket ticket) + throws JsonProcessingException { + ticket.setOrgId(user.getOrgId()); + boolean response = ticketService.updateTicketChecklist(ticket); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(); + + } + + @GetMapping(PathRoutes.TicketRoutes.GET_ALL_TICKETS) + public String getTickets(@RequestAttribute(value = Constants.RequestParams.USER_INFO) User user, + @RequestParam(value = Constants.RequestParams.ID, required = false) Long id, + @RequestParam(value = Constants.RequestParams.APP_ID, required = false) Long appId) + throws JsonProcessingException { + if (id != null && id > 0) { + Ticket tickets = ticketService.getTicketsById(user, id); + return ResponseGenerator.successResponse(tickets); + } else if (appId != null && appId > 0) { + List<Ticket> tickets = ticketService.getAllTicketsByAppId(appId); + return ResponseGenerator.successResponse(tickets); + } else { + List<Ticket> tickets = ticketService.getAllTicketsByUserId(user.getId()); + return ResponseGenerator.successResponse(tickets); + } + } + + @PostMapping(PathRoutes.TicketRoutes.GET_ALL_TICKETS) + public String getTicketDetailsByHelpdeskId(@RequestAttribute(value = USER_INFO) User user, + @RequestBody Ticket ticket) throws JsonProcessingException { + ticket.setUserId(user.getId()); + if (ticket.getHelpdeskId() != null && ticket.getHelpdeskId() > 0) { + List<TicketElastic> data = ticketService.getTicketDetailsByHelpdeskId(ticket); + return ResponseGenerator.successResponse(data); + } + return ResponseGenerator.failureResponse(); + } + + @PostMapping(PathRoutes.TicketRoutes.GET_TICKET_COUNT_PER_MONTH_PER_USER) + public String getTicketsCountPerMonthPerUser(@RequestAttribute(value = USER_INFO) User user, + @RequestBody Analytics analytics) throws JsonProcessingException { + analytics.setUserId(user.getId()); + if (analytics.getStartDate() != null && analytics.getEndDate() != null && !analytics.getStartDate().isEmpty() + && !analytics.getEndDate().isEmpty()) { + Map<String, Long> data = ticketService.getTicketsCountPerMonthPerUser(analytics); + return ResponseGenerator.successResponse(data); + } + return ResponseGenerator.failureResponse(); + } + + @PostMapping(PathRoutes.TicketRoutes.GET_FEEDBACK_FROM_AURORA_SDK) + public String getFeedBacksFromAuroraSdk(@RequestAttribute(value = USER_INFO) User user) + throws JsonProcessingException { + List<Ticket> tickets = ticketService.getFeedBacksFromAuroraSdk(); + if (tickets != null) { + return ResponseGenerator.successResponse(tickets); + } + return ResponseGenerator.failureResponse(); + + } + + @GetMapping(PathRoutes.TicketRoutes.GET_ACTIVITY_LOGS) + public String getActivityLogsPerTicket(@RequestParam(value = ID, required = true) Long id) + throws JsonProcessingException { + List<ActivityLog> activityLog = ticketService.getActivityLogsPerTicket(id); + if (activityLog != null) { + return ResponseGenerator.successResponse(activityLog); + } + return ResponseGenerator.failureResponse(); + } + + @GetMapping(PathRoutes.TicketRoutes.GET_ACTIVITY_LOGS_PER_USER) + public String getActivityLogsPerUser(@RequestAttribute(value = USER_INFO) User user) + throws JsonProcessingException { + List<ActivityLog> activityLog = ticketService.getActivityLogsPerUser(user.getId()); + if (activityLog != null) { + return ResponseGenerator.successResponse(activityLog); + } + return ResponseGenerator.failureResponse(); + } + + @PostMapping(PathRoutes.TicketRoutes.ADD_NOTES) + public String updateNotesToTicket(@RequestAttribute(value = USER_INFO) User user, @RequestBody Ticket ticket) + throws JsonProcessingException { + ticket.setRequestedBy(user.getId()); + boolean response = ticketService.updateNotesToTicket(ticket); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(); + + } + + @PostMapping(PathRoutes.TicketRoutes.ADD_UPDATE_UPDATES) + public String addUpdateUpdatesToTicket(@RequestAttribute(value = USER_INFO) User user, @RequestBody Updates updates) + throws JsonProcessingException { + Long id = user.getId(); + updates.setCreatedBy(id); + List<Ticket> ticketList = new ArrayList<>(); + Ticket ticket = ticketService.getTicketsById(user, updates.getTicketId()); + List<Long> admins = helpdeskDao.getHelpdeskAdmins(ticket.getHelpdeskId()); + Boolean admin = false; + if (admins.contains(id)) { + admin = true; + } + ticketList.add(ticket); + List<Ticket> tickets = ticketService.keepOnlyCreatedAndCopiedToTickets(id, ticketList); + if (tickets != null && !tickets.isEmpty() || admin) { + boolean response = ticketService.addUpdateUpdatesToTicket(updates); + if (response) { + return ResponseGenerator.successResponse(response); + } + } + return ResponseGenerator.failureResponse(); + + } + + @GetMapping(PathRoutes.TicketRoutes.GET_UPDATES) + public String getUpdatesForTicket(@RequestParam(value = ID, required = true) Long id) + throws JsonProcessingException { + List<Updates> update = ticketService.getUpdatesForTicket(id); + if (update != null) { + return ResponseGenerator.successResponse(update); + } + return ResponseGenerator.failureResponse(); + } + + @GetMapping(value = PathRoutes.TicketRoutes.GET_PRIORITY_LEVELS) + public String getPriorityLevels(@RequestAttribute(value = USER_INFO) User user) throws JsonProcessingException { + final List<CommonDataModel> priorityList = new ArrayList<>(); + for (final PriorityLevels key : PriorityLevels.values()) { + priorityList.add(new CommonDataModel(key)); + } + return ResponseGenerator.successResponse(priorityList); + } + + @GetMapping(value = PathRoutes.TicketRoutes.GET_TEMPLATES_VERSION) + public String getTemplatesVersion(@RequestAttribute(value = USER_INFO, required = false) User user) + throws JsonProcessingException { + Long version = ticketService.getTemplatesVersion(); + TemplateVersion templateVersion = new TemplateVersion(); + templateVersion.setTemplates(null); + templateVersion.setVersion(version); + return ResponseGenerator.successResponse(templateVersion); + } + + @GetMapping(value = PathRoutes.TicketRoutes.GET_TEMPLATES) + public String getTemplates(@RequestAttribute(value = USER_INFO, required = false) User user) + throws JsonProcessingException { + TemplateVersion templateVersion = ticketService.getTemplates(); + return ResponseGenerator.successResponse(templateVersion); + } + + @GetMapping(value = PathRoutes.TicketRoutes.GET_NO_OF_TICKETS) + public String getNoOfTicketsPerUser(@RequestAttribute(value = USER_INFO, required = false) User user) + throws JsonProcessingException { + TicketCount tc = ticketService.getNoOfTickets(user.getId()); + return ResponseGenerator.successResponse(tc); + } + + @PostMapping(PathRoutes.TicketRoutes.CONFIGURE_TEMPLATE) + public String configureTemplates(@RequestBody TemplateVersion templateVersion, + @RequestAttribute(value = USER_INFO) User user) throws JsonProcessingException { + boolean response = ticketService.configureTemplates(templateVersion); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(); + } + + @PostMapping(PathRoutes.TicketRoutes.SEND_REPLY_TO_REVIEWS) + public String sendRepliesToReviews(@RequestAttribute(value = USER_INFO) User user, @RequestBody Updates updates) + throws JsonProcessingException { + Long id = user.getId(); + updates.setCreatedBy(id); + boolean response = ticketService.sendRepliesToReviews(updates); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(); + + } + +} diff --git a/src/main/java/org/upsmf/grievance/controller/UserController.java b/src/main/java/org/upsmf/grievance/controller/UserController.java new file mode 100644 index 0000000..7529be7 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/controller/UserController.java @@ -0,0 +1,194 @@ +package org.upsmf.grievance.controller; + +import java.io.IOException; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.upsmf.grievance.dto.ChangePasswordDto; +import org.upsmf.grievance.dto.LoginDto; +import org.upsmf.grievance.dto.UserDto; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.model.Action; +import org.upsmf.grievance.model.RolesDto; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.service.UserService; +import org.upsmf.grievance.util.Constants; +import org.upsmf.grievance.util.PathRoutes; +import org.upsmf.grievance.util.ProjectUtil; +import org.upsmf.grievance.util.ResponseGenerator; +import org.upsmf.grievance.util.ResponseMessages; +import org.upsmf.grievance.util.Sql; + +@RestController +@RequestMapping(PathRoutes.USER_ACTIONS_URL) +public class UserController { + + private static final String BEARER = "Bearer "; + private static final String FILE2 = "file"; + private static final String ID = "id"; + private static final String ORG_ID = "orgId"; + private static final String USER_INFO = "UserInfo"; + + public static final Logger LOGGER = LoggerFactory.getLogger(UserController.class); + + @Autowired + private UserService userService; + + @PostMapping(value = PathRoutes.UserRoutes.USER_ACTIONS_POST) + public String getActions(@RequestBody RolesDto roles) throws JsonProcessingException { + List<Action> actions = userService.findAllActionsByRoleID(roles.getIds()); + return ResponseGenerator.successResponse(actions); + } + + @PostMapping(value = PathRoutes.UserRoutes.NUMBER_OF_USERS_GET) + public String getNumberOfUsers(@RequestBody RolesDto roles) throws JsonProcessingException { + return ResponseGenerator.successResponse(userService.getNumberOfUsers(roles.getId(), roles.isActive())); + } + + @GetMapping(value = PathRoutes.UserRoutes.NUMBER_OF_ROLES_GET) + public String getNumberOfRoles() throws JsonProcessingException { + return ResponseGenerator.successResponse(userService.getNumberOfRoles()); + } + + @GetMapping(value = PathRoutes.UserRoutes.USER_BY_ID_GET) + public String getOne(@RequestParam(value = ID, required = true) Long id) throws JsonProcessingException { + return ResponseGenerator.successResponse(userService.findById(id)); + } + + @GetMapping(value = PathRoutes.UserRoutes.LIST_USER_GET) + public String listUser(@RequestParam(value = ORG_ID, required = true) Long orgId) throws JsonProcessingException { + return ResponseGenerator.successResponse(userService.findAll(orgId)); + } + + @GetMapping(value = PathRoutes.UserRoutes.UPLOAD_PROFILE_PICTURE) + public String uploadProfilePicture(@RequestParam(value = FILE2, required = true) MultipartFile file, + @RequestAttribute(value = USER_INFO) User user) throws JsonProcessingException { + return ResponseGenerator.successResponse(userService.uploadFile(file, user.getId())); + } + + @GetMapping(value = PathRoutes.UserRoutes.GET_PROFILE_PICTURE) + public String getProfilePicture(@RequestAttribute(value = USER_INFO) User user) throws IOException { + return ResponseGenerator.successResponse(userService.getFile(user.getId())); + } + + @PostMapping(value = PathRoutes.UserRoutes.CREATE_UPDATE_USER_POST) + public String saveUser(@RequestAttribute(value = USER_INFO) User user, + @RequestParam(value = FILE2, required = false) MultipartFile file, @RequestBody User profile) + throws JsonProcessingException { + if (!StringUtils.isNotBlank(profile.getUsername())) { + ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.EMAIL_MANDATORY); + } + ControllerRequestValidator.validateRegistrationData(profile); + Long userId = userService.checkUserNameExists(profile.getUsername()); + if (!ProjectUtil.isObjectNull(profile.getId())) { + if (userId.equals(profile.getId())) { + return ResponseGenerator.successResponse(userService.update(file, profile)); + } else { + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.EMAIL_PHONE_ALREADY_EXISTS); + } + } else if (userId > 0) { + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.EMAIL_PHONE_ALREADY_EXISTS); + } + String name = MasterDataManager.getRoleMap().get(MasterDataManager.getUserRoleMap().get(user.getId())) + .getName(); + if (userId == 0 + && (name.equalsIgnoreCase(Sql.Common.SUPER_ADMIN) || name.equalsIgnoreCase(Sql.Common.ORGADMIN))) { + User isAdded = userService.save(file, user.getId(), profile); + if (isAdded != null) { + MasterDataManager.getAllOrgUsers(); + MasterDataManager.getAllUserRoles(); + return ResponseGenerator.successResponse(isAdded); + } + } + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.USER_PROFILE_SAVE_FAILURE); + } + + @PostMapping(value = PathRoutes.UserRoutes.LOGIN) + public String login(@RequestBody UserDto userDto) throws JsonProcessingException { + ControllerRequestValidator.login(userDto); + LoginDto response = userService.login(userDto); + if (response != null) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.LOGIN_FAILED); + } + + @PostMapping(value = PathRoutes.UserRoutes.FORGOT_PSWRD) + public String forgotPassword(@RequestBody UserDto userDto) throws JsonProcessingException { + ControllerRequestValidator.forgotPassword(userDto); + boolean forgotPasswordResponse = userService.forgotPassword(userDto); + + if (forgotPasswordResponse) { + return ResponseGenerator.successResponse(forgotPasswordResponse); + } + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.FORGOT_PSWRD_FAILED); + } + + @PostMapping(value = PathRoutes.UserRoutes.CHANGE_PSWRD) + public String changePassword(@RequestAttribute(value = USER_INFO) User user, + @RequestBody ChangePasswordDto changePasswordDto) throws JsonProcessingException { + ControllerRequestValidator.changePassword(changePasswordDto); + changePasswordDto.setUserId(user.getId()); + boolean response = userService.changePassword(changePasswordDto); + if (response) { + return ResponseGenerator.successResponse(response); + } + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.CHANGE_PSWRD_FAILED); + } + + @PostMapping(value = PathRoutes.UserRoutes.USER_ROLE_MAPPING_POST) + public String mapUserToRole(@RequestBody User user) throws JsonProcessingException { + if (user != null && user.getRoles() != null) { + if (user.getRoles().isEmpty()) { + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.ROLE_ID_UNAVAILABLE); + } + if (user.getId() == null) { + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.USER_ID_UNAVAILABLE); + } + } else { + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.ROLE_DETAILS_UNAVAILABLE); + } + Boolean mappingStatus = userService.mapUserToRole(user); + if (mappingStatus) { + return ResponseGenerator.successResponse(ResponseMessages.SuccessMessages.USER_ROLE_MAPPED); + } else { + return ResponseGenerator.failureResponse(HttpStatus.SERVICE_UNAVAILABLE.toString()); + } + } + + @GetMapping(value = PathRoutes.UserRoutes.LOGOUT_GET) + public String invalidateToken(@RequestHeader(value = Constants.AUTH_HEADER) String authToken) + throws JsonProcessingException { + Boolean status = false; + if (authToken != null) { + authToken = authToken.replace(BEARER, ""); + status = userService.invalidateToken(authToken); + } + if (status) { + return ResponseGenerator.successResponse(ResponseMessages.SuccessMessages.LOGOUT_SUCCESS); + } + return ResponseGenerator.failureResponse(ResponseMessages.ErrorMessages.LOGOUT_FAILED); + } + + @GetMapping(value = PathRoutes.UserRoutes.GET_REVIEWS) + public String getReviews(@RequestAttribute(value = USER_INFO) User user) throws IOException { + userService.getReviews(); + return ResponseGenerator.successResponse(); + } + +} diff --git a/src/main/java/org/upsmf/grievance/dao/ApplicationDao.java b/src/main/java/org/upsmf/grievance/dao/ApplicationDao.java new file mode 100644 index 0000000..5ea2ec7 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dao/ApplicationDao.java @@ -0,0 +1,64 @@ +package org.upsmf.grievance.dao; + +import java.util.List; + +import org.upsmf.grievance.model.App; +import org.upsmf.grievance.model.ServiceRequest; +import org.upsmf.grievance.model.StatusIdMap; +import org.upsmf.grievance.model.User; + +public interface ApplicationDao { + + public App createApp(App app, User user); + + /** + * This method will return an application information + * + * @param id + * Long + * @param orgId + * Long + * @return List<App> + */ + public List<App> getApp(Long id); + + /** + * This method will return all the applications + * + * @return List<App> + */ + public List<App> getAllApps(); + + /** + * This method will return applications assigned to an org + * + * @param orgId + * Long + * @return List<App> + */ + public List<App> getAppsByOrgId(Long orgId); + + /** + * This method will map an application to a helpdesk + * + * @param statusIdMap + * StatusIdMap + * @return boolean + */ + public boolean mapAppsToHelpdesk(StatusIdMap statusIdMap); + + /** + * This method will fetch the available Service Requests from the database and + * map it to a list of Service Request Objects and returns to the Service Layer + * + * @return List<ServiceRequest> + */ + public List<ServiceRequest> getServiceRequests(); + + public List<App> getAppIdAndAppObject(); + + App updateApp(App app, User user); + + List<String> getDistinctAppNames(Long orgId); + +} diff --git a/src/main/java/org/upsmf/grievance/dao/HelpdeskDao.java b/src/main/java/org/upsmf/grievance/dao/HelpdeskDao.java new file mode 100644 index 0000000..b412dd7 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dao/HelpdeskDao.java @@ -0,0 +1,66 @@ +package org.upsmf.grievance.dao; + +import java.util.List; + +import org.upsmf.grievance.dto.HelpdeskDto; +import org.upsmf.grievance.dto.HelpdeskTypeDto; +import org.upsmf.grievance.model.ChecklistItem; +import org.upsmf.grievance.model.HelpDeskApp; +import org.upsmf.grievance.model.Helpdesk; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.model.mapper.SqlDataMapper.HelpdeskRowRecordMapper; + +public interface HelpdeskDao { + + /** + * This method will add or update helpdesk of an organization + * + * @param helpdesk + * Helpdesk + * @return boolean + */ + boolean createUpdateHelpdesk(Helpdesk app); + + /** + * This method gives all the active helpdesk of an organization + * + * @param orgId + * Long + * @return List<Helpdesk> + */ + Boolean deleteWorkflowForHelpdeskType(Long typeId); + + Boolean deleteChecklistForHelpdeskType(Long helpdeskId, Long typeId); + + Boolean deleteTypeForHelpdesk(Long helpdeskId); + + Boolean addTypeForHelpdesk(HelpdeskTypeDto helpdeskTypeDto, Long helpdeskId); + + Boolean addChecklistForHelpdeskType(HelpdeskTypeDto helpdeskTypeDto, Long helpdeskId); + + Boolean addWorkflowForHelpdeskType(HelpdeskTypeDto helpdeskTypeDto); + + List<Long> getHelpdeskAdmins(Long id); + + boolean addUpdateHelpdeskAdmins(Helpdesk helpdesk); + + List<HelpdeskDto> getAllHelpdesks(Long orgId); + + HelpdeskRowRecordMapper getHelpdeskForId(Long orgId, Long id); + + List<ChecklistItem> getChecklistItemsForHelpdesk(Long helpdeskId, Long typeId); + + List<HelpDeskApp> getAppIdAndHelpDeskId(); + + public List<Helpdesk> getHelpdeskObjectFromHelpdeskId(); + + boolean addUpdateHelpdeskUsers(Helpdesk helpdesk); + + List<User> getAdminForHelpeskId(Long helpdeskId); + + List<User> getUsersForHelpeskId(Long helpdeskId); + + List<HelpdeskDto> getHelpdeskAdminUser(List<HelpdeskDto> helpdeskList); + + List<Helpdesk> getHelpdeskByUserId(Long userId); +} diff --git a/src/main/java/org/upsmf/grievance/dao/RoleDao.java b/src/main/java/org/upsmf/grievance/dao/RoleDao.java new file mode 100644 index 0000000..8a39342 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dao/RoleDao.java @@ -0,0 +1,51 @@ +package org.upsmf.grievance.dao; + +import java.util.List; +import java.util.Map; + +import org.upsmf.grievance.model.Role; + +public interface RoleDao { + /** + * This method hits the DB and fetches all the available active roles + * + * @param fetchData + * @return + */ + public List<Role> getAllRoles(Long orgId); + + /** + * This method is used to save the Role Details in the Database + * + * @param role + * @return + */ + public Role saveRole(Role role); + + /** + * This method is used to update the Role Details based on the Role ID passed in + * the Role Object + * + * @param role + * @return + */ + public Role updateRole(Role role); + + /** + * This method supplies the ID to Database and fetches the Role for the ID and + * returns the Role Object + * + * @param role + * @return + */ + public String findById(Role role); + + public List<Role> getAllOrgRoles(); + + public void initializeActions(); + + public void intializeRolesAndActions(); + + public Map<Long, List<String>> getAllActionsForRoles(List<Long> roleIds); + +} diff --git a/src/main/java/org/upsmf/grievance/dao/SuperAdminDao.java b/src/main/java/org/upsmf/grievance/dao/SuperAdminDao.java new file mode 100644 index 0000000..054269f --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dao/SuperAdminDao.java @@ -0,0 +1,38 @@ +package org.upsmf.grievance.dao; + +import java.util.List; + +import org.upsmf.grievance.model.Organization; +import org.upsmf.grievance.model.S3Config; +import org.upsmf.grievance.model.StatusIdMap; +import org.upsmf.grievance.model.User; + +public interface SuperAdminDao { + + List<Organization> getAllOrganization(); + + Organization addOrganization(Organization organization); + + boolean updateOrganizationById(Organization organization); + + boolean deleteOrganization(Organization organization); + + int getOrganizationByUserId(long authUserId); + + boolean mapUserToOrg(long userId, int organisationId); + + boolean addAdmin(long userId); + + boolean removeAdmin(long userId); + + User userDetailsByUserId(long userId); + + boolean mapAppsToOrg(StatusIdMap statusIdMap); + + List<Organization> getOrganizationByUser(Long userId); + + S3Config getS3Access(); + + Organization getOrganizationByIdV2(Long id); + +} diff --git a/src/main/java/org/upsmf/grievance/dao/TagDao.java b/src/main/java/org/upsmf/grievance/dao/TagDao.java new file mode 100644 index 0000000..4f4ff68 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dao/TagDao.java @@ -0,0 +1,21 @@ +package org.upsmf.grievance.dao; + +import java.util.List; + +import org.upsmf.grievance.model.Tags; + +public interface TagDao { + + List<Tags> getAllTags(Long orgId); + + Tags getTagByName(String trim, Long id); + + Long addTag(Long id, Tags tag); + + boolean addTicketTags(Long id, List<Tags> tags); + + List<Tags> getAllTicketTags(Long id); + + List<Tags> getHelpdeskTags(Long id, Long userId); + +} diff --git a/src/main/java/org/upsmf/grievance/dao/TicketDao.java b/src/main/java/org/upsmf/grievance/dao/TicketDao.java new file mode 100644 index 0000000..dfed0c3 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dao/TicketDao.java @@ -0,0 +1,84 @@ +package org.upsmf.grievance.dao; + +import java.util.List; +import java.util.Map; + +import org.springframework.web.multipart.MultipartFile; + +import org.upsmf.grievance.dto.TicketTypeDto; +import org.upsmf.grievance.dto.TicketWorkflowDto; +import org.upsmf.grievance.model.ActivityLog; +import org.upsmf.grievance.model.Analytics; +import org.upsmf.grievance.model.ChecklistItem; +import org.upsmf.grievance.model.Ticket; +import org.upsmf.grievance.model.TicketCount; +import org.upsmf.grievance.model.TicketElastic; +import org.upsmf.grievance.model.Updates; + +/** + * This interface contains all the ticket related dao + * + * @author Juhi Agarwal + * + */ +public interface TicketDao { + + Ticket addTicket(Ticket ticket); + + Long getTemplatesVersion(); + + boolean updateTemplateVersion(Long versionTimeStamp); + + Boolean updateNotesToTicket(Long requestedBy, Long ticketId, String notes); + + Boolean addUpdateUpdatesToTicket(Updates update); + + Boolean deleteWorkflowForTicketType(Long typeId); + + Boolean addChecklistForTicketType(TicketTypeDto ticketTypeDto); + + boolean updateTicketBasic(MultipartFile file, Ticket ticket); + + Ticket getTicketsById(Long userId, Long id); + + List<ChecklistItem> getChecklistItemsForTicket(Long ticketId); + + List<Ticket> getAllTicketsByAppId(Long appId); + + List<TicketWorkflowDto> getWorkflowForTicket(Long ticketId); + + List<Updates> getUpdatesForTicket(Long id); + + boolean updateTicketType(TicketTypeDto ticketTypeDto, Long userId); + + boolean updateTicketStatus(Ticket ticket); + + boolean updateTicketChecklist(Ticket ticket); + + Boolean deleteChecklistForTicketType(TicketTypeDto ticketTypeDto); + + String addDefaultWorkflowForTicketType(TicketTypeDto ticketTypeDto); + + List<ActivityLog> getActivityLogsPerTicket(Long id); + + List<Ticket> getAllTicketsByUserId(Long id); + + List<TicketElastic> getTicketDetailsByHelpdeskId(Ticket ticket); + + boolean pinTicket(Ticket ticket); + + TicketCount getNoOfTickets(Long userId); + + List<ActivityLog> getActivityLogsPerUser(Long id); + + Map<String, Long> getTicketsCountPerMonthPerUser(Analytics analytics); + + boolean attachmentUpload(MultipartFile file, Ticket ticket); + + List<Ticket> keepOnlyCreatedAndCopiedToTickets(Long userId, List<Ticket> ticketList); + + List<Ticket> getFeedBacksFromAuroraSdk(); + + boolean sendRepliesToReviews(Updates updates); + +} diff --git a/src/main/java/org/upsmf/grievance/dao/UserDao.java b/src/main/java/org/upsmf/grievance/dao/UserDao.java new file mode 100644 index 0000000..0dc95d6 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dao/UserDao.java @@ -0,0 +1,188 @@ +package org.upsmf.grievance.dao; + +import java.io.IOException; +import java.util.List; + +import org.upsmf.grievance.dto.ChangePasswordDto; +import org.upsmf.grievance.dto.LoginDto; +import org.upsmf.grievance.dto.OrgUserRoleDto; +import org.upsmf.grievance.dto.UserDto; +import org.upsmf.grievance.model.Access; +import org.upsmf.grievance.model.Action; +import org.upsmf.grievance.model.CommonDataModel; +import org.upsmf.grievance.model.HelpDeskApp; +import org.upsmf.grievance.model.Role; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.model.UserAuthentication; +import org.upsmf.grievance.model.mapper.SqlDataMapper.UserDetailsMapper; +import org.upsmf.grievance.model.mapper.SqlDataMapper.UserRoleMapper; + +public interface UserDao { + + /** + * This method is used to fetch the User high level Object from the database + * based on the username parameter which is being passed + * + * @param username + * @return + */ + public User findByUsername(String username, Boolean withRoles, Boolean withActions); + + /** + * This method is used to fetch the User Detailed object from the database based + * on the User ID which is being passed + * + * @param id + * @return + */ + public List<User> findOne(Long id); + + /** + * This method receives the User ID and the List of Roles which are associated + * with the user Save the same to database for further Role Based Access + * + * @param list + * @param userId + * + * @param userRole + * @return + */ + public Boolean mapUserToRole(long userId, List<Role> list); + + /** + * This method receives the User Profile Object with updated Image URL and + * updates the same against the User ID + * + * @param profile + * @return + */ + public User updateUserImage(User profile); + + /** + * While adding a new user to the system, this method is called with Email ID + * and Phone Number to verify whether there already exists a user with same + * username as that of the Email ID and Phone Number This method responds with a + * long value of the User ID if exists and returns 0 in the case of negative + * scenario + * + * @param emailId + * @param phoneNo + * @return + */ + public Long checkUserNameExists(String username); + + /** + * On receiving the Role ID, this method fetches the Actions which are mapped to + * that role + * + * @param roleID + * @return + */ + public List<Action> findAllActionsByRoleID(Integer roleID); + + /** + * In order to show the count of Users available in the system, this method is + * invoked The method responds with the count of users available in the system + * + * @return + */ + public Long getNumberOfUsers(Long role, Boolean active); + + /** + * In order to show the count of Roles available in the system, this method is + * invoked The method responds with the count of roles available in the system + * + * @return + */ + public Long getNumberOfRoles(); + + /** + * This method receives the JWT Auth Token and invalidates the token from the + * Jwt Token Store and also removes the entry of the Token from the Database + * + * @param authToken + * @return + */ + public Boolean invalidateToken(String authToken); + + /** + * This method receives the Auth Token and finds out whether there is an active + * user for that Authentication Token Auth Token in this method is the JWT Token + * + * @param authToken + * @return + */ + public Boolean findUserByToken(String authToken); + + /** + * This method receives the Auth Token of the FCM and verifies whether the token + * is already registered against any User ID or not. + * + * @param userId + * @param deviceToken + * @return + */ + public Boolean checkUserTokenExists(Long userId, String deviceToken); + + /** + * This method receives the Device Token and the User ID and updates it against + * the record which is already available in the system database + * + * @param userId + * @param deviceToken + * @return + */ + + public UserAuthentication findOneUserAuthentication(Long id); + + public UserDetailsMapper findListOfUsers(List<Long> userIdList); + + public User update(User user); + + public UserRoleMapper findAllRolesByUser(Long userId); + + public Long fetchAuthTokenReference(String authToken); + + int insertIntoPassword(Long id, String password); + + int getAuthId(Long userId); + + boolean customAuth(UserDto userDto); + + User insertIntoUser(final User user); + + Long insertAnonymousUser(User user); + + public boolean changePassword(ChangePasswordDto changePasswordDto); + + public long forgotPassword(UserDto userDto); + + boolean saveForgotPassword(long userId, String password); + + public User getUserDetailsByEmail(String username); + + public LoginDto login(UserDto userDto); + + public CommonDataModel getAuthDomain(UserDto userDto); + + public boolean getFirstAdminsOfOrg(Long id); + + public Boolean onBoardingCheck(Long orgId, Long id); + + boolean isPasswordMatch(long userId, String password); + + List<User> findAll(Long orgId); + + List<OrgUserRoleDto> getAllOrgUsers(); + + List<OrgUserRoleDto> getAllUserRoles(); + + public List<HelpDeskApp> getAppIdAndHelpDeskId(); + + public List<User> getUserIdAndUserName(); + + public void getReviews() throws IOException; + + Access getReviewConfig(Long orgId); + +} diff --git a/src/main/java/org/upsmf/grievance/dao/impl/ApplicationDaoImpl.java b/src/main/java/org/upsmf/grievance/dao/impl/ApplicationDaoImpl.java new file mode 100644 index 0000000..8639e27 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dao/impl/ApplicationDaoImpl.java @@ -0,0 +1,238 @@ +package org.upsmf.grievance.dao.impl; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Repository; + +import org.upsmf.grievance.dao.ApplicationDao; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.model.App; +import org.upsmf.grievance.model.KeyFactory; +import org.upsmf.grievance.model.S3Config; +import org.upsmf.grievance.model.ServiceRequest; +import org.upsmf.grievance.model.StatusIdMap; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.util.Constants; +import org.upsmf.grievance.util.DateUtil; +import org.upsmf.grievance.util.S3FileManager; +import org.upsmf.grievance.util.Sql; +import org.upsmf.grievance.util.Sql.Apps; + +@Repository(Constants.APP_DAO) +public class ApplicationDaoImpl implements ApplicationDao { + + private static final String ENCOUNTERED_AN_EXCEPTION_WHILE_CREATING_APP_S = "Encountered an Exception while creating App : %s"; + private static final String ENCOUNTERED_AN_EXCEPTION_GET_ORGANIZATION_APP_DAO_IMPL_S = "Encountered an exception getOrganizationApp daoImpl : %s"; + private static final String QUERY_TO_EXECUTE = "Query to execute : "; + private static final String ENCOUNTERED_AN_EXCEPTION_S = "Encountered an Exception : %s"; + public static final Logger LOGGER = LoggerFactory.getLogger(ApplicationDaoImpl.class); + @Autowired + JdbcTemplate jdbcTemplate; + + @Override + public App createApp(App app, User user) { + Long id = (long) 0; + try { + app.setAppKey(UUID.randomUUID().toString()); + KeyHolder keyHolder = KeyFactory.getkeyHolder(); + jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { + String[] returnValColumn = new String[] { "id" }; + PreparedStatement statement = con.prepareStatement(Apps.INSERT_NEW_APP, returnValColumn); + statement.setString(1, app.getName()); + statement.setString(2, app.getAppUrl()); + statement.setString(3, app.getLogo()); + statement.setLong(4, app.getSourceId()); + statement.setLong(5, user.getId()); + statement.setBoolean(6, Boolean.TRUE); + statement.setString(7, app.getClientName()); + statement.setString(8, app.getVersion()); + statement.setString(9, app.getAppKey()); + statement.setString(10, app.getDescription()); + return statement; + } + }, keyHolder); + id = keyHolder.getKey().longValue(); + app.setId(id); + Long orgAppId = jdbcTemplate.queryForObject(Sql.Apps.GET_ID_FROM_ORG_APP, + new Object[] { id, user.getOrgId() }, Long.class); + if (orgAppId < 1) { + jdbcTemplate.update(Apps.MAP_APP_TO_ORG, new Object[] { id, user.getOrgId() }); + } + MasterDataManager.getAppObjectFromAppName(); + } catch (InvalidDataAccessApiUsageException e) { + LOGGER.error(String.format( + "Encountered an Exception while creating App : InvalidDataAccessApiUsageException : %s", + e.getMessage())); + } catch (DataAccessException e) { + LOGGER.error(String.format("Encountered an Exception while creating App : DataAccessException : %s", + e.getMessage())); + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_CREATING_APP_S, e.getMessage())); + } + return app; + } + + @Override + public App updateApp(App app, User user) { + try { + + jdbcTemplate.update(Apps.UPDATE_APP, new Object[] { app.getName(), app.getAppUrl(), app.getLogo(), + app.getSourceId(), app.getActiveStatus(), app.getClientName(), app.getVersion(), user.getId(), + DateUtil.getFormattedDateInUTC(new Date()), app.getAppKey(), app.getDescription(), app.getId() }); + if (app.getActiveStatus()) { + jdbcTemplate.update(Sql.Apps.DELETE_ORG_APP, new Object[] { app.getId(), user.getOrgId() }); + } + MasterDataManager.getAppObjectFromAppName(); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_CREATING_APP_S, e.getMessage())); + } + return app; + } + + @Override + public List<App> getApp(Long id) { + List<App> appList = null; + try { + LOGGER.info(QUERY_TO_EXECUTE + Apps.GET_APP + Sql.Common.WHERE_CLAUSE + Apps.ID_CONDITION); + appList = jdbcTemplate.query(Apps.GET_APP + Sql.Common.WHERE_CLAUSE + Apps.ID_CONDITION, + new Object[] { id }, MasterDataManager.rowMapApp); + appList = getLogo(appList); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an exception while fetching all roles : %s", e.getMessage())); + } + return appList; + } + + public List<App> getLogo(List<App> appList) { + try { + for (int i = 0; i < appList.size(); i++) { + String url = getAppLogo(appList.get(i)); + appList.get(i).setLogo(url); + } + return appList; + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return appList; + } + + public String getAppLogo(App app) { + if (app.getLogo() != null && !app.getLogo().isEmpty()) { + try { + List<S3Config> s3 = jdbcTemplate.query(Sql.GET_S3_ACCESS, MasterDataManager.rowMapS3Config); + S3Config s3values; + if (!s3.isEmpty()) { + s3values = s3.get(0); + String url = null; + url = S3FileManager.getPreSignedURL(s3values, app.getLogo()); + return url; + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + } + return null; + } + + @Override + public List<App> getAllApps() { + List<App> appList = null; + + try { + LOGGER.info(QUERY_TO_EXECUTE + Apps.GET_APP); + appList = jdbcTemplate.query(Apps.GET_APP, new Object[] {}, MasterDataManager.rowMapApp); + if (appList != null && !appList.isEmpty()) { + appList = getLogo(appList); + } + } catch (Exception e) { + LOGGER.error(String.format("Exception in getAllApplications daoImpl : %s", e.getMessage())); + } + + return appList; + } + + @Override + public List<App> getAppsByOrgId(Long orgId) { + try { + LOGGER.info(QUERY_TO_EXECUTE + Apps.GET_ORG_APPS); + List<App> apps = jdbcTemplate.query(Apps.GET_ORG_APPS, new Object[] { orgId }, MasterDataManager.rowMapApp); + if (apps != null && !apps.isEmpty()) { + apps = getLogo(apps); + } + return apps; + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_GET_ORGANIZATION_APP_DAO_IMPL_S, e.getMessage())); + return new ArrayList<>(); + } + } + + @Override + public List<String> getDistinctAppNames(Long orgId) { + try { + LOGGER.info(QUERY_TO_EXECUTE + Apps.GET_APP_URLS); + return jdbcTemplate.queryForList(Apps.GET_APP_URLS, new Object[] { orgId }, String.class); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_GET_ORGANIZATION_APP_DAO_IMPL_S, e.getMessage())); + return new ArrayList<>(); + } + } + + @Override + public boolean mapAppsToHelpdesk(StatusIdMap statusIdMap) { + try { + Long id = jdbcTemplate.queryForObject(Apps.GET_HELPDESK_ID, + new Object[] { statusIdMap.getHelpdeskId(), statusIdMap.getAppId() }, Long.class); + if (id == 0) { + LOGGER.info(QUERY_TO_EXECUTE + Apps.MAP_HELPDESK_APP); + jdbcTemplate.update(Apps.MAP_HELPDESK_APP, + new Object[] { statusIdMap.getHelpdeskId(), statusIdMap.getAppId() }); + MasterDataManager.getHelpdeskIdFromAppId(); + return true; + } + } catch (Exception e) { + LOGGER.error(String.format("Exception in mapAppToOrg daoImpl : %s", e.getMessage())); + } + return false; + } + + @Override + public List<ServiceRequest> getServiceRequests() { + List<ServiceRequest> serviceRequests = null; + try { + LOGGER.info(QUERY_TO_EXECUTE + Apps.GET_SOURCE); + serviceRequests = jdbcTemplate.query(Apps.GET_SOURCE, MasterDataManager.rowMapServiceRequest); + return serviceRequests; + } catch (Exception e) { + LOGGER.error(String.format("Encountered an exception getOrganizationApp daoImpl %s", e.getMessage())); + return serviceRequests; + } + } + + @Override + public List<App> getAppIdAndAppObject() { + List<App> app = null; + try { + app = jdbcTemplate.query(Sql.UserQueries.GET_APP_ID_APP_OBJECT, MasterDataManager.rowMapApp); + return app; + } catch (Exception e) { + LOGGER.error(String.format("Encountered an exception while fetching all roles %s", e.getMessage())); + return app; + } + } + +} diff --git a/src/main/java/org/upsmf/grievance/dao/impl/HelpdeskDaoImpl.java b/src/main/java/org/upsmf/grievance/dao/impl/HelpdeskDaoImpl.java new file mode 100644 index 0000000..195c24d --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dao/impl/HelpdeskDaoImpl.java @@ -0,0 +1,485 @@ +package org.upsmf.grievance.dao.impl; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Repository; + +import org.upsmf.grievance.dao.ApplicationDao; +import org.upsmf.grievance.dao.HelpdeskDao; +import org.upsmf.grievance.dao.SuperAdminDao; +import org.upsmf.grievance.dto.HelpdeskDto; +import org.upsmf.grievance.dto.HelpdeskTypeDto; +import org.upsmf.grievance.dto.HelpdeskWorkflowDto; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.model.ChecklistItem; +import org.upsmf.grievance.model.HelpDeskApp; +import org.upsmf.grievance.model.Helpdesk; +import org.upsmf.grievance.model.KeyFactory; +import org.upsmf.grievance.model.S3Config; +import org.upsmf.grievance.model.StatusIdMap; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.model.mapper.SqlDataMapper; +import org.upsmf.grievance.model.mapper.SqlDataMapper.HelpdeskRowRecordMapper; +import org.upsmf.grievance.util.Constants; +import org.upsmf.grievance.util.DateUtil; +import org.upsmf.grievance.util.JsonKey; +import org.upsmf.grievance.util.ProjectUtil; +import org.upsmf.grievance.util.S3FileManager; +import org.upsmf.grievance.util.SendMail; +import org.upsmf.grievance.util.Sql; + +@Repository +public class HelpdeskDaoImpl implements HelpdeskDao { + + private static final String ENCOUNTERED_AN_EXCEPTION_WHILE_FETCHING_USERS_FOR_HELPDESK_S = "Encountered an exception while fetching Users for Helpdesk : : %s"; + + private static final String ENCOUNTERED_AN_EXCEPTION_WHILE_DELETING_WORKFLOW_STAGES_FOR_A_HELPDESK_TYPE_S = "Encountered an Exception while deleting Workflow Stages for a Helpdesk Type : : %s"; + + public static final Logger LOGGER = LoggerFactory.getLogger(HelpdeskDaoImpl.class); + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Autowired + private ApplicationDao appDao; + + @Autowired + private SuperAdminDao superAdminDao; + + @Override + public boolean createUpdateHelpdesk(Helpdesk helpdesk) { + KeyHolder keyHolder = KeyFactory.getkeyHolder(); + if (ProjectUtil.isObjectNull(helpdesk.getId())) { + try { + jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { + String[] returnValColumn = new String[] { "id" }; + PreparedStatement statement = con.prepareStatement(Sql.Helpdesk.CREATE_HELPDESK, + returnValColumn); + statement.setString(1, helpdesk.getName()); + statement.setLong(2, helpdesk.getOrgId()); + statement.setLong(3, helpdesk.getCreatedBy()); + statement.setString(4, DateUtil.getFormattedDateInUTC(new Date())); + statement.setBoolean(5, helpdesk.getIsActive()); + statement.setString(6, helpdesk.getColor()); + statement.setString(7, helpdesk.getDescription()); + return statement; + } + }, keyHolder); + helpdesk.setId((Long) keyHolder.getKey()); + setHelpdeskChannels(helpdesk); + return true; + } catch (Exception e) { + LOGGER.error(String.format("Encountered exception in create daoImpl : %s", e.getMessage())); + } + } else { + try { + jdbcTemplate.update(Sql.Helpdesk.UPDATE_HELPDESK, + new Object[] { helpdesk.getName(), helpdesk.getUpdatedBy(), + DateUtil.getFormattedDateInUTC(new Date()), helpdesk.getIsActive(), helpdesk.getColor(), + helpdesk.getDescription(), helpdesk.getId(), helpdesk.getOrgId() }); + setHelpdeskChannels(helpdesk); + return true; + } catch (Exception e) { + LOGGER.error(String.format("Encountered exception in updating Helpdesk daoImpl : %s", e.getMessage())); + } + } + return false; + } + + private void setHelpdeskChannels(Helpdesk helpdesk) { + if (updateAdminAndAppIds(helpdesk) && helpdesk.getDirect() != null && helpdesk.getPlaystore() != null + && helpdesk.getAppstore() != null && helpdesk.getAurora_sdk() != null) { + jdbcTemplate.update(Sql.Helpdesk.UPDATE_HELPDESK_CHANNELS, + new Object[] { helpdesk.getDirect(), helpdesk.getPlaystore(), helpdesk.getAppstore(), + helpdesk.getAurora_sdk(), helpdesk.getId(), helpdesk.getOrgId() }); + } + } + + private boolean updateAdminAndAppIds(Helpdesk helpdesk) { + + if (helpdesk != null) { + // jdbcTemplate.update(Sql.UserQueries.REMOVE_ALL_HELPDESK_SOURCE, new Object[] + // { helpdesk.getId() }); + // for (int i = 0; i < helpdesk.getSourceId().size(); i++) { + // jdbcTemplate.update(Sql.Ticket.ADD_SOURCE_TO_HELPDESK, + // new Object[] { helpdesk.getId(), helpdesk.getSourceId().get(i) }); + // } + boolean value = addUpdateHelpdeskAdmins(helpdesk); + boolean values = addUpdateHelpdeskUsers(helpdesk); + if (value && values) { + for (int i = 0; i < helpdesk.getAppIds().size(); i++) { + StatusIdMap statusIdMap = new StatusIdMap(); + statusIdMap.setHelpdeskId(helpdesk.getId()); + statusIdMap.setHelpdeskAppStatus(true); + statusIdMap.setAppId(helpdesk.getAppIds().get(i)); + appDao.mapAppsToHelpdesk(statusIdMap); + } + MasterDataManager.getHelpdeskObjectFromHelpdeskId(); + } + return true; + } + return false; + } + + @Override + public List<HelpdeskDto> getAllHelpdesks(Long orgId) { + try { + return jdbcTemplate.query(Sql.Helpdesk.GET_ORG_HELPDESK, new Object[] { orgId, true }, + MasterDataManager.rowMapHelpdeskDto); + } catch (Exception e) { + LOGGER.error(String.format("Encountered exception in getOrgHelpdesk daoImpl : %s", e.getMessage())); + return new ArrayList<>(); + } + + } + + @Override + public HelpdeskRowRecordMapper getHelpdeskForId(Long orgId, Long id) { + HelpdeskRowRecordMapper rowMapper = new SqlDataMapper().new HelpdeskRowRecordMapper(); + try { + jdbcTemplate.query(Sql.Helpdesk.GET_HELPDESK_FOR_ID, new Object[] { id, orgId }, rowMapper); + } catch (Exception e) { + LOGGER.error(String.format("Encountered exception in getHelpdeskForId daoImpl : %s", e.getMessage())); + } + return rowMapper; + } + + @Override + public List<ChecklistItem> getChecklistItemsForHelpdesk(Long helpdeskId, Long typeId) { + List<ChecklistItem> checklistItems = new ArrayList<>(); + try { + checklistItems = jdbcTemplate.query(Sql.Helpdesk.GET_CHECKLIST_FOR_HELPDESK, + new Object[] { helpdeskId, typeId }, new SqlDataMapper().new ChecklistItemMapper()); + } catch (Exception e) { + LOGGER.error(String.format("Encountered exception in getHelpdeskForId daoImpl : %s", e.getMessage())); + } + return checklistItems; + } + + @Override + public List<Long> getHelpdeskAdmins(Long id) { + List<Long> list = null; + try { + list = jdbcTemplate.queryForList(Sql.UserQueries.GET_HELPDESK_ADMINS, new Object[] { id }, Long.class); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception : : %s", e.getMessage())); + } + return list; + + } + + @Override + public boolean addUpdateHelpdeskAdmins(Helpdesk helpdesk) { + try { + List<Long> oldAdmins = getHelpdeskAdmins(helpdesk.getId()); + for (Long admin : helpdesk.getAdminIds()) { + if (oldAdmins.contains(admin)) { + oldAdmins.remove(admin); + } + } + for (int i = 0; i < oldAdmins.size(); i++) { + User user = superAdminDao.userDetailsByUserId(oldAdmins.get(i)); + String email = user.getUsername(); + Map<String, String> keyValue = new HashMap<>(); + keyValue.put(JsonKey.FIRST_NAME, user.getName()); + keyValue.put(JsonKey.HELPDESKNAME, helpdesk.getName()); + String[] emails = email.split(","); + SendMail.sendMail(keyValue, emails, Constants.DELETE_HELPDESK_ADMIN, "remove_helpdeskadmin.vm"); + } + jdbcTemplate.update(Sql.UserQueries.REMOVE_ALL_HELPDESK_ADMIN, new Object[] { helpdesk.getId() }); + if (helpdesk != null && helpdesk.getAdminIds() != null) { + for (int i = 0; i < helpdesk.getAdminIds().size(); i++) { + jdbcTemplate.update(Sql.UserQueries.ADD_ADMINS_TO_HELPDESK, + new Object[] { helpdesk.getId(), helpdesk.getAdminIds().get(i) }); + User user = superAdminDao.userDetailsByUserId(helpdesk.getAdminIds().get(i)); + user.setOrgId(MasterDataManager.getUserOrgMap().get(helpdesk.getAdminIds().get(i))); + String email = user.getUsername(); + Map<String, String> keyValue = new HashMap<>(); + keyValue.put(JsonKey.FIRST_NAME, user.getName()); + keyValue.put(JsonKey.HELPDESKNAME, helpdesk.getName()); + LOGGER.info(helpdesk.getName()); + String[] emails = email.split(","); + SendMail.sendMail(keyValue, emails, Constants.NEW_HELPDESK_ADMIN, "add-helpdeskadmin-aurora.vm"); + } + } + return true; + } catch (DataAccessException e) { + LOGGER.error( + String.format("Encountered an Exception while adding admins to helpdesk : : %s", e.getMessage())); + } catch (Exception ex) { + LOGGER.error( + String.format("Encountered an Exception while adding admins to helpdesk : : %s", ex.getMessage())); + } + return false; + } + + @Override + public Boolean addTypeForHelpdesk(HelpdeskTypeDto dto, Long helpdeskId) { + Long id = 0l; + try { + KeyHolder keyHolder = KeyFactory.getkeyHolder(); + jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { + String[] returnValColumn = new String[] { "id" }; + PreparedStatement statement = con.prepareStatement(Sql.Helpdesk.INSERT_TYPE_FOR_HELPDESK, + returnValColumn); + statement.setLong(1, helpdeskId); + statement.setString(2, dto.getName()); + return statement; + } + }, keyHolder); + id = keyHolder.getKey().longValue(); + dto.setId(id); + } catch (Exception e) { + LOGGER.error( + String.format("Encountered an Exception while adding type for a Helpdesk : : %s", e.getMessage())); + } + return true; + } + + @Override + public Boolean addWorkflowForHelpdeskType(HelpdeskTypeDto helpdeskTypeDto) { + int[] values = null; + try { + values = jdbcTemplate.batchUpdate(Sql.Helpdesk.INSERT_WORKFLOW_FOR_HELPDESK_TYPE, + new BatchPreparedStatementSetter() { + @Override + public void setValues(java.sql.PreparedStatement statement, int i) throws SQLException { + HelpdeskWorkflowDto workflowDto = helpdeskTypeDto.getWorkflowStages().get(i); + statement.setString(1, workflowDto.getName()); + statement.setLong(2, helpdeskTypeDto.getId()); + } + + @Override + public int getBatchSize() { + return helpdeskTypeDto.getWorkflowStages().size(); + } + }); + } catch (Exception e) { + LOGGER.error(String.format("Exception Occured while mapping Products to Order : %s", e.getMessage())); + + } + return (values != null && values.length > 0); + + } + + @Override + public Boolean addChecklistForHelpdeskType(HelpdeskTypeDto helpdeskTypeDto, Long helpdeskId) { + Long id = 0l; + try { + for (ChecklistItem item : helpdeskTypeDto.getChecklistItems()) { + KeyHolder keyHolder = KeyFactory.getkeyHolder(); + jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { + String[] returnValColumn = new String[] { "id" }; + PreparedStatement statement = con.prepareStatement(Sql.Helpdesk.INSERT_CHECKLIST_FOR_HDTYPE, + returnValColumn); + statement.setString(1, item.getItem()); + return statement; + } + }, keyHolder); + id = keyHolder.getKey().longValue(); + item.setId(id); + jdbcTemplate.update(Sql.Helpdesk.MAP_CHECKLIST_HDTYPE, + new Object[] { helpdeskId, item.getId(), helpdeskTypeDto.getId() }); + } + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception while adding checklist type for a Helpsedk : : %s", + e.getMessage())); + } + return true; + } + + @Override + public boolean addUpdateHelpdeskUsers(Helpdesk helpdesk) { + try { + if (helpdesk.getAllowAllUsers()) { + jdbcTemplate.update(Sql.UserQueries.UPDATE_ALLOW_ALL_USERS, + new Object[] { helpdesk.getAllowAllUsers(), helpdesk.getId() }); + jdbcTemplate.update(Sql.UserQueries.REMOVE_ALL_USERS_FROM_HELPDESK, new Object[] { helpdesk.getId() }); + } else { + jdbcTemplate.update(Sql.UserQueries.UPDATE_ALLOW_ALL_USERS, + new Object[] { helpdesk.getAllowAllUsers(), helpdesk.getId() }); + jdbcTemplate.update(Sql.UserQueries.REMOVE_ALL_USERS_FROM_HELPDESK, new Object[] { helpdesk.getId() }); + for (int i = 0; i < helpdesk.getUserIds().size(); i++) { + jdbcTemplate.update(Sql.UserQueries.ADD_USERS_TO_HELPDESK, + new Object[] { helpdesk.getId(), helpdesk.getUserIds().get(i) }); + } + } + return true; + } catch (Exception ex) { + LOGGER.error( + String.format("Encountered an Exception while adding users to helpdesk : : %s", ex.getMessage())); + } + return false; + } + + @Override + public Boolean deleteTypeForHelpdesk(Long helpdeskId) { + int status = 0; + try { + status = jdbcTemplate.update(Sql.Helpdesk.DELETE_TYPE_FOR_HELPDESK, new Object[] { helpdeskId }); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_DELETING_WORKFLOW_STAGES_FOR_A_HELPDESK_TYPE_S, + e.getMessage())); + return false; + } + + return (status > 0); + } + + @Override + public Boolean deleteWorkflowForHelpdeskType(Long typeId) { + int status = 0; + try { + status = jdbcTemplate.update(Sql.Helpdesk.DELETE_WORKFLOW_FOR_HELPDESKTYPE, new Object[] { typeId }); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_DELETING_WORKFLOW_STAGES_FOR_A_HELPDESK_TYPE_S, + e.getMessage())); + return false; + } + + return (status > 0); + } + + @Override + public Boolean deleteChecklistForHelpdeskType(Long helpdeskId, Long typeId) { + int status = 0; + try { + status = jdbcTemplate.update(Sql.Helpdesk.DELETE_CHECKLIST_FOR_HDTYPE, new Object[] { helpdeskId, typeId }); + } catch (Exception e) { + LOGGER.error( + String.format("Encountered an Exception while deleting Workflow Stages for a Helpdesk Type : : %s ", + e.getMessage())); + return false; + } + + return (status > 0); + } + + @Override + public List<HelpDeskApp> getAppIdAndHelpDeskId() { + List<HelpDeskApp> helpdeskApp = null; + try { + helpdeskApp = jdbcTemplate.query(Sql.UserQueries.GET_APP_ID_HELPDESK_ID, + MasterDataManager.rowMapHelpDeskApp); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an exception while fetching all roles : %s", e.getMessage())); + } + return helpdeskApp; + } + + @Override + public List<Helpdesk> getHelpdeskObjectFromHelpdeskId() { + List<Helpdesk> helpdesk = null; + try { + helpdesk = jdbcTemplate.query(Sql.UserQueries.GET_HELPDESK_ID_HELPDESK_OBJECT, + MasterDataManager.rowMapHelpdesk); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an exception while fetching all roles : %s", e.getMessage())); + } + return helpdesk; + } + + @Override + public List<User> getAdminForHelpeskId(Long helpdeskId) { + List<User> helpdeskUsers = null; + try { + helpdeskUsers = jdbcTemplate.query(Sql.Helpdesk.GET_HELPDESK_ADMIN_BY_ID, new Object[] { helpdeskId }, + new SqlDataMapper().new HelpdeskUserMapper()); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_FETCHING_USERS_FOR_HELPDESK_S, e.getMessage())); + } + return helpdeskUsers; + } + + @Override + public List<User> getUsersForHelpeskId(Long helpdeskId) { + List<User> helpdeskUsers = new ArrayList<>(); + List<HelpdeskDto> data = new ArrayList<>(); + try { + data = jdbcTemplate.query(Sql.Helpdesk.GET_HELPDESK_BY_ID, new Object[] { helpdeskId }, + MasterDataManager.rowMapHelpdeskDto); + if (!data.isEmpty()) { + HelpdeskDto helpdesk = data.get(0); + if (helpdesk.getAllowAllUsers()) { + helpdeskUsers = jdbcTemplate.query(Sql.Helpdesk.GET_USER_DETAILS_FOR_HELPDESK, + new Object[] { helpdesk.getOrgId() }, new SqlDataMapper().new HelpdeskUserMapper()); + } else { + helpdeskUsers = jdbcTemplate.query(Sql.Helpdesk.GET_HELPDESK_USER_BY_ID, + new Object[] { helpdeskId }, new SqlDataMapper().new HelpdeskUserMapper()); + } + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_FETCHING_USERS_FOR_HELPDESK_S, e.getMessage())); + } + return helpdeskUsers; + } + + @Override + public List<HelpdeskDto> getHelpdeskAdminUser(List<HelpdeskDto> helpdeskList) { + try { + for (int i = 0; i < helpdeskList.size(); i++) { + HelpdeskDto dto = helpdeskList.get(i); + List<User> admins = jdbcTemplate.query(Sql.Helpdesk.GET_HELPDESK_ADMIN_USER, + new Object[] { dto.getId() }, MasterDataManager.rowMapUser); + dto.setUsers(getUsersForHelpeskId(dto.getId())); + admins = getImageUrl(admins); + dto.setAdmins(admins); + } + + return helpdeskList; + + } catch (Exception e) { + LOGGER.error(String.format("Encountered an exception in getHelpdeskAdminUser : : %s", e.getMessage())); + return new ArrayList<>(); + } + + } + + private List<User> getImageUrl(List<User> userList) { + S3Config s3values = superAdminDao.getS3Access(); + for (int i = 0; i < userList.size(); i++) { + if (userList.get(i).getImagePath() != null && !userList.get(i).getImagePath().isEmpty() + && userList.get(i).getImagePath().contains("userprofile")) { + String url = null; + url = S3FileManager.getPreSignedURL(s3values, userList.get(i).getImagePath()); + userList.get(i).setImagePath(url); + } + } + return userList; + + } + + @Override + public List<Helpdesk> getHelpdeskByUserId(Long userId) { + List<Helpdesk> helpdeskUsers = null; + Long orgId = MasterDataManager.getUserOrgMap().get(userId); + try { + helpdeskUsers = jdbcTemplate.query(Sql.Helpdesk.GET_HELPDESK_BY_USER_ID, + new Object[] { userId, userId, orgId }, new SqlDataMapper().new UserHelpdeskMapper()); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_FETCHING_USERS_FOR_HELPDESK_S, e.getMessage())); + } + return helpdeskUsers; + } +} diff --git a/src/main/java/org/upsmf/grievance/dao/impl/RoleDaoImpl.java b/src/main/java/org/upsmf/grievance/dao/impl/RoleDaoImpl.java new file mode 100644 index 0000000..03b6583 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dao/impl/RoleDaoImpl.java @@ -0,0 +1,204 @@ +package org.upsmf.grievance.dao.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +import org.upsmf.grievance.dao.RoleDao; +import org.upsmf.grievance.dao.SuperAdminDao; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.model.Organization; +import org.upsmf.grievance.model.Role; +import org.upsmf.grievance.model.mapper.SqlDataMapper; +import org.upsmf.grievance.model.mapper.SqlDataMapper.RoleActionMapper; +import org.upsmf.grievance.util.Constants; +import org.upsmf.grievance.util.ProjectUtil; +import org.upsmf.grievance.util.Sql; +import org.upsmf.grievance.util.Sql.Common; +import org.upsmf.grievance.util.Sql.RoleAction; + +@Repository(Constants.ROLE_DAO) +public class RoleDaoImpl implements RoleDao { + + private static final String ENCOUNTERED_AN_EXCEPTION_WHILE_SAVING_THE_ROLE_DETAILS_S = "Encountered an exception while saving the Role Details : %s"; + + private static final String ENCOUNTERED_AN_EXCEPTION_WHILE_FETCHING_ALL_ROLES_S = "Encountered an exception while fetching all roles %s"; + + private static final String ENCOUNTERED_AN_EXCEPTION_S = "Encountered an Exception : %s"; + + public static final Logger LOGGER = LoggerFactory.getLogger(RoleDaoImpl.class); + + @Autowired + JdbcTemplate jdbcTemplate; + + @Autowired + private SuperAdminDao superAdminDao; + + @Override + public Role saveRole(Role role) { + int saveRole = 0; + try { + saveRole = jdbcTemplate.update(RoleAction.SAVE_NEW_ROLE, new Object[] { role.getName(), role.getOrgId() }); + } catch (Exception ex) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_SAVING_THE_ROLE_DETAILS_S, ex.getMessage())); + } + if (saveRole > 0) { + return role; + } + return null; + } + + @Override + public Role updateRole(Role role) { + int updateRole = 0; + try { + updateRole = jdbcTemplate.update(RoleAction.UPDATE_ROLE, + new Object[] { role.getName(), role.getId(), role.getOrgId() }); + } catch (Exception ex) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_SAVING_THE_ROLE_DETAILS_S, ex.getMessage())); + } + if (updateRole > 0) { + return role; + } + return null; + } + + @Override + public List<Role> getAllRoles(Long orgId) { + List<Role> roleList = null; + String query = RoleAction.GET_ALL_ROLES + Common.WHERE_CLAUSE + RoleAction.ORG_ID_CONDITION; + try { + roleList = jdbcTemplate.query(query, new Object[] { orgId }, MasterDataManager.rowMapRole); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_FETCHING_ALL_ROLES_S, e.getMessage())); + } + return roleList; + } + + @Override + public String findById(Role role) { + String roleList = null; + try { + roleList = jdbcTemplate.queryForObject(RoleAction.SELECT_ROLES_ON_ID, + new Object[] { role.getId(), role.getOrgId() }, String.class); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_FETCHING_ALL_ROLES_S, e.getMessage())); + } + if (roleList != null) { + return roleList; + } + return null; + } + + @Override + public List<Role> getAllOrgRoles() { + List<Role> roleList = null; + try { + roleList = jdbcTemplate.query(RoleAction.GET_ALL_ROLES, MasterDataManager.rowMapRole); + return roleList; + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_FETCHING_ALL_ROLES_S, e.getMessage())); + } + return new ArrayList<>(); + } + + @Override + public void initializeActions() { + + try { + Iterator<Entry<Integer, List<String>>> it = Constants.getActions().entrySet().iterator(); + while (it.hasNext()) { + Entry<Integer, List<String>> pair = it.next(); + Boolean value = jdbcTemplate.queryForObject(Sql.Organization.CHECK_IF_ACTION_EXISTS, + new Object[] { pair.getKey() }, Boolean.class); + if (!value) { + if (!ProjectUtil.isObjectListNullOrEmpty(Constants.getActions().get(pair.getKey())) + && Constants.getActions().get(pair.getKey()).size() == 3) { + jdbcTemplate.update(Sql.UserQueries.INSERT_ACTION, + new Object[] { pair.getKey(), Constants.getActions().get(pair.getKey()).get(0), + Constants.getActions().get(pair.getKey()).get(1), + Constants.getActions().get(pair.getKey()).get(2) }); + } + } else if (!ProjectUtil.isObjectListNullOrEmpty(Constants.getActions().get(pair.getKey())) + && Constants.getActions().get(pair.getKey()).size() == 3) { + jdbcTemplate.update(Sql.UserQueries.UPDATE_ACTION, + new Object[] { Constants.getActions().get(pair.getKey()).get(0), + Constants.getActions().get(pair.getKey()).get(1), + Constants.getActions().get(pair.getKey()).get(2), pair.getKey() }); + } + + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + + } + + @Override + public void intializeRolesAndActions() { + Long roleId = null; + List<Organization> organizations = superAdminDao.getAllOrganization(); + for (int i = 0; i < organizations.size(); i++) { + for (Constants.userRole roleName : Constants.userRole.values()) { + try { + roleId = jdbcTemplate.queryForObject(Sql.Organization.GET_ROLE_ID_FROM_ORG, + new Object[] { String.valueOf(roleName), organizations.get(i).getId() }, Long.class); + jdbcTemplate.update(Sql.Organization.DELETE_ACTION, new Object[] { roleId }); + List<Integer> actions; + switch (String.valueOf(roleName)) { + case Common.SUPER_ADMIN: + actions = Constants.getSuperadminactions(); + break; + case Common.ORGADMIN: + actions = Constants.getOrgadminactions(); + break; + case Common.ENDUSER: + actions = Constants.getEnduseractions(); + break; + default: + actions = new ArrayList<>(); + } + for (int j = 0; j < actions.size(); j++) { + jdbcTemplate.update(Sql.Organization.ADD_ROLE_PERMISSION, + new Object[] { roleId, actions.get(j) }); + } + } catch (Exception e) { + LOGGER.info(String.format("Role Doesn't exist as per mapped, Please check. %s", roleId.toString())); + } + } + } + + } + + @Override + public Map<Long, List<String>> getAllActionsForRoles(List<Long> roleIds) { + RoleActionMapper mapper = new SqlDataMapper().new RoleActionMapper(); + String queryToExecute = RoleAction.GET_ALL_ACTIONS_FOR_ROLES + getIdQuery(roleIds); + try { + jdbcTemplate.query(queryToExecute, mapper); + return mapper.getRoleActionsMap(); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_FETCHING_ALL_ROLES_S, e.getMessage())); + } + return null; + } + + private static String getIdQuery(final List<Long> idList) { + final StringBuilder query = new StringBuilder("("); + if (!idList.isEmpty()) { + query.append(idList.get(0).toString()); + for (int i = 1; i < idList.size(); i++) { + query.append(", " + idList.get(i)); + } + } + return query.append(")").toString(); + } +} diff --git a/src/main/java/org/upsmf/grievance/dao/impl/SuperAdminDaoImpl.java b/src/main/java/org/upsmf/grievance/dao/impl/SuperAdminDaoImpl.java new file mode 100644 index 0000000..1f99fef --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dao/impl/SuperAdminDaoImpl.java @@ -0,0 +1,391 @@ +package org.upsmf.grievance.dao.impl; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.apache.velocity.VelocityContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Repository; + +import org.upsmf.grievance.dao.SuperAdminDao; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.model.KeyFactory; +import org.upsmf.grievance.model.Organization; +import org.upsmf.grievance.model.S3Config; +import org.upsmf.grievance.model.StatusIdMap; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.model.mapper.SqlDataMapper; +import org.upsmf.grievance.model.mapper.SqlDataMapper.OrgMapper; +import org.upsmf.grievance.util.Constants; +import org.upsmf.grievance.util.DateUtil; +import org.upsmf.grievance.util.JsonKey; +import org.upsmf.grievance.util.OneWayHashing; +import org.upsmf.grievance.util.ProjectUtil; +import org.upsmf.grievance.util.S3FileManager; +import org.upsmf.grievance.util.SendMail; +import org.upsmf.grievance.util.Sql; +import org.upsmf.grievance.util.Sql.Apps; +import org.upsmf.grievance.util.Sql.Common; + +@Repository(Constants.SUPER_ADMIN_DAO) +public class SuperAdminDaoImpl implements SuperAdminDao { + + private static final String ENCOUNTERED_AN_EXCEPTION_S = "Encountered an Exception : %s"; + + public static final Logger LOGGER = LoggerFactory.getLogger(SuperAdminDaoImpl.class); + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Override + public List<Organization> getAllOrganization() { + List<Organization> list = new ArrayList<>(); + try { + list = jdbcTemplate.query(Sql.Organization.GET_ALL_ORG, new Object[] {}, + MasterDataManager.rowMapOrganizationModel); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return list; + } + + @Override + public boolean addAdmin(long userId) { + try { + MasterDataManager.getUserOrgMap().get(userId); + int orgId = getOrganizationByUserId(userId); + Long roleId = jdbcTemplate.queryForObject(Sql.UserQueries.GET_ROLE_ID_BY_ORG, + new Object[] { orgId, Sql.Common.ORGADMIN }, Long.class); + + Integer response = jdbcTemplate.update(Sql.UserQueries.ADD_ADMIN, + new Object[] { roleId.intValue(), userId }); + if (response > 0) { + MasterDataManager.getUserRoleMap().put(userId, roleId); + return true; + } + return false; + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception while Adding an Admin : %s", e.getMessage())); + return false; + } + + } + + @Override + public boolean removeAdmin(long userId) { + try { + int orgId = getOrganizationByUserId(userId); + MasterDataManager.getUserOrgMap().get(userId); + Long roleId = jdbcTemplate.queryForObject(Sql.UserQueries.GET_ROLE_ID_BY_ORG, + new Object[] { orgId, Sql.Common.ENDUSER }, Long.class); + Integer response = jdbcTemplate.update(Sql.UserQueries.DELETE_ADMIN, + new Object[] { roleId.intValue(), userId }); + if (response > 0) { + MasterDataManager.getUserRoleMap().put(userId, roleId); + return true; + } + return false; + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception while removing an Admin : %s", e.getMessage())); + return false; + } + + } + + @Override + public Organization addOrganization(Organization organization) { + int insertSuccessful = 0; + KeyHolder keyHolder = KeyFactory.getkeyHolder(); + List<Organization> list = jdbcTemplate.query(Sql.Organization.GET_ORG_BY_NAME, + new Object[] { organization.getOrgName() }, MasterDataManager.rowMapOrganizationModel); + if (list == null || list.isEmpty()) { + Long userId = newOrgCreateAdmin(organization); + if (userId == null) { + return null; + } + try { + insertSuccessful = jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { + String[] returnValColumn = new String[] { "id" }; + PreparedStatement statement = con.prepareStatement(Sql.Organization.ADD_NEW_ORG, + returnValColumn); + statement.setString(1, organization.getOrgName()); + statement.setString(2, organization.getUrl()); + statement.setString(3, organization.getLogo()); + statement.setLong(4, userId); + statement.setLong(5, userId); + statement.setString(6, organization.getOrgDescription()); + statement.setString(7, organization.getOrgColor()); + statement.setString(8, organization.getEmailDomain()); + return statement; + } + }, keyHolder); + organization.setId((Long) keyHolder.getKey()); + MasterDataManager.getOrgIdAndOrgNameMap().put(organization.getId(), organization.getOrgName()); + } catch (Exception e) { + LOGGER.error( + String.format("Encountered an Exception while Adding an Organization : %s", e.getMessage())); + } + if (insertSuccessful > 0) { + jdbcTemplate.update(Sql.UserQueries.NEW_ORG_AUTH, new Object[] { organization.getId(), + organization.getAuthId(), organization.getUrl(), organization.getEmailDomain() }); + orgSetup(organization, userId); + return organization; + } + } + return null; + } + + public Long newOrgCreateAdmin(final Organization org) { + KeyHolder keyHolder = KeyFactory.getkeyHolder(); + try { + Long list = jdbcTemplate.queryForObject(Sql.UserQueries.USER_DATA, + new Object[] { org.getAdminDetails().get(0).getUsername() }, Long.class); + if (list == 0) { + jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { + String[] returnValColumn = new String[] { "id" }; + PreparedStatement statement = connection.prepareStatement(Sql.Organization.NEW_ORG_ADMIN_USER, + returnValColumn); + statement.setString(1, org.getAdminDetails().get(0).getName()); + statement.setString(2, org.getAdminDetails().get(0).getUsername()); + statement.setString(3, org.getAdminDetails().get(0).getPhone()); + statement.setString(4, org.getAdminDetails().get(0).getImagePath()); + return statement; + } + }, keyHolder); + return keyHolder.getKey().longValue(); + } + MasterDataManager.getAllUserRoles(); + } catch (Exception e) { + LOGGER.error( + String.format("Encountered an Exception while Adding an Admin for New Org : %s", e.getMessage())); + } + + return null; + } + + public void orgSetup(final Organization org, Long newOrgAdminUserId) { + Long id = org.getId(); + if (id > 0) { + LOGGER.info("Org Id: {}", id); + } + if (newOrgAdminUserId > 0) { + LOGGER.info("User Id : {}", newOrgAdminUserId); + } + String password = null; + int adminRoleId = 0; + try { + for (Constants.userRole roleName : Constants.userRole.values()) { + Boolean value = jdbcTemplate.queryForObject(Sql.Organization.CHECK_IF_ROLE_EXISTS, + new Object[] { String.valueOf(roleName), id }, Boolean.class); + if (!value) { + jdbcTemplate.update(Sql.Organization.ADD_ORG_ROLES, new Object[] { String.valueOf(roleName), id }); + } + List<Integer> actions = new ArrayList<>(); + Integer roleId = jdbcTemplate.queryForObject(Sql.Organization.GET_ROLE_ID_BY_ORG, + new Object[] { id, String.valueOf(roleName) }, Integer.class); + if (String.valueOf(roleName).equals(Common.ORGADMIN)) { + adminRoleId = roleId; + actions = Constants.getOrgadminactions(); + } + if (String.valueOf(roleName).equals(Common.ENDUSER)) { + actions = Constants.getEnduseractions(); + } + for (int i = 0; i < actions.size(); i++) { + jdbcTemplate.update(Sql.Organization.ADD_ROLE_PERMISSION, new Object[] { roleId, actions.get(i) }); + } + } + jdbcTemplate.update(Sql.Organization.NEW_ORG_ADMIN_ROLE, new Object[] { newOrgAdminUserId, adminRoleId }); + MasterDataManager.getAllUserRoles(); + jdbcTemplate.update(Sql.Organization.FIRST_ADMIN_COMP, new Object[] { id, newOrgAdminUserId }); + MasterDataManager.getUserOrgMap().put(newOrgAdminUserId, id); + password = ProjectUtil.getRandomStringVal().trim(); + if (!StringUtils.isBlank(password)) { + LOGGER.info("New Admin Password : {}", password); + } + String encodedPwd = OneWayHashing.encryptVal(password); + jdbcTemplate.update(Sql.Organization.NEW_ORG_ADMIN_PSWRD, new Object[] { encodedPwd, newOrgAdminUserId }); + if (!StringUtils.isBlank(password)) { + LOGGER.info("Password : {}", password); + } + sendAdminMail(org.getAdminDetails().get(0).getUsername(), org.getAdminDetails().get(0).getName(), password); + } catch (Exception e) { + LOGGER.error( + String.format("Encountered an Exception while setting up an Organization : %s", e.getMessage())); + } + + } + + private void sendAdminMail(String email, String firstName, String password) { + VelocityContext context = new VelocityContext(); + try { + context.put(JsonKey.MAIL_SUBJECT, "Welcome to Aurora-Desk!"); + context.put(JsonKey.MAIL_BODY, "You have been successfully added as the Org Admin to the system" + + " Please find your username and password"); + context.put(JsonKey.PSWRD, password); + context.put(JsonKey.USER_NAME, email); + context.put(JsonKey.FIRST_NAME, firstName); + + SendMail.sendMail(new String[] { email }, "Welcome To Aurora-Desk", context, "email_template.vm"); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception while sending an Admin Mail : %s", e.getMessage())); + } + } + + @Override + public S3Config getS3Access() { + S3Config exp = null; + try { + exp = jdbcTemplate.query(Sql.GET_S3_ACCESS, MasterDataManager.rowMapS3Config).get(0); + } catch (Exception e) { + LOGGER.error(e.getMessage()); + } + return exp; + } + + @Override + public boolean updateOrganizationById(Organization org) { + int value = 0; + try { + value = jdbcTemplate.update(Sql.Organization.UPDATE_ORG, + new Object[] { org.getOrgName(), org.getLogo(), DateUtil.getFormattedDateInUTC(new Date()), + org.getUserId(), org.getUrl(), org.getOrgDescription(), org.getOrgColor(), + org.getEmailDomain(), org.getId() }); + } catch (Exception e) { + LOGGER.error( + String.format("Encountered an Exception while updating Organization by ID : %s", e.getMessage())); + } + return (value > 0); + } + + private String getOrgLogo(Organization org) { + if (org.getLogo() != null) { + try { + S3Config s3values = jdbcTemplate.query(Sql.GET_S3_ACCESS, MasterDataManager.rowMapS3Config).get(0); + String url = null; + url = S3FileManager.getPreSignedURL(s3values, org.getLogo()); + return url; + } catch (Exception e) { + return ""; + } + } + return ""; + } + + @Override + public boolean deleteOrganization(Organization organization) { + try { + int value = jdbcTemplate.update(Sql.Organization.DELETE_ORG, new Object[] { organization.getUserId(), + DateUtil.getFormattedDateInUTC(new Date()), organization.getId() }); + return (value > 0); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return false; + } + + @Override + public int getOrganizationByUserId(long authUserId) { + try { + return jdbcTemplate.query(Sql.Organization.GET_ORG_BY_USERID, new Object[] { authUserId }, + MasterDataManager.rowMapOrganizationModel).get(0).getId().intValue(); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return 0; + } + + @Override + public boolean mapUserToOrg(long userId, int organisationId) { + try { + Integer response = jdbcTemplate.update(Sql.UserQueries.MAP_USER_TO_ORG, + new Object[] { userId, organisationId }); + return (response > 0); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return false; + } + + @Override + public User userDetailsByUserId(long userId) { + try { + List<User> list = jdbcTemplate.query(Sql.UserQueries.USER, new Object[] { userId }, + MasterDataManager.rowMapUser); + return list.get(0); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return null; + } + + @Override + public boolean mapAppsToOrg(StatusIdMap statusIdMap) { + + try { + LOGGER.debug("Query to execute : " + Apps.DELETE_ORG_APP); + Integer response1 = jdbcTemplate.update(Sql.Apps.DELETE_ORG_APP, + new Object[] { statusIdMap.getAppId(), statusIdMap.getOrgId() }); + Integer response = jdbcTemplate.update(Sql.Apps.MAP_APP_TO_ORG, + new Object[] { statusIdMap.getAppId(), statusIdMap.getOrgId() }); + return (response > 0 && response1 > 0); + } catch (Exception e) { + LOGGER.error(String.format("Exception in mapAppToOrg daoImpl %s", e.getMessage())); + return false; + + } + } + + @Override + public List<Organization> getOrganizationByUser(Long userId) { + try { + List<Organization> org = jdbcTemplate.query(Sql.Organization.GET_ORG_BY_USERID, new Object[] { userId }, + MasterDataManager.rowMapOrganizationModel); + for (int i = 0; i < org.size(); i++) { + String url = getOrgLogo(org.get(i)); + if (!url.isEmpty()) { + org.get(i).setLogo(url); + } else { + org.get(i).setLogo(null); + } + } + return org; + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + return new ArrayList<>(); + } + } + + @Override + public Organization getOrganizationByIdV2(Long id) { + try { + OrgMapper orgMapper = new SqlDataMapper().new OrgMapper(); + jdbcTemplate.query(Sql.Organization.ORG_BY_ID, new Object[] { true, true, id, id, Sql.Common.ORGADMIN }, + orgMapper); + String url = getOrgLogo(orgMapper.getOrg()); + if (!url.isEmpty()) { + orgMapper.getOrg().setLogo(url); + } else { + orgMapper.getOrg().setLogo(null); + } + return orgMapper.getOrg(); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception in getOrganizationByIdV2 : %s", e.getMessage())); + } + return null; + } + +} diff --git a/src/main/java/org/upsmf/grievance/dao/impl/TagDaoImpl.java b/src/main/java/org/upsmf/grievance/dao/impl/TagDaoImpl.java new file mode 100644 index 0000000..443f6ca --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dao/impl/TagDaoImpl.java @@ -0,0 +1,139 @@ +package org.upsmf.grievance.dao.impl; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.ParameterizedPreparedStatementSetter; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Repository; + +import org.upsmf.grievance.dao.HelpdeskDao; +import org.upsmf.grievance.dao.TagDao; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.interceptor.TicketsRequestInterceptor; +import org.upsmf.grievance.model.Tags; +import org.upsmf.grievance.model.Ticket; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.util.Constants; +import org.upsmf.grievance.util.Sql; + +@Repository(Constants.TAG_DAO) +public class TagDaoImpl implements TagDao { + + private static final String ENCOUNTERED_AN_EXCEPTION_WHILE_FETCHING_ALL_TAGS_BY_ORG_S = "Encountered an Exception while fetching all tags by org : %s"; + + public static final Logger LOGGER = LoggerFactory.getLogger(TagDaoImpl.class); + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Autowired + private HelpdeskDao helpdeskDao; + + @Autowired + private TicketsRequestInterceptor ticketsRequestInterceptor; + + @Override + public List<Tags> getAllTags(Long orgId) { + try { + return jdbcTemplate.query(Sql.Tags.GET_ALL_TAG_BY_ORGANISATION, new Object[] { orgId }, + MasterDataManager.rowMapTags); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_FETCHING_ALL_TAGS_BY_ORG_S, e.getMessage())); + } + return new ArrayList<>(); + } + + @Override + public Tags getTagByName(String name, Long id) { + Tags tag = null; + try { + tag = jdbcTemplate.queryForObject(Sql.Tags.GET_TAG_BY_NAME, new Object[] { name, id }, + MasterDataManager.rowMapTags); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception while fetching tag by name : %s", e.getMessage())); + } + return tag; + } + + @Override + public Long addTag(Long id, Tags tag) { + KeyHolder keyHolderForTag = new GeneratedKeyHolder(); + jdbcTemplate.update(new PreparedStatementCreator() { + + @Override + public PreparedStatement createPreparedStatement(Connection conn) throws SQLException { + String[] returnCol = new String[] { Sql.Tags.TAG_ID }; + PreparedStatement preparedStatement = conn.prepareStatement(Sql.Tags.SAVE_TAG, returnCol); + preparedStatement.setString(1, tag.getName().trim()); + preparedStatement.setLong(2, id); + preparedStatement.setLong(3, MasterDataManager.getOrgForUser(id)); + return preparedStatement; + } + }, keyHolderForTag); + return keyHolderForTag.getKey().longValue(); + } + + @Override + public boolean addTicketTags(Long id, List<Tags> tags) { + jdbcTemplate.update(Sql.Tags.DELETE_TICKET_TAGS, new Object[] { id }); + int[][] added; + added = jdbcTemplate.batchUpdate(Sql.Tags.SAVE_TICKET_TAG, tags, tags.size(), + new ParameterizedPreparedStatementSetter<Tags>() { + @Override + public void setValues(PreparedStatement ps, Tags tag) throws SQLException { + ps.setLong(1, id); + ps.setLong(2, tag.getId()); + + } + }); + if (added.length > 0) { + Ticket ticket = new Ticket(); + ticket.setOperation("update"); + ticket.setId(id); + ticket.setTags(tags); + ticketsRequestInterceptor.addData(ticket); + return true; + } + return false; + } + + @Override + public List<Tags> getAllTicketTags(Long id) { + try { + return jdbcTemplate.query(Sql.Tags.GET_ALL_TICKET_TAGS, new Object[] { id }, MasterDataManager.rowMapTags); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_FETCHING_ALL_TAGS_BY_ORG_S, e.getMessage())); + } + return new ArrayList<>(); + } + + @Override + public List<Tags> getHelpdeskTags(Long id, Long userId) { + List<Long> admins = helpdeskDao.getHelpdeskAdmins(id); + List<User> user = helpdeskDao.getUsersForHelpeskId(id); + List<Long> userIds = user.stream().map(User::getId).collect(Collectors.toList()); + if (admins.contains(userId) || userIds.contains(userId)) { + try { + return jdbcTemplate.query(Sql.Tags.GET_ALL_TAG_BY_HELPDESK, new Object[] { id }, + MasterDataManager.rowMapTags); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_FETCHING_ALL_TAGS_BY_ORG_S, e.getMessage())); + } + } else { + LOGGER.info("This user is not a part of this helpdesk:"); + } + return new ArrayList<>(); + } + +} diff --git a/src/main/java/org/upsmf/grievance/dao/impl/TicketDaoImpl.java b/src/main/java/org/upsmf/grievance/dao/impl/TicketDaoImpl.java new file mode 100644 index 0000000..b030b39 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dao/impl/TicketDaoImpl.java @@ -0,0 +1,1595 @@ +package org.upsmf.grievance.dao.impl; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.apache.commons.lang.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; +import org.apache.velocity.exception.ResourceNotFoundException; +import org.elasticsearch.action.bulk.BulkRequest; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestClientBuilder; +import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback; +import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.index.query.BoolQueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.aggregations.AggregationBuilders; +import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval; +import org.elasticsearch.search.aggregations.bucket.histogram.Histogram; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Repository; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; + +import com.bazaarvoice.jolt.Chainr; +import com.bazaarvoice.jolt.JsonUtils; +import com.google.gson.Gson; +import org.upsmf.grievance.dao.HelpdeskDao; +import org.upsmf.grievance.dao.SuperAdminDao; +import org.upsmf.grievance.dao.TagDao; +import org.upsmf.grievance.dao.TicketDao; +import org.upsmf.grievance.dto.HelpdeskDto; +import org.upsmf.grievance.dto.HelpdeskTypeDto; +import org.upsmf.grievance.dto.HelpdeskWorkflowDto; +import org.upsmf.grievance.dto.TicketTypeDto; +import org.upsmf.grievance.dto.TicketWorkflowDto; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.interceptor.TicketsRequestInterceptor; +import org.upsmf.grievance.model.Access; +import org.upsmf.grievance.model.AccessResponse; +import org.upsmf.grievance.model.ActivityLog; +import org.upsmf.grievance.model.Analytics; +import org.upsmf.grievance.model.ChecklistItem; +import org.upsmf.grievance.model.Helpdesk; +import org.upsmf.grievance.model.KeyFactory; +import org.upsmf.grievance.model.S3Config; +import org.upsmf.grievance.model.Ticket; +import org.upsmf.grievance.model.TicketCount; +import org.upsmf.grievance.model.TicketElastic; +import org.upsmf.grievance.model.Updates; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.model.mapper.SqlDataMapper; +import org.upsmf.grievance.model.mapper.SqlDataMapper.HelpdeskRowRecordMapper; +import org.upsmf.grievance.model.mapper.SqlDataMapper.TicketWorkFlowMapperV2; +import org.upsmf.grievance.service.HelpdeskService; +import org.upsmf.grievance.service.UserService; +import org.upsmf.grievance.util.Constants; +import org.upsmf.grievance.util.DateUtil; +import org.upsmf.grievance.util.JsonKey; +import org.upsmf.grievance.util.ProjectUtil; +import org.upsmf.grievance.util.S3FileManager; +import org.upsmf.grievance.util.SendMail; +import org.upsmf.grievance.util.Sql; +import org.upsmf.grievance.util.Sql.Apps; + +@Repository(Constants.TICKET_DAO) +public class TicketDaoImpl implements TicketDao { + private static final String EL_STIC123 = "El@stic123"; + + private static final String ELASTIC = "elastic"; + + private static final String T = "T"; + + private static final String COUNT = "count"; + + private static final String CREATED_TIME = "createdTime"; + + private static final String EVENT = "event"; + + private static final String FEEDBACK_D1 = "feedback-d1"; + + private static final String REPLY = ":reply"; + + private static final String REVIEWS = "/reviews/"; + + private static final String REPLY_TEXT = "replyText"; + + private static final String ENCOUNTERED_AN_EXCEPTION_WHILE_UPDATING_TICKET_S = "Encountered an Exception while updating ticket : %s"; + + private static final String UPDATE = "update"; + + private static final String ENCOUNTERED_AN_EXCEPTION_WHILE_DELETING_WORKFLOW_STAGES_FOR_A_HELPDESK_TYPE = "Encountered an Exception while deleting Workflow Stages for a Helpdesk Type : %s"; + + private static final String ENCOUNTERED_AN_EXCEPTION_S = "Encountered an Exception : %s"; + + public static final Logger LOGGER = LoggerFactory.getLogger(TicketDaoImpl.class); + + private Boolean attachmentSource; + @Value("${elk.data.up}") + private boolean elkDataUp; + + @Value("${elasticsearch.url}") + private String elasticsearchUrl; + + @Value("${elasticsearch.index}") + private String elasticsearchIndex; + + @Value("${elasticsearch.type}") + private String elasticsearchType; + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Autowired + private HelpdeskDao helpdeskDao; + + @Autowired + private HelpdeskService helpdeskService; + + @Autowired + private SuperAdminDao superAdminDao; + + @Autowired + private UserService userService; + + @Autowired + private TagDao tagDao; + + @Autowired + private TicketsRequestInterceptor ticketsRequestInterceptor; + + public TicketDaoImpl(@Value("${image.source.attachment.aws}") Boolean attachmentSource, JdbcTemplate jdbcTemplate, + HelpdeskDao helpdeskDao, HelpdeskService helpdeskService, SuperAdminDao superAdminDao) { + this.attachmentSource = attachmentSource; + this.jdbcTemplate = jdbcTemplate; + this.helpdeskDao = helpdeskDao; + this.helpdeskService = helpdeskService; + this.superAdminDao = superAdminDao; + } + + @Override + public Ticket addTicket(Ticket ticket) { + if (ProjectUtil.isObjectNull(intializeAddTicket(ticket))) { + return null; + } + KeyHolder keyHolder = KeyFactory.getkeyHolder(); + try { + if (ProjectUtil.isObjectNull(getApps(ticket))) { + return null; + } + Long orgId = jdbcTemplate.queryForObject(Apps.GET_ORG_ID_FROM_APP_ID, new Object[] { ticket.getAppId() }, + Long.class); + ticket.setOrgId(orgId); + if (ticket.getHelpdeskId() == null) { + Long helpdeskId = jdbcTemplate.queryForObject(Apps.GET_HELPDESK_ID_FROM_APP_ID, + new Object[] { ticket.getAppId() }, Long.class); + ticket.setHelpdeskId(helpdeskId); + } + if (sourceId(ticket)) { + ticket.setSourceId(3L); + } + if (ticket.getHelpdeskId() != null) { + Helpdesk helpdesk = jdbcTemplate.query(Sql.UserQueries.GET_HELPDESK_CHANNELS, + new Object[] { ticket.getHelpdeskId() }, MasterDataManager.rowMapHelpdesk).get(0); + boolean val = val(ticket, helpdesk); + if (val) { + return null; + } + } + if (ticket.getRequestedBy() == null) { + setUsername(ticket); + } + jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { + String[] returnValColumn = new String[] { "id" }; + PreparedStatement statement = connection.prepareStatement(Sql.Ticket.ADD_TICKET, returnValColumn); + ticket.setCreatedTime(DateUtil.getFormattedDateInUTC(new Date())); + ticket.setUpdatedTime(DateUtil.getFormattedDateInUTC(new Date())); + ticket.setCreatedTimeTS(new Date().getTime()); + ticket.setUpdatedTimeTS(new Date().getTime()); + statement.setString(1, ticket.getCreatedTime()); + if (!StringUtils.isBlank(String.valueOf(ticket.getRate()))) { + statement.setLong(2, ticket.getRate()); + } else { + statement.setLong(2, 0L); + } + if (!StringUtils.isBlank(String.valueOf(ticket.getMaxRating()))) { + statement.setLong(3, ticket.getMaxRating()); + } else { + statement.setLong(3, 0L); + } + if (!StringUtils.isBlank(ticket.getPriority())) { + statement.setString(4, ticket.getPriority()); + } else { + statement.setString(4, "p3"); + } + if (ticket.getRequestedBy() != null) { + statement.setLong(5, ticket.getRequestedBy()); + } + if (ticket.getDescription() != null) { + statement.setString(6, ticket.getDescription()); + } else if (ticket.getFeedback() != null) { + ticket.setDescription(ticket.getFeedback()); + statement.setString(6, ticket.getFeedback()); + } else { + statement.setString(6, ""); + } + if (ticket.getType() != null) { + statement.setLong(7, ticket.getType()); + } else { + Long id = jdbcTemplate.queryForObject(Sql.Ticket.GET_DEFAULT_TICKET_TYPE, + new Object[] { ticket.getHelpdeskId() }, Long.class); + ticket.setType(id); + if (id > 0) { + statement.setLong(7, id); + } + } + statement.setString(8, ticket.getUpdatedTime()); + statement.setBoolean(9, false); + return statement; + } + }, keyHolder); + ticket.setId(keyHolder.getKey().longValue()); + if (ticket.getReviewId() != null) { + jdbcTemplate.update(Sql.Ticket.UPDATE_TICKET_REVIEW_ID, + new Object[] { ticket.getReviewId(), ticket.getId() }); + boolean v = value(ticket); + if (v) { + jdbcTemplate.update(Sql.Ticket.ADD_UPDATES, + new Object[] { ticket.getDeveloperComment(), ticket.getRequestedBy(), ticket.getId(), + convertFromTimestampToUTC(ticket.getDeveloperTimestamp()) }); + } + } + ticket.setSourceId(ticket.getSourceId()); + mapTicketToHelpdesk(ticket); + addCc(ticket); + TicketTypeDto ticketTypeDto = new TicketTypeDto(ticket); + String value = addDefaultWorkflowForTicketType(ticketTypeDto); + Boolean value1 = addChecklistForTicketType(ticketTypeDto); + ticket.setActive(true); + ticket.setOperation("save"); + ticket.setStatus(value); + if (ticket.getSourceId().equals(3L)) { + sendTicketEmail(ticket); + ticketsRequestInterceptor.addData(ticket); + } + if (!value1) { + return null; + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + return null; + } + addTicketActivityLog(ticket.getId(), "New ticket has been created", ticket.getRequestedBy()); + return ticket; + } + + public void setUsername(Ticket ticket) { + User user = new User(); + if (!StringUtils.isBlank(ticket.getUserName())) { + user.setUsername(ticket.getUserName()); + } else { + user.setUsername("anonymous" + genText() + "@mail.com"); + } + user.setOrgId(ticket.getOrgId()); + ticket.setRequestedBy(userService.saveAnonymousUser(user)); + } + + public boolean sourceId(Ticket ticket) { + return ticket.getSourceId() == null || ticket.getSourceId().toString().isEmpty(); + } + + public boolean value(Ticket ticket) { + return ticket.getDeveloperComment() != null && ticket.getDeveloperTimestamp() != null; + } + + public boolean val(Ticket ticket, Helpdesk helpdesk) { + return !((helpdesk.getDirect() && ticket.getSourceId() == 3L) + || (helpdesk.getPlaystore() && ticket.getSourceId() == 4L) + || (helpdesk.getAppstore() && ticket.getSourceId() == 5L) + || (helpdesk.getAurora_sdk() && ticket.getSourceId() == 1L)); + } + + private Ticket getApps(Ticket ticket) { + if (ticket.getAppId() == null && ticket.getAppName() != null) { + Long id = jdbcTemplate.queryForObject(Apps.CHECK_IF_APP_NAME_EXISTS, new Object[] { ticket.getAppName() }, + Long.class); + if (id > 0) { + id = jdbcTemplate.queryForObject(Apps.GET_APP_ID_APP_KEY, new Object[] { ticket.getAppName() }, + Long.class); + ticket.setAppId(id); + } else { + LOGGER.info("There is no app Url in the system as sent in the feedback, therefore no ticket is created " + + ticket.getAppName()); + return null; + } + } else if (ticket.getAppId() == null && ticket.getAppKey() != null) { + Long id = jdbcTemplate.queryForObject(Apps.CHECK_GET_APP_ID_FROM_APP_KEY, + new Object[] { ticket.getAppName() }, Long.class); + if (id != 0) { + id = jdbcTemplate.queryForObject(Apps.GET_APP_ID_FROM_APP_KEY, new Object[] { ticket.getAppKey() }, + Long.class); + ticket.setAppId(id); + } else { + LOGGER.info( + "There is no app related to the app key sent in the feedback, therefore no ticket is created " + + ticket.getAppKey()); + return null; + } + } + return ticket; + } + + private Ticket intializeAddTicket(Ticket ticket) { + if (!StringUtils.isBlank(ticket.getFeedback()) && !StringUtils.isBlank(ticket.getUserName())) { + if (jdbcTemplate.queryForObject(Apps.CHECK_IF_TICKET_EXIST, + new Object[] { ticket.getFeedback(), ticket.getUserName() }, Long.class) != 0) { + if (ticket.getSourceId() == 4L && ticket.getReviewId() != null) { + if (jdbcTemplate.queryForObject(Apps.CHECK_IF_TICKET_EXISTS, + new Object[] { ticket.getReviewId(), ticket.getUserName() }, Long.class) != 0) { + if (value(ticket) + && jdbcTemplate.queryForObject(Apps.CHECK_IF_UPDATE_EXISTS, + new Object[] { ticket.getDeveloperComment(), + convertFromTimestampToUTC(ticket.getDeveloperTimestamp()) }, + Long.class) == 0) { + jdbcTemplate.update(Sql.Ticket.ADD_UPDATES, + new Object[] { ticket.getDeveloperComment(), ticket.getRequestedBy(), + ticket.getId(), + convertFromTimestampToUTC(ticket.getDeveloperTimestamp()) }); + } + return null; + } else { + return null; + } + } + } else if (ticket.getSourceId() == 4L && ticket.getReviewId() != null + && jdbcTemplate.queryForObject(Apps.CHECK_IF_TICKET_EXISTS, + new Object[] { ticket.getReviewId(), ticket.getUserName() }, Long.class) != 0) { + if (ticket.getUserTimestamp() != null && jdbcTemplate.queryForObject(Apps.CHECK_IF_UPDATE_EXISTS, + new Object[] { ticket.getFeedback(), convertFromTimestampToUTC(ticket.getUserTimestamp()) }, + Long.class) == 0) { + jdbcTemplate.update(Sql.Ticket.ADD_UPDATES, + new Object[] { ticket.getFeedback(), ticket.getUserName(), ticket.getId(), + convertFromTimestampToUTC(ticket.getUserTimestamp()) }); + } + if (value(ticket) + && jdbcTemplate + .queryForObject(Apps.CHECK_IF_UPDATE_EXISTS, + new Object[] { ticket.getDeveloperComment(), + convertFromTimestampToUTC(ticket.getDeveloperTimestamp()) }, + Long.class) == 0) { + jdbcTemplate.update(Sql.Ticket.ADD_UPDATES, + new Object[] { ticket.getDeveloperComment(), ticket.getRequestedBy(), ticket.getId(), + convertFromTimestampToUTC(ticket.getDeveloperTimestamp()) }); + } + return null; + } + } + return ticket; + } + + public String genText() { + String randomText = "abcdefghijklmnopqrstuvwxyz123456789"; + int length = 5; + return RandomStringUtils.random(length, randomText); + } + + private void sendTicketEmail(Ticket ticket) { + try { + User user = superAdminDao.userDetailsByUserId(ticket.getRequestedBy()); + user.setOrgId(MasterDataManager.getUserOrgMap().get(ticket.getRequestedBy())); + String email = user.getUsername(); + Map<String, String> keyValue = new HashMap<>(); + keyValue.put(JsonKey.FIRST_NAME, user.getName()); + keyValue.put(JsonKey.ID, ticket.getId().toString()); + keyValue.put(JsonKey.HELPDESKID, ticket.getHelpdeskId().toString()); + keyValue.put(JsonKey.HELPDESKNAME, + MasterDataManager.getHelpdeskIdHelpdeskObjectMapping().get(ticket.getHelpdeskId()).getName()); + String[] emails = email.split(","); + SendMail.sendMail(keyValue, emails, Constants.TICKETCREATION, "new-ticket-createdby-aurora.vm"); + } catch (ResourceNotFoundException e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + } + + private void mapTicketToHelpdesk(Ticket ticket) { + if (ticket.getAppId() != null) { + jdbcTemplate.update(Sql.Ticket.ADD_TICKET_TO_HELPDESK, + new Object[] { ticket.getId(), ticket.getSourceId(), ticket.getHelpdeskId(), ticket.getAppId() }); + } + + } + + @Override + public boolean attachmentUpload(MultipartFile file, Ticket ticket) { + List<Long> ticketIds = jdbcTemplate.queryForList(Sql.Ticket.GET_CREATED_AND_COPIED_TO_TICKET_IDS, + new Object[] { ticket.getUserId(), ticket.getUserId() }, Long.class); + Long helpdeskId = jdbcTemplate.queryForObject(Sql.Ticket.GET_HELPDESK_ID_FOR_TICKET, + new Object[] { ticket.getId() }, Long.class); + List<User> admins = new ArrayList<>(); + if (helpdeskId != null) { + admins = helpdeskDao.getAdminForHelpeskId(helpdeskId); + } + List<Long> userIdList = admins.stream().map(User::getId).collect(Collectors.toList()); + if (ticketIds.contains(ticket.getId()) || userIdList.contains(ticket.getUserId())) { + if (attachmentSource) { + return fetchAttach(ticket); + } else if (file != null) { + return fetchAtt(file, ticket); + } + } + return false; + } + + public boolean fetchAttach(Ticket ticket) { + try { + if (ticket.getAttachmentUrl() != null) { + jdbcTemplate.update(Sql.UserQueries.REMOVE_ALL_TICKET_ATTACHMENT, new Object[] { ticket.getId() }); + for (int i = 0; i < ticket.getAttachmentUrl().size(); i++) { + String val = getImagePathValue(ticket, ticket.getAttachmentUrl().get(i)); + addAttachmentToTicket(ticket, val); + } + return true; + } else { + return false; + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + return false; + } + } + + public boolean fetchAtt(MultipartFile file, Ticket ticket) { + try { + String val = uploadFile(file, ticket.getId()); + Long attachmentId = getLastInsertId(val); + if (attachmentId > 0) { + jdbcTemplate.update(Sql.ADD_ATTACHMENT_TO_TICKET, new Object[] { ticket.getId(), attachmentId }); + } + return true; + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + return false; + } + } + + private void addAttachmentToTicket(Ticket ticket, String val) { + try { + Long attachmentId = getLastInsertId(val); + if (attachmentId > 0) { + jdbcTemplate.update(Sql.ADD_ATTACHMENT_TO_TICKET, new Object[] { ticket.getId(), attachmentId }); + } + } catch (Exception e) { + LOGGER.error("Erorr while uploading the attachment"); + } + } + + public Long getLastInsertId(String val) { + Long id = (long) 0; + try { + KeyHolder keyHolder = KeyFactory.getkeyHolder(); + jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { + String[] returnValColumn = new String[] { "id" }; + PreparedStatement statement = con.prepareStatement(Sql.INSERT_ATTACHMENT, returnValColumn); + statement.setString(1, val); + return statement; + } + }, keyHolder); + id = keyHolder.getKey().longValue(); + } catch (Exception e) { + + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return id; + } + + public String getImagePathValue(Ticket ticket, String url) { + String value = null; + try { + Long organization = MasterDataManager.getUserOrgMap().get(ticket.getUserId()); + value = S3FileManager.attachementfilePath(url, "attachment", ticket.getId(), organization); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return value; + } + + public void addCc(Ticket ticket) { + try { + if (ticket.getCc() != null) { + Long id = ticket.getId(); + Long helpdeskId = ticket.getHelpdeskId(); + List<Long> oldCC = getTicketCC(id); + for (Long admin : ticket.getCc()) { + if (oldCC.contains(admin)) { + oldCC.remove(admin); + } + } + for (int i = 0; i < oldCC.size(); i++) { + User user = superAdminDao.userDetailsByUserId(oldCC.get(i)); + String email = user.getUsername(); + Map<String, String> keyValue = new HashMap<>(); + keyValue.put(JsonKey.FIRST_NAME, user.getName()); + keyValue.put(JsonKey.ID, id.toString()); + keyValue.put(JsonKey.HELPDESKID, helpdeskId.toString()); + keyValue.put(JsonKey.HELPDESKNAME, + MasterDataManager.getHelpdeskIdHelpdeskObjectMapping().get(helpdeskId).getName()); + String[] emails = email.split(","); + SendMail.sendMail(keyValue, emails, Constants.REMOVEDFROMCOPIEDTO, + "remove-copied-to-ticket-aurora.vm"); + } + jdbcTemplate.update(Sql.UserQueries.REMOVE_ALL_TICKET_CC, new Object[] { id }); + for (int i = 0; i < ticket.getCc().size(); i++) { + jdbcTemplate.update(Sql.UserQueries.ADD_CC_TO_TICKET, new Object[] { id, ticket.getCc().get(i) }); + User user = superAdminDao.userDetailsByUserId(ticket.getCc().get(i)); + user.setOrgId(MasterDataManager.getUserOrgMap().get(ticket.getCc().get(i))); + String email = user.getUsername(); + Map<String, String> keyValue = new HashMap<>(); + keyValue.put(JsonKey.FIRST_NAME, user.getName()); + keyValue.put(JsonKey.ID, id.toString()); + keyValue.put(JsonKey.HELPDESKID, helpdeskId.toString()); + keyValue.put(JsonKey.HELPDESKNAME, + MasterDataManager.getHelpdeskIdHelpdeskObjectMapping().get(helpdeskId).getName()); + LOGGER.info(MasterDataManager.getHelpdeskIdHelpdeskObjectMapping().get(helpdeskId).getName()); + String[] emails = email.split(","); + SendMail.sendMail(keyValue, emails, Constants.COPIEDTO, "copied-to-ticket-aurora.vm"); + } + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + } + + public List<Ticket> addTicketActivityLog(Long ticketId, String activity, Long changesBy) { + List<Ticket> ticketList = null; + try { + jdbcTemplate.update(Sql.Ticket.ADD_ACTIVITY_LOG, + new Object[] { activity, ticketId, DateUtil.getFormattedDateInUTC(new Date()), changesBy }); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return ticketList; + } + + @Override + public List<Ticket> getAllTicketsByUserId(Long id) { + List<Ticket> ticketList = new ArrayList<>(); + try { + ticketList = jdbcTemplate.query(Sql.Ticket.GET_ALL_TICKETS, new Object[] { id }, + MasterDataManager.rowMapTicket); + setUserNamesAndWorkflow(ticketList); + for (int i = 0; i < ticketList.size(); i++) { + setTicketCCAndStatus(ticketList, i); + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return ticketList; + } + + @Override + public List<Ticket> keepOnlyCreatedAndCopiedToTickets(Long userId, List<Ticket> ticketList) { + List<Long> ticketIds = jdbcTemplate.queryForList(Sql.Ticket.GET_CREATED_AND_COPIED_TO_TICKET_IDS, + new Object[] { userId, userId }, Long.class); + Iterator<Ticket> itr = ticketList.iterator(); + while (itr.hasNext()) { + Ticket ticket = itr.next(); + if (!ticketIds.contains(ticket.getId())) { + itr.remove(); + } + } + return ticketList; + } + + @Override + public List<ChecklistItem> getChecklistItemsForTicket(Long ticketId) { + List<ChecklistItem> checklistItems = new ArrayList<>(); + try { + checklistItems = jdbcTemplate.query(Sql.Helpdesk.GET_CHECKLIST_FOR_TICKET, new Object[] { ticketId }, + new SqlDataMapper().new TicketsChecklistItemMapper()); + } catch (Exception e) { + LOGGER.error(String.format("Encountered exception in get Checklist for ticket %s", e.getMessage())); + } + return checklistItems; + } + + @Override + public String addDefaultWorkflowForTicketType(TicketTypeDto ticketTypeDto) { + HelpdeskRowRecordMapper helpdesk = helpdeskDao.getHelpdeskForId(ticketTypeDto.getOrgId(), + ticketTypeDto.getHelpdeskId()); + List<Long> workFlowIds = new ArrayList<>(helpdesk.getHelpdeskWorkflowMap().keySet()); + int[] values = null; + String name = ""; + try { + values = jdbcTemplate.batchUpdate(Sql.Ticket.INSERT_WORKFLOW_FOR_TICKET_TYPE, + new BatchPreparedStatementSetter() { + @Override + public void setValues(java.sql.PreparedStatement statement, int i) throws SQLException { + statement.setLong(1, workFlowIds.get(i)); + statement.setLong(2, ticketTypeDto.getId()); + } + + @Override + public int getBatchSize() { + return workFlowIds.size(); + } + }); + name = updateTicketWorkFlowinDB(ticketTypeDto, workFlowIds, values, name); + } catch (Exception ex) { + LOGGER.error(String.format("Exception Occured while mapping Products to Order : %s", ex.getMessage())); + } + return name; + + } + + private String updateTicketWorkFlowinDB(TicketTypeDto ticketTypeDto, List<Long> workFlowIds, int[] values, + String name) { + if (values != null && values.length > 0) { + jdbcTemplate.update(Sql.Ticket.UPDATE_TICKET_WORKFLOW, new Object[] { true, + DateUtil.getFormattedDateInUTC(new Date()), workFlowIds.get(0), ticketTypeDto.getId() }); + name = jdbcTemplate.queryForObject(Sql.Ticket.GET_WORKFLOW_NAME, new Object[] { workFlowIds.get(0) }, + String.class); + } + return name; + } + + @Override + public Boolean addChecklistForTicketType(TicketTypeDto ticketTypeDto) { + List<ChecklistItem> helpdesk = helpdeskDao.getChecklistItemsForHelpdesk(ticketTypeDto.getHelpdeskId(), + ticketTypeDto.getTypeId()); + int[] values = null; + try { + values = jdbcTemplate.batchUpdate(Sql.Ticket.INSERT_CHECKLIST_FOR_TICKET_TYPE, + new BatchPreparedStatementSetter() { + @Override + public void setValues(java.sql.PreparedStatement statement, int i) throws SQLException { + statement.setLong(1, ticketTypeDto.getId()); + statement.setLong(2, helpdesk.get(i).getId()); + } + + @Override + public int getBatchSize() { + return helpdesk.size(); + } + }); + return (values != null && values.length > 0); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception while adding checklist type for a ticket : %s", + e.getMessage())); + return false; + } + } + + @Override + public Boolean deleteWorkflowForTicketType(Long ticketId) { + int status = 0; + try { + status = jdbcTemplate.update(Sql.Ticket.DELETE_WORKFLOW_FOR_TICKET_TYPE, new Object[] { ticketId }); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_DELETING_WORKFLOW_STAGES_FOR_A_HELPDESK_TYPE, + e.getMessage())); + return false; + } + return (status > 0); + } + + @Override + public Boolean deleteChecklistForTicketType(TicketTypeDto ticketTypeDto) { + int status = 0; + try { + status = jdbcTemplate.update(Sql.Helpdesk.DELETE_CHECKLIST_FOR_TICKET, + new Object[] { ticketTypeDto.getId() }); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_DELETING_WORKFLOW_STAGES_FOR_A_HELPDESK_TYPE, + e.getMessage())); + return false; + } + return (status > 0); + } + + @Override + public List<TicketWorkflowDto> getWorkflowForTicket(Long ticketId) { + List<TicketWorkflowDto> ticketWorkFlow = new ArrayList<>(); + try { + ticketWorkFlow = jdbcTemplate.query(Sql.Helpdesk.GET_WORKFLOW_FOR_TICKET, new Object[] { ticketId }, + new SqlDataMapper().new TicketWorkFlowMapper()); + } catch (Exception e) { + LOGGER.error(String.format("Encountered exception in getchecklist for ticket %s", e.getMessage())); + } + return ticketWorkFlow; + } + + public Map<Long, List<TicketWorkflowDto>> getWorkflowForTicketList(List<Long> ticketIdList) { + TicketWorkFlowMapperV2 mapper = new SqlDataMapper().new TicketWorkFlowMapperV2(); + if (!ticketIdList.isEmpty()) { + String queryAppend = getIdQuery(ticketIdList); + try { + jdbcTemplate.query(Sql.Helpdesk.GET_WORKFLOW_FOR_TICKET_LIST + queryAppend, new Object[] {}, mapper); + } catch (Exception e) { + LOGGER.error(String.format("Encountered exception in getchecklist for ticket %s", e.getMessage())); + } + } + return mapper.getTicketWorkflowMap(); + } + + private static String getIdQuery(final List<Long> idList) { + final StringBuilder query = new StringBuilder("("); + if (!idList.isEmpty()) { + query.append(idList.get(0).toString()); + for (int i = 1; i < idList.size(); i++) { + query.append(", " + idList.get(i)); + } + } + return query.append(")").toString(); + } + + @Override + public Boolean updateNotesToTicket(Long requestedBy, Long ticketId, String notes) { + try { + jdbcTemplate.update(Sql.Ticket.UPDATE_NOTES_TO_TICKETS, new Object[] { notes, ticketId }); + addTicketActivityLog(ticketId, "Ticket Notes has been updated", requestedBy); + return true; + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return false; + } + + @Override + public Boolean addUpdateUpdatesToTicket(Updates update) { + + try { + if (update.getId() != null) { + sendRepliesToReviews(update); + jdbcTemplate.update(Sql.Ticket.UPDATE_UPDATES, new Object[] { update.getUpds(), update.isActive(), + DateUtil.getFormattedDateInUTC(new Date()), update.getId() }); + } else { + sendRepliesToReviews(update); + List<Long> ccList = getTicketCC(update.getTicketId()); + Long requestedBy = jdbcTemplate.queryForObject(Apps.GET_REQUESTED_BY, + new Object[] { update.getTicketId() }, Long.class); + ccList.add(requestedBy); + ccList.remove(update.getCreatedBy()); + jdbcTemplate.update(Sql.Ticket.ADD_UPDATES, new Object[] { update.getUpds(), update.getCreatedBy(), + update.getTicketId(), DateUtil.getFormattedDateInUTC(new Date()) }); + for (int i = 0; i < ccList.size(); i++) { + sendMailToCC(update, ccList, i); + } + } + return true; + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return false; + } + + private void sendMailToCC(Updates update, List<Long> ccList, int i) { + try { + User user = superAdminDao.userDetailsByUserId(ccList.get(i)); + String email = user.getUsername(); + Map<String, String> keyValue = new HashMap<>(); + keyValue.put(JsonKey.FIRST_NAME, user.getName()); + keyValue.put(JsonKey.ID, update.getTicketId().toString()); + keyValue.put(JsonKey.UPDATE, update.getUpds()); + String[] emails = email.split(","); + SendMail.sendMail(keyValue, emails, Constants.UPDATES, "ticket-status-update-aurora.vm"); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + } + + @Override + public List<Updates> getUpdatesForTicket(Long id) { + List<Updates> update = null; + try { + update = jdbcTemplate.query(Sql.Ticket.GET_UPDATES, new Object[] { id }, MasterDataManager.rowMapUpdate); + } catch (Exception e) { + + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return update; + } + + @Override + public Long getTemplatesVersion() { + Long version = 0l; + try { + version = jdbcTemplate.queryForObject(Sql.Ticket.GET_VERSION_FOR_TEMPLATES, Long.class); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_DELETING_WORKFLOW_STAGES_FOR_A_HELPDESK_TYPE, + e.getMessage())); + } + return version; + } + + @Override + public boolean updateTemplateVersion(Long versionTimeStamp) { + LOGGER.info("Updating the Template Version Timestamp"); + try { + jdbcTemplate.update(Sql.Ticket.UPDATE_VERSION_TIMESTAMP, new Object[] { versionTimeStamp }); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception while updating the Version TimeStamp : %s", + e.getMessage())); + return false; + } + return true; + } + + @Override + public Ticket getTicketsById(Long userId, Long id) { + List<Ticket> ticketList = null; + try { + ticketList = jdbcTemplate.query(Sql.Ticket.GET_TICKET_BY_ID, new Object[] { id }, + MasterDataManager.rowMapTicket); + for (int i = 0; i < ticketList.size(); i++) { + List<Long> cc = getTicketCC(ticketList.get(i).getId()); + ticketList.get(i).setCc(cc); + List<String> attachment = getTicketAttachment(ticketList.get(i).getId()); + ticketList.get(i).setAttachmentUrl(attachment); + } + + if (!ticketList.isEmpty()) { + List<ChecklistItem> checklist = getChecklistItemsForTicket(id); + ticketList.get(0).setChecklist(checklist); + ticketList = setUserNamesAndWorkflow(ticketList); + List<TicketWorkflowDto> data = ticketList.get(0).getWorkflowStages(); + for (int i = 0; i < data.size(); i++) { + if (data.get(i).getStatus()) { + ticketList.get(0).setStatus(data.get(i).getName()); + } + } + List<String> att = fetchAtt(ticketList); + ticketList.get(0).setAttachmentUrl(att); + ticketList.get(0).setTags(tagDao.getAllTicketTags(id)); + return ticketList.get(0); + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return null; + } + + private List<String> fetchAtt(List<Ticket> ticketList) { + List<String> att = null; + try { + att = new ArrayList<>(); + S3Config s3values = superAdminDao.getS3Access(); + if (ticketList.get(0).getAttachmentUrl() != null) { + for (int i = 0; i < ticketList.get(0).getAttachmentUrl().size(); i++) { + if (ticketList.get(0).getAttachmentUrl() != null) { + fetchAttachment(ticketList, att, s3values, i); + } + } + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return att; + } + + private void fetchAttachment(List<Ticket> ticketList, List<String> att, S3Config s3values, int i) { + try { + String url = null; + url = S3FileManager.getPreSignedURL(s3values, ticketList.get(0).getAttachmentUrl().get(i)); + att.add(url); + } catch (Exception e) { + fetchFile(ticketList, i, e); + } + } + + private void fetchFile(List<Ticket> ticketList, int i, Exception e) { + try { + byte[] file = getFile(ticketList.get(0).getAttachmentUrl().get(i)); + ticketList.get(0).setImg(file); + } catch (Exception e1) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + } + + public byte[] getFile(String attachmentUrl) { + try { + byte[] content = null; + if (!StringUtils.isBlank(attachmentUrl)) { + Path path = Paths.get(Constants.ATTACHMENT_FOLDER + attachmentUrl); + content = readBytes(content, path); + } + return content; + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return new byte[0]; + } + + private byte[] readBytes(byte[] content, Path path) { + try { + content = Files.readAllBytes(path); + } catch (final IOException e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return content; + } + + private List<Ticket> setUserNamesAndWorkflow(List<Ticket> newTicketList) { + List<Long> ticketIdList = newTicketList.stream().map(Ticket::getId).collect(Collectors.toList()); + Map<Long, List<TicketWorkflowDto>> ticketWorkflowMap = getWorkflowForTicketList(ticketIdList); + for (Ticket ticket : newTicketList) { + if (ticket.getRequestedBy() != null && StringUtils + .isNotBlank(MasterDataManager.getUserIdAndUserNameMap().get(ticket.getRequestedBy()))) { + ticket.setRequestedByName(MasterDataManager.getUserIdAndUserNameMap().get(ticket.getRequestedBy())); + } + if (ticketWorkflowMap.get(ticket.getId()) != null && !ticketWorkflowMap.get(ticket.getId()).isEmpty()) { + ticket.setWorkflowStages(ticketWorkflowMap.get(ticket.getId())); + } + } + return newTicketList; + } + + @Override + public TicketCount getNoOfTickets(Long userId) { + try { + TicketCount ticketCount = new TicketCount(); + List<Ticket> tickets = getAllTicketsByUserId(userId); + Long pinnedTicketCount = 0L; + Long closedTicketCount = 0L; + if (!tickets.isEmpty()) { + for (int i = 0; i < tickets.size(); i++) { + if (getPinnedTicket(tickets, i)) { + pinnedTicketCount = pinnedTicketCount + 1; + } + List<TicketWorkflowDto> workflow = getWorkflowForTicket(tickets.get(i).getId()); + for (int j = 0; j < workflow.size(); j++) { + if (workflow.get(j).getStatus() && workflow.get(j).getName().equals("Closed")) { + closedTicketCount = closedTicketCount + 1; + } + } + + } + } + ticketCount.setCreatedTicketCount(Long.valueOf(tickets.size())); + ticketCount.setPinnedTicketCount(pinnedTicketCount); + ticketCount.setClosedTicketCount(closedTicketCount); + return ticketCount; + } catch (Exception e) { + + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return null; + + } + + public boolean getPinnedTicket(List<Ticket> tickets, int i) { + return !ProjectUtil.isObjectNull(tickets.get(i).getPinnedTicket()) && tickets.get(i).getPinnedTicket(); + } + + public List<Long> getTicketCC(Long id) { + try { + return jdbcTemplate.queryForList(Sql.UserQueries.GET_TICKET_CC, new Object[] { id }, Long.class); + } catch (Exception e) { + + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return new ArrayList<>(); + + } + + public List<String> getTicketAttachment(Long id) { + try { + return jdbcTemplate.queryForList(Sql.UserQueries.GET_TICKET_ATTACHMENT, new Object[] { id }, String.class); + } catch (Exception e) { + + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return new ArrayList<>(); + + } + + @Override + public List<Ticket> getAllTicketsByAppId(Long appId) { + List<Ticket> ticketList = null; + try { + ticketList = jdbcTemplate.query(Sql.Ticket.GET_ALL_TICKETS_BY_APP_ID, new Object[] { appId }, + MasterDataManager.rowMapTicket); + for (int i = 0; i < ticketList.size(); i++) { + setTicketCCAndStatus(ticketList, i); + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return ticketList; + } + + private void setTicketCCAndStatus(List<Ticket> ticketList, int i) { + List<Long> cc = getTicketCC(ticketList.get(i).getId()); + ticketList.get(i).setCc(cc); + List<TicketWorkflowDto> workFlow = getWorkflowForTicket(ticketList.get(i).getId()); + for (int j = 0; j < workFlow.size(); j++) { + if (workFlow.get(j).getStatus()) { + ticketList.get(i).setStatus(workFlow.get(j).getName()); + } + } + } + + @Override + public boolean updateTicketBasic(MultipartFile file, Ticket ticket) { + ticket.setUpdatedTime(DateUtil.getFormattedDateInUTC(new Date())); + Long loggedInUserId = ticket.getUserId(); + int status = 0; + Long id = ticket.getId(); + Ticket oldticket = getTicketsById(loggedInUserId, id); + List<Long> admins = helpdeskDao.getHelpdeskAdmins(oldticket.getHelpdeskId()); + Ticket oldestTicket = oldticket; + try { + if (!admins.contains(loggedInUserId)) { + List<Ticket> ticketList = new ArrayList<>(); + ticketList.add(oldticket); + List<Ticket> t = keepOnlyCreatedAndCopiedToTickets(loggedInUserId, ticketList); + if (!t.isEmpty()) { + oldticket = t.get(0); + oldestTicket = oldticket; + } + } else { + status = jdbcTemplate.update(Sql.Ticket.UPDATE_TICKET, new Object[] { ticket.getPriority(), + ticket.getNotes(), ticket.getActive(), ticket.getUpdatedTime(), id }); + } + if (checkIfLoggedInUserIsTheCreatorOfTheTicket(loggedInUserId, oldticket, admins)) { + ticket.setHelpdeskId(oldticket.getHelpdeskId()); + addCc(ticket); + status = jdbcTemplate.update(Sql.Ticket.UPDATE_TICKET_DESCRIPTION, + new Object[] { ticket.getDescription(), id }); + } + Ticket newticket = getTicketsById(loggedInUserId, id); + Ticket t = new Ticket(); + t.setId(id); + if (newticket != null) { + if (!oldestTicket.getDescription().equals(newticket.getDescription())) { + addTicketActivityLog(id, "Ticket Description has been updated to " + newticket.getDescription(), + loggedInUserId); + t.setDescription(newticket.getDescription()); + } + if (!oldestTicket.getPriority().equals(newticket.getPriority())) { + addTicketActivityLog(id, "Ticket priority has been updated to " + newticket.getPriority(), + loggedInUserId); + t.setPriority(newticket.getPriority()); + } + if (newticket.getNotes() != null && oldestTicket.getNotes() != null + && !oldestTicket.getNotes().equals(newticket.getNotes())) { + addTicketActivityLog(id, "Ticket Notes has been updated to " + newticket.getNotes(), + loggedInUserId); + } + } else { + addTicketActivityLog(id, "Ticket Status has been updated to " + ticket.getActive(), loggedInUserId); + t.setActive(ticket.getActive()); + } + + t.setCc(ticket.getCc()); + t.setOperation(UPDATE); + t.setUpdatedTimeTS(new Date().getTime()); + t.setUpdatedTime(ticket.getUpdatedTime()); + ticketsRequestInterceptor.addData(t); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_UPDATING_TICKET_S, e.getMessage())); + return false; + } + return (status > 0); + } + + public boolean checkIfLoggedInUserIsTheCreatorOfTheTicket(Long loggedInUserId, Ticket oldticket, + List<Long> admins) { + return oldticket.getRequestedBy().equals(loggedInUserId) || admins.contains(loggedInUserId); + } + + public String convertFromTimestampToUTC(Long timestamp) { + try { + Date d = new Date(timestamp * 1000); + DateFormat f = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); + return f.format(d); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return ""; + } + + public String uploadFile(MultipartFile file, long ticketId) { + try { + if (!new File(Constants.ATTACHMENT_FOLDER).exists()) { + if (new File(Constants.ATTACHMENT_FOLDER).mkdir()) { + LOGGER.info("Directory is created!"); + } else { + LOGGER.error("Failed to create directory!"); + } + } else { + LOGGER.info("Folder exist"); + } + User user = new User(); + byte[] bytes = file.getBytes(); + String newFileName = ticketId + "." + file.getOriginalFilename().split(".")[1]; + String val = "\\" + ticketId + "\\" + newFileName; + Path path = Paths.get(Constants.ATTACHMENT_FOLDER + val); + if (!StringUtils.isBlank(path.toString())) { + LOGGER.info("Path before write: {}", path); + } + Path path1 = Files.write(path, bytes); + if (!StringUtils.isBlank(path1.toString())) { + LOGGER.info("Path after write : {}", path1); + } + Long attachmentId = getLastInsertId(val); + if (attachmentId > 0) { + jdbcTemplate.update(Sql.ADD_ATTACHMENT_TO_TICKET, new Object[] { ticketId, attachmentId }); + } + jdbcTemplate.update(Sql.INSERT_ATTACHMENT, new Object[] { val, ticketId }); + user.setImagePath(val); + return user.getImagePath(); + } catch (IOException e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return null; + } + + @Override + public boolean updateTicketType(TicketTypeDto ticketTypeDto, Long userId) { + int status = 0; + try { + status = jdbcTemplate.update(Sql.Ticket.UPDATE_TICKET_TYPE, + new Object[] { ticketTypeDto.getTypeId(), ticketTypeDto.getId() }); + deleteWorkflowForTicketType(ticketTypeDto.getId()); + String stat = addWorkFlowForTicketType(ticketTypeDto); + deleteChecklistForTicketType(ticketTypeDto); + addChecklistForTicketType(ticketTypeDto); + addTicketActivityLog(ticketTypeDto.getId(), + "Ticket Type has been updated to" + ticketTypeDto.getTypeId().toString(), userId); + Ticket newticket = new Ticket(); + newticket.setType(ticketTypeDto.getTypeId()); + newticket.setOperation(UPDATE); + newticket.setStatus(stat); + newticket.setUpdatedTime(DateUtil.getFormattedDateInUTC(new Date())); + newticket.setUpdatedTimeTS(new Date().getTime()); + ticketsRequestInterceptor.addData(newticket); + + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception while updating ticket type : %s", e.getMessage())); + return false; + } + return (status > 0); + } + + private String addWorkFlowForTicketType(TicketTypeDto ticketTypeDto) { + List<HelpdeskDto> helpdesk = helpdeskService.getHelpdeskById(ticketTypeDto.getOrgId(), + ticketTypeDto.getHelpdeskId()); + List<HelpdeskWorkflowDto> workFlowStages = new ArrayList<>(); + List<HelpdeskTypeDto> helpdeskTypes = helpdesk.get(0).getTypes(); + for (int i = 0; i < helpdeskTypes.size(); i++) { + if (helpdeskTypes.get(i).getId().equals(ticketTypeDto.getTypeId())) { + workFlowStages = helpdeskTypes.get(i).getWorkflowStages(); + } + } + List<Long> workFlowIds = workFlowStages.stream().map(HelpdeskWorkflowDto::getId).collect(Collectors.toList()); + int[] values = null; + String name = ""; + try { + values = jdbcTemplate.batchUpdate(Sql.Ticket.INSERT_WORKFLOW_FOR_TICKET_TYPE, + new BatchPreparedStatementSetter() { + @Override + public void setValues(java.sql.PreparedStatement statement, int i) throws SQLException { + statement.setLong(1, workFlowIds.get(i)); + statement.setLong(2, ticketTypeDto.getId()); + } + + @Override + public int getBatchSize() { + return workFlowIds.size(); + } + }); + if (values != null && values.length > 0) { + jdbcTemplate.update(Sql.Ticket.UPDATE_TICKET_WORKFLOW, + new Object[] { true, DateUtil.getFormattedDateInUTC(new Date()), workFlowStages.get(0).getId(), + ticketTypeDto.getId() }); + name = jdbcTemplate.queryForObject(Sql.Ticket.GET_WORKFLOW_NAME, new Object[] { workFlowIds.get(0) }, + String.class); + } + } catch (Exception ex) { + LOGGER.error(String.format("Exception Occured while mapping the new workflow : %s", ex.getMessage())); + } + return name; + } + + @Override + public boolean updateTicketStatus(Ticket ticket) { + int status = 0; + List<TicketWorkflowDto> oldWorkFlow = getWorkflowForTicket(ticket.getId()); + String oldStatus = ""; + String newStatus = ""; + for (int i = 0; i < oldWorkFlow.size(); i++) { + if (oldWorkFlow.get(i).getStatus()) { + oldStatus = oldWorkFlow.get(i).getName(); + } + } + try { + for (int i = 0; i < ticket.getWorkflowStages().size(); i++) { + status = jdbcTemplate.update(Sql.Ticket.UPDATE_TICKET_WORKFLOW, + new Object[] { ticket.getWorkflowStages().get(i).getStatus(), + DateUtil.getFormattedDateInUTC(new Date()), + ticket.getWorkflowStages().get(i).getWorkFlowId(), ticket.getId() }); + } + List<TicketWorkflowDto> workFlow = getWorkflowForTicket(ticket.getId()); + for (int i = 0; i < workFlow.size(); i++) { + if (workFlow.get(i).getStatus()) { + newStatus = workFlow.get(i).getName(); + } + } + addTicketActivityLog(ticket.getId(), + "Ticket Request Status has been updated from " + oldStatus + " to " + newStatus, + ticket.getRequestedBy()); + Ticket newticket = new Ticket(); + newticket.setId(ticket.getId()); + newticket.setOperation(UPDATE); + newticket.setStatus(newStatus); + newticket.setUpdatedTime(DateUtil.getFormattedDateInUTC(new Date())); + newticket.setUpdatedTimeTS(new Date().getTime()); + User user = superAdminDao.userDetailsByUserId(ticket.getRequestedBy()); + String email = user.getUsername(); + Map<String, String> keyValue = new HashMap<>(); + keyValue.put(JsonKey.FIRST_NAME, user.getName()); + keyValue.put(JsonKey.ID, ticket.getId().toString()); + keyValue.put(JsonKey.HELPDESKID, ticket.getHelpdeskId().toString()); + keyValue.put(JsonKey.HELPDESK_NAME, + MasterDataManager.getHelpdeskIdHelpdeskObjectMapping().get(ticket.getHelpdeskId()).getName()); + keyValue.put(JsonKey.OLDSTATUS, oldStatus); + keyValue.put(JsonKey.NEWSTATUS, newStatus); + String[] emails = email.split(","); + SendMail.sendMail(keyValue, emails, Constants.STATUS_CHANGE, "ticket-status-update-aurora.vm"); + ticketsRequestInterceptor.addData(newticket); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_UPDATING_TICKET_S, e.getMessage())); + return false; + } + return (status > 0); + } + + @Override + public List<TicketElastic> getTicketDetailsByHelpdeskId(Ticket ticket) { + RestHighLevelClient client = connectToElasticSearch(); + SearchResponse searchResponse = null; + List<TicketElastic> mapper = new ArrayList<>(); + List<Long> admins = helpdeskDao.getHelpdeskAdmins(ticket.getHelpdeskId()); + List<User> user = helpdeskDao.getUsersForHelpeskId(ticket.getHelpdeskId()); + Long userId = ticket.getUserId(); + ticket.setCc(new ArrayList<>(Arrays.asList(userId))); + List<Long> userIds = user.stream().map(User::getId).collect(Collectors.toList()); + if (userId > 0) { + try { + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); + BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); + setBoolQuery(ticket, admins, userId, userIds, boolQuery); + searchSourceBuilder.query(boolQuery); + commonQuery(ticket, searchSourceBuilder); + if (!searchSourceBuilder.toString().equals("{}")) { + searchResponse = searchFromTicketElasticData(client, searchSourceBuilder); + SearchHit[] hit = searchResponse.getHits().getHits(); + long total = searchResponse.getHits().getTotalHits(); + for (SearchHit hits : hit) { + String sourceAsMap = hits.getSourceAsString(); + Gson g = new Gson(); + TicketElastic ticketElastic = g.fromJson(sourceAsMap, TicketElastic.class); + ticketElastic.setTotal(total); + mapper.add(ticketElastic); + } + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + } + return mapper; + } + + public void setBoolQuery(Ticket ticket, List<Long> admins, Long userId, List<Long> userIds, + BoolQueryBuilder boolQuery) { + if (admins.contains(userId)) { + boolQuery.must(QueryBuilders.matchQuery("helpdeskId", ticket.getHelpdeskId())); + boolQuery.must(QueryBuilders.matchQuery("active", "true")); + } else if (userIds.contains(userId)) { + boolQuery.must(QueryBuilders.matchQuery("helpdeskId", ticket.getHelpdeskId())); + boolQuery.must(QueryBuilders.matchQuery("active", "true")); + BoolQueryBuilder newBoolQuery = QueryBuilders.boolQuery(); + newBoolQuery.should(QueryBuilders.termsQuery(Sql.Ticket.CC, ticket.getCc())); + newBoolQuery.should(QueryBuilders.matchQuery("requestedBy", ticket.getUserId())); + boolQuery.must(newBoolQuery); + } + if (ticket.getSourceId() != null) { + boolQuery.filter(QueryBuilders.termQuery(Sql.Ticket.SOURCE_ID, ticket.getSourceId())); + } + if (StringUtils.isNotBlank(ticket.getSearchKeyword())) { + boolQuery + .filter(QueryBuilders.wildcardQuery(Sql.Ticket.DESCRIPTION, "*" + ticket.getSearchKeyword() + "*")); + } + if (!ProjectUtil.isObjectListNullOrEmpty(ticket.getFilterStatus()) && !ticket.getFilterStatus().isEmpty()) { + boolQuery.filter(QueryBuilders.termsQuery(Sql.Ticket.STATUS, ticket.getFilterStatus())); + } + if (!ProjectUtil.isObjectListNullOrEmpty(ticket.getSelectedTags()) && !ticket.getSelectedTags().isEmpty()) { + boolQuery.filter(QueryBuilders.termsQuery(Sql.Ticket.TAGS, ticket.getSelectedTags())); + } + } + + public static <T, U> List<U> convertIntListToStringList(List<T> listOfInteger, Function<T, U> function) { + return listOfInteger.stream().map(function).collect(Collectors.toList()); + } + + private void commonQuery(Ticket ticket, SearchSourceBuilder searchSourceBuilder) { + if (!StringUtils.isBlank(ticket.getFilterCTUT())) { + searchSourceBuilder.sort(ticket.getFilterCTUT(), org.elasticsearch.search.sort.SortOrder.DESC); + } else { + searchSourceBuilder.sort("createdTimeTS", org.elasticsearch.search.sort.SortOrder.DESC); + } + if (!StringUtils.isBlank(String.valueOf(ticket.getFrom())) && ticket.getFrom() >= 0) { + searchSourceBuilder.from(ticket.getFrom()); + } + if (!StringUtils.isBlank(String.valueOf(ticket.getSize())) && ticket.getSize() >= 0) { + searchSourceBuilder.size(ticket.getSize()); + } else { + searchSourceBuilder.size(25); + } + searchSourceBuilder.fetchSource(Constants.getIncludeFields(), Constants.getExcludeFields()); + } + + @Override + public List<Ticket> getFeedBacksFromAuroraSdk() { + RestHighLevelClient client = connectToElasticSearch(); + SearchResponse searchResponse = null; + List<Ticket> mapper = new ArrayList<>(); + try { + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder() + .query(QueryBuilders.boolQuery().must(QueryBuilders.matchAllQuery())).size(700); + searchResponse = searchFromAuroraSdkData(client, searchSourceBuilder); + SearchHit[] hit = searchResponse.getHits().getHits(); + long total = searchResponse.getHits().getTotalHits(); + for (SearchHit hits : hit) { + String sourceAsMap = hits.getSourceAsString(); + Gson g = new Gson(); + Ticket t = g.fromJson(sourceAsMap, Ticket.class); + mapper.add(t); + } + BulkRequest request = new BulkRequest(); + for (int i = 0; i < total; i++) { + mapper.get(i).setSourceId(1L); + Ticket tkt = addTicket(mapper.get(i)); + if (tkt != null) { + Map<String, Object> jsonMap = ticketsRequestInterceptor.createJsonMap(tkt); + request.add(new IndexRequest(elasticsearchIndex, elasticsearchType, tkt.getId().toString()) + .source(jsonMap)); + } + } + client.bulk(request); + client.close(); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return mapper; + } + + @Override + public Map<String, Long> getTicketsCountPerMonthPerUser(Analytics analytics) { + RestHighLevelClient client = connectToElasticSearch(); + SearchResponse searchResponse = null; + Map<String, Long> monthCountMap = new HashMap<>(); + try { + DateHistogramInterval dateHistogramInterval = DateHistogramInterval.MONTH; + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder() + .query(QueryBuilders.boolQuery() + .must(QueryBuilders.rangeQuery(CREATED_TIME).gte(analytics.getStartDate()) + .lte(analytics.getEndDate())) + .filter(QueryBuilders.termQuery(Sql.Ticket.REQUESTEDBY, analytics.getUserId()))) + .aggregation(AggregationBuilders.dateHistogram(COUNT).field(CREATED_TIME) + .dateHistogramInterval(dateHistogramInterval)) + .size(0); + searchResponse = searchFromTicketElasticData(client, searchSourceBuilder); + Histogram hist = searchResponse.getAggregations().get(COUNT); + for (Histogram.Bucket bucket : hist.getBuckets()) { + monthCountMap.put(bucket.getKeyAsString().split(T)[0], bucket.getDocCount()); + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return monthCountMap; + } + + private RestHighLevelClient connectToElasticSearch() { + final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(ELASTIC, EL_STIC123)); + HttpClientConfigCallback r = new RestClientBuilder.HttpClientConfigCallback() { + @Override + public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { + return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); + } + }; + return new RestHighLevelClient( + RestClient.builder(new HttpHost(elasticsearchUrl)).setHttpClientConfigCallback(r)); + } + + private SearchResponse searchFromTicketElasticData(RestHighLevelClient client, + SearchSourceBuilder searchSourceBuilder) throws IOException { + SearchRequest searchRequest = new SearchRequest(elasticsearchIndex).types(elasticsearchType) + .source(searchSourceBuilder); + SearchResponse searchResponse = client.search(searchRequest); + client.close(); + return searchResponse; + } + + private SearchResponse searchFromAuroraSdkData(RestHighLevelClient client, SearchSourceBuilder searchSourceBuilder) + throws IOException { + SearchRequest searchRequest = new SearchRequest(FEEDBACK_D1).types(EVENT).source(searchSourceBuilder); + SearchResponse searchResponse = client.search(searchRequest); + client.close(); + return searchResponse; + } + + @Override + public boolean updateTicketChecklist(Ticket ticket) { + int status = 0; + try { + for (int i = 0; i < ticket.getChecklist().size(); i++) { + status = jdbcTemplate.update(Sql.Ticket.UPDATE_TICKET_CHECKLIST, + new Object[] { ticket.getChecklist().get(i).getChecked(), ticket.getChecklist().get(i).getId(), + ticket.getId() }); + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_WHILE_UPDATING_TICKET_S, e.getMessage())); + return false; + } + return (status > 0); + } + + @Override + public List<ActivityLog> getActivityLogsPerTicket(Long id) { + List<ActivityLog> activityLogs = null; + try { + activityLogs = jdbcTemplate.query(Sql.Ticket.GET_ACTIVITY_LOGS, new Object[] { id }, + MasterDataManager.rowMapActivityLogs); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return activityLogs; + } + + @Override + public List<ActivityLog> getActivityLogsPerUser(Long id) { + List<ActivityLog> activities = new ArrayList<>(); + try { + activities = jdbcTemplate.query(Sql.Ticket.GET_ACTIVITY_LOGS_PER_USER, new Object[] { id, id }, + MasterDataManager.rowMapActivityLogs); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return activities; + } + + @Override + public boolean pinTicket(Ticket ticket) { + try { + if (ticket.getPinnedTicket() != null) { + jdbcTemplate.update(Sql.Ticket.UPDATE_TICKET_PIN, + new Object[] { ticket.getPinnedTicket(), ticket.getId() }); + Ticket newticket = new Ticket(); + newticket.setId(ticket.getId()); + newticket.setPinnedTicket(ticket.getPinnedTicket()); + newticket.setOperation(UPDATE); + newticket.setUpdatedTime(DateUtil.getFormattedDateInUTC(new Date())); + newticket.setUpdatedTimeTS(new Date().getTime()); + ticketsRequestInterceptor.addData(newticket); + } + return true; + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return false; + } + + @Override + public boolean sendRepliesToReviews(Updates updates) { + try { + String reviewId = jdbcTemplate.queryForObject(Sql.Ticket.GET_REVIEW_ID, + new Object[] { updates.getTicketId() }, String.class); + if (reviewId != null) { + Long id = jdbcTemplate.queryForObject(Sql.Ticket.GET_ORG_ID_FROM_TICKET_ID, + new Object[] { updates.getTicketId() }, Long.class); + String appName = jdbcTemplate.queryForObject(Sql.Ticket.GET_APP_URL_FROM_TICKET_ID, + new Object[] { updates.getTicketId() }, String.class); + if (checkIfIDAndAppNameIsNotNull(id, appName)) { + RestTemplate restTemplate = new RestTemplate(); + Access exp = userService.getReviewConfig(id); + AccessResponse accessResponse = new AccessResponse(); + accessResponse = transformTOJSONString(restTemplate, exp, accessResponse); + final String uri = Constants.HTTPS_WWW_GOOGLEAPIS_COM_ANDROIDPUBLISHER_V3_APPLICATIONS + appName + + REVIEWS + reviewId + REPLY; + HttpHeaders header = new HttpHeaders(); + header.setContentType(MediaType.APPLICATION_JSON); + header.set(Constants.HEADER_STRING, Constants.TOKEN_PREFIX + accessResponse.getAccessToken()); + JSONObject request = new JSONObject(); + if (extractUpdates(updates)) { + request.put(REPLY_TEXT, updates.getUpds()); + } else { + return false; + } + HttpEntity<String> entity = new HttpEntity<>(request.toString(), header); + ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.POST, entity, String.class); + if (matchStatus(result)) { + return true; + } + } + + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return false; + } + + public boolean checkIfIDAndAppNameIsNotNull(Long id, String appName) { + return id != null && appName != null; + } + + public AccessResponse transformTOJSONString(RestTemplate restTemplate, Access exp, AccessResponse accessResponse) { + if (!ProjectUtil.isObjectNull(exp)) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + Map<String, Object> map = new HashMap<>(); + map.put(Constants.GRANT_TYPE, Constants.REFRESH_TOKEN); + map.put(Constants.CLIENT_ID, exp.getClientId()); + map.put(Constants.CLIENT_SECRET, exp.getClientSecret()); + map.put(Constants.REFRESH_TOKEN, exp.getRefreshToken()); + HttpEntity<Map<String, Object>> request = new HttpEntity<>(map, headers); + ResponseEntity<String> response = restTemplate + .postForEntity(Constants.HTTPS_ACCOUNTS_GOOGLE_COM_O_OAUTH2_TOKEN, request, String.class); + if (!StringUtils.isEmpty(response.getBody())) { + List<Object> chainrSpecJSON = JsonUtils.classpathToList(Constants.ACCESSTOKENSPEC_JSON); + Chainr chainr = Chainr.fromSpec(chainrSpecJSON); + Object transformedOutput = chainr.transform(JsonUtils.jsonToObject(response.getBody())); + Gson g = new Gson(); + accessResponse = g.fromJson(JsonUtils.toJsonString(transformedOutput), AccessResponse.class); + } + } + return accessResponse; + } + + public boolean extractUpdates(Updates updates) { + return updates.getUpds() != null && !updates.getUpds().isEmpty(); + } + + public boolean matchStatus(ResponseEntity<String> result) { + return result.getStatusCode() == HttpStatus.OK; + } + +} diff --git a/src/main/java/org/upsmf/grievance/dao/impl/UserDaoImpl.java b/src/main/java/org/upsmf/grievance/dao/impl/UserDaoImpl.java new file mode 100644 index 0000000..1f2b581 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dao/impl/UserDaoImpl.java @@ -0,0 +1,912 @@ +package org.upsmf.grievance.dao.impl; + +import static org.upsmf.grievance.util.Constants.TOKEN_PREFIX; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; +import org.apache.velocity.VelocityContext; +import org.elasticsearch.action.bulk.BulkRequest; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestClientBuilder; +import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback; +import org.elasticsearch.client.RestHighLevelClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Repository; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +import com.bazaarvoice.jolt.Chainr; +import com.bazaarvoice.jolt.JsonUtils; +import com.google.gson.Gson; +import org.upsmf.grievance.config.JwtTokenUtil; +import org.upsmf.grievance.dao.ApplicationDao; +import org.upsmf.grievance.dao.RoleDao; +import org.upsmf.grievance.dao.SuperAdminDao; +import org.upsmf.grievance.dao.TicketDao; +import org.upsmf.grievance.dao.UserDao; +import org.upsmf.grievance.dto.ChangePasswordDto; +import org.upsmf.grievance.dto.LoginDto; +import org.upsmf.grievance.dto.OrgUserRoleDto; +import org.upsmf.grievance.dto.UserDto; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.interceptor.TicketsRequestInterceptor; +import org.upsmf.grievance.model.Access; +import org.upsmf.grievance.model.AccessResponse; +import org.upsmf.grievance.model.Action; +import org.upsmf.grievance.model.CommonDataModel; +import org.upsmf.grievance.model.HelpDeskApp; +import org.upsmf.grievance.model.KeyFactory; +import org.upsmf.grievance.model.Rev; +import org.upsmf.grievance.model.Role; +import org.upsmf.grievance.model.S3Config; +import org.upsmf.grievance.model.Ticket; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.model.UserAuthentication; +import org.upsmf.grievance.model.mapper.SqlDataMapper; +import org.upsmf.grievance.model.mapper.SqlDataMapper.RolesUserMapper; +import org.upsmf.grievance.model.mapper.SqlDataMapper.UserDetailsMapper; +import org.upsmf.grievance.model.mapper.SqlDataMapper.UserRoleMapper; +import org.upsmf.grievance.model.mapper.SqlDataMapper.UserRolesActionsMapper; +import org.upsmf.grievance.service.UserService; +import org.upsmf.grievance.util.Constants; +import org.upsmf.grievance.util.DateUtil; +import org.upsmf.grievance.util.JsonKey; +import org.upsmf.grievance.util.OneWayHashing; +import org.upsmf.grievance.util.ProjectUtil; +import org.upsmf.grievance.util.S3FileManager; +import org.upsmf.grievance.util.SendMail; +import org.upsmf.grievance.util.Sql; +import org.upsmf.grievance.util.Sql.UserQueries; + +@Repository(Constants.USER_DAO) +public class UserDaoImpl implements UserDao { + + private static final String ENCOUNTERED_AN_EXCEPTION_S = "Encountered an Exception : %s"; + + private static final String EL_STIC123 = "El@stic123"; + + private static final String ELASTIC = "elastic"; + + public static final Logger LOGGER = LoggerFactory.getLogger(UserDaoImpl.class); + + @Value("${elk.data.up}") + private boolean elkDataUp; + + @Value("${elasticsearch.url}") + private String elasticsearchUrl; + + @Value("${elasticsearch.index}") + private String elasticsearchIndex; + + @Value("${elasticsearch.type}") + private String elasticsearchType; + + @Autowired + private TicketsRequestInterceptor ticketsRequestInterceptor; + + @Autowired + JdbcTemplate jdbcTemplate; + + @Autowired + RoleDao roleDao; + + @Autowired + JwtTokenUtil jwtTokenUtil; + + @Autowired + UserService userService; + + @Autowired + SuperAdminDao superAdminDao; + + @Autowired + TicketDao ticketDao; + + @Autowired + ApplicationDao applicationDao; + + public UserDaoImpl(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + @Override + public List<Action> findAllActionsByRoleID(Integer roleID) { + List<Action> actions = new ArrayList<>(); + try { + actions = jdbcTemplate.query(UserQueries.GET_USER_ACTIONS, new Object[] { roleID }, + MasterDataManager.rowMapAction); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception while fetching all the actions by Role ID %s", + e.getMessage())); + } + return actions; + } + + @Override + public User findByUsername(String username, Boolean withRoles, Boolean withActions) { + User user = null; + try { + if (withRoles && withActions) { + UserRolesActionsMapper mapper = new SqlDataMapper().new UserRolesActionsMapper(); + user = jdbcTemplate + .query(UserQueries.SELECT_USER_ROLES_ACTIONS_ON_USERNAME, new Object[] { username }, mapper) + .get(0); + user.setRoles(mapper.getRoleMap().values().stream().collect(Collectors.toList())); + user.setActions(mapper.getActionMap().values().stream().collect(Collectors.toList())); + } else if (withRoles) { + user = jdbcTemplate.query(UserQueries.SELECT_USER_ROLES_ON_USERNAME, new Object[] { username }, + new SqlDataMapper().new UserRolesMapper()).get(0); + user.setRoles(new SqlDataMapper().new UserRolesMapper().getRoleMap().values().stream() + .collect(Collectors.toList())); + } else { + user = jdbcTemplate.query(UserQueries.SELECT_USER_ON_USERNAME, new Object[] { username }, + new SqlDataMapper().new UserMapper()).get(0); + } + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception while fetching the User by Username : %s", + e.getMessage())); + } + return user; + } + + @Override + public List<User> findOne(Long id) { + List<User> data = new ArrayList<>(); + try { + data = jdbcTemplate.query(UserQueries.USER_PROFILE_FETCH, new Object[] { id }, + new SqlDataMapper().new UserDetailsMapper()); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an exception while fetching the User By ID : %s", e.getMessage())); + } + return data; + } + + @Override + public UserAuthentication findOneUserAuthentication(Long id) { + UserAuthentication user = null; + try { + user = jdbcTemplate.query(UserQueries.GET_USER_AUTH_DETAILS, new Object[] { id }, + new SqlDataMapper().new UserAuthenticationMapper()).get(0); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an exception while fetching the Users Auth Details : %s", + e.getMessage())); + } + return user; + } + + @Override + public User insertIntoUser(final User user) { + Long id = (long) 0; + try { + KeyHolder keyHolder = KeyFactory.getkeyHolder(); + jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { + String[] returnValColumn = new String[] { "id" }; + PreparedStatement statement = con.prepareStatement(UserQueries.SAVE_USER, returnValColumn); + statement.setString(1, user.getName()); + statement.setString(2, user.getUsername()); + statement.setString(3, user.getPhone()); + statement.setString(4, user.getImagePath()); + return statement; + } + }, keyHolder); + id = keyHolder.getKey().longValue(); + user.setId(id); + MasterDataManager.getUserIdAndUserNameMap().put(id, user.getName()); + } catch (InvalidDataAccessApiUsageException e) { + LOGGER.error(String.format("Encountered an Invalid Data Access Exception while creating a new User: %s", + e.getMessage())); + } catch (DataAccessException e) { + LOGGER.error(String.format("Encountered a Data Access Exception while creating a new User : %s", + e.getMessage())); + } catch (Exception e) { + LOGGER.error(String.format("Encountered a Exception while creating a new User : %s", e.getMessage())); + } + return user; + } + + @Override + public Long insertAnonymousUser(final User user) { + Long id = (long) 0; + String anonymous = "Anonymous"; + try { + KeyHolder keyHolder = KeyFactory.getkeyHolder(); + jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { + String[] returnValColumn = new String[] { "id" }; + PreparedStatement statement = con.prepareStatement(UserQueries.SAVE_ANONYMOUS_USER, + returnValColumn); + statement.setString(1, anonymous); + statement.setString(2, user.getUsername()); + statement.setString(3, ""); + statement.setString(4, ""); + statement.setBoolean(5, true); + return statement; + } + }, keyHolder); + id = keyHolder.getKey().longValue(); + } catch (Exception e) { + LOGGER.error( + String.format("Encountered a Exception while creating a Anonymous User : %s", e.getMessage())); + } + return id; + } + + @Override + public boolean customAuth(UserDto user) { + int row = 0; + VelocityContext context = new VelocityContext(); + try { + String password = ProjectUtil.getRandomStringVal(); + if (!StringUtils.isBlank(password)) { + LOGGER.info("Password : " + password); + } + String encodedPwd = OneWayHashing.encryptVal(password); + user.setPassword(encodedPwd); + row = insertIntoPassword(user.getId(), encodedPwd); + if (row > 0) { + context.put(JsonKey.MAIL_SUBJECT, "You're a Aurora-Desk User now!"); + context.put(JsonKey.MAIL_BODY, "You have been successfully added as the user to the system" + + " Please find your username and password"); + context.put(JsonKey.PSWRD, password); + context.put(JsonKey.USER_NAME, user.getUsername()); + context.put(JsonKey.FIRST_NAME, user.getName()); + SendMail.sendMail(new String[] { user.getUsername() }, "User Added, Password Generated", context, + "email_template.vm"); + } + return true; + } catch (Exception e) { + LOGGER.error(String.format("Password insertion failed for user: %s", user.getId())); + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return false; + } + + private UserAuthentication save(final UserAuthentication user) { + UserAuthentication user1 = new UserAuthentication(); + try { + KeyHolder keyHolder = KeyFactory.getkeyHolder(); + jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { + String[] returnValColumn = new String[] { "id" }; + PreparedStatement statement = con.prepareStatement(UserQueries.SAVE_USER_AUTHENTICATION, + returnValColumn); + statement.setLong(1, user.getUserId()); + statement.setString(2, user.getAuthToken()); + return statement; + } + }, keyHolder); + Long id = keyHolder.getKey().longValue(); + user1 = this.findOneUserAuthentication(id); + + } catch (Exception e) { + LOGGER.error( + String.format("Encountered an exception while saving User Authentication : %s", e.getMessage())); + } + return user1; + } + + @Override + public int getAuthId(Long userId) { + int orgId = 0; + orgId = superAdminDao.getOrganizationByUserId(userId); + if (orgId > 0) { + try { + return jdbcTemplate.queryForObject(Sql.UserQueries.GET_AUTH_TYPE_ID, new Object[] { orgId }, + Integer.class); + } catch (Exception e) { + LOGGER.error(String.format("Encountered a Exception while getting an Authentication ID: %s", + e.getMessage())); + } + } + return 0; + } + + @Override + public int insertIntoPassword(Long id, String password) { + return jdbcTemplate.update(Sql.UserQueries.INSERT_PD, new Object[] { password, id.longValue() }); + } + + @Override + public User update(final User user) { + try { + if (user.getImagePath() != null) { + updateProfilePic(user.getId(), user.getImagePath()); + } + } catch (Exception e) { + LOGGER.error(String.format("error while updating profile pic %s", e.getMessage())); + } + try { + jdbcTemplate.update(UserQueries.UPDATE_USER, new Object[] { user.getName(), user.getUsername(), + user.getPhone(), user.getIsActive(), user.getImagePath(), user.getId() }); + MasterDataManager.getUserIdAndUserName(); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an error while updating User Object : %s", e.getMessage())); + } + return user; + } + + private String updateProfilePic(Long id, String imagePath) { + if (imagePath != null) { + Long organization = MasterDataManager.getUserOrgMap().get(id); + String profilePicPath = null; + profilePicPath = S3FileManager.filePath(imagePath, "userprofile", id, organization); + jdbcTemplate.update(Sql.INSERT_PROFILE_PICTURE, new Object[] { profilePicPath, id }); + return profilePicPath; + } + return null; + } + + @Override + public UserRoleMapper findAllRolesByUser(Long userId) { + UserRoleMapper mapper = new SqlDataMapper().new UserRoleMapper(); + try { + jdbcTemplate.query(UserQueries.GET_ROLES_FOR_USER, new Object[] { userId }, mapper); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an exception while fetching the Roles for a User : %s", + e.getMessage())); + } + + return mapper; + } + + @Override + public Boolean mapUserToRole(long userId, List<Role> roleList) { + try { + jdbcTemplate.update(UserQueries.REMOVE_USER_ROLE_MAP, new Object[] { userId }); + } catch (Exception ex) { + LOGGER.error(String.format("Encountered an exception while removing the User Role mapping : %s", + ex.getMessage())); + } + + try { + jdbcTemplate.batchUpdate(UserQueries.MAP_USER_TO_ROLE, new BatchPreparedStatementSetter() { + @Override + public void setValues(java.sql.PreparedStatement statement, int i) throws SQLException { + Role role = roleList.get(i); + statement.setLong(1, userId); + statement.setLong(2, role.getId()); + } + + @Override + public int getBatchSize() { + return roleList.size(); + } + }); + MasterDataManager.getUserRoleMap().clear(); + MasterDataManager.getRoleUserMap().clear(); + MasterDataManager.getAllUserRoles(); + return true; + + } catch (Exception ex) { + LOGGER.error("Exception Occured while adding Roles to User : %s", ex); + return false; + } + + } + + @Override + public User updateUserImage(User profile) { + try { + KeyHolder keyHolder = KeyFactory.getkeyHolder(); + jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { + String[] returnValColumn = new String[] { "id" }; + PreparedStatement statement = con.prepareStatement(UserQueries.UPDATE_USER_PROFILE_PROFILE_IMAGE, + returnValColumn); + statement.setString(1, profile.getImagePath()); + statement.setLong(2, profile.getId()); + return statement; + } + }, keyHolder); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an error while updating User Profile image %s", e.getMessage())); + } + return profile; + } + + @Override + public Long checkUserNameExists(String username) { + Long userId; + try { + userId = jdbcTemplate.queryForObject("SELECT id FROM user WHERE username = ?", new Object[] { username }, + Long.class); + } catch (Exception e) { + return 0l; + } + return userId; + } + + @Override + public UserDetailsMapper findListOfUsers(List<Long> userIdList) { + UserDetailsMapper mapper = new SqlDataMapper().new UserDetailsMapper(); + String query = buildMyQuery(userIdList); + LOGGER.info(String.format("Query to execute for fetching the User Profile : %s", query)); + try { + jdbcTemplate.query(query, new Object[] {}, mapper); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an exception while fetching the User By ID : %s", e.getMessage())); + } + return mapper; + } + + private String buildMyQuery(List<Long> userIdList) { + StringBuilder builder = new StringBuilder(UserQueries.USER_PROFILE_FETCH); + if (!userIdList.isEmpty()) { + builder.append("("); + for (int i = 0; i < userIdList.size(); i++) { + if (i == 0 && i == userIdList.size() - 1) { + builder.append(userIdList.get(i)); + } else if (i == userIdList.size() - 1) { + builder.append(userIdList.get(i)); + } else { + builder.append(userIdList.get(i) + ","); + } + } + builder.append(")"); + } + return builder.toString(); + } + + @Override + public List<User> findAll(Long orgId) { + List<User> user = null; + try { + if (orgId > 0) { + user = jdbcTemplate.query(Sql.Common.GET_ALL_USERS_BY_ORG, new Object[] { orgId }, + new SqlDataMapper().new UserDetailsMapper()); + } + setImageUrlFromImagePath(user); + MasterDataManager.getAllUserRoles(); + for (int i = 0; i < user.size(); i++) { + List<Long> roles = MasterDataManager.getUserRoleListMap().get(user.get(i).getId()); + List<Role> roleList = new ArrayList<>(); + for (int j = 0; j < roles.size(); j++) { + roleList.add(MasterDataManager.getRoleMap().get(roles.get(j))); + } + user.get(i).setRoles(roleList); + } + } catch (Exception e) { + LOGGER.error( + String.format("Encountered an exception while fetching the User Profile : %s", e.getMessage())); + } + return user; + } + + private void setImageUrlFromImagePath(List<User> user) { + for (int i = 0; i < user.size(); i++) { + if (user.get(i).getImagePath() != null) { + S3Config s3values = superAdminDao.getS3Access(); + String url = null; + url = S3FileManager.getPreSignedURL(s3values, user.get(i).getImagePath()); + user.get(i).setImagePath(url); + } + } + } + + @Override + public Long getNumberOfUsers(Long role, Boolean active) { + Long numberOfUsers = 0L; + try { + if (role != null) { + numberOfUsers = jdbcTemplate.queryForObject(UserQueries.GET_USER_COUNT_FOR_ROLE, new Object[] { role }, + Long.class); + } else if (active != null) { + numberOfUsers = jdbcTemplate.queryForObject(UserQueries.GET_USER_COUNT_ON_ACTIVE_STATUS, + new Object[] { active }, Long.class); + } else { + numberOfUsers = jdbcTemplate.queryForObject(UserQueries.GET_USER_COUNT, Long.class); + } + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception while fetching count of Users : %s", e.getMessage())); + } + return numberOfUsers; + } + + @Override + public Long getNumberOfRoles() { + Long numberOfRoles = 0L; + try { + numberOfRoles = jdbcTemplate.queryForObject(UserQueries.GET_ROLE_COUNT, Long.class); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception while fetching count of Roles : %s", e.getMessage())); + } + return numberOfRoles; + } + + @Override + public Boolean invalidateToken(String authToken) { + try { + jdbcTemplate.update(UserQueries.INVALIDATE_TOKEN, new Object[] { authToken }); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an error while invalidating Auth Token : %s", e.getMessage())); + return false; + } + return true; + } + + @Override + public Boolean findUserByToken(String authToken) { + Long countOfUsers = 0L; + authToken = authToken.replace(TOKEN_PREFIX, ""); + try { + countOfUsers = jdbcTemplate.queryForObject(UserQueries.SELECT_USER_BY_TOKEN, new Object[] { authToken }, + Long.class); + } catch (Exception e) { + LOGGER.error( + String.format("Encountered an Exception while fetching User by auth token: %s", e.getMessage())); + } + return (countOfUsers > 0); + } + + @Override + public Boolean checkUserTokenExists(Long userId, String deviceToken) { + Long available = 0L; + try { + available = jdbcTemplate.queryForObject(UserQueries.CHECK_USER_DEVICE_TOKEN, + new Object[] { userId, deviceToken }, Long.class); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception while fetching User Device by Device token: %s", + e.getMessage())); + } + return (available > 0); + } + + @Override + public Long fetchAuthTokenReference(String authToken) { + authToken = authToken.split(" ")[1]; + Long authTokenRef = 0L; + try { + authTokenRef = jdbcTemplate.queryForObject(UserQueries.FETCH_AUTH_TOKEN_REF, new Object[] { authToken }, + Long.class); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an Exception while fetching User Device by Device token: %s", + e.getMessage())); + } + return authTokenRef; + } + + @Override + public boolean changePassword(ChangePasswordDto changePasswordDto) { + boolean resposne = false; + if (isPasswordMatch(changePasswordDto.getUserId(), changePasswordDto.getOldPass())) { + int count = jdbcTemplate.update(Sql.Common.UPDATE_PSWRD, + new Object[] { OneWayHashing.encryptVal(changePasswordDto.getNewPass()), + DateUtil.getFormattedDateInUTC(new Date()), changePasswordDto.getUserId(), + OneWayHashing.encryptVal(changePasswordDto.getOldPass()) }); + if (count > 0) { + resposne = true; + } + } + return resposne; + } + + @Override + public boolean isPasswordMatch(long userId, String password) { + boolean response = false; + String storedPassword = ""; //$NON-NLS-1$ + try { + storedPassword = jdbcTemplate.queryForObject(Sql.Common.CHECK_OLD_PSWRD, new Object[] { userId }, + String.class); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + if (storedPassword.equals(OneWayHashing.encryptVal(password))) { + response = true; + } + return response; + } + + @Override + public long forgotPassword(UserDto userDto) { + long userId = 0; + try { + userId = jdbcTemplate.queryForObject(Sql.Common.CHECK_USER_BY_USERNAME, + new Object[] { userDto.getUsername() }, Long.class); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + + return userId; + } + + @Override + public boolean saveForgotPassword(long userId, String password) { + boolean response = false; + int count = 0; + try { + String encryptVal = OneWayHashing.encryptVal(password); + count = jdbcTemplate.update(Sql.Common.SAVE_FORGOT_PSWRD, + new Object[] { encryptVal, DateUtil.getFormattedDateInUTC(new Date()), userId }); + LOGGER.info("Password : {}", encryptVal); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + if (count > 0) { + response = true; + } + return response; + } + + @Override + public User getUserDetailsByEmail(String username) { + User user = null; + try { + user = jdbcTemplate + .query(Sql.Common.GET_USER_DETAIL_BY_EMAIL, new Object[] { username }, MasterDataManager.rowMapUser) + .get(0); + user.setOrgId(jdbcTemplate.queryForObject(Sql.Common.GET_ORG_ID_BY_USER_ID, new Object[] { user.getId() }, + Long.class)); + } catch (Exception e) { + LOGGER.error(String.format("getUserDetailsByEmail method : %s", e.getMessage())); //$NON-NLS-1$ + } + return user; + } + + @Override + public LoginDto login(UserDto userDto) { + final String token = jwtTokenUtil.generateToken(userDto); + UserAuthentication userAuthentication = new UserAuthentication(); + userAuthentication.setUserId(userDto.getId()); + userAuthentication.setAuthToken(token); + save(userAuthentication); + LoginDto loginDto = new LoginDto(); + loginDto.setAuthToken(token); + loginDto.setUserId(userDto.getId()); + List<Role> roles = userService.findAllRolesByUser(userDto.getId()); + loginDto.setRoles(roles); + return loginDto; + + } + + @Override + public CommonDataModel getAuthDomain(UserDto userDto) { + CommonDataModel authDomain = null; + try { + authDomain = jdbcTemplate + .query(createSqlForAuth(userDto.getOrgId()), MasterDataManager.rowMapCommonDataModel).get(0); + } catch (DataAccessException e) { + LOGGER.error(String.format("Encountered an Exception while getting Auth Domain : %s", e.getMessage())); + } + return authDomain; + } + + private final String createSqlForAuth(long orgId) { + StringBuilder queryBuilder = new StringBuilder( + UserQueries.QUERY1 + UserQueries.QUERY2 + orgId + UserQueries.QUERY3); + return queryBuilder.toString(); + } + + @Override + public boolean getFirstAdminsOfOrg(Long id) { + try { + Long value = null; + value = jdbcTemplate.queryForObject(Sql.UserQueries.CHECK_FIRST_ADMIN, Long.class, new Object[] { id }); + return (value != null); + } catch (Exception e) { + LOGGER.error(String.format("Error while check first admin %s", e.getMessage())); //$NON-NLS-1$ + return false; + } + } + + @Override + public Boolean onBoardingCheck(Long orgId, Long userId) { + try { + Long check = jdbcTemplate.queryForObject(Sql.UserQueries.GET_MASTER_DATA_CHECK, new Object[] { orgId }, + Long.class); + if (check > 0) { + User user = getUserProfile(userId); + return (user.getUsername() != null && user.getName() != null); + } + } catch (Exception e) { + LOGGER.error(String.format("Error while check master Data %s", e.getMessage())); //$NON-NLS-1$ + } + return false; + } + + public User getUserProfile(Long userId) { + return jdbcTemplate + .query(Sql.UserQueries.USER_PROFILE_FETCH, new Object[] { userId }, MasterDataManager.rowMapUser) + .get(0); + } + + @Override + public List<OrgUserRoleDto> getAllOrgUsers() { + List<OrgUserRoleDto> orgUserList = null; + try { + orgUserList = jdbcTemplate.query(Sql.UserQueries.GET_USER_ORG_MAP, new SqlDataMapper().new UserOrgMapper()); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an exception while fetching all roles %s", e.getMessage())); + } + return orgUserList; + } + + @Override + public List<OrgUserRoleDto> getAllUserRoles() { + RolesUserMapper mapper = new SqlDataMapper().new RolesUserMapper(); + List<OrgUserRoleDto> userRoleList = new ArrayList<>(); + try { + jdbcTemplate.query(Sql.UserQueries.GET_USER_ROLE_MAP, mapper); + } catch (Exception e) { + LOGGER.error(String.format("Encountered an exception while fetching all roles %s", e.getMessage())); + } + + for (Map.Entry<Long, OrgUserRoleDto> entry : mapper.getUserMap().entrySet()) { + userRoleList.add(entry.getValue()); + } + return userRoleList; + } + + @Override + public List<HelpDeskApp> getAppIdAndHelpDeskId() { + List<HelpDeskApp> helpdeskApp = null; + try { + helpdeskApp = jdbcTemplate.query(Sql.UserQueries.GET_APP_ID_HELPDESK_ID, + new SqlDataMapper().new HelpDeskAppMapper()); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return helpdeskApp; + } + + @Override + public List<User> getUserIdAndUserName() { + try { + return jdbcTemplate.query(Sql.UserQueries.GET_USER_ID_AND_USER_NAME, new Object[] {}, + MasterDataManager.rowMapUser); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + return new ArrayList<>(); + } + } + + @Override + public Access getReviewConfig(Long orgId) { + Access exp = null; + try { + exp = jdbcTemplate.query(Sql.GET_CONFIG, new Object[] { orgId }, MasterDataManager.rowMapAccess).get(0); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return exp; + } + + @Override + public void getReviews() throws IOException { + try { + for (int i = 0; i < superAdminDao.getAllOrganization().size(); i++) { + Long id = superAdminDao.getAllOrganization().get(i).getId(); + Access exp = getReviewConfig(id); + AccessResponse accessResponse = new AccessResponse(); + if (!ProjectUtil.isObjectNull(exp)) { + HttpHeaders headers = new HttpHeaders(); + RestTemplate restTemplate = new RestTemplate(); + headers.setContentType(MediaType.APPLICATION_JSON); + Map<String, Object> map = new HashMap<>(); + map.put(Constants.GRANT_TYPE, Constants.REFRESH_TOKEN); + map.put(Constants.CLIENT_ID, exp.getClientId()); + map.put(Constants.CLIENT_SECRET, exp.getClientSecret()); + map.put(Constants.REFRESH_TOKEN, exp.getRefreshToken()); + HttpEntity<Map<String, Object>> request = new HttpEntity<>(map, headers); + ResponseEntity<String> response = restTemplate + .postForEntity(Constants.HTTPS_ACCOUNTS_GOOGLE_COM_O_OAUTH2_TOKEN, request, String.class); + if (!StringUtils.isBlank(response.getBody())) { + List<Object> chainrSpecJSON = JsonUtils.classpathToList(Constants.ACCESSTOKENSPEC_JSON); + Chainr chainr = Chainr.fromSpec(chainrSpecJSON); + Object transformedOutput = chainr.transform(JsonUtils.jsonToObject(response.getBody())); + Gson g = new Gson(); + accessResponse = g.fromJson(JsonUtils.toJsonString(transformedOutput), AccessResponse.class); + } + if (!StringUtils.isBlank(accessResponse.getAccessToken())) { + List<String> distinctAppNames = applicationDao.getDistinctAppNames(id); + for (int j = 0; j < distinctAppNames.size(); j++) { + Rev reviews = new Rev(); + String appName = distinctAppNames.get(j); + integrateReviews(accessResponse, restTemplate, reviews, appName); + } + } + } + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + } + + private void integrateReviews(AccessResponse accessResponse, RestTemplate restTemplate, Rev reviews, String appName) + throws ParseException, IOException { + try { + final String uri = Constants.HTTPS_WWW_GOOGLEAPIS_COM_ANDROIDPUBLISHER_V3_APPLICATIONS + appName + + Constants.REVIEWS2; + HttpHeaders header = new HttpHeaders(); + header.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); + header.set(Constants.HEADER_STRING, Constants.TOKEN_PREFIX + accessResponse.getAccessToken()); + HttpEntity<String> entity = new HttpEntity<>(Constants.PARAMETERS, header); + ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class); + if (!StringUtils.isBlank(result.getBody())) { + Gson g = new Gson(); + reviews = g.fromJson(result.getBody(), Rev.class); + } + if (!reviews.getReviews().isEmpty()) { + Ticket t; + List<Ticket> mapper = new ArrayList<>(); + RestHighLevelClient client = connectToElasticSearch(); + for (int k = 0; k < reviews.getReviews().size(); k++) { + List<Object> chainrSpecJSON = JsonUtils.classpathToList(Constants.REVIEWSPEC_JSON); + Chainr chainr = Chainr.fromSpec(chainrSpecJSON); + Gson gson = new Gson(); + String inputJSON = gson.toJson(reviews.getReviews().get(k)); + Object transformedOutput = chainr.transform(JsonUtils.jsonToObject(inputJSON)); + Gson g = new Gson(); + t = g.fromJson(JsonUtils.toJsonString(transformedOutput), Ticket.class); + t.setAppName(appName); + mapper.add(t); + } + BulkRequest req = new BulkRequest(); + for (int l = 0; l < mapper.size(); l++) { + Ticket tkt = ticketDao.addTicket(mapper.get(l)); + if (tkt != null) { + Map<String, Object> jsonMap = ticketsRequestInterceptor.createJsonMap(tkt); + req.add(new IndexRequest(elasticsearchIndex, elasticsearchType, tkt.getId().toString()) + .source(jsonMap)); + } + } + client.bulk(req); + client.close(); + } + } catch (RestClientException e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + } + + private RestHighLevelClient connectToElasticSearch() { + final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(ELASTIC, EL_STIC123)); + + HttpClientConfigCallback httpClientConfigCallback = new RestClientBuilder.HttpClientConfigCallback() { + @Override + public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { + return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); + } + }; + return new RestHighLevelClient(RestClient.builder(new HttpHost(elasticsearchUrl)) + .setHttpClientConfigCallback(httpClientConfigCallback)); + } + +} diff --git a/src/main/java/org/upsmf/grievance/dto/ChangePasswordDto.java b/src/main/java/org/upsmf/grievance/dto/ChangePasswordDto.java new file mode 100644 index 0000000..0a87e20 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dto/ChangePasswordDto.java @@ -0,0 +1,54 @@ +/** + * + */ +package org.upsmf.grievance.dto; + +/** + * @author Manzarul + * + */ +public class ChangePasswordDto { + private Long userId; + private String oldPass; + private String newPass; + private String confirmNewPass; + + public String getOldPass() { + return oldPass; + } + + public void setOldPass(String oldPass) { + this.oldPass = oldPass; + } + + public String getNewPass() { + return newPass; + } + + public void setNewPass(String newPass) { + this.newPass = newPass; + } + + public String getConfirmNewPass() { + return confirmNewPass; + } + + public void setConfirmNewPass(String confirmNewPass) { + this.confirmNewPass = confirmNewPass; + } + + @Override + public String toString() { + return "ChangePasswordDto [oldPass=" + oldPass + ", newPass=" + newPass + ", confirmNewPass=" + confirmNewPass + + "]"; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + +} diff --git a/src/main/java/org/upsmf/grievance/dto/HelpdeskDto.java b/src/main/java/org/upsmf/grievance/dto/HelpdeskDto.java new file mode 100644 index 0000000..f095324 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dto/HelpdeskDto.java @@ -0,0 +1,44 @@ +package org.upsmf.grievance.dto; + +import java.util.List; + +import org.upsmf.grievance.model.App; +import org.upsmf.grievance.model.User; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class HelpdeskDto { + + private Long id; + private String name; + private Long orgId; + private Long createdBy; + private String createdDate; + private Long updatedBy; + private String updatedDate; + private Boolean isActive; + private List<HelpdeskTypeDto> types; + private List<App> apps; + private List<User> admins; + private List<User> users; + private String description; + private String color; + private List<Long> adminIds; + private List<Long> appIds; + private List<Long> sourceId; + private List<Long> userIds; + private Boolean allowAllUsers; + private Boolean direct; + private Boolean playstore; + private Boolean appstore; + private Boolean auroraSdk; +} diff --git a/src/main/java/org/upsmf/grievance/dto/HelpdeskTypeDto.java b/src/main/java/org/upsmf/grievance/dto/HelpdeskTypeDto.java new file mode 100644 index 0000000..363c71f --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dto/HelpdeskTypeDto.java @@ -0,0 +1,25 @@ +package org.upsmf.grievance.dto; + +import java.util.List; + +import org.upsmf.grievance.model.ChecklistItem; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class HelpdeskTypeDto { + + private Long id; + private Long helpdeskId; + private String name; + private List<HelpdeskWorkflowDto> workflowStages; + private List<ChecklistItem> checklistItems; +} diff --git a/src/main/java/org/upsmf/grievance/dto/HelpdeskWorkflowDto.java b/src/main/java/org/upsmf/grievance/dto/HelpdeskWorkflowDto.java new file mode 100644 index 0000000..3ffb403 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dto/HelpdeskWorkflowDto.java @@ -0,0 +1,19 @@ +package org.upsmf.grievance.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class HelpdeskWorkflowDto { + + private Long id; + private Long typeId; + private String name; +} diff --git a/src/main/java/org/upsmf/grievance/dto/LoginDto.java b/src/main/java/org/upsmf/grievance/dto/LoginDto.java new file mode 100644 index 0000000..cf3057f --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dto/LoginDto.java @@ -0,0 +1,48 @@ +package org.upsmf.grievance.dto; + +import java.util.List; + +import org.upsmf.grievance.model.Role; + +public class LoginDto { + + private String authToken; + + private Long userId; + + private List<Role> roles; + + private String imageUrl; + + public String getAuthToken() { + return authToken; + } + + public void setAuthToken(String authToken) { + this.authToken = authToken; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public List<Role> getRoles() { + return roles; + } + + public void setRoles(List<Role> roles) { + this.roles = roles; + } + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } +} diff --git a/src/main/java/org/upsmf/grievance/dto/OrgUserRoleDto.java b/src/main/java/org/upsmf/grievance/dto/OrgUserRoleDto.java new file mode 100644 index 0000000..d7b5f6c --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dto/OrgUserRoleDto.java @@ -0,0 +1,52 @@ +package org.upsmf.grievance.dto; + +import java.util.List; + +public class OrgUserRoleDto { + + private Long id; + private Long userId; + private Long orgId; + private Long roleId; + private List<Long> roleIds; + + public List<Long> getRoleIds() { + return roleIds; + } + + public void setRoleIds(List<Long> roleIds) { + this.roleIds = roleIds; + } + + public Long getRoleId() { + return roleId; + } + + public void setRoleId(Long roleId) { + this.roleId = roleId; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public Long getOrgId() { + return orgId; + } + + public void setOrgId(Long orgId) { + this.orgId = orgId; + } +} diff --git a/src/main/java/org/upsmf/grievance/dto/TicketTagDto.java b/src/main/java/org/upsmf/grievance/dto/TicketTagDto.java new file mode 100644 index 0000000..554c859 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dto/TicketTagDto.java @@ -0,0 +1,74 @@ +package org.upsmf.grievance.dto; + +import java.util.ArrayList; +import java.util.List; + +import org.upsmf.grievance.model.Tags; + +public class TicketTagDto { + + private Long id; + private String url; + private int typeId; + private String description; + private boolean isDeleted = false; + private Long orgId; + private List<Tags> tags = new ArrayList<>(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public int getTypeId() { + return typeId; + } + + public void setTypeId(int typeId) { + this.typeId = typeId; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public boolean isDeleted() { + return isDeleted; + } + + public void setDeleted(boolean isDeleted) { + this.isDeleted = isDeleted; + } + + public Long getOrgId() { + return orgId; + } + + public void setOrgId(Long orgId) { + this.orgId = orgId; + } + + public List<Tags> getTags() { + return tags; + } + + public void setTags(List<Tags> tags) { + this.tags = tags; + } + +} diff --git a/src/main/java/org/upsmf/grievance/dto/TicketTypeDto.java b/src/main/java/org/upsmf/grievance/dto/TicketTypeDto.java new file mode 100644 index 0000000..eb71228 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dto/TicketTypeDto.java @@ -0,0 +1,35 @@ +package org.upsmf.grievance.dto; + +import java.util.List; + +import org.upsmf.grievance.model.ChecklistItem; +import org.upsmf.grievance.model.Ticket; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class TicketTypeDto { + + private Long id; + private Long helpdeskId; + private String name; + private Long orgId; + private Long typeId; + private List<TicketWorkflowDto> workflowStages; + private List<ChecklistItem> checklistItems; + + public TicketTypeDto(Ticket ticket) { + this.id = ticket.getId(); + this.orgId = ticket.getOrgId(); + this.helpdeskId = ticket.getHelpdeskId(); + this.typeId = ticket.getType(); + } +} diff --git a/src/main/java/org/upsmf/grievance/dto/TicketWorkflowDto.java b/src/main/java/org/upsmf/grievance/dto/TicketWorkflowDto.java new file mode 100644 index 0000000..e82d6a7 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dto/TicketWorkflowDto.java @@ -0,0 +1,22 @@ +package org.upsmf.grievance.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class TicketWorkflowDto { + + private Long id; + private Long workFlowId; + private Long typeId; + private String name; + private String time; + private Boolean status; +} diff --git a/src/main/java/org/upsmf/grievance/dto/UserDto.java b/src/main/java/org/upsmf/grievance/dto/UserDto.java new file mode 100644 index 0000000..8f53220 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dto/UserDto.java @@ -0,0 +1,144 @@ +package org.upsmf.grievance.dto; + +import java.util.List; +import java.util.Set; + +import org.upsmf.grievance.model.Action; +import org.upsmf.grievance.model.Role; + +/** + * Data Transfer Object which carries the User Information to the Data Access + * Layers + * + * @author Juhi Agarwal + * + */ +public class UserDto { + + private long id; + + private String name; + + private String username; + + private String password; + + private Long orgId; + + private List<Role> roles; + + private Set<Action> actions; + + private String statusMsg; + + private String googleEmail; + private String googleClientId; + private String portal; + private String authType; + private String googleIdToken; + + public Long getOrgId() { + return orgId; + } + + public void setOrgId(Long orgId) { + this.orgId = orgId; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public List<Role> getRoles() { + return roles; + } + + public void setRoles(List<Role> roles) { + this.roles = roles; + } + + public Set<Action> getActions() { + return actions; + } + + public void setActions(Set<Action> actions) { + this.actions = actions; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getStatusMsg() { + return statusMsg; + } + + public void setStatusMsg(String statusMsg) { + this.statusMsg = statusMsg; + } + + public String getGoogleEmail() { + return googleEmail; + } + + public void setGoogleEmail(String googleEmail) { + this.googleEmail = googleEmail; + } + + public String getGoogleClientId() { + return googleClientId; + } + + public void setGoogleClientId(String googleClientId) { + this.googleClientId = googleClientId; + } + + public String getPortal() { + return portal; + } + + public void setPortal(String portal) { + this.portal = portal; + } + + public String getAuthType() { + return authType; + } + + public void setAuthType(String authType) { + this.authType = authType; + } + + public String getGoogleIdToken() { + return googleIdToken; + } + + public void setGoogleIdToken(String googleIdToken) { + this.googleIdToken = googleIdToken; + } + +} diff --git a/src/main/java/org/upsmf/grievance/dto/UserProfileDto.java b/src/main/java/org/upsmf/grievance/dto/UserProfileDto.java new file mode 100644 index 0000000..f404fcf --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dto/UserProfileDto.java @@ -0,0 +1,49 @@ +package org.upsmf.grievance.dto; + +import java.util.Date; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +/** + * This Data Transfer Object will carry the information related to the User + * Profile to update the User Profile Information in the API + * + * @author Darshan Nagesh + * + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class UserProfileDto { + + private Long id; + private Long userId; + private String firstName; + private String lastName; + private int age; + private String emailId; + private String phoneNumber; + private String dob; + private String gender; + private String avatarUrl; + private Date startDate; + private Date endDate; + private Long salary; + private String address; + private Boolean isActive; + private Boolean isDeleted; + private Date registrationDate; + private Date createdDate; + private Long createdBy; + private Date updatedDate; + private Long updatedBy; + private String employmentType; +} diff --git a/src/main/java/org/upsmf/grievance/dto/UserRoleDto.java b/src/main/java/org/upsmf/grievance/dto/UserRoleDto.java new file mode 100644 index 0000000..e521328 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/dto/UserRoleDto.java @@ -0,0 +1,34 @@ +package org.upsmf.grievance.dto; + +import java.util.List; + +import org.upsmf.grievance.model.Role; + +/** + * Data Transfer Object which carries the User ID and the Roles associated. + * + * @author Darshan Nagesh + * + */ +public class UserRoleDto { + + private Long userId; + private List<Role> roles; + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public List<Role> getRoles() { + return roles; + } + + public void setRoles(List<Role> roles) { + this.roles = roles; + } + +} diff --git a/src/main/java/org/upsmf/grievance/exceptions/RbacException.java b/src/main/java/org/upsmf/grievance/exceptions/RbacException.java new file mode 100644 index 0000000..b93b4df --- /dev/null +++ b/src/main/java/org/upsmf/grievance/exceptions/RbacException.java @@ -0,0 +1,188 @@ +package org.upsmf.grievance.exceptions; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +@SuppressWarnings("all") +public class RbacException extends Exception { + + private static final long serialVersionUID = 1L; + /** + * The primary message for the exception + */ + private String message; + /** + * designated error code of the error + */ + private String errorCode; + /** + * Server timestamp when error occured + */ + private long timeStamp; + /** + * Additional parameters + */ + private Map<String, Object> params; + /** + * root Exception object + */ + private Exception ex; + /** + * root throwable object + */ + private Throwable t; + /** + * variable determining the error been logged to file or not + */ + private boolean logged; + + private String originalStackTrace; + + public RbacException(Exception e) { + super(e); + initializeException(e.getMessage()); + processOriginalStackTrace(e.getStackTrace()); + } + + public RbacException(Throwable t) { + super(t); + initializeException(t.getMessage()); + processOriginalStackTrace(t.getStackTrace()); + } + + public RbacException(String msg) { + super(msg); + initializeException(msg); + } + + public RbacException(String msg, Throwable t) { + super(msg, t); + initializeException(msg); + processOriginalStackTrace(t.getStackTrace()); + } + + public RbacException withParam(String name, Object value) { + if (params == null) { + params = new HashMap<>(); + } + params.put(name, value); + return this; + } + + public RbacException withErrorCode(String errorCode) { + this.errorCode = errorCode; + return this; + } + + private void initializeException(String msg) { + this.timeStamp = System.currentTimeMillis(); + this.message = msg; + } + + public String prepareFullErrorDescription() { + StringBuilder stackBuilder = new StringBuilder(); + stackBuilder.append("Exception Message : ").append(this.message).append(" \n"); + stackBuilder.append("Exception Time : ").append(new Date(this.timeStamp)).append(" \n"); + stackBuilder.append("Error code : ").append(this.errorCode).append(" \n "); + if (this.params != null && !this.params.isEmpty()) { + stackBuilder.append(" Parameters : "); + for (Entry<String, Object> entry : params.entrySet()) { + stackBuilder.append("\n\t ").append(entry.getKey()).append(" : ").append(entry.getValue()); + } + } + if (originalStackTrace != null) { + stackBuilder.append("\n stacktrace : ").append(originalStackTrace); + return stackBuilder.toString(); + } + StackTraceElement[] stack; + if (this.ex != null) { + stack = ex.getStackTrace(); + } else if (this.t != null) { + stack = t.getStackTrace(); + } else { + stack = super.getStackTrace(); + } + if (stack == null) { + return stackBuilder.toString(); + } + stackBuilder.append("\n stacktrace : "); + for (StackTraceElement s : stack) { + stackBuilder.append(" \n ").append(s); + } + return stackBuilder.toString(); + } + + private void processOriginalStackTrace(StackTraceElement[] stack) { + if (stack == null || stack.length == 0) { + return; + } + StringBuilder stackBuilder = new StringBuilder(); + for (StackTraceElement trace : stack) { + stackBuilder.append(trace).append("\n "); + } + originalStackTrace = stackBuilder.toString(); + } + + public boolean isLogged() { + return logged; + } + + public void setLogged(boolean logged) { + this.logged = logged; + } + + public RbacException logToFile(String prependingMessage) { + if (!logged) { + if (prependingMessage != null) { + + } + + logged = true; + } + return this; + } + + @Override + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getErrorCode() { + return errorCode; + } + + public void setErrorCode(String errorCode) { + this.errorCode = errorCode; + } + + public long getTimeStamp() { + return timeStamp; + } + + public Map<String, Object> getParams() { + return params; + } + + public void addParamsToMessage() { + if (params == null) { + return; + } + StringBuilder message = new StringBuilder("{ "); + int i = params.size(); + for (Entry<String, Object> entry : params.entrySet()) { + message.append(entry.getKey()).append(" : ").append(entry.getValue()); + i--; + if (i > 0) { + message.append(", "); + } + } + message.append(" } , ").append(getMessage()); + this.message = message.toString(); + } +} diff --git a/src/main/java/org/upsmf/grievance/exceptions/RequestDataMissingException.java b/src/main/java/org/upsmf/grievance/exceptions/RequestDataMissingException.java new file mode 100644 index 0000000..0aae454 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/exceptions/RequestDataMissingException.java @@ -0,0 +1,34 @@ +/** + * + */ +package org.upsmf.grievance.exceptions; + +/** + * @author Juhi Agarwal This exception will capture missing data and will create + * message according to missing data field + */ +public class RequestDataMissingException extends RuntimeException { + /** + * serialVersionUID + */ + private static final long serialVersionUID = 1L; + private final String message; + + /** + * @param code + * the code to set + */ + @Override + public String getMessage() { + return message; + } + + /** + * + * @param message + */ + public RequestDataMissingException(String message) { + this.message = message; + } + +} diff --git a/src/main/java/org/upsmf/grievance/exceptions/package-info.java b/src/main/java/org/upsmf/grievance/exceptions/package-info.java new file mode 100644 index 0000000..3b9f2dc --- /dev/null +++ b/src/main/java/org/upsmf/grievance/exceptions/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author Juhi Agarwal + * + */ +package org.upsmf.grievance.exceptions; \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/executor/MasterDataManager.java b/src/main/java/org/upsmf/grievance/executor/MasterDataManager.java new file mode 100644 index 0000000..381faed --- /dev/null +++ b/src/main/java/org/upsmf/grievance/executor/MasterDataManager.java @@ -0,0 +1,513 @@ +package org.upsmf.grievance.executor; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.stereotype.Component; + +import org.upsmf.grievance.dto.HelpdeskDto; +import org.upsmf.grievance.dto.OrgUserRoleDto; +import org.upsmf.grievance.model.Access; +import org.upsmf.grievance.model.Action; +import org.upsmf.grievance.model.ActivityLog; +import org.upsmf.grievance.model.App; +import org.upsmf.grievance.model.CommonDataModel; +import org.upsmf.grievance.model.HelpDeskApp; +import org.upsmf.grievance.model.Helpdesk; +import org.upsmf.grievance.model.Organization; +import org.upsmf.grievance.model.Role; +import org.upsmf.grievance.model.S3Config; +import org.upsmf.grievance.model.ServiceRequest; +import org.upsmf.grievance.model.Tags; +import org.upsmf.grievance.model.Ticket; +import org.upsmf.grievance.model.TicketTags; +import org.upsmf.grievance.model.Updates; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.service.ApplicationService; +import org.upsmf.grievance.service.HelpdeskService; +import org.upsmf.grievance.service.RoleActionService; +import org.upsmf.grievance.service.SuperAdminService; +import org.upsmf.grievance.service.UserService; + +@Component +public class MasterDataManager implements ApplicationRunner { + + public static final Logger LOGGER = LoggerFactory.getLogger(MasterDataManager.class); + + + protected static ConcurrentMap<Long, Role> roleMap = new ConcurrentHashMap<>(); + protected static ConcurrentMap<Long, List<Role>> orgRoleMap = new ConcurrentHashMap<>(); + + + protected static ConcurrentMap<Long, List<Long>> orgUserMap = new ConcurrentHashMap<>(); + protected static ConcurrentMap<Long, Long> userOrgMap = new ConcurrentHashMap<>(); + + + protected static ConcurrentMap<Long, Long> userRoleMap = new ConcurrentHashMap<>(); + protected static ConcurrentMap<Long, List<Long>> userRoleListMap = new ConcurrentHashMap<>(); + protected static ConcurrentMap<Long, Long> roleUserMap = new ConcurrentHashMap<>(); + protected static ConcurrentMap<Long, List<String>> roleActionsListMap = new ConcurrentHashMap<>(); + + protected static ConcurrentMap<Long, Long> appIdHelpdeskIdMapping = new ConcurrentHashMap<>(); + protected static ConcurrentMap<String, App> appNameAppObjectMapping = new ConcurrentHashMap<>(); + protected static ConcurrentMap<Long, App> appIdAppObjectMapping = new ConcurrentHashMap<>(); + + + protected static ConcurrentMap<Long, String> orgIdAndOrgNameMap = new ConcurrentHashMap<>(); + + + protected static ConcurrentMap<Long, Helpdesk> helpdeskIdHelpdeskObjectMapping = new ConcurrentHashMap<>(); + protected static ConcurrentMap<Long, List<Long>> helpdeskIdAppIdsMapping = new ConcurrentHashMap<>(); + + protected static ConcurrentMap<Long, String> userIdAndUserNameMap = new ConcurrentHashMap<>(); + + + public static final BeanPropertyRowMapper<User> rowMapUser = new BeanPropertyRowMapper<>(User.class); + public static final BeanPropertyRowMapper<CommonDataModel> rowMapCommonDataModel = new BeanPropertyRowMapper<>( + CommonDataModel.class); + public static final BeanPropertyRowMapper<Organization> rowMapOrganizationModel = new BeanPropertyRowMapper<>( + Organization.class); + public static final BeanPropertyRowMapper<HelpdeskDto> rowMapHelpdeskDto = new BeanPropertyRowMapper<>( + HelpdeskDto.class); + public static final BeanPropertyRowMapper<App> rowMapApp = new BeanPropertyRowMapper<>(App.class); + public static final BeanPropertyRowMapper<ServiceRequest> rowMapServiceRequest = new BeanPropertyRowMapper<>( + ServiceRequest.class); + public static final BeanPropertyRowMapper<Ticket> rowMapTicket = new BeanPropertyRowMapper<>(Ticket.class); + public static final BeanPropertyRowMapper<Updates> rowMapUpdate = new BeanPropertyRowMapper<>(Updates.class); + public static final BeanPropertyRowMapper<ActivityLog> rowMapActivityLogs = new BeanPropertyRowMapper<>( + ActivityLog.class); + public static final BeanPropertyRowMapper<S3Config> rowMapS3Config = new BeanPropertyRowMapper<>(S3Config.class); + public static final BeanPropertyRowMapper<Access> rowMapAccess = new BeanPropertyRowMapper<>(Access.class); + public static final BeanPropertyRowMapper<Tags> rowMapTags = new BeanPropertyRowMapper<>(Tags.class); + public static final BeanPropertyRowMapper<TicketTags> rowMapTicketTags = new BeanPropertyRowMapper<>( + TicketTags.class); + public static final BeanPropertyRowMapper<Role> rowMapRole = new BeanPropertyRowMapper<>(Role.class); + public static final BeanPropertyRowMapper<OrgUserRoleDto> rowMapOrgUserRoleDto = new BeanPropertyRowMapper<>( + OrgUserRoleDto.class); + public static final BeanPropertyRowMapper<HelpDeskApp> rowMapHelpDeskApp = new BeanPropertyRowMapper<>( + HelpDeskApp.class); + public static final BeanPropertyRowMapper<Helpdesk> rowMapHelpdesk = new BeanPropertyRowMapper<>(Helpdesk.class); + public static final BeanPropertyRowMapper<Action> rowMapAction = new BeanPropertyRowMapper<>(Action.class); + + private static RoleActionService roleActionService; + + private static UserService userService; + + private static ApplicationService applicationService; + + private static HelpdeskService helpdeskService; + + private static SuperAdminService superAdminService; + + @Autowired + public void setApplicationService(ApplicationService applicationService) { + MasterDataManager.applicationService = applicationService; + } + + @Autowired + public void setUserService(HelpdeskService helpdeskService) { + MasterDataManager.helpdeskService = helpdeskService; + } + + @Autowired + public void setRoleActionService(RoleActionService roleActionService) { + MasterDataManager.roleActionService = roleActionService; + } + + @Autowired + public void setUserService(UserService userService) { + MasterDataManager.userService = userService; + } + + @Autowired + public void setSuperAdminService(SuperAdminService superAdminService) { + MasterDataManager.superAdminService = superAdminService; + } + + @Override + public void run(ApplicationArguments args) throws Exception { + getAllOrgRoles(); + getAllOrg(); + getAllOrgUsers(); + getAllUserRoles(); + getAppObjectFromAppName(); + getHelpdeskIdFromAppId(); + getHelpdeskObjectFromHelpdeskId(); + getUserIdAndUserName(); + initializeActions(); + intializeRolesAndActions(); + getAllActionsForRoles(); + } + + private static void intializeRolesAndActions() { + roleActionService.intializeRolesAndActions(); + + } + + private static void initializeActions() { + LOGGER.info("#MasterDataManager :: Initializing Actions : "); + roleActionService.initializeActions(); + + } + + public static void flushMasterData() { + orgRoleMap.clear(); + orgUserMap.clear(); + getUserOrgMap().clear(); + getRoleMap().clear(); + getUserRoleMap().clear(); + getRoleUserMap().clear(); + appIdHelpdeskIdMapping.clear(); + appNameAppObjectMapping.clear(); + appIdAppObjectMapping.clear(); + getOrgIdAndOrgNameMap().clear(); + getHelpdeskIdHelpdeskObjectMapping().clear(); + helpdeskIdAppIdsMapping.clear(); + getUserIdAndUserNameMap().clear(); + } + + public static void reloadMasterData() { + getAllOrgRoles(); + getAllOrg(); + getUserIdAndUserName(); + getAllOrgUsers(); + getAllUserRoles(); + getAppObjectFromAppName(); + getHelpdeskIdFromAppId(); + getHelpdeskObjectFromHelpdeskId(); + } + + + + public static void getAllOrgRoles() { + getRoleMap().clear(); + orgRoleMap.clear(); + + List<Role> roleList = roleActionService.getAllOrgRoles(); + for (Role role : roleList) { + getRoleMap().put(role.getId(), role); + if (orgRoleMap.containsKey(role.getOrgId())) { + List<Role> orgRoleList = orgRoleMap.get(role.getOrgId()); + orgRoleList.add(role); + } else { + List<Role> orgRoleList = new ArrayList<>(); + orgRoleList.add(role); + orgRoleMap.put(role.getOrgId(), orgRoleList); + } + } + } + + public static void getAllOrg() { + getOrgIdAndOrgNameMap().clear(); + + try { + List<Organization> orgs = superAdminService.getAllOrganization(); + for (Organization org : orgs) { + getOrgIdAndOrgNameMap().put(org.getId(), org.getOrgName()); + } + } catch (Exception e) { + LOGGER.error(String.format("Error : %s", e.getMessage())); + } + } + + public static void getAllOrgUsers() { + orgUserMap.clear(); + getUserOrgMap().clear(); + + List<OrgUserRoleDto> orgUserList = userService.getAllOrgUsers(); + for (OrgUserRoleDto dto : orgUserList) { + if (orgUserMap.containsKey(dto.getOrgId())) { + List<Long> userList = orgUserMap.get(dto.getOrgId()); + userList.add(dto.getUserId()); + } else { + List<Long> userList = new ArrayList<>(); + userList.add(dto.getUserId()); + orgUserMap.put(dto.getOrgId(), userList); + } + getUserOrgMap().put(dto.getUserId(), dto.getOrgId()); + } + } + + public static void getAllUserRoles() { + getUserRoleMap().clear(); + getRoleUserMap().clear(); + getUserRoleListMap().clear(); + + List<OrgUserRoleDto> userRoleList = userService.getAllUserRoles(); + for (OrgUserRoleDto dto : userRoleList) { + if (!getUserRoleMap().containsKey(dto.getUserId())) { + getUserRoleMap().put(dto.getUserId(), dto.getRoleId()); + } + + if (!getRoleUserMap().containsKey(dto.getRoleId())) { + getRoleUserMap().put(dto.getRoleId(), dto.getUserId()); + } + + if (!getUserRoleListMap().containsKey(dto.getUserId())) { + getUserRoleListMap().put(dto.getUserId(), dto.getRoleIds()); + } + } + } + + public static void getAllActionsForRoles() { + roleActionsListMap.clear(); + List<Long> roleIds = new ArrayList<>(); + for (Map.Entry<Long, Role> entry : getRoleMap().entrySet()) { + roleIds.add(entry.getKey()); + } + Map<Long, List<String>> fetchedMap = roleActionService.getAllActionsForRoles(roleIds); + roleActionsListMap.putAll(fetchedMap); + } + + public static void getHelpdeskIdFromAppId() { + helpdeskIdAppIdsMapping.clear(); + appIdHelpdeskIdMapping.clear(); + + List<HelpDeskApp> appIdHelpdeskId = helpdeskService.getAppIdAndHelpDeskId(); + for (HelpDeskApp dto : appIdHelpdeskId) { + appIdHelpdeskIdMapping.put(dto.getAppId(), dto.getHelpDeskId()); + List<Long> appIds = new ArrayList<>(); + if (helpdeskIdAppIdsMapping.get(dto.getHelpDeskId()) != null) { + appIds = helpdeskIdAppIdsMapping.get(dto.getHelpDeskId()); + } + appIds.add(dto.getAppId()); + helpdeskIdAppIdsMapping.put(dto.getHelpDeskId(), appIds); + } + } + + public static void getAppObjectFromAppName() { + appIdAppObjectMapping.clear(); + appNameAppObjectMapping.clear(); + + List<App> app = applicationService.getAppIdAndAppObject(); + for (App dto : app) { + appNameAppObjectMapping.put(dto.getName(), dto); + appIdAppObjectMapping.put(dto.getId(), dto); + } + + } + + public static void getHelpdeskObjectFromHelpdeskId() { + getHelpdeskIdHelpdeskObjectMapping().clear(); + + List<Helpdesk> helpdesk = helpdeskService.getHelpdeskObjectFromHelpdeskId(); + for (Helpdesk dto : helpdesk) { + getHelpdeskIdHelpdeskObjectMapping().put(dto.getId(), dto); + } + } + + public static void getUserIdAndUserName() { + getUserIdAndUserNameMap().clear(); + List<User> users = userService.getUserIdAndUserName(); + for (User usr : users) { + getUserIdAndUserNameMap().put(usr.getId(), usr.getName()); + } + } + + + + public static List<Role> getRolesByOrg(Long orgId) { + if (orgRoleMap.containsKey(orgId)) { + return orgRoleMap.get(orgId); + } else { + getAllOrgRoles(); + if (orgRoleMap.containsKey(orgId)) { + return orgRoleMap.get(orgId); + } else { + return new ArrayList<>(); + } + } + } + + public static Role getRoleById(Long roleId) { + if (getRoleMap().containsKey(roleId)) { + return getRoleMap().get(roleId); + } else { + getAllOrgRoles(); + if (getRoleMap().containsKey(roleId)) { + return getRoleMap().get(roleId); + } else { + return new Role(); + } + } + } + + public static Long getOrgForUser(Long userId) { + if (getUserOrgMap().containsKey(userId)) { + return getUserOrgMap().get(userId); + } else { + getAllOrgUsers(); + if (getUserOrgMap().containsKey(userId)) { + return getUserOrgMap().get(userId); + } else { + return 0L; + } + } + } + + public static List<Long> getUsersForOrg(Long orgId) { + if (orgUserMap.containsKey(orgId)) { + return orgUserMap.get(orgId); + } else { + getAllOrgUsers(); + if (orgUserMap.containsKey(orgId)) { + return orgUserMap.get(orgId); + } else { + return new ArrayList<>(); + } + } + } + + public static Long getRoleForUser(Long userId) { + if (getUserRoleMap().containsKey(userId)) { + return getUserRoleMap().get(userId); + } else { + getAllUserRoles(); + if (getUserRoleMap().containsKey(userId)) { + return getUserRoleMap().get(userId); + } else { + return 0l; + } + } + } + + public static Long getUserForRole(Long roleId) { + if (getRoleUserMap().containsKey(roleId)) { + return getRoleUserMap().get(roleId); + } else { + getAllUserRoles(); + if (getRoleUserMap().containsKey(roleId)) { + return getRoleUserMap().get(roleId); + } else { + return 0l; + } + } + } + + public static List<Long> getAppIdsForHelpdesk(Long helpdeskId) { + if (helpdeskIdAppIdsMapping.containsKey(helpdeskId)) { + return helpdeskIdAppIdsMapping.get(helpdeskId); + } else { + getHelpdeskIdFromAppId(); + if (helpdeskIdAppIdsMapping.containsKey(helpdeskId)) { + return helpdeskIdAppIdsMapping.get(helpdeskId); + } else { + return new ArrayList<>(); + } + } + } + + public static App getAppFromAppId(Long appId) { + if (appIdAppObjectMapping.containsKey(appId)) { + return appIdAppObjectMapping.get(appId); + } else { + getAppObjectFromAppName(); + if (appIdAppObjectMapping.containsKey(appId)) { + return appIdAppObjectMapping.get(appId); + } else { + return null; + } + } + } + + public static List<Long> getRoleIdsForUserId(Long userId) { + if (getUserRoleListMap().containsKey(userId)) { + return getUserRoleListMap().get(userId); + } else { + getAllUserRoles(); + if (getUserRoleListMap().containsKey(userId)) { + return getUserRoleListMap().get(userId); + } else { + return new ArrayList<>(); + } + } + } + + public static List<String> getActionUrlsForRoleId(Long roleId) { + if (roleActionsListMap.containsKey(roleId)) { + return roleActionsListMap.get(roleId); + } else { + getAllUserRoles(); + if (roleActionsListMap.containsKey(roleId)) { + return roleActionsListMap.get(roleId); + } else { + return new ArrayList<>(); + } + } + } + + public static ConcurrentMap<Long, Long> getUserOrgMap() { + return userOrgMap; + } + + public static void setUserOrgMap(ConcurrentMap<Long, Long> userOrgMap) { + MasterDataManager.userOrgMap = userOrgMap; + } + + public static ConcurrentMap<Long, String> getOrgIdAndOrgNameMap() { + return orgIdAndOrgNameMap; + } + + public static void setOrgIdAndOrgNameMap(ConcurrentMap<Long, String> orgIdAndOrgNameMap) { + MasterDataManager.orgIdAndOrgNameMap = orgIdAndOrgNameMap; + } + + public static ConcurrentMap<Long, Role> getRoleMap() { + return roleMap; + } + + public static void setRoleMap(ConcurrentMap<Long, Role> roleMap) { + MasterDataManager.roleMap = roleMap; + } + + public static ConcurrentMap<Long, Long> getUserRoleMap() { + return userRoleMap; + } + + public static void setUserRoleMap(ConcurrentMap<Long, Long> userRoleMap) { + MasterDataManager.userRoleMap = userRoleMap; + } + + public static ConcurrentMap<Long, Helpdesk> getHelpdeskIdHelpdeskObjectMapping() { + return helpdeskIdHelpdeskObjectMapping; + } + + public static void setHelpdeskIdHelpdeskObjectMapping( + ConcurrentMap<Long, Helpdesk> helpdeskIdHelpdeskObjectMapping) { + MasterDataManager.helpdeskIdHelpdeskObjectMapping = helpdeskIdHelpdeskObjectMapping; + } + + public static ConcurrentMap<Long, String> getUserIdAndUserNameMap() { + return userIdAndUserNameMap; + } + + public static void setUserIdAndUserNameMap(ConcurrentMap<Long, String> userIdAndUserNameMap) { + MasterDataManager.userIdAndUserNameMap = userIdAndUserNameMap; + } + + public static ConcurrentMap<Long, Long> getRoleUserMap() { + return roleUserMap; + } + + public static void setRoleUserMap(ConcurrentMap<Long, Long> roleUserMap) { + MasterDataManager.roleUserMap = roleUserMap; + } + + public static ConcurrentMap<Long, List<Long>> getUserRoleListMap() { + return userRoleListMap; + } + + public static void setUserRoleListMap(ConcurrentMap<Long, List<Long>> userRoleListMap) { + MasterDataManager.userRoleListMap = userRoleListMap; + } + +} diff --git a/src/main/java/org/upsmf/grievance/interceptor/TicketsRequestInterceptor.java b/src/main/java/org/upsmf/grievance/interceptor/TicketsRequestInterceptor.java new file mode 100644 index 0000000..fb690d7 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/interceptor/TicketsRequestInterceptor.java @@ -0,0 +1,498 @@ +package org.upsmf.grievance.interceptor; + +import java.io.IOException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.stream.Collectors; + +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; +import org.elasticsearch.action.delete.DeleteRequest; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.update.UpdateRequest; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback; +import org.elasticsearch.client.RestHighLevelClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import org.upsmf.grievance.dao.impl.ApplicationDaoImpl; +import org.upsmf.grievance.model.Tags; +import org.upsmf.grievance.model.Ticket; +import org.upsmf.grievance.util.Constants; +import org.upsmf.grievance.util.ProjectUtil; + +@Component +public class TicketsRequestInterceptor { + + private static final String EL_STIC123 = "El@stic123"; + private static final String ELASTIC = "elastic"; + private static final String ENCOUNTERED_AN_EXCEPTION_S = "Encountered an Exception : %s"; + private static final String CLASSNAME = TicketsRequestInterceptor.class.getName(); + private static BlockingQueue<Ticket> queue = new ArrayBlockingQueue<>(Constants.CAPACITY); + public static final Logger LOGGER = LoggerFactory.getLogger(ApplicationDaoImpl.class); + + @Value("${elk.data.up}") + private boolean elkDataUp; + + @Value("${elasticsearch.url}") + private String elasticsearchUrl; + + @Value("${elasticsearch.index}") + private String elasticsearchIndex; + + @Value("${elasticsearch.type}") + private String elasticsearchType; + + public void addData(Ticket data) { + try { + if (elkDataUp) { + queue.add(data); + processData(); + } else { + LOGGER.info("ELK data insertion is not allowed %s"); + } + } catch (Exception e) { + LOGGER.error(e.getMessage()); + } + } + + public void processData() { + Runnable task1 = new Runnable() { + @Override + public void run() { + try { + Thread.sleep(1000); + Ticket data = queue.take(); + if (data != null) { + if (Constants.ELK_OPERATION.SAVE.toString().equalsIgnoreCase(data.getOperation())) { + addTicketDataToElastic(data); + } else if (Constants.ELK_OPERATION.UPDATE.toString().equalsIgnoreCase(data.getOperation())) { + updateTicketDataInElastic(data); + } else if (Constants.ELK_OPERATION.DELETE.toString().equalsIgnoreCase(data.getOperation())) { + deleteTicketDataFromElastic(data); + } + } else { + LOGGER.error(String.format("unable to get value %s", CLASSNAME)); + } + } catch (Exception e) { + LOGGER.error(e.getMessage()); + } + } + }; + Thread thread1 = new Thread(task1); + thread1.start(); + } + + private Map<String, Object> addTicketDataToElastic(Ticket value) throws ParseException, IOException { + Map<String, Object> jsonMap = createJsonMap(value); + writeDatatoElastic(jsonMap, String.valueOf(value.getId())); + return jsonMap; + } + + private Map<String, Object> updateTicketDataInElastic(Ticket value) throws ParseException, IOException { + Map<String, Object> jsonMap = updateJsonMap(value); + updateDataInElastic(jsonMap, String.valueOf(value.getId())); + return jsonMap; + } + + private Map<String, Object> updateJsonMap(Ticket value) throws ParseException { + Map<String, Object> jsonMap = new HashMap<>(); + setValuesOnUpdate(value, jsonMap); + setValuesOnUpdate2(value, jsonMap); + if (!StringUtils.isBlank(value.getOsVersion())) { + jsonMap.put(Constants.OS_VERSION, value.getOsVersion()); + } + if (!StringUtils.isBlank(value.getOsType())) { + jsonMap.put(Constants.OS_TYPE, value.getOsType()); + } + if (!StringUtils.isBlank(value.getDeviceType())) { + jsonMap.put(Constants.DEVICE_TYPE, value.getDeviceType()); + } + if (!StringUtils.isBlank(value.getIp())) { + jsonMap.put(Constants.IP, value.getIp()); + } + if (!StringUtils.isBlank(value.getCountry())) { + jsonMap.put(Constants.COUNTRY, value.getCountry()); + } + if (!StringUtils.isBlank(value.getDeviceName())) { + jsonMap.put(Constants.DEVICE_NAME, value.getDeviceName()); + } + if (!StringUtils.isBlank(value.getDeviceManufacture())) { + jsonMap.put(Constants.DEVICE_MANUFACTURE, value.getDeviceManufacture()); + } + if (!StringUtils.isBlank(value.getDeviceLocale())) { + jsonMap.put(Constants.DEVICE_LOCALE, value.getDeviceLocale()); + } + if (!StringUtils.isBlank(value.getDeviceScreenResolution())) { + jsonMap.put(Constants.DEVICE_SCREEN_RESOLUTION, value.getDeviceScreenResolution()); + } + if (!StringUtils.isBlank(value.getUserEvent())) { + jsonMap.put(Constants.USER_EVENT, value.getUserEvent()); + } + if (!ProjectUtil.isObjectListNullOrEmpty(value.getTags())) { + jsonMap.put(Constants.TAGS2, value.getTags().stream().map(Tags::getName).collect(Collectors.toList())); + } + if (!ProjectUtil.isObjectListNullOrEmpty(value.getCc())) { + jsonMap.put(Constants.CC, value.getCc()); + } + return jsonMap; + } + + public void setValuesOnUpdate2(Ticket value, Map<String, Object> jsonMap) { + if (value.getPinnedTicket() != null) { + jsonMap.put(Constants.PINNED_TICKET, value.getPinnedTicket()); + } + jsonMap.put(Constants.OPR, Constants.UPDATE); + if (value.getAppId() != null) { + jsonMap.put(Constants.APP_ID, value.getAppId()); + } + if (value.getHelpdeskId() != null) { + jsonMap.put(Constants.HELPDESK_ID, value.getHelpdeskId()); + } + if (value.getSourceId() != null) { + jsonMap.put(Constants.SOURCE_ID, value.getSourceId()); + } + if (value.getType() != null) { + jsonMap.put(Constants.TYPE_ID, value.getType()); + } + if (!StringUtils.isBlank(value.getPriority())) { + jsonMap.put(Constants.PRIORITY, value.getPriority()); + } + if (!StringUtils.isBlank(value.getStatus())) { + jsonMap.put(Constants.STATUS, value.getStatus()); + } + } + + public void setValuesOnUpdate(Ticket value, Map<String, Object> jsonMap) throws ParseException { + setValuesOnUpdate3(value, jsonMap); + if (value.getUpdatedTime() != null) { + jsonMap.put(Constants.U_T, value.getUpdatedTime().split(" ")[1]); + } + if (value.getCreatedTimeTS() != null) { + jsonMap.put(Constants.CREATED_TIME_TS, value.getCreatedTimeTS()); + } else if (value.getCreatedTime() != null) { + jsonMap.put(Constants.CREATED_TIME_TS, timestampconvertor(value.getCreatedTime())); + } + if (value.getUpdatedTimeTS() != null) { + jsonMap.put(Constants.UPDATED_TIME_TS, value.getUpdatedTimeTS()); + } + if (value.getRequestedBy() != null) { + jsonMap.put(Constants.REQUESTED_BY, value.getRequestedBy()); + } + if (!StringUtils.isBlank(value.getAppVersion())) { + jsonMap.put(Constants.APP_VERSION, value.getAppVersion()); + } + if (!StringUtils.isBlank(value.getAppName())) { + jsonMap.put(Constants.APP_NAME, value.getAppName()); + } + if (value.getActive() != null) { + jsonMap.put(Constants.ACTIVE, value.getActive()); + } + } + + public void setValuesOnUpdate3(Ticket value, Map<String, Object> jsonMap) { + if (!StringUtils.isBlank(value.getDescription())) { + jsonMap.put(Constants.DESCRIPTION, value.getDescription()); + } + if (!StringUtils.isBlank(value.getReviewId())) { + jsonMap.put(Constants.REVIEW_ID, value.getReviewId()); + } + if (!StringUtils.isBlank(String.valueOf(value.getRate())) && value.getRate() > 0) { + jsonMap.put(Constants.RATE, value.getRate()); + } + if (!StringUtils.isBlank(String.valueOf(value.getMaxRating())) && value.getMaxRating() > 0) { + jsonMap.put(Constants.MAX_RATING, value.getMaxRating()); + } + if (value.getCreatedTime() != null) { + jsonMap.put(Constants.CREATED_TIME, value.getCreatedTime().split(" ")[0]); + } + if (value.getUpdatedTime() != null) { + jsonMap.put(Constants.UPDATED_TIME, value.getUpdatedTime().split(" ")[0]); + } + if (value.getCreatedTime() != null) { + jsonMap.put(Constants.C_T, value.getCreatedTime().split(" ")[1]); + } + } + + public Map<String, Object> createJsonMap(Ticket value) throws ParseException { + Map<String, Object> jsonMap = new HashMap<>(); + setValuesOnCreate(value, jsonMap); + setValuesOnCreate2(value, jsonMap); + setValuesOnCreate3(value, jsonMap); + setValuesOnCreate4(value, jsonMap); + setValuesOnCreate5(value, jsonMap); + return jsonMap; + } + + public void setValuesOnCreate5(Ticket value, Map<String, Object> jsonMap) { + if (!StringUtils.isBlank(value.getDeviceScreenResolution())) { + jsonMap.put(Constants.DEVICE_SCREEN_RESOLUTION, value.getDeviceScreenResolution()); + } else { + jsonMap.put(Constants.DEVICE_SCREEN_RESOLUTION, null); + } + if (!StringUtils.isBlank(value.getUserEvent())) { + jsonMap.put(Constants.USER_EVENT, value.getUserEvent()); + } else { + jsonMap.put(Constants.USER_EVENT, null); + } + if (!ProjectUtil.isObjectListNullOrEmpty(value.getTags())) { + jsonMap.put(Constants.TAGS2, value.getTags().stream().map(Tags::getName).collect(Collectors.toList())); + } else { + jsonMap.put(Constants.TAGS2, null); + } + if (!ProjectUtil.isObjectListNullOrEmpty(value.getCc())) { + jsonMap.put(Constants.CC, value.getCc()); + } else { + jsonMap.put(Constants.CC, null); + } + } + + public void setValuesOnCreate4(Ticket value, Map<String, Object> jsonMap) { + setValuesOnCreate6(value, jsonMap); + if (!StringUtils.isBlank(value.getCountry())) { + jsonMap.put(Constants.COUNTRY, value.getCountry()); + } else { + jsonMap.put(Constants.COUNTRY, null); + } + if (!StringUtils.isBlank(value.getDeviceName())) { + jsonMap.put(Constants.DEVICE_NAME, value.getDeviceName()); + } else { + jsonMap.put(Constants.DEVICE_NAME, null); + } + if (!StringUtils.isBlank(value.getDeviceManufacture())) { + jsonMap.put(Constants.DEVICE_MANUFACTURE, value.getDeviceManufacture()); + } else { + jsonMap.put(Constants.DEVICE_MANUFACTURE, null); + } + if (!StringUtils.isBlank(value.getDeviceLocale())) { + jsonMap.put(Constants.DEVICE_LOCALE, value.getDeviceLocale()); + } else { + jsonMap.put(Constants.DEVICE_LOCALE, null); + } + } + + public void setValuesOnCreate6(Ticket value, Map<String, Object> jsonMap) { + if (!StringUtils.isBlank(value.getOsVersion())) { + jsonMap.put(Constants.OS_VERSION, value.getOsVersion()); + } else { + jsonMap.put(Constants.OS_VERSION, null); + } + if (!StringUtils.isBlank(value.getOsType())) { + jsonMap.put(Constants.OS_TYPE, value.getOsType()); + } else { + jsonMap.put(Constants.OS_TYPE, null); + } + if (!StringUtils.isBlank(value.getDeviceType())) { + jsonMap.put(Constants.DEVICE_TYPE, value.getDeviceType()); + } else { + jsonMap.put(Constants.DEVICE_TYPE, null); + } + jsonMap.put(Constants.SV, Constants.A_1_0); + if (!StringUtils.isBlank(value.getIp())) { + jsonMap.put(Constants.IP, value.getIp()); + } else { + jsonMap.put(Constants.IP, null); + } + } + + public void setValuesOnCreate3(Ticket value, Map<String, Object> jsonMap) { + setValuesOnCreate7(value, jsonMap); + if (!StringUtils.isBlank(String.valueOf(value.getHelpdeskId()))) { + jsonMap.put(Constants.HELPDESK_ID, value.getHelpdeskId()); + } else { + jsonMap.put(Constants.HELPDESK_ID, null); + } + if (!StringUtils.isBlank(String.valueOf(value.getSourceId()))) { + jsonMap.put(Constants.SOURCE_ID, value.getSourceId()); + } else { + jsonMap.put(Constants.SOURCE_ID, null); + } + if (!StringUtils.isBlank(String.valueOf(value.getType()))) { + jsonMap.put(Constants.TYPE_ID, value.getType()); + } else { + jsonMap.put(Constants.TYPE_ID, null); + } + if (!StringUtils.isBlank(value.getPriority())) { + jsonMap.put(Constants.PRIORITY, value.getPriority()); + } else { + jsonMap.put(Constants.PRIORITY, null); + } + if (!StringUtils.isBlank(value.getStatus())) { + jsonMap.put(Constants.STATUS, value.getStatus()); + } else { + jsonMap.put(Constants.STATUS, null); + } + } + + public void setValuesOnCreate7(Ticket value, Map<String, Object> jsonMap) { + if (!StringUtils.isBlank(value.getAppName())) { + jsonMap.put(Constants.APP_NAME, value.getAppName()); + } else { + jsonMap.put(Constants.APP_NAME, null); + } + jsonMap.put(Constants.ACTIVE, value.getActive()); + jsonMap.put(Constants.PINNED_TICKET, value.getPinnedTicket()); + if (value.getOperation().equalsIgnoreCase(Constants.SAVE)) { + jsonMap.put(Constants.OPR, Constants.SAVE); + } else { + jsonMap.put(Constants.OPR, Constants.UPDATE); + } + if (!StringUtils.isBlank(String.valueOf(value.getAppId()))) { + jsonMap.put(Constants.APP_ID, value.getAppId()); + } else { + jsonMap.put(Constants.APP_ID, null); + } + } + + public void setValuesOnCreate2(Ticket value, Map<String, Object> jsonMap) throws ParseException { + if (!StringUtils.isBlank(String.valueOf(value.getCreatedTime()))) { + jsonMap.put(Constants.C_T, value.getCreatedTime().split(" ")[1]); + } else { + jsonMap.put(Constants.C_T, null); + } + if (!StringUtils.isBlank(String.valueOf(value.getUpdatedTime()))) { + jsonMap.put(Constants.U_T, value.getUpdatedTime().split(" ")[1]); + } else { + jsonMap.put(Constants.U_T, null); + } + if (!StringUtils.isBlank(String.valueOf(value.getCreatedTimeTS()))) { + jsonMap.put(Constants.CREATED_TIME_TS, value.getCreatedTimeTS()); + } else if (!StringUtils.isBlank(String.valueOf(value.getCreatedTime()))) { + jsonMap.put(Constants.CREATED_TIME_TS, timestampconvertor(value.getCreatedTime())); + } else { + jsonMap.put(Constants.CREATED_TIME_TS, null); + } + if (!StringUtils.isBlank(String.valueOf(value.getUpdatedTimeTS()))) { + jsonMap.put(Constants.UPDATED_TIME_TS, value.getUpdatedTimeTS()); + } else { + jsonMap.put(Constants.UPDATED_TIME_TS, null); + } + if (!StringUtils.isBlank(String.valueOf(value.getRequestedBy()))) { + jsonMap.put(Constants.REQUESTED_BY, value.getRequestedBy()); + } else { + jsonMap.put(Constants.REQUESTED_BY, null); + } + if (!StringUtils.isBlank(value.getAppVersion())) { + jsonMap.put(Constants.APP_VERSION, value.getAppVersion()); + } else { + jsonMap.put(Constants.APP_VERSION, null); + } + } + + public void setValuesOnCreate(Ticket value, Map<String, Object> jsonMap) { + if (!StringUtils.isBlank(String.valueOf(value.getId()))) { + jsonMap.put(Constants.ID, value.getId()); + } else { + jsonMap.put(Constants.ID, 0); + } + if (!StringUtils.isBlank(value.getDescription())) { + jsonMap.put(Constants.DESCRIPTION, value.getDescription()); + } else { + jsonMap.put(Constants.DESCRIPTION, null); + } + if (!StringUtils.isBlank(value.getReviewId())) { + jsonMap.put(Constants.REVIEW_ID, value.getReviewId()); + } else { + jsonMap.put(Constants.REVIEW_ID, null); + } + if (!StringUtils.isBlank(String.valueOf(value.getRate()))) { + jsonMap.put(Constants.RATE, value.getRate()); + } else { + jsonMap.put(Constants.RATE, null); + } + if (!StringUtils.isBlank(String.valueOf(value.getMaxRating()))) { + jsonMap.put(Constants.MAX_RATING, value.getMaxRating()); + } else { + jsonMap.put(Constants.MAX_RATING, null); + } + if (!StringUtils.isBlank(String.valueOf(value.getCreatedTime()))) { + jsonMap.put(Constants.CREATED_TIME, value.getCreatedTime().split(" ")[0]); + } else { + jsonMap.put(Constants.CREATED_TIME, null); + } + if (!StringUtils.isBlank(String.valueOf(value.getUpdatedTime()))) { + jsonMap.put(Constants.UPDATED_TIME, value.getUpdatedTime().split(" ")[0]); + } else { + jsonMap.put(Constants.UPDATED_TIME, null); + } + } + + private void deleteTicketDataFromElastic(Ticket data) throws IOException { + RestHighLevelClient rc = new RestHighLevelClient(RestClient.builder(new HttpHost(elasticsearchUrl))); + try { + DeleteRequest request = new DeleteRequest(elasticsearchIndex, "doc", String.valueOf(data.getId())); + rc.delete(request); + } catch (Exception e) { + LOGGER.error(e.getMessage()); + } finally { + rc.close(); + } + } + + public Long timestampconvertor(String createdDate) throws ParseException { + try { + DateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss"); + Date date = dateFormat.parse(createdDate); + return date.getTime() / 1000; + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + } + return null; + } + + private RestHighLevelClient connectToElasticSearch() { + final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(ELASTIC, EL_STIC123)); + + HttpClientConfigCallback httpClientConfigCallback = new HttpClientConfigCallback() { + @Override + public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { + return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); + } + }; + return new RestHighLevelClient(RestClient.builder(new HttpHost(elasticsearchUrl)) + .setHttpClientConfigCallback(httpClientConfigCallback)); + } + + private void writeDatatoElastic(Map<String, Object> jsonMap, String id) throws IOException { + RestHighLevelClient rc = connectToElasticSearch(); + try { + IndexRequest indexRequest = new IndexRequest(elasticsearchIndex, elasticsearchType, id).source(jsonMap); + IndexResponse response = rc.index(indexRequest); + if (!StringUtils.isBlank(response.toString())) { + LOGGER.info("Response : {}", response); + } + } catch (Exception e) { + LOGGER.error(e.getMessage()); + } finally { + rc.close(); + } + } + + private void updateDataInElastic(Map<String, Object> jsonMap, String id) throws IOException { + RestHighLevelClient rc = connectToElasticSearch(); + try { + UpdateRequest updateRequest = new UpdateRequest(elasticsearchIndex, elasticsearchType, id).doc(jsonMap); + rc.update(updateRequest); + } catch (Exception e) { + LOGGER.error(e.getMessage()); + } finally { + rc.close(); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/interceptor/package-info.java b/src/main/java/org/upsmf/grievance/interceptor/package-info.java new file mode 100644 index 0000000..01a6f3a --- /dev/null +++ b/src/main/java/org/upsmf/grievance/interceptor/package-info.java @@ -0,0 +1,8 @@ +/** + * + */ +/** + * @author Juhi Agarwal + * + */ +package org.upsmf.grievance.interceptor; \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/model/Access.java b/src/main/java/org/upsmf/grievance/model/Access.java new file mode 100644 index 0000000..e5c4fc8 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/Access.java @@ -0,0 +1,25 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class Access { + + private Long orgId; + private String grantType; + private String code; + private String clientId; + private String clientSecret; + private String refreshToken; + +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/model/AccessResponse.java b/src/main/java/org/upsmf/grievance/model/AccessResponse.java new file mode 100644 index 0000000..4ba5b17 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/AccessResponse.java @@ -0,0 +1,22 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class AccessResponse { + + private String accessToken; + private Long expiresIn; + private String scope; + private String tokenType; +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/model/Action.java b/src/main/java/org/upsmf/grievance/model/Action.java new file mode 100644 index 0000000..14f1d85 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/Action.java @@ -0,0 +1,24 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@AllArgsConstructor +@EqualsAndHashCode +@NoArgsConstructor +@ToString +public class Action { + + private Long id; + private String name; + private String displayName; + private String url; + private String queryParams; + private String serviceCode; +} diff --git a/src/main/java/org/upsmf/grievance/model/ActionRole.java b/src/main/java/org/upsmf/grievance/model/ActionRole.java new file mode 100644 index 0000000..71839de --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/ActionRole.java @@ -0,0 +1,20 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class ActionRole { + + private long actionId; + private long roleId; +} diff --git a/src/main/java/org/upsmf/grievance/model/ActivityLog.java b/src/main/java/org/upsmf/grievance/model/ActivityLog.java new file mode 100644 index 0000000..f2cbdaf --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/ActivityLog.java @@ -0,0 +1,29 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class ActivityLog implements Comparable<ActivityLog> { + + private Long id; + private String activity; + private Long ticketId; + private String timestamp; + private Long changesBy; + private Long helpdeskId; + + @Override + public int compareTo(ActivityLog o) { + return this.getId().compareTo(o.getId()); + } +} diff --git a/src/main/java/org/upsmf/grievance/model/Analytics.java b/src/main/java/org/upsmf/grievance/model/Analytics.java new file mode 100644 index 0000000..b663653 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/Analytics.java @@ -0,0 +1,22 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class Analytics { + + private Long userId; + private String startDate; + private String endDate; + +} diff --git a/src/main/java/org/upsmf/grievance/model/App.java b/src/main/java/org/upsmf/grievance/model/App.java new file mode 100644 index 0000000..b169067 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/App.java @@ -0,0 +1,35 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class App { + + private Long id; + private String name; + private String code; + private String description; + private String clientName; + private String version; + private String appUrl; + private String logo; + private Long sourceId; + private Boolean activeStatus; + private Long orgId; + private String createdDate; + private Long createdBy; + private String updatedDate; + private Long updatedBy; + private String appKey; + +} diff --git a/src/main/java/org/upsmf/grievance/model/ChecklistItem.java b/src/main/java/org/upsmf/grievance/model/ChecklistItem.java new file mode 100644 index 0000000..73b7358 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/ChecklistItem.java @@ -0,0 +1,21 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class ChecklistItem { + + private Long id; + private String item; + private Boolean checked; +} diff --git a/src/main/java/org/upsmf/grievance/model/Comment.java b/src/main/java/org/upsmf/grievance/model/Comment.java new file mode 100644 index 0000000..ab702b4 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/Comment.java @@ -0,0 +1,20 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class Comment { + + private UserComment userComment; + private DeveloperComment developerComment; +} diff --git a/src/main/java/org/upsmf/grievance/model/CommonDataModel.java b/src/main/java/org/upsmf/grievance/model/CommonDataModel.java new file mode 100644 index 0000000..c16e622 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/CommonDataModel.java @@ -0,0 +1,79 @@ +package org.upsmf.grievance.model; + +import org.upsmf.grievance.model.enums.AuthTypes; +import org.upsmf.grievance.model.enums.PriorityLevels; + +public class CommonDataModel { + private int id; + private String name; + private String description; + private long userId; + private boolean active; + private long orgId; + + public long getOrgId() { + return orgId; + } + + public void setOrgId(long orgId) { + this.orgId = orgId; + } + + public CommonDataModel() { + } + + public CommonDataModel(PriorityLevels priorityLevels) { + this.name = String.valueOf(priorityLevels); + } + + public CommonDataModel(AuthTypes authTypes) { + this.id = authTypes.ordinal() + 1; + this.name = String.valueOf(authTypes); + } + + public CommonDataModel(int id, String name) { + this.id = id; + this.name = name; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public long getUserId() { + return userId; + } + + public void setUserId(long userId) { + this.userId = userId; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/src/main/java/org/upsmf/grievance/model/DeveloperComment.java b/src/main/java/org/upsmf/grievance/model/DeveloperComment.java new file mode 100644 index 0000000..161cbf8 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/DeveloperComment.java @@ -0,0 +1,21 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class DeveloperComment { + + private String text; + private LastModified lastModified; + +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/model/DeviceMetadata.java b/src/main/java/org/upsmf/grievance/model/DeviceMetadata.java new file mode 100644 index 0000000..fd58796 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/DeviceMetadata.java @@ -0,0 +1,30 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class DeviceMetadata { + + private String productName; + private String manufacturer; + private String deviceClass; + private Long screenWidthPx; + private Long screenHeightPx; + private String nativePlatform; + private Long screenDensityDpi; + private Long glEsVersion; + private String cpuModel; + private String cpuMake; + private Long ramMb; + +} diff --git a/src/main/java/org/upsmf/grievance/model/HelpDeskApp.java b/src/main/java/org/upsmf/grievance/model/HelpDeskApp.java new file mode 100644 index 0000000..93faa0a --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/HelpDeskApp.java @@ -0,0 +1,21 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class HelpDeskApp { + + private Long helpDeskId; + private Long appId; + +} diff --git a/src/main/java/org/upsmf/grievance/model/Helpdesk.java b/src/main/java/org/upsmf/grievance/model/Helpdesk.java new file mode 100644 index 0000000..a70c316 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/Helpdesk.java @@ -0,0 +1,67 @@ +package org.upsmf.grievance.model; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.upsmf.grievance.dto.HelpdeskDto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Helpdesk { + + private Long id; + private String name; + private Long orgId; + private Long createdBy; + private String createdDate; + private Long updatedBy; + private String updatedDate; + private List<Long> adminIds; + private List<User> adminDetails; + private String description; + private String color; + private List<Long> appIds; + private List<Long> sourceId; + private List<Long> userIds; + private Boolean allowAllUsers; + private List<User> admins; + private Boolean direct; + private Boolean playstore; + private Boolean appstore; + private Boolean aurora_sdk; + + public Helpdesk(HelpdeskDto helpdeskDto) { + this.id = helpdeskDto.getId(); + this.name = helpdeskDto.getName(); + this.orgId = helpdeskDto.getOrgId(); + this.createdBy = helpdeskDto.getCreatedBy(); + this.createdDate = helpdeskDto.getCreatedDate(); + this.updatedBy = helpdeskDto.getUpdatedBy(); + this.updatedDate = helpdeskDto.getUpdatedDate(); + this.isActive = helpdeskDto.getIsActive(); + this.color = helpdeskDto.getColor(); + this.description = helpdeskDto.getDescription(); + this.adminIds = helpdeskDto.getAdminIds(); + this.appIds = helpdeskDto.getAppIds(); + this.sourceId = helpdeskDto.getSourceId(); + this.userIds = helpdeskDto.getUserIds(); + this.allowAllUsers = helpdeskDto.getAllowAllUsers(); + this.admins = helpdeskDto.getAdmins(); + this.direct = helpdeskDto.getDirect(); + this.playstore = helpdeskDto.getPlaystore(); + this.appstore = helpdeskDto.getAppstore(); + this.aurora_sdk = helpdeskDto.getAuroraSdk(); + } + + @JsonProperty("isActive") + private Boolean isActive; +} diff --git a/src/main/java/org/upsmf/grievance/model/HelpdeskType.java b/src/main/java/org/upsmf/grievance/model/HelpdeskType.java new file mode 100644 index 0000000..7c44f6a --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/HelpdeskType.java @@ -0,0 +1,21 @@ +package org.upsmf.grievance.model; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class HelpdeskType { + private Long id; + private Long helpdeskId; + private String name; + private List<ChecklistItem> checklistItems; +} diff --git a/src/main/java/org/upsmf/grievance/model/HelpdeskWorkflow.java b/src/main/java/org/upsmf/grievance/model/HelpdeskWorkflow.java new file mode 100644 index 0000000..6e19aaa --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/HelpdeskWorkflow.java @@ -0,0 +1,22 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class HelpdeskWorkflow { + + private Long id; + private Long typeId; + private String name; + +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/model/KeyFactory.java b/src/main/java/org/upsmf/grievance/model/KeyFactory.java new file mode 100644 index 0000000..47a52de --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/KeyFactory.java @@ -0,0 +1,18 @@ +package org.upsmf.grievance.model; + +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Component; + +@Component +public class KeyFactory { + + private KeyFactory() { + super(); + } + + public static KeyHolder getkeyHolder() { + return new GeneratedKeyHolder(); + } + +} diff --git a/src/main/java/org/upsmf/grievance/model/LastModified.java b/src/main/java/org/upsmf/grievance/model/LastModified.java new file mode 100644 index 0000000..7cec582 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/LastModified.java @@ -0,0 +1,19 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +public class LastModified { + + private String seconds; + private Long nanos; + +} diff --git a/src/main/java/org/upsmf/grievance/model/LoginUser.java b/src/main/java/org/upsmf/grievance/model/LoginUser.java new file mode 100644 index 0000000..88e4350 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/LoginUser.java @@ -0,0 +1,21 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class LoginUser { + + private String username; + private String password; + private String email; +} diff --git a/src/main/java/org/upsmf/grievance/model/MasterData.java b/src/main/java/org/upsmf/grievance/model/MasterData.java new file mode 100644 index 0000000..7b6f5e3 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/MasterData.java @@ -0,0 +1,20 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class MasterData { + + private String field; + private Long count; +} diff --git a/src/main/java/org/upsmf/grievance/model/Organization.java b/src/main/java/org/upsmf/grievance/model/Organization.java new file mode 100644 index 0000000..d6df849 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/Organization.java @@ -0,0 +1,34 @@ +package org.upsmf.grievance.model; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +public class Organization { + private Long id; + private Long userId; + private String orgName; + private String url; + private String logo; + private Long createdBy; + private String createdDate; + private Long updatedBy; + private String updatedDate; + private Boolean isActive; + private List<User> adminDetails; + private String authId; + private String emailDomain; + private String orgDescription; + private String orgColor; + private String baseUrl; + +} diff --git a/src/main/java/org/upsmf/grievance/model/ReplyToReviews.java b/src/main/java/org/upsmf/grievance/model/ReplyToReviews.java new file mode 100644 index 0000000..b4180e4 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/ReplyToReviews.java @@ -0,0 +1,19 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class ReplyToReviews { + + private String reply; +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/model/Rev.java b/src/main/java/org/upsmf/grievance/model/Rev.java new file mode 100644 index 0000000..a1b2666 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/Rev.java @@ -0,0 +1,19 @@ +package org.upsmf.grievance.model; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +public class Rev { + + private List<Review> reviews = null; +} diff --git a/src/main/java/org/upsmf/grievance/model/Review.java b/src/main/java/org/upsmf/grievance/model/Review.java new file mode 100644 index 0000000..542a174 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/Review.java @@ -0,0 +1,23 @@ +package org.upsmf.grievance.model; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +public class Review { + + private String reviewId; + + private String authorName; + private List<Comment> comments = null; + +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/model/Role.java b/src/main/java/org/upsmf/grievance/model/Role.java new file mode 100644 index 0000000..f08e0b0 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/Role.java @@ -0,0 +1,18 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Role { + private Long id; + private String name; + private Long orgId; +} diff --git a/src/main/java/org/upsmf/grievance/model/RolesDto.java b/src/main/java/org/upsmf/grievance/model/RolesDto.java new file mode 100644 index 0000000..6a85aad --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/RolesDto.java @@ -0,0 +1,22 @@ +package org.upsmf.grievance.model; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +public class RolesDto { + + private List<Integer> ids; + private Long id; + private boolean active; + +} diff --git a/src/main/java/org/upsmf/grievance/model/S3Config.java b/src/main/java/org/upsmf/grievance/model/S3Config.java new file mode 100644 index 0000000..82c39c2 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/S3Config.java @@ -0,0 +1,46 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class S3Config { + + private String secretKey; + private String accessKey; + private String bucketName; + + public String getSecretKey() { + return secretKey; + } + + public void setSecretKey(String secretKey) { + this.secretKey = secretKey; + } + + public String getAccessKey() { + return accessKey; + } + + public void setAccessKey(String accessKey) { + this.accessKey = accessKey; + } + + public String getBucketName() { + return bucketName; + } + + public void setBucketName(String bucketName) { + this.bucketName = bucketName; + } + +} diff --git a/src/main/java/org/upsmf/grievance/model/ServiceRequest.java b/src/main/java/org/upsmf/grievance/model/ServiceRequest.java new file mode 100644 index 0000000..1230eb2 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/ServiceRequest.java @@ -0,0 +1,20 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class ServiceRequest { + private Long id; + private String name; + +} diff --git a/src/main/java/org/upsmf/grievance/model/StatusIdMap.java b/src/main/java/org/upsmf/grievance/model/StatusIdMap.java new file mode 100644 index 0000000..8b913fe --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/StatusIdMap.java @@ -0,0 +1,26 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class StatusIdMap { + + private Long orgId; + private Long appId; + private Long helpdeskId; + private boolean orgAppStatus; + private boolean helpdeskAppStatus; + private Long orgAppMapId; + private Long helpdeskAppMapId; + +} diff --git a/src/main/java/org/upsmf/grievance/model/Tags.java b/src/main/java/org/upsmf/grievance/model/Tags.java new file mode 100644 index 0000000..0faa4b7 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/Tags.java @@ -0,0 +1,21 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class Tags { + + private Long id; + private String name; + private Long createdBy; +} diff --git a/src/main/java/org/upsmf/grievance/model/Task.java b/src/main/java/org/upsmf/grievance/model/Task.java new file mode 100644 index 0000000..f5d6ead --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/Task.java @@ -0,0 +1,20 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class Task { + private Long id; + private String name; + private String description; +} diff --git a/src/main/java/org/upsmf/grievance/model/Template.java b/src/main/java/org/upsmf/grievance/model/Template.java new file mode 100644 index 0000000..c16ceb4 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/Template.java @@ -0,0 +1,22 @@ +package org.upsmf.grievance.model; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +public class Template { + + private String name; + private Long id; + private Long helpdeskId; + private List<Task> tasks; +} diff --git a/src/main/java/org/upsmf/grievance/model/TemplateVersion.java b/src/main/java/org/upsmf/grievance/model/TemplateVersion.java new file mode 100644 index 0000000..90791b1 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/TemplateVersion.java @@ -0,0 +1,20 @@ +package org.upsmf.grievance.model; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +public class TemplateVersion { + + private Long version; + private List<Template> templates; +} diff --git a/src/main/java/org/upsmf/grievance/model/Ticket.java b/src/main/java/org/upsmf/grievance/model/Ticket.java new file mode 100644 index 0000000..f081766 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/Ticket.java @@ -0,0 +1,82 @@ +package org.upsmf.grievance.model; + +import java.util.List; + +import org.upsmf.grievance.dto.TicketWorkflowDto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +public class Ticket { + + private Long userId; + private Long id; + private String description; + private String feedback; + private String reviewId; + private String developerComment; + private int rate; + private int maxRating; + private String createdTime; + private String updatedTime; + private Long createdTimeTS; + private Long updatedTimeTS; + private String userName; + private Long requestedBy; + private String operation; + private Long ts; + private Long total; + private Long userTimestamp; + private Long developerTimestamp; + + private String appName; + private String appVersion; + private String country; + private String feedbackByName; + private String sv; + private String userEvent; + private String ip; + private String deviceName; + private String deviceManufacture; + private String deviceScreenResolution; + private String deviceLocale; + private String deviceType; + private String osType; + private String osVersion; + + private String requestedByName; + private String priority; + private List<String> filterStatus; + private String notes; + private List<ChecklistItem> checklist; + + private Long appId; + private String appKey; + private Long helpdeskId; + private Long sourceId; + private Long type; + private List<Updates> updates; + private Long orgId; + private Boolean active; + private Boolean pinnedTicket = false; + private List<TicketWorkflowDto> workflowStages; + private List<Long> cc; + private String filterCTUT; + private int from; + private int size; + private String searchKeyword; + private String status; + private byte[] img; + private List<String> attachmentUrl; + private List<String> selectedTags; + private List<Tags> tags; + +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/model/TicketCount.java b/src/main/java/org/upsmf/grievance/model/TicketCount.java new file mode 100644 index 0000000..49b4ef8 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/TicketCount.java @@ -0,0 +1,23 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class TicketCount { + + private Long userId; + private Long id; + private Long createdTicketCount; + private Long pinnedTicketCount; + private Long closedTicketCount; +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/model/TicketElastic.java b/src/main/java/org/upsmf/grievance/model/TicketElastic.java new file mode 100644 index 0000000..94f6c47 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/TicketElastic.java @@ -0,0 +1,31 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class TicketElastic { + + private String updatedTime; + private String description; + private Long helpdeskId; + private Long requestedBy; + private String createdTime; + private Long id; + private String status; + private Long total; + private Boolean pinnedTicket; + private String uT; + private String cT; + private String[] cc; + private String[] tags; +} diff --git a/src/main/java/org/upsmf/grievance/model/TicketTags.java b/src/main/java/org/upsmf/grievance/model/TicketTags.java new file mode 100644 index 0000000..b9f1098 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/TicketTags.java @@ -0,0 +1,24 @@ +package org.upsmf.grievance.model; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +public class TicketTags { + + private Long id; + private List<Long> tag; + private Long userId; + private boolean isActive = true; + private Long orgId; + +} diff --git a/src/main/java/org/upsmf/grievance/model/TicketsTagsList.java b/src/main/java/org/upsmf/grievance/model/TicketsTagsList.java new file mode 100644 index 0000000..6d64d8c --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/TicketsTagsList.java @@ -0,0 +1,20 @@ +package org.upsmf.grievance.model; + +import java.util.ArrayList; +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +public class TicketsTagsList { + private List<Ticket> ticket = new ArrayList<>(); + private List<Tags> tags = new ArrayList<>(); +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/model/Updates.java b/src/main/java/org/upsmf/grievance/model/Updates.java new file mode 100644 index 0000000..aac9b62 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/Updates.java @@ -0,0 +1,24 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class Updates { + + private Long ticketId; + private Long id; + private String upds; + private String createdDate; + private Long createdBy; + private boolean active; +} diff --git a/src/main/java/org/upsmf/grievance/model/User.java b/src/main/java/org/upsmf/grievance/model/User.java new file mode 100644 index 0000000..7ac1681 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/User.java @@ -0,0 +1,77 @@ +package org.upsmf.grievance.model; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +/** + * This class holds the information about the User's basic authentication along + * with Mail ID. + * + * @author Darshan Nagesh + * + */ +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +public class User { + + private Long id; + + private String username; + private byte[] img; + @JsonInclude(Include.NON_NULL) + private String password; + @JsonInclude(Include.NON_NULL) + private String phone; + + @JsonInclude(Include.NON_NULL) + private Long orgId; + + private String name; + private String imagePath; + + @JsonInclude(Include.NON_NULL) + private Boolean isActive; + + @JsonInclude(Include.NON_NULL) + private String authType; + + @JsonProperty("authToken") + @JsonInclude(Include.NON_NULL) + private String authToken; + + @JsonInclude(Include.NON_NULL) + private String createdDate; + + @JsonInclude(Include.NON_NULL) + private Long createdBy; + + @JsonInclude(Include.NON_NULL) + private String updatedDate; + + @JsonInclude(Include.NON_NULL) + private Long updatedBy; + + @JsonInclude(Include.NON_NULL) + private List<Role> roles; + + @JsonInclude(Include.NON_NULL) + private List<Action> actions; + + private List<Organization> organization; + private List<Helpdesk> helpdesk; + + private Boolean isAnonymous; + +} diff --git a/src/main/java/org/upsmf/grievance/model/UserAuthentication.java b/src/main/java/org/upsmf/grievance/model/UserAuthentication.java new file mode 100644 index 0000000..90dcb02 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/UserAuthentication.java @@ -0,0 +1,21 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class UserAuthentication { + + private long id; + private long userId; + private String authToken; +} diff --git a/src/main/java/org/upsmf/grievance/model/UserComment.java b/src/main/java/org/upsmf/grievance/model/UserComment.java new file mode 100644 index 0000000..bdfd702 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/UserComment.java @@ -0,0 +1,29 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class UserComment { + + private String text; + private LastModified lastModified; + private Long starRating; + private String reviewerLanguage; + private String device; + private Long androidOsVersion; + private Long appVersionCode; + private String appVersionName; + private Long thumbsUpCount; + private Long thumbsDownCount; + private DeviceMetadata deviceMetadata; +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/model/UserIdAndUserName.java b/src/main/java/org/upsmf/grievance/model/UserIdAndUserName.java new file mode 100644 index 0000000..e5b1f37 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/UserIdAndUserName.java @@ -0,0 +1,20 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class UserIdAndUserName { + + private Long id; + private String name; +} diff --git a/src/main/java/org/upsmf/grievance/model/UserRole.java b/src/main/java/org/upsmf/grievance/model/UserRole.java new file mode 100644 index 0000000..abd5bf7 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/UserRole.java @@ -0,0 +1,21 @@ +package org.upsmf.grievance.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +@Builder +public class UserRole { + + private long userId; + private long roleId; + +} diff --git a/src/main/java/org/upsmf/grievance/model/contract/RequestInfo.java b/src/main/java/org/upsmf/grievance/model/contract/RequestInfo.java new file mode 100644 index 0000000..b362034 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/contract/RequestInfo.java @@ -0,0 +1,44 @@ +package org.upsmf.grievance.model.contract; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +/** + * RequestInfo should be used to carry meta information about the requests to + * the server as described in the fields below. Some of this information will be + * returned back from the server as part of the ResponseInfo in the response + * body to ensure correlation + */ +@AllArgsConstructor +@EqualsAndHashCode +@Getter +@NoArgsConstructor +@Setter +@ToString +public class RequestInfo { + + private String apiId; + + private String ver; + + private Long ts; + + private String action; + + private String did; + + private String key; + + private String msgId; + + private String requesterId; + + private String authToken; + + private String correlationId; + +} diff --git a/src/main/java/org/upsmf/grievance/model/contract/RoleActionRequest.java b/src/main/java/org/upsmf/grievance/model/contract/RoleActionRequest.java new file mode 100644 index 0000000..f766592 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/contract/RoleActionRequest.java @@ -0,0 +1,45 @@ +/* + * Musti Backend API - User + * All services for User service + * + * OpenAPI spec version: 1.0 + * + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ + +package org.upsmf.grievance.model.contract; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * RoleActionRequest + */ + +public class RoleActionRequest { + + @JsonProperty("RequestInfo") + private RequestInfo requestInfo; + + @JsonProperty("RoleRequest") + private RoleRequest roleRequest; + + public RequestInfo getRequestInfo() { + return requestInfo; + } + + public void setRequestInfo(RequestInfo requestInfo) { + this.requestInfo = requestInfo; + } + + public RoleRequest getRoleRequest() { + return roleRequest; + } + + public void setRoleRequest(RoleRequest roleRequest) { + this.roleRequest = roleRequest; + } + +} diff --git a/src/main/java/org/upsmf/grievance/model/contract/RoleActionResponseInfo.java b/src/main/java/org/upsmf/grievance/model/contract/RoleActionResponseInfo.java new file mode 100644 index 0000000..4c54a52 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/contract/RoleActionResponseInfo.java @@ -0,0 +1,26 @@ +package org.upsmf.grievance.model.contract; + +import java.util.List; + +import org.upsmf.grievance.model.Action; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * ResponseInfo should be used to carry metadata information about the response + * from the server along with the requested data. + */ +@AllArgsConstructor +@Getter +@NoArgsConstructor +@Setter +public class RoleActionResponseInfo { + + private StatusInfo statusInfo; + + private List<Action> actions; + +} diff --git a/src/main/java/org/upsmf/grievance/model/contract/RoleRequest.java b/src/main/java/org/upsmf/grievance/model/contract/RoleRequest.java new file mode 100644 index 0000000..f33413d --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/contract/RoleRequest.java @@ -0,0 +1,39 @@ +package org.upsmf.grievance.model.contract; + +import java.util.ArrayList; +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +/** + * RoleRequest + */ +@AllArgsConstructor +@EqualsAndHashCode +@NoArgsConstructor +@ToString +public class RoleRequest { + + private Boolean enabled; + private List<Integer> roles = new ArrayList<>(); + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public List<Integer> getRoles() { + return roles; + } + + public void setRoles(List<Integer> roles) { + this.roles = roles; + } + +} diff --git a/src/main/java/org/upsmf/grievance/model/contract/StatusInfo.java b/src/main/java/org/upsmf/grievance/model/contract/StatusInfo.java new file mode 100644 index 0000000..0c7d063 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/contract/StatusInfo.java @@ -0,0 +1,30 @@ +package org.upsmf.grievance.model.contract; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +/** + * Status Information object will hold the run time status and the live response + * obtained from the server for the respective API Call. + */ +@AllArgsConstructor +@EqualsAndHashCode +@Getter +@NoArgsConstructor +@Setter +@ToString +public class StatusInfo { + + private Integer statusCode; + + private String statusMessage; + + private Long errorCode; + + private String errorMessage; + +} diff --git a/src/main/java/org/upsmf/grievance/model/contract/UserGetRequest.java b/src/main/java/org/upsmf/grievance/model/contract/UserGetRequest.java new file mode 100644 index 0000000..579f118 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/contract/UserGetRequest.java @@ -0,0 +1,23 @@ +package org.upsmf.grievance.model.contract; + +import java.util.List; + +/** + * + * @author Darshan Nagesh + * + */ + +public class UserGetRequest { + + private List<Long> userIdList; + + public List<Long> getUserIdList() { + return userIdList; + } + + public void setUserIdList(List<Long> userIdList) { + this.userIdList = userIdList; + } + +} diff --git a/src/main/java/org/upsmf/grievance/model/enums/AuthTypes.java b/src/main/java/org/upsmf/grievance/model/enums/AuthTypes.java new file mode 100644 index 0000000..f4ff265 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/enums/AuthTypes.java @@ -0,0 +1,34 @@ +package org.upsmf.grievance.model.enums; + +import org.apache.commons.lang3.StringUtils; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum AuthTypes { + + GOOGLE("1"), CUSTOM("2"); + + private String value; + + AuthTypes(final String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return StringUtils.capitalize(name()); + } + + @JsonCreator + public static AuthTypes fromValue(final String passedValue) { + for (final AuthTypes obj : AuthTypes.values()) { + if (String.valueOf(obj.value).equalsIgnoreCase(passedValue)) { + return obj; + } + } + return null; + } + +} diff --git a/src/main/java/org/upsmf/grievance/model/enums/PriorityLevels.java b/src/main/java/org/upsmf/grievance/model/enums/PriorityLevels.java new file mode 100644 index 0000000..2d269f3 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/enums/PriorityLevels.java @@ -0,0 +1,34 @@ +package org.upsmf.grievance.model.enums; + +import org.apache.commons.lang3.StringUtils; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public enum PriorityLevels { + + LOW("LOW"), MOD("MODERATE"), HIGH("HIGH"); + + private String value; + + PriorityLevels(final String value) { + this.value = value; + } + + @Override + @JsonValue + public String toString() { + return StringUtils.capitalize(name()); + } + + @JsonCreator + public static PriorityLevels fromValue(final String passedValue) { + for (final PriorityLevels obj : PriorityLevels.values()) { + if (String.valueOf(obj.value).equalsIgnoreCase(passedValue)) { + return obj; + } + } + return null; + } + +} diff --git a/src/main/java/org/upsmf/grievance/model/mapper/SqlDataMapper.java b/src/main/java/org/upsmf/grievance/model/mapper/SqlDataMapper.java new file mode 100644 index 0000000..d8e0ca0 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/mapper/SqlDataMapper.java @@ -0,0 +1,576 @@ +package org.upsmf.grievance.model.mapper; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.RowMapper; + +import org.upsmf.grievance.dto.HelpdeskDto; +import org.upsmf.grievance.dto.HelpdeskTypeDto; +import org.upsmf.grievance.dto.HelpdeskWorkflowDto; +import org.upsmf.grievance.dto.OrgUserRoleDto; +import org.upsmf.grievance.dto.TicketWorkflowDto; +import org.upsmf.grievance.model.Action; +import org.upsmf.grievance.model.ChecklistItem; +import org.upsmf.grievance.model.HelpDeskApp; +import org.upsmf.grievance.model.Helpdesk; +import org.upsmf.grievance.model.Organization; +import org.upsmf.grievance.model.Role; +import org.upsmf.grievance.model.Ticket; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.model.UserAuthentication; +import org.upsmf.grievance.util.SqlConstants; + +public class SqlDataMapper { + + public static final Logger LOGGER = LoggerFactory.getLogger(SqlDataMapper.class); + public static final String ERROR_LOG_FOREWORD = "Encountered an Exception while "; + + public User buildUserObjectFromResultSet(ResultSet rs) { + User user = new User(); + try { + user.setId(rs.getLong(SqlConstants.DbAttributes.ID)); + user.setUsername(rs.getString(SqlConstants.DbAttributes.USERNAME)); + user.setName(rs.getString(SqlConstants.DbAttributes.NAME)); + user.setOrgId(rs.getLong(SqlConstants.DbAttributes.ORGID)); + user.setIsActive(rs.getBoolean(SqlConstants.DbAttributes.ISACTIVE)); + user.setPassword(rs.getString(SqlConstants.DbAttributes.PSWRD)); + } catch (Exception e) { + + } + return user; + } + + public class UserMapper implements RowMapper<User> { + + @Override + public User mapRow(ResultSet rs, int rowNum) throws SQLException { + return buildUserObjectFromResultSet(rs); + } + + } + + public class UserRolesMapper implements RowMapper<User> { + private Map<Long, Role> roleMap = new HashMap<>(); + + public Map<Long, Role> getRoleMap() { + return roleMap; + } + + public void setRoleMap(Map<Long, Role> roleMap) { + this.roleMap = roleMap; + } + + @Override + public User mapRow(ResultSet rs, int rowNum) throws SQLException { + User user = buildUserObjectFromResultSet(rs); + if (!roleMap.containsKey(rs.getLong(SqlConstants.DbAttributes.ROLEID))) { + roleMap.put(rs.getLong(SqlConstants.DbAttributes.ROLEID), buildRoleObjectFromResultSet(rs)); + } + return user; + } + + } + + public class UserRolesActionsMapper implements RowMapper<User> { + private Map<Long, Role> roleMap = new HashMap<>(); + private Map<Long, Action> actionMap = new HashMap<>(); + + @Override + public User mapRow(ResultSet rs, int rowNum) throws SQLException { + User user = buildUserObjectFromResultSet(rs); + if (!getRoleMap().containsKey(rs.getLong(SqlConstants.DbAttributes.ROLEID))) { + getRoleMap().put(rs.getLong(SqlConstants.DbAttributes.ROLEID), buildRoleObjectFromResultSet(rs)); + } + if (!getActionMap().containsKey(rs.getLong(SqlConstants.DbAttributes.ACTIONID))) { + getActionMap().put(rs.getLong(SqlConstants.DbAttributes.ACTIONID), buildActionObjectFromResultSet(rs)); + } + return user; + } + + private Action buildActionObjectFromResultSet(ResultSet rs) { + Action action = new Action(); + try { + action.setId(rs.getLong(SqlConstants.DbAttributes.ACTIONID)); + action.setName(rs.getString(SqlConstants.DbAttributes.ACTIONNAME)); + action.setDisplayName(rs.getString(SqlConstants.DbAttributes.ACTIONDISPLAYNAME)); + action.setQueryParams(rs.getString(SqlConstants.DbAttributes.ACTIONQUERYPARAMS)); + action.setServiceCode(rs.getString(SqlConstants.DbAttributes.ACTIONSERVICECODE)); + action.setUrl(rs.getString(SqlConstants.DbAttributes.ACTIONURL)); + } catch (Exception e) { + + } + return action; + } + + public Map<Long, Role> getRoleMap() { + return roleMap; + } + + public void setRoleMap(Map<Long, Role> roleMap) { + this.roleMap = roleMap; + } + + public Map<Long, Action> getActionMap() { + return actionMap; + } + + public void setActionMap(Map<Long, Action> actionMap) { + this.actionMap = actionMap; + } + + } + + private Role buildRoleObjectFromResultSet(ResultSet rs) { + Role role = new Role(); + try { + role.setId(rs.getLong(SqlConstants.DbAttributes.ROLEID)); + role.setName(rs.getString(SqlConstants.DbAttributes.ROLENAME)); + role.setOrgId(rs.getLong(SqlConstants.DbAttributes.ROLEORGID)); + } catch (Exception e) { + + } + return role; + } + + public class UserDetailsMapper implements RowMapper<User> { + @Override + public User mapRow(ResultSet rs, int rowNum) throws SQLException { + User user = new User(); + user.setId(rs.getLong(SqlConstants.DbAttributes.ID)); + user.setUsername(rs.getString(SqlConstants.DbAttributes.USERNAME)); + user.setName(rs.getString(SqlConstants.DbAttributes.NAME)); + user.setPhone(rs.getString(SqlConstants.DbAttributes.PHONE)); + user.setImagePath(rs.getString(SqlConstants.DbAttributes.IMAGE_PATH)); + user.setIsActive(rs.getBoolean(SqlConstants.DbAttributes.IS_ACTIVE)); + user.setCreatedDate(rs.getString(SqlConstants.DbAttributes.CREATED_DATE)); + user.setUpdatedDate(rs.getString(SqlConstants.DbAttributes.UPDATED_DATE)); + return user; + } + } + + public class UserAuthenticationMapper implements RowMapper<UserAuthentication> { + @Override + public UserAuthentication mapRow(ResultSet rs, int rowNum) throws SQLException { + UserAuthentication userAuthentication = new UserAuthentication(); + userAuthentication.setId(rs.getLong(SqlConstants.DbAttributes.ID)); + userAuthentication.setUserId(rs.getLong(SqlConstants.DbAttributes.USERID)); + userAuthentication.setAuthToken(rs.getString(SqlConstants.DbAttributes.AUTH_TOKEN)); + return userAuthentication; + } + } + + public class UserRoleMapper implements RowMapper<Role> { + private Map<Long, Role> roleMap = new HashMap<>(); + + @Override + public Role mapRow(ResultSet rs, int rowNum) throws SQLException { + if (!getRoleMap().containsKey(rs.getLong(SqlConstants.DbAttributes.ROLEID))) { + Role role = new Role(); + role.setId(rs.getLong(SqlConstants.DbAttributes.ROLEID)); + role.setName(rs.getString(SqlConstants.DbAttributes.ROLENAME)); + getRoleMap().put(rs.getLong(SqlConstants.DbAttributes.ROLEID), role); + } + return null; + } + + public Map<Long, Role> getRoleMap() { + return roleMap; + } + + public void setRoleMap(Map<Long, Role> roleMap) { + this.roleMap = roleMap; + } + } + + public class RoleActionMapper implements RowMapper<Long> { + private Map<Long, List<String>> roleActionsMap = new HashMap<>(); + + @Override + public Long mapRow(ResultSet rs, int rowNum) throws SQLException { + if (getRoleActionsMap().containsKey(rs.getLong(SqlConstants.DbAttributes.ROLEID))) { + List<String> actionsList = getRoleActionsMap().get(rs.getLong(SqlConstants.DbAttributes.ROLEID)); + actionsList.add(rs.getString(SqlConstants.DbAttributes.ACTIONURL)); + } else { + List<String> actionsList = new ArrayList<>(); + actionsList.add(rs.getString(SqlConstants.DbAttributes.ACTIONURL)); + getRoleActionsMap().put(rs.getLong(SqlConstants.DbAttributes.ROLEID), actionsList); + } + return null; + } + + public Map<Long, List<String>> getRoleActionsMap() { + return roleActionsMap; + } + + public void setRoleActionsMap(Map<Long, List<String>> roleActionsMap) { + this.roleActionsMap = roleActionsMap; + } + } + + public class UserOrgMapper implements RowMapper<OrgUserRoleDto> { + @Override + public OrgUserRoleDto mapRow(ResultSet rs, int rowNum) throws SQLException { + OrgUserRoleDto dto = new OrgUserRoleDto(); + dto.setId(rs.getLong(SqlConstants.DbAttributes.ID)); + dto.setOrgId(rs.getLong(SqlConstants.DbAttributes.ORGID)); + dto.setUserId(rs.getLong(SqlConstants.DbAttributes.USERID)); + return dto; + } + } + + public class RolesUserMapper implements RowMapper<OrgUserRoleDto> { + private Map<Long, OrgUserRoleDto> userMap = new HashMap<>(); + Map<Long, List<Long>> userRolesMap = new HashMap<>(); + + @Override + public OrgUserRoleDto mapRow(ResultSet rs, int rowNum) throws SQLException { + if (userRolesMap.containsKey(rs.getLong(SqlConstants.DbAttributes.USERID))) { + List<Long> roleIds = userRolesMap.get(rs.getLong(SqlConstants.DbAttributes.USERID)); + roleIds.add(rs.getLong(SqlConstants.DbAttributes.ROLEID)); + } else { + OrgUserRoleDto dto = new OrgUserRoleDto(); + dto.setId(rs.getLong(SqlConstants.DbAttributes.ID)); + dto.setRoleId(rs.getLong(SqlConstants.DbAttributes.ROLEID)); + dto.setUserId(rs.getLong(SqlConstants.DbAttributes.USERID)); + List<Long> roleIds = new ArrayList<>(); + roleIds.add(rs.getLong(SqlConstants.DbAttributes.ROLEID)); + userRolesMap.put(rs.getLong(SqlConstants.DbAttributes.USERID), roleIds); + dto.setRoleIds(userRolesMap.get(rs.getLong(SqlConstants.DbAttributes.USERID))); + getUserMap().put(rs.getLong(SqlConstants.DbAttributes.USERID), dto); + } + return null; + } + + public Map<Long, OrgUserRoleDto> getUserMap() { + return userMap; + } + + public void setUserMap(Map<Long, OrgUserRoleDto> userMap) { + this.userMap = userMap; + } + } + + public class HelpDeskAppMapper implements RowMapper<HelpDeskApp> { + @Override + public HelpDeskApp mapRow(ResultSet rs, int rowNum) throws SQLException { + HelpDeskApp app = new HelpDeskApp(); + app.setAppId(rs.getLong(SqlConstants.DbAttributes.APPID)); + app.setHelpDeskId(rs.getLong(SqlConstants.DbAttributes.HELPDESKID)); + return app; + } + } + + public class HelpdeskUserMapper implements RowMapper<User> { + @Override + public User mapRow(ResultSet rs, int rowNum) throws SQLException { + User user = new User(); + user.setId(rs.getLong(SqlConstants.DbAttributes.ID)); + user.setName(rs.getString(SqlConstants.DbAttributes.NAME)); + user.setUsername(rs.getString(SqlConstants.DbAttributes.USERNAME)); + user.setImagePath(rs.getString(SqlConstants.DbAttributes.IMAGE_PATH)); + return user; + } + } + + public class UserHelpdeskMapper implements RowMapper<Helpdesk> { + @Override + public Helpdesk mapRow(ResultSet rs, int rowNum) throws SQLException { + Helpdesk helpdesk = new Helpdesk(); + helpdesk.setId(rs.getLong(SqlConstants.DbAttributes.ID)); + helpdesk.setName(rs.getString(SqlConstants.DbAttributes.NAME)); + helpdesk.setIsActive(rs.getBoolean(SqlConstants.DbAttributes.ISACTIVE)); + helpdesk.setColor(rs.getString(SqlConstants.DbAttributes.COLOR)); + return helpdesk; + } + } + + public class ChecklistItemMapper implements RowMapper<ChecklistItem> { + @Override + public ChecklistItem mapRow(ResultSet rs, int rowNum) throws SQLException { + ChecklistItem item = new ChecklistItem(); + item.setId(rs.getLong(SqlConstants.DbAttributes.CHECKLISTID)); + item.setItem(rs.getString(SqlConstants.DbAttributes.ITEMNAME)); + return item; + } + } + + public class TicketsChecklistItemMapper implements RowMapper<ChecklistItem> { + @Override + public ChecklistItem mapRow(ResultSet rs, int rowNum) throws SQLException { + ChecklistItem item = new ChecklistItem(); + item.setId(rs.getLong(SqlConstants.DbAttributes.ID)); + item.setItem(rs.getString(SqlConstants.DbAttributes.NAME)); + item.setChecked(rs.getBoolean(SqlConstants.DbAttributes.CHECKED)); + return item; + } + } + + public class TicketWorkFlowMapper implements RowMapper<TicketWorkflowDto> { + @Override + public TicketWorkflowDto mapRow(ResultSet rs, int rowNum) throws SQLException { + TicketWorkflowDto ticketWorkflowDto = new TicketWorkflowDto(); + ticketWorkflowDto.setId(rs.getLong(SqlConstants.DbAttributes.ID)); + ticketWorkflowDto.setName(rs.getString(SqlConstants.DbAttributes.NAME)); + ticketWorkflowDto.setStatus(rs.getBoolean(SqlConstants.DbAttributes.STATUS)); + ticketWorkflowDto.setTime(rs.getString(SqlConstants.DbAttributes.TIME)); + ticketWorkflowDto.setWorkFlowId(rs.getLong(SqlConstants.DbAttributes.WORKFLOWID)); + return ticketWorkflowDto; + } + } + + public class TicketWorkFlowMapperV2 implements RowMapper<TicketWorkflowDto> { + private Map<Long, List<TicketWorkflowDto>> ticketWorkflowMap = new HashMap<>(); + + @Override + public TicketWorkflowDto mapRow(ResultSet rs, int rowNum) throws SQLException { + if (getTicketWorkflowMap().containsKey(rs.getLong(SqlConstants.DbAttributes.TICKET_ID))) { + TicketWorkflowDto ticketWorkflowDto = new TicketWorkflowDto(); + ticketWorkflowDto.setId(rs.getLong(SqlConstants.DbAttributes.ID)); + ticketWorkflowDto.setName(rs.getString(SqlConstants.DbAttributes.NAME)); + ticketWorkflowDto.setStatus(rs.getBoolean(SqlConstants.DbAttributes.STATUS)); + ticketWorkflowDto.setTime(rs.getString(SqlConstants.DbAttributes.TIME)); + ticketWorkflowDto.setWorkFlowId(rs.getLong(SqlConstants.DbAttributes.WORKFLOWID)); + List<TicketWorkflowDto> ticketWorkflowList = getTicketWorkflowMap() + .get(rs.getLong(SqlConstants.DbAttributes.TICKET_ID)); + ticketWorkflowList.add(ticketWorkflowDto); + } else { + TicketWorkflowDto ticketWorkflowDto = new TicketWorkflowDto(); + ticketWorkflowDto.setId(rs.getLong(SqlConstants.DbAttributes.ID)); + ticketWorkflowDto.setName(rs.getString(SqlConstants.DbAttributes.NAME)); + ticketWorkflowDto.setStatus(rs.getBoolean(SqlConstants.DbAttributes.STATUS)); + ticketWorkflowDto.setTime(rs.getString(SqlConstants.DbAttributes.TIME)); + ticketWorkflowDto.setWorkFlowId(rs.getLong(SqlConstants.DbAttributes.WORKFLOWID)); + List<TicketWorkflowDto> ticketWorkflowList = new ArrayList<>(); + ticketWorkflowList.add(ticketWorkflowDto); + getTicketWorkflowMap().put(rs.getLong(SqlConstants.DbAttributes.TICKET_ID), ticketWorkflowList); + } + return null; + } + + public Map<Long, List<TicketWorkflowDto>> getTicketWorkflowMap() { + return ticketWorkflowMap; + } + + public void setTicketWorkflowMap(Map<Long, List<TicketWorkflowDto>> ticketWorkflowMap) { + this.ticketWorkflowMap = ticketWorkflowMap; + } + } + + public class HelpdeskRowRecordMapper implements RowMapper<HelpdeskDto> { + private Map<Long, HelpdeskDto> helpdeskMap = new HashMap<>(); + private Map<Long, List<Long>> helpdeskTypeMapping = new HashMap<>(); + private Map<Long, HelpdeskTypeDto> helpdeskTypeMap = new HashMap<>(); + private Map<Long, List<Long>> typeWorkflowMapping = new HashMap<>(); + private Map<Long, HelpdeskWorkflowDto> helpdeskWorkflowMap = new HashMap<>(); + + @Override + public HelpdeskDto mapRow(ResultSet rs, int rowNum) throws SQLException { + if (getHelpdeskMap().containsKey(rs.getLong(SqlConstants.DbAttributes.ID))) { + if (getHelpdeskTypeMap().containsKey(rs.getLong(SqlConstants.DbAttributes.HELPDESKTYPEID))) { + if (!getHelpdeskWorkflowMap().containsKey(rs.getLong(SqlConstants.DbAttributes.WORKFLOWSTAGEID))) { + HelpdeskWorkflowDto workflowDto = new HelpdeskWorkflowDto(); + workflowDto.setId(rs.getLong(SqlConstants.DbAttributes.WORKFLOWSTAGEID)); + workflowDto.setName(rs.getString(SqlConstants.DbAttributes.WORKFLOWSTAGE)); + workflowDto.setTypeId(rs.getLong(SqlConstants.DbAttributes.HELPDESKTYPEID)); + getHelpdeskWorkflowMap().put(rs.getLong(SqlConstants.DbAttributes.WORKFLOWSTAGEID), + workflowDto); + + List<Long> workflowStageIds = getTypeWorkflowMapping() + .get(rs.getLong(SqlConstants.DbAttributes.HELPDESKTYPEID)); + workflowStageIds.add(workflowDto.getId()); + getTypeWorkflowMapping().put(rs.getLong(SqlConstants.DbAttributes.HELPDESKTYPEID), + workflowStageIds); + } + } else { + HelpdeskWorkflowDto workflowDto = new HelpdeskWorkflowDto(); + workflowDto.setId(rs.getLong(SqlConstants.DbAttributes.WORKFLOWSTAGEID)); + workflowDto.setName(rs.getString(SqlConstants.DbAttributes.WORKFLOWSTAGE)); + workflowDto.setTypeId(rs.getLong(SqlConstants.DbAttributes.HELPDESKTYPEID)); + getHelpdeskWorkflowMap().put(rs.getLong(SqlConstants.DbAttributes.WORKFLOWSTAGEID), workflowDto); + + HelpdeskTypeDto typeDto = new HelpdeskTypeDto(); + typeDto.setId(rs.getLong(SqlConstants.DbAttributes.HELPDESKTYPEID)); + typeDto.setName(rs.getString(SqlConstants.DbAttributes.HELPDESKTYPE)); + typeDto.setHelpdeskId(rs.getLong(SqlConstants.DbAttributes.ID)); + getHelpdeskTypeMap().put(rs.getLong(SqlConstants.DbAttributes.HELPDESKTYPEID), typeDto); + + List<Long> workflowStageIds = new ArrayList<>(); + workflowStageIds.add(workflowDto.getId()); + getTypeWorkflowMapping().put(rs.getLong(SqlConstants.DbAttributes.HELPDESKTYPEID), + workflowStageIds); + + List<Long> typeIds = getHelpdeskTypeMapping().get(rs.getLong(SqlConstants.DbAttributes.ID)); + typeIds.add(typeDto.getId()); + getHelpdeskTypeMapping().put(rs.getLong(SqlConstants.DbAttributes.ID), typeIds); + + } + } else { + HelpdeskWorkflowDto workflowDto = new HelpdeskWorkflowDto(); + workflowDto.setId(rs.getLong(SqlConstants.DbAttributes.WORKFLOWSTAGEID)); + workflowDto.setName(rs.getString(SqlConstants.DbAttributes.WORKFLOWSTAGE)); + workflowDto.setTypeId(rs.getLong(SqlConstants.DbAttributes.HELPDESKTYPEID)); + getHelpdeskWorkflowMap().put(rs.getLong(SqlConstants.DbAttributes.WORKFLOWSTAGEID), workflowDto); + + HelpdeskTypeDto typeDto = new HelpdeskTypeDto(); + typeDto.setId(rs.getLong(SqlConstants.DbAttributes.HELPDESKTYPEID)); + typeDto.setName(rs.getString(SqlConstants.DbAttributes.HELPDESKTYPE)); + typeDto.setHelpdeskId(rs.getLong(SqlConstants.DbAttributes.ID)); + getHelpdeskTypeMap().put(rs.getLong(SqlConstants.DbAttributes.HELPDESKTYPEID), typeDto); + + HelpdeskDto dto = new HelpdeskDto(); + dto.setId(rs.getLong(SqlConstants.DbAttributes.ID)); + dto.setName(rs.getString(SqlConstants.DbAttributes.NAME)); + dto.setIsActive(rs.getBoolean(SqlConstants.DbAttributes.ISACTIVE)); + dto.setOrgId(rs.getLong(SqlConstants.DbAttributes.ORGID)); + dto.setAllowAllUsers(rs.getBoolean(SqlConstants.DbAttributes.ALLOW_ALL_USERS)); + getHelpdeskMap().put(rs.getLong(SqlConstants.DbAttributes.ID), dto); + dto.setColor(rs.getString(SqlConstants.DbAttributes.COLOR)); + dto.setDescription(rs.getString(SqlConstants.DbAttributes.DESCRIPTION)); + + List<Long> workflowStageIds = new ArrayList<>(); + workflowStageIds.add(workflowDto.getId()); + getTypeWorkflowMapping().put(rs.getLong(SqlConstants.DbAttributes.HELPDESKTYPEID), workflowStageIds); + + List<Long> typeIds = new ArrayList<>(); + typeIds.add(typeDto.getId()); + getHelpdeskTypeMapping().put(rs.getLong(SqlConstants.DbAttributes.ID), typeIds); + } + return null; + } + + public Map<Long, HelpdeskWorkflowDto> getHelpdeskWorkflowMap() { + return helpdeskWorkflowMap; + } + + public void setHelpdeskWorkflowMap(Map<Long, HelpdeskWorkflowDto> helpdeskWorkflowMap) { + this.helpdeskWorkflowMap = helpdeskWorkflowMap; + } + + public Map<Long, List<Long>> getHelpdeskTypeMapping() { + return helpdeskTypeMapping; + } + + public void setHelpdeskTypeMapping(Map<Long, List<Long>> helpdeskTypeMapping) { + this.helpdeskTypeMapping = helpdeskTypeMapping; + } + + public Map<Long, HelpdeskTypeDto> getHelpdeskTypeMap() { + return helpdeskTypeMap; + } + + public void setHelpdeskTypeMap(Map<Long, HelpdeskTypeDto> helpdeskTypeMap) { + this.helpdeskTypeMap = helpdeskTypeMap; + } + + public Map<Long, List<Long>> getTypeWorkflowMapping() { + return typeWorkflowMapping; + } + + public void setTypeWorkflowMapping(Map<Long, List<Long>> typeWorkflowMapping) { + this.typeWorkflowMapping = typeWorkflowMapping; + } + + public Map<Long, HelpdeskDto> getHelpdeskMap() { + return helpdeskMap; + } + + public void setHelpdeskMap(Map<Long, HelpdeskDto> helpdeskMap) { + this.helpdeskMap = helpdeskMap; + } + } + + public class TicketDetailsMapper implements RowMapper<Ticket> { + Map<Long, Ticket> ticketMap = new HashMap<>(); + + @Override + public Ticket mapRow(ResultSet rs, int rowNum) throws SQLException { + if (ticketMap.containsKey(rs.getLong(SqlConstants.DbAttributes.TICKETID))) { + Ticket ticket = ticketMap.get(rs.getLong(SqlConstants.DbAttributes.TICKETID)); + ticket.getCc().add(rs.getLong(SqlConstants.DbAttributes.TKTCCUSERID)); + List<ChecklistItem> checklistList = ticket.getChecklist(); + ChecklistItem checklistItem = new ChecklistItem(); + checklistItem.setId(rs.getLong(SqlConstants.DbAttributes.CHECKLISTID)); + checklistItem.setItem(rs.getString(SqlConstants.DbAttributes.CHECKLISTNAME)); + checklistItem.setChecked(rs.getBoolean(SqlConstants.DbAttributes.TCLCHECKED)); + checklistList.add(checklistItem); + } else { + Ticket ticket = new Ticket(); + ticket.setId(rs.getLong(SqlConstants.DbAttributes.TICKETID)); + ticket.setAppId(rs.getLong(SqlConstants.DbAttributes.APPID)); + ticket.setPinnedTicket(rs.getBoolean(SqlConstants.DbAttributes.PINNEDTICKET)); + ticket.setUpdatedTime(rs.getString(SqlConstants.DbAttributes.UPDATEDTIME)); + ticket.setUpdatedTimeTS(rs.getDate(SqlConstants.DbAttributes.UPDATEDTIME).getTime()); + ticket.setCreatedTime(rs.getString(SqlConstants.DbAttributes.CREATEDTIME)); + ticket.setCreatedTimeTS(rs.getDate(SqlConstants.DbAttributes.CREATEDTIME).getTime()); + ticket.setRate(rs.getInt(SqlConstants.DbAttributes.RATING)); + ticket.setMaxRating(rs.getInt(SqlConstants.DbAttributes.MAXRATING)); + ticket.setPriority(rs.getString(SqlConstants.DbAttributes.PRIORITY)); + ticket.setRequestedBy(rs.getLong(SqlConstants.DbAttributes.REQUESTEDBY)); + ticket.setDescription(rs.getString(SqlConstants.DbAttributes.DESCRIPTION)); + ticket.setNotes(rs.getString(SqlConstants.DbAttributes.NOTES)); + ticket.setActive(rs.getBoolean(SqlConstants.DbAttributes.ACTIVE)); + ticket.setSourceId(rs.getLong(SqlConstants.DbAttributes.SOURCEID)); + ticket.setHelpdeskId(rs.getLong(SqlConstants.DbAttributes.HELPDESKID)); + List<Long> ccList = new ArrayList<>(); + ccList.add(rs.getLong(SqlConstants.DbAttributes.TKTCCUSERID)); + ticket.setCc(ccList); + List<ChecklistItem> checklistList = new ArrayList<>(); + ChecklistItem checklistItem = new ChecklistItem(); + checklistItem.setId(rs.getLong(SqlConstants.DbAttributes.CHECKLISTID)); + checklistItem.setItem(rs.getString(SqlConstants.DbAttributes.CHECKLISTNAME)); + checklistItem.setChecked(rs.getBoolean(SqlConstants.DbAttributes.TCLCHECKED)); + checklistList.add(checklistItem); + ticket.setChecklist(checklistList); + ticketMap.put(rs.getLong(SqlConstants.DbAttributes.TICKETID), ticket); + } + return null; + } + } + + public class OrgMapper implements RowMapper<Organization> { + private Organization org = new Organization(); + List<User> adminList = new ArrayList<>(); + + @Override + public Organization mapRow(ResultSet rs, int rowNum) throws SQLException { + User orgAdmin = new User(); + if (rowNum == 0) { + getOrg().setId(rs.getLong(SqlConstants.DbAttributes.ID)); + getOrg().setOrgName(rs.getString(SqlConstants.DbAttributes.ORGNAME)); + getOrg().setUrl(rs.getString(SqlConstants.DbAttributes.URL)); + getOrg().setLogo(rs.getString(SqlConstants.DbAttributes.LOGO)); + getOrg().setEmailDomain(rs.getString(SqlConstants.DbAttributes.DOMAIN)); + getOrg().setOrgColor(rs.getString(SqlConstants.DbAttributes.COLOR)); + getOrg().setCreatedBy(rs.getLong(SqlConstants.DbAttributes.CREATEDBY)); + getOrg().setCreatedDate(rs.getString(SqlConstants.DbAttributes.CREATEDDATE)); + getOrg().setIsActive(rs.getBoolean(SqlConstants.DbAttributes.ISACTIVE)); + getOrg().setOrgDescription(rs.getString(SqlConstants.DbAttributes.DESCRIPTION)); + } + + orgAdmin.setId(rs.getLong(SqlConstants.DbAttributes.USERID)); + orgAdmin.setName(rs.getString(SqlConstants.DbAttributes.NAME)); + orgAdmin.setUsername(rs.getString(SqlConstants.DbAttributes.USERNAME)); + orgAdmin.setPhone(rs.getString(SqlConstants.DbAttributes.PHONE)); + adminList.add(orgAdmin); + getOrg().setAdminDetails(adminList); + return null; + + } + + public Organization getOrg() { + return org; + } + + public void setOrg(Organization org) { + this.org = org; + } + } + +} diff --git a/src/main/java/org/upsmf/grievance/repository/ElasticSearchRepository.java b/src/main/java/org/upsmf/grievance/repository/ElasticSearchRepository.java new file mode 100644 index 0000000..77d86fe --- /dev/null +++ b/src/main/java/org/upsmf/grievance/repository/ElasticSearchRepository.java @@ -0,0 +1,95 @@ +package org.upsmf.grievance.repository; + +import java.io.IOException; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.apache.http.HttpHost; +import org.elasticsearch.action.search.MultiSearchRequest; +import org.elasticsearch.action.search.MultiSearchResponse; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestHighLevelClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpServerErrorException; +import org.springframework.web.client.RestTemplate; + +import org.upsmf.grievance.model.TemplateVersion; + +/** + * This Repository Class is used to perform the transactions of storing the data + * into the Elastic Search Repository + * + * @author Darshan Nagesh + * + */ +@Service +public class ElasticSearchRepository { + + private static final String ERROR = "Error : %s"; + String daoImplMarker = "AuroraESRepoMarker"; + Marker marker = MarkerFactory.getMarker(daoImplMarker); + + public static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchRepository.class); + + private final RestTemplate restTemplate; + private RestHighLevelClient client; + private String elasticHost; + private int elasticPort; + private static final String REST_SCHEME = "http"; + + public ElasticSearchRepository(RestTemplate restTemplate, + @Value("${services.esindexer.host.name}") String elasticHost, + @Value("${services.esindexer.host.port}") int elasticPort) { + this.elasticHost = elasticHost; + this.elasticPort = elasticPort; + this.restTemplate = restTemplate; + this.client = getClientForElastic(); + } + + private RestHighLevelClient getClientForElastic() { + return new RestHighLevelClient(RestClient.builder(new HttpHost(elasticHost, elasticPort, REST_SCHEME))); + } + + public Boolean saveTemplate(TemplateVersion templateVersion, String url, HttpHeaders headers) { + ResponseEntity<Map> map = null; + try { + map = restTemplate.exchange(url, HttpMethod.PUT, new HttpEntity<>(templateVersion, headers), Map.class); + } catch (final HttpClientErrorException httpClientErrorException) { + LOGGER.error(String.format(ERROR, httpClientErrorException)); + } catch (HttpServerErrorException httpServerErrorException) { + LOGGER.error(String.format(ERROR, httpServerErrorException)); + } catch (Exception e) { + LOGGER.error(String.format(ERROR, e.getMessage())); + } + return (map != null && map.getStatusCode() != null + && ((map.getStatusCode() == HttpStatus.OK) || (map.getStatusCode() == HttpStatus.CREATED))); + } + + public MultiSearchResponse executeMultiSearchRequest(SearchRequest searchRequest) { + MultiSearchRequest multiRequest = new MultiSearchRequest(); + MultiSearchResponse response = null; + if (!StringUtils.isBlank(marker.toString()) && !StringUtils.isBlank(searchRequest.source().toString())) { + LOGGER.info("ES Query is : {}", searchRequest.source()); + } + multiRequest.add(searchRequest); + try { + response = client.multiSearch(multiRequest); + } catch (IOException e) { + LOGGER.error(String.format(marker.toString(), " Encountered an error while connecting : %s", e)); + LOGGER.error(String.format(marker.toString(), " Error Message to report : %s", e.getMessage())); + } + return response; + } +} diff --git a/src/main/java/org/upsmf/grievance/service/ApplicationService.java b/src/main/java/org/upsmf/grievance/service/ApplicationService.java new file mode 100644 index 0000000..3183053 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/ApplicationService.java @@ -0,0 +1,53 @@ +package org.upsmf.grievance.service; + +import java.util.List; + +import org.upsmf.grievance.model.App; +import org.upsmf.grievance.model.ServiceRequest; +import org.upsmf.grievance.model.StatusIdMap; +import org.upsmf.grievance.model.User; + +/** + * @author Darshan Nagesh + * + */ +public interface ApplicationService { + + public App createApp(App app, User user); + + /** + * This method will return List of applications + * + * @param id + * Long + * @param keyword + * String + * @param user + * User + * @return List<App> + */ + public List<App> getApp(Long id, String keyword, User user); + + /** + * This method will map an application to a helpdesk + * + * @param statusIdMap + * StatusIdMap + * @return boolean + */ + public boolean mapAppsToHelpdesk(StatusIdMap statusIdMap); + + /** + * This method will invoke the DAO method to fetch the master data of Service + * Request types available in the application + * + * @return List<ServiceRequest> + * + */ + public List<ServiceRequest> getServiceRequests(); + + public List<App> getAppIdAndAppObject(); + + public Object getApp(Long orgId); + +} diff --git a/src/main/java/org/upsmf/grievance/service/HelpdeskService.java b/src/main/java/org/upsmf/grievance/service/HelpdeskService.java new file mode 100644 index 0000000..b293c8f --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/HelpdeskService.java @@ -0,0 +1,45 @@ +package org.upsmf.grievance.service; + +import java.util.List; + +import org.upsmf.grievance.dto.HelpdeskDto; +import org.upsmf.grievance.model.HelpDeskApp; +import org.upsmf.grievance.model.Helpdesk; +import org.upsmf.grievance.model.User; + +public interface HelpdeskService { + + /** + * This method will add or update helpdesk of an organization + * + * @param helpdesk + * Helpdesk + * @return boolean + */ + boolean createUpdateHelpdesk(HelpdeskDto helpdeskDto, User user); + + /** + * This method gives all the active helpdesk of an organization + * + * @param orgId + * Long + * @return List<Helpdesk> + */ + List<HelpdeskDto> getHelpdesk(Long orgId); + + List<HelpdeskDto> getHelpdeskById(Long orgId, Long id); + + boolean configureHelpdesk(HelpdeskDto helpdeskDto, User user); + + List<Long> getHelpdeskAdmins(Long id); + + boolean addUpdateHelpdeskAdmins(Helpdesk helpdesk, User user); + + List<HelpDeskApp> getAppIdAndHelpDeskId(); + + public List<Helpdesk> getHelpdeskObjectFromHelpdeskId(); + + List<User> getUsersForHelpeskId(Long id); + + void getHelpdeskAdminUser(List<HelpdeskDto> helpdeskList); +} diff --git a/src/main/java/org/upsmf/grievance/service/RoleActionService.java b/src/main/java/org/upsmf/grievance/service/RoleActionService.java new file mode 100644 index 0000000..b532820 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/RoleActionService.java @@ -0,0 +1,61 @@ +package org.upsmf.grievance.service; + +import java.util.List; +import java.util.Map; + +import org.upsmf.grievance.model.Role; + +/** + * This interface handles the service layer of business operation logic + * implementation for all the Role and its Action related transactions + * + * @author Darshan Nagesh + * + */ +public interface RoleActionService { + + /** + * This method receives the request with details related to a new role and + * passes on to the DAO layer to save in DB + * + * @param role + * @return + */ + Role saveRole(Role role); + + /** + * This method receives the request with details related to a new role and + * passes on to the DAO layer to update the role information in DB + * + * @param role + * @return + */ + Role updateRole(Role role); + + /** + * This method fetches all the Roles available in the system + * + * @param fetchData + * @return + */ + List<Role> getAllRoles(Long orgId); + + /** + * This method receives the ID from Controller to pass on the same to DAO to + * fetch the Role Object from Database This returns the Role Object for the + * respective Role ID + * + * @param role + * @return + */ + String findById(Role role); + + List<Role> getAllOrgRoles(); + + void initializeActions(); + + void intializeRolesAndActions(); + + Map<Long, List<String>> getAllActionsForRoles(List<Long> roleIds); + +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/service/SuperAdminService.java b/src/main/java/org/upsmf/grievance/service/SuperAdminService.java new file mode 100644 index 0000000..8b8d4cb --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/SuperAdminService.java @@ -0,0 +1,34 @@ +package org.upsmf.grievance.service; + +import java.util.List; + +import org.upsmf.grievance.model.Organization; +import org.upsmf.grievance.model.StatusIdMap; + +public interface SuperAdminService { + + List<Organization> getAllOrganization(); + + Organization addOrganization(Organization organization); + + boolean updateOrganizationById(Organization organization); + + Organization getOrganizationById(Long id); + + boolean deleteOrganization(Organization organization); + + boolean addAdmin(long userId); + + boolean removeAdmin(long userId); + + /** + * This method will map an application to an organization + * + * @param statusIdMap + * @return + */ + boolean mapAppsToOrg(StatusIdMap statusIdMap); + + List<Organization> getOrganizationByUserId(Long userId); + +} diff --git a/src/main/java/org/upsmf/grievance/service/TagService.java b/src/main/java/org/upsmf/grievance/service/TagService.java new file mode 100644 index 0000000..13a0b9f --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/TagService.java @@ -0,0 +1,19 @@ +package org.upsmf.grievance.service; + +import java.util.List; + +import org.upsmf.grievance.dto.TicketTagDto; +import org.upsmf.grievance.model.Tags; +import org.upsmf.grievance.model.TicketsTagsList; + +public interface TagService { + + public boolean saveTags(TicketTagDto ticketTagDto, Long id); + + public TicketsTagsList getAllOrgTags(Long orgId); + + public List<Tags> getAllTicketTags(Long id); + + public TicketsTagsList getHelpdeskTags(Long id, Long userId); + +} diff --git a/src/main/java/org/upsmf/grievance/service/TicketService.java b/src/main/java/org/upsmf/grievance/service/TicketService.java new file mode 100644 index 0000000..4cf25d7 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/TicketService.java @@ -0,0 +1,82 @@ +package org.upsmf.grievance.service; + +import java.util.List; +import java.util.Map; + +import org.springframework.web.multipart.MultipartFile; + +import org.upsmf.grievance.dto.TicketTypeDto; +import org.upsmf.grievance.model.ActivityLog; +import org.upsmf.grievance.model.Analytics; +import org.upsmf.grievance.model.TemplateVersion; +import org.upsmf.grievance.model.Ticket; +import org.upsmf.grievance.model.TicketCount; +import org.upsmf.grievance.model.TicketElastic; +import org.upsmf.grievance.model.Updates; +import org.upsmf.grievance.model.User; + +/** + * This interface contains all the ticket related service + * + * @author Juhi Agarwal + * + */ +public interface TicketService { + + Ticket addTicket(Ticket ticket); + + Long getTemplatesVersion(); + + TemplateVersion getTemplates(); + + boolean configureTemplates(TemplateVersion templateVersion); + + boolean updateTicketBasic(MultipartFile file, Ticket ticket); + + /** + * Get Method which receives the User Object and the Ticket ID from the + * Controller and calls the respective DAO Method to get the Ticket Response for + * the specific Ticket which is being requested for + * + * @param user + * @param id + * @return + */ + Ticket getTicketsById(User user, Long id); + + List<Ticket> getAllTicketsByAppId(Long appId); + + Boolean updateNotesToTicket(Ticket ticket); + + Boolean addUpdateUpdatesToTicket(Updates update); + + List<Updates> getUpdatesForTicket(Long id); + + boolean updateTicketType(TicketTypeDto ticketTypeDto, Long userId); + + boolean updateTicketStatus(Ticket ticket); + + boolean updateTicketChecklist(Ticket ticket); + + boolean sendRepliesToReviews(Updates updates); + + List<ActivityLog> getActivityLogsPerTicket(Long id); + + List<Ticket> getFeedBacksFromAuroraSdk(); + + List<Ticket> keepOnlyCreatedAndCopiedToTickets(Long userId, List<Ticket> ticketList); + + Map<String, Long> getTicketsCountPerMonthPerUser(Analytics analytics); + + List<ActivityLog> getActivityLogsPerUser(Long id); + + List<TicketElastic> getTicketDetailsByHelpdeskId(Ticket ticket); + + List<Ticket> getAllTicketsByUserId(Long id); + + boolean attachmentUpload(MultipartFile file, Ticket ticket); + + TicketCount getNoOfTickets(Long userId); + + boolean pinTicket(Ticket ticket); +} diff --git a/src/main/java/org/upsmf/grievance/service/UserService.java b/src/main/java/org/upsmf/grievance/service/UserService.java new file mode 100644 index 0000000..1791c07 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/UserService.java @@ -0,0 +1,147 @@ +package org.upsmf.grievance.service; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import org.upsmf.grievance.dto.ChangePasswordDto; +import org.upsmf.grievance.dto.LoginDto; +import org.upsmf.grievance.dto.OrgUserRoleDto; +import org.upsmf.grievance.dto.UserDto; +import org.upsmf.grievance.model.Access; +import org.upsmf.grievance.model.Action; +import org.upsmf.grievance.model.HelpDeskApp; +import org.upsmf.grievance.model.Role; +import org.upsmf.grievance.model.User; + + +public interface UserService { + + /** + * This method receives the List of Role IDs from the controller and passes the + * same to DAO to fetch the List of Actions allowed and configured for the Role + * ID + * + * @param roleID + * @return + */ + public List<Action> findAllActionsByRoleID(List<Integer> roleID); + + /** + * This method receives the existing User object to update the details in the + * Database for the respective User + * + * @param file + * + * @param user + * @return + */ + User update(MultipartFile file, User user); + + /** + * This method supports pagination and fetches the User Profiles for the + * respective search criteria Search can happen based on Page Number, Number of + * Records, Active status of the user Keyword to search the user and also based + * on the Roles Assigned to the User + * + * @param pageNumber + * @param numberOfRecords + * @param orgId + * @param roles + * @return + */ + List<User> findAll(Long orgId); + + /** + * This method receives the String Username to fetch the respective User record + * from the Database + * + * @param username + * @return + */ + User findOne(String username, Boolean withRoles, Boolean withActions); + + /** + * This method receives the Long ID to fetch the respective User Profile from + * the database + * + * @param id + * @return + */ + User findById(Long id); + + /** + * This method receives the User ID and find the corresponding roles for the + * User ID and lists out the Roles as a response + * + * @param userId + * @return + */ + public List<Role> findAllRolesByUser(Long userId); + + /** + * This method receives the User ID and then fetches the Role ID for the same + * With the help of Role ID, it fetches the corresponding Actions which are + * allowed and mapped. As a result, this responds Action object + * + * @param userId + * @return + */ + + /** + * This method receives the User Role Object. For a User ID and each Role ID in + * the list, this method creates a mapping so that User Role Mapping is added + * + * @param userRole + * @return + */ + Boolean mapUserToRole(User user); + + Long checkUserNameExists(String username); + + String uploadFile(MultipartFile file, long userId); + + Long getNumberOfUsers(Long role, Boolean active); + + Long getNumberOfRoles(); + + Boolean invalidateToken(String authToken); + + Boolean findUserByToken(String authToken); + + Long fetchAuthTokenReference(String authToken); + + Boolean checkUserTokenExists(Long userId, String deviceToken); + + User updateUserImage(User profile); + + public LoginDto login(UserDto userDto); + + public boolean forgotPassword(UserDto userDto); + + public boolean changePassword(ChangePasswordDto changePasswordDto); + + User save(MultipartFile file, long authUserId, User user); + + public List<OrgUserRoleDto> getAllOrgUsers(); + + public List<OrgUserRoleDto> getAllUserRoles(); + + List<HelpDeskApp> getAppIdAndHelpDeskId(); + + public List<User> getUserIdAndUserName(); + + String getFile(Long userId) throws IOException; + + public Map<String, Object> getUserInfoObjects(String userId); + + Long saveAnonymousUser(User user); + + public void getReviews() throws IOException; + + public Access getReviewConfig(Long id); + +} diff --git a/src/main/java/org/upsmf/grievance/service/impl/ApplicationServiceImpl.java b/src/main/java/org/upsmf/grievance/service/impl/ApplicationServiceImpl.java new file mode 100644 index 0000000..21d39ca --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/impl/ApplicationServiceImpl.java @@ -0,0 +1,69 @@ +package org.upsmf.grievance.service.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.upsmf.grievance.dao.ApplicationDao; +import org.upsmf.grievance.model.App; +import org.upsmf.grievance.model.ServiceRequest; +import org.upsmf.grievance.model.StatusIdMap; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.service.ApplicationService; +import org.upsmf.grievance.util.Constants; +import org.upsmf.grievance.util.ProjectUtil; +import org.upsmf.grievance.util.Sql; + +@Service(value = Constants.APP_SERVICE) +public class ApplicationServiceImpl implements ApplicationService { + + @Autowired + private ApplicationDao applicationDao; + + @Override + public App createApp(App app, User user) { + if (app.getId() != null) { + return applicationDao.updateApp(app, user); + } + return applicationDao.createApp(app, user); + } + + @Override + public List<App> getApp(Long id, String keyword, User user) { + List<App> app = new ArrayList<>(); + if (id != null) { + return applicationDao.getApp(id); + } else if (!ProjectUtil.isObjectNull(user.getRoles()) && user.getOrgId() == null) { + if (user.getRoles().get(0).getName().equalsIgnoreCase(Sql.Common.SUPER_ADMIN)) { + return applicationDao.getAllApps(); + } + + } else if (user.getOrgId() != null) { + return applicationDao.getAppsByOrgId(user.getOrgId()); + } + return app; + } + + @Override + public boolean mapAppsToHelpdesk(StatusIdMap statusIdMap) { + return applicationDao.mapAppsToHelpdesk(statusIdMap); + } + + @Override + public List<ServiceRequest> getServiceRequests() { + return applicationDao.getServiceRequests(); + } + + @Override + public List<App> getAppIdAndAppObject() { + return applicationDao.getAppIdAndAppObject(); + } + + @Override + public List<App> getApp(Long orgId) { + return applicationDao.getAppsByOrgId(orgId); + } + +} diff --git a/src/main/java/org/upsmf/grievance/service/impl/HelpdeskServiceImpl.java b/src/main/java/org/upsmf/grievance/service/impl/HelpdeskServiceImpl.java new file mode 100644 index 0000000..9cbcca5 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/impl/HelpdeskServiceImpl.java @@ -0,0 +1,213 @@ +package org.upsmf.grievance.service.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.upsmf.grievance.dao.HelpdeskDao; +import org.upsmf.grievance.dao.SuperAdminDao; +import org.upsmf.grievance.dto.HelpdeskDto; +import org.upsmf.grievance.dto.HelpdeskTypeDto; +import org.upsmf.grievance.dto.HelpdeskWorkflowDto; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.model.App; +import org.upsmf.grievance.model.ChecklistItem; +import org.upsmf.grievance.model.HelpDeskApp; +import org.upsmf.grievance.model.Helpdesk; +import org.upsmf.grievance.model.S3Config; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.model.mapper.SqlDataMapper.HelpdeskRowRecordMapper; +import org.upsmf.grievance.service.HelpdeskService; +import org.upsmf.grievance.util.S3FileManager; + +@Service +public class HelpdeskServiceImpl implements HelpdeskService { + + private static final String ENCOUNTERED_AN_EXCEPTION = "Encountered an Exception : %s"; + + private static final String USERPROFILE = "userprofile"; + + public static final Logger LOGGER = LoggerFactory.getLogger(HelpdeskServiceImpl.class); + + @Autowired + private HelpdeskDao helpdeskDao; + + @Autowired + private SuperAdminDao superAdminDao; + + @Override + public boolean createUpdateHelpdesk(HelpdeskDto helpdeskDto, User user) { + Helpdesk helpdesk = new Helpdesk(helpdeskDto); + helpdesk.setOrgId(helpdesk.getOrgId()); + helpdesk.setCreatedBy(user.getId()); + helpdesk.setUpdatedBy(user.getId()); + Boolean status = helpdeskDao.createUpdateHelpdesk(helpdesk); + if (status && helpdeskDto.getId() == null) { + helpdeskDto.setId(helpdesk.getId()); + configureHelpdesk(helpdeskDto, user); + } + return status; + } + + @Override + public List<HelpdeskDto> getHelpdesk(Long orgId) { + return helpdeskDao.getAllHelpdesks(orgId); + } + + @Override + public List<HelpdeskDto> getHelpdeskById(Long orgId, Long id) { + List<HelpdeskDto> helpdeskList = new ArrayList<>(); + try { + HelpdeskRowRecordMapper mapper = helpdeskDao.getHelpdeskForId(orgId, id); + createHelpdeskListFromRowRecords(mapper, helpdeskList); + getAppsForHelpdesk(helpdeskList); + helpdeskList = helpdeskDao.getHelpdeskAdminUser(helpdeskList); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return helpdeskList; + } + + public void getAppsForHelpdesk(List<HelpdeskDto> helpdeskList) { + MasterDataManager.getHelpdeskIdFromAppId(); + try { + for (HelpdeskDto dto : helpdeskList) { + List<App> appList = new ArrayList<>(); + dto.setApps(appList); + List<Long> appIds = MasterDataManager.getAppIdsForHelpdesk(dto.getId()); + if (!appIds.isEmpty()) { + LOGGER.info("app idis : {}", appIds); + } + for (Long appId : appIds) { + App app = MasterDataManager.getAppFromAppId(appId); + if (appId > 0) { + LOGGER.info("app idis : {}", appIds); + } + if (app != null) { + dto.getApps().add(app); + } + } + } + } catch (Exception e) { + + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + } + + public void getUsersForHelpdesk(List<HelpdeskDto> helpdeskList) { + try { + for (HelpdeskDto dto : helpdeskList) { + List<User> userList = helpdeskDao.getUsersForHelpeskId(dto.getId()); + userList = getImageUrl(userList); + dto.setUsers(userList); + } + } catch (Exception e) { + + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + } + + public void getAdminForHelpdesk(List<HelpdeskDto> helpdeskList) { + try { + for (HelpdeskDto dto : helpdeskList) { + List<User> userList = helpdeskDao.getAdminForHelpeskId(dto.getId()); + userList = getImageUrl(userList); + dto.setAdmins(userList); + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + } + + private List<User> getImageUrl(List<User> userList) { + S3Config s3values = superAdminDao.getS3Access(); + for (int i = 0; i < userList.size(); i++) { + if (userList.get(i).getImagePath() != null && !userList.get(i).getImagePath().isEmpty() + && userList.get(i).getImagePath().contains(USERPROFILE)) { + String url = null; + url = S3FileManager.getPreSignedURL(s3values, userList.get(i).getImagePath()); + userList.get(i).setImagePath(url); + } + } + return userList; + } + + public void createHelpdeskListFromRowRecords(HelpdeskRowRecordMapper mapper, List<HelpdeskDto> helpdeskList) { + Iterator<Entry<Long, HelpdeskDto>> itr = mapper.getHelpdeskMap().entrySet().iterator(); + while (itr.hasNext()) { + Entry<Long, HelpdeskDto> entry = itr.next(); + Long helpdeskId = entry.getKey(); + HelpdeskDto helpdeskDto = entry.getValue(); + List<Long> typeIds = mapper.getHelpdeskTypeMapping().get(helpdeskId); + List<HelpdeskTypeDto> helpdeskTypes = new ArrayList<>(); + for (Long typeId : typeIds) { + List<HelpdeskWorkflowDto> workflowStages = new ArrayList<>(); + HelpdeskTypeDto helpdeskTypeDto = mapper.getHelpdeskTypeMap().get(typeId); + List<Long> workflowStageIds = mapper.getTypeWorkflowMapping().get(helpdeskTypeDto.getId()); + for (Long workflowStageId : workflowStageIds) { + HelpdeskWorkflowDto workflowStageDto = mapper.getHelpdeskWorkflowMap().get(workflowStageId); + workflowStages.add(workflowStageDto); + } + helpdeskTypeDto.setWorkflowStages(workflowStages); + List<ChecklistItem> checklistItems = helpdeskDao.getChecklistItemsForHelpdesk(helpdeskDto.getId(), + helpdeskTypeDto.getId()); + helpdeskTypeDto.setChecklistItems(checklistItems); + helpdeskTypes.add(helpdeskTypeDto); + } + helpdeskDto.setTypes(helpdeskTypes); + helpdeskList.add(helpdeskDto); + } + } + + @Override + public boolean configureHelpdesk(HelpdeskDto helpdeskDto, User user) { + if (helpdeskDto.getId() != null) { + helpdeskDao.deleteTypeForHelpdesk(helpdeskDto.getId()); + List<HelpdeskTypeDto> typeDtoList = helpdeskDto.getTypes(); + for (HelpdeskTypeDto typeDto : typeDtoList) { + helpdeskDao.deleteWorkflowForHelpdeskType(typeDto.getId()); + helpdeskDao.deleteChecklistForHelpdeskType(helpdeskDto.getId(), typeDto.getId()); + helpdeskDao.addTypeForHelpdesk(typeDto, helpdeskDto.getId()); + helpdeskDao.addWorkflowForHelpdeskType(typeDto); + helpdeskDao.addChecklistForHelpdeskType(typeDto, helpdeskDto.getId()); + } + } + return true; + } + + @Override + public List<Long> getHelpdeskAdmins(Long id) { + return helpdeskDao.getHelpdeskAdmins(id); + } + + @Override + public boolean addUpdateHelpdeskAdmins(Helpdesk helpdesk, User user) { + return helpdeskDao.addUpdateHelpdeskAdmins(helpdesk); + } + + @Override + public List<HelpDeskApp> getAppIdAndHelpDeskId() { + return helpdeskDao.getAppIdAndHelpDeskId(); + } + + @Override + public List<Helpdesk> getHelpdeskObjectFromHelpdeskId() { + return helpdeskDao.getHelpdeskObjectFromHelpdeskId(); + } + + @Override + public List<User> getUsersForHelpeskId(Long id) { + return helpdeskDao.getUsersForHelpeskId(id); + } + + @Override + public void getHelpdeskAdminUser(List<HelpdeskDto> helpdeskList) { + helpdeskDao.getHelpdeskAdminUser(helpdeskList); + } +} diff --git a/src/main/java/org/upsmf/grievance/service/impl/RoleActionServiceImpl.java b/src/main/java/org/upsmf/grievance/service/impl/RoleActionServiceImpl.java new file mode 100644 index 0000000..cfd4af8 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/impl/RoleActionServiceImpl.java @@ -0,0 +1,62 @@ +package org.upsmf.grievance.service.impl; + +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.upsmf.grievance.dao.RoleDao; +import org.upsmf.grievance.model.Role; +import org.upsmf.grievance.service.RoleActionService; +import org.upsmf.grievance.util.Constants; + +@Service(value = Constants.ROLE_ACTION_SERVICE) +public class RoleActionServiceImpl implements RoleActionService { + + @Autowired + private RoleDao roleDao; + + @Override + public Role saveRole(Role role) { + return roleDao.saveRole(role); + } + + @Override + public Role updateRole(Role role) { + return roleDao.updateRole(role); + } + + @Override + public List<Role> getAllRoles(Long orgId) { + return roleDao.getAllRoles(orgId); + } + + @Override + public String findById(Role role) { + return roleDao.findById(role); + } + + @Override + public List<Role> getAllOrgRoles() { + return roleDao.getAllOrgRoles(); + } + + @Override + public void initializeActions() { + roleDao.initializeActions(); + + } + + @Override + public void intializeRolesAndActions() { + roleDao.intializeRolesAndActions(); + + } + + @Override + public Map<Long, List<String>> getAllActionsForRoles(List<Long> roleIds) { + return roleDao.getAllActionsForRoles(roleIds); + } + +} diff --git a/src/main/java/org/upsmf/grievance/service/impl/SuperAdminServiceImpl.java b/src/main/java/org/upsmf/grievance/service/impl/SuperAdminServiceImpl.java new file mode 100644 index 0000000..3f4ea37 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/impl/SuperAdminServiceImpl.java @@ -0,0 +1,102 @@ +package org.upsmf.grievance.service.impl; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.upsmf.grievance.dao.SuperAdminDao; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.model.Organization; +import org.upsmf.grievance.model.StatusIdMap; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.service.SuperAdminService; +import org.upsmf.grievance.util.Constants; +import org.upsmf.grievance.util.JsonKey; +import org.upsmf.grievance.util.SendMail; + +@Service(value = Constants.SUPER_ADMIN_SERVICE) +public class SuperAdminServiceImpl implements SuperAdminService { + public static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class); + + @Autowired + private SuperAdminDao superAdminDao; + + @Override + public List<Organization> getAllOrganization() { + return superAdminDao.getAllOrganization(); + } + + @Override + public Organization addOrganization(Organization organization) { + return superAdminDao.addOrganization(organization); + } + + @Override + public boolean updateOrganizationById(Organization organization) { + + return superAdminDao.updateOrganizationById(organization); + } + + @Override + public Organization getOrganizationById(Long id) { + return superAdminDao.getOrganizationByIdV2(id); + } + + @Override + public boolean deleteOrganization(Organization organization) { + + return superAdminDao.deleteOrganization(organization); + } + + @Override + public boolean addAdmin(long userId) { + boolean value = superAdminDao.addAdmin(userId); + if (value) { + User user = superAdminDao.userDetailsByUserId(userId); + user.setOrgId(MasterDataManager.getUserOrgMap().get(userId)); + String email = user.getUsername(); + Map<String, String> keyValue = new HashMap<>(); + keyValue.put(JsonKey.FIRST_NAME, user.getName()); + keyValue.put(JsonKey.LAST_NAME, user.getUsername()); + keyValue.put(JsonKey.ORGNAME, MasterDataManager.getOrgIdAndOrgNameMap().get(user.getOrgId())); + LOGGER.info(MasterDataManager.getOrgIdAndOrgNameMap().get(user.getOrgId())); + String[] emails = email.split(","); + SendMail.sendMail(keyValue, emails, Constants.NEW_ADMIN, Constants.ADD_ADMIN_VM_FILE); + } + return value; + } + + @Override + public boolean removeAdmin(long userId) { + boolean value = superAdminDao.removeAdmin(userId); + if (value) { + User user = superAdminDao.userDetailsByUserId(userId); + user.setOrgId(MasterDataManager.getUserOrgMap().get(userId)); + String email = user.getUsername(); + Map<String, String> keyValue = new HashMap<>(); + keyValue.put(JsonKey.FIRST_NAME, user.getName()); + keyValue.put(JsonKey.ORGNAME, MasterDataManager.getOrgIdAndOrgNameMap().get(user.getOrgId())); + LOGGER.info(MasterDataManager.getOrgIdAndOrgNameMap().get(user.getOrgId())); + String[] emails = email.split(","); + SendMail.sendMail(keyValue, emails, Constants.DELETE_ADMIN, Constants.DELETE_ADMIN_VM_FILE); + } + return value; + } + + @Override + public boolean mapAppsToOrg(StatusIdMap statusIdMap) { + return superAdminDao.mapAppsToOrg(statusIdMap); + + } + + @Override + public List<Organization> getOrganizationByUserId(Long userId) { + + return superAdminDao.getOrganizationByUser(userId); + } +} diff --git a/src/main/java/org/upsmf/grievance/service/impl/TagServiceImpl.java b/src/main/java/org/upsmf/grievance/service/impl/TagServiceImpl.java new file mode 100644 index 0000000..fa3a4a7 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/impl/TagServiceImpl.java @@ -0,0 +1,53 @@ +package org.upsmf.grievance.service.impl; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.upsmf.grievance.dao.TagDao; +import org.upsmf.grievance.dto.TicketTagDto; +import org.upsmf.grievance.model.Tags; +import org.upsmf.grievance.model.TicketsTagsList; +import org.upsmf.grievance.service.TagService; +import org.upsmf.grievance.util.Constants; + +@Service(value = Constants.TAG_SERVICE) +public class TagServiceImpl implements TagService { + + @Autowired + private TagDao tagDao; + + @Override + public boolean saveTags(TicketTagDto ticketTagDto, Long id) { + for (Tags tag : ticketTagDto.getTags()) { + Tags savedTag = tagDao.getTagByName(tag.getName().trim(), id); + if (savedTag == null) { + tag.setId(tagDao.addTag(id, tag)); + } else { + tag.setId(savedTag.getId()); + } + } + return tagDao.addTicketTags(ticketTagDto.getId(), ticketTagDto.getTags()); + } + + @Override + public TicketsTagsList getAllOrgTags(Long orgId) { + TicketsTagsList list = new TicketsTagsList(); + list.setTags(tagDao.getAllTags(orgId)); + return list; + } + + @Override + public List<Tags> getAllTicketTags(Long id) { + return tagDao.getAllTicketTags(id); + } + + @Override + public TicketsTagsList getHelpdeskTags(Long id, Long userId) { + TicketsTagsList list = new TicketsTagsList(); + list.setTags(tagDao.getHelpdeskTags(id, userId)); + return list; + } + +} diff --git a/src/main/java/org/upsmf/grievance/service/impl/TicketServiceImpl.java b/src/main/java/org/upsmf/grievance/service/impl/TicketServiceImpl.java new file mode 100644 index 0000000..3925cd5 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/impl/TicketServiceImpl.java @@ -0,0 +1,262 @@ +package org.upsmf.grievance.service.impl; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.apache.tomcat.util.codec.binary.Base64; +import org.elasticsearch.action.search.MultiSearchResponse; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import com.google.gson.Gson; +import org.upsmf.grievance.dao.TicketDao; +import org.upsmf.grievance.dto.TicketTypeDto; +import org.upsmf.grievance.model.ActivityLog; +import org.upsmf.grievance.model.Analytics; +import org.upsmf.grievance.model.TemplateVersion; +import org.upsmf.grievance.model.Ticket; +import org.upsmf.grievance.model.TicketCount; +import org.upsmf.grievance.model.TicketElastic; +import org.upsmf.grievance.model.Updates; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.repository.ElasticSearchRepository; +import org.upsmf.grievance.service.TicketService; +import org.upsmf.grievance.util.Constants; + +@Service(value = Constants.TICKET_SERVICE) +public class TicketServiceImpl implements TicketService { + + @Autowired + private TicketDao ticketDao; + + private final String indexServiceHost; + private final String userName; + private final String password; + private final String templatesIndexName; + private final String templatesDocumentType; + private static final String AUTHORIZATION = "Authorization"; + private static final String BASIC_AUTH = "Basic %s"; + public static final Logger LOGGER = LoggerFactory.getLogger(TicketServiceImpl.class); + Gson gson = new Gson(); + + public TicketServiceImpl(@Value("${services.esindexer.host}") String indexServiceHost, + @Value("${services.esindexer.username}") String userName, + @Value("${services.esindexer.password}") String password, + @Value("${es.templates.index.name}") String templatesIndexName, + @Value("${es.templates.document.type}") String templatesDocumentType, TicketDao ticketDao) { + this.indexServiceHost = indexServiceHost; + this.userName = userName; + this.password = password; + this.templatesIndexName = templatesIndexName; + this.templatesDocumentType = templatesDocumentType; + this.ticketDao = ticketDao; + + } + + @Autowired + private ElasticSearchRepository elasticRepository; + + @Override + public Ticket addTicket(Ticket ticket) { + return ticketDao.addTicket(ticket); + } + + @Override + public Long getTemplatesVersion() { + return ticketDao.getTemplatesVersion(); + } + + @Override + public boolean configureTemplates(TemplateVersion templateVersion) { + Long versionOfTemplate = new Date().getTime(); + if (versionOfTemplate > 0) { + LOGGER.info("New Version of the Template : {}", versionOfTemplate); + } + if (null == templateVersion.getVersion()) { + templateVersion.setVersion(versionOfTemplate); + } + String url = String.format("%s%s/%s/%s", this.indexServiceHost, templatesIndexName, templatesDocumentType, + templateVersion.getVersion()); + HttpHeaders headers = getHttpHeaders(); + if (templateVersion.getVersion() > 0) { + LOGGER.info("Template Version to be added to ES : {}", templateVersion.getVersion()); + } + if (!StringUtils.isBlank(url)) { + LOGGER.info("URL to invoke : {}", url); + } + Boolean saveStatus = elasticRepository.saveTemplate(templateVersion, url, headers); + ticketDao.updateTemplateVersion(versionOfTemplate); + return saveStatus; + } + + @Override + public TemplateVersion getTemplates() { + MultiSearchResponse response = executeTemplatesElasticQuery(); + return templateResponseTranslator(response); + } + + private MultiSearchResponse executeTemplatesElasticQuery() { + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().size(1000); + return elasticRepository.executeMultiSearchRequest( + new SearchRequest(templatesIndexName).types(templatesDocumentType).source(searchSourceBuilder)); + } + + private TemplateVersion templateResponseTranslator(MultiSearchResponse templateResponse) { + + SearchResponse searchResponse = templateResponse.getResponses()[0].getResponse(); + List<TemplateVersion> templateVersionList = new ArrayList<>(); + if (searchResponse != null) { + for (SearchHit hit : searchResponse.getHits()) { + TemplateVersion templateVersion = gson.fromJson(hit.getSourceAsString(), TemplateVersion.class); + templateVersionList.add(templateVersion); + } + } + return Collections.max(templateVersionList, Comparator.comparing(template -> template.getVersion())); + } + + /** + * A helper method to create the headers for Rest Connection with UserName and + * Password + * + * @return HttpHeaders + */ + private HttpHeaders getHttpHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.add(AUTHORIZATION, getBase64Value(userName, password)); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + headers.setContentType(MediaType.APPLICATION_JSON); + return headers; + } + + /** + * Helper Method to create the Base64Value for headers + * + * @param userName + * @param password + * @return + */ + public String getBase64Value(String userName, String password) { + String authString = String.format("%s:%s", userName, password); + byte[] encodedAuthString = Base64.encodeBase64(authString.getBytes(StandardCharsets.US_ASCII)); + return String.format(BASIC_AUTH, new String(encodedAuthString)); + } + + @Override + public boolean updateTicketBasic(MultipartFile file, Ticket ticket) { + + return ticketDao.updateTicketBasic(file, ticket); + } + + @Override + public Ticket getTicketsById(User user, Long id) { + return ticketDao.getTicketsById(user.getId(), id); + } + + @Override + public List<Ticket> getAllTicketsByAppId(Long appId) { + return ticketDao.getAllTicketsByAppId(appId); + } + + @Override + public Boolean updateNotesToTicket(Ticket ticket) { + return ticketDao.updateNotesToTicket(ticket.getRequestedBy(), ticket.getId(), ticket.getNotes()); + } + + @Override + public Boolean addUpdateUpdatesToTicket(Updates update) { + return ticketDao.addUpdateUpdatesToTicket(update); + } + + @Override + public List<Updates> getUpdatesForTicket(Long id) { + return ticketDao.getUpdatesForTicket(id); + } + + @Override + public boolean updateTicketType(TicketTypeDto ticketTypeDto, Long userId) { + return ticketDao.updateTicketType(ticketTypeDto, userId); + } + + @Override + public boolean updateTicketStatus(Ticket ticket) { + return ticketDao.updateTicketStatus(ticket); + } + + @Override + public boolean updateTicketChecklist(Ticket ticket) { + return ticketDao.updateTicketChecklist(ticket); + } + + @Override + public List<ActivityLog> getActivityLogsPerTicket(Long id) { + return ticketDao.getActivityLogsPerTicket(id); + } + + @Override + public List<ActivityLog> getActivityLogsPerUser(Long id) { + + return ticketDao.getActivityLogsPerUser(id); + } + + @Override + public List<Ticket> getAllTicketsByUserId(Long id) { + return new ArrayList<>(); + } + + @Override + public List<TicketElastic> getTicketDetailsByHelpdeskId(Ticket ticket) { + return ticketDao.getTicketDetailsByHelpdeskId(ticket); + } + + @Override + public List<Ticket> keepOnlyCreatedAndCopiedToTickets(Long userId, List<Ticket> ticketList) { + return ticketDao.keepOnlyCreatedAndCopiedToTickets(userId, ticketList); + } + + @Override + public boolean pinTicket(Ticket ticket) { + return ticketDao.pinTicket(ticket); + } + + @Override + public TicketCount getNoOfTickets(Long userId) { + return ticketDao.getNoOfTickets(userId); + } + + @Override + public Map<String, Long> getTicketsCountPerMonthPerUser(Analytics analytics) { + return ticketDao.getTicketsCountPerMonthPerUser(analytics); + } + + @Override + public boolean attachmentUpload(MultipartFile file, Ticket ticket) { + return ticketDao.attachmentUpload(file, ticket); + } + + @Override + public List<Ticket> getFeedBacksFromAuroraSdk() { + return ticketDao.getFeedBacksFromAuroraSdk(); + } + + @Override + public boolean sendRepliesToReviews(Updates updates) { + return ticketDao.sendRepliesToReviews(updates); + } + +} diff --git a/src/main/java/org/upsmf/grievance/service/impl/UserServiceImpl.java b/src/main/java/org/upsmf/grievance/service/impl/UserServiceImpl.java new file mode 100644 index 0000000..32153be --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/impl/UserServiceImpl.java @@ -0,0 +1,522 @@ +package org.upsmf.grievance.service.impl; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; +import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload; +import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.JsonFactory; +import com.google.api.client.json.jackson2.JacksonFactory; +import org.upsmf.grievance.dao.HelpdeskDao; +import org.upsmf.grievance.dao.RoleDao; +import org.upsmf.grievance.dao.SuperAdminDao; +import org.upsmf.grievance.dao.UserDao; +import org.upsmf.grievance.dto.ChangePasswordDto; +import org.upsmf.grievance.dto.LoginDto; +import org.upsmf.grievance.dto.OrgUserRoleDto; +import org.upsmf.grievance.dto.UserDto; +import org.upsmf.grievance.executor.MasterDataManager; +import org.upsmf.grievance.model.Access; +import org.upsmf.grievance.model.Action; +import org.upsmf.grievance.model.CommonDataModel; +import org.upsmf.grievance.model.HelpDeskApp; +import org.upsmf.grievance.model.Role; +import org.upsmf.grievance.model.S3Config; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.model.mapper.SqlDataMapper.UserRoleMapper; +import org.upsmf.grievance.service.UserService; +import org.upsmf.grievance.util.Constants; +import org.upsmf.grievance.util.JsonKey; +import org.upsmf.grievance.util.ProjectUtil; +import org.upsmf.grievance.util.S3FileManager; +import org.upsmf.grievance.util.SendMail; +import org.upsmf.grievance.util.Sql; + +@Service(value = Constants.USER_SERVICE) +public class UserServiceImpl implements UserDetailsService, UserService { + private static final String ENCOUNTERED_AN_EXCEPTION = "Encountered an Exception : %s"; + + private static final String USERPROFILE = "userprofile"; + + public static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class); + + @Autowired + private UserDao userDao; + + @Autowired + JdbcTemplate jdbcTemplate; + + @Autowired + RoleDao roleDao; + + @Autowired + SuperAdminDao superAdminDao; + + @Autowired + HelpdeskDao helpdeskDao; + + @Value("${image.source.aws}") + private Boolean imageSource; + + @Override + public List<Action> findAllActionsByRoleID(List<Integer> roleID) { + List<Action> completeActions = new ArrayList<>(); + for (int roleid : roleID) { + completeActions.addAll(userDao.findAllActionsByRoleID(roleid)); + } + return completeActions; + } + + @Override + public Map<String, Object> getUserInfoObjects(String userId) { + User user = userDao.findByUsername(userId, Boolean.FALSE, Boolean.FALSE); + if (user == null) { + throw new UsernameNotFoundException("Invalid username or password."); + } + Map<String, Object> userInfoObjectMap = new HashMap<>(); + userInfoObjectMap.put("User", user); + userInfoObjectMap.put("UserDetails", new org.springframework.security.core.userdetails.User(user.getUsername(), + user.getPassword(), getAuthority())); + return userInfoObjectMap; + } + + @Override + public UserDetails loadUserByUsername(String userId) { + User user = userDao.findByUsername(userId, Boolean.FALSE, Boolean.FALSE); + if (user == null) { + throw new UsernameNotFoundException("Invalid username or password."); + } + return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), + getAuthority()); + } + + private List<SimpleGrantedAuthority> getAuthority() { + return Arrays.asList(new SimpleGrantedAuthority("ROLE_ADMIN")); + } + + @Override + public User findOne(String username, Boolean withRoles, Boolean withActions) { + return userDao.findByUsername(username, withRoles, withActions); + } + + @Override + public User findById(Long id) { + User user = new User(); + List<Role> roleList = new ArrayList<>(); + try { + List<User> mapper = userDao.findOne(id); + if (!ProjectUtil.isObjectListNullOrEmpty(mapper)) { + user = mapper.get(0); + MasterDataManager.getAllUserRoles(); + if (user != null) { + List<Long> roles = MasterDataManager.getUserRoleListMap().get(user.getId()); + for (int i = 0; i < roles.size(); i++) { + roleList.add(MasterDataManager.getRoleMap().get(roles.get(i))); + } + user.setRoles(roleList); + user.setOrgId(jdbcTemplate.queryForObject(Sql.Common.GET_ORG_ID_BY_USER_ID, new Object[] { id }, + Long.class)); + user.setOrganization(superAdminDao.getOrganizationByUser(id)); + user.setHelpdesk(helpdeskDao.getHelpdeskByUserId(id)); + String image = jdbcTemplate.queryForObject(Sql.Common.GET_IMAGE_PATH, new Object[] { id }, + String.class); + user.setImagePath(image); + setUserImage(user); + return user; + } + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return null; + } + + private void setUserImage(User user) { + if (!StringUtils.isBlank(user.getImagePath())) { + try { + if (user.getImagePath().contains(USERPROFILE)) { + S3Config s3values = superAdminDao.getS3Access(); + String url = null; + url = S3FileManager.getPreSignedURL(s3values, user.getImagePath()); + user.setImagePath(url); + } else { + String data = getFile(user.getId()); + user.setImagePath(data); + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + } + } + + @Override + public User save(MultipartFile file, long authUserId, User user) { + user.setUpdatedBy(authUserId); + user = userDao.insertIntoUser(user); + if (user.getId() == 0) { + return null; + } else { + LOGGER.info("userId: {}", user.getId()); + } + UserDto userDto = new UserDto(); + userDto.setName(user.getName()); + userDto.setUsername(user.getUsername()); + userDto.setId(user.getId()); + userDao.customAuth(userDto); + + boolean userRoleInsert = userDao.mapUserToRole(user.getId(), user.getRoles()); + if (!userRoleInsert && user.getId() > 0 && user.getId() != null) { + LOGGER.info("Inserting into tt_user_role FAILED for user: {}", user.getId()); + } + + if (user.getOrgId() != null) { + boolean userCompInsert = superAdminDao.mapUserToOrg(user.getId(), user.getOrgId().intValue()); + if (!userCompInsert && user.getId() > 0 && user.getId() != null) { + LOGGER.info("Inserting into tt_user_comp FAILED for user: {}", user.getId()); + } else { + MasterDataManager.getUserOrgMap().put(user.getId(), user.getOrgId()); + } + } + + insertProfilePicture(file, user); + return user; + } + + @Override + public Long saveAnonymousUser(User user) { + Long userId = checkUserNameExists(user.getUsername()); + if (userId == 0) { + userId = userDao.insertAnonymousUser(user); + if (userId == 0) { + return null; + } else if (userId > 0 && userId != null) { + LOGGER.info("userId: {}", userId); + } + if (user.getOrgId() != null) { + boolean userCompInsert = superAdminDao.mapUserToOrg(userId, user.getOrgId().intValue()); + if (!userCompInsert && userId > 0 && userId != null) { + LOGGER.info("Inserting into tt_user_comp FAILED for user: {}", userId); + } + } + } + return userId; + } + + private void insertProfilePicture(MultipartFile file, User user) { + try { + if (imageSource) { + if (user.getImagePath() != null) { + String value = getImagePathValue(user); + pathValue(user, value); + } + } else { + String value = null; + if (!file.isEmpty()) { + value = uploadFile(file, user.getId()); + } + jdbcTemplate.update(Sql.INSERT_PROFILE_PICTURE, new Object[] { value, user.getId() }); + } + } catch (Exception e) { + + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + } + + private void pathValue(User user, String value) { + try { + jdbcTemplate.update(Sql.INSERT_PROFILE_PICTURE, new Object[] { value, user.getId() }); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + } + + @Override + public User update(MultipartFile file, User user) { + try { + if (imageSource) { + if (user.getImagePath() != null) { + String value = null; + value = getImagePathValue(user); + user.setImagePath(value); + } + } else if (!file.isEmpty()) { + String value = uploadFile(file, user.getId()); + user.setImagePath(value); + } + } catch (Exception e) { + + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return userDao.update(user); + } + + private String getImagePathValue(User user) { + String value = null; + try { + Long organization = MasterDataManager.getUserOrgMap().get(user.getId()); + value = S3FileManager.filePath(user.getImagePath(), USERPROFILE, user.getId(), organization); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return value; + } + + @Override + public List<Role> findAllRolesByUser(Long userId) { + UserRoleMapper mapper = userDao.findAllRolesByUser(userId); + List<Role> roleList = new ArrayList<>(); + Iterator<Entry<Long, Role>> itr = mapper.getRoleMap().entrySet().iterator(); + while (itr.hasNext()) { + roleList.add(itr.next().getValue()); + } + return roleList; + } + + @Override + public Boolean mapUserToRole(User user) { + return userDao.mapUserToRole(user.getId(), user.getRoles()); + } + + @Override + public User updateUserImage(User profile) { + return userDao.updateUserImage(profile); + } + + @Override + public Long checkUserNameExists(String username) { + return userDao.checkUserNameExists(username); + } + + @Override + public boolean changePassword(ChangePasswordDto changePasswordDto) { + if (changePasswordDto.getOldPass().equals(changePasswordDto.getNewPass())) { + + return true; + } + LOGGER.info("Entering Dao from service"); + return userDao.changePassword(changePasswordDto); + } + + @Override + public boolean forgotPassword(UserDto userDto) { + Map<String, String> keyValue = new HashMap<>(); + boolean response = false; + long userId = userDao.forgotPassword(userDto); + if (userId > 0) { + response = true; + String[] emails = { userDto.getUsername() }; + String randomPassword = ProjectUtil.getRandomStringVal(); + LOGGER.info(randomPassword); + userDao.saveForgotPassword(userId, randomPassword); + keyValue.put(JsonKey.PSWRD, randomPassword); + SendMail.sendMail(keyValue, emails, Constants.PSWORD_REGENERATED, Constants.FORGOT_PSWORD_VM_FILE); + } + return response; + } + + @Override + public String uploadFile(MultipartFile file, long userId) { + return null; + } + + @Override + public String getFile(Long userId) throws IOException { + try { + String imagePath = null; + List<User> u = userDao.findOne(userId); + if (!ProjectUtil.isObjectNull(u.get(0))) { + imagePath = u.get(0).getImagePath(); + } + if (!ProjectUtil.isStringNullOrEmpty(imagePath)) { + Path path = Paths.get(Constants.UPLOADED_FOLDER + imagePath); + readb(path); + } + return "http://aurora-images.tarento.com/images" + imagePath; + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return null; + } + + private void readb(Path path) { + try { + Files.readAllBytes(path); + } catch (final IOException e) { + + } + } + + @Override + public Long getNumberOfUsers(Long role, Boolean active) { + return userDao.getNumberOfUsers(role, active); + } + + @Override + public Long getNumberOfRoles() { + return userDao.getNumberOfRoles(); + } + + @Override + public Boolean invalidateToken(String authToken) { + return userDao.invalidateToken(authToken); + } + + @Override + public Boolean findUserByToken(String authToken) { + return userDao.findUserByToken(authToken); + } + + @Override + public Boolean checkUserTokenExists(Long userId, String deviceToken) { + return userDao.checkUserTokenExists(userId, deviceToken); + } + + @Override + public Long fetchAuthTokenReference(String authToken) { + return userDao.fetchAuthTokenReference(authToken); + } + + @Override + public LoginDto login(UserDto userDto) { + User userObject = userDao.getUserDetailsByEmail(userDto.getUsername()); + if (userObject == null) { + LOGGER.info("getUserDetailsByEmail method is returning Null"); + return null; + } + userDto.setUsername(userObject.getUsername()); + userDto.setOrgId(userObject.getOrgId()); + userDto.setAuthType(userObject.getAuthType()); + userDto.setId(userObject.getId()); + userDao.getAuthDomain(userDto); + if (authenticate(userDto)) { + LoginDto loginData = userDao.login(userDto); + if (!StringUtils.isBlank(userObject.getImagePath()) && userObject.getImagePath().contains(USERPROFILE)) { + S3Config s3values = superAdminDao.getS3Access(); + String url = S3FileManager.getPreSignedURL(s3values, userObject.getImagePath()); + loginData.setImageUrl(url); + } + for (int i = 0; i < loginData.getRoles().size(); i++) { + if (loginData.getRoles().get(i).getId() == Constants.ADMIN_ID) { + boolean check = userDao.getFirstAdminsOfOrg(userObject.getId()); + if (check && userDao.onBoardingCheck(userObject.getOrgId(), userObject.getId())) { + return loginData; + } + break; + } + } + return loginData; + } + return null; + + } + + private boolean authenticate(UserDto userDto) { + if (userDto.getGoogleEmail() != null) { + return googleAuth(userDto); + } + CommonDataModel authDomainMap; + authDomainMap = userDao.getAuthDomain(userDto); + if (authDomainMap == null) { + LOGGER.error("Method Name: authenticate, Message: authDomainMap is Null"); + return false; + } + switch (authDomainMap.getDescription()) { + case Constants.GOOGLE_AUTH: + return googleAuth(userDto); + case Constants.CUSTOM_AUTH: + return customAuth(userDto); + default: + return false; + } + } + + private boolean customAuth(UserDto userDto) { + return userDao.isPasswordMatch(userDto.getId(), userDto.getPassword()); + } + + private boolean googleAuth(UserDto userDto) { + try { + final HttpTransport transport = new NetHttpTransport(); + final JsonFactory jsonFactory = new JacksonFactory(); + String email = null; + GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory) + .setAudience(Collections.singletonList(userDto.getGoogleClientId())).build(); + + GoogleIdToken idToken = verifier.verify(userDto.getGoogleIdToken()); + if (idToken != null) { + Payload payload = idToken.getPayload(); + email = payload.getEmail(); + } + if (StringUtils.isNotBlank(email) && email.trim().equalsIgnoreCase(userDto.getGoogleEmail())) { + return true; + } + } catch (Exception e) { + LOGGER.error(e.getMessage()); + } + return false; + + } + + @Override + public List<User> findAll(Long orgId) { + return userDao.findAll(orgId); + } + + @Override + public List<OrgUserRoleDto> getAllOrgUsers() { + return userDao.getAllOrgUsers(); + } + + @Override + public List<OrgUserRoleDto> getAllUserRoles() { + return userDao.getAllUserRoles(); + } + + @Override + public List<HelpDeskApp> getAppIdAndHelpDeskId() { + return userDao.getAppIdAndHelpDeskId(); + } + + @Override + public List<User> getUserIdAndUserName() { + return userDao.getUserIdAndUserName(); + } + + @Override + public void getReviews() throws IOException { + userDao.getReviews(); + } + + @Override + public Access getReviewConfig(Long id) { + return userDao.getReviewConfig(id); + } + +} \ No newline at end of file diff --git a/src/main/java/org/upsmf/grievance/util/Constants.java b/src/main/java/org/upsmf/grievance/util/Constants.java new file mode 100644 index 0000000..29744f1 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/Constants.java @@ -0,0 +1,342 @@ +package org.upsmf.grievance.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Constants { + + private static final String FEEDBACK_BY_NAME = "feedbackByName"; + private static final String TYPE = "type"; + private static final String TOTAL = "total"; + /** + * Header and Request Parameters + */ + public static final long ACCESS_TOKEN_VALIDITY_SECONDS = (long) 30 * 24 * 60 * 60; + public static final String REVIEWS2 = "/reviews?translationLanguage=en"; + public static final String HTTPS_WWW_GOOGLEAPIS_COM_ANDROIDPUBLISHER_V3_APPLICATIONS = "https://www.googleapis.com/androidpublisher/v3/applications/"; + public static final String REVIEWSPEC_JSON = "/reviewspec.json"; + public static final String ACCESSTOKENSPEC_JSON = "/accesstokenspec.json"; + public static final String SIGNING_KEY = "devglan123r"; + public static final String JWT_ISSUER = "http://devglan.com"; + public static final String JWT_GRANTED_AUTHORITY = "ROLE_ADMIN"; + public static final String TOKEN_PREFIX = "Bearer "; + public static final String HEADER_STRING = "Authorization"; + public static final String HEADER_APPLICATION_JSON = "application/json"; + public static final String ERROR_CODE = "errorCode"; + public static final String ERROR_FIELD = "errorField"; + public static final String ERROR_MESSAGE_CODE = "errorMessageCode"; + public static final String ERROR_MESSAGE_VALUE = "common.error."; + public static final String SUCCESS_CODE = "successCode"; + public static final String ERROR_MESSAGE = "errorMessage"; + public static final String SUCCESS_MESSAGE = "successMessage"; + public static final String AUTH_HEADER = "Authorization"; + public static final String PARAMETERS = "parameters"; + + public enum ELK_OPERATION { + SAVE, UPDATE, DELETE; + } + + public final class RequestParams { + private RequestParams() { + super(); + } + + public static final String USER_INFO = "UserInfo"; + public static final String ID = "id"; + public static final String HELPDESK_ID = "helpdeskId"; + public static final String APP_ID = "appId"; + } + + /** + * Query Parameters and Response Parameters + */ + public static final String USER_INFO_HEADER = "x-user-info"; + public static final String SUCCESS = "success"; + public static final String ASC = "asc"; + public static final String DESC = "desc"; + public static final String TRUE = "true"; + public static final String FALSE = "false"; + public static final String STRING_BLANK = ""; + public static final String COMMA_SPACE_SEPARATOR = ", "; + public static final String DATE = "date"; + public static final String QUERY_ALERT_SUBJECT = "Query Alert!!"; + public static final String SCHEDULER_ALERT_SUBJECT = "Scheduler Alert!!"; + public static final String STRING_SPACE = " "; + public static final String STRING_HYPEN = "-"; + public static final String NEW_MESSAGE = "New"; + public static final String READ_MESSAGE = "Read"; + public static final String DELETE_MESSAGE = "Delete"; + public static final String SEND_MESSAGE = "Send"; + public static final String FILE_TYPE = "PDF,DOC,TXT,JPG,JPEG,PNG,GIF,AAC,MP3,MP4"; + public static final String IMAGE_FILE_TYPE = "JPG,JPEG,PNG,GIF"; + public static final String FCM_API_URL = "fcm.api.url"; + public static final String FCM_API_KEY = "fcm.api.key"; + + /** + * URLs and Paths + */ + public static final String UPLOADED_FOLDER = "/usr/grievance"; + public static final String ATTACHMENT_FOLDER = "C:\\Users\\Juhi Agarwal\\git\\grievance-desk-core\\public\\attachments"; + + /** + * Status Code and Messages + */ + public static final int UNAUTHORIZED_ID = 401; + public static final int SUCCESS_ID = 200; + public static final int FAILURE_ID = 320; + public static final String UNAUTHORIZED = "Invalid credentials. Please try again."; + public static final String PROCESS_FAIL = "Process failed, Please try again."; + + public enum userRole { + SUPERADMIN, ORGADMIN, ENDUSER; + } + + /** + * Indicators or Classifiers + */ + public static final String ROLE = "ROLE"; + public static final String ORG = "ORG"; + + /** + * Allowed Origins for CORS Bean + */ + public static final String GET = "GET"; + public static final String POST = "POST"; + public static final String PUT = "PUT"; + public static final String DELETE = "DELETE"; + public static final String OPTIONS = "OPTIONS"; + + /** + * Qualifiers and Services + */ + public static final String USER_SERVICE = "userService"; + public static final String USER_DAO = "userDao"; + public static final String SUPER_ADMIN_SERVICE = "superAdminService"; + public static final String SUPER_ADMIN_DAO = "superAdminDao"; + public static final String TICKET_SERVICE = "ticketService"; + public static final String TICKET_DAO = "ticketDao"; + public static final String ROLE_ACTION_SERVICE = "roleActionService"; + public static final String APP_SERVICE = "appService"; + public static final String TAG_SERVICE = "tagService"; + public static final String ROLE_DAO = "roleDao"; + public static final String APP_DAO = "appDao"; + public static final String TAG_DAO = "tagDao"; + public static final String TIME_ZONE = "UTC"; + public static final String APPEND_SECONDS = ":00"; + public static final String HTTPS_ACCOUNTS_GOOGLE_COM_O_OAUTH2_TOKEN = "https://accounts.google.com/o/oauth2/token"; + public static final String CLIENT_SECRET = "client_secret"; + public static final String CLIENT_ID = "client_id"; + public static final String REFRESH_TOKEN = "refresh_token"; + public static final String GRANT_TYPE = "grant_type"; + + private static final List<Integer> superAdminActions = new ArrayList<>(Arrays.asList(1, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61)); + private static final List<Integer> orgAdminActions = new ArrayList<>( + Arrays.asList(3, 4, 5, 6, 9, 11, 12, 15, 18, 23, 24, 25, 29, 30, 33, 34, 36, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61)); + private static final List<Integer> endUserActions = new ArrayList<>(Arrays.asList(11, 12, 23, 24, 29, 30, 33, 34, + 36, 38, 39, 40, 41, 44, 45, 46, 47, 48, 49, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61)); + + private static Map<Integer, List<String>> actions = createMap(); + + protected static Map<Integer, List<String>> createMap() { + Map<Integer, List<String>> actions = new HashMap<>(); + actions.put(1, Arrays.asList("Get Apps", "Get All Applications", "/app/getAllApps")); + actions.put(3, Arrays.asList("Get Roles", "Get All Roles", "/roles/getAllRoles")); + actions.put(4, Arrays.asList("Add Update Apps", "Add Or Update App", "/apps/addUpdateApp")); + actions.put(5, Arrays.asList("Get Apps", "Get Applications", "/apps/getApp")); + actions.put(6, Arrays.asList("Create Update Helpdesk", "Create or Update a new Helpdesk", + "/helpdesk/createUpdateHelpdesk")); + actions.put(7, Arrays.asList("Fetch Helpdesk", "Get Helpdesk", "/helpdesk/getOrgHelpdesk")); + actions.put(8, Arrays.asList("Check MDM", "Check MDM", "/roles/mdmCheck")); + actions.put(9, Arrays.asList("Get Service Request", "Fetch Service Requests", "/apps/getServiceRequests")); + actions.put(10, + Arrays.asList("Get Priority Levels", "Get All Ticket Priority Levels", "/tickets/getPriorityLevels")); + actions.put(11, Arrays.asList("Get Helpdesk", "Fetch Helpdesks", "/helpdesk/getHelpdesk")); + actions.put(12, Arrays.asList("Add Update User", "Add Or Update User Details", "/user/createOrUpdate")); + actions.put(15, Arrays.asList("Update Organization", "Update Organization", "/superadmin/updateOrgById")); + actions.put(16, Arrays.asList("Add Org", "Add Organization", "/superadmin/addOrganization")); + actions.put(17, Arrays.asList("Get Org By ID", "Get Org By ID", "/superadmin/getOrgById")); + actions.put(18, Arrays.asList("Delete Org", "Delete Organization", "/superadmin/deleteOrganization")); + actions.put(20, + Arrays.asList("Get Template Version", "Get Version of Template", "/tickets/getTemplatesVersion")); + actions.put(21, Arrays.asList("Configure Templates", "Configure Templates", "/tickets/configureTemplates")); + actions.put(22, Arrays.asList("Get Templates", "Get Templates", "/tickets/getTemplates")); + actions.put(23, Arrays.asList("Get All Users", "getAllUsers", "/user/getAllUsers")); + actions.put(24, Arrays.asList("Get User By Id", "getUserById", "/user/getUser")); + actions.put(25, Arrays.asList("Get Apps By Org", "getAppByOrgId", "/apps/getAppByOrgId")); + actions.put(26, Arrays.asList("Add or Update Helpdesk Admins", "addOrUpdateHelpdeskAdmins", + "/helpdesk/addUpdateHelpdeskAdmins")); + actions.put(27, Arrays.asList("Get Helpdesk Admins", "getHelpdeskAdmins", "/helpdesk/getHelpdeskAdmins")); + actions.put(28, Arrays.asList("Map Apps To Helpdesk", "mappAppsToHelpdesk", "/apps/mapAppToHelpdesk")); + actions.put(29, Arrays.asList("Add Ticket", "addTicket", "/tickets/addTicket")); + actions.put(30, Arrays.asList("Get Tickets", "getAllTickets", "/tickets/getAllTickets")); + actions.put(32, Arrays.asList("Add Notes", "addNotes", "/tickets/addNotes")); + actions.put(33, Arrays.asList("Add Update Updates", "addUpdateUpdates", "/tickets/addUpdateUpdates")); + actions.put(34, Arrays.asList("Get Updates", "getUpdates", "/tickets/getUpdates")); + actions.put(35, Arrays.asList("add admin", "addAdmin", "/superadmin/addAdmin")); + actions.put(36, Arrays.asList("Update Ticket Basic", "updateTicketBasic", "/tickets/updateTicketBasic")); + actions.put(37, Arrays.asList("Update Ticket Type", "updateTicketType", "/tickets/updateTicketType")); + actions.put(38, Arrays.asList("Update Ticket Status", "updateTicketStatus", "/tickets/updateTicketStatus")); + actions.put(39, + Arrays.asList("Update Ticket Checklist", "updateTicketChecklist", "/tickets/updateTicketChecklist")); + actions.put(40, Arrays.asList("Get Activity Logs Per Ticket", "getActivityLogs", "/tickets/getActivityLogs")); + actions.put(41, Arrays.asList("Change Password", "changePassword", "/user/changePassword")); + actions.put(42, Arrays.asList("Add Admin", "addAdmin", "/superadmin/addAdmin")); + actions.put(43, Arrays.asList("Remove Admin", "removeAdmin", "/superadmin/removeAdmin")); + actions.put(44, Arrays.asList("Upload Profile Picture", "uploadProfilePicture", "/user/uploadProfilePicture")); + actions.put(45, Arrays.asList("Pin Ticket", "pinTicket", "/tickets/pinTicket")); + actions.put(46, Arrays.asList("Get No Of Tickets", "getNoOfTickets", "/tickets/getNoOfTickets")); + actions.put(47, Arrays.asList("Get Activity Logs Per User", "getActivityLogsPerUser", + "/tickets/getActivityLogsPerUser")); + actions.put(48, Arrays.asList("Get Tickets Count Per Month Per User", "getTicketsCountPerMonthPerUser", + "/tickets/getTicketsCountPerMonthPerUser")); + actions.put(49, Arrays.asList("Upload Ticket Attachments", "uploadAttachment", "/tickets/uploadAttachment")); + actions.put(51, Arrays.asList("Add Update Tag", "addorUpdateTags", "/tags/addUpdateTag")); + actions.put(52, Arrays.asList("Get All Ticket Tags", "getAllTicketTags", "/tags/getAllTicketTags")); + actions.put(53, Arrays.asList("Get All Tags By Org Id", "getTagByOrgId", "/tags/getTagByOrgId")); + actions.put(54, Arrays.asList("Get All Tags By Helpdesk Id", "getTagByHelpdeskId", "/tags/getTagByHelpdeskId")); + actions.put(55, Arrays.asList("Get Feedback From grievance Sdk", "getFeedbackFromAuroraSdk", + "/tickets/getFeedbackFromAuroraSdk")); + actions.put(56, Arrays.asList("Get All Tickets V2", "getAllTicketsV2", "/tickets/getAllTicketsV2")); + actions.put(57, Arrays.asList("Get All Org", "getAllOrg", "/superadmin/getAllOrg")); + actions.put(58, Arrays.asList("Forgot Password", "forgotPassword", "/user/forgotPassword")); + actions.put(59, Arrays.asList("Map Apps To Org", "mapAppsToOrg", "/superadmin/mapAppsToOrg")); + actions.put(60, Arrays.asList("Get Reviews", "getReviews", "/user/getReviews")); + actions.put(61, Arrays.asList("Send Reply To Reviews", "sendReplyToReviews", "/tickets/sendRepliesToReviews")); + return actions; + } + + public static List<Integer> getOrgadminactions() { + return orgAdminActions; + } + + public static List<Integer> getEnduseractions() { + return endUserActions; + } + + public static Map<Integer, List<String>> getActions() { + return actions; + } + + public static void setActions(Map<Integer, List<String>> actions) { + Constants.actions = actions; + } + + public static List<Integer> getSuperadminactions() { + return superAdminActions; + } + + public static String[] getExcludeFields() { + return EXCLUDE_FIELDS; + } + + public static String[] getIncludeFields() { + return INCLUDE_FIELDS; + } + + public class SMTP { + private SMTP() { + super(); + } + + public static final String HOST = "smtp.sendgrid.net"; + public static final int PORT = 465; + public static final boolean SSL = true; + public static final String USER = "apikey"; + public static final String PSWRD = "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"; + public static final String EMAIL = "shishir.suman@tarento.com"; + public static final String ALIAS = "grievance-desk.support"; + } + + public static final String HOST = "smtp.sendgrid.net"; + public static final String FROM = "shishir.suman@tarento.com"; + public static final String USER = "apikey"; + public static final String PSWRD = "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"; + public static final String LOGO_URL = "https://cabhound-static.s3.amazonaws.com/insuranceDoc/claim/tarento_logo.png"; + public static final String ALIAS = "auroradesk.support"; + + public static final int MAX_EXECUTOR_THREAD = 10; + public static final String HTTPHEADERANDSECURITY = null; + public static final String USER_NAME_MISSING = "User name is mandatory."; + public static final String NAME_MISSING = " Oops ! Name is mandatory."; + public static final String PHONE_NUMBER_MISSING = "Phone number is mandatory."; + public static final String ID_MISSING = " Oops ! Id is mandatory."; + public static final String PSWRD_MISSING = "Oops! Password is Missing"; + public static final String PSWRD_MISMATCH = "New and Confirm passwords don't match."; + public static final String PSWRD_SAME = "New and Old passwords cannot be same."; + public static final int AUTH_TYPE = 1; + public static final String PSWRD_REGENERATED = "Password regenerated"; + public static final String FORGOT_PSWRD_VM_FILE = "forgot-password.vm"; + public static final String NOT_A_CUSTOM_PSWRD = "Please visit GreenPine for Forgot Password Link"; + public static final int ADMIN_ID = 2; + public static final String USERS = "user"; + public static final String GOOGLE_AUTH = "google"; + public static final String CUSTOM_AUTH = "custom"; + public static final String ADD_ADMIN_VM_FILE = "add-admin-grievance.vm"; + public static final String NEW_ADMIN = "You are added as an admin in grievance-Desk"; + public static final String NEW_HELPDESK_ADMIN = "You are added as a helpdesk admin in grievance-Desk"; + public static final String DELETE_HELPDESK_ADMIN = "Revoke of helpdesk admin access in grievance-Desk"; + public static final String COPIEDTO = "You are copied to a ticket in grievance-Desk"; + public static final String TICKETCREATION = "You have created a new ticket in grievance-Desk"; + public static final String REMOVEDFROMCOPIEDTO = "You are removed from a ticket in grievance-Desk"; + public static final String DELETE_ADMIN_VM_FILE = "remove_admin.vm"; + public static final String DELETE_ADMIN = "Revoke of admin access in grievance-Desk"; + public static final String HELPDESKTYPE_WITHOUTWORKFLOW = "Helpdesk Type cannot be created without workflow. Please add workflow and try again"; + public static final String HELPDESKTYPE_WORKFLOW_EMPTY = "Helpdesk Type Workflow cannot be empty. Please add valid workflow and try again"; + public static final int CAPACITY = 1024; + public static final String PSWORD_REGENERATED = "Password regenerated"; + public static final String FORGOT_PSWORD_VM_FILE = "forgot-password.vm"; + public static final String STATUS_CHANGE = "Ticket Status Change!"; + public static final String UPDATES = "Here's what you missed while you were away!"; + public static final String A_1_0 = "1.0"; + public static final String SV = "sv"; + public static final String SAVE = "save"; + public static final String ID = "id"; + public static final String CC = "cc"; + public static final String TAGS2 = "tags"; + public static final String USER_EVENT = "userEvent"; + public static final String DEVICE_SCREEN_RESOLUTION = "deviceScreenResolution"; + public static final String DEVICE_LOCALE = "deviceLocale"; + public static final String DEVICE_MANUFACTURE = "deviceManufacture"; + public static final String REVIEW_ID = "reviewId"; + public static final String DEVICE_NAME = "deviceName"; + public static final String COUNTRY = "country"; + public static final String IP = "ip"; + public static final String DEVICE_TYPE = "deviceType"; + public static final String OS_TYPE = "osType"; + public static final String OS_VERSION = "osVersion"; + public static final String STATUS = "status"; + public static final String PRIORITY = "priority"; + public static final String TYPE_ID = "typeId"; + public static final String SOURCE_ID = "sourceId"; + public static final String HELPDESK_ID = "helpdeskId"; + public static final String APP_ID = "appId"; + public static final String UPDATE = "update"; + public static final String OPR = "opr"; + public static final String PINNED_TICKET = "pinnedTicket"; + public static final String ACTIVE = "active"; + public static final String APP_NAME = "appName"; + public static final String APP_VERSION = "appVersion"; + public static final String REQUESTED_BY = "requestedBy"; + public static final String UPDATED_TIME_TS = "updatedTimeTS"; + public static final String CREATED_TIME_TS = "createdTimeTS"; + public static final String U_T = "uT"; + public static final String C_T = "cT"; + public static final String UPDATED_TIME = "updatedTime"; + public static final String CREATED_TIME = "createdTime"; + public static final String MAX_RATING = "max-rating"; + public static final String RATE = "rate"; + public static final String DESCRIPTION = "description"; + + private static final String[] INCLUDE_FIELDS = new String[] { ID, STATUS, TOTAL, DESCRIPTION, PINNED_TICKET, + REQUESTED_BY, HELPDESK_ID, UPDATED_TIME, CREATED_TIME, U_T, C_T }; + private static final String[] EXCLUDE_FIELDS = new String[] { OS_VERSION, OS_TYPE, DEVICE_TYPE, DEVICE_LOCALE, + DEVICE_SCREEN_RESOLUTION, DEVICE_MANUFACTURE, DEVICE_NAME, IP, USER_EVENT, SV, COUNTRY, SOURCE_ID, TYPE_ID, + TYPE, PRIORITY, RATE, MAX_RATING, APP_VERSION, APP_NAME, APP_ID, FEEDBACK_BY_NAME, ACTIVE, CREATED_TIME_TS, + UPDATED_TIME_TS }; +} diff --git a/src/main/java/org/upsmf/grievance/util/CustomException.java b/src/main/java/org/upsmf/grievance/util/CustomException.java new file mode 100644 index 0000000..a53ec56 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/CustomException.java @@ -0,0 +1,52 @@ +package org.upsmf.grievance.util; + +public class CustomException { + public CustomException() { + } + + public CustomException(Integer errorCode, String errorMessage, String errorMessageCode, CustomResponse response) { + this.errorCode = errorCode; + this.errorMessage = errorMessage; + this.errorMessageCode = errorMessageCode; + this.response = response; + } + + protected Integer errorCode; + protected String errorMessage; + protected String errorMessageCode; + protected CustomResponse response; + + public Integer getErrorCode() { + return errorCode; + } + + public void setErrorCode(Integer errorCode) { + this.errorCode = errorCode; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public String getErrorMessageCode() { + return errorMessageCode; + } + + public void setErrorMessageCode(String errorMessageCode) { + this.errorMessageCode = errorMessageCode; + } + + public void setResponse(CustomResponse response) { + this.response = response; + } + + public CustomException(int errorCode, String errorMessage) { + this.errorCode = errorCode; + this.errorMessage = errorMessage; + this.errorMessageCode = Constants.ERROR_MESSAGE_VALUE + errorCode; + } +} diff --git a/src/main/java/org/upsmf/grievance/util/CustomListResponse.java b/src/main/java/org/upsmf/grievance/util/CustomListResponse.java new file mode 100644 index 0000000..f816bed --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/CustomListResponse.java @@ -0,0 +1,31 @@ +package org.upsmf.grievance.util; + +public class CustomListResponse { + private int page; + private int pageSize; + private int count; + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getPageSize() { + return pageSize; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } +} diff --git a/src/main/java/org/upsmf/grievance/util/CustomResponse.java b/src/main/java/org/upsmf/grievance/util/CustomResponse.java new file mode 100644 index 0000000..8025dbb --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/CustomResponse.java @@ -0,0 +1,44 @@ +package org.upsmf.grievance.util; + +import java.util.ArrayList; +import java.util.List; + +public class CustomResponse { + private String status; + private String success; + private List<Object> data = new ArrayList<>(); + + public CustomResponse() { + } + + public CustomResponse(String status, String success, List<Object> data) { + this.status = status; + this.success = success; + this.data = data; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getSuccess() { + return success; + } + + public void setSuccess(String success) { + this.success = success; + } + + public List<Object> getData() { + return data; + } + + public void setData(List<Object> data) { + this.data = data; + } + +} diff --git a/src/main/java/org/upsmf/grievance/util/CustomSuccess.java b/src/main/java/org/upsmf/grievance/util/CustomSuccess.java new file mode 100644 index 0000000..83a7b09 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/CustomSuccess.java @@ -0,0 +1,102 @@ +package org.upsmf.grievance.util; + +import java.util.HashMap; +import java.util.List; + +public class CustomSuccess { + protected Integer successCode; + protected String successMessage; + protected Object data; + protected List<Object> dataList; + protected CustomResponse customResponse = null; + + public CustomSuccess(int successCode, String successMessage) { + this.successCode = successCode; + this.successMessage = successMessage; + } + + public CustomSuccess(Object data) { + if (data instanceof List) { + this.dataList = (List) data; + } else { + this.data = data; + } + } + + public Integer getSuccessCode() { + return successCode; + } + + public void setSuccessCode(Integer successCode) { + this.successCode = successCode; + } + + public String getSuccessMessage() { + return successMessage; + } + + public void setSuccessMessage(String successMessage) { + this.successMessage = successMessage; + } + + public Object getData() { + return data; + } + + public void setData(Object data) { + this.data = data; + } + + public List<Object> getDataList() { + return dataList; + } + + public void setDataList(List<Object> dataList) { + this.dataList = dataList; + } + + public CustomResponse getCustomResponse() { + if (customResponse != null) { + return customResponse; + } + customResponse = new CustomResponse(); + customResponse.setSuccess(Constants.SUCCESS); + if (data != null) { + customResponse.getData().add(data); + } else if (dataList != null) { + customResponse.getData().addAll(dataList); + } else if (successCode != null) { + HashMap<String, Object> responseData = new HashMap<>(); + responseData.put(Constants.SUCCESS_CODE, successCode); + responseData.put(Constants.SUCCESS_MESSAGE, successMessage); + customResponse.getData().add(responseData); + } + return customResponse; + } + + public CustomResponse getCustomResponse(Object object) { + if (customResponse != null) { + return customResponse; + } + customResponse = new CustomResponse(); + customResponse.setSuccess(Constants.SUCCESS); + customResponse.setStatus("200"); + if (data != null) { + customResponse.getData().add(data); + } else if (dataList != null) { + customResponse.getData().addAll(dataList); + } else if (successCode != null) { + HashMap<String, Object> responseData = new HashMap<>(); + responseData.put(Constants.SUCCESS_CODE, successCode); + responseData.put(Constants.SUCCESS_MESSAGE, successMessage); + responseData.put("responseData", object); + customResponse.getData().add(responseData); + } + return customResponse; + } + + public void setCustomResponse(CustomResponse customResponse) { + this.customResponse = customResponse; + } + +} diff --git a/src/main/java/org/upsmf/grievance/util/DateUtil.java b/src/main/java/org/upsmf/grievance/util/DateUtil.java new file mode 100644 index 0000000..f6f72a9 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/DateUtil.java @@ -0,0 +1,391 @@ +package org.upsmf.grievance.util; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import lombok.NoArgsConstructor; + +@NoArgsConstructor +public class DateUtil { + + private static final String ENCOUNTERED_AN_EXCEPTION = "Encountered an Exception : %s"; + public static final Logger LOGGER = LoggerFactory.getLogger(DateUtil.class); + + public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + public static final String INVOICE_DATE_FORMATTER = "EEEE, MMMM d, yyyy"; + public static final String YYYYMMDD_FORMATTER = "yyyy-MM-dd"; + public static final String DATE_MONTH_YEAR_FORMAT = "dd-MMMM-yyyy"; + + /** + * this method take date object and format the date with time zone UTC. + * + * @param date + * date object + * @return formatted date as String in "yyyy-MM-dd HH:mm:ss" + */ + public static String getFormattedDateInUTC(Date date) { + SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATE_FORMAT); + format.setTimeZone(TimeZone.getTimeZone(Constants.TIME_ZONE)); + return format.format(date); + } + + /** + * this method take date object and time zone ,and format date object with + * incoming time zone. + * + * @param date + * date object + * @param timeZone + * @return formatted date as String in "yyyy-MM-dd HH:mm:ss" + */ + public static String getFormattedDateWithTimeZone(Date date, String timeZone) { + SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATE_FORMAT); + format.setTimeZone(TimeZone.getTimeZone(timeZone)); + return format.format(date); + } + + /** + * this method will format current date object with incoming formatter + * + * @param format + * date formatter + * @return String formatted date object. + */ + public static String getCurrentDate(String format) { + SimpleDateFormat dateFormat = new SimpleDateFormat(format); + return dateFormat.format(new Date()); + } + + /** + * this method will format long time value to given time zone with MM-dd-yyyy + * HH:mm:ss + * + * @param timeZone + * @param time + * @return String + */ + public static String convertLongToStringAsDateTime(String timeZone, long time) { + SimpleDateFormat format = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss"); + format.setTimeZone(TimeZone.getTimeZone(timeZone)); + Date date = new Date(time); + return format.format(date); + } + + /** + * this method will format long time value to given time zone with MM-dd-yyyy + * HH:mm:ss + * + * @param timeZone + * @param date + * @param incomingDateFormat + * @return String + */ + public static String dateFormatter(String timeZone, String date, String incomingDateFormat) { + SimpleDateFormat format = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss"); + SimpleDateFormat incomingFormatter = new SimpleDateFormat(incomingDateFormat); + incomingFormatter.setTimeZone(TimeZone.getDefault()); + format.setTimeZone(TimeZone.getTimeZone(timeZone)); + String response = ""; + try { + Date defaultFormattedDate = incomingFormatter.parse(date); + response = format.format(defaultFormattedDate); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return response; + } // + + /** + * this method will format long time value to given time zone with MMMMM d + * EEEEEEEEE,hh:mm a + * + * @param timeZone + * @param date + * @param incomingDateFormat + * @return String + */ + public static String ormatterInMMMMdEEE(String timeZone, String date, String incomingDateFormat) { + SimpleDateFormat format = new SimpleDateFormat("EEEEEEEEE, MMMMM d @hh:mm a"); + SimpleDateFormat incomingFormatter = new SimpleDateFormat(incomingDateFormat); + incomingFormatter.setTimeZone(TimeZone.getDefault()); + format.setTimeZone(TimeZone.getTimeZone(timeZone)); + String response = ""; + try { + Date defaultFormattedDate = incomingFormatter.parse(date); + response = format.format(defaultFormattedDate); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return response; + } + + /** + * this method will format long time value to given time zone with MMMMM d + * EEEEEEEEE,hh:mm a + * + * @param timeZone + * @param time + * @return String + */ + public static String convertLongToStringAsMMMMEEEE(String timeZone, long time) { + SimpleDateFormat format = new SimpleDateFormat("EEEEEEEEE, MMMMM d @hh:mm a"); + format.setTimeZone(TimeZone.getTimeZone(timeZone)); + Date date = new Date(time); + return format.format(date); + } + + /** + * this method will format date object with time zone + * + * @param date + * date object + * @param timeZone + * String + * @return String + */ + public static String getSqlTimeStamp(Date date, String... timeZone) { + + DateFormat format = new SimpleDateFormat(DEFAULT_DATE_FORMAT); + if (timeZone != null && timeZone.length > 0) { + format.setTimeZone(TimeZone.getTimeZone(timeZone[0])); + } + return format.format(date); + } + + /** + * this method will convert long value to date object and provide formatted date + * object in "yyyy-MM-dd HH:mm:ss" this form + * + * @param time + * @return String + */ + public static String getSqlTimeStamp(Long time) { + return getSqlTimeStamp(new Date(time)); + } + + /** + * + * @param date + * @param timeZone + * @return Date + * @throws Exception + */ + public static Date getDateInDefaultTimeZone(String date, String timeZone) throws Exception { + SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATE_FORMAT); + SimpleDateFormat formatterWithDefaultTimeZone = new SimpleDateFormat(DEFAULT_DATE_FORMAT); + format.setTimeZone(TimeZone.getTimeZone(timeZone)); + Date reservationTimeWithTimeZone = format.parse(date + ":00"); + String reservationTimeWithDefaultTimeZone = formatterWithDefaultTimeZone.format(reservationTimeWithTimeZone); + return formatterWithDefaultTimeZone.parse(reservationTimeWithDefaultTimeZone); + } + + /** + * + * @return Date + * @throws Exception + */ + public static Date getCurrentDate() throws Exception { + SimpleDateFormat formatterWithDefaultTimeZone = new SimpleDateFormat(DEFAULT_DATE_FORMAT); + Date currDate = new Date(); + String currTimeWithTimeZone = formatterWithDefaultTimeZone.format(currDate); + return formatterWithDefaultTimeZone.parse(currTimeWithTimeZone); + } + + /** + * This method will convert String date time with UTC time Zone in "yyyy-MM-dd + * HH:mm:ss" format + * + * @param date + * String + * @return Date jave.util Date object + */ + public static Date convertStringToDateWithTime(String date) { + SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATE_FORMAT); + format.setTimeZone(TimeZone.getTimeZone(Constants.TIME_ZONE)); + Date afterFormat = null; + try { + afterFormat = format.parse(date); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return afterFormat; + } + + /** + * this method will provide current data in GMT. + * + * @return Date Object + */ + public static Date getCurrentDateInGmt() { + Calendar c = Calendar.getInstance(); + TimeZone z = c.getTimeZone(); + int offset = z.getRawOffset(); + if (z.inDaylightTime(new Date())) { + offset = offset + z.getDSTSavings(); + } + int offsetHrs = offset / 1000 / 60 / 60; + int offsetMints = offset / 1000 / 60 % 60; + c.add(Calendar.HOUR_OF_DAY, (-offsetHrs)); + c.add(Calendar.MINUTE, (-offsetMints)); + return c.getTime(); + } + + /** + * this method is used to take system current time and return time with time + * zone. + * + * @param date + * current date + * @param timezone + * time + * @return String + */ + public static String convertDateWithTimeZone(Date date, String timezone) { + SimpleDateFormat dateFormatGmt = new SimpleDateFormat(DEFAULT_DATE_FORMAT); + dateFormatGmt.setTimeZone(TimeZone.getTimeZone(timezone)); + return dateFormatGmt.format(date); + + } + + /** + * this method will convert String to date object with system time zone. + * + * @param date + * String + * @return Date + */ + public static Date convertStringToDate(String date) { + SimpleDateFormat format = new SimpleDateFormat(DEFAULT_DATE_FORMAT); + Date afterFormat = null; + try { + afterFormat = format.parse(date); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return afterFormat; + } + + /** + * this will format incoming date with MM/dd/yyyy + * + * @param date + * String + * @return String + */ + public static String formateWithMMddyyyy(String date) { + SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT); + SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy"); + String formattedDate = ""; + try { + formattedDate = format.format(dateFormat.parse(date)); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + + return formattedDate; + } + + /** + * This method will return reservation time and current time difference in + * minutes. + * + * @param date + * String reservation time + * @return int + */ + public static int getDateDifferenceInMinutes(String date) { + int diffDate = 0; + SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT); + dateFormat.setTimeZone(TimeZone.getTimeZone(Constants.TIME_ZONE)); + try { + Date requestedDate = dateFormat.parse(date); + Date currentDate = new Date(); + currentDate = dateFormat.parse(dateFormat.format(currentDate)); + diffDate = (int) ((requestedDate.getTime() - currentDate.getTime()) / 60000); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return diffDate; + } + + /** + * This method will formate incoming String to time zone and format. + * + * @param date + * @param timZone + * @param format + * @return + */ + public static String formatStringToTimeZone(String date, String timZone, String format) { + SimpleDateFormat dateFormat = new SimpleDateFormat(format); + dateFormat.setTimeZone(TimeZone.getTimeZone(timZone)); + SimpleDateFormat dateFormat1 = new SimpleDateFormat(format); + dateFormat1.setTimeZone(TimeZone.getTimeZone(Constants.TIME_ZONE)); + String formattedDate = date; + try { + Date parseDate = dateFormat.parse(date); + formattedDate = dateFormat1.format(parseDate); + formattedDate = dateFormat1.format(dateFormat1.parse(formattedDate)); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return formattedDate; + } + + /** + * This method will provide current date in UTC format in YYYY_MM_DD format. + * + * @return String + */ + public static String getYyyyMmDdInUTC() { + SimpleDateFormat format = new SimpleDateFormat(YYYYMMDD_FORMATTER); + format.setTimeZone(TimeZone.getTimeZone(Constants.TIME_ZONE)); + return format.format(new Date()); + } + + /** + * this method will convert String to date object in UTC + * + * @param date + * String + * @return Date + */ + public static Date convertStringToDateUTC(String date) { + SimpleDateFormat format = new SimpleDateFormat(YYYYMMDD_FORMATTER); + format.setTimeZone(TimeZone.getTimeZone(Constants.TIME_ZONE)); + Date afterFormat = null; + try { + afterFormat = format.parse(date); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return afterFormat; + } + + public static String getTimeWithHHMMSSFormat() { + + Calendar cal = Calendar.getInstance(); + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); + return sdf.format(cal.getTime()); + + } + + public static Date convertPorjectUploadDate(String date) { + SimpleDateFormat format = new SimpleDateFormat(DATE_MONTH_YEAR_FORMAT); + Date formatDate = null; + try { + formatDate = format.parse(date); + } catch (ParseException e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return formatDate; + } + +} diff --git a/src/main/java/org/upsmf/grievance/util/ExecutorManager.java b/src/main/java/org/upsmf/grievance/util/ExecutorManager.java new file mode 100644 index 0000000..9050fc5 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/ExecutorManager.java @@ -0,0 +1,32 @@ +package org.upsmf.grievance.util; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + +import lombok.NoArgsConstructor; + +/** + * This class will manage execute service thread. + * + * @author Manzarul.Haque + * + */ +@NoArgsConstructor +public class ExecutorManager { + /* + * service ScheduledExecutorService object + */ + private static ScheduledExecutorService service = null; + static { + service = Executors.newScheduledThreadPool(Constants.MAX_EXECUTOR_THREAD); + } + + /** + * This method will send executor service object. + * + * @return + */ + public static ScheduledExecutorService getExecutorService() { + return service; + } +} diff --git a/src/main/java/org/upsmf/grievance/util/GMailAuthenticator.java b/src/main/java/org/upsmf/grievance/util/GMailAuthenticator.java new file mode 100644 index 0000000..1bb9890 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/GMailAuthenticator.java @@ -0,0 +1,36 @@ +/** + * + */ +package org.upsmf.grievance.util; + +import javax.mail.Authenticator; +import javax.mail.PasswordAuthentication; + +/** + * @author Manzarul.Haque + * + */ +public class GMailAuthenticator extends Authenticator { + String user; + String pw; + + /** + * this method is used to authenticate gmail user name and password. + * + * @param username + * @param password + */ + public GMailAuthenticator(String username, String password) { + super(); + this.user = username; + this.pw = password; + } + + /** + * + */ + @Override + public PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(this.user, this.pw); + } +} diff --git a/src/main/java/org/upsmf/grievance/util/JSONObjectUtil.java b/src/main/java/org/upsmf/grievance/util/JSONObjectUtil.java new file mode 100644 index 0000000..d5e0be9 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/JSONObjectUtil.java @@ -0,0 +1,57 @@ +package org.upsmf.grievance.util; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; + +/** + * Created by Abhishek on 10/5/2017. + */ +@Service(value = "jsonObjectUtil") +public class JSONObjectUtil { + @Autowired + public ObjectMapper mapper; + @Autowired + public Gson gson; + + /** + * @return + */ + public static String getJsonString(ObjectMapper objectMapper, Object object) throws JsonProcessingException { + + if (objectMapper != null) { + return objectMapper.writeValueAsString(object); + } + return null; + } + + public String getJsonString(Object object) throws JsonProcessingException { + + if (mapper != null) { + return mapper.writeValueAsString(object); + } + if (gson != null) { + return gson.toJson(object); + } + return null; + } + + public ObjectMapper getMapper() { + return mapper; + } + + public void setObjectMapper(ObjectMapper objectMapper) { + mapper = objectMapper; + } + + public Gson getGson() { + return gson; + } + + public void setGson(Gson gsonn) { + gson = gsonn; + } +} diff --git a/src/main/java/org/upsmf/grievance/util/JsonKey.java b/src/main/java/org/upsmf/grievance/util/JsonKey.java new file mode 100644 index 0000000..ee88bd1 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/JsonKey.java @@ -0,0 +1,115 @@ +/** + * + */ +package org.upsmf.grievance.util; + +import lombok.NoArgsConstructor; + +/** + * @author Abhishek + * + */ +@NoArgsConstructor +public class JsonKey { + /* + * USER_NAME contains userName as key + */ + public static final String USER_ID = "userId"; + /* + * USER_NAME contains userName as key + */ + public static final String USER_NAME = "username"; + /* + * PASSWORD contains password + */ + public static final String PSWRD = "password"; + /* + * OLD_PASSWORD + */ + public static final String OLD_PSWRD = "oldPass"; + /* + * NEW_PASSWORD + */ + public static final String NEW_PSWRD = "newPass"; + /* + * DEVICE_TYPE user device type + */ + public static final String DEVICE_TYPE = "deviceType"; + /* + * DEVICE_ID user device id. + */ + public static final String DEVICE_ID = "deviceId"; + /* + * TIMEZONE + */ + public static final String TIMEZONE = "timeZone"; + /* + * SESSION + */ + public static final String SESSION = "sessionId"; + /* + * FIRST_NAME + */ + public static final String FIRST_NAME = "firstName"; + /* + * LAST_NAME + */ + public static final String LAST_NAME = "lastName"; + + public static final String URL = "url"; + + public static final String USERNAME = "username"; + + public static final String LINK = "link"; + + public static final String ROLE_IDS = "roleIds"; + + public static final String ROLENAME = "roleName"; + /* + * EMAIL + */ + public static final String EMAIL = "email"; + public static final String STATUS_CODE = "statusCode"; + public static final String STATUS = "statusInfo"; + public static final String STATUS_MESSAGE = "statusMessage"; + public static final String ERROR_MESSAGE = "errorMessage"; + /** + * RESPONSE. + */ + public static final String RESPONSE = "response"; + public static final String RESPONSE_DATA = "responseData"; + + /** + * IS_ACTIVE. + */ + public static final String IS_ACTIVE = "isActive"; + /** + * IS_DELETED. + */ + public static final String IS_DELETED = "isDeleted"; + + public static final String TIME = "time"; + + public static final String SUBSCRIPTION_NAME = "subscriptionName"; + + public static final String ASSET_TYPE = "assetType"; + public static final String ASSET_NAME = "assetName"; + public static final String FROM_USER = "fromUser"; + public static final String MAIL_SUBJECT = "mail_subject"; + public static final String MAIL_BODY = "mail_body"; + public static final String LOGO_URL = "logo_url"; + public static final String TYPE = "type"; + public static final String TICKET_ID = "ticketId"; + public static final String SEVERITY = "severity"; + public static final String CREATED_BY = "createdBy"; + public static final String OWNER = "owner"; + public static final String SUMMARY = "summary"; + public static final String ORGNAME = "CompName"; + public static final String HELPDESKNAME = "HelpdeskName"; + public static final String HELPDESK_NAME = "helpdeskName"; + public static final String OLDSTATUS = "oldStatus"; + public static final String UPDATE = "update"; + public static final String NEWSTATUS = "newStatus"; + public static final String ID = "id"; + public static final String HELPDESKID = "helpdeskId"; +} diff --git a/src/main/java/org/upsmf/grievance/util/OneWayHashing.java b/src/main/java/org/upsmf/grievance/util/OneWayHashing.java new file mode 100644 index 0000000..4067c01 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/OneWayHashing.java @@ -0,0 +1,40 @@ +package org.upsmf.grievance.util; + +import java.security.MessageDigest; + +import lombok.NoArgsConstructor; + +/** + * @author Juhi Agarwal This class will hash data only one way. once it + * encrypted you can't decrypt it. + */ +@NoArgsConstructor +public class OneWayHashing { + + /** + * This method will encrypt value using SHA-256 . it is one way encryption. + * + * @param val + * String + * @return String encrypted value or empty in case of exception + */ + + public static String encryptVal(String val) { + try { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + md.update(val.getBytes()); + byte[] byteData = md.digest(); + + StringBuilder sb = new StringBuilder(); + for (byte element : byteData) { + sb.append(Integer.toString((element & 0xff) + 0x100, 16).substring(1)); + } + + + return sb.toString(); + } catch (Exception e) { + + } + return ""; + } +} diff --git a/src/main/java/org/upsmf/grievance/util/PathRoutes.java b/src/main/java/org/upsmf/grievance/util/PathRoutes.java new file mode 100644 index 0000000..98996ba --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/PathRoutes.java @@ -0,0 +1,158 @@ +package org.upsmf.grievance.util; + +/** + * + * @author Darshan Nagesh + * + */ + +public final class PathRoutes { + + public static final String USER_ACTIONS_URL = "/user"; + public static final String SUPERADMIN_ACTIONS_URL = "/superadmin"; + public static final String TICKET_ACTIONS_URL = "/tickets"; + public static final String ROLE_ACTIONS_URL = "/roles"; + public static final String HELPDESK_URL = "/helpdesk"; + public static final String APPS_ACTIONS_URL = "/apps"; + public static final String TAGS_URL = "/tags"; + + public final class UserRoutes { + private UserRoutes() { + super(); + } + + public static final String USER_ACTIONS_POST = "/getAllActions"; + public static final String EMPLOYMENT_TYPES_GET = "/getEmploymentTypes"; + public static final String NUMBER_OF_USERS_GET = "/getNumberOfUsers"; + public static final String NUMBER_OF_ROLES_GET = "/getNumberOfRoles"; + public static final String LIST_USER_GET = "/getAllUsers"; + public static final String USER_BY_ID_GET = "/getUser"; + public static final String CREATE_UPDATE_USER_POST = "/createOrUpdate"; + public static final String USER_ROLE_MAPPING_POST = "/mapUserToRole"; + public static final String SINGLE_FILE_UPLOAD_POST = "/upload"; + public static final String IMAGE_GET = "/images"; + public static final String LOGOUT_GET = "/logout"; + public static final String PUBLIC = "/public"; + public static final String CHANGE_PSWRD = "/changePassword"; + public static final String FORGOT_PSWRD = "/forgotPassword"; + public static final String LOGIN = "/login"; + public static final String GET_PROFILE_PICTURE = "/getProfilePicture"; + public static final String UPLOAD_PROFILE_PICTURE = "/uploadProfilePicture"; + public static final String GET_REVIEWS = "/getReviews"; + } + + public final class SuperAdminRoutes { + private SuperAdminRoutes() { + super(); + } + + public static final String GET_ALL_ORG = "/getAllOrg"; + public static final String UPDATE_ORG_BY_ID = "/updateOrgById"; + public static final String GET_ORG_BY_ID = "/getOrgById"; + public static final String DELETE_ORGANIZATION = "/deleteOrganization"; + public static final String ADD_ORGANIZATION = "/addOrganization"; + public static final String ADD_ADMIN = "/addAdmin"; + public static final String REMOVE_ADMIN = "/removeAdmin"; + public static final String MAP_APPS_TO_ORG = "/mapAppsToOrg"; + public static final String GET_AUTH_TYPES = "/getAuthTypes"; + } + + public final class RoleActionRoutes { + private RoleActionRoutes() { + super(); + + } + + public static final String LIST_ROLES_GET = "/getAllRoles"; + public static final String ADD_ROLE_POST = "/addRole"; + public static final String ROLE_BY_ID_GET = "/getRoleById"; + public static final String UPDATE_ROLE_POST = "/updateRole"; + public static final String MDM_CHECK = "/mdmCheck"; + } + + public final class AppsRoutes { + private AppsRoutes() { + super(); + + } + + public static final String CREATE_APP = "/addUpdateApp"; + public static final String GET_APP = "/getApp"; + public static final String GET_APP_BY_ORG_ID = "/getAppByOrgId"; + public static final String MAP_APP_TO_HELPDESK = "/mapAppToHelpdesk"; + public static final String GET_SERVICE_REQUEST = "/getServiceRequests"; + } + + public final class TagRoutes { + private TagRoutes() { + super(); + + } + + public static final String CREATE_TAG = "/addUpdateTag"; + public static final String GET_TAG = "/getTag"; + public static final String GET_ALL_TAGS = "/getAllTags"; + public static final String GET_TAG_BY_ORG_ID = "/getTagByOrgId"; + public static final String GET_TAG_BY_HELPDESK_ID = "/getTagByHelpdeskId"; + public static final String REMOVE_TAG = "/removeTag"; + public static final String ADD_TICKET_TAG = "/addTicketTag"; + public static final String GET_ALL_TICKET_TAGS = "/getAllTicketTags"; + public static final String DELETE_TICKET_TAG = "/deleteTicketTag"; + } + + public final class TicketRoutes { + + private TicketRoutes() { + super(); + + } + + public static final String ADD_TICKET = "/addTicket"; + public static final String GET_ALL_TICKETS_BY_ORG = "/getAllTicketsByOrg"; + public static final String UPDATE_TICKET_BASIC = "/updateTicketBasic"; + public static final String UPDATE_TICKET_TYPE = "/updateTicketType"; + public static final String UPDATE_TICKET_STATUS = "/updateTicketStatus"; + public static final String UPDATE_TICKET_CHECKLIST = "/updateTicketChecklist"; + public static final String GET_ALL_TICKETS = "/getAllTickets"; + public static final String GET_ALL_TICKETS_PER_USER = "/getAllTicketsPerUser"; + public static final String GET_ALL_TICKETS_ASSIGNED_TO_ME = "/getAllTicketsAssignedToMe"; + public static final String GET_ALL_TICKETS_TO_BE_APPROVED = "/getAllTicketsToBeApproved"; + public static final String GET_TICKET_DETAILS_PER_TICKET = "/getTicketDetailsPerTicket"; + public static final String GET_PRIORITY_LEVELS = "/getPriorityLevels"; + public static final String GET_TEMPLATES_VERSION = "/getTemplatesVersion"; + public static final String GET_TEMPLATES = "/getTemplates"; + public static final String GET_NO_OF_TICKETS = "/getNoOfTickets"; + public static final String CONFIGURE_TEMPLATE = "/configureTemplates"; + public static final String ADD_NOTES = "/addNotes"; + public static final String ADD_UPDATE_UPDATES = "/addUpdateUpdates"; + public static final String GET_UPDATES = "/getUpdates"; + public static final String GET_ACTIVITY_LOGS = "/getActivityLogs"; + public static final String GET_ACTIVITY_LOGS_PER_USER = "/getActivityLogsPerUser"; + public static final String PINNED_TICKET = "/pinTicket"; + public static final String GET_TICKET_COUNT_PER_MONTH_PER_USER = "/getTicketsCountPerMonthPerUser"; + public static final String GET_FEEDBACK_FROM_AURORA_SDK = "/getFeedbackFromAuroraSdk"; + public static final String UPLOAD_ATTACHMENT = "/uploadAttachment"; + public static final String SEND_REPLY_TO_REVIEWS = "/sendRepliesToReviews"; + + } + + public final class HelpdeskRoutes { + + private HelpdeskRoutes() { + super(); + + } + + public static final String CREATE_UPDATE_HELPDESK = "/createUpdateHelpdesk"; + public static final String GET_ORG_HELPDESK = "/getOrgHelpdesk"; + public static final String CREATE_UPDATE_HELPDESK_TYPE = "/createUpdateHelpdeskType"; + public static final String ADD_UPDATE_HELPDESK_ADMINS = "/addUpdateHelpdeskAdmins"; + public static final String GET_HELPDESK_ADMINS = "/getHelpdeskAdmins"; + public static final String GET_HELPDESK = "/getHelpdesk"; + public static final String CONFIGURE_HELPDESK = "/configureHelpdesk"; + + public static final String GET_PERFORMANCE_WITH_ACCESSCONTROL = "/getPerformanceWithAccessControl"; + public static final String GET_PERFORMANCE_WITHOUT_ACCESSCONTROL = "/getPerformanceWithoutAccessControl"; + } + +} diff --git a/src/main/java/org/upsmf/grievance/util/ProjectUtil.java b/src/main/java/org/upsmf/grievance/util/ProjectUtil.java new file mode 100644 index 0000000..c96cde7 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/ProjectUtil.java @@ -0,0 +1,451 @@ +/** + * + */ +package org.upsmf.grievance.util; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Random; +import java.util.regex.Pattern; + +import javax.mail.internet.InternetAddress; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.JsonNode; + +public class ProjectUtil { + /* + * projectUtil ProjectUtil instance + */ + public static final Logger LOGGER = LoggerFactory.getLogger(ProjectUtil.class); + private static ProjectUtil projectUtil = null; + private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@" + + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"; + private static final Random random = new Random(); + private static final String ENCOUNTERED_AN_EXCEPTION = "Encountered an Exception : %s"; + + /** + * Default constructor + * + * @throws Exception + */ + private ProjectUtil() throws Exception { + if (projectUtil != null) { + throw new Exception(); + } + } + + static { + try { + projectUtil = getProjectUtilInstance(); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + Pattern.compile(EMAIL_PATTERN); + } + + /** + * + * @return + * @throws Exception + * @throws RuntimeException + */ + public static synchronized ProjectUtil getProjectUtilInstance() throws Exception { + if (projectUtil == null) { + projectUtil = new ProjectUtil(); + } + return projectUtil; + } + + /** + * this method is used to print class name and line number + * + * @param object + * @return + */ + public String getClassNameAndLineNo(Object object) { + String message = ""; + message = " " + object.getClass().getName() + "********" + + Thread.currentThread().getStackTrace()[2].getLineNumber(); + return message; + } + + /** + * this method will generate some random password. which is dog name and is + * suggested by client. + * + * @return String password. + */ + public static String generatePassword() { + String[] passwords = new String[] { "" }; + + int index = random.nextInt(passwords.length); + + return passwords[index]; + } + + /** + * this method is used to add fare and tip amount + * + * @param fare + * fare amount + * @param tip + * tip amount + * @return result + */ + public static double addDoubles(String fare, String tip) { + double fareAmount = 0; + double tipAmount = 0; + if (fare != null && !"".equals(fare)) { + fareAmount = Double.parseDouble(fare.trim()); + } + if (tip != null && !"".equals(tip)) { + tipAmount = Double.parseDouble(tip); + } + return fareAmount + tipAmount; + } + + /** + * this method is used to subtract fare and tip amount + * + * @param fare + * fare amount + * @param tip + * tip amount + * @return result + */ + public static double substractDoubles(String fare, String tip) { + + double fareAmount = Double.parseDouble(fare); + double tipAmount = Double.parseDouble(tip); + boolean order = fareAmount - tipAmount > 0; + + String bigger = fareAmount - tipAmount > 0 ? fare : tip; + String smaller = fareAmount - tipAmount < 0 ? fare : tip; + + int bigDollars = bigger.contains(".") ? Integer.parseInt(bigger.split("\\.")[0]) : Integer.parseInt(bigger); + int smallDollars = smaller.contains(".") ? Integer.parseInt(smaller.split("\\.")[0]) + : Integer.parseInt(smaller); + + int bigCents = bigger.contains(".") ? Integer.parseInt(bigger.split("\\.")[1]) : 0; + int smallCents = smaller.contains(".") ? Integer.parseInt(smaller.split("\\.")[1]) : 0; + if (smallCents < 10 && smallCents != 0) { + smallCents = smallCents * 10; + } + int totalCents = bigCents - smallCents; + int extraDollar = 0; + int cents = totalCents; + + if (totalCents < 0) { + extraDollar = -1; + cents = 100 + bigCents - smallCents; + } + int dollars = bigDollars - smallDollars + extraDollar; + if (!order) { + dollars = dollars * -1; + } + + String totalAmount = dollars + "." + cents; + if (cents < 10) { + totalAmount = dollars + ".0" + cents; + } + return Double.parseDouble(totalAmount); + } + + /** + * this method is used to generate user session id. + * + * @param email + * user email id. + * @param roleId + * user role id. + * @param source + * String + * @return String session id value. + */ + public static String getUniqueId(String email, long roleId, String source) { + email = email.replace('.', 'D'); + email = email.replace('@', 'L'); + email = email.replace("com", "se"); + email = email.replace("in", "xp"); + StringBuilder builder = new StringBuilder(); + String str = System.currentTimeMillis() + random.nextInt() + ""; + byte[] data = { '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', '4', 'i', 'j', 'k', '5', 'l', 'm', 'n', 'o', 'p', + 'q', '6', 'A', 'B', 'C', 'D', '9', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', '8', 'M', 'N', 'O', 'P', 'Q', + 'R', '7', 'S', 'T', 't', 'u', 'U', 'V', 'v', 'W', 'w', 'X', 'x', 'Y', 'y', 'Z', 'z', '1', '2', '3' }; + String value = random.nextInt() + ""; + builder.append(value.substring(1, value.length() / 2)); + builder.append(email.substring(3, email.length() / 2)); + builder.append(str.substring(str.length() - 2) + "" + str.substring(0, str.length() - 2)); + builder.append(email.substring(email.length() - 4)); + for (int i = 0; i < 4; i++) { + builder.append(random.nextInt(data.length)); + } + builder.append("#" + source + "#" + roleId * random.nextInt(random.nextInt(data.length))); + return builder.toString(); + } + + /** + * This method will check incoming request data contains that key or not. + * + * @param requestData + * requested data. + * @param key + * String + * @return true/false + */ + public static boolean isKeyFound(JsonNode requestData, String key) { + return (requestData.has(key)); + } + + public static String formatPhoneNumber(String phone) { + String phoneNumber = phone; + StringBuilder builder = new StringBuilder(phone); + if (phone != null && phone.trim().length() == 10) { + phoneNumber = "(" + builder.substring(0, 3) + ") " + builder.substring(3, 6) + "-" + builder.substring(6); + } + return phoneNumber; + } + + /** + * This method will remove user phone number format from (xxx) xxx-xxxx to + * xxxxxxxxxx format. + * + * @param phone + * String + * @return String + */ + public static String removePhoneNumberFormat(String phone) { + if (phone != null && phone.trim().length() > 10) { + phone = phone.replace("(", "").replace(") ", "").trim().replace("-", ""); + } + return (phone != null) ? phone.trim() : ""; + + } + + /** + * This method will check user phone number it should not empty , null and + * length should be 10 digits and it should contain all numeric value. + * + * @param phoneNumber + * @return + */ + public static boolean isPhoneNumbervalid(String phoneNumber) { + boolean response = true; + if (phoneNumber == null || "".equals(phoneNumber) || phoneNumber.trim().length() < 10 + || "0000000000".equals(phoneNumber.trim())) { + response = false; + } else { + try { + Long.parseLong(phoneNumber.trim()); + } catch (Exception e) { + response = false; + } + } + return response; + } + + /** + * This method will check provided string is null or empty if string is null or + * empty then it will provide true other wise false. + * + * @param value + * String + * @return boolean + */ + public static boolean isStringNullOrEmpty(String value) { + return (value == null || "".equals(value.trim()) || "null".equals(value.trim())); + } + + public static boolean isEmailValid(String email) { + boolean response = false; + if (ProjectUtil.isStringNullOrEmpty(email)) { + return response; + } + String[] emails = email.split("@"); + try { + String[] splitedVal = emails[1].split("[.]"); + if ("gmail".equalsIgnoreCase(splitedVal[0]) || "yahoo".equalsIgnoreCase(splitedVal[0]) + || "rediffmail".equalsIgnoreCase(splitedVal[0]) || "hotmail".equalsIgnoreCase(splitedVal[0]) + || "AOL".equalsIgnoreCase(splitedVal[0])) { + if ("com".equalsIgnoreCase(splitedVal[1])) { + response = true; + } + } else { + response = true; + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return response; + } + + /** + * This method will calculate percentage(4.75) of provided amount. + * + * @param amount + * double + * @param charge + * doubel + * @return double + */ + public static double calculatePercentage(double amount, double charge) { + return ((amount * charge) / 100); + } + + /** + * This method will crate sub string of provided String based on count. + * + * @param val + * String + * @param count + * int + * @return String + */ + public static String cutOffStringSize(String val, int count) { + if (val == null) { + return val; + } + val = val.trim(); + if (val.length() > count) { + val = val.substring(0, count); + val = val + "..."; + } + return val; + } + + public static String getRandomStringVal() { + String ALPHA_NUMERIC_STRING = "abcdefghijklmnopqrstuvwxyz0123456789"; + StringBuilder builder = new StringBuilder(); + for (int i = 0; i <= 8; i++) { + int character = (int) (Math.random() * ALPHA_NUMERIC_STRING.length()); + builder.append(ALPHA_NUMERIC_STRING.charAt(character)); + } + return builder.toString(); + + } + + /** + * This method will return random int value. + * + * @param lower + * int + * @param upper + * int + * @return int + */ + private static int getRandom(int lower, int upper) { + return (random.nextInt() * (upper - lower)) + lower; + } + + /** + * This method receives the minutes and converts it into hours in 00H:00M format + * + * @param minutes + * @return String + */ + public static String convertMinutesToHours(long minutes) { + String startTime = "00:00"; + long h = minutes / 60 + Integer.parseInt(startTime.substring(0, 1)); + long m = minutes % 60 + Integer.parseInt(startTime.substring(3, 4)); + return h + "H:" + m + "M"; + } + + public static String[] getStartAndEndDatForMonth(String date) { + String startDate = date + "-01"; + String[] ymd = startDate.split("-"); + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.DATE, 1); + cal.set(Calendar.MONTH, Integer.parseInt(ymd[1])); + cal.set(Calendar.YEAR, Integer.parseInt(ymd[0])); + cal.set(Calendar.DATE, cal.get(Calendar.DATE) - 1); + String endDate = date + "-" + cal.get(Calendar.DATE); + String[] dates = new String[2]; + dates[0] = startDate; + dates[1] = endDate; + return dates; + + } + + public static int[] getMonthAndYearFromDate(String dateString) { + int[] calender = new int[2]; + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM"); + try { + Date date = formatter.parse(dateString); + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int year = cal.get(Calendar.YEAR); + int month = cal.get(Calendar.MONTH); + calender[0] = month + 1; + calender[1] = year; + + } catch (ParseException e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return calender; + } + + public static Date getFullDate(String dateString) { + Date date = null; + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + try { + date = formatter.parse(dateString); + } catch (ParseException e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + return date; + } + + /** + * This method gets the complete file name + * + * @param fileName + * @return + */ + + public static String getAppendedDocumentName(String fileName) { + long timestamp = System.currentTimeMillis(); + String[] splitFileName = fileName.split("\\."); + String fileExtenstion = splitFileName[(splitFileName.length) - 1]; + splitFileName[splitFileName.length - 1] = ""; + StringBuilder builder = new StringBuilder(); + for (String stringPart : splitFileName) { + builder.append(stringPart); + } + return builder.toString() + "_" + Long.toString(timestamp) + "." + fileExtenstion; + + } + + public static boolean validateEmail(String email) { + boolean result = true; + try { + InternetAddress emailAddr = new InternetAddress(email); + emailAddr.validate(); + } catch (Exception ex) { + result = false; + } + return result; + } + + public static boolean validateDateFormat(String date) { + try { + return (date.matches("((?:19|20)\\d\\d)-(0?[1-9]|1[012])-([12][0-9]|3[01]|0?[1-9])")); + } catch (Exception ex) { + return false; + } + } + + public static boolean isObjectListNullOrEmpty(List<? extends Object> objectList) { + return (objectList == null) || (objectList.isEmpty()); + } + + public static boolean isObjectNull(Object object) { + return (object == null); + } + +} diff --git a/src/main/java/org/upsmf/grievance/util/ResponseCode.java b/src/main/java/org/upsmf/grievance/util/ResponseCode.java new file mode 100644 index 0000000..bcd7b40 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/ResponseCode.java @@ -0,0 +1,84 @@ +package org.upsmf.grievance.util; + +/** + * + * @author Abhishek + * + */ +public enum ResponseCode { + UNAUTHORIZED(Constants.UNAUTHORIZED_ID, Constants.UNAUTHORIZED), SUCCESS(Constants.SUCCESS_ID, + Constants.SUCCESS), FAILURE(Constants.FAILURE_ID, Constants.PROCESS_FAIL); + private static final String STRING = ""; + /** + * error code contains int value + */ + private int errorCode; + /** + * errorMessage contains proper error message. + */ + private String errorMessage; + + /** + * @param errorCode + * @param errorMessage + */ + private ResponseCode(int errorCode, String errorMessage) { + this.errorCode = errorCode; + this.errorMessage = errorMessage; + } + + /** + * + * @param errorCode + * @return + */ + public String getMessage(int errorCode) { + this.errorCode = errorCode; + return STRING; + } + + /** + * @return + */ + public int getErrorCode() { + return errorCode; + } + + /** + * @param errorCode + */ + void setErrorCode(int errorCode) { + this.errorCode = errorCode; + } + + /** + * @return + */ + public String getErrorMessage() { + return errorMessage; + } + + /** + * @param errorMessage + */ + void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + /** + * This method will provide status message based on code + * + * @param code + * @return String + */ + public static String getResponseMessage(int code) { + String value = STRING; + ResponseCode[] responseCodes = ResponseCode.values(); + for (ResponseCode actionState : responseCodes) { + if (actionState.getErrorCode() == code) { + value = actionState.getErrorMessage(); + } + } + return value; + } +} diff --git a/src/main/java/org/upsmf/grievance/util/ResponseGenerator.java b/src/main/java/org/upsmf/grievance/util/ResponseGenerator.java new file mode 100644 index 0000000..dabe076 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/ResponseGenerator.java @@ -0,0 +1,73 @@ +package org.upsmf.grievance.util; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import lombok.NoArgsConstructor; +@NoArgsConstructor +public class ResponseGenerator { + + private static ObjectMapper objectMapper = new ObjectMapper(); + + public static String failureResponse() throws JsonProcessingException { + ObjectNode actualResponse = objectMapper.createObjectNode(); + ObjectNode response = objectMapper.createObjectNode(); + response.put(JsonKey.STATUS_CODE, ResponseCode.FAILURE.getErrorCode()); + response.put(JsonKey.STATUS_MESSAGE, ResponseCode.FAILURE.getErrorMessage()); + response.put(JsonKey.ERROR_MESSAGE, ResponseCode.FAILURE.getErrorMessage()); + actualResponse.putPOJO(JsonKey.STATUS, response); + return JSONObjectUtil.getJsonString(objectMapper, actualResponse); + } + + public static String failureResponse(String message) throws JsonProcessingException { + ObjectNode actualResponse = objectMapper.createObjectNode(); + + ObjectNode response = objectMapper.createObjectNode(); + response.put(JsonKey.STATUS_CODE, ResponseCode.FAILURE.getErrorCode()); + response.put(JsonKey.STATUS_MESSAGE, ResponseCode.FAILURE.getErrorMessage()); + response.put(JsonKey.ERROR_MESSAGE, message); + actualResponse.putPOJO(JsonKey.STATUS, response); + + return JSONObjectUtil.getJsonString(objectMapper, actualResponse); + } + + /** + * this method will crate success response and send to controller. + * + * @param obj + * Object + * @return ObjectNode object. + */ + public static String successResponse(Object obj) throws JsonProcessingException { + ObjectNode actualResponse = objectMapper.createObjectNode(); + + ObjectNode response = objectMapper.createObjectNode(); + response.put(JsonKey.STATUS_CODE, ResponseCode.SUCCESS.getErrorCode()); + response.put(JsonKey.STATUS_MESSAGE, ResponseCode.SUCCESS.getErrorMessage()); + response.put(JsonKey.ERROR_MESSAGE, ""); + actualResponse.putPOJO(JsonKey.STATUS, response); + if (obj != null) { + actualResponse.putPOJO(JsonKey.RESPONSE_DATA, obj); + } + + return JSONObjectUtil.getJsonString(objectMapper, actualResponse); + } + + /** + * this method will crate success response and send to controller. + * + * @return ObjectNode object. + */ + public static String successResponse() throws JsonProcessingException { + ObjectNode actualResponse = objectMapper.createObjectNode(); + + ObjectNode response = objectMapper.createObjectNode(); + response.put(JsonKey.STATUS_CODE, ResponseCode.SUCCESS.getErrorCode()); + response.put(JsonKey.STATUS_MESSAGE, ResponseCode.SUCCESS.getErrorMessage()); + response.put(JsonKey.ERROR_MESSAGE, ""); + actualResponse.putPOJO(JsonKey.STATUS, response); + + return JSONObjectUtil.getJsonString(objectMapper, actualResponse); + } +} diff --git a/src/main/java/org/upsmf/grievance/util/ResponseMessages.java b/src/main/java/org/upsmf/grievance/util/ResponseMessages.java new file mode 100644 index 0000000..16099d0 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/ResponseMessages.java @@ -0,0 +1,58 @@ +package org.upsmf.grievance.util; + +import lombok.NoArgsConstructor; + +@NoArgsConstructor +public class ResponseMessages { + + public static final String UNAVAILABLE = "UNAVAILABLE"; + public static final String INVALID = "INVALID"; + public static final String ALREADY_EXISITS = "ALREADYEXISTS"; + public static final String INTERNAL_ERROR = "INTERNALERROR"; + + public class ErrorMessages { + final Integer CUSTOM_ERROR_ID = 9999; + public static final String ROLE_NAME_UNAVAILABLE = "Role Name is mandatory. Please add and try again"; + public static final String ROLE_ID_UNAVAILABLE = "Role ID is mandatory. Please add and try again"; + public static final String ROLE_DETAILS_UNAVAILABLE = "Role Details are not available. Please check"; + public static final String ROLE_DETAILS_NOTSAVED = "Unable to save the Role Details. Please try again later"; + public static final String USER_ROLE_MAPPING_NOTSAVED = "Unable to save the User Role mapping"; + public static final String USER_ID_UNAVAILABLE = "User ID is mandatory. Please add and try again"; + public static final String ROLE_ID_INVALID = "Role ID cannot be Zero. Please check and try again!"; + public static final String FEATURE_NAME_UNAVAILABLE = "Feature Name is mandatory. Please add and try again"; + public static final String FEATURE_CODE_UNAVAILABLE = "Feature Code is mandatory. Please add and try again"; + public static final String FEATURE_URL_UNAVAILABLE = "Feature URL is mandatory. Please add and try again"; + public static final String FEATURE_DETAILS_UNAVAILABLE = "Feature Details are not available. Please check"; + public static final String FEATURE_DETAILS_NOTSAVED = "Unable to save the Feature Details. Please try again later"; + public static final String USER_PROFILE_UNAVAILABLE = "User Profile Details are not found. Please check"; + public static final String USER_NAME_ALREADY_EXISTS = "UserName already exists. Please try with a different input"; + public static final String USER_PROFILE_ID_MANDATORY = "User Profile ID is mandatory. Please check"; + public static final String USER_PROFILE_SAVE_FAILURE = "Could not save the User Profile. Please check"; + public static final String EMAIL_PHONE_ALREADY_EXISTS = "This email or phone number already exists. Please reenter and check "; + public static final String EMAIL_MANDATORY = "Email Address is mandatory. Please enter and try again"; + public static final String LOGOUT_FAILED = "User Log Out action has failed. Please try again"; + public static final String GETALLORG_FAILED = "Couldn't fetch all the organization. Please try again later"; + public static final String UPDATE_ORG_FAILED = "Couldn't update the organization. Please check"; + public static final String GET_ORG_BY_ID_FAILED = "Couldn't fetch this organization. Please try again later"; + public static final String ADD_ORG_FAILED = "Couldn't create new organization. Please try with a different email address"; + public static final String DELETE_ORG_FAILED = "Couldn't delete this organization. Please check."; + public static final String ADDTICKET_FAILED = "Couldn't create this Ticket. Please check."; + public static final String GETALLTICKET_FAILED = "Could't fetch the tickets. Please try again later"; + public static final String UPDATETICKET_FAILED = "Couldn't update this ticket at the moment. Please check"; + public static final String GETTICKETDETAILS_FAILED = "Couldn't fetch ticket details. Please try again later"; + public static final String LOGIN_FAILED = "We couldn't log you in. Please try again later with right credentials"; + public static final String FORGOT_PSWRD_FAILED = "Something went wrong. Please enter your correct username"; + public static final String CHANGE_PSWRD_FAILED = "Couldn't change your password. Please try again with the correct passwords"; + public static final String INVALID_ACCESS_ROLE = "Role does not have access to this URL"; + public static final String UNAUTHORIZED_ACCESS = "Unauthorized Access. Please login again and try!!"; + } + + public class SuccessMessages { + public static final String ROLE_CREATED = "Role has been added successfully!"; + public static final String ROLE_UPDATED = "Role has been updated successfully!"; + public static final String USER_ROLE_MAPPED = "User has been mapped to Role"; + public static final String ACTION_ADDED = "Feature has been added successfully!"; + public static final String LOGOUT_SUCCESS = "User Logged out successfully"; + } + +} diff --git a/src/main/java/org/upsmf/grievance/util/ResponseUtil.java b/src/main/java/org/upsmf/grievance/util/ResponseUtil.java new file mode 100644 index 0000000..fc6da31 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/ResponseUtil.java @@ -0,0 +1,95 @@ +package org.upsmf.grievance.util; + +import java.io.IOException; + +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; + +import org.apache.cxf.jaxrs.ext.MessageContext; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import lombok.NoArgsConstructor; +@NoArgsConstructor +public class ResponseUtil { + + /** + * Method to throw bad request with error message + * + * @param errorDescription + */ + public static void sendBadRequest(String errorDescription) { + ResponseBuilder resp = Response.status(Response.Status.BAD_REQUEST); + resp.entity(errorDescription); + throw new WebApplicationException(resp.build()); + } + + /** + * Method to throw Unauthorized request with error message + * + * @param errorDescription + */ + public static Response sendUnauthorized(String errorDescription) throws JsonProcessingException { + ResponseBuilder resp = Response.status(Response.Status.UNAUTHORIZED); + resp.entity(ResponseGenerator.failureResponse(errorDescription)); + return resp.build(); + } + + /** + * Method to throw Internal server error + * + * @param errorDescription + */ + public static Response sendServerError(String errorDescription) { + ResponseBuilder resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR); + resp.entity(errorDescription); + return resp.build(); + } + + /** + * Method to throw Unauthorized request with error message + * + * @param errorDescription + */ + public static void unauthorizedResponse(HttpServletResponse response, String errorDescription) throws IOException { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.setContentType("application/json"); + response.getWriter().write(errorDescription); + } + + public static Response sendOK(ObjectNode obj) { + ResponseBuilder resp = Response.status(Response.Status.OK); + resp.entity(obj); + return resp.build(); + } + + public static Response sendOK(String obj) { + ResponseBuilder resp = Response.status(Response.Status.OK); + resp.entity(obj); + return resp.build(); + } + + public static void sendRedirect(MessageContext context, String path) { + try { + HttpServletResponse response = context.getHttpServletResponse(); + response.sendRedirect(path); + } catch (Exception e) { + sendServerError("Unable to redirect"); + } + } + + public static void sendInternalError(String errorDescription) throws JsonProcessingException { + ResponseBuilder resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR); + resp.entity(ResponseGenerator.failureResponse(errorDescription)); + throw new WebApplicationException(resp.build()); + } + + public static void sendInternalError() throws JsonProcessingException { + ResponseBuilder resp = Response.status(Response.Status.INTERNAL_SERVER_ERROR); + resp.entity(ResponseGenerator.failureResponse()); + throw new WebApplicationException(resp.build()); + } +} diff --git a/src/main/java/org/upsmf/grievance/util/S3FileManager.java b/src/main/java/org/upsmf/grievance/util/S3FileManager.java new file mode 100644 index 0000000..2ff0741 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/S3FileManager.java @@ -0,0 +1,77 @@ +package org.upsmf.grievance.util; + +import java.net.URL; +import java.util.Calendar; +import java.util.TimeZone; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.amazonaws.HttpMethod; +import com.amazonaws.auth.AWSCredentialsProvider; +import com.amazonaws.auth.AWSCredentialsProviderChain; +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.regions.Regions; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest; +import org.upsmf.grievance.dao.impl.SuperAdminDaoImpl; +import org.upsmf.grievance.model.S3Config; + +public class S3FileManager { + + private S3FileManager() { + super(); + } + + public static final Logger LOGGER = LoggerFactory.getLogger(SuperAdminDaoImpl.class); + + /** + * This method will remove particular file form given bucket name. + * + * @param fileName + * String + * @param bucketLocation + * String + * @return boolean + */ + + private static AmazonS3 getS3(S3Config s3Config) { + AWSCredentialsProvider provider = new AWSCredentialsProviderChain(new AWSStaticCredentialsProvider( + new BasicAWSCredentials(s3Config.getAccessKey(), s3Config.getSecretKey()))); + return AmazonS3ClientBuilder.standard().withRegion(Regions.fromName("ap-south-1")).withCredentials(provider) + .enablePathStyleAccess().build(); + } + + public static String filePath(String fileName, String folder, Long userId, Long compId) { + String key = null; + key = compId + "/" + folder + "/" + userId + "/" + fileName; + return key; + + } + + public static String attachementfilePath(String fileName, String folder, Long ticketId, Long compId) { + String key = null; + key = compId + "/" + folder + "/" + ticketId + "/" + fileName; + return key; + + } + + public static String getPreSignedURL(S3Config s3values, String path) { + try { + GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(s3values.getBucketName(), path, + HttpMethod.GET); + Calendar cal = Calendar.getInstance(); + cal.setTimeZone(TimeZone.getTimeZone("Asia/Calcutta")); + cal.add(Calendar.HOUR, 100); + request.withExpiration(cal.getTime()); + URL url = getS3(s3values).generatePresignedUrl(request); + return url.toString(); + } catch (Exception e) { + LOGGER.error(String.format("S3 url for download Error %s", e.getMessage())); + } + return null; + } + +} diff --git a/src/main/java/org/upsmf/grievance/util/SendMail.java b/src/main/java/org/upsmf/grievance/util/SendMail.java new file mode 100644 index 0000000..c21fde2 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/SendMail.java @@ -0,0 +1,209 @@ +package org.upsmf.grievance.util; + +import java.io.StringWriter; +import java.util.Map; +import java.util.Properties; + +import javax.activation.DataHandler; +import javax.activation.DataSource; +import javax.activation.FileDataSource; +import javax.mail.BodyPart; +import javax.mail.Message; +import javax.mail.Multipart; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; + +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Async; + +import lombok.NoArgsConstructor; + +/** + * this api is used to sending mail. + * + * @author Manzarul.Haque + * + */ +@NoArgsConstructor +public class SendMail { + private static final String ENCOUNTERED_AN_EXCEPTION = "Encountered an Exception : %s"; + private static final String TEXT_HTML = "text/html"; + private static final String EMAILS = "/emails/"; + public static final Logger LOGGER = LoggerFactory.getLogger(SendMail.class); + private static final String CLASSNAME = SendMail.class.getName(); + private static Properties props = null; + static { + props = System.getProperties(); + props.put("mail.smtp.host", Constants.SMTP.HOST); + props.put("mail.smtp.socketFactory.port", Constants.SMTP.PORT); + props.put("mail.smtp.auth", Constants.SMTP.SSL); + props.put("mail.smtp.port", Constants.SMTP.PORT); + } + + /** + * this method is used to send email. + * + * @param receipent + * email to whom we send mail + * @param context + * VelocityContext + * @param templateName + * String + * @param subject + * subject + */ + @Async + public static void sendMail(String[] receipent, String subject, VelocityContext context, String templateName) { + try { + Session session = Session.getInstance(props, new GMailAuthenticator(Constants.USER, Constants.PSWRD)); + MimeMessage message = new MimeMessage(session); + message.setFrom(new InternetAddress(Constants.FROM, Constants.ALIAS)); + int size = receipent.length; + int i = 0; + while (size > 0) { + message.addRecipient(Message.RecipientType.TO, new InternetAddress(receipent[i])); + i++; + size--; + } + message.setSubject(subject); + VelocityEngine engine = new VelocityEngine(); + engine.init(); + String templatePath = EMAILS; + Template template = engine.getTemplate(templatePath + templateName); + StringWriter writer = new StringWriter(); + template.merge(context, writer); + message.setContent(writer.toString(), TEXT_HTML); + Transport transport = session.getTransport("smtp"); + transport.connect(Constants.HOST, Constants.USER, Constants.PSWRD); + transport.sendMessage(message, message.getAllRecipients()); + transport.close(); + } catch (Exception e) { + LOGGER.error(e.toString(), CLASSNAME); + } + } + + /** + * this method is used to send email along with CC Recipients list. + * + * @param receipent + * email to whom we send mail + * @param context + * VelocityContext + * @param templateName + * String + * @param subject + * subject + * @param ccList + * String + */ + @Async + public static void sendMail(String[] receipent, String subject, VelocityContext context, String templateName, + String[] ccList) { + try { + Session session = Session.getInstance(props, new GMailAuthenticator(Constants.USER, Constants.PSWRD)); + MimeMessage message = new MimeMessage(session); + message.setFrom(new InternetAddress(Constants.FROM, Constants.ALIAS)); + int size = receipent.length; + int i = 0; + while (size > 0) { + message.addRecipient(Message.RecipientType.TO, new InternetAddress(receipent[i])); + i++; + size--; + } + size = ccList.length; + i = 0; + while (size > 0) { + message.addRecipient(Message.RecipientType.CC, new InternetAddress(ccList[i])); + i++; + size--; + } + message.setSubject(subject); + VelocityEngine engine = new VelocityEngine(); + engine.init(); + String templatePath = EMAILS; + Template template = engine.getTemplate(templatePath + templateName); + StringWriter writer = new StringWriter(); + template.merge(context, writer); + message.setContent(writer.toString(), TEXT_HTML); + Transport transport = session.getTransport("smtp"); + transport.connect(Constants.HOST, Constants.USER, Constants.PSWRD); + transport.sendMessage(message, message.getAllRecipients()); + transport.close(); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + } + + /** + * this method is used to send email as an attachment. + * + * @param receipent + * email to whom we send mail + * @param mail + * mail body. + * @param subject + * subject + * @param filePath + * String + */ + @Async + public static void sendAttachment(String[] receipent, String mail, String subject, String filePath) { + try { + Session session = Session.getInstance(props, + new GMailAuthenticator(Constants.SMTP.USER, Constants.SMTP.PSWRD)); + MimeMessage message = new MimeMessage(session); + message.setFrom(new InternetAddress(Constants.SMTP.USER, Constants.SMTP.ALIAS)); + int size = receipent.length; + int i = 0; + while (size > 0) { + message.addRecipient(Message.RecipientType.TO, new InternetAddress(receipent[i])); + i++; + size--; + } + message.setSubject(subject); + BodyPart messageBodyPart = new MimeBodyPart(); + messageBodyPart.setContent(mail, TEXT_HTML); + + Multipart multipart = new MimeMultipart(); + multipart.addBodyPart(messageBodyPart); + DataSource source = new FileDataSource(filePath); + messageBodyPart = new MimeBodyPart(); + messageBodyPart.setDataHandler(new DataHandler(source)); + messageBodyPart.setFileName(filePath); + multipart.addBodyPart(messageBodyPart); + message.setSubject(subject); + message.setContent(multipart); + Transport transport = session.getTransport("smtp"); + transport.connect(Constants.SMTP.HOST, Constants.SMTP.USER, Constants.SMTP.PSWRD); + transport.sendMessage(message, message.getAllRecipients()); + transport.close(); + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION, e.getMessage())); + } + } + + public static void sendMail(final Map<String, String> keyValue, final String[] emails, final String subject, + final String vmFileName) { + ExecutorManager.getExecutorService().execute(new Runnable() { + @Override + public void run() { + VelocityContext context = new VelocityContext(); + for (Map.Entry<String, String> entry : keyValue.entrySet()) { + context.put(entry.getKey(), entry.getValue()); + } + + context.put(JsonKey.LOGO_URL, Constants.LOGO_URL); + sendMail(emails, subject, context, vmFileName); + } + + }); + } +} diff --git a/src/main/java/org/upsmf/grievance/util/Sql.java b/src/main/java/org/upsmf/grievance/util/Sql.java new file mode 100644 index 0000000..ef71237 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/Sql.java @@ -0,0 +1,401 @@ +package org.upsmf.grievance.util; + +/** + * This interface will hold all the SQL Queries which are being used by the + * application Internally, the inner interface will have the queries separated + * based on the functionalities that they are associated with + * + * @author Darshan Nagesh + * + */ +public final class Sql { + + public static final String ID = "id"; + + /** + * All the queries associated with the Common activities or transactions will be + * placed here + * + * @author Darshan Nagesh + * + */ + public final class Common { + private Common() { + super(); + + } + + public static final String VERIFY_PSWRD = "SELECT id FROM user WHERE password = ? AND name = ? "; + public static final String WHERE_CLAUSE = " WHERE "; + public static final String AND_CONDITION = " AND "; + public static final String OR_CONDITION = " OR "; + public static final String OPEN_BRACE = "("; + public static final String CLOSE_BRACE = ")"; + public static final String CHECK_EMAIL_IN_USE = "SELECT id FROM user WHERE username=? AND is_active IS TRUE"; + public static final String CHECK_OLD_PSWRD = "SELECT pwd FROM password WHERE user_id=?"; + public static final String UPDATE_PSWRD = "UPDATE password SET pwd=?,updated_date=? WHERE user_id=? and pwd=?"; + public static final String CHECK_USER_BY_USERNAME = "SELECT id from user where username=?"; + public static final String SAVE_FORGOT_PSWRD = "UPDATE password SET pwd=? , updated_date=? WHERE user_id= ? "; + public static final String GET_USER_DETAIL_BY_EMAIL = "Select id, name, username, phone, is_active as isActive, created_date as createdDate, updated_date as updatedDate, img_path as imagePath from user where username=?"; + public static final String GET_ORG_ID_BY_USER_ID = "SELECT org_id FROM user JOIN user_org where user.id=user_org.user_id and user.id=?"; + public static final String GET_ALL_USERS_BY_ORG = "Select user.id, name, username, phone, is_active, img_path, created_date, updated_date from user JOIN user_org where user.id=user_org.user_id and user.is_active is true and user_org.org_id=?"; + public static final String GET_IMAGE_PATH = "SELECT img_path from user where id=?;"; + public static final String ORGADMIN = "ORGADMIN"; + public static final String ENDUSER = "ENDUSER"; + public static final String SUPER_ADMIN = "SUPERADMIN"; + } + + public final class Tags { + private Tags() { + super(); + + } + + public static final String SAVE_TICKET_TAG = "INSERT INTO tag_ticket(ticket_id,tag_id) values(?,?)"; + public static final String GET_ALL_TAGS = "SELECT id as id, tag_name as name, created_by as createdBy FROM tag"; + public static final String GET_ALL_TAG_BY_ORGANISATION = "select t.id as id, t.tag_name as name from tag t where t.org_id = ?"; + public static final String GET_ALL_TAG_BY_HELPDESK = "SELECT distinct t.id as id, t.tag_name as name FROM tag t, tag_ticket tt where tt.ticket_id in (select ticket_id from ticket,helpdesk_ticket where helpdesk_id=? and ticket.id=ticket_id and active is true) and t.id=tt.tag_id order by id;"; + public static final String GET_TAG_BY_NAME = "SELECT t.id as id, t.tag_name as name FROM tag t where t.tag_name = ? and t.org_id = (select org_id from user_org where user_id = ?)"; + public static final String TAG_ID = "id"; + public static final String SAVE_TAG = "INSERT INTO tag(tag_name, created_by, org_id) values(?, ?, ?)"; + public static final String REMOVE_TAG = "DELETE FROM tag_ticket WHERE ticket_id=? AND tag_id=?"; + public static final String DELETE_TICKET_TAGS = "DELETE FROM tag_ticket WHERE ticket_id=?"; + public static final String GET_ALL_TICKET_TAGS = "select t.id as id, t.tag_name as name, created_by as createdBy from tag t, tag_ticket tt where tt.tag_id=t.id and tt.ticket_id=? "; + + } + + public static final String SAVE_LINK_TAG = "INSERT INTO tt_tag_link(link_id,tag_id) values(?,?)"; + + public final class Organization { + private Organization() { + super(); + + } + + public static final String GET_ALL_ORG = "SELECT id, org_name as orgName, url as url, logo as logo, domain as emailDomain, color as orgColor, " + + " created_by as createdBy, created_date as createdDate, is_active as isActive, description as orgDescription FROM organization where is_active is TRUE"; + public static final String GET_ORG_BY_NAME = "SELECT id FROM organization where org_name=? and is_active=1"; + public static final String GET_ORG_BY_ID = "select id, org_name as orgName, url as url, logo as logo, domain as emailDomain, color as orgColor, created_by as createdBy, created_date as createdDate, is_active as isActive, description as orgDescription FROM organization where id = ? and is_active is true"; + public static final String AND_CONDITION = " AND "; + public static final String OR_CONDITION = " OR "; + public static final String OPEN_BRACE = "("; + public static final String CLOSE_BRACE = ")"; + public static final String ADD_NEW_ORG = "INSERT INTO organization (org_name, url, logo, created_by, updated_by, description, color, domain) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; + public static final String NEW_ORG_ADMIN_USER = "INSERT INTO user (name, username, phone, img_path) VALUES (?,?,?,?)"; + public static final String DELETE_ORG = "UPDATE organization SET is_active = FALSE , updated_by = ? , updated_date = ? WHERE id = ?"; + public static final String GET_ADMIN_BY_ORG = "SELECT DISTINCT a.id,a.name,a.username,a.phone FROM user a,organization b,roles c, user_org d, user_role e " + + "WHERE a.id = d.user_id AND a.id = e.user_id " + "AND c.id = ? AND b.id = ? AND a.is_active IS TRUE"; + public static final String GET_ROLE_ID_BY_ORG = "SELECT id FROM roles where org_id = ? and role_name = ?"; + public static final String ADD_ORG_ROLES = "insert into roles(role_name, org_id) values (?,?)"; + public static final String ADD_ROLE_PERMISSION = "insert into role_action(role_id, action_id) values (?,?)"; + public static final String NEW_ORG_ADMIN_ROLE = "INSERT INTO user_role(user_id,role_id) VALUES (?,?)"; + public static final String NEW_ORG_ADMIN_PSWRD = "INSERT INTO password (pwd, user_id) VALUES (?,?)"; + public static final String FIRST_ADMIN_COMP = "INSERT INTO user_org (org_id,user_id) VALUES (?,?)"; + public static final String UPDATE_ORG = "UPDATE organization SET org_name = ?,logo = ?,updated_date = ?,updated_by = ?,url = ?,description = ?,color = ?, domain = ? WHERE id = ?"; + public static final String GET_ORG_BY_USERID = "select user_org.org_id as id, logo from user, user_org, organization where user.id=user_org.user_id and user_org.org_id=organization.id and user.id= ?"; + public static final String CHECK_IF_ROLE_EXISTS = "select exists(select id from roles where role_name = ? and org_id = ?)"; + public static final String CHECK_IF_ACTION_EXISTS = "SELECT exists(select id from action where id=?);"; + public static final String GET_ROLE_ID_FROM_ORG = "select id from roles where role_name = ? and org_id = ?"; + public static final String DELETE_ACTION = "delete from role_action where role_id=?"; + + public static final String ORG_BY_ID = "select organization.id as id, organization.org_name as orgName, organization.url, organization.logo, organization.domain as domain, organization.color as color,organization.created_by as createdBy, organization.created_date as createdDate, organization.is_active as isActive, organization.description as description, user.id as userId, user.name, user.username, user.phone from organization, roles, user, user_org, user_role where user.id = user_org.user_id and user.id = user_role.user_id and user_org.org_id = organization.id and organization.id = roles.org_id and organization.is_active = ? and user.is_active = ? and organization.id = ? and roles.id = (select id from roles where org_id = ? and role_name = ?)"; + } + + public final class Helpdesk { + + private Helpdesk() { + super(); + + } + + public static final String CREATE_HELPDESK = "insert into helpdesk(helpdesk_name, org_id, created_by, created_date, is_active, color, description) values(?, ?, ?, ?,?,?,?)"; + public static final String UPDATE_HELPDESK = "update helpdesk set helpdesk_name = ?, updated_by = ?, updated_date = ?, is_active = ?, color = ?, description = ? where id = ? and org_id = ?"; + public static final String GET_ORG_HELPDESK = "select id, helpdesk_name as name, color from helpdesk where org_id = ? and is_active = ?"; + public static final String DELETE_WORKFLOW_FOR_HELPDESKTYPE = "delete FROM workflow_stage where type_id=?"; + public static final String DELETE_TYPE_FOR_HELPDESK = " update helpdesk_type set is_active=false WHERE helpdesk_id = ? "; + public static final String DELETE_CHECKLIST_FOR_HDTYPE = " Update checklist set is_active=false WHERE id in (select checklist_id from helpdesk_checklist where helpdesk_id = ? and helpdesk_type_id = ? ) "; + public static final String DELETE_CHECKLIST_HD_MAP = " DELETE from helpdesk_checklist WHERE helpdesk_id = ? "; + public static final String INSERT_TYPE_FOR_HELPDESK = " INSERT INTO helpdesk_type (helpdesk_id, name) values (?,?)"; + public static final String INSERT_WORKFLOW_FOR_HELPDESK_TYPE = " INSERT INTO workflow_stage (name, type_id) VALUES (?, ?) "; + public static final String INSERT_CHECKLIST_FOR_HDTYPE = " INSERT INTO checklist (name) values (?)"; + public static final String MAP_CHECKLIST_HDTYPE = " INSERT INTO helpdesk_checklist (helpdesk_id, checklist_id, helpdesk_type_id) values (?, ?, ?) "; + public static final String GET_HELPDESK_FOR_ID = " SELECT hlpdsk.id as id, hlpdsk.helpdesk_name as name, hlpdsk.is_active as isActive, hlpdsk.color as color, hlpdsk.allow_all_users, hlpdsk.description as description, hlpdsk.org_id as orgId, " + + " hlpdsktyp.id as helpdeskTypeId, hlpdsktyp.name as helpdeskType, " + + " ws.id as workflowStageId, ws.name as workflowStage " + + " FROM helpdesk hlpdsk LEFT JOIN helpdesk_type hlpdsktyp ON hlpdsk.id = hlpdsktyp.helpdesk_id " + + " LEFT JOIN workflow_stage ws ON hlpdsktyp.id = ws.type_id " + + " WHERE hlpdsk.id = ? AND hlpdsk.org_id = ? and hlpdsktyp.is_active is true"; + public static final String GET_HELPDESK_BY_ID = " SELECT hlpdsk.id as id, hlpdsk.allow_all_users as allowAllUsers, hlpdsk.org_id as orgId FROM helpdesk hlpdsk WHERE hlpdsk.id = ? and hlpdsk.is_active is true"; + + public static final String GET_CHECKLIST_FOR_HELPDESK = " SELECT cl.id as checklistId, cl.name as itemName, hcl.helpdesk_id as helpdeskId from helpdesk_checklist hcl " + + " LEFT JOIN checklist cl ON hcl.checklist_id= cl.id " + + " WHERE hcl.helpdesk_id = ? AND hcl.helpdesk_type_id = ? and cl.is_active is true"; + public static final String GET_CHECKLIST_FOR_TICKET = "SELECT c.id as id, name , checked from ticket_checklist tcl, checklist c where c.id=tcl.checklist_id and ticket_id=? and c.is_active is true;"; + public static final String GET_WORKFLOW_FOR_TICKET = "SELECT t.id, workflow_id as workFlowId, name, time, status FROM ticket_workflow t, workflow_stage w where ticket_id=? and w.id=t.workflow_id;"; + public static final String GET_WORKFLOW_FOR_TICKET_LIST = "SELECT t.id, ticket_id as ticketId, workflow_id as workFlowId, name, time, status FROM ticket_workflow t, workflow_stage w where w.id=t.workflow_id and ticket_id IN "; + + public static final String GET_HELPDESK_BY_USER_ID = "SELECT hlpdsk.id as id, hlpdsk.helpdesk_name as name, hlpdsk.is_active as isActive, hlpdsk.color as color from helpdesk hlpdsk where id IN (SELECT distinct id FROM helpdesk AS h LEFT JOIN helpdesk_admin AS ha ON h.id=ha.helpdesk_id LEFT JOIN helpdesk_users AS hu ON h.id = hu.helpdesk_id where is_active is true and (ha.user_id=? or hu.user_id=?)) or allow_all_users is true and is_active is true and org_id=?"; + public static final String GET_HELPDESK_USER_BY_ID = " SELECT id as id, name as name, username as userName, img_path from user where id IN (select user_id from helpdesk_users where helpdesk_id = ? ) "; + public static final String DELETE_CHECKLIST_FOR_TICKET = "DELETE from ticket_checklist WHERE ticket_id = ?"; + public static final String GET_HELPDESK_ADMIN_BY_ID = " SELECT id as id, name as name, username as userName, img_path from user where id IN (select user_id from helpdesk_admin where helpdesk_id = ? ) "; + public static final String GET_APP_ORG_ID = "SELECT org_id FROM organization_app where app_id=?;"; + public static final String GET_USER_DETAILS_FOR_HELPDESK = "SELECT user_id as id, name as name, username as userName, img_path from user, user_org where is_active is true and user.id=user_org.user_id and org_id=?"; + + public static final String GET_HELPDESK_ADMIN_USER = "select distinct user.id, name as name, username, img_path as imagePath" + + " from user, helpdesk_admin " + "where user.id = helpdesk_admin.user_id" + + " and helpdesk_admin.helpdesk_id = ? and user.is_active = true"; + public static final String UPDATE_HELPDESK_CHANNELS = "update helpdesk set direct = ?, playstore = ?, appstore = ?, aurora_sdk = ? where id = ? and org_id = ?"; + } + + public final class RoleAction { + private RoleAction() { + super(); + + } + + public static final String GET_ALL_ROLES = "SELECT id as id, role_name as name, org_id as orgId FROM roles"; + public static final String ORG_ID_CONDITION = " org_id = ? "; + public static final String SELECT_ROLES_ON_ID = "SELECT role_name FROM roles WHERE id= ? and org_id = ?"; + public static final String SELECT_ROLE_ACTIONS_ON_ROLEID = "SELECT action_id as actionId, role_id as roleId FROM role_action WHERE role_id=?"; + public static final String SELECT_ACTIONS_ON_ID = "SELECT * FROM action WHERE id=?"; + public static final String SAVE_NEW_ROLE = "INSERT INTO roles (role_name, org_id) VALUES (?,?)"; + public static final String UPDATE_ROLE = "UPDATE roles SET role_name = ? WHERE id = ? and org_id=?"; + public static final String GET_ALL_ACTIONS_FOR_ROLES = "select role.id as roleId, act.id as actionId, role.role_name as roleName, " + + "act.name as actionName, act.display_name as displayName, act.url as actionUrl " + + "from role_action ra LEFT JOIN roles role ON ra.role_id = role.id " + + "LEFT JOIN action act ON act.id = ra.action_id " + "where role.id IN "; + } + + public final class Apps { + private Apps() { + super(); + + } + + public static final String INSERT_NEW_APP = "INSERT into application (app_name, url, logo, sr_source_id, created_by, is_active, client_name, version, app_key, description) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + public static final String UPDATE_APP = "UPDATE application SET app_name=?, url=?, logo=?, sr_source_id=?, is_active=?, client_name=?, version=?," + + " updated_by=?, updated_date=?, app_key=?, description=? where id=?"; + public static final String GET_APP = "SELECT id as id, app_name as name, description, url as appUrl, logo as logo, created_by as createdBy, created_date as createdDate, " + + " is_active as activeStatus, client_name as clientName, version, sr_source_id as sourceId, app_key as appKey FROM application"; + public static final String ID_CONDITION = " id = ? "; + public static final String GET_ID_FROM_ORG_APP = "select exists (select id from organization_app where app_id = ? and org_id = ?)"; + public static final String MAP_APP_TO_ORG = "insert into organization_app(app_id, org_id) values(?,?);"; + public static final String DELETE_ORG_APP = "delete from organization_app where app_id = ? and org_id = ?"; + public static final String GET_ORG_APPS = "select application.id as id,application.app_name as name, application.url as appUrl, application.description as description, application.logo, application.client_name as clientName, application.version, application.sr_source_id as sourceId, application.app_key as appKey, application.is_active as activeStatus from organization_app, application where application.id = organization_app.app_id and organization_app.org_id = ? and application.is_active is true"; + public static final String GET_APP_URLS = "select distinct application.url as appUrl from organization_app, application where application.id = organization_app.app_id and organization_app.org_id = ? and application.is_active is true"; + + public static final String MAP_HELPDESK_APP = "insert into helpdesk_app(helpdesk_id, app_id) values (?,?)"; + public static final String UPDATE_HELPDESK_APP = "update helpdesk_app set is_active = ? where helpdesk_id = ? and app_id = ?"; + public static final String GET_SOURCE = " SELECT id, name FROM source "; + public static final String GET_HELPDESK_ID = "select exists(select id from helpdesk_app where helpdesk_id=? and app_id = ?)"; + public static final String GET_APP_ID_APP_KEY = "select id FROM application where url = ? and is_active is true;"; + public static final String CHECK_IF_APP_NAME_EXISTS = "select exists(select id FROM application where url = ? and is_active is true);"; + public static final String CHECK_IF_TICKET_EXIST = "select exists(select id from ticket where description = ? and active is true and requested_by in (select id from user where username=? and is_active is true) LIMIT 1);"; + public static final String CHECK_IF_TICKET_EXISTS = "select exists(select id from ticket where reviewId = ? and active is true and requested_by in (select id from user where username=? and is_active is true) LIMIT 1);"; + public static final String GET_APP_ID_FROM_APP_KEY = "select id FROM application where app_key = ? and is_active is true;"; + + public static final String CHECK_IF_UPDATE_EXISTS = "select exists(select id from ticket_updates where updates = ? and active is true and created_date=? limit 1);"; + public static final String GET_REQUESTED_BY = "select requested_by from ticket where id=? and active is true"; + public static final String CHECK_GET_APP_ID_FROM_APP_KEY = "select exists(select id FROM application where app_key = ? and is_active is true);"; + public static final String GET_ORG_ID_FROM_APP_ID = "SELECT org_id as orgId FROM organization_app where app_id=?;"; + public static final String GET_HELPDESK_ID_FROM_APP_ID = "select helpdesk_id from helpdesk_app where app_id = ? and is_active is true LIMIT 1"; + + } + + public final class UserQueries { + private UserQueries() { + super(); + + } + + public static final String SELECT_USER_BY_TOKEN = "SELECT \"user\".id as id FROM \"user\",\"user_authentication\" WHERE auth_token = ? and \"user\".is_active is true and \"user\".id=user_authentication.user_id;"; + public static final String SELECT_USER_ON_USERNAME = "SELECT user.id as id, user.name as name, user.username as username, user_org.org_id as orgId, " + + " user.is_active as isActive, pwd.pwd as password from user, user_org, password pwd where " + + " user.id = user_org.user_id and pwd.user_id = user.id and username = ?"; + public static final String SELECT_USER_ROLES_ON_USERNAME = "SELECT usr.id as id, usr.name as name, usr.username as username, usr.is_active as isActive, " + + " usrorg.org_id as orgId, " + " pwd.pwd as password, " + + " role.role_name as roleName, role.id as roleId, role.org_id as roleOrgId " + + " from user usr LEFT JOIN user_org usrorg ON usr.id = usrorg.user_id " + + " LEFT JOIN password pwd ON pwd.user_id = usr.id " + + " LEFT JOIN user_role usrrole ON usr.id = usrrole.user_id " + + " LEFT JOIN roles role ON usrrole.role_id = role.id " + Common.WHERE_CLAUSE + + " role.org_id = usrorg.org_id and usr.username = ?"; + public static final String SELECT_USER_ROLES_ACTIONS_ON_USERNAME = "SELECT usr.id as id, usr.name as name, usr.username as username, usr.is_active as isActive, " + + " usrorg.org_id as orgId, " + " pwd.pwd as password, " + + " role.role_name as roleName, role.id as roleId, role.org_id as roleOrgId, " + + " actn.id as actionId, actn.name as actionName, actn.display_name as actionDisplayName, actn.query_params as actionQueryParams, " + + " actn.service_code as actionServiceCode, actn.url as actionUrl " + + " from user usr LEFT JOIN user_org usrorg ON usr.id = usrorg.user_id " + + " LEFT JOIN password pwd ON pwd.user_id = usr.id " + + " LEFT JOIN user_role usrrole ON usr.id = usrrole.user_id " + + " LEFT JOIN roles role ON usrrole.role_id = role.id " + + " LEFT JOIN role_action rolactn ON role.id = rolactn.role_id " + + " LEFT JOIN action actn ON rolactn.action_id = actn.id " + Common.WHERE_CLAUSE + + " role.org_id = usrorg.org_id and usr.username = ? "; + public static final String MAP_USER_TO_ROLE = "INSERT INTO user_role (user_id, role_id) VALUES (?, ?)"; + public static final String REMOVE_USER_ROLE_MAP = "DELETE FROM user_role WHERE user_id = ? "; + + public static final String UPDATE_USER_PROFILE_PROFILE_IMAGE = "UPDATE user SET img_path = ? WHERE id = ?"; + + public static final String GET_USER_ACTIONS = "Select action.id, action.display_name as displayName, name, url from action inner join role_action on role_action.action_id = action.id where role_action.role_id = ?"; + public static final String USER_PROFILE_FETCH = "select * from user usr where id=? "; + public static final String USER_DATA = "select COUNT(*) from user where username=?"; + public static final String USER = "select * from user where id=?"; + public static final String GET_USER_AUTH_DETAILS = "SELECT id, user_id as userId, auth_token FROM user_authentication WHERE id=?"; + public static final String SAVE_USER = "INSERT INTO user(name,username,phone,img_path) VALUES (?,?,?,?)"; + public static final String SAVE_ANONYMOUS_USER = "INSERT INTO user(name,username,phone,img_path,is_anonymous) VALUES (?,?,?,?,?)"; + public static final String SAVE_USER_AUTHENTICATION = "INSERT INTO user_authentication(user_id,auth_token) VALUES (?,?)"; + public static final String GET_USER_ROLE = "SELECT user_id, role_id FROM retail_user_role WHERE user_id=?"; + public static final String GET_ROLES_FOR_USER = "select ur.role_id as roleId, r.role_name as roleName from roles r, user_role ur where r.id = ur.role_id and ur.user_id = ?"; + public static final String USER_ACTIVE_CONDITION = " WHERE usr.is_active = ? "; + public static final String WHERE_CLAUSE = " WHERE "; + public static final String AND_CONDITION = " AND "; + public static final String OR_CONDITION = " OR "; + + public static final String UPDATE_USER = "UPDATE user SET name = ?,username = ?, phone = ?, is_active = ?, img_path = ? where id = ? "; + public static final String GET_USER_COUNT = "SELECT count(*) FROM user usr"; + public static final String GET_USER_COUNT_ON_ACTIVE_STATUS = "SELECT count(*) FROM user usr where usr.is_active = ? "; + public static final String GET_USER_COUNT_FOR_ROLE = "SELECT count(*) FROM user usr LEFT JOIN user_role ur ON usr.id = ur.user_id where ur.role_id = ? and usr.is_active IS TRUE"; + public static final String GET_ROLE_COUNT = "SELECT count(*) FROM roles"; + + public static final String INVALIDATE_TOKEN = "DELETE from user_authentication WHERE auth_token = ? "; + public static final String FETCH_AUTH_TOKEN_REF = "SELECT id FROM user_authentication WHERE auth_token = ? "; + public static final String CHECK_USER_DEVICE_TOKEN = "SELECT COUNT(*) FROM user_device WHERE user_id = ? AND device_token = ? "; + public static final String INSERT_PD = "insert into password(pwd, user_id) values(?,?)"; + public static final String INSERT_ACTION = "INSERT INTO action(`id`,`name`,`display_name`,`url`) VALUES(?,?,?,?);"; + public static final String UPDATE_ACTION = "UPDATE action set name=?, display_name=?, url=? where id=?"; + public static final String GET_AUTH_TYPE_ID = "select aut_id from organization_auth where org_id = ?"; + public static final String CHECK_FIRST_ADMIN = "SELECT org_id FROM user_org WHERE user_id=?"; + public static final String GET_MASTER_DATA_CHECK = "SELECT COUNT(user_id) as id FROM user_org WHERE org_id = ? "; + public static final String NEW_ORG_AUTH = "Insert into organization_auth(org_id, aut_id, base_url, email_domain) values (?,?,?,?)"; + public static final String GET_ROLE_ID_BY_ORG = "SELECT id FROM roles where org_id = ? and role_name = ?"; + public static final String ADD_ADMIN = "UPDATE user_role SET role_id = ? WHERE user_id = ?"; + public static final String DELETE_ADMIN = "UPDATE user_role SET role_id = ? WHERE user_id = ?"; + public static final String MAP_USER_TO_ORG = "Insert into user_org(user_id,org_id) values (?,?)"; + public static final String GET_HELPDESK_ADMINS = "select user_id from helpdesk_admin where helpdesk_id=? "; + public static final String GET_TICKET_CC = "select user_id from ticket_cc where ticket_id=? "; + public static final String GET_TICKET_ATTACHMENT = "select url from ticket_attachment,attachment_url where ticket_id=? and ticket_attachment.attachment_id=attachment_url.id;"; + public static final String REMOVE_ALL_HELPDESK_ADMIN = "DELETE FROM helpdesk_admin where helpdesk_id=?"; + public static final String REMOVE_ALL_USERS_FROM_HELPDESK = "DELETE FROM helpdesk_users where helpdesk_id=?"; + public static final String REMOVE_ALL_TICKET_CC = "DELETE FROM ticket_cc where ticket_id=?"; + public static final String REMOVE_ALL_HELPDESK_SOURCE = "DELETE FROM helpdesk_source where helpdesk_id=?"; + public static final String ADD_ADMINS_TO_HELPDESK = "insert into helpdesk_admin(helpdesk_id,user_id) values (?,?)"; + public static final String ADD_USERS_TO_HELPDESK = "insert into helpdesk_users(helpdesk_id,user_id) values (?,?)"; + public static final String ADD_CC_TO_TICKET = "insert into ticket_cc(ticket_id,user_id) values (?,?)"; + public static final String GET_USER_ORG_MAP = "SELECT user_org.id as id , user_id as userId , org_id as orgId FROM \"user\", \"user_org\" where \"user\".id=user_org.user_id and \"user\".is_anonymous is false;"; + public static final String GET_USER_ROLE_MAP = "SELECT id as id, user_id as userId, role_id as roleId FROM user_role "; + public static final String GET_APP_ID_HELPDESK_ID = "select helpdesk_id as helpdeskId,app_id as appId from helpdesk_app where is_active is true;"; + public static final String GET_APP_ID_APP_OBJECT = "SELECT id,app_name as name,logo,url FROM application;"; + public static final String GET_HELPDESK_ID_HELPDESK_OBJECT = "SELECT id,helpdesk_name as name,org_id as orgId FROM helpdesk where is_active is true "; + public static final String GET_USER_ID_AND_USER_NAME = "SELECT id,name FROM \"user\" where is_active is true;"; + public static final String UPDATE_ALLOW_ALL_USERS = "UPDATE helpdesk SET allow_all_users = ? WHERE id = ?"; + public static final String REMOVE_ALL_TICKET_ATTACHMENT = "DELETE FROM ticket_attachment where ticket_id=?"; + public static final String GET_HELPDESK_CHANNELS = "SELECT direct, playstore, appstore, aurora_sdk FROM helpdesk where id=? and is_active is true "; + + public static final String QUERY1 = "SELECT toa.aut_id as id, toa.base_url as name, auth_name as description from organization_auth toa, "; + public static final String QUERY2 = " authentication auth WHERE toa.aut_id = auth.id AND toa.org_id = "; + public static final String QUERY3 = " AND toa.is_active IS TRUE "; + } + + public final class Ticket { + private Ticket() { + super(); + + } + + public static final String ADD_SOURCE_TO_HELPDESK = "INSERT INTO helpdesk_source(helpdesk_id, source_id) VALUES (?,?);"; + public static final String ADD_TICKET = "insert into ticket(created_time, rate, max_rating, priority, requested_by, description, type, updated_time, pinned_ticket) values(?,?,?,?,?,?,?,?,?);"; + public static final String ADD_TICKET_TO_HELPDESK = "INSERT INTO helpdesk_ticket(ticket_id, sr_source_id, helpdesk_id, app_id) VALUES (?,?,?,?);"; + public static final String UPDATE_TICKET = "update ticket set priority=?, notes=?, active=?, updated_time=? where id=?"; + public static final String UPDATE_TICKET_REVIEW_ID = "update ticket set reviewId=? where id=?"; + public static final String GET_ALL_TICKETS = "SELECT t.id, t.created_time as createdTime, t.updated_time as updatedTime, t.rate, t.max_rating as maxRating, t.priority, requested_by as requestedBy, description, notes , pinned_ticket as pinnedTicket from ticket t where requested_by = ? and active is true;"; + public static final String GET_TICKET_BY_ID = "select t.id, pinned_ticket as pinnedTicket, created_time as createdTime, updated_time as updatedTime, rate, max_rating as maxRating, priority, requested_by as requestedBy, description, notes, type, sr_source_id as sourceId, helpdesk_id as helpdeskId, app_id as appId, active from ticket t, helpdesk_ticket ht where t.id = ? and t.id=ht.ticket_id and active is true;"; + public static final String GET_ALL_TICKETS_BY_HELPDESK_ID = "select t.id as id, pinned_ticket as pinnedTicket, created_time as createdTime, updated_time as updatedTime, rate, max_rating as maxRating, priority, requested_by as requestedBy, description from ticket t, helpdesk_ticket ht where t.active is true and ht.helpdesk_id=? and t.id=ht.ticket_id order by t.id desc;"; + public static final String GET_ALL_TICKETS_BY_APP_ID = "select t.id as id, pinned_ticket as pinnedTicket, created_time as createdTime, updated_time as updatedTime, rate, max_rating as maxRating, priority, requested_by as requestedBy, description from ticket t, helpdesk_ticket ht where t.active is true and ht.app_id=? and t.id=ht.ticket_id order by t.id desc;"; + public static final String UPDATE_STATUS = "update tt_ticket set status=? where id=?"; + public static final String CLOSE_TICKET = "update tt_ticket set closed_by=?,closed_time=current_timestamp,is_closed=true where id=?;"; + public static final String APPROVE_TICKET = "update tt_ticket set updated_by=?,updated_time=current_timestamp,is_approved=true where id=?;"; + public static final String GET_VERSION_FOR_TEMPLATES = "SELECT version FROM template_version "; + public static final String UPDATE_VERSION_TIMESTAMP = " UPDATE template_version SET version = ? "; + public static final String UPDATE_NOTES_TO_TICKETS = "update ticket set notes=? where id=?"; + public static final String UPDATE_UPDATES = "update ticket_updates set updates=?, active=?, created_date=? where id=?"; + public static final String ADD_UPDATES = "insert into ticket_updates(updates,created_by,ticket_id,created_date) values(?,?,?,?);"; + public static final String INSERT_TYPE_FOR_TICKETS = " INSERT INTO ticket_details (ticket_id, info_type) values (?,?)"; + public static final String INSERT_WORKFLOW_FOR_TICKET_TYPE = " INSERT INTO ticket_workflow (workflow_id, ticket_id) VALUES (?, ?) "; + public static final String INSERT_CHECKLIST_FOR_TICKET_TYPE = " INSERT INTO ticket_checklist (ticket_id, checklist_id) VALUES (?, ?)"; + public static final String DELETE_WORKFLOW_FOR_TICKET_TYPE = "delete FROM ticket_workflow where ticket_id=?"; + public static final String GET_DEFAULT_TICKET_TYPE = "SELECT min(id) as id FROM helpdesk_type where helpdesk_id=? and is_active is true;"; + public static final String GET_DEFAULT_ADMIN_ID = "SELECT user_id as id FROM helpdesk_admin where helpdesk_id=? LIMIT 1;"; + public static final String UPDATE_TICKET_WORKFLOW = "update ticket_workflow set status=?, time=? where workflow_id=? and ticket_id=?"; + public static final String GET_UPDATES = "SELECT created_by as createdBy, updates as upds, created_date as createdDate FROM ticket_updates where ticket_id=? and active is true order by id asc; "; + public static final String UPDATE_TICKET_TYPE = "update ticket set type=? where id=?;"; + public static final String UPDATE_TICKET_CHECKLIST = "update ticket_checklist set checked=? where checklist_id=? and ticket_id=?"; + public static final String ADD_ACTIVITY_LOG = "INSERT INTO activity_logs(activity, ticket_id, timestamp, changes_by) VALUES (?,?,?,?);"; + public static final String GET_ACTIVITY_LOGS = "select id,activity,ticket_id as ticketId, timestamp, changes_by as changesBy from activity_logs where ticket_id=?"; + public static final String GET_WORKFLOW_NAME = "SELECT name FROM workflow_stage where id=?;"; + public static final String UPDATE_TICKET_DESCRIPTION = "update ticket set description=? where id=?"; + public static final String UPDATE_TICKET_PIN = "update ticket set pinned_ticket=? where id=?"; + public static final String GET_REVIEW_ID = "SELECT reviewId FROM ticket where id=? and active is true;"; + public static final String GET_ORG_ID_FROM_TICKET_ID = "SELECT org_id from helpdesk where id in (select helpdesk_id FROM helpdesk_ticket where ticket_id=?) limit 1;"; + public static final String GET_APP_URL_FROM_TICKET_ID = "select url from application where id in (select app_id FROM helpdesk_ticket where ticket_id=?);"; + + public static final String GET_ACTIVITY_LOGS_PER_USER = "select activity_logs.id,activity,activity_logs.ticket_id as ticketId, timestamp, changes_by as changesBy, helpdesk_id as helpdeskId from activity_logs, helpdesk_ticket where activity_logs.ticket_id=helpdesk_ticket.ticket_id and activity_logs.ticket_id in (SELECT distinct t.id from ticket t where (requested_by = ? or (id in (select ticket_id from ticket_cc where user_id = ?))) and active is true) order by id desc;"; + + public static final String GET_CREATED_AND_COPIED_TO_TICKET_IDS = "SELECT distinct t.id from ticket t where requested_by = ? or (id in (select ticket_id from ticket_cc where user_id = ?)) and active is true;"; + public static final String GET_CREATED_AND_COPIED_TO_TICKET_IDS_BY_HELPDESK_ID = "SELECT distinct t.id from ticket t, helpdesk_ticket where (requested_by = ? or (t.id in (select ticket_id from ticket_cc where user_id = ?))) and helpdesk_ticket.ticket_id=t.id and helpdesk_ticket.helpdesk_id=? and active is true"; + public static final String GET_TICKETS_BY_TAGS = "SELECT distinct ticket_id as id FROM tag_ticket where tag_ticket.tag_id in (select id from tag where tag_name in "; + public static final String GET_HELPDESK_ID_FOR_TICKET = "select helpdesk.id from helpdesk_ticket,helpdesk where ticket_id=? and helpdesk.id=helpdesk_ticket.helpdesk_id and helpdesk.is_active is true;"; + public static final String STATUS = "status.keyword"; + public static final String ACTIVE = "active"; + public static final String DESCRIPTION = "description"; + public static final String HELPDESK_ID = "helpdeskId"; + public static final String TAGS = "tags.keyword"; + public static final String CC = "cc.keyword"; + public static final String SOURCE_ID = "sourceId"; + public static final String GET_TICKET_IDS_BY_HELPDESK_ID = "SELECT distinct t.id from ticket t, helpdesk_ticket where helpdesk_ticket.ticket_id=t.id and helpdesk_ticket.helpdesk_id=? and active is true;"; + + public static final String GET_TICKET_DETAILS_BY_HELPDESK = "select tkt.id as ticketId, tkt.pinned_ticket as pinnedTicket, tkt.created_time as createdTime, tkt.updated_time as updatedTime, " + + " tkt.rate as rate, tkt.max_rating as maxRating, tkt.priority as priority, tkt.requested_by as requestedBy, " + + " tkt.description as decription, tkt.notes as notes, tkt.type as type, tkt.active as active, " + + " ht.sr_source_id as sourceId, ht.helpdesk_id as helpdeskId, ht.app_id as appId, " + + " tcc.user_id as tktCCUserId, " + + " clist.id as clistId, clist.name as clistName, tcl.checked as tclChecked " + + " from ticket tkt LEFT JOIN helpdesk_ticket ht ON tkt.id=ht.ticket_id " + + " LEFT JOIN ticket_cc tcc ON tkt.id = tcc.ticket_id " + + " LEFT JOIN ticket_checklist tcl ON tkt.id = tcl.ticket_id " + + " LEFT JOIN checklist clist ON tcl.checklist_id = clist.id " + + " where ht.helpdesk_id = ? and active is true"; + public static final String REQUESTEDBY = "requestedBy"; + } + + public static final String GET_USER_ACTIONS = "SELECT * FROM retail_actions ma inner join retail_role_actions mra on mra.action_id = ma.id where ma.enabled = true and mra.role_id = ? order by ma.order_number"; + public static final String GET_USER_AUTH_DETAILS = "SELECT id, user_id, auth_token FROM user_authentication WHERE id=?"; + public static final String SAVE_USER = "INSERT INTO user(name,username,password) VALUES (?,?,?)"; + public static final String SAVE_USER_AUTHENTICATION = "INSERT INTO user_authentication(user_id,auth_token) VALUES (?,?)"; + public static final String GET_USER_ROLE = "SELECT user_id, role_id FROM retail_user_role WHERE user_id=?"; + public static final String GET_ROLES_FOR_USER = " select mur.user_id, mur.role_id, mr.role_name, mr.description, mr.priority from retail_user_role mur LEFT JOIN retail_role mr ON mur.role_id = mr.id " + + " WHERE mur.user_id = ? "; + public static final String USER_ACTIVE_CONDITION = " WHERE usr.is_active = ? "; + public static final String WHERE_CLAUSE = " WHERE "; + public static final String AND_CONDITION = " AND "; + public static final String OR_CONDITION = " OR "; + + public static final String UPDATE_USER = "UPDATE user SET name = ?, username = ? , is_active = ? where id = ? "; + public static final String UPDATE_USER_PROFILE = "UPDATE user_profile SET name = ?, email = ?, phone_number = ?," + + " updated_by = ? WHERE user_id = ? "; + public static final String GET_USER_COUNT = "SELECT count(*) FROM user usr"; + public static final String GET_USER_COUNT_ON_ACTIVE_STATUS = "SELECT count(*) FROM user usr where usr.is_active = ? "; + public static final String GET_USER_COUNT_FOR_ROLE = "SELECT count(*) FROM user usr LEFT JOIN retail_user_role usrrole ON usr.id = usrrole.user_id where usrrole.role_id = ? " + + "and usr.is_active IS TRUE"; + public static final String GET_ROLE_COUNT = "SELECT count(*) FROM retail_role"; + + public static final String INVALIDATE_TOKEN = "DELETE from user_authentication WHERE auth_token = ? "; + public static final String FETCH_AUTH_TOKEN_REF = "SELECT id FROM user_authentication WHERE auth_token = ? "; + public static final String CHECK_USER_DEVICE_TOKEN = "SELECT COUNT(*) FROM user_device WHERE user_id = ? AND device_token = ? "; + public static final String GET_S3_ACCESS = "SELECT access_key as accessKey,secret_key as secretKey,bucket_name as bucketName FROM s3_config WHERE id = 1"; + public static final String GET_CONFIG = "SELECT client_id as clientId,client_secret as clientSecret,refresh_token as refreshToken FROM review_config where org_id=?;"; + public static final String INSERT_PROFILE_PICTURE = "UPDATE user set img_path=? WHERE id=?"; + public static final String GET_DP = "SELECT img_path FROM user WHERE id=?"; + public static final String ADD_ATTACHMENT_TO_TICKET = "insert into ticket_attachment(ticket_id, attachment_id) values (?,?);"; + public static final String INSERT_ATTACHMENT = "insert into attachment_url(url) values (?);"; +} diff --git a/src/main/java/org/upsmf/grievance/util/SqlConstants.java b/src/main/java/org/upsmf/grievance/util/SqlConstants.java new file mode 100644 index 0000000..5452b48 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/SqlConstants.java @@ -0,0 +1,86 @@ +package org.upsmf.grievance.util; + +public final class SqlConstants { + + public final class DbAttributes { + private DbAttributes() { + super(); + } + + public static final String ID = "id"; + public static final String NAME = "name"; + public static final String USERNAME = "username"; + public static final String ISACTIVE = "isActive"; + public static final String PSWRD = "password"; + public static final String ORGID = "orgId"; + public static final String USERID = "userId"; + + public static final String ROLEID = "roleId"; + public static final String ROLENAME = "roleName"; + public static final String ROLEORGID = "roleOrgId"; + + public static final String ACTIONID = "actionId"; + public static final String ACTIONNAME = "actionName"; + public static final String ACTIONDISPLAYNAME = "actionDisplayName"; + public static final String ACTIONQUERYPARAMS = "actionQueryParams"; + public static final String ACTIONSERVICECODE = "actionServiceCode"; + public static final String ACTIONURL = "actionUrl"; + + public static final String ROLEORORG = "roleOrOrg"; + + public static final String LOGO = "logo"; + public static final String URL = "url"; + + public static final String ORGNAME = "orgName"; + public static final String DOMAIN = "domain"; + public static final String COLOR = "color"; + public static final String CREATEDBY = "createdBy"; + public static final String CREATEDDATE = "createdDate"; + public static final String DESCRIPTION = "description"; + + public static final String HELPDESKTYPEID = "helpdeskTypeId"; + public static final String HELPDESKTYPE = "helpdeskType"; + public static final String WORKFLOWSTAGEID = "workflowStageId"; + public static final String WORKFLOWSTAGE = "workflowStage"; + public static final String CHECKLISTID = "checklistId"; + public static final String CHECKLISTNAME = "checklistName"; + + public static final String ITEMNAME = "itemName"; + public static final String HELPDESKID = "helpdeskId"; + + public static final String TICKETID = "ticketId"; + public static final String APPVERSION = "appVersion"; + public static final String PINNEDTICKET = "pinnedTicket"; + public static final String CREATEDTIME = "createdTime"; + public static final String UPDATEDTIME = "updatedTime"; + public static final String RATING = "rate"; + public static final String MAXRATING = "maxRating"; + public static final String PRIORITY = "priority"; + public static final String REQUESTEDBY = "requestedBy"; + public static final String ASSIGNEDTO = "assignedTo"; + public static final String NOTES = "notes"; + public static final String TYPE = "type"; + public static final String ACTIVE = "active"; + public static final String SOURCEID = "sourceId"; + public static final String APPID = "appId"; + public static final String TKTCCUSERID = "tktCCUserId"; + public static final String CLISTID = "clistId"; + public static final String CLISTNAME = "clistName"; + public static final String TCLCHECKED = "tclChecked"; + public static final String PHONE = "phone"; + public static final String IMAGE_PATH = "img_path"; + public static final String TICKET_ID = "ticketId"; + public static final String STATUS = "status"; + public static final String TIME = "time"; + public static final String WORKFLOWID = "workFlowId"; + public static final String IS_ACTIVE = "is_active"; + public static final String CREATED_DATE = "created_date"; + public static final String UPDATED_DATE = "updated_date"; + public static final String AUTH_TOKEN = "auth_token"; + public static final String DISPLAY_NAME = "display_name"; + public static final String CHECKED = "checked"; + public static final String ALLOW_ALL_USERS = "allow_all_users"; + + } + +} diff --git a/src/main/java/org/upsmf/grievance/util/executor/FetchReviewsWeeklyJob.java b/src/main/java/org/upsmf/grievance/util/executor/FetchReviewsWeeklyJob.java new file mode 100644 index 0000000..d978b67 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/executor/FetchReviewsWeeklyJob.java @@ -0,0 +1,33 @@ +package org.upsmf.grievance.util.executor; + +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import org.upsmf.grievance.dao.TicketDao; +import org.upsmf.grievance.dao.UserDao; + +public class FetchReviewsWeeklyJob implements Job { + public static final Logger LOGGER = LoggerFactory.getLogger(FetchReviewsWeeklyJob.class); + private static final String CLASSNAME = FetchReviewsWeeklyJob.class.getName(); + + @Autowired + private UserDao userDao; + + @Autowired + private TicketDao ticketDao; + + @Override + public void execute(JobExecutionContext ctx) throws JobExecutionException { + try { + userDao.getReviews(); + ticketDao.getFeedBacksFromAuroraSdk(); + } catch (Exception e) { + LOGGER.error(e.getMessage(), CLASSNAME); + } + } + +} diff --git a/src/main/java/org/upsmf/grievance/util/executor/ReviewsSchedulerManager.java b/src/main/java/org/upsmf/grievance/util/executor/ReviewsSchedulerManager.java new file mode 100644 index 0000000..58c2b9f --- /dev/null +++ b/src/main/java/org/upsmf/grievance/util/executor/ReviewsSchedulerManager.java @@ -0,0 +1,38 @@ +package org.upsmf.grievance.util.executor; + +import org.quartz.CronScheduleBuilder; +import org.quartz.JobBuilder; +import org.quartz.JobDetail; +import org.quartz.Scheduler; +import org.quartz.Trigger; +import org.quartz.TriggerBuilder; +import org.quartz.impl.StdSchedulerFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ReviewsSchedulerManager { + private static final String CLASSNAME = ReviewsSchedulerManager.class.getName(); + public static final Logger LOGGER = LoggerFactory.getLogger(FetchReviewsWeeklyJob.class); + + /** + * scheduler job is configured here + */ + public static void schedule() { + JobDetail weeklyJob = JobBuilder.newJob(FetchReviewsWeeklyJob.class) + .withIdentity("WeeklyFetchReviews", "WeeklyFetchReviewsData").build(); + Trigger weeklyTrigger = TriggerBuilder.newTrigger().withIdentity("FetchReviewsWeekly", "FetchReviewsDataWeekly") + .withSchedule(CronScheduleBuilder.cronSchedule("0 0 8 ? * SUN *")).build(); + try { + Scheduler scheduler = new StdSchedulerFactory().getScheduler(); + scheduler.start(); + scheduler.scheduleJob(weeklyJob, weeklyTrigger); + } catch (Exception e) { + LOGGER.error(e.getMessage(), CLASSNAME); + } + + } + + private ReviewsSchedulerManager() { + super(); + } +} \ No newline at end of file diff --git a/src/main/resources/accesstokenspec.json b/src/main/resources/accesstokenspec.json new file mode 100644 index 0000000..646e55a --- /dev/null +++ b/src/main/resources/accesstokenspec.json @@ -0,0 +1,11 @@ +[ + { + "operation": "shift", + "spec": { + "access_token": "accessToken", + "expires_in": "expiresIn", + "scope": "scope", + "token_type": "tokenType" + } + } +] \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..a10bd9f --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,38 @@ +# SET CONTEXT PATH +server.port=8085 +spring.main.allow-bean-definition-overriding=true + +spring.http.multipart.max-file-size=10MB +spring.http.multipart.max-request-size=10MB + +spring.datasource.url=jdbc:postgresql://localhost:5432/postgres +spring.datasource.username=postgres +spring.datasource.password=mysecretpassword +spring.datasource.driver-class-name=org.postgresql.Driver +spring.jpa.hibernate.ddl-auto=none +spring.datasource.initialization-mode=always +spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true + +urls.whitelist=/,/user/login,/user/logout,/signup,/token/validate,/upload,/user/forgotPassword,/superadmin/getAuthTypes,/tickets/getTemplateVersion,/user/updateEkstepUser,/superadmin/addOrganization,/helpdesk/getPerformanceWithoutAccessControl + +services.esindexer.host=es.rain.idc.tarento.com +services.esindexer.host.name=http://es.rain.idc.tarento.com/ +services.esindexer.host.port=9200 +services.esindexer.username=elastic +services.esindexer.password=Elastic123 +es.templates.index.name=tkt_templates +es.templates.document.type=tkt_templates +elasticsearch.url=elasticsearch-dev.idc.tarento.com +elasticsearch.index=ticket-prod +elasticsearch.type=doc + + +elk.data.up=true + +image.source.aws=true +image.source.attachment.aws=true + + + + + diff --git a/src/main/resources/application.properties.j2 b/src/main/resources/application.properties.j2 new file mode 100644 index 0000000..064498f --- /dev/null +++ b/src/main/resources/application.properties.j2 @@ -0,0 +1,32 @@ +# SET CONTEXT PATH +server.port=8081 + + +spring.datasource.driver-class-name=com.mysql.jdbc.Driver +spring.datasource.url=jdbc:mysql://localhost:3306/aurora_desk?autoReconnect=true&zeroDateTimeBehavior=convertToNull +spring.datasource.username={{ datasource_user | b64decode }} +spring.datasource.password={{ datasource_pwd | b64decode }} +spring.http.multipart.max-file-size=10MB +spring.http.multipart.max-request-size=10MB + +urls.whitelist=/,/user/login,/user/logout,/signup,/token/validate,/upload,/user/forgotPassword,/superadmin/getAuthTypes,/tickets/getTemplateVersion,/user/updateEkstepUser,/superadmin/addOrganization,/helpdesk/getPerformanceWithoutAccessControl + +services.esindexer.host={{ es_host | b64decode }} +services.esindexer.host.name={{ es_host_name | b64decode }} +services.esindexer.host.port=9200 +services.esindexer.username={{ es_user | b64decode }} +services.esindexer.password={{ es_pwd | b64decode }} +es.templates.index.name=tkt_templates +es.templates.document.type=tkt_templates +elasticsearch.url=elasticsearch-dev.idc.tarento.com +elasticsearch.index=aurora-ticket +elasticsearch.type=doc + +elk.data.up=true + +image.source.aws=true +image.source.attachment.aws=true + + + + diff --git a/src/main/resources/reviewspec.json b/src/main/resources/reviewspec.json new file mode 100644 index 0000000..80743dd --- /dev/null +++ b/src/main/resources/reviewspec.json @@ -0,0 +1,43 @@ +[ + { + "operation": "shift", + "spec": { + "authorName": "userName", + "reviewId": "reviewId", + "comments": { + "0": { + "userComment": { + "text": "feedback", + "starRating": "rate", + "lastModified": { + "seconds": "userTimestamp" + }, + "androidOsVersion": "osVersion", + "appVersionName": "appVersion", + "deviceMetadata": { + "productName": "deviceName", + "manufacturer": "deviceManufacture", + "deviceClass": "deviceType" + } + } + }, + "*": { + "developerComment": { + "text": "developerComment", + "lastModified": { + "seconds": "developerTimestamp" + } + } + } + } + } + }, + { + "operation": "default", + "spec": { + "maxRating": "5", + "sourceId": "4", + "pinnedTicket": "false" + } + } +] diff --git a/src/test/java/org/upsmf/grievance/dao/impl/ApplicatioDaoImplTest.java b/src/test/java/org/upsmf/grievance/dao/impl/ApplicatioDaoImplTest.java new file mode 100644 index 0000000..c09980e --- /dev/null +++ b/src/test/java/org/upsmf/grievance/dao/impl/ApplicatioDaoImplTest.java @@ -0,0 +1,292 @@ +package org.upsmf.grievance.dao.impl; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.eq; + +import java.util.ArrayList; +import java.util.List; + +import org.upsmf.grievance.dao.impl.ApplicationDaoImpl; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +import org.upsmf.grievance.model.App; +import org.upsmf.grievance.model.ServiceRequest; +import org.upsmf.grievance.model.StatusIdMap; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.util.S3FileManager; + +public class ApplicatioDaoImplTest { + + @Mock + JdbcTemplate jdbcTemplate; + + @InjectMocks + ApplicationDaoImpl applicationDao; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Spy + private ApplicationDaoImpl appDao; + + @Spy + private S3FileManager s3; + + @SuppressWarnings("unchecked") + @Test + public void updateAppTest() { + App app = new App(); + app.setActiveStatus(false); + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(app.getActiveStatus(), applicationDao.updateApp(app, new User()).getActiveStatus()); + } + + + + + + + + + + + + + + + + + + + + // + + + + + + + + + + + + + + + + + + + // + + + + + + + + + + + + + + + + + + + // + + + + + + + + + + + + + + + + + + + + @SuppressWarnings("unchecked") + @Test + public void mapAppsToHelpdeskTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenReturn(0L); + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(false, applicationDao.mapAppsToHelpdesk(new StatusIdMap())); + } + + @SuppressWarnings("unchecked") + @Test + public void mapAppsToHelpdeskNullTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenReturn(0L); + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, applicationDao.mapAppsToHelpdesk(new StatusIdMap())); + } + + @SuppressWarnings("unchecked") + @Test + public void getAppTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(new ArrayList<App>()); + Mockito.doReturn(new ArrayList<App>()).when(appDao).getLogo(Matchers.any()); + assertEquals(0, applicationDao.getApp(1L).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void getLogoTest() { + List<App> a = new ArrayList<App>(); + App app = new App(); + a.add(app); + app.setLogo("p"); + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenReturn(1L); + Mockito.doReturn("d").when(appDao).getAppLogo(Matchers.any()); + assertEquals(a.getClass(), applicationDao.getLogo(a).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void getAllAppsTest() { + List<App> a = new ArrayList<App>(); + App app = new App(); + a.add(app); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(a); + Mockito.doReturn(a).when(appDao).getLogo(Matchers.any()); + assertEquals(1, applicationDao.getAllApps().size()); + } + + @SuppressWarnings("unchecked") + @Test + public void getAppsByOrgIdTest() { + List<App> a = new ArrayList<App>(); + App app = new App(); + a.add(app); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(a); + Mockito.doReturn(a).when(appDao).getLogo(Matchers.any()); + assertEquals(1, applicationDao.getAppsByOrgId(1L).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void getServiceRequestsTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(new ArrayList<ServiceRequest>()); + assertEquals(0, applicationDao.getServiceRequests().size()); + } + + @SuppressWarnings("unchecked") + @Test + public void getAppIdAndAppObjectTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(new ArrayList<App>()); + assertEquals(0, applicationDao.getAppIdAndAppObject().size()); + } + + @SuppressWarnings("unchecked") + @Test + public void updateAppNullTest() { + App app = new App(); + app.setActiveStatus(false); + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(app.getActiveStatus(), applicationDao.updateApp(app, new User()).getActiveStatus()); + } + + @SuppressWarnings("unchecked") + @Test + public void getAppNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + Mockito.doReturn(new ArrayList<App>()).when(appDao).getLogo(Matchers.any()); + assertEquals(null, applicationDao.getApp(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void getLogoNullTest() { + List<App> a = new ArrayList<App>(); + App app = new App(); + a.add(app); + app.setLogo("p"); + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenThrow(NullPointerException.class); + Mockito.doReturn("d").when(appDao).getAppLogo(Matchers.any()); + assertEquals(a.getClass(), applicationDao.getLogo(a).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void getAllAppsNullTest() { + List<App> a = new ArrayList<App>(); + App app = new App(); + a.add(app); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + Mockito.doReturn(new ArrayList<App>()).when(appDao).getLogo(Matchers.any()); + assertEquals(null, applicationDao.getAllApps()); + } + + @SuppressWarnings("unchecked") + @Test + public void getAppsByOrgIdNullTest() { + List<App> a = new ArrayList<App>(); + App app = new App(); + a.add(app); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + Mockito.doReturn(new ArrayList<App>()).when(appDao).getLogo(Matchers.any()); + assertEquals(new ArrayList<>(), applicationDao.getAppsByOrgId(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void getServiceRequestsNullTest() { + Mockito.when(jdbcTemplate.query(Matchers.anyString(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(null, applicationDao.getServiceRequests()); + } + + @SuppressWarnings("unchecked") + @Test + public void getAppIdAndAppObjectNullTest() { + Mockito.when(jdbcTemplate.query(Matchers.anyString(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(null, applicationDao.getAppIdAndAppObject()); + } + +} diff --git a/src/test/java/org/upsmf/grievance/dao/impl/HelpdeskDaoImplTest.java b/src/test/java/org/upsmf/grievance/dao/impl/HelpdeskDaoImplTest.java new file mode 100644 index 0000000..2750038 --- /dev/null +++ b/src/test/java/org/upsmf/grievance/dao/impl/HelpdeskDaoImplTest.java @@ -0,0 +1,281 @@ +package org.upsmf.grievance.dao.impl; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.eq; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.upsmf.grievance.dao.impl.HelpdeskDaoImpl; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +import org.upsmf.grievance.dto.HelpdeskDto; +import org.upsmf.grievance.model.ChecklistItem; +import org.upsmf.grievance.model.HelpDeskApp; +import org.upsmf.grievance.model.Helpdesk; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.model.mapper.SqlDataMapper; +import org.upsmf.grievance.model.mapper.SqlDataMapper.HelpdeskRowRecordMapper; + +public class HelpdeskDaoImplTest { + + @Mock + JdbcTemplate jdbcTemplate; + + @InjectMocks + HelpdeskDaoImpl helpdeskDao; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @SuppressWarnings("unchecked") + @Test + public void getAllHelpdesksTest() { + List<HelpdeskDto> list = new ArrayList<>(); + HelpdeskDto h = new HelpdeskDto(); + h.setId(1L); + list.add(h); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(list); + assertEquals(1, helpdeskDao.getAllHelpdesks(1L).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void getHelpdeskForIdTest() { + HelpdeskRowRecordMapper rowMapper = new SqlDataMapper().new HelpdeskRowRecordMapper(); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(Arrays.asList(new HelpdeskDto())); + assertEquals(rowMapper.getClass(), helpdeskDao.getHelpdeskForId(1L, 1L).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void getChecklistItemsForHelpdeskTest() { + List<ChecklistItem> checklistItems = new ArrayList<>(); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(checklistItems); + assertEquals(checklistItems.getClass(), helpdeskDao.getChecklistItemsForHelpdesk(1L, 1L).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void getHelpdeskAdminsTest() { + Mockito.when(jdbcTemplate.queryForList(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenReturn(Arrays.asList(1L, 2L)); + assertEquals(2, helpdeskDao.getHelpdeskAdmins(1L).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void addUpdateHelpdeskUsersTest() { + Helpdesk helpdesk = new Helpdesk(); + helpdesk.setUserIds(Arrays.asList(1L, 2L)); + helpdesk.setAllowAllUsers(false); + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(true, helpdeskDao.addUpdateHelpdeskUsers(helpdesk)); + } + + @SuppressWarnings("unchecked") + @Test + public void addUpdateHelpdeskUsersTrueTest() { + Helpdesk helpdesk = new Helpdesk(); + helpdesk.setUserIds(Arrays.asList(1L, 2L)); + helpdesk.setAllowAllUsers(true); + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(true, helpdeskDao.addUpdateHelpdeskUsers(helpdesk)); + } + + @SuppressWarnings("unchecked") + @Test + public void deleteTypeForHelpdeskTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(true, helpdeskDao.deleteTypeForHelpdesk(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void deleteWorkflowForHelpdeskTypeTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(true, helpdeskDao.deleteWorkflowForHelpdeskType(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void deleteChecklistForHelpdeskTypeTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(true, helpdeskDao.deleteChecklistForHelpdeskType(1L, 1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void deleteChecklistForHelpdeskTypeFalseTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(0); + assertEquals(false, helpdeskDao.deleteChecklistForHelpdeskType(1L, 1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void getAppIdAndHelpDeskIdTest() { + List<HelpDeskApp> helpdeskApp = new ArrayList<HelpDeskApp>(); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(helpdeskApp); + assertEquals(0, helpdeskDao.getAppIdAndHelpDeskId().size()); + } + + @SuppressWarnings("unchecked") + @Test + public void getHelpdeskObjectFromHelpdeskIdTest() { + List<Helpdesk> helpdesk = new ArrayList<Helpdesk>(); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(helpdesk); + assertEquals(0, helpdeskDao.getHelpdeskObjectFromHelpdeskId().size()); + } + + @SuppressWarnings("unchecked") + @Test + public void getAdminForHelpeskIdTest() { + List<User> user = new ArrayList<User>(); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(user); + assertEquals(0, helpdeskDao.getAdminForHelpeskId(1L).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void getAllHelpdesksNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(new ArrayList<>(), helpdeskDao.getAllHelpdesks(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void getHelpdeskForIdNullTest() { + HelpdeskRowRecordMapper rowMapper = new SqlDataMapper().new HelpdeskRowRecordMapper(); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(rowMapper.getClass(), helpdeskDao.getHelpdeskForId(1L, 1L).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void getChecklistItemsForHelpdeskNullTest() { + List<ChecklistItem> checklistItems = new ArrayList<>(); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(checklistItems.getClass(), helpdeskDao.getChecklistItemsForHelpdesk(1L, 1L).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void getHelpdeskAdminsNullTest() { + Mockito.when(jdbcTemplate.queryForList(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenThrow(NullPointerException.class); + assertEquals(null, helpdeskDao.getHelpdeskAdmins(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void addUpdateHelpdeskUsersNullTest() { + Helpdesk helpdesk = new Helpdesk(); + helpdesk.setUserIds(Arrays.asList(1L, 2L)); + helpdesk.setAllowAllUsers(false); + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, helpdeskDao.addUpdateHelpdeskUsers(helpdesk)); + } + + @SuppressWarnings("unchecked") + @Test + public void deleteTypeForHelpdeskNullTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, helpdeskDao.deleteTypeForHelpdesk(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void deleteWorkflowForHelpdeskTypeNullTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, helpdeskDao.deleteWorkflowForHelpdeskType(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void deleteChecklistForHelpdeskTypeNullTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, helpdeskDao.deleteChecklistForHelpdeskType(1L, 1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void getAppIdAndHelpDeskIdNullTest() { + Mockito.when(jdbcTemplate.query(Matchers.anyString(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(null, helpdeskDao.getAppIdAndHelpDeskId()); + } + + @SuppressWarnings("unchecked") + @Test + public void getHelpdeskObjectFromHelpdeskIdNullTest() { + Mockito.when(jdbcTemplate.query(Matchers.anyString(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(null, helpdeskDao.getHelpdeskObjectFromHelpdeskId()); + } + + @SuppressWarnings("unchecked") + @Test + public void getAdminForHelpeskIdNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(null, helpdeskDao.getAdminForHelpeskId(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void getUsersForHelpeskIdNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(new ArrayList<>(), helpdeskDao.getUsersForHelpeskId(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void deleteTypeForHelpdeskTrueTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(0); + assertEquals(false, helpdeskDao.deleteTypeForHelpdesk(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void deleteWorkflowForHelpdeskTypeTrueTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(0); + assertEquals(false, helpdeskDao.deleteWorkflowForHelpdeskType(1L)); + } + +} diff --git a/src/test/java/org/upsmf/grievance/dao/impl/RoleDaoImplTest.java b/src/test/java/org/upsmf/grievance/dao/impl/RoleDaoImplTest.java new file mode 100644 index 0000000..825e737 --- /dev/null +++ b/src/test/java/org/upsmf/grievance/dao/impl/RoleDaoImplTest.java @@ -0,0 +1,124 @@ +package org.upsmf.grievance.dao.impl; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.eq; + +import java.util.ArrayList; + +import org.upsmf.grievance.dao.impl.RoleDaoImpl; +import org.upsmf.grievance.dao.impl.SuperAdminDaoImpl; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +import org.upsmf.grievance.model.Role; + +public class RoleDaoImplTest { + + @Mock + JdbcTemplate jdbcTemplate; + + @InjectMocks + RoleDaoImpl roleDao; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Spy + private RoleDaoImpl role; + + @Spy + private SuperAdminDaoImpl superAdmin; + + @SuppressWarnings("unchecked") + @Test + public void saveRoleTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(new Role().getClass(), roleDao.saveRole(new Role()).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void updateRoleTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(new Role().getClass(), roleDao.updateRole(new Role()).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void getAllRolesTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(new ArrayList<Role>()); + assertEquals(0, roleDao.getAllRoles(1L).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void findByIdTest() { + Mockito.when( + jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(String.class))) + .thenReturn("d"); + assertEquals("d", roleDao.findById(new Role())); + } + + @SuppressWarnings("unchecked") + @Test + public void getAllOrgRolesTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.any(RowMapper.class))) + .thenReturn(new ArrayList<Role>()); + assertEquals(0, roleDao.getAllOrgRoles().size()); + } + + @SuppressWarnings("unchecked") + @Test + public void saveRoleNullTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(null, roleDao.saveRole(new Role())); + } + + @SuppressWarnings("unchecked") + @Test + public void updateRoleNullTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(null, roleDao.updateRole(new Role())); + } + + @SuppressWarnings("unchecked") + @Test + public void getAllRolesNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(null, roleDao.getAllRoles(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void findByIdNullTest() { + Mockito.when( + jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(String.class))) + .thenThrow(NullPointerException.class); + assertEquals(null, roleDao.findById(new Role())); + } + + @SuppressWarnings("unchecked") + @Test + public void getAllOrgRolesNullTest() { + Mockito.when(jdbcTemplate.query(Matchers.anyString(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(new ArrayList<>(), roleDao.getAllOrgRoles()); + } + +} diff --git a/src/test/java/org/upsmf/grievance/dao/impl/SuperAdminDaoImplTest.java b/src/test/java/org/upsmf/grievance/dao/impl/SuperAdminDaoImplTest.java new file mode 100644 index 0000000..86ab970 --- /dev/null +++ b/src/test/java/org/upsmf/grievance/dao/impl/SuperAdminDaoImplTest.java @@ -0,0 +1,179 @@ +package org.upsmf.grievance.dao.impl; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import org.upsmf.grievance.dao.impl.SuperAdminDaoImpl; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +import org.upsmf.grievance.model.Organization; +import org.upsmf.grievance.model.StatusIdMap; +import org.upsmf.grievance.model.User; + +public class SuperAdminDaoImplTest { + + @Mock + JdbcTemplate jdbcTemplate; + + @InjectMocks + SuperAdminDaoImpl superAdminDao; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @SuppressWarnings("unchecked") + @Test + public void getAllOrganizationTest() { + List<Organization> list = new ArrayList<>(); + Organization org = new Organization(); + org.setId(1L); + list.add(org); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(list); + assertEquals(1, superAdminDao.getAllOrganization().size()); + } + + @SuppressWarnings("unchecked") + @Test + public void deleteOrganizationTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(true, superAdminDao.deleteOrganization(new Organization())); + } + + @SuppressWarnings("unchecked") + @Test + public void deleteOrganizationFalseTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(0); + assertEquals(false, superAdminDao.deleteOrganization(new Organization())); + } + + @SuppressWarnings("unchecked") + @Test + public void getOrganizationByUserIdTest() { + List<Organization> list = new ArrayList<>(); + Organization org = new Organization(); + org.setId(1L); + list.add(org); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(list); + assertEquals(1, superAdminDao.getOrganizationByUserId(1l)); + } + + @SuppressWarnings("unchecked") + @Test + public void mapUserToOrgTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(true, superAdminDao.mapUserToOrg(1L, 2)); + } + + @SuppressWarnings("unchecked") + @Test + public void mapUserToOrgFalseTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(0); + assertEquals(false, superAdminDao.mapUserToOrg(1L, 2)); + } + + @SuppressWarnings("unchecked") + @Test + public void userDetailsByUserIdTest() { + List<User> list = new ArrayList<>(); + User user = new User(); + user.setId(4L); + list.add(user); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(list); + assertEquals(4L, superAdminDao.userDetailsByUserId(1L).getId().longValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void mapAppsToOrgTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(true, superAdminDao.mapAppsToOrg(new StatusIdMap())); + } + + @SuppressWarnings("unchecked") + @Test + public void getOrganizationByUserTest() { + List<Organization> list = new ArrayList<>(); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(list); + assertEquals(0, list.size()); + } + + @SuppressWarnings("unchecked") + @Test + public void getAllOrganizationNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(new ArrayList<>(), superAdminDao.getAllOrganization()); + } + + @SuppressWarnings("unchecked") + @Test + public void deleteOrganizationNullTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, superAdminDao.deleteOrganization(new Organization())); + } + + @SuppressWarnings("unchecked") + @Test + public void getOrganizationByUserIdNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(0, superAdminDao.getOrganizationByUserId(1l)); + } + + @SuppressWarnings("unchecked") + @Test + public void mapUserToOrgNullTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, superAdminDao.mapUserToOrg(1L, 2)); + } + + @SuppressWarnings("unchecked") + @Test + public void userDetailsByUserIdNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(null, superAdminDao.userDetailsByUserId(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void mapAppsToOrgNullTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, superAdminDao.mapAppsToOrg(new StatusIdMap())); + } + + @SuppressWarnings("unchecked") + @Test + public void getOrganizationByUserNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(new ArrayList<>(), superAdminDao.getOrganizationByUser(1L)); + } +} diff --git a/src/test/java/org/upsmf/grievance/dao/impl/TicketDaoImplTest.java b/src/test/java/org/upsmf/grievance/dao/impl/TicketDaoImplTest.java new file mode 100644 index 0000000..1c2e54c --- /dev/null +++ b/src/test/java/org/upsmf/grievance/dao/impl/TicketDaoImplTest.java @@ -0,0 +1,337 @@ +package org.upsmf.grievance.dao.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.upsmf.grievance.dao.impl.TicketDaoImpl; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.KeyHolder; + +import org.upsmf.grievance.dto.TicketTypeDto; +import org.upsmf.grievance.dto.TicketWorkflowDto; +import org.upsmf.grievance.model.ActivityLog; +import org.upsmf.grievance.model.ChecklistItem; +import org.upsmf.grievance.model.KeyFactory; +import org.upsmf.grievance.model.Ticket; +import org.upsmf.grievance.model.Updates; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ KeyFactory.class }) +public class TicketDaoImplTest { + + @Mock + JdbcTemplate jdbcTemplate; + + @InjectMocks + TicketDaoImpl ticketdao; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void deleteWorkflowForTicketTypeTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(true, ticketdao.deleteWorkflowForTicketType(1L)); + } + + @Test + public void deleteWorkflowForTicketTypeFalseTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(0); + assertEquals(false, ticketdao.deleteWorkflowForTicketType(1L)); + } + + @Test + public void deleteChecklistForTicketTypeTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(true, ticketdao.deleteChecklistForTicketType(new TicketTypeDto())); + } + + @Test + public void deleteChecklistForTicketTypeFalseTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(0); + assertEquals(false, ticketdao.deleteChecklistForTicketType(new TicketTypeDto())); + } + + @SuppressWarnings("unchecked") + @Test + public void getWorkflowForTicketTest() { + TicketWorkflowDto t = new TicketWorkflowDto(); + t.setId(1L); + List<TicketWorkflowDto> ticketWorkFlow = new ArrayList<>(); + ticketWorkFlow.add(t); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(ticketWorkFlow); + assertEquals(1L, ticketdao.getWorkflowForTicket(1L).get(0).getId().longValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void addUpdateUpdatesToTicket() { + Updates u = new Updates(); + u.setId(1L); + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(true, ticketdao.addUpdateUpdatesToTicket(u)); + } + + @SuppressWarnings("unchecked") + @Test + public void addUpdateUpdatesToTicketNull() { + Updates u = new Updates(); + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(true, ticketdao.addUpdateUpdatesToTicket(u)); + } + + @SuppressWarnings("unchecked") + @Test + public void getUpdatesForTicketTest() { + Updates u = new Updates(); + u.setId(1L); + List<Updates> update = new ArrayList<>(); + update.add(u); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(update); + assertEquals(1L, ticketdao.getUpdatesForTicket(1L).get(0).getId().longValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void getTemplatesVersionTest() { + Updates u = new Updates(); + u.setId(1L); + List<Updates> update = new ArrayList<>(); + update.add(u); + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), eq(Long.class))).thenReturn(1L); + assertEquals(1L, ticketdao.getTemplatesVersion().longValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void updateTemplateVersionTest() { + Updates u = new Updates(); + u.setId(1L); + List<Updates> update = new ArrayList<>(); + update.add(u); + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(true, ticketdao.updateTemplateVersion(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void getTicketCCTest() { + List<Long> l = Arrays.asList(1L, 2L, 3L); + Mockito.when(jdbcTemplate.queryForList(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenReturn(l); + assertEquals(3, ticketdao.getTicketCC(1L).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void updateTicketChecklistFalseTest() { + Ticket ticket = new Ticket(); + List<ChecklistItem> cc = new ArrayList<>(); + ChecklistItem e = new ChecklistItem(); + e.setId(1L); + cc.add(e); + ticket.setChecklist(cc); + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertEquals(true, ticketdao.updateTicketChecklist(ticket)); + } + + @SuppressWarnings("unchecked") + @Test + public void updateTicketChecklistTest() { + Ticket ticket = new Ticket(); + List<ChecklistItem> cc = new ArrayList<>(); + ChecklistItem e = new ChecklistItem(); + e.setId(1L); + cc.add(e); + ticket.setChecklist(cc); + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(0); + assertEquals(false, ticketdao.updateTicketChecklist(ticket)); + } + + @SuppressWarnings("unchecked") + @Test + public void getActivityLogsPerTicketTest() { + List<ActivityLog> activityLogs = new ArrayList<>(); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(activityLogs); + assertEquals(activityLogs.getClass(), ticketdao.getActivityLogsPerTicket(1L).getClass()); + } + + + + + + + + + + + + + + + + @Test + public void getLastInsertIdTest() { + KeyHolder keyHolder = mock(KeyHolder.class); + Mockito.when(keyHolder.getKey()).thenReturn(1L); + PowerMockito.mockStatic(KeyFactory.class); + PowerMockito.when(KeyFactory.getkeyHolder()).thenReturn(keyHolder); + when(jdbcTemplate.update(Matchers.any(PreparedStatementCreator.class), Matchers.any(KeyHolder.class))) + .thenReturn(1); + assertEquals(1L, ticketdao.getLastInsertId("d").longValue()); + } + + @Test + public void addTicketActivityLogTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(1); + assertNull(ticketdao.addTicketActivityLog(1L, "d", 1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void getChecklistItemsForTicketTest() { + ChecklistItem checklist = new ChecklistItem(); + checklist.setId(1L); + List<ChecklistItem> checklistItems = new ArrayList<>(); + checklistItems.add(checklist); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(checklistItems); + assertEquals(1L, ticketdao.getChecklistItemsForTicket(1L).get(0).getId().longValue()); + } + + @Test + public void keepOnlyCreatedAndCopiedToTicketsTest() { + Ticket ticket = new Ticket(); + ticket.setId(1L); + ticket.setRequestedBy(1L); + List<Long> cc = Arrays.asList(1L, 2L, 4L); + ticket.setCc(cc); + List<Ticket> t = new ArrayList<>(); + t.add(ticket); + assertEquals(new ArrayList<Ticket>().getClass(), ticketdao.keepOnlyCreatedAndCopiedToTickets(1L, t).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void deleteWorkflowForTicketTypeNullTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, ticketdao.deleteWorkflowForTicketType(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void deleteChecklistForTicketTypeNullTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, ticketdao.deleteChecklistForTicketType(new TicketTypeDto())); + } + + @SuppressWarnings("unchecked") + @Test + public void getWorkflowForTicketNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(0, ticketdao.getWorkflowForTicket(1L).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void addUpdateUpdatesToNullTicket() { + Updates u = new Updates(); + u.setId(1L); + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, ticketdao.addUpdateUpdatesToTicket(u)); + } + + @SuppressWarnings("unchecked") + @Test + public void getUpdatesForTicketNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertNull(ticketdao.getUpdatesForTicket(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void getTemplatesVersionNullTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), eq(Long.class))) + .thenThrow(NullPointerException.class); + assertEquals(0L, ticketdao.getTemplatesVersion().longValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void updateTemplateVersionNullTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, ticketdao.updateTemplateVersion(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void updateTicketChecklistNullTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, ticketdao.updateTicketChecklist(new Ticket())); + } + + @SuppressWarnings("unchecked") + @Test + public void getActivityLogsPerTicketNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertNull(ticketdao.getActivityLogsPerTicket(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void addTicketActivityLogNullTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertNull(ticketdao.addTicketActivityLog(1L, "d", 1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void getChecklistItemsForTicketNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(new ArrayList<ChecklistItem>().getClass(), ticketdao.getChecklistItemsForTicket(1L).getClass()); + } + +} diff --git a/src/test/java/org/upsmf/grievance/dao/impl/UserDaoImplTest.java b/src/test/java/org/upsmf/grievance/dao/impl/UserDaoImplTest.java new file mode 100644 index 0000000..1db2b33 --- /dev/null +++ b/src/test/java/org/upsmf/grievance/dao/impl/UserDaoImplTest.java @@ -0,0 +1,529 @@ +package org.upsmf.grievance.dao.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.upsmf.grievance.dao.impl.SuperAdminDaoImpl; +import org.upsmf.grievance.dao.impl.UserDaoImpl; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; + +import org.upsmf.grievance.dto.OrgUserRoleDto; +import org.upsmf.grievance.dto.UserDto; +import org.upsmf.grievance.model.Action; +import org.upsmf.grievance.model.HelpDeskApp; +import org.upsmf.grievance.model.MasterData; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.model.UserAuthentication; +import org.upsmf.grievance.model.mapper.SqlDataMapper; +import org.upsmf.grievance.model.mapper.SqlDataMapper.UserDetailsMapper; +import org.upsmf.grievance.model.mapper.SqlDataMapper.UserRoleMapper; + +@RunWith(MockitoJUnitRunner.class) +public class UserDaoImplTest { + + @Mock + JdbcTemplate jdbcTemplate; + + @Spy + private SuperAdminDaoImpl superAdminDao; + + @InjectMocks + UserDaoImpl userdao; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @SuppressWarnings("unchecked") + @Test + public void findAllActionsByRoleIdTest() { + Action action = new Action(); + action.setId(1L); + List<Action> actions = new ArrayList<>(); + actions.add(action); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.any(Object[].class), Matchers.any(RowMapper.class))) + .thenReturn(actions); + List<Action> act = userdao.findAllActionsByRoleID(1); + assertEquals(1, act.size()); + } + + @Test + public void getAuthIdTest() { + User user = new User(); + user.setId(1L); + List<User> users = new ArrayList<>(); + users.add(user); + Mockito.doReturn(2).when(superAdminDao).getOrganizationByUserId(1L); + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.any(Object[].class), eq(Integer.class))) + .thenReturn(1); + assertEquals(1, userdao.getAuthId(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void findOneTest() { + User user = new User(); + user.setId(1L); + user.setName("jay"); + List<User> users = new ArrayList<>(); + users.add(user); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.any(Object[].class), Matchers.any(RowMapper.class))) + .thenReturn(users); + assertEquals(new ArrayList<>().getClass(), userdao.findOne(1L).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void findOneuserAuthenticationTest() { + UserAuthentication user = new UserAuthentication(); + user.setAuthToken("abcd"); + List<UserAuthentication> users = new ArrayList<>(); + users.add(user); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.any(Object[].class), Matchers.any(RowMapper.class))) + .thenReturn(users); + assertEquals("abcd", userdao.findOneUserAuthentication(1L).getAuthToken()); + } + + @Test + public void insertIntoPasswordTest() { + UserAuthentication user = new UserAuthentication(); + user.setAuthToken("abcd"); + List<UserAuthentication> users = new ArrayList<>(); + users.add(user); + Mockito.when(jdbcTemplate.update(anyString(), Matchers.<Object[]>anyVararg())).thenReturn(5); + assertEquals(5, userdao.insertIntoPassword(1L, "d")); + } + + @SuppressWarnings("unchecked") + @Test + public void findAllRolesByUserTest() { + UserRoleMapper mapper = new SqlDataMapper().new UserRoleMapper(); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.any(Object[].class), Matchers.any(RowMapper.class))) + .thenReturn(null); + assertEquals(mapper.getClass(), userdao.findAllRolesByUser(1L).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void findListOfUsersTest() { + List<Long> users = Arrays.asList(1L, 2L); + UserDetailsMapper mapper = new SqlDataMapper().new UserDetailsMapper(); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.any(Object[].class), Matchers.any(RowMapper.class))) + .thenReturn(null); + assertEquals(mapper.getClass(), userdao.findListOfUsers(users).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void findAllTest() { + User user = new User(); + user.setId(1L); + user.setName("jay"); + List<User> users = new ArrayList<>(); + users.add(user); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.any(Object[].class), Matchers.any(RowMapper.class))) + .thenReturn(users); + assertEquals("jay", userdao.findAll(1L).get(0).getName()); + } + + @SuppressWarnings("unchecked") + @Test + public void getNumberOfUsersNTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.any(Object[].class), eq(Long.class))) + .thenReturn(5L); + assertEquals(5L, userdao.getNumberOfUsers(null, false).longValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void getNumberOfUsersNNTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.any(Object[].class), eq(Long.class))) + .thenReturn(5L); + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), eq(Long.class))).thenReturn(5L); + assertEquals(5L, userdao.getNumberOfUsers(null, null).longValue()); + } + + @Test + public void checkUserNameExistsTest() { + UserAuthentication user = new UserAuthentication(); + user.setAuthToken("abcd"); + List<UserAuthentication> users = new ArrayList<>(); + users.add(user); + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.any(Object[].class), eq(Long.class))) + .thenReturn(5L); + assertEquals(5L, userdao.checkUserNameExists("d").longValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void getNumberOfRolesTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), eq(Long.class))).thenReturn(5L); + assertEquals(5L, userdao.getNumberOfRoles().longValue()); + } + + @Test + public void invalidateTokenTest() { + Mockito.when(jdbcTemplate.update(anyString(), Matchers.<Object[]>anyVararg())).thenReturn(5); + assertEquals(true, userdao.invalidateToken("d")); + } + + @Test + public void findUserByTokenTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.any(Object[].class), eq(Long.class))) + .thenReturn(5L); + assertEquals(true, userdao.findUserByToken("d")); + } + + @Test + public void checkUserTokenExistsTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenReturn(5L); + assertEquals(true, userdao.checkUserTokenExists(1L, "d")); + } + + @Test + public void fetchAuthTokenReferenceTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenReturn(5L); + assertEquals(5L, userdao.fetchAuthTokenReference("d a").longValue()); + } + + @Test + public void getFirstAdminsOfOrgTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), eq(Long.class), Matchers.<Object[]>anyVararg())) + .thenReturn(5L); + assertEquals(true, userdao.getFirstAdminsOfOrg(1L)); + } + + @Test + public void getFirstAdminsOfOrgNTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), eq(Long.class), Matchers.<Object[]>anyVararg())) + .thenReturn(null); + assertEquals(false, userdao.getFirstAdminsOfOrg(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void onBoardingCheckTest() { + List<MasterData> masterDataCheckList = new ArrayList<>(); + MasterData m = new MasterData(); + m.setField("u"); + m.setCount(5L); + masterDataCheckList.add(m); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(masterDataCheckList); + assertEquals(false, userdao.onBoardingCheck(1L, 1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void getUserProfileTest() { + User user = new User(); + user.setId(1L); + user.setName("jay"); + List<User> users = new ArrayList<>(); + users.add(user); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(users); + assertEquals(user.getId(), userdao.getUserProfile(1L).getId()); + } + + @SuppressWarnings("unchecked") + @Test + public void getAllOrgUsersTest() { + List<OrgUserRoleDto> orgUserList = new ArrayList<>(); + OrgUserRoleDto o = new OrgUserRoleDto(); + o.setId(5L); + orgUserList.add(o); + Mockito.when(jdbcTemplate.query(Matchers.anyString(), Matchers.any(RowMapper.class))).thenReturn(orgUserList); + assertEquals(1, userdao.getAllOrgUsers().size()); + } + + /* + * @SuppressWarnings("unchecked") + * + * @Test public void getAllUserRoles() { List<OrgUserRoleDto> orgUserList = new + * ArrayList<>(); OrgUserRoleDto o = new OrgUserRoleDto(); o.setId(5L); + * orgUserList.add(o); Mockito.when(jdbcTemplate.query(Mockito.anyString(), + * Mockito.any(RowMapper.class))).thenReturn(orgUserList); assertEquals(1, + * userdao.getAllUserRoles().size()); } + */ + + @SuppressWarnings("unchecked") + @Test + public void getAppIdAndHelpDeskId() { + List<HelpDeskApp> helpdeskAppList = new ArrayList<>(); + HelpDeskApp o = new HelpDeskApp(); + o.setAppId(5L); + helpdeskAppList.add(o); + Mockito.when(jdbcTemplate.query(Matchers.anyString(), Matchers.any(RowMapper.class))) + .thenReturn(helpdeskAppList); + assertEquals(1, userdao.getAppIdAndHelpDeskId().size()); + } + + @Test + public void isPasswordMatchTest() { + Mockito.when( + jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(String.class))) + .thenReturn("abcd"); + assertEquals(false, userdao.isPasswordMatch(1L, "d")); + } + + @Test + public void forgotPasswordTest() { + UserDto userDto = new UserDto(); + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenReturn(2L); + assertEquals(2L, userdao.forgotPassword(userDto)); + } + + @Test + public void saveForgotPasswordTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())).thenReturn(2); + assertEquals(true, userdao.saveForgotPassword(1, "d")); + } + + @SuppressWarnings("unchecked") + @Test + public void getUserDetailsByEmailTest() { + User user = new User(); + user.setId(1L); + user.setName("jay"); + List<User> users = new ArrayList<>(); + users.add(user); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenReturn(users); + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenReturn(2L); + assertEquals(2L, userdao.getUserDetailsByEmail("d").getOrgId().longValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void findAllActionsByRoleIdNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.any(Object[].class), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(0, userdao.findAllActionsByRoleID(1).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void getAuthIdNullTest() { + Mockito.doReturn(2).when(superAdminDao).getOrganizationByUserId(1L); + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.any(Object[].class), eq(Integer.class))) + .thenThrow(NullPointerException.class); + assertEquals(0, userdao.getAuthId(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void findOneNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.any(Object[].class), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(new ArrayList<>().getClass(), userdao.findOne(1L).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void findOneuserAuthenticationNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.any(Object[].class), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertNull(userdao.findOneUserAuthentication(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void findAllRolesByUserNullTest() { + UserRoleMapper mapper = new SqlDataMapper().new UserRoleMapper(); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.any(Object[].class), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(mapper.getClass(), userdao.findAllRolesByUser(1L).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void findListOfUsersNullTest() { + List<Long> users = Arrays.asList(1L, 2L); + UserDetailsMapper mapper = new SqlDataMapper().new UserDetailsMapper(); + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.any(Object[].class), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(mapper.getClass(), userdao.findListOfUsers(users).getClass()); + } + + @SuppressWarnings("unchecked") + @Test + public void findAllNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.any(Object[].class), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertNull(userdao.findAll(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void getNumberOfUsersNullTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.any(Object[].class), eq(Long.class))) + .thenThrow(NullPointerException.class); + assertEquals(0L, userdao.getNumberOfUsers(1L, false).longValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void checkUserNameExistsNullTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.any(Object[].class), eq(Long.class))) + .thenThrow(NullPointerException.class); + assertEquals(0L, userdao.checkUserNameExists("d").longValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void getNumberOfRolesNullTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), eq(Long.class))) + .thenThrow(NullPointerException.class); + assertEquals(0L, userdao.getNumberOfRoles().longValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void invalidateTokenNullTest() { + Mockito.when(jdbcTemplate.update(anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, userdao.invalidateToken("d")); + } + + @SuppressWarnings("unchecked") + @Test + public void findUserByTokenNullTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.any(Object[].class), eq(Long.class))) + .thenThrow(NullPointerException.class); + assertEquals(false, userdao.findUserByToken("d")); + } + + @SuppressWarnings("unchecked") + @Test + public void checkUserTokenExistsNullTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenThrow(NullPointerException.class); + assertEquals(false, userdao.checkUserTokenExists(1L, "d")); + } + + @SuppressWarnings("unchecked") + @Test + public void fetchAuthTokenReferenceNullTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenThrow(NullPointerException.class); + assertEquals(0L, userdao.fetchAuthTokenReference("d a").longValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void getFirstAdminsOfOrgNullTest() { + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), eq(Long.class), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, userdao.getFirstAdminsOfOrg(1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void onBoardingCheckNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertEquals(false, userdao.onBoardingCheck(1L, 1L)); + } + + @SuppressWarnings("unchecked") + @Test + public void getAllOrgUsersNullTest() { + Mockito.when(jdbcTemplate.query(Matchers.anyString(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertNull(userdao.getAllOrgUsers()); + } + + /* + * @SuppressWarnings("unchecked") + * + * @Test public void getAllUserRolesNullTest() { + * Mockito.when(jdbcTemplate.query(Mockito.anyString(), + * Mockito.any(RowMapper.class))) .thenThrow(NullPointerException.class); + * assertNull(userdao.getAllUserRoles()); } + */ + + @SuppressWarnings("unchecked") + @Test + public void getAppIdAndHelpDeskIdNullTest() { + Mockito.when(jdbcTemplate.query(Matchers.anyString(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + assertNull(userdao.getAppIdAndHelpDeskId()); + } + + @SuppressWarnings("unchecked") + @Test + public void isPasswordMatchNullTest() { + Mockito.when( + jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(String.class))) + .thenThrow(NullPointerException.class); + assertEquals(false, userdao.isPasswordMatch(1L, "d")); + } + + @SuppressWarnings("unchecked") + @Test + public void forgotPasswordNullTest() { + UserDto userDto = new UserDto(); + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenThrow(NullPointerException.class); + assertEquals(0, userdao.forgotPassword(userDto)); + } + + @SuppressWarnings("unchecked") + @Test + public void saveForgotPasswordNullTest() { + Mockito.when(jdbcTemplate.update(Matchers.anyString(), Matchers.<Object[]>anyVararg())) + .thenThrow(NullPointerException.class); + assertEquals(false, userdao.saveForgotPassword(1, "d")); + } + + @SuppressWarnings("unchecked") + @Test + public void getUserDetailsByEmailNullTest() { + Mockito.when( + jdbcTemplate.query(Matchers.anyString(), Matchers.<Object[]>anyVararg(), Matchers.any(RowMapper.class))) + .thenThrow(NullPointerException.class); + Mockito.when(jdbcTemplate.queryForObject(Matchers.anyString(), Matchers.<Object[]>anyVararg(), eq(Long.class))) + .thenThrow(NullPointerException.class); + assertNull(userdao.getUserDetailsByEmail("d")); + } + +} diff --git a/src/test/java/org/upsmf/grievance/service/impl/ApplicationServiceImplTest.java b/src/test/java/org/upsmf/grievance/service/impl/ApplicationServiceImplTest.java new file mode 100644 index 0000000..1c9abd2 --- /dev/null +++ b/src/test/java/org/upsmf/grievance/service/impl/ApplicationServiceImplTest.java @@ -0,0 +1,86 @@ +package org.upsmf.grievance.service.impl; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; + +import org.upsmf.grievance.service.impl.ApplicationServiceImpl; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +import org.upsmf.grievance.dao.ApplicationDao; +import org.upsmf.grievance.model.App; +import org.upsmf.grievance.model.Role; +import org.upsmf.grievance.model.ServiceRequest; +import org.upsmf.grievance.model.StatusIdMap; +import org.upsmf.grievance.model.User; + +public class ApplicationServiceImplTest { + + @Mock + ApplicationDao applicationDao; + + @InjectMocks + ApplicationServiceImpl applicationService; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void createAppTest() { + Mockito.when(applicationDao.createApp(Matchers.any(App.class), Matchers.any(User.class))).thenReturn(new App()); + Mockito.when(applicationDao.updateApp(Matchers.any(App.class), Matchers.any(User.class))).thenReturn(new App()); + assertEquals(new App().getClass(), applicationService.createApp(new App(), new User()).getClass()); + App a = new App(); + a.setId(5L); + assertEquals(new App().getClass(), applicationService.createApp(a, new User()).getClass()); + } + + @Test + public void getAppTestTrue() { + Mockito.when(applicationDao.getApp(Matchers.any(Long.class))).thenReturn(new ArrayList<App>()); + Mockito.when(applicationDao.getAllApps()).thenReturn(new ArrayList<App>()); + Mockito.when(applicationDao.getAppsByOrgId(Matchers.any(Long.class))).thenReturn(new ArrayList<App>()); + assertEquals(0, applicationService.getApp(null, "a", new User()).size()); + assertEquals(0, applicationService.getApp(1L, "a", new User()).size()); + User user = new User(); + Role role = new Role(); + role.setName("SuperAdmin"); + user.setRoles(Arrays.asList(role)); + assertEquals(0, applicationService.getApp(null, "a", user).size()); + user.setOrgId(1L); + assertEquals(0, applicationService.getApp(null, "a", user).size()); + } + + @Test + public void mapAppsToHelpdeskTest() { + Mockito.when(applicationDao.mapAppsToHelpdesk(Matchers.any(StatusIdMap.class))).thenReturn(true); + assertEquals(true, applicationService.mapAppsToHelpdesk(new StatusIdMap())); + } + + @Test + public void getServiceRequestsTest() { + Mockito.when(applicationDao.getServiceRequests()).thenReturn(new ArrayList<ServiceRequest>()); + assertEquals(0, applicationService.getServiceRequests().size()); + } + + @Test + public void getAppIdAndAppObjectTest() { + Mockito.when(applicationDao.getAppIdAndAppObject()).thenReturn(new ArrayList<App>()); + assertEquals(0, applicationService.getAppIdAndAppObject().size()); + } + + @Test + public void getAppTest() { + Mockito.when(applicationDao.getAppsByOrgId(Matchers.any(Long.class))).thenReturn(new ArrayList<App>()); + assertEquals(0, applicationService.getApp(1L).size()); + } +} diff --git a/src/test/java/org/upsmf/grievance/service/impl/HelpdeskServiceImplTest.java b/src/test/java/org/upsmf/grievance/service/impl/HelpdeskServiceImplTest.java new file mode 100644 index 0000000..14d861d --- /dev/null +++ b/src/test/java/org/upsmf/grievance/service/impl/HelpdeskServiceImplTest.java @@ -0,0 +1,116 @@ +package org.upsmf.grievance.service.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.upsmf.grievance.service.impl.HelpdeskServiceImpl; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; + +import org.upsmf.grievance.dao.HelpdeskDao; +import org.upsmf.grievance.dto.HelpdeskDto; +import org.upsmf.grievance.dto.HelpdeskTypeDto; +import org.upsmf.grievance.model.HelpDeskApp; +import org.upsmf.grievance.model.Helpdesk; +import org.upsmf.grievance.model.User; +import org.upsmf.grievance.model.mapper.SqlDataMapper.HelpdeskRowRecordMapper; + +public class HelpdeskServiceImplTest { + + @Mock + HelpdeskDao helpdeskDao; + + @Spy + HelpdeskServiceImpl helpdesk; + + @InjectMocks + HelpdeskServiceImpl helpdeskService; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void createUpdateHelpdeskTest() { + Mockito.when(helpdeskDao.createUpdateHelpdesk(Matchers.any(Helpdesk.class))).thenReturn(true); + Mockito.doReturn(true).when(helpdesk).configureHelpdesk(Matchers.any(HelpdeskDto.class), + Matchers.any(User.class)); + assertEquals(true, helpdeskService.createUpdateHelpdesk(new HelpdeskDto(), new User())); + } + + @Test + public void getHelpdeskByIdTest() { + Mockito.when(helpdeskDao.getHelpdeskForId(Matchers.anyLong(), Matchers.anyLong())).thenReturn(null); + Mockito.doNothing().when(helpdesk).createHelpdeskListFromRowRecords(Matchers.any(HelpdeskRowRecordMapper.class), + Matchers.anyListOf(HelpdeskDto.class)); + Mockito.doNothing().when(helpdesk).getAppsForHelpdesk(Matchers.anyListOf(HelpdeskDto.class)); + Mockito.doNothing().when(helpdesk).getAdminForHelpdesk(Matchers.anyListOf(HelpdeskDto.class)); + Mockito.doNothing().when(helpdesk).getUsersForHelpdesk(Matchers.anyListOf(HelpdeskDto.class)); + assertEquals(0, helpdeskService.getHelpdeskById(1L, 1L).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void configureHelpdeskTest() { + List<HelpdeskDto> helpdeskList = new ArrayList<>(); + HelpdeskDto helpdeskDto = new HelpdeskDto(); + helpdeskDto.setId(1L); + HelpdeskTypeDto type = new HelpdeskTypeDto(); + type.setId(1L); + List<HelpdeskTypeDto> types = new ArrayList<>(); + types.add(type); + helpdeskDto.setTypes(types); + helpdeskList.add(helpdeskDto); + Mockito.when(helpdeskDao.deleteTypeForHelpdesk(Matchers.anyLong())).thenReturn(true); + Mockito.when(helpdeskDao.deleteWorkflowForHelpdeskType(Matchers.anyLong())).thenReturn(true); + Mockito.when(helpdeskDao.deleteChecklistForHelpdeskType(Matchers.anyLong(), Matchers.anyLong())) + .thenReturn(true); + Mockito.when(helpdeskDao.addTypeForHelpdesk(Matchers.any(HelpdeskTypeDto.class), Matchers.anyLong())) + .thenReturn(true); + Mockito.when(helpdeskDao.addWorkflowForHelpdeskType(Matchers.any(HelpdeskTypeDto.class))).thenReturn(true); + Mockito.when(helpdeskDao.addChecklistForHelpdeskType(Matchers.any(HelpdeskTypeDto.class), Matchers.anyLong())) + .thenReturn(true); + assertTrue(helpdeskService.configureHelpdesk(helpdeskDto, new User())); + } + + @Test + public void getHelpdeskTest() { + Mockito.when(helpdeskDao.getAllHelpdesks(Matchers.anyLong())).thenReturn(new ArrayList<HelpdeskDto>()); + assertEquals(0, helpdeskService.getHelpdesk(1L).size()); + } + + @Test + public void addUpdateHelpdeskAdminsTest() { + Mockito.when(helpdeskDao.addUpdateHelpdeskAdmins(Matchers.any(Helpdesk.class))).thenReturn(true); + assertEquals(true, helpdeskService.addUpdateHelpdeskAdmins(new Helpdesk(), new User())); + } + + @Test + public void getHelpdeskAdminsTest() { + Mockito.when(helpdeskDao.getHelpdeskAdmins(Matchers.anyLong())).thenReturn(new ArrayList<Long>()); + assertEquals(0, helpdeskService.getHelpdeskAdmins(1L).size()); + } + + @Test + public void getAppIdAndHelpDeskIdTest() { + Mockito.when(helpdeskDao.getAppIdAndHelpDeskId()).thenReturn(new ArrayList<HelpDeskApp>()); + assertEquals(0, helpdeskService.getAppIdAndHelpDeskId().size()); + } + + @Test + public void getHelpdeskObjectFromHelpdeskIdTest() { + Mockito.when(helpdeskDao.getHelpdeskObjectFromHelpdeskId()).thenReturn(new ArrayList<Helpdesk>()); + assertEquals(0, helpdeskService.getHelpdeskObjectFromHelpdeskId().size()); + } + +} \ No newline at end of file diff --git a/src/test/java/org/upsmf/grievance/service/impl/RoleServiceImplTest.java b/src/test/java/org/upsmf/grievance/service/impl/RoleServiceImplTest.java new file mode 100644 index 0000000..a0e1a8b --- /dev/null +++ b/src/test/java/org/upsmf/grievance/service/impl/RoleServiceImplTest.java @@ -0,0 +1,62 @@ +package org.upsmf.grievance.service.impl; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; + +import org.upsmf.grievance.service.impl.RoleActionServiceImpl; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +import org.upsmf.grievance.dao.RoleDao; +import org.upsmf.grievance.model.Role; + +public class RoleServiceImplTest { + + @Mock + RoleDao roleDao; + + @InjectMocks + RoleActionServiceImpl roleService; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void saveRoleTest() { + Mockito.when(roleDao.saveRole(Matchers.any(Role.class))).thenReturn(new Role()); + assertEquals(new Role().getClass(), roleService.saveRole(new Role()).getClass()); + } + + @Test + public void updateRoleTest() { + Mockito.when(roleDao.updateRole(Matchers.any(Role.class))).thenReturn(new Role()); + assertEquals(new Role().getClass(), roleService.updateRole(new Role()).getClass()); + } + + @Test + public void getAllRolesTest() { + Mockito.when(roleDao.getAllRoles(Matchers.anyLong())).thenReturn(new ArrayList<Role>()); + assertEquals(0, roleService.getAllRoles(1L).size()); + } + + @Test + public void findByIdTest() { + Mockito.when(roleDao.findById(Matchers.any(Role.class))).thenReturn("d"); + assertEquals("d", roleService.findById(new Role())); + } + + @Test + public void getAllOrgRolesTest() { + Mockito.when(roleDao.getAllOrgRoles()).thenReturn(new ArrayList<Role>()); + assertEquals(0, roleService.getAllOrgRoles().size()); + } + +} \ No newline at end of file diff --git a/src/test/java/org/upsmf/grievance/service/impl/SuperAdminImplTest.java b/src/test/java/org/upsmf/grievance/service/impl/SuperAdminImplTest.java new file mode 100644 index 0000000..9b1c85c --- /dev/null +++ b/src/test/java/org/upsmf/grievance/service/impl/SuperAdminImplTest.java @@ -0,0 +1,75 @@ +package org.upsmf.grievance.service.impl; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; + +import org.upsmf.grievance.service.impl.SuperAdminServiceImpl; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +import org.upsmf.grievance.dao.SuperAdminDao; +import org.upsmf.grievance.model.Organization; +import org.upsmf.grievance.model.StatusIdMap; + +public class SuperAdminImplTest { + + @Mock + SuperAdminDao superAdminDao; + + @InjectMocks + SuperAdminServiceImpl superAdminService; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void getAllOrganizationTest() { + Mockito.when(superAdminDao.getAllOrganization()).thenReturn(new ArrayList<Organization>()); + assertEquals(0, superAdminService.getAllOrganization().size()); + } + + @Test + public void addOrganizationTest() { + Mockito.when(superAdminDao.addOrganization(Matchers.any(Organization.class))).thenReturn(new Organization()); + assertEquals(new Organization().getClass(), superAdminService.addOrganization(new Organization()).getClass()); + } + + @Test + public void updateOrganizationByIdTest() { + Mockito.when(superAdminDao.updateOrganizationById(Matchers.any(Organization.class))).thenReturn(true); + assertEquals(true, superAdminService.updateOrganizationById(new Organization())); + } + + /* + * @Test public void getOrganizationByIdTest() { + * Mockito.when(superAdminDao.getOrganizationById(Mockito.anyLong())).thenReturn + * (new Organization()); assertEquals(new Organization().getClass(), + * superAdminService.getOrganizationById(1L).getClass()); } + */ + + @Test + public void deleteOrganizationTest() { + Mockito.when(superAdminDao.deleteOrganization(Matchers.any(Organization.class))).thenReturn(true); + assertEquals(true, superAdminService.deleteOrganization(new Organization())); + } + + @Test + public void mapAppsToOrgTest() { + Mockito.when(superAdminDao.mapAppsToOrg(Matchers.any(StatusIdMap.class))).thenReturn(true); + assertEquals(true, superAdminService.mapAppsToOrg(new StatusIdMap())); + } + + @Test + public void getOrganizationByUserIdTest() { + Mockito.when(superAdminDao.getOrganizationByUser(Matchers.anyLong())).thenReturn(new ArrayList<Organization>()); + assertEquals(0, superAdminService.getOrganizationByUserId(1L).size()); + } +} diff --git a/src/test/java/org/upsmf/grievance/service/impl/TicketServiceImplTest.java b/src/test/java/org/upsmf/grievance/service/impl/TicketServiceImplTest.java new file mode 100644 index 0000000..b438952 --- /dev/null +++ b/src/test/java/org/upsmf/grievance/service/impl/TicketServiceImplTest.java @@ -0,0 +1,124 @@ +package org.upsmf.grievance.service.impl; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; + +import org.upsmf.grievance.service.impl.TicketServiceImpl; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.web.multipart.MultipartFile; + +import org.upsmf.grievance.dao.TicketDao; +import org.upsmf.grievance.dto.TicketTypeDto; +import org.upsmf.grievance.model.ActivityLog; +import org.upsmf.grievance.model.Ticket; +import org.upsmf.grievance.model.TicketElastic; +import org.upsmf.grievance.model.Updates; +import org.upsmf.grievance.model.User; + +public class TicketServiceImplTest { + + @Mock + TicketDao ticketDao; + + @InjectMocks + TicketServiceImpl ticketService; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void getTemplatesVersionTest() { + Mockito.when(ticketDao.getTemplatesVersion()).thenReturn(1L); + assertEquals(1L, ticketService.getTemplatesVersion().longValue()); + } + + @Test + public void updateTicketBasicTest() { + Mockito.when(ticketDao.updateTicketBasic(Matchers.any(MultipartFile.class), Matchers.any(Ticket.class))) + .thenReturn(true); + MultipartFile file = null; + assertEquals(true, ticketService.updateTicketBasic(file, new Ticket())); + } + + @Test + public void getTicketsByIdTest() { + Mockito.when(ticketDao.getTicketsById(Matchers.anyLong(), Matchers.anyLong())).thenReturn(new Ticket()); + assertEquals(new Ticket().getClass(), ticketService.getTicketsById(new User(), 1L).getClass()); + } + + @Test + public void getAllTicketsByAppIdTest() { + Mockito.when(ticketDao.getAllTicketsByAppId(Matchers.anyLong())).thenReturn(new ArrayList<Ticket>()); + assertEquals(0, ticketService.getAllTicketsByAppId(1L).size()); + } + + @Test + public void updateNotesToTicketTest() { + Mockito.when(ticketDao.updateNotesToTicket(Matchers.anyLong(), Matchers.anyLong(), Matchers.anyString())) + .thenReturn(true); + assertEquals(true, ticketService.updateNotesToTicket(new Ticket())); + } + + @Test + public void addUpdateUpdatesToTicketTest() { + Mockito.when(ticketDao.addUpdateUpdatesToTicket(Matchers.any(Updates.class))).thenReturn(true); + assertEquals(true, ticketService.addUpdateUpdatesToTicket(new Updates())); + } + + @Test + public void updateTicketTypeTest() { + Mockito.when(ticketDao.updateTicketType(Matchers.any(TicketTypeDto.class), Matchers.anyLong())) + .thenReturn(true); + assertEquals(true, ticketService.updateTicketType(new TicketTypeDto(), 1L)); + } + + @Test + public void getUpdatesForTicketTest() { + Mockito.when(ticketDao.getUpdatesForTicket(Matchers.anyLong())).thenReturn(new ArrayList<Updates>()); + assertEquals(0, ticketService.getUpdatesForTicket(1L).size()); + } + + @Test + public void updateTicketStatusTest() { + Mockito.when(ticketDao.updateTicketStatus(Matchers.any(Ticket.class))).thenReturn(true); + assertEquals(true, ticketService.updateTicketStatus(new Ticket())); + } + + @Test + public void updateTicketChecklistTest() { + Mockito.when(ticketDao.updateTicketStatus(Matchers.any(Ticket.class))).thenReturn(true); + assertEquals(false, ticketService.updateTicketChecklist(new Ticket())); + } + + @Test + public void getActivityLogsPerTicketTest() { + Mockito.when(ticketDao.getActivityLogsPerTicket(Matchers.anyLong())).thenReturn(new ArrayList<ActivityLog>()); + assertEquals(0, ticketService.getActivityLogsPerTicket(1L).size()); + } + + @Test + public void getTicketDetailsByHelpdeskIdTest() { + Mockito.when(ticketDao.getTicketDetailsByHelpdeskId(Matchers.any(Ticket.class))) + .thenReturn(new ArrayList<TicketElastic>()); + assertEquals(0, ticketService.getTicketDetailsByHelpdeskId(new Ticket()).size()); + } + + /* + * @Test public void keepOnlyCreatedAndCopiedToTicketsTest() { + * Mockito.when(ticketDao.keepOnlyCreatedAndCopiedToTickets(Mockito.anyLong(), + * Mockito.anyListOf(Ticket.class), + * Mockito.anyListOf(Ticket.class))).thenReturn(new ArrayList<Ticket>()); + * assertEquals(0, ticketService .keepOnlyCreatedAndCopiedToTickets(1L, new + * ArrayList<Ticket>(), new ArrayList<Ticket>()).size()); } + */ + +} -- GitLab