OrderRequestService.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  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. if(entity == null)
  41. {
  42. throw new AppException(ExceptionEnum.RecordNotExist);
  43. }
  44. var response = MapperObject.Mapper.Map<OrderRequestDto>(entity);
  45. response.Employee = await GetEmployeeDto(entity.RequestingEmployeeId);
  46. return response;
  47. }
  48. public async Task<OverTimeDto> GetOverTime(long id)
  49. {
  50. var entity = await _unitOfWork.OrderRequest.GetByIdWithAllChildren(id);
  51. if (entity == null)
  52. {
  53. throw new AppException(ExceptionEnum.RecordNotExist);
  54. }
  55. var response = MapperObject.Mapper.Map<OverTimeDto>(entity);
  56. response.Employee = await GetEmployeeDto(entity.RequestingEmployeeId);
  57. return response;
  58. }
  59. public async Task<BusinessTripDto> GetBusinessTrip(long id)
  60. {
  61. var entity = await _unitOfWork.OrderRequest.GetByIdWithAllChildren(id);
  62. if (entity == null)
  63. {
  64. throw new AppException(ExceptionEnum.RecordNotExist);
  65. }
  66. var response = MapperObject.Mapper.Map<BusinessTripDto>(entity);
  67. response.Employee = await GetEmployeeDto(entity.RequestingEmployeeId);
  68. return response;
  69. }
  70. public async Task<ServiceCertificateRequestDto> GetServiceCertificate(long id)
  71. {
  72. var entity = await _unitOfWork.OrderRequest.GetByIdWithAllChildren(id);
  73. if (entity == null)
  74. {
  75. throw new AppException(ExceptionEnum.RecordNotExist);
  76. }
  77. var response = MapperObject.Mapper.Map<ServiceCertificateRequestDto>(entity);
  78. response.Employee = await GetEmployeeDto(entity.RequestingEmployeeId);
  79. return response;
  80. }
  81. private async Task<EmployeeDto> GetEmployeeDto(string employeeId)
  82. {
  83. var user = await _userService.GetUserById(employeeId);
  84. var image = await _userService.GetProfileImage(employeeId);
  85. return new EmployeeDto
  86. {
  87. Id = employeeId,
  88. FirstName = user.FirstName,
  89. LastName = user.LastName,
  90. Email = user.Email,
  91. ProfileImagePath = image
  92. };
  93. }
  94. public async Task<PagingResultDto<OrderRequestDto>> GetAll(OrderPagingInputDto PagingInputDto)
  95. {
  96. var res = await _unitOfWork.OrderRequest.GetAllWithChildrenAsync();
  97. var query = res.Item1;
  98. if (_globalInfo.UserType != UserTypeEnum.Business)
  99. {
  100. query = query.Where(m => m.RequestingEmployeeId != null && m.RequestingEmployeeId == _globalInfo.UserId);
  101. }
  102. if (PagingInputDto.Filter != null)
  103. {
  104. var filter = PagingInputDto.Filter;
  105. query = query.Where(u => u.RequestComments!.Contains(filter)
  106. || u.OrderType.NameEn!.Contains(filter)
  107. || u.OrderType.NameAr!.Contains(filter)
  108. || u.LeaveType!.NameEn!.Contains(filter)
  109. || u.LeaveType!.NameAr!.Contains(filter));
  110. }
  111. if (PagingInputDto.SearchDate != null)
  112. {
  113. query = query.Where(u => u.StartDate.Date <= PagingInputDto.SearchDate.Value.Date && u.EndDate!.Value.Date >= PagingInputDto.SearchDate.Value.Date) ;
  114. }
  115. if (PagingInputDto.OrderTypeId != null)
  116. {
  117. query = query.Where(u => u.OrderTypeId == PagingInputDto.OrderTypeId);
  118. }
  119. if (PagingInputDto.LeaveTypeId != null)
  120. {
  121. query = query.Where(u => u.LeaveTypeId == PagingInputDto.LeaveTypeId);
  122. }
  123. if (PagingInputDto.StatusId != null)
  124. {
  125. query = query.Where(u => (long?)u.OrderStatus == PagingInputDto.StatusId);
  126. }
  127. var order = query.OrderBy(PagingInputDto.OrderByField + " " + PagingInputDto.OrderType);
  128. var page = order.Skip((PagingInputDto.PageNumber * PagingInputDto.PageSize) - PagingInputDto.PageSize).Take(PagingInputDto.PageSize);
  129. var total = await query.CountAsync();
  130. var list = MapperObject.Mapper
  131. .Map<IList<OrderRequestDto>>(await page.ToListAsync());
  132. foreach (var item in list)
  133. {
  134. if (item.RequestingEmployeeId != null)
  135. {
  136. var user = await _userService.GetUserWithAttachmentById(item.RequestingEmployeeId);
  137. if (user != null)
  138. {
  139. item.Employee = new EmployeeDto { Id = item.RequestingEmployeeId, FirstName = user.FirstName, LastName = user.LastName, Email = user.Email };
  140. var attach = user.UserAttachments?.FirstOrDefault(a => a.AttachmentTypeId == 9);
  141. item.Employee.ProfileImagePath = attach?.FilePath;
  142. // if (attach != null)
  143. //using (var stream = new MemoryStream(attach.Content))
  144. //{
  145. // var file = new FormFile(stream, 0, stream.Length, Path.GetFileNameWithoutExtension(attach.FileName), attach.FileName)
  146. // {
  147. // Headers = new HeaderDictionary(),
  148. // ContentType = attach.ContentType,
  149. // };
  150. // System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
  151. // {
  152. // FileName = file.FileName
  153. // };
  154. // file.ContentDisposition = cd.ToString();
  155. //}
  156. }
  157. }
  158. }
  159. var response = new PagingResultDto<OrderRequestDto>
  160. {
  161. Result = list,
  162. Total = total
  163. };
  164. return response;
  165. }
  166. public override async Task<OrderRequestDto> Create(OrderRequestDto input)
  167. {
  168. var period = DateTime.Now.Year;
  169. input.LeaveTypeId = (input.LeaveTypeId != null && input.LeaveTypeId > 0 ) ? input.LeaveTypeId : null;
  170. input.OrderStatus = (input.OrderStatus != null && input.OrderStatus > 0 ) ? input.OrderStatus : ApprovalStatusEnum.Pending;
  171. if (string.IsNullOrEmpty( input.RequestingEmployeeId))
  172. {
  173. input.RequestingEmployeeId = _globalInfo.UserId;
  174. }
  175. if (input is BusinessTripDto)
  176. {
  177. input.OrderTypeId = 3;
  178. }
  179. else if (input is OverTimeDto)
  180. {
  181. input.OrderTypeId = 2;
  182. }
  183. else if (input is ServiceCertificateRequestDto)
  184. {
  185. input.OrderTypeId = 5;
  186. }
  187. var contract = await _unitOfWork.Contract.GetLatestActiveContract(input.RequestingEmployeeId);
  188. if(contract!= null)
  189. input.ContractId = contract.Id;
  190. if (input.OrderTypeId == 1 && input.LeaveTypeId == 1) // Annual vacation in contract
  191. {
  192. if (contract != null)
  193. {
  194. var allocation = await _unitOfWork.OrderAllocation.GetUserAllocations(input.RequestingEmployeeId, input.OrderTypeId, input.LeaveTypeId, contract.Id, period);
  195. if (allocation is null)
  196. {
  197. throw new AppException(ExceptionEnum.NoVacationBalance, "You do not have any allocations for this leave type.");
  198. }
  199. else
  200. {
  201. int daysRequested = (int)(input.EndDate - input.StartDate).TotalDays;
  202. if (daysRequested > allocation.NumberOfDays)
  203. {
  204. throw new AppException(ExceptionEnum.NoVacationBalance, "You do not have enough days for this request");
  205. }
  206. }
  207. }
  208. }
  209. var orderRequest = MapperObject.Mapper.Map<OrderRequest>(input);
  210. orderRequest = await _unitOfWork.OrderRequest.AddAsync(orderRequest);
  211. await _unitOfWork.CompleteAsync();
  212. try
  213. {
  214. var requestingEmployee = await _userManager.Users.FirstOrDefaultAsync(x => x.Id == input.RequestingEmployeeId);
  215. var sendMailResult = await _emailSender.SendEmail(new EmailMessage
  216. {
  217. To = requestingEmployee.Email,
  218. Body = $"Your leave request for {input.StartDate:D} to {input.EndDate:D} " +
  219. $"has been submitted successfully.",
  220. Subject = "Leave Request Submitted",
  221. userId = input.RequestingEmployeeId
  222. });
  223. if (!sendMailResult)
  224. {
  225. throw new AppException("User created, but could not send the email!");
  226. }
  227. }
  228. catch (Exception ex)
  229. {
  230. //// Log or handle error, but don't throw...
  231. }
  232. var res = await _unitOfWork.OrderRequest.GetByIdWithTypes(orderRequest.Id);
  233. var response = MapperObject.Mapper.Map<OrderRequestDto>(res);
  234. if (response.RequestingEmployeeId != null)
  235. {
  236. var user = await _userService.GetUserWithAttachmentById(response.RequestingEmployeeId);
  237. if (user != null)
  238. {
  239. response.Employee = new EmployeeDto { Id = response.RequestingEmployeeId, FirstName = user.FirstName, LastName = user.LastName, Email = user.Email };
  240. var attach = user.UserAttachments?.FirstOrDefault(a => a.AttachmentTypeId == 9);
  241. response.Employee.ProfileImagePath = attach?.FilePath;
  242. //if (attach != null)
  243. // using (var stream = new MemoryStream(attach?.Content))
  244. // {
  245. // var file = new FormFile(stream, 0, stream.Length, Path.GetFileNameWithoutExtension(attach.FileName), attach.FileName)
  246. // {
  247. // Headers = new HeaderDictionary(),
  248. // ContentType = attach?.ContentType,
  249. // };
  250. // System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
  251. // {
  252. // FileName = file.FileName
  253. // };
  254. // file.ContentDisposition = cd.ToString();
  255. // response.Employee.ProfileImage = file;
  256. // }
  257. }
  258. }
  259. return response;
  260. }
  261. public async Task<OrderRequestDto> ChangeStatus(long id, int statusId )
  262. {
  263. var orderRequest = await _unitOfWork.OrderRequest.GetByIdAsync(id);
  264. if (orderRequest == null)
  265. {
  266. throw new AppException(ExceptionEnum.RecordNotExist);
  267. }
  268. orderRequest.OrderStatus = (ApprovalStatusEnum)statusId;
  269. if (orderRequest.OrderStatus == ApprovalStatusEnum.Approved)
  270. {
  271. long? contractId = orderRequest.ContractId;
  272. if (contractId == null || contractId == 0)
  273. {
  274. var contract = await _unitOfWork.Contract.GetLatestActiveContract(orderRequest.RequestingEmployeeId);
  275. contractId = contract.Id;
  276. }
  277. var allocation = await _unitOfWork.OrderAllocation.GetUserAllocations(orderRequest.RequestingEmployeeId, orderRequest.OrderTypeId, orderRequest.LeaveTypeId, contractId.Value, DateTime.Now.Year);
  278. if (allocation != null)
  279. {
  280. int daysRequested = !orderRequest.EndDate.HasValue ? 1 : (int)(orderRequest.EndDate.Value - orderRequest.StartDate).TotalDays;
  281. allocation.NumberOfDays -= daysRequested;
  282. }
  283. }
  284. await _unitOfWork.CompleteAsync();
  285. var response = MapperObject.Mapper.Map<OrderRequestDto>(orderRequest);
  286. return response;
  287. }
  288. }
  289. }