using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.WebUtilities; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using MTWorkHR.Application.Identity; using MTWorkHR.Application.Mapper; using MTWorkHR.Application.Models; using MTWorkHR.Core.Global; using MTWorkHR.Core.IRepositories; using MTWorkHR.Core.UnitOfWork; using MTWorkHR.Infrastructure.Entities; using MTWorkHR.Application.Services.Interfaces; using MTWorkHR.Core.Email; using MTWorkHR.Core.Entities; using MTWorkHR.Infrastructure.UnitOfWorks; using MTWorkHR.Core.Entities.User; using System.Linq.Dynamic.Core; using Microsoft.AspNetCore.Http; namespace MTWorkHR.Application.Services { public class OrderRequestService : BaseService, IOrderRequestService { private readonly IUnitOfWork _unitOfWork; private readonly IMailSender _emailSender; private readonly ApplicationUserManager _userManager; private readonly GlobalInfo _globalInfo; private readonly IUserService _userService; public OrderRequestService(IUnitOfWork unitOfWork, IMailSender emailSender, ApplicationUserManager userManager, GlobalInfo globalInfo, IUserService userService) : base(unitOfWork) { _unitOfWork = unitOfWork; _emailSender = emailSender; _userManager = userManager; _globalInfo = globalInfo; _userService = userService; } public override async Task GetById(long id) { var entity = await _unitOfWork.OrderRequest.GetByIdWithAllChildren(id); var response = MapperObject.Mapper.Map(entity); response.Employee = await _userService.GetUserWithAttachmentById(entity.RequestingEmployeeId); return response; } public async Task> GetAll(OrderPagingInputDto PagingInputDto) { var res = await _unitOfWork.OrderRequest.GetAllWithChildrenAsync(); var query = res.Item1; if (_globalInfo.UserType != UserTypeEnum.Business) { query = query.Where(m => m.RequestingEmployeeId != null && m.RequestingEmployeeId == _globalInfo.UserId); } if (PagingInputDto.Filter != null) { var filter = PagingInputDto.Filter; query = query.Where(u => u.RequestComments!.Contains(filter) || u.OrderType.NameEn!.Contains(filter) || u.OrderType.NameAr!.Contains(filter) || u.LeaveType!.NameEn!.Contains(filter) || u.LeaveType!.NameAr!.Contains(filter)); } if (PagingInputDto.SearchDate != null) { query = query.Where(u => u.StartDate.Date <= PagingInputDto.SearchDate.Value.Date && u.EndDate!.Value.Date >= PagingInputDto.SearchDate.Value.Date) ; } if (PagingInputDto.OrderTypeId != null) { query = query.Where(u => u.OrderTypeId == PagingInputDto.OrderTypeId); } if (PagingInputDto.LeaveTypeId != null) { query = query.Where(u => u.LeaveTypeId == PagingInputDto.LeaveTypeId); } if (PagingInputDto.StatusId != null) { query = query.Where(u => (long?)u.OrderStatus == PagingInputDto.StatusId); } var order = query.OrderBy(PagingInputDto.OrderByField + " " + PagingInputDto.OrderType); var page = order.Skip((PagingInputDto.PageNumber * PagingInputDto.PageSize) - PagingInputDto.PageSize).Take(PagingInputDto.PageSize); var total = await query.CountAsync(); var list = MapperObject.Mapper .Map>(await page.ToListAsync()); foreach (var item in list) { if (item.RequestingEmployeeId != null) { var user = await _userService.GetUserWithAttachmentById(item.RequestingEmployeeId); if (user != null) { item.Employee = user; var attach = user.UserAttachments?.FirstOrDefault(a => a.AttachmentTypeId == 9); if(attach != null) using (var stream = new MemoryStream(attach.Content)) { var file = new FormFile(stream, 0, stream.Length, Path.GetFileNameWithoutExtension(attach.FileName), attach.FileName) { Headers = new HeaderDictionary(), ContentType = attach.ContentType, }; System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition { FileName = file.FileName }; file.ContentDisposition = cd.ToString(); item.Employee.ProfileImage = file; } } } } var response = new PagingResultDto { Result = list, Total = total }; return response; } public override async Task Create(OrderRequestDto input) { var period = DateTime.Now.Year; if(string.IsNullOrEmpty( input.RequestingEmployeeId)) { input.RequestingEmployeeId = _globalInfo.UserId; } var allocation = await _unitOfWork.OrderAllocation.GetUserAllocations(input.RequestingEmployeeId, input.OrderTypeId, input.LeaveTypeId, period); if (allocation is null) { throw new AppException(ExceptionEnum.NoVacationBalance, "You do not have any allocations for this leave type."); } else { int daysRequested = (int)(input.EndDate - input.StartDate).TotalDays; if (daysRequested > allocation.NumberOfDays) { throw new AppException(ExceptionEnum.NoVacationBalance, "You do not have enough days for this request"); } } var orderRequest = MapperObject.Mapper.Map(input); orderRequest = await _unitOfWork.OrderRequest.AddAsync(orderRequest); await _unitOfWork.CompleteAsync(); try { var requestingEmployee = await _userManager.Users.FirstOrDefaultAsync(x => x.Id == input.RequestingEmployeeId); var sendMailResult = await _emailSender.SendEmail(new EmailMessage { To = requestingEmployee.Email, Body = $"Your leave request for {input.StartDate:D} to {input.EndDate:D} " + $"has been submitted successfully.", Subject = "Leave Request Submitted", userId = input.RequestingEmployeeId }); if (!sendMailResult) { throw new AppException("User created, but could not send the email!"); } } catch (Exception ex) { //// Log or handle error, but don't throw... } var response = MapperObject.Mapper.Map(orderRequest); if (response.RequestingEmployeeId != null) { var user = await _userService.GetUserWithAttachmentById(response.RequestingEmployeeId); if (user != null) { response.Employee = user; var attach = user.UserAttachments?.FirstOrDefault(a => a.AttachmentTypeId == 9); if (attach != null) using (var stream = new MemoryStream(attach.Content)) { var file = new FormFile(stream, 0, stream.Length, Path.GetFileNameWithoutExtension(attach.FileName), attach.FileName) { Headers = new HeaderDictionary(), ContentType = attach.ContentType, }; System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition { FileName = file.FileName }; file.ContentDisposition = cd.ToString(); response.Employee.ProfileImage = file; } } } return response; } public async Task ChangeStatus(long id, int statusId ) { var orderRequest = await _unitOfWork.OrderRequest.GetByIdAsync(id); orderRequest.OrderStatus = (ApprovalStatusEnum)statusId; if (orderRequest.OrderStatus == ApprovalStatusEnum.Approved) { var allocation = await _unitOfWork.OrderAllocation.GetUserAllocations(orderRequest.RequestingEmployeeId, orderRequest.OrderTypeId, orderRequest.LeaveTypeId, DateTime.Now.Year); int daysRequested = !orderRequest.EndDate.HasValue ? 1 : (int)(orderRequest.EndDate.Value - orderRequest.StartDate).TotalDays; allocation.NumberOfDays -= daysRequested; } await _unitOfWork.CompleteAsync(); var response = MapperObject.Mapper.Map(orderRequest); return response; } } }