public async Task <IActionResult> Hire(EmployeeHireViewModel model) { if (string.IsNullOrWhiteSpace(model.PIN)) { return(BadRequest(new { Message = string.Format(StringBlankErrorMessage, model.GetPropertyDisplayName(nameof(model.PIN))) })); } if (employeeService.FindByPin(model.PIN) != null) { return(BadRequest(new { Message = string.Format(ObjectExistsErrorMessage, "A record with the same identification number") })); } if (string.IsNullOrWhiteSpace(model.FirstName) || string.IsNullOrWhiteSpace(model.MiddleName) || string.IsNullOrWhiteSpace(model.LastName)) { return(BadRequest(new { Message = string.Format(StringBlankErrorMessage, "A name") })); } if (string.IsNullOrWhiteSpace(model.DepartmentName)) { return(BadRequest(new { Message = string.Format(SelectionNullErrorMessage, "a department") })); } if (string.IsNullOrWhiteSpace(model.ManagerId)) { return(BadRequest(new { Message = string.Format(SelectionNullErrorMessage, "a manager") })); } if (string.IsNullOrWhiteSpace(model.RoleName)) { return(BadRequest(new { Message = string.Format(SelectionNullErrorMessage, "a role") })); } if (model.MonthlySalaryInEUR <= 0) { return(BadRequest(new { Message = string.Format(InvalidObjectErrorMessage, "Salary") })); } string dateHiredDisplayName = model.GetPropertyDisplayName(nameof(model.DateHired)); if (model.DateHired.Date < DateTimeOffset.Now.Date) { return(BadRequest(new { Message = string.Format(DateInPastErrorMessage, dateHiredDisplayName) })); } if (model.IsTemporary && model.DateRelieved.Value.Date <= model.DateHired.Date) { string dateRelievedDisplayName = model.GetPropertyDisplayName(nameof(model.DateRelieved)); return(BadRequest(new { Message = $"{dateRelievedDisplayName} must be after {dateHiredDisplayName.ToLower()}!" })); } string portraitMimeType = string.Empty; if (model.Portrait != null) { string propertyDisplayName = model.GetPropertyDisplayName(nameof(model.Portrait)); portraitMimeType = await fileService.GetMimeTypeAsync(model.Portrait); if (string.IsNullOrWhiteSpace(portraitMimeType)) { return(BadRequest(new { Message = $"{propertyDisplayName} is corrupted." })); } if (!portraitMimeType.StartsWith(ImageMimeTypePrefix)) { return(BadRequest(new { Message = $"{propertyDisplayName} must be an image file!" })); } } var employee = mapper.Map <Employee>(model); employee.Manager = await employeeService.FindByIdAsync(model.ManagerId); var role = await roleService.FindByNameAsync(model.RoleName); employee.Position = role; if (!string.IsNullOrWhiteSpace(model.ProfileId)) { var profile = await profileService.FindByIdAsync(model.ProfileId); if (profile.Employee != null) { return(BadRequest(new { Message = $"Profile '{profile.UserName}' is already in use by another employee." })); } employee.Profile = profile; if (!employee.Profile.Claims.Any(c => c.ClaimType == TypeKey)) { var typeClaim = new Claim(TypeKey, nameof(Employee)); await profileService.AddClaimAsync(employee.Profile, typeClaim); } if (!employee.Profile.Claims.Any(c => c.ClaimType == DepartmentKey)) { var departmentClaim = new Claim(DepartmentKey, employee.Department.ToString()); await profileService.AddClaimAsync(employee.Profile, departmentClaim); } var roleAssignTask = await profileService.AddToRoleAsync(employee.Profile, model.RoleName); if (!roleAssignTask.Succeeded) { return(BadRequest(new { Message = string.Join(HtmlNewLine, roleAssignTask.Errors.Select(e => e.Description)) })); } if (!employee.Profile.Claims.Any(c => c.ClaimValue == model.RoleName)) { var roleClaim = new Claim(RoleKey, model.RoleName); await profileService.AddClaimAsync(employee.Profile, roleClaim); } employee.Profile.DateDeleted = employee.DateRelieved; } try { await employeeService.HireAsync(employee); if (!string.IsNullOrWhiteSpace(portraitMimeType)) { string portraitFileType = portraitMimeType.Replace(ImageMimeTypePrefix, string.Empty); string portraitFileName = $"portrait.{portraitFileType}"; string profileDirectoryName = employee.PIN.ToBase64(); string portraitFilePath = fileService.BuildPath(new string[] { PersonnelDataRoot, profileDirectoryName, portraitFileName }, trimmed: true); await fileService.SaveFileAsync(model.Portrait, portraitFilePath); } logger.LogInformation($"'{User.Identity.Name}' hired a new employee - {employee.ToString()}."); await employeeService.UpdateLastWorkedAsync(User.GetId()); return(Json(new { Message = $"{employee.ToString()} hired." })); } catch (Exception exception) { logger.LogError(exception.GetMessageStack()); return(BadRequest(new { Message = exception.GetMessageStack(HtmlNewLine) })); } }