OrderRequestService.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. using Microsoft.AspNetCore.Identity;
  2. using Microsoft.AspNetCore.WebUtilities;
  3. using Microsoft.EntityFrameworkCore;
  4. using Microsoft.Extensions.Configuration;
  5. using MTWorkHR.Application.Identity;
  6. using MTWorkHR.Application.Mapper;
  7. using MTWorkHR.Application.Models;
  8. using MTWorkHR.Core.Global;
  9. using MTWorkHR.Core.IRepositories;
  10. using MTWorkHR.Core.UnitOfWork;
  11. using MTWorkHR.Infrastructure.Entities;
  12. using MTWorkHR.Application.Services.Interfaces;
  13. using MTWorkHR.Core.Email;
  14. using MTWorkHR.Core.Entities;
  15. using MTWorkHR.Infrastructure.UnitOfWorks;
  16. using System.Linq.Dynamic.Core;
  17. using Microsoft.AspNetCore.Http;
  18. using MTWorkHR.Core.Entities.User;
  19. using MTWorkHR.Core.Entities.Base;
  20. namespace MTWorkHR.Application.Services
  21. {
  22. public class OrderRequestService : BaseService<OrderRequest, OrderRequestDto, OrderRequestDto>, IOrderRequestService
  23. {
  24. private readonly IUnitOfWork _unitOfWork;
  25. private readonly IMailSender _emailSender;
  26. private readonly ApplicationUserManager _userManager;
  27. private readonly GlobalInfo _globalInfo;
  28. private readonly IUserService _userService;
  29. public OrderRequestService(IUnitOfWork unitOfWork, IMailSender emailSender, ApplicationUserManager userManager, GlobalInfo globalInfo, IUserService userService) : base(unitOfWork)
  30. {
  31. _unitOfWork = unitOfWork;
  32. _emailSender = emailSender;
  33. _userManager = userManager;
  34. _globalInfo = globalInfo;
  35. _userService = userService;
  36. }
  37. public override async Task<OrderRequestDto> GetById(long id)
  38. {
  39. var entity = await _unitOfWork.OrderRequest.GetByIdWithAllChildren(id);
  40. var response = MapperObject.Mapper.Map<OrderRequestDto>(entity);
  41. var user = await _userService.GetUserById(entity.RequestingEmployeeId);
  42. var image = await _userService.GetProfileImage(entity.RequestingEmployeeId);
  43. response.Employee = new EmployeeDto { Id = entity.RequestingEmployeeId, FirstName = user.FirstName, LastName = user.LastName, Email = user.Email, ProfileImagePath = image };
  44. return response;
  45. }
  46. public async Task<PagingResultDto<OrderRequestDto>> GetAll(OrderPagingInputDto PagingInputDto)
  47. {
  48. var res = await _unitOfWork.OrderRequest.GetAllWithChildrenAsync();
  49. var query = res.Item1;
  50. if (_globalInfo.UserType != UserTypeEnum.Business)
  51. {
  52. query = query.Where(m => m.RequestingEmployeeId != null && m.RequestingEmployeeId == _globalInfo.UserId);
  53. }
  54. if (PagingInputDto.Filter != null)
  55. {
  56. var filter = PagingInputDto.Filter;
  57. query = query.Where(u => u.RequestComments!.Contains(filter)
  58. || u.OrderType.NameEn!.Contains(filter)
  59. || u.OrderType.NameAr!.Contains(filter)
  60. || u.LeaveType!.NameEn!.Contains(filter)
  61. || u.LeaveType!.NameAr!.Contains(filter));
  62. }
  63. if (PagingInputDto.SearchDate != null)
  64. {
  65. query = query.Where(u => u.StartDate.Date <= PagingInputDto.SearchDate.Value.Date && u.EndDate!.Value.Date >= PagingInputDto.SearchDate.Value.Date) ;
  66. }
  67. if (PagingInputDto.OrderTypeId != null)
  68. {
  69. query = query.Where(u => u.OrderTypeId == PagingInputDto.OrderTypeId);
  70. }
  71. if (PagingInputDto.LeaveTypeId != null)
  72. {
  73. query = query.Where(u => u.LeaveTypeId == PagingInputDto.LeaveTypeId);
  74. }
  75. if (PagingInputDto.StatusId != null)
  76. {
  77. query = query.Where(u => (long?)u.OrderStatus == PagingInputDto.StatusId);
  78. }
  79. var order = query.OrderBy(PagingInputDto.OrderByField + " " + PagingInputDto.OrderType);
  80. var page = order.Skip((PagingInputDto.PageNumber * PagingInputDto.PageSize) - PagingInputDto.PageSize).Take(PagingInputDto.PageSize);
  81. var total = await query.CountAsync();
  82. var list = MapperObject.Mapper
  83. .Map<IList<OrderRequestDto>>(await page.ToListAsync());
  84. foreach (var item in list)
  85. {
  86. if (item.RequestingEmployeeId != null)
  87. {
  88. var user = await _userService.GetUserWithAttachmentById(item.RequestingEmployeeId);
  89. if (user != null)
  90. {
  91. item.Employee = new EmployeeDto { Id = item.RequestingEmployeeId, FirstName = user.FirstName, LastName = user.LastName, Email = user.Email };
  92. var attach = user.UserAttachments?.FirstOrDefault(a => a.AttachmentTypeId == 9);
  93. item.Employee.ProfileImagePath = attach?.FilePath;
  94. // if (attach != null)
  95. //using (var stream = new MemoryStream(attach.Content))
  96. //{
  97. // var file = new FormFile(stream, 0, stream.Length, Path.GetFileNameWithoutExtension(attach.FileName), attach.FileName)
  98. // {
  99. // Headers = new HeaderDictionary(),
  100. // ContentType = attach.ContentType,
  101. // };
  102. // System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
  103. // {
  104. // FileName = file.FileName
  105. // };
  106. // file.ContentDisposition = cd.ToString();
  107. //}
  108. }
  109. }
  110. }
  111. var response = new PagingResultDto<OrderRequestDto>
  112. {
  113. Result = list,
  114. Total = total
  115. };
  116. return response;
  117. }
  118. public override async Task<OrderRequestDto> Create(OrderRequestDto input)
  119. {
  120. var period = DateTime.Now.Year;
  121. if(string.IsNullOrEmpty( input.RequestingEmployeeId))
  122. {
  123. input.RequestingEmployeeId = _globalInfo.UserId;
  124. }
  125. if (input is BusinessTripDto)
  126. {
  127. input.OrderTypeId = 3;
  128. input.LeaveTypeId = null;
  129. }
  130. else if (input is OverTimeDto)
  131. {
  132. input.OrderTypeId = 2;
  133. input.LeaveTypeId = null;
  134. }
  135. var contract = await _unitOfWork.Contract.GetLatestActiveContract(input.RequestingEmployeeId);
  136. if(contract!= null)
  137. input.ContractId = contract.Id;
  138. if (input.OrderTypeId == 1 && input.LeaveTypeId == 1) // Annual vacation in contract
  139. {
  140. if (contract != null)
  141. {
  142. var allocation = await _unitOfWork.OrderAllocation.GetUserAllocations(input.RequestingEmployeeId, input.OrderTypeId, input.LeaveTypeId, contract.Id, period);
  143. if (allocation is null)
  144. {
  145. throw new AppException(ExceptionEnum.NoVacationBalance, "You do not have any allocations for this leave type.");
  146. }
  147. else
  148. {
  149. int daysRequested = (int)(input.EndDate - input.StartDate).TotalDays;
  150. if (daysRequested > allocation.NumberOfDays)
  151. {
  152. throw new AppException(ExceptionEnum.NoVacationBalance, "You do not have enough days for this request");
  153. }
  154. }
  155. }
  156. }
  157. var orderRequest = MapperObject.Mapper.Map<OrderRequest>(input);
  158. orderRequest = await _unitOfWork.OrderRequest.AddAsync(orderRequest);
  159. await _unitOfWork.CompleteAsync();
  160. try
  161. {
  162. var requestingEmployee = await _userManager.Users.FirstOrDefaultAsync(x => x.Id == input.RequestingEmployeeId);
  163. var sendMailResult = await _emailSender.SendEmail(new EmailMessage
  164. {
  165. To = requestingEmployee.Email,
  166. Body = $"Your leave request for {input.StartDate:D} to {input.EndDate:D} " +
  167. $"has been submitted successfully.",
  168. Subject = "Leave Request Submitted",
  169. userId = input.RequestingEmployeeId
  170. });
  171. if (!sendMailResult)
  172. {
  173. throw new AppException("User created, but could not send the email!");
  174. }
  175. }
  176. catch (Exception ex)
  177. {
  178. //// Log or handle error, but don't throw...
  179. }
  180. var response = MapperObject.Mapper.Map<OrderRequestDto>(orderRequest);
  181. if (response.RequestingEmployeeId != null)
  182. {
  183. var user = await _userService.GetUserWithAttachmentById(response.RequestingEmployeeId);
  184. if (user != null)
  185. {
  186. response.Employee = new EmployeeDto { Id = response.RequestingEmployeeId, FirstName = user.FirstName, LastName = user.LastName, Email = user.Email };
  187. var attach = user.UserAttachments?.FirstOrDefault(a => a.AttachmentTypeId == 9);
  188. response.Employee.ProfileImagePath = attach?.FilePath;
  189. //if (attach != null)
  190. // using (var stream = new MemoryStream(attach?.Content))
  191. // {
  192. // var file = new FormFile(stream, 0, stream.Length, Path.GetFileNameWithoutExtension(attach.FileName), attach.FileName)
  193. // {
  194. // Headers = new HeaderDictionary(),
  195. // ContentType = attach?.ContentType,
  196. // };
  197. // System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
  198. // {
  199. // FileName = file.FileName
  200. // };
  201. // file.ContentDisposition = cd.ToString();
  202. // response.Employee.ProfileImage = file;
  203. // }
  204. }
  205. }
  206. return response;
  207. }
  208. public async Task<OrderRequestDto> ChangeStatus(long id, int statusId )
  209. {
  210. var orderRequest = await _unitOfWork.OrderRequest.GetByIdAsync(id);
  211. orderRequest.OrderStatus = (ApprovalStatusEnum)statusId;
  212. if (orderRequest.OrderStatus == ApprovalStatusEnum.Approved)
  213. {
  214. var contract = await _unitOfWork.Contract.GetLatestActiveContract(orderRequest.RequestingEmployeeId);
  215. var allocation = await _unitOfWork.OrderAllocation.GetUserAllocations(orderRequest.RequestingEmployeeId, orderRequest.OrderTypeId, orderRequest.LeaveTypeId, contract.Id, DateTime.Now.Year);
  216. if (allocation != null)
  217. {
  218. int daysRequested = !orderRequest.EndDate.HasValue ? 1 : (int)(orderRequest.EndDate.Value - orderRequest.StartDate).TotalDays;
  219. allocation.NumberOfDays -= daysRequested;
  220. }
  221. }
  222. await _unitOfWork.CompleteAsync();
  223. var response = MapperObject.Mapper.Map<OrderRequestDto>(orderRequest);
  224. return response;
  225. }
  226. }
  227. }