Commit 3e557516 authored by Vijay Akula's avatar Vijay Akula

Merge branch 'FEATURE/REPORTS_ENHANCEMENTS' of...

Merge branch 'FEATURE/REPORTS_ENHANCEMENTS' of https://gitlab.mynisum.com/hr/mytime into FEATURE/REPORTS_ENHANCEMENTS
parents ed2d5cc3 7702c665
......@@ -11,10 +11,12 @@ import javax.servlet.http.HttpServletRequest;
import com.nisum.myteam.model.dao.EmployeeSubStatus;
import com.nisum.myteam.model.dao.EmployeeVisa;
import com.nisum.myteam.model.vo.EmployeeSubStatusVO;
import com.nisum.myteam.repository.EmployeeVisaRepo;
import com.nisum.myteam.service.ISubStatusService;
import com.nisum.myteam.service.impl.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
......@@ -280,6 +282,19 @@ public class EmployeeController {
return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);
}
@RequestMapping(value = "/employeesBasedOnSubStatusForGivenDates", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> employeesBasedOnSubStatusForGivenDates(@RequestParam("fromDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date fromDate ,
@RequestParam("toDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date toDate,
@RequestParam("subStatus") String subStatus ,
HttpServletRequest request){
List<EmployeeSubStatusVO> employees = subStatusService.employeesBasedOnSubStatusForGivenDates(fromDate,toDate,subStatus);
ResponseDetails responseDetails = new ResponseDetails(new Date(), 904, "Fetched Employees Successfully",
"Fetched Employees Successfully", employees , request.getRequestURI(), "Resource details", null);
return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);
}
......
package com.nisum.myteam.model.vo;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@ToString
public class EmployeeSubStatusVO {
private String empId;
private String empName;
private String empStatus;
private Date fromDate;
private Date toDate;
private String functionalGroup;
}
......@@ -9,6 +9,7 @@ import com.nisum.myteam.model.dao.Employee;
public interface EmployeeRepo
extends MongoRepository<Employee, String> {
Employee findByEmployeeIdAndEmpStatus(String employeeId,String empStatus);
Employee findByEmailId(String emailId);
......
......@@ -8,4 +8,6 @@ import java.util.List;
public interface EmployeeSubStatusRepo extends MongoRepository<EmployeeSubStatus, String> {
public List<EmployeeSubStatus> findByEmployeeID(String employeeId);
public List<EmployeeSubStatus> findBySubStatus(String subStatus);
}
package com.nisum.myteam.service;
import java.util.Date;
import java.util.List;
import com.nisum.myteam.model.dao.Employee;
import com.nisum.myteam.model.dao.EmployeeSubStatus;
import com.nisum.myteam.model.vo.EmployeeSubStatusVO;
public interface ISubStatusService {
public EmployeeSubStatus getLatestEmployeeSubStatus(String empId);
......@@ -12,4 +17,6 @@ public interface ISubStatusService {
public EmployeeSubStatus getCurrentSubStatus(String employeeId);
public EmployeeSubStatus endSubStatus(String loginnEmployeeId,EmployeeSubStatus subStatus);
public List<EmployeeSubStatusVO> employeesBasedOnSubStatusForGivenDates(Date fromDate, Date toDate, String subStatus);
}
......@@ -583,7 +583,9 @@ public class ResourceService implements IResourceService {
// Active
if (statusFlag.equals(ResourceStatus.ACTIVE.getStatus()) && resource.getStatus().equals(MyTeamUtils.STATUS_ENGAGED)) {
if (statusFlag.equals(ResourceStatus.ACTIVE.getStatus()) &&
(resource.getStatus().equals(MyTeamUtils.STATUS_ENGAGED) ||
(resource.getProjectId().equalsIgnoreCase(MyTeamUtils.BENCH_PROJECT_ID) && this.isAllocationActiveToday(resource)))) {
resourceVO.setResourceStatus(ResourceStatus.ACTIVE.getStatus());
resourcesList.add(resourceVO);
} else if (statusFlag.equals(ResourceStatus.IN_ACTIVE.getStatus()) && resource.getStatus().equals(MyTeamUtils.STATUS_RELEASED)) {
......
package com.nisum.myteam.service.impl;
import com.nisum.myteam.model.dao.Employee;
import com.nisum.myteam.model.dao.EmployeeSubStatus;
import com.nisum.myteam.model.vo.EmployeeSubStatusVO;
import com.nisum.myteam.repository.EmployeeRepo;
import com.nisum.myteam.repository.EmployeeSubStatusRepo;
import com.nisum.myteam.service.ISubStatusService;
import com.nisum.myteam.utils.MyTeamDateUtils;
......@@ -8,7 +11,13 @@ import com.nisum.myteam.utils.MyTeamUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
......@@ -17,6 +26,10 @@ public class SubStatusService implements ISubStatusService {
@Autowired
private EmployeeSubStatusRepo employeeSubStatusRepo;
@Autowired
private EmployeeRepo employeeRepo;
public HashMap<String, Object> respMap = new HashMap<>();
@Override
......@@ -71,5 +84,64 @@ public class SubStatusService implements ISubStatusService {
}
return null;
}
//not called by ANY ONE
public boolean isDatesValid(EmployeeSubStatus subStatus){
boolean isValid = false;
List<EmployeeSubStatus> subStatusList = employeeSubStatusRepo.findByEmployeeID(subStatus.getEmployeeID());
List<EmployeeSubStatus> matchedList = subStatusList.stream().filter(s -> (s.getFromDate().compareTo(subStatus.getFromDate())<=0 && s.getToDate().compareTo(subStatus.getFromDate())>=0) &&
(s.getFromDate().compareTo(subStatus.getToDate())<=0 && s.getToDate().compareTo(subStatus.getToDate())>=0)).collect(Collectors.toList());
if(!matchedList.isEmpty()){
respMap.put("statusCode", 811);
respMap.put("message", "resource is already on substatus on these days");
//resource is already on substatus on these days
}else{
isValid = true;
}
return isValid;
}
@Override
public List<EmployeeSubStatusVO> employeesBasedOnSubStatusForGivenDates(Date fromDate, Date toDate, String subStatus) {
List<EmployeeSubStatusVO> employees=new ArrayList<>();
List<EmployeeSubStatus> employeswithSubStatus=employeeSubStatusRepo.findBySubStatus(subStatus);
if(subStatus.equals("All")) {
employeswithSubStatus=employeeSubStatusRepo.findAll();
}
employeswithSubStatus.stream().filter(e->isDateCommon(e,fromDate,toDate)
)
.forEach(e->{
Employee employee=employeeRepo.findByEmployeeIdAndEmpStatus(e.getEmployeeID(), MyTeamUtils.ACTIVE);
if(employee!=null) {
EmployeeSubStatusVO empSubStatus=new EmployeeSubStatusVO();
empSubStatus.setEmpId(e.getEmployeeID());
empSubStatus.setEmpName(employee.getEmployeeName());
empSubStatus.setEmpStatus(e.getSubStatus());
empSubStatus.setFromDate(e.getFromDate());
empSubStatus.setToDate(e.getToDate());
empSubStatus.setFunctionalGroup(employee.getFunctionalGroup());
employees.add(empSubStatus);
}});
return employees;
}
private boolean isDateCommon(EmployeeSubStatus e, Date fromDate, Date toDate) {
for (LocalDate datei = convert(fromDate); datei.isBefore(convert(toDate).plusDays(1)); datei = datei.plusDays(1))
for (LocalDate datej = convert(e.getFromDate()); datej.isBefore(convert(e.getToDate()).plusDays(1)); datej = datej.plusDays(1))
if(datej.equals(datei))
return true;
return false;
}
private LocalDate convert(Date date) {
Instant instant = Instant.ofEpochMilli(date.getTime());
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
return localDateTime.toLocalDate();
}
}
......@@ -6,10 +6,6 @@ myApp.controller("allocationChangeReportController",function($scope,exportUiGrid
$scope.toDate = today;
$scope.fromDate = priorDt;
// +'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i ng-show="row.entity.status == \'InActive\'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</i><i class="fa fa-minus-circle fa-2x" aria-hidden="true" style="font-size:1.5em;margin-top:3px;cursor:pointer;" data-placement="left" title="Delete" onmouseenter="$(this).tooltip(\'show\')" ng-click="grid.appScope.getRowData(row,\'Delete\')"></i></p>';
$scope.gridOptions = {
paginationPageSizes : [ 10, 20, 30, 40, 50, 100],
paginationPageSize : 10,
......
......@@ -266,6 +266,7 @@ myApp.controller("loginController",function($scope, myFactory, $compile, $window
menuItems.push({"menu" : "Employee Efforts","icon" : "fa fa-user-circle-o fa-2x","path" : "templates/employeeEfforts.html"});
menuItems.push({"menu" : "Reserved Reports","icon" : "fa fa-file-pdf-o fa-2x","path" : "templates/reservedReport.html"});
menuItems.push({"menu" : "Allocation Change","icon" : "fa fa-file-excel-o fa-2x","path" : "templates/allocationChangeReport.html"});
menuItems.push({"menu" : "SubStatus Report","icon" : "fa fa-area-chart fa-2x","path" : "templates/subStatusReport.html"});
}else if(role == "Delivery Lead"){
//menuItems.push({"menu" : "Manage Employees","icon" : "fa fa-user-plus fa-2x","path" : "templates/roles.html"});
//menuItems.push({"menu" : "Manage Team","icon" : "fa fa-sitemap fa-2x","path" : "templates/projectDetails.html"});
......@@ -304,6 +305,7 @@ myApp.controller("loginController",function($scope, myFactory, $compile, $window
menuItems.push({"menu" : "Employee Efforts ","icon" : "fa fa-user-circle-o fa-2x","path" : "templates/employeeEfforts.html"});
menuItems.push({"menu" : "Reserved Reports","icon" : "fa fa-file-pdf-o fa-2x","path" : "templates/reservedReport.html"});
menuItems.push({"menu" : "Allocation Change","icon" : "fa fa-file-excel-o fa-2x","path" : "templates/allocationChangeReport.html"});
menuItems.push({"menu" : "SubStatus Report","icon" : "fa fa-area-chart fa-2x","path" : "templates/subStatusReport.html"});
}else if(role == "Lead"){
menuItems.push({"menu" : "My Team","icon" : "fa fa-futbol-o fa-2x","path" : "templates/myTeam.html"});
menuItems.push({"menu" : "Reportee Login Details","icon" : "fa fa-users fa-2x","path" : "templates/reportees.html"});
......@@ -335,6 +337,7 @@ myApp.controller("loginController",function($scope, myFactory, $compile, $window
menuItems.push({"menu" : "Employee Efforts","icon" : "fa fa-user-circle-o fa-2x","path" : "templates/employeeEfforts.html"});
menuItems.push({"menu" : "Reserved Reports","icon" : "fa fa-file-pdf-o fa-2x","path" : "templates/reservedReport.html"});
menuItems.push({"menu" : "Allocation Change","icon" : "fa fa-file-excel-o fa-2x","path" : "templates/allocationChangeReport.html"});
menuItems.push({"menu" : "SubStatus Report","icon" : "fa fa-area-chart fa-2x","path" : "templates/subStatusReport.html"});
}else{
menuItems.push({"menu" : "My Team","icon" : "fa fa-futbol-o fa-2x","path" : "templates/myTeam.html"});
menuItems.push({"menu" : "My Project Allocations","icon" : "fa fa-life-ring fa-2x","path" : "templates/myProjectAllocations.html"});
......
myApp.controller("subStatusController", function($scope, $http, myFactory, $mdDialog, appConfig) {
$scope.records = [];
$scope.empSubStatuses = myFactory.getEmployeeSubStatus();
if($scope.empSubStatuses.indexOf("All") == "-1"){
$scope.empSubStatuses.unshift("All");
}
// Date picker related code
var today = new Date();
var priorDt = new Date(today.getTime() - ( 30 * 24 * 60 * 60 * 1000));
$scope.maxDate = today;
$scope.fromDate = priorDt;
$scope.toDate = today;
$scope.gridOptions = {
paginationPageSizes : [ 10, 20, 30, 40, 50, 100],
paginationPageSize : 10,
pageNumber: 1,
pageSize:10,
enableFiltering:true,
columnDefs : [
{field : 'empId',displayName: 'Employee ID', enableColumnMenu: true, enableSorting: true, enableFiltering: true,width:'*'},
{field : 'empName',displayName: 'Employee Name', enableColumnMenu: false, enableSorting: false, enableFiltering: true,width:'*'},
{field : 'empStatus',displayName: 'Sub Status', enableColumnMenu: false, enableSorting: false,enableFiltering: true,width:'*'},
{field : 'fromDate',displayName: 'From Date', enableColumnMenu: false,enableFiltering: false, cellFilter: 'date:"dd-MMM-yyyy"',width:'*'},
{field : 'toDate',displayName: 'To Date', enableColumnMenu: false,enableSorting: false,enableFiltering: false , cellFilter: 'date:"dd-MMM-yyyy"',width:'*'},
{field : 'functionalGroup',displayName: 'Functional Group', enableColumnMenu: false, enableSorting: false, enableFiltering: true,width:'*'}
],
enableGridMenu: true,
enableSelectAll: true,
exporterMenuExcel:false,
exporterMenuCsv:false,
exporterCsvFilename: 'SubStatusReport.csv',
exporterExcelFilename:'SubStatusReport',
exporterPdfDefaultStyle: {fontSize: 9},
exporterPdfTableStyle: {margin: [15, 15, 15, 15]},
exporterPdfTableHeaderStyle: {fontSize: 10, bold: true, italics: true, color: 'red'},
exporterPdfHeader: { text: "Employee SubStatus Report", style: 'headerStyle' },
exporterPdfFooter: function ( currentPage, pageCount ) {
return { text: currentPage.toString() + ' of ' + pageCount.toString(), style: 'footerStyle' };
},
exporterPdfCustomFormatter: function ( docDefinition ) {
docDefinition.styles.headerStyle = { fontSize: 22, bold: true };
docDefinition.styles.footerStyle = { fontSize: 10, bold: true };
return docDefinition;
},
exporterPdfOrientation: 'portrait',
exporterPdfPageSize: 'LETTER',
exporterPdfMaxGridWidth: 500,
exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")),
onRegisterApi: function(gridApi){
$scope.gridApi = gridApi;
},
gridMenuCustomItems: [{
title: 'Export all data as EXCEL',
action: function ($event) {
exportUiGridService.exportToExcel('sheet 1', $scope.gridApi, 'all', 'all');
},
order: 110
},
{
title: 'Export visible data as EXCEL',
action: function ($event) {
exportUiGridService.exportToExcel('sheet 1', $scope.gridApi, 'visible', 'visible');
},
order: 111
}
]
};
$scope.gridOptions.data = [];
$scope.getSubStatusDetails = function(){
var fromDate = getFormattedDate($scope.fromDate);
var toDate = getFormattedDate($scope.toDate);
var empSubStatusV = $scope.empSubStatusValue;
if(empSubStatusV == undefined || empSubStatusV==""){
empSubStatusV="All";
}
$scope.empSubStatusValue=empSubStatusV;
$http({
method : "GET",
url : appConfig.appUri + 'employeesBasedOnSubStatusForGivenDates?fromDate='+fromDate+'&toDate='+toDate+'&subStatus='+$scope.empSubStatusValue
}).then(function mySuccess(response) {
$scope.gridOptions.data = response.data.records;
if(response.data.records.length > 10){
$scope.gridOptions.enablePaginationControls = true;
}
else{
$scope.gridOptions.enablePaginationControls = false;
}
}, function myError(response) {
showAlert("Something went wrong while fetching data!!!");
$scope.gridOptions.data = [];
});
};
$scope.getSelectedSubStatus = function(){
if ($scope.empSubStatusValue !== undefined) {
return $scope.empSubStatusValue;
} else {
return "Please select a SubStatus";
}
};
$scope.validateDates = function(dateValue, from) {
if(from == "FromDate"){
var toDat = $scope.toDate;
var difference = daysBetween(dateValue, toDat);
if(difference < 0 ){
showAlert('From Date should not be greater than To Date');
$scope.fromDate = priorDt;
$scope.toDate = today;
}else{
$scope.fromDate = dateValue;
$scope.toDate = toDat;
}
}else if(from == "ToDate"){
var fromDat = $scope.fromDate;
var differene = daysBetween(fromDat, dateValue);
if(differene < 0 ){
showAlert('To Date should not be less than From Date');
$scope.fromDate = priorDt;
$scope.toDate = today;
}else{
$scope.fromDate = fromDat;
$scope.toDate = dateValue;
}
}
};
function showAlert(message) {
$mdDialog.show($mdDialog.alert().parent(
angular.element(document.querySelector('#popupContainer')))
.clickOutsideToClose(true).textContent(message).ariaLabel(
'Alert Dialog').ok('Ok'));
}
function getFormattedDate(date){
var day = date.getDate();
var month = date.getMonth() + 1;
var year = date.getFullYear();
return year + '-' + (month < 10 ? "0" + month : month) + '-'
+ (day < 10 ? "0" + day : day);
}
function treatAsUTC(date) {
var result = new Date(date);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}
function daysBetween(fromDate, toDate) {
var millisecondsPerDay = 24 * 60 * 60 * 1000;
return Math.round((treatAsUTC(toDate) - treatAsUTC(fromDate)) / millisecondsPerDay);
}
});
......@@ -182,7 +182,7 @@ i.fa.fa-refresh:hover {
background: transparent;
}
#sidebar-wrapper .sidebar-nav li ul.reportsGroup {
max-height: 291px;
max-height: 332px;
height: auto;
overflow: hidden;
padding: 0;
......@@ -679,4 +679,18 @@ cursor: pointer;
.alertMsg{
margin: 10px 0 0 0;
}
.substatus-dropdown > label {
padding:0;
margin-top:10px;
}
.substatus-dropdown md-datepicker {
padding:0;
}
.substatus-dropdown >md-select {
margin:0;
}
.substatus-report-grid {
height: calc(85vh - 150px) !important;
}
\ No newline at end of file
......@@ -73,6 +73,7 @@
<script src="controllers/MyProfileController.js"></script>
<script src="controllers/ResyncDataController.js"></script>
<script src="controllers/MyProjectAllocations.js"></script>
<script src="controllers/SubStatusReportController.js"></script>
<script src="controllers/DashboardController.js"></script>
<script src="controllers/VisaController.js"></script>
......
<div class="md-padding" id="popupContainer" ng-controller="subStatusController" ng-init="getSubStatusDetails()">
<div class="container-fluid mainDivHeaderClass">
<div class="row">
<div class="col-lg-12">
<h1 class="no-padding">Employee SubStatus Report
<span class="right">
<i class="fa fa-refresh" aria-hidden="true" ng-click="refreshPage()"></i>
</span>
</h1>
</div>
<div class="clearfix"></div>
</div>
</div>
<div class="form-horizontal">
<div class="form-group">
<div class="form-inline col-lg-12">
<div class="form-group row col-lg-4 col-sm-4 substatus-dropdown">
<label class="col-lg-3" for="fromDate">Start Date: </label>
<md-datepicker class="col-lg-9"
ng-model="fromDate" md-placeholder="Enter date"
md-min-date="minDate" md-max-date="maxDate"
onkeydown="return false"
ng-change="validateDates(fromDate, 'FromDate')">
</md-datepicker>
</div>
<div class="form-group row col-lg-4 col-sm-5 substatus-dropdown">
<label class="col-lg-3" for="toDate">End Date: </label>
<md-datepicker
class="col-lg-8"
ng-model="toDate" md-placeholder="Enter date"
md-min-date="minDate" md-max-date="maxDate"
onkeydown="return false"
ng-change="validateDates(toDate, 'ToDate')">
</md-datepicker>
</div>
<div class="form-group col-lg-3 col-sm-5 d-flex substatus-dropdown">
<label class="col-lg-5" for="fromDate">SubStatus: </label>
<md-select class="col-lg-7 " ng-model="empSubStatusValue" md-selected-text="getSelectedSubStatus() " id="empSubStatus" name="empSubStatus">
<md-optgroup label="Employee SubStatus ">
<md-option ng-value="empSubStatusValue " ng-repeat="empSubStatusValue in empSubStatuses">{{empSubStatusValue}}</md-option>
</md-optgroup>
</md-select>
</div>
<div class="form-group col-lg-1 col-sm-2" style="margin-left: 20px;">
<label for="submitBtn"> <md-button
class="md-raised md-primary"
ng-click="getSubStatusDetails('click')"> <i
class="fa fa-search fa-2x"></i> Search</md-button></label>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div id="gridTest" ui-grid="gridOptions" ui-grid-pagination ui-grid-exporter
class="myGrid substatus-report-grid">
<div class="watermark" ng-show="!gridOptions.data.length">No
data available</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment