Promact/slack-erp-custom-integration-mvc

View on GitHub
Slack.Automation/Promact.Core.Repository/LeaveReportRepository/LeaveReportRepository.cs

Summary

Maintainability
B
4 hrs
Test Coverage
using Promact.Core.Repository.OauthCallsRepository;
using Promact.Erp.DomainModel.ApplicationClass;
using Promact.Erp.DomainModel.DataRepository;
using Promact.Erp.DomainModel.Models;
using Promact.Erp.Util.StringConstants;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Promact.Core.Repository.LeaveReportRepository
{
    public class LeaveReportRepository : ILeaveReportRepository
    {

        #region Private Variables
        private readonly IRepository<LeaveRequest> _leaveRequest;
        private readonly IOauthCallHttpContextRespository _oauthCallsRepository;
        private readonly IStringConstantRepository _stringConstant;
        #endregion

        #region Constructor
        public LeaveReportRepository(IRepository<LeaveRequest> leaveRequest, IStringConstantRepository stringConstant, 
            IOauthCallHttpContextRespository oauthCallsRepository)
        {
            _leaveRequest = leaveRequest;
            _stringConstant = stringConstant;
            _oauthCallsRepository = oauthCallsRepository;
        }
        #endregion

        #region Private methods
        /// <summary>
        /// Method to return the list of leave reports
        /// </summary>
        /// <param name="distinctLeaveRequests">list of LeaveRequest</param>
        /// <returns>List of leave reports</returns>
        private async Task<List<LeaveReport>> GetLeaveReportListAsync(List<LeaveRequest> distinctLeaveRequests)
        {
            List<LeaveReport> leaveReports = new List<LeaveReport>();
            foreach (var leaveRequest in distinctLeaveRequests)
            {
                //Get details of the employee from oauth server
                User user = await GetEmployeeByIdAsync(leaveRequest.EmployeeId);
                if (!string.IsNullOrEmpty(user.Id))
                {
                    LeaveReport leaveReport = new LeaveReport
                    {
                        Role = user.Role,
                        EmployeeId = user.Id,
                        EmployeeUserName = user.Email,
                        EmployeeName = string.Format(_stringConstant.EmployeeFirstLastNameFormat, user.FirstName, user.LastName),
                        TotalCasualLeave = user.NumberOfCasualLeave,
                        TotalSickLeave = user.NumberOfSickLeave,
                        UtilisedCasualLeave = await GetUtilisedCasualLeavesByEmployeeAsync(leaveRequest.EmployeeId),
                        BalanceCasualLeave = user.NumberOfCasualLeave - (await GetUtilisedCasualLeavesByEmployeeAsync(leaveRequest.EmployeeId)),
                        UtilisedSickLeave = await GetUtilisedSickLeavesByEmployeeAsync(leaveRequest.EmployeeId),
                        BalanceSickLeave = user.NumberOfSickLeave - ( await GetUtilisedSickLeavesByEmployeeAsync(leaveRequest.EmployeeId)),
                    };
                    leaveReports.Add(leaveReport);
                }
            }
            return leaveReports;
        }

        /// <summary>
        /// Method to calculate number of casual leaves used by a specific employee
        /// </summary>
        /// <param name="employeeId">userId of user</param>
        /// <returns>Number of casual leaves utilised</returns>
        private async Task<double> GetUtilisedCasualLeavesByEmployeeAsync(string employeeId)
        {
            var utilisedCasualLeave = 0;
            //Get all leaves applied by the specific employee 
            List<LeaveRequest> leaves = (await _leaveRequest.FetchAsync(x => x.EmployeeId == employeeId)).ToList();
            foreach (var leave in leaves)
            {
                //Calculate utilised casual leaves
                if (leave.Status == Condition.Approved && leave.Type == LeaveType.cl)
                {
                    utilisedCasualLeave = utilisedCasualLeave + leave.EndDate.Value.Date.Subtract(leave.FromDate).Days + 1;
                }
            }
            return utilisedCasualLeave;
        }

        /// <summary>
        /// Method to calculate number of sick leaves used by a specific employee
        /// </summary>
        /// <param name="employeeId">userId of user</param>
        /// <returns>Number of sick leaves utilised</returns>
        private async Task<double> GetUtilisedSickLeavesByEmployeeAsync(string employeeId)
        {
            var utilisedSickLeave = 0;
            //Get all leaves applied by the specific employee
            List<LeaveRequest> leaves = (await _leaveRequest.FetchAsync(x => x.EmployeeId == employeeId)).ToList();
            foreach (var leave in leaves)
            {
                //Calculate utilised sick leaves
                if (leave.Status == Condition.Approved && leave.Type == LeaveType.sl)
                {
                    utilisedSickLeave = utilisedSickLeave + leave.EndDate.Value.Date.Subtract(leave.FromDate).Days + 1;
                }
            }
            return utilisedSickLeave;
        }

        /// <summary>
        /// Method to get user details from the Oauth server using their id and access token
        /// </summary>
        /// <param name="employeeId">userId of user</param>
        /// <returns>User details</returns>
        private async Task<User> GetEmployeeByIdAsync(string employeeId)
        {
            User user = await _oauthCallsRepository.GetUserByEmployeeIdAsync(employeeId);
            return user;
        }

        #endregion

        #region Public methods
        /// <summary>
        /// Method that returns leave report based on the role of logged in user
        /// </summary>
        /// <param name="userId">userId of user</param>
        /// <returns>list of Leave report</returns>       
        public async Task<IEnumerable<LeaveReport>> LeaveReportAsync(string userId)
        {
            //Get all approved leave requests
            List<LeaveRequest> leaveRequests = _leaveRequest.GetAll().ToList().FindAll(x => x.Status.Equals(Condition.Approved));
            List<LeaveReport> leaveReports = new List<LeaveReport>();
           
            //Get details of logged in user
            User loginUser = await GetEmployeeByIdAsync(userId);

            //Check if there exists any approved leave request 
            if(leaveRequests.Any())
            {
                //Return leave report as per the role of logged in user
                //For admin, leave report of all the employees 
                if (loginUser.Role.Equals(_stringConstant.Admin))
                {
                    List<LeaveRequest> distinctLeaveRequests = leaveRequests.GroupBy(x => x.EmployeeId).Select(x => x.FirstOrDefault()).ToList();
                    leaveReports = await GetLeaveReportListAsync(distinctLeaveRequests);
                }
                //For teamleader, leave report of all the team member(s) 
                else
                {
                    var projectUsers = await _oauthCallsRepository.GetListOfEmployeeAsync(loginUser.Id);
                    foreach (var projectUser in projectUsers)
                    {
                        List<LeaveRequest> distinctLeaveRequests = leaveRequests.Where(x => x.EmployeeId.Contains(projectUser.UserId)).GroupBy(x => x.EmployeeId).Select(x => x.FirstOrDefault()).ToList();
                        List<LeaveReport> leaveReport = await GetLeaveReportListAsync(distinctLeaveRequests);
                        leaveReports.AddRange(leaveReport);
                    }
                }
            }            
            return leaveReports;
        }

        
        /// <summary>
        /// Method that returns the details of leave for an employee
        /// </summary>
        /// <param name="employeeId">userId of user</param>
        /// <returns>Details of leave for an employee</returns>
        public async Task <IEnumerable<LeaveReportDetails>> LeaveReportDetailsAsync(string employeeId)
        {
            //Get user details
            User user = await GetEmployeeByIdAsync(employeeId);
            List<LeaveReportDetails> leaveReportDetails = new List<LeaveReportDetails>();

            if (user != null)
            {
                //Get all leaves applied by the employee
                List<LeaveRequest> leaves = (await _leaveRequest.FetchAsync(x => x.EmployeeId == employeeId)).ToList();

                //Assign details of approved leaves
                foreach (var leave in leaves)
                {
                    LeaveReportDetails leaveReportDetail = new LeaveReportDetails();
                    if (leave.Status == Condition.Approved)
                    {
                        leaveReportDetail.EmployeeUserName = user.Email;
                        leaveReportDetail.EmployeeName = string.Format(_stringConstant.EmployeeFirstLastNameFormat, user.FirstName, user.LastName);
                        leaveReportDetail.LeaveFrom = leave.FromDate.ToShortDateString();
                        leaveReportDetail.StartDay = leave.FromDate.DayOfWeek.ToString();
                        leaveReportDetail.LeaveUpto = leave.EndDate.Value.ToShortDateString();
                        leaveReportDetail.EndDay = leave.EndDate.Value.DayOfWeek.ToString();
                        leaveReportDetail.Reason = leave.Reason;
                        leaveReportDetail.Type = leave.Type.ToString();
                        leaveReportDetails.Add(leaveReportDetail);
                    }
                }
                return leaveReportDetails;
            }
            return leaveReportDetails;
        }
        #endregion
    }
}