Preview:
//Suggested changes
1. Create Separate ViewModels: Define different ViewModels for each user type (Member, Employee, Owner) with the specific fields required for each.

2. Determine User Type First: Create a step in your registration process to first capture the user type.

3. Use Specific ViewModel Based on User Type: Use the captured user type to select and validate the appropriate ViewModel.

//Viewmodels
public class UserViewModel
{
    public string Email { get; set; }
    public string Password { get; set; }
    public int User_Type_ID { get; set; }
    // Common fields...
}

public class MemberViewModel : UserViewModel
{
    public int Contract_ID { get; set; }
    public bool Is_Active { get; set; }
    // Other member-specific fields...
}

public class EmployeeViewModel : UserViewModel
{
    public int Employee_Type_ID { get; set; }
    public int Shift_ID { get; set; }
    public int Hours_Worked { get; set; }
    // Other employee-specific fields...
}

public class OwnerViewModel : UserViewModel
{
    // Owner-specific fields...
}

//UserTypeVM
public class UserTypeVM
{
    public int User_Type_ID { get; set; }
}


//Controller
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Identity;
using System.Text.RegularExpressions;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;

[Route("api/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
    private readonly UserManager<User> _userManager;
    private readonly AppDbContext _appDbContext;
    private readonly ILogger<UserController> _logger;

    public UserController(UserManager<User> userManager, AppDbContext appDbContext, ILogger<UserController> logger)
    {
        _userManager = userManager;
        _appDbContext = appDbContext;
        _logger = logger;
    }

    [HttpPost]
    [Route("DetermineUserType")]
    public async Task<IActionResult> DetermineUserType([FromForm] UserTypeViewModel userTypeViewModel)
    {
        if (userTypeViewModel == null || userTypeViewModel.User_Type_ID <= 0)
        {
            return BadRequest("Invalid user type.");
        }

        // Determine user type based on the provided information
        int userTypeID = userTypeViewModel.User_Type_ID;

        // Redirect to the appropriate registration method
        switch (userTypeID)
        {
            case 1:
                return await RegisterMember(userTypeViewModel);
            case 2:
                return await RegisterEmployee(userTypeViewModel);
            case 3:
                return await RegisterOwner(userTypeViewModel);
            default:
                return BadRequest("Invalid user type.");
        }
    }

    private async Task<IActionResult> RegisterMember(UserTypeViewModel userTypeViewModel)
    {
        // Map UserTypeViewModel to MemberViewModel
        var memberViewModel = new MemberViewModel
        {
            Email = userTypeViewModel.Email,
            Password = userTypeViewModel.Password,
            User_Type_ID = userTypeViewModel.User_Type_ID,
            // Initialize other member-specific fields
        };

        return await Register(memberViewModel);
    }

    private async Task<IActionResult> RegisterEmployee(UserTypeViewModel userTypeViewModel)
    {
        // Map UserTypeViewModel to EmployeeViewModel
        var employeeViewModel = new EmployeeViewModel
        {
            Email = userTypeViewModel.Email,
            Password = userTypeViewModel.Password,
            User_Type_ID = userTypeViewModel.User_Type_ID,
            // Initialize other employee-specific fields
        };

        return await Register(employeeViewModel);
    }

    private async Task<IActionResult> RegisterOwner(UserTypeViewModel userTypeViewModel)
    {
        // Map UserTypeViewModel to OwnerViewModel
        var ownerViewModel = new OwnerViewModel
        {
            Email = userTypeViewModel.Email,
            Password = userTypeViewModel.Password,
            User_Type_ID = userTypeViewModel.User_Type_ID,
            // Initialize other owner-specific fields
        };

        return await Register(ownerViewModel);
    }

    private async Task<IActionResult> Register(UserViewModel uvm)
    {
        try
        {
            var formCollection = await Request.ReadFormAsync();
            var photo = formCollection.Files.FirstOrDefault();

            // Validate Phone Number Pattern
            var phoneNumberPattern = @"^\d{10}$";
            bool isValidPhoneNumber = Regex.IsMatch(uvm.PhoneNumber, phoneNumberPattern);

            if (!isValidPhoneNumber) return BadRequest("Enter valid 10-digit phone number.");

            // Validate South African ID number
            if (!IsValidSouthAfricanIDNumber(uvm.Id_Number, uvm.Date_of_Birth))
            {
                return BadRequest("Enter a valid South African ID number.");
            }

            var user = await _userManager.FindByEmailAsync(uvm.Email);
            int lastUserID = _appDbContext.Users
                                .OrderByDescending(u => u.User_ID)
                                .Select(u => u.User_ID)
                                .FirstOrDefault();

            if (user == null)
            {
                if (photo != null && photo.Length > 0)
                {
                    using (var memoryStream = new MemoryStream())
                    {
                        await photo.CopyToAsync(memoryStream);
                        var fileBytes = memoryStream.ToArray();
                        string base64Image = Convert.ToBase64String(fileBytes);

                        user = new User
                        {
                            User_ID = lastUserID + 1,
                            Name = uvm.Name,
                            Surname = uvm.Surname,
                            UserName = uvm.Email,
                            Email = uvm.Email,
                            PasswordHash = _userManager.PasswordHasher.HashPassword(null, uvm.Password),
                            User_Status_ID = uvm.User_Status_ID,
                            User_Type_ID = uvm.User_Type_ID,
                            PhoneNumber = uvm.PhoneNumber,
                            Date_of_Birth = uvm.Date_of_Birth,
                            ID_Number = uvm.Id_Number,
                            Physical_Address = uvm.Physical_Address,
                            Photo = base64Image // Store the base64 string of the photo
                        };

                        IdentityResult result = await _userManager.CreateAsync(user);

                        if (result.Succeeded)
                        {
                            // Assign role based on User_Type_ID
                            string roleName = GetRoleNameByUserType(uvm.User_Type_ID);
                            if (!string.IsNullOrEmpty(roleName))
                            {
                                var roleResult = await _userManager.AddToRoleAsync(user, roleName);
                                if (!roleResult.Succeeded)
                                {
                                    return BadRequest(new { Status = "Error", Errors = roleResult.Errors });
                                }
                            }

                            if (uvm.User_Type_ID == 1) // Member
                            {
                                var memberViewModel = uvm as MemberViewModel;
                                int lastMemberID = _appDbContext.Members
                                    .OrderByDescending(m => m.Member_ID)
                                    .Select(m => m.Member_ID)
                                    .FirstOrDefault();

                                var newMember = new Member
                                {
                                    Member_ID = lastMemberID + 1,
                                    User_ID = user.User_ID,
                                    Contract_ID = memberViewModel.Contract_ID,
                                    Is_Active = memberViewModel.Is_Active // Use the value from the view model
                                };

                                _appDbContext.Members.Add(newMember);
                                _logger.LogInformation("Adding new member with User_ID: {User_ID}, Member_ID: {Member_ID}", user.User_ID, newMember.Member_ID);
                                await _appDbContext.SaveChangesAsync();
                                _logger.LogInformation("Member added successfully with User_ID: {User_ID}, Member_ID: {Member_ID}", user.User_ID, newMember.Member_ID);
                            }
                            else if (uvm.User_Type_ID == 2) // Employee
                            {
                                var employeeViewModel = uvm as EmployeeViewModel;
                                int lastEmployeeID = _appDbContext.Employees
                                    .OrderByDescending(e => e.Employee_ID)
                                    .Select(e => e.Employee_ID)
                                    .FirstOrDefault();

                                var newEmployee = new Employee
                                {
                                    Employee_ID = lastEmployeeID == 0 ? 1 : lastEmployeeID + 1,
                                    User_ID = user.User_ID,
                                    Employment_Date = DateTime.UtcNow,
                                    Hours_Worked = employeeViewModel.Hours_Worked, // Use the value from the view model (initialized to zero)
                                    Employee_Type_ID = employeeViewModel.Employee_Type_ID,
                                    Shift_ID = employeeViewModel.Shift_ID
                                };

                                _appDbContext.Employees.Add(newEmployee);
                                _logger.LogInformation("Adding new employee with User_ID: {User_ID}, Employee_ID: {Employee_ID}", user.User_ID, newEmployee.Employee_ID);
                                await _appDbContext.SaveChangesAsync();
                                _logger.LogInformation("Employee added successfully with User_ID: {User_ID}, Employee_ID: {Employee_ID}", user.User_ID, newEmployee.Employee_ID);
                            }
                            else if (uvm.User_Type_ID == 3) // Owner
                            {
                                var ownerViewModel = uvm as OwnerViewModel;
                                int lastOwnerID = _appDbContext.Owners
                                    .OrderByDescending(o => o.Owner_ID)
                                    .Select(o => o.Owner_ID)
                                    .FirstOrDefault();

                                var newOwner = new Owner
                                {
                                    Owner_ID = lastOwnerID == 0 ? 1 : lastOwnerID + 1,
                                    User_ID = user.User_ID
                                };

                                _appDbContext.Owners.Add(newOwner);
                                _logger.LogInformation("Adding new owner with User_ID: {User_ID}, Owner_ID: {Owner_ID}", user.User_ID, newOwner.Owner_ID);
                                await _appDbContext.SaveChangesAsync();
                                _logger.LogInformation("Owner added successfully with User_ID: {User_ID}, Owner_ID: {Owner_ID}", user.User_ID, newOwner.Owner_ID);
                            }

                            return Ok(new { Status = "Success", Message = "Your profile has been created successfully!" });
                        }
                        else
                        {
                            return StatusCode(StatusCodes.Status500InternalServerError, result.Errors.FirstOrDefault()?.Description);
                        }
                    }
                }
                else
                {
                    return BadRequest("Photo is required.");
                }
            }
            else
            {
                return Forbid("User already exists.");
            }
        }
        catch (DbUpdateException dbEx)
        {
            return StatusCode(StatusCodes.Status500InternalServerError, dbEx.InnerException?.Message ?? "An error occurred while processing your request.");
        }
        catch (Exception ex)
        {
            return StatusCode(StatusCodes.Status500InternalServerError, "An error occurred while processing your request.");
        }
    }

    private bool IsValidSouthAfricanIDNumber(string idNumber, DateTime dateOfBirth)
    {
        // Implement South African ID number validation logic here
        return true;
    }

    private string GetRoleNameByUserType(int userTypeID)
    {
        // Implement logic to get role name by user type ID
        return "RoleName";
    }
}
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter