/* * eGov suite of products aim to improve the internal efficiency,transparency, * accountability and the service delivery of the government organizations. * * Copyright (C) <2015> eGovernments Foundation * * The updated version of eGov suite of products as by eGovernments Foundation * is available at http://www.egovernments.org * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/ or * http://www.gnu.org/licenses/gpl.html . * * In addition to the terms of the GPL license to be adhered to in using this * program, the following additional terms are to be complied with: * * 1) All versions of this program, verbatim or modified must carry this * Legal Notice. * * 2) Any misrepresentation of the origin of the material is prohibited. It * is required that all modified versions of this material be marked in * reasonable ways as different from the original version. * * 3) This license does not grant any rights to any user of the program * with regards to rights under trademark law for use of the trade names * or trademarks of eGovernments Foundation. * * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. */ package org.egov.api.controller; import static java.util.Arrays.asList; import static org.egov.infra.utils.ApplicationConstant.N; import static org.egov.infra.utils.ApplicationConstant.Y; import static org.egov.infra.workflow.entity.StateAware.byCreatedDate; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; import org.egov.api.adapter.ForwardDetailsAdapter; import org.egov.api.adapter.UserAdapter; import org.egov.api.controller.core.ApiController; import org.egov.api.controller.core.ApiResponse; import org.egov.api.controller.core.ApiUrl; import org.egov.api.model.ComplaintSearchRequest; import org.egov.api.model.ForwardDetails; import org.egov.config.search.Index; import org.egov.config.search.IndexType; import org.egov.eis.entity.EmployeeView; import org.egov.eis.service.PositionMasterService; import org.egov.infra.security.utils.SecurityUtils; import org.egov.infra.workflow.entity.State.StateStatus; import org.egov.infra.workflow.entity.StateAware; import org.egov.infra.workflow.entity.WorkflowTypes; import org.egov.infra.workflow.inbox.InboxRenderServiceDeligate; import org.egov.infra.workflow.service.WorkflowTypeService; import org.egov.infstr.services.EISServeable; import org.egov.infstr.services.PersistenceService; import org.egov.search.domain.Document; import org.egov.search.domain.SearchResult; import org.egov.search.domain.Sort; import org.egov.search.service.SearchService; import org.elasticsearch.search.sort.SortOrder; import org.hibernate.FetchMode; import org.hibernate.FlushMode; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; @org.springframework.web.bind.annotation.RestController @RequestMapping("/v1.0") public class EmployeeController extends ApiController { private static final Logger LOGGER = Logger.getLogger(EmployeeController.class); public static final String EGOV_API_ERROR = "EGOV-API ERROR "; @Autowired private TokenStore tokenStore; @Autowired @Qualifier("entityQueryService") private PersistenceService entityQueryService; @Autowired private WorkflowTypeService workflowTypeService; @Autowired private PositionMasterService posMasterService; @Autowired private SearchService searchService; @Autowired private SecurityUtils securityUtils; @Autowired InboxRenderServiceDeligate<StateAware> inboxRenderServiceDelegate; @Autowired private EISServeable eisService; @RequestMapping(value = ApiUrl.EMPLOYEE_INBOX_LIST_WFT_COUNT, method = RequestMethod.GET, produces = MediaType.TEXT_PLAIN_VALUE) public ResponseEntity<String> getWorkFlowTypesWithItemsCount(final HttpServletRequest request) { final ApiResponse res = ApiResponse.newInstance(); try { return res.setDataAdapter(new UserAdapter()) .success(getWorkflowTypesWithCount(securityUtils.getCurrentUser().getId(), posMasterService .getPositionsForEmployee(securityUtils.getCurrentUser().getId(), new Date()).parallelStream() .map(position -> position.getId()).collect(Collectors.toList()))); } catch (final Exception ex) { LOGGER.error(EGOV_API_ERROR, ex); return res.error(getMessage("server.error")); } } @RequestMapping(value = ApiUrl.EMPLOYEE_INBOX_LIST_FILTER_BY_WFT, method = RequestMethod.GET, produces = MediaType.TEXT_PLAIN_VALUE) public ResponseEntity<String> getInboxListByWorkFlowType(@PathVariable final String workFlowType, @PathVariable final int resultsFrom, @PathVariable final int resultsTo) { final ApiResponse res = ApiResponse.newInstance(); try { return res.setDataAdapter(new UserAdapter()) .success(createInboxData(getWorkflowItemsByUserAndWFType(securityUtils.getCurrentUser().getId(), posMasterService.getPositionsForEmployee(securityUtils.getCurrentUser().getId(), new Date()) .parallelStream() .map(position -> position.getId()).collect(Collectors.toList()), workFlowType, resultsFrom, resultsTo))); } catch (final Exception ex) { LOGGER.error(EGOV_API_ERROR, ex); return res.error(getMessage("server.error")); } } @RequestMapping(value = ApiUrl.EMPLOYEE_SEARCH_INBOX, method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE) public ResponseEntity<String> searchEmployeeInbox(@PathVariable final Integer pageno, @PathVariable final Integer limit, @RequestBody final ComplaintSearchRequest searchRequest) { try { final org.egov.search.domain.Page page = org.egov.search.domain.Page.at(pageno); page.ofSize(limit); final SearchResult searchResult = searchService.search( asList(Index.PGR.toString()), asList(IndexType.COMPLAINT.toString()), searchRequest.searchQuery(), searchRequest.searchFilters(), Sort.by().field("common.createdDate", SortOrder.DESC), page); final String jsonString = searchResult.rawResponse(); final JSONObject respObj = (JSONObject) new JSONParser().parse(jsonString); final JSONObject jObjHits = (JSONObject) respObj.get("hits"); final Long total = (Long) jObjHits.get("total"); final boolean hasNextPage = total > pageno * limit; final ArrayList<Document> inboxItems = new ArrayList<>(); for (final Document document : searchResult.getDocuments()) { final JSONObject jResourceObj = document.getResource(); final LinkedHashMap<String, Object> jSearchableObj = (LinkedHashMap<String, Object>) jResourceObj .get("searchable"); final LinkedHashMap<String, Object> jOwnerObj = (LinkedHashMap<String, Object>) jSearchableObj.get("owner"); if ((int) jOwnerObj.get("id") == posMasterService.getPositionByUserId(securityUtils.getCurrentUser().getId()) .getId()) inboxItems.add(document); } final JsonArray result = (JsonArray) new Gson().toJsonTree(inboxItems, new TypeToken<List<Document>>() { }.getType()); final JsonObject jsonResp = new JsonObject(); jsonResp.add("searchItems", result); jsonResp.addProperty("hasNextPage", hasNextPage); return getResponseHandler().success(jsonResp); } catch (final Exception e) { LOGGER.error(EGOV_API_ERROR, e); return getResponseHandler().error(getMessage("server.error")); } } // --------------------------------------------------------------------------------// /** * Clear the session * * @param request * @return */ @RequestMapping(value = ApiUrl.EMPLOYEE_LOGOUT, method = RequestMethod.POST) public ResponseEntity<String> logout(final HttpServletRequest request, final OAuth2Authentication authentication) { try { final OAuth2AccessToken token = tokenStore.getAccessToken(authentication); if (token == null) return ApiResponse.newInstance().error(getMessage("msg.logout.unknown")); tokenStore.removeAccessToken(token); return ApiResponse.newInstance().success("", getMessage("msg.logout.success")); } catch (final Exception ex) { LOGGER.error(EGOV_API_ERROR, ex); return ApiResponse.newInstance().error(getMessage("server.error")); } } @RequestMapping(value = ApiUrl.EMPLOYEE_FORWARD_DEPT_DESIGNATION_USER, method = RequestMethod.GET, produces = MediaType.TEXT_PLAIN_VALUE) public ResponseEntity<String> getForwardDetails( @RequestParam(value = "department", required = true) final Integer departmentId, @RequestParam(value = "designation", required = false) final Integer designationId) { try { final ForwardDetails forwardDetails = new ForwardDetails(); // identify requesting for users or designations with this if condition if (departmentId != null && designationId != null) { final Set<EmployeeView> users = new HashSet<>(); final HashMap<String, String> paramMap = new HashMap<String, String>(); paramMap.put("departmentId", String.valueOf(departmentId)); paramMap.put("designationId", String.valueOf(designationId)); final List<EmployeeView> empViewList = (List<EmployeeView>) eisService.getEmployeeInfoList(paramMap); empViewList.stream().forEach(user -> { user.getEmployee().getRoles().stream().forEach(role -> { if (role.getName().matches("Redressal Officer|Grievance Officer|Grievance Routing Officer")) users.add(user); }); }); forwardDetails.setUsers(users); } else if (departmentId != null) forwardDetails.setDesignations(eisService.getAllDesignationByDept(departmentId, new Date())); return getResponseHandler().setDataAdapter(new ForwardDetailsAdapter()).success(forwardDetails); } catch (final Exception e) { LOGGER.error(EGOV_API_ERROR, e); return getResponseHandler().error(getMessage("server.error")); } } /* DATA RELATED FUCNTIONS */ private JsonArray createInboxData(final List<StateAware> inboxStates) { final JsonArray inboxItems = new JsonArray(); inboxStates.sort(byCreatedDate()); for (final StateAware stateAware : inboxStates) inboxItems.add(new JsonParser().parse(stateAware.getStateInfoJson()).getAsJsonObject()); return inboxItems; } @SuppressWarnings("unchecked") public List<StateAware> getWorkflowItemsByUserAndWFType(final Long userId, final List<Long> owners, final String workFlowType, final int resultsFrom, final int resultsTo) throws HibernateException, ClassNotFoundException { return entityQueryService.getSession() .createCriteria(Class.forName(workflowTypeService.getEnabledWorkflowTypeByType(workFlowType).getTypeFQN())) .setFirstResult(resultsFrom) .setMaxResults(resultsTo) .setFetchMode("state", FetchMode.JOIN).createAlias("state", "state") .setFlushMode(FlushMode.MANUAL).setReadOnly(true).setCacheable(true) .add(Restrictions.eq("state.type", workFlowType)) .add(Restrictions.in("state.ownerPosition.id", owners)) .add(Restrictions.ne("state.status", StateStatus.ENDED)) .add(Restrictions.not(Restrictions.conjunction().add(Restrictions.eq("state.status", StateStatus.STARTED)) .add(Restrictions.eq("createdBy.id", userId)))) .addOrder(Order.desc("state.createdDate")) .list(); } @SuppressWarnings("unchecked") public Number getWorkflowItemsCountByWFType(final Long userId, final List<Long> owners, final String workFlowType) throws HibernateException, ClassNotFoundException { return (Number) entityQueryService.getSession() .createCriteria(Class.forName(workflowTypeService.getEnabledWorkflowTypeByType(workFlowType).getTypeFQN())) .setFetchMode("state", FetchMode.JOIN).createAlias("state", "state") .setFlushMode(FlushMode.MANUAL).setReadOnly(true).setCacheable(true) .setProjection(Projections.rowCount()) .add(Restrictions.eq("state.type", workFlowType)) .add(Restrictions.in("state.ownerPosition.id", owners)) .add(Restrictions.ne("state.status", StateStatus.ENDED)) .add(Restrictions.not(Restrictions.conjunction().add(Restrictions.eq("state.status", StateStatus.STARTED)) .add(Restrictions.eq("createdBy.id", userId)))) .uniqueResult(); } public List<HashMap<String, Object>> getWorkflowTypesWithCount(final Long userId, final List<Long> ownerPostitions) throws HibernateException, ClassNotFoundException { final List<HashMap<String, Object>> workFlowTypesWithItemsCount = new ArrayList<>(); final Query query = entityQueryService.getSession().createQuery( "select type, count(type) from State where ownerPosition.id in (:ownerPositions) and status != :statusEnded and createdBy.id != :userId group by type"); query.setParameterList("ownerPositions", ownerPostitions); query.setParameter("statusEnded", StateStatus.ENDED); query.setParameter("userId", userId); final List<Object[]> result = query.list(); for (final Object[] rowObj : result) { final Long wftitemscount = (Long) getWorkflowItemsCountByWFType(userId, ownerPostitions, String.valueOf(rowObj[0])); if (wftitemscount > 0) { final HashMap<String, Object> workFlowType = new HashMap<>(); final WorkflowTypes workFlowTypeObj = workflowTypeService.getEnabledWorkflowTypeByType(String.valueOf(rowObj[0])); workFlowType.put("workflowtype", rowObj[0]); workFlowType.put("inboxlistcount", wftitemscount); workFlowType.put("workflowtypename", workFlowTypeObj.getDisplayName()); workFlowType.put("workflowgroupYN", workFlowTypeObj.isGrouped() ? Y : N); workFlowTypesWithItemsCount.add(workFlowType); } } return workFlowTypesWithItemsCount; } }