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 Azure; using System.Security.Claims; using MTWorkHR.Core.Entities.Base; namespace MTWorkHR.Application.Services { public class OrderRequestService : BaseService, IOrderRequestService { private readonly IUnitOfWork _unitOfWork; private readonly IMailSender _emailSender; private readonly ApplicationUserManager _userManager; public OrderRequestService(IUnitOfWork unitOfWork, IMailSender emailSender, ApplicationUserManager userManager) : base(unitOfWork) { _unitOfWork = unitOfWork; _emailSender = emailSender; _userManager = userManager; } public override async Task GetById(long id) { var entity = await _unitOfWork.OrderRequest.GetByIdWithAllChildren(id); var response = MapperObject.Mapper.Map(entity); return response; } public override async Task Create(OrderRequestDto input) { var period = DateTime.Now.Year; var allocation = await _unitOfWork.OrderAllocation.GetUserAllocations(input.RequestingEmployeeId, input.OrderTypeId, input.LeaveTypeId, period); if (allocation is null) { throw new AppException(ExceptionEnum.RecordNotExist, "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.RecordNotExist, "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); 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; } } }