diff --git a/Controllers/API/AdminAPI.cs b/Controllers/API/AdminAPI.cs index a328047..cf48d8c 100644 --- a/Controllers/API/AdminAPI.cs +++ b/Controllers/API/AdminAPI.cs @@ -8,6 +8,7 @@ using static System.Runtime.InteropServices.JavaScript.JSType; using System.Security.Cryptography; using System.Text; using System.Text.Json; +using System.ComponentModel.DataAnnotations; namespace PSTW_CentralSystem.Controllers.API { @@ -17,14 +18,14 @@ namespace PSTW_CentralSystem.Controllers.API public class AdminAPI : Controller { private readonly ILogger _logger; - private readonly IdentityDBContext _authDbContext; + private readonly IdentityDBContext _identityDbContext; private readonly UserManager _userManager; private readonly SignInManager _signInManager; public AdminAPI(ILogger logger, IdentityDBContext authDbContext, UserManager userManager, SignInManager signInManager) { _logger = logger; - _authDbContext = authDbContext; + _identityDbContext = authDbContext; _userManager = userManager; _signInManager = signInManager; } @@ -96,7 +97,7 @@ namespace PSTW_CentralSystem.Controllers.API List userInfo = new List(); // Fetch all users excluding those with roles SuperAdmin or SystemAdmin - var allUsers = await _authDbContext.Users + var allUsers = await _identityDbContext.Users .Include(u => u.Department) .ToListAsync(); @@ -113,7 +114,7 @@ namespace PSTW_CentralSystem.Controllers.API } else { - userInfo = await _authDbContext.Users.Include(u => u.Department).ToListAsync(); + userInfo = await _identityDbContext.Users.Include(u => u.Department).ToListAsync(); } var userList = userInfo.Select(u => new { @@ -130,5 +131,95 @@ namespace PSTW_CentralSystem.Controllers.API return StatusCode(500, $"An error occurred: {ex.Message}"); } } + + [HttpPost("GetDepartmentWithCompanyList")] + public async Task GetDepartmentWithCompanyList() + { + var companyList = await _identityDbContext.Companies + .Include(c => c.Departments) + .Select(c => new { + c.CompanyId, + c.CompanyName, + Departments = c.Departments + .OrderBy(d => d.DepartmentId) + .Select(d => new { d.DepartmentId, d.DepartmentName, d.DepartmentCode }) + }) + .ToListAsync(); + return Json(companyList); + } + + [HttpPost("GetDepartmentWithCompany")] + public async Task GetDepartmentWithCompany(int companyId, int departmentId) + { + var departmentList = await _identityDbContext.Departments.FirstOrDefaultAsync(d => d.DepartmentId == departmentId); + var companyList = await _identityDbContext.Companies.FirstOrDefaultAsync(c => c.CompanyId == companyId); + + // Create a new list to store departments with their company name + var departmentWithCompany = new DepartmentCompany + { + DepartmentId = departmentList!.DepartmentId, + DepartmentName = departmentList.DepartmentName, + CompanyId = departmentList.CompanyId, + CompanyName = companyList?.CompanyName + }; + + // Return the constructed list as JSON + return departmentWithCompany; + } + [HttpPost("AddCompanyDepartment")] + public async Task AddCompanyDepartment([FromBody] UpdateDepartmentCompany departmentCompanyDetails) + { + try + { + CompanyModel companyModel = new CompanyModel + { + CompanyName = departmentCompanyDetails.Company! + }; + + _identityDbContext.Companies.Add(companyModel); + await _identityDbContext.SaveChangesAsync(); + + foreach (var department in departmentCompanyDetails.Department!) + { + DepartmentModel departmentModel = new DepartmentModel + { + CompanyId = companyModel.CompanyId, + DepartmentName = department.DepartmentName ?? string.Empty, + DepartmentCode = department.DepartmentCode ?? string.Empty + }; + + _identityDbContext.Departments.Add(departmentModel); + await _identityDbContext.SaveChangesAsync(); + } + + return Ok( new { message = "Company and department added successfully" }); + } + catch (Exception ex) + { + return StatusCode(500, new { message = $"An error occurred: {ex.Message}" }); + } + } + public class UpdateDepartmentCompany + { + [Required] + public string? Company { get; set; } + [Required] + public List? Department { get; set; } + + } + public class DepartmentInfo + { + [Required] + public string? DepartmentName { get; set; } + [Required] + public string? DepartmentCode { get; set; } + } + public class DepartmentCompany + { + public int DepartmentId { get; set; } + public string? DepartmentName { get; set; } + public int CompanyId { get; set; } + public string? CompanyName { get; set; } + } } } diff --git a/Controllers/API/IdentityAPI.cs b/Controllers/API/IdentityAPI.cs index b43846d..0334965 100644 --- a/Controllers/API/IdentityAPI.cs +++ b/Controllers/API/IdentityAPI.cs @@ -11,10 +11,10 @@ namespace PSTW_CentralSystem.Controllers.API [ApiController] [Route("[controller]")] - public class IdentityAPI : ControllerBase + public class IdentityAPI : Controller { private readonly ILogger _logger; - private readonly IdentityDBContext _authDbContext; + private readonly IdentityDBContext _identityDbContext; private readonly UserManager _userManager; private readonly SignInManager _signInManager; // Communication Key for API. Not API authentication key @@ -24,7 +24,7 @@ namespace PSTW_CentralSystem.Controllers.API public IdentityAPI(ILogger logger, IdentityDBContext authDbContext, UserManager userManager, SignInManager signInManager) { _logger = logger; - _authDbContext = authDbContext; + _identityDbContext = authDbContext; _userManager = userManager; _signInManager = signInManager; } @@ -38,18 +38,18 @@ namespace PSTW_CentralSystem.Controllers.API var userRole = await _userManager.GetRolesAsync(user!); if (user == null) { - return NotFound(new { message = $"Unable to load user with ID '{_userManager.GetUserId(User)}'."}); + return NotFound(new { message = $"Unable to load user with ID '{_userManager.GetUserId(User)}'." }); } - var userInfo = await _authDbContext.Users.Include(u => u.Department).Select(u => new - { - id = u.Id, - email = u.NormalizedEmail, + var userInfo = await _identityDbContext.Users.Include(u => u.Department).Select(u => new + { + id = u.Id, + email = u.NormalizedEmail, company = u.Department!.Company!.CompanyName, - department =u.Department, + department = u.Department, role = userRole, }).Where(u => u.id == user.Id).FirstOrDefaultAsync(); - + if (userInfo == null) { return NotFound(new { message = "User not found" }); @@ -133,17 +133,68 @@ namespace PSTW_CentralSystem.Controllers.API if (existUser == null) { await _userManager.CreateAsync(ldapuser); - //await _userManager.SetLockoutEnabledAsync(ldapuser, false); - //return RedirectToAction("AssignRoleAfterLdap", "IdentityController"); + await _signInManager.SignInAsync(ldapuser, false); return Ok(new { RedirectUrl = Url.Action("ComDeptAssignment", "Identity") }); }; await _signInManager.SignInAsync(existUser, false); - //return RedirectToAction("Index", "HomeController"); + + if (existUser.UserStatus == null || existUser.UserStatus != 0) + { + return Ok(new { RedirectUrl = Url.Action("ComDeptAssignment", "Identity") }); + } + return Ok(new { RedirectUrl = Url.Action("Index", "Home") }); } + #region Company + + [HttpPost("CompanyDepartmentList")] + public async Task CompanyDepartmentList() + { + var companyList = await _identityDbContext.Companies + .Include(c => c.Departments) + .Select(c => new { + c.CompanyId, + c.CompanyName, + Departments = c.Departments + .OrderBy(d => d.DepartmentId) + .Select(d => new { d.DepartmentId, d.DepartmentName }) + }) + .ToListAsync(); + return Json(companyList); + } + + #endregion Company + + #region Department + + [HttpPost("DepartmentCompanyList")] + public async Task DepartmentCompanyList() + { + var itemDepartment = await _identityDbContext.Departments + .Include(d => d.Company) // Include the related Company entity + .Select(d => new + { + d.DepartmentId, + d.DepartmentName, + d.CompanyId, + d.Company.CompanyName, + }) + .ToListAsync(); + + //return Json(await GetDepartmentWithCompanyList()); + return Json(itemDepartment); + } + + #endregion Department + + [HttpPost("UserComptDeptAssignment")] + public async Task UserComptDeptAssignment([FromBody] UserModel userModel) + { + return Ok(); + } public async Task doUserExists(string username) { diff --git a/Controllers/API/Inventory/InvMainAPI.cs b/Controllers/API/Inventory/InvMainAPI.cs index 3c91525..08c7e25 100644 --- a/Controllers/API/Inventory/InvMainAPI.cs +++ b/Controllers/API/Inventory/InvMainAPI.cs @@ -197,45 +197,7 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory #endregion Product - #region Company - - [HttpPost("CompanyDepartmentList")] - public async Task CompanyDepartmentList() - { - var companyList = await _identityDbContext.Companies - .Include(c => c.Departments) - .Select(c => new { c.CompanyId, c.CompanyName, Departments = c.Departments - .OrderBy(d => d.DepartmentId) - .Select(d => new { d.DepartmentId, d.DepartmentName }) - }) - .ToListAsync(); - return Json(companyList); - } - - #endregion Company - - #region Department - - [HttpPost("DepartmentCompanyList")] - public async Task DepartmentCompanyList() - { - var itemDepartment = await _identityDbContext.Departments - .Include(d => d.Company) // Include the related Company entity - .Select(d => new - { - d.DepartmentId, - d.DepartmentName, - d.CompanyId, - d.Company.CompanyName, - }) - .ToListAsync(); - - //return Json(await GetDepartmentWithCompanyList()); - return Json(itemDepartment); - } - - #endregion Department - + #region Supplier [HttpPost("SupplierList")] diff --git a/Controllers/AdminController.cs b/Controllers/AdminController.cs index 84a6ac5..e1135bf 100644 --- a/Controllers/AdminController.cs +++ b/Controllers/AdminController.cs @@ -63,5 +63,13 @@ namespace PSTW_CentralSystem.Controllers { return View(); } + public IActionResult RoleAdmin() + { + return View(); + } + public IActionResult CompDeptAdmin() + { + return View(); + } } } diff --git a/Controllers/IdentityController.cs b/Controllers/IdentityController.cs index fbc69cd..d9a082d 100644 --- a/Controllers/IdentityController.cs +++ b/Controllers/IdentityController.cs @@ -25,7 +25,7 @@ namespace PSTW_CentralSystem.Controllers public async Task ComDeptAssignment() { var thisUser = await _userManager.GetUserAsync(User); - return View(thisUser.Id); + return View(thisUser); } } diff --git a/DBContext/IdentityDBContext.cs b/DBContext/IdentityDBContext.cs index b1b210d..e9598ea 100644 --- a/DBContext/IdentityDBContext.cs +++ b/DBContext/IdentityDBContext.cs @@ -51,7 +51,8 @@ namespace PSTW_CentralSystem.DBContext Email = "admin@pstw.com.my", NormalizedEmail = "ADMIN@PSTW.COM.MY", SecurityStamp = Guid.NewGuid().ToString(), - EmailConfirmed = true + EmailConfirmed = true, + UserStatus = 1, }; var systemAdmin = new UserModel { @@ -62,7 +63,8 @@ namespace PSTW_CentralSystem.DBContext Email = "sysadmin@pstw.com.my", NormalizedEmail = "SYSADMIN@PSTW.COM.MY", SecurityStamp = Guid.NewGuid().ToString(), - EmailConfirmed = true + EmailConfirmed = true, + UserStatus = 1, }; // Hash the password diff --git a/Models/DepartmentModel.cs b/Models/DepartmentModel.cs index ca25c9c..0d94b44 100644 --- a/Models/DepartmentModel.cs +++ b/Models/DepartmentModel.cs @@ -9,7 +9,7 @@ namespace PSTW_CentralSystem.Models public int DepartmentId { get; set; } public required string DepartmentName { get; set; } public required string DepartmentCode { get; set; } - public required int CompanyId { get; set; } + public int CompanyId { get; set; } [ForeignKey("CompanyId")] public virtual CompanyModel? Company { get; set; } diff --git a/Views/Admin/CompDeptAdmin.cshtml b/Views/Admin/CompDeptAdmin.cshtml new file mode 100644 index 0000000..5b69477 --- /dev/null +++ b/Views/Admin/CompDeptAdmin.cshtml @@ -0,0 +1,341 @@ +@* + For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 +*@ +@{ + ViewData["Title"] = "Company & Department Administration"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} +
+
+
+ +
+
+
+
+

Company And Department

+
+
+
+
+
+
+
+
+
+ + + + + +
+@section Scripts { + @{ + await Html.RenderPartialAsync("_ValidationScriptsPartial"); + } + +} diff --git a/Views/Admin/Index.cshtml b/Views/Admin/Index.cshtml index d6e4e07..052f8fe 100644 --- a/Views/Admin/Index.cshtml +++ b/Views/Admin/Index.cshtml @@ -30,4 +30,16 @@ + diff --git a/Views/Admin/UserAdmin.cshtml b/Views/Admin/UserAdmin.cshtml index 52dbe7d..58e4148 100644 --- a/Views/Admin/UserAdmin.cshtml +++ b/Views/Admin/UserAdmin.cshtml @@ -62,10 +62,10 @@ }; }, mounted() { - this.fetchModule(); + this.fetchUsers(); }, methods: { - fetchModule() { + fetchUsers() { fetch('/AdminAPI/GetUserList', { method: 'POST' }) @@ -78,7 +78,7 @@ console.error('There was a problem with the fetch operation:', error); }); }, - editModule(module) { + editUser(user) { // Check if the user ID exists if (module.settingId) { // Redirect the user to the edit user page @@ -87,13 +87,13 @@ console.error('Module ID not found'); } }, - deleteModule(module) { + deleteUser(user) { this.selectedModule = module; // Set selected user $('#confirm-dialog').modal('show'); // Show the modal // console.log(this.selectedModule); }, - confirmDelete(module) { + confirmDelete(user) { fetch(`/ModuleAPI/DeleteModule/${module.settingId}`, { method: 'POST' }) @@ -149,9 +149,13 @@ { "title": "Delete", "data": "id", - "render": function (data) { - var deleteButton = ``; - return deleteButton; + "render": function (data, type, row, meta) { + if (!row.role.includes("SuperAdmin") && !row.role.includes("SystemAdmin")) { + var deleteButton = ``; + return deleteButton; + } else { + return ""; // Return empty string if role is "SuperAdmin" or "SystemAdmin" + } }, } ], diff --git a/Views/Identity/ComDeptAssignment.cshtml b/Views/Identity/ComDeptAssignment.cshtml index ff4841a..21eec61 100644 --- a/Views/Identity/ComDeptAssignment.cshtml +++ b/Views/Identity/ComDeptAssignment.cshtml @@ -4,52 +4,52 @@ @{ ViewData["Title"] = "Company & Department Assignment"; Layout = "~/Views/Shared/_Layout.cshtml"; - int userId = ViewBag.UserId; + @model UserModel? }

@* Create New *@

-@userId; + +
-

Latest Posts

+

Update Compulsory Details

-
+

User ID: @Model?.Id

+

User Name: @Model?.UserName

+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
- -
@section Scripts { @{ @@ -60,13 +60,50 @@ data() { return { userList: null, - selectedModule: null + selectedModule: null, + companyList: null, + company: '', + selectedDepartment: '', + selectedCompany: '', }; }, mounted() { - this.fetchModule(); + this.fetchModule(); + this.fetchCompanies(); + }, + computed: { + // Computed property to dynamically update departmentList based on selectedCompany + departmentList() { + // If selectedCompany is empty, return an empty array to prevent errors + if (!this.selectedCompany) { + this.selectedDepartment = '' + return []; + } + + const selectedCompanyObj = this.companyList.find(c => c.companyName === this.selectedCompany); + // Ensure that the selected company exists before accessing its departments + return selectedCompanyObj ? selectedCompanyObj.departments : []; + }, }, methods: { + async fetchCompanies() { + try { + const response = await fetch('/IdentityAPI/CompanyDepartmentList', { + method: 'POST', // Specify the HTTP method + headers: { + 'Content-Type': 'application/json' + } + }); + if (!response.ok) { + throw new Error('Failed to fetch companies'); + } + + this.companyList = await response.json(); + + } catch (error) { + console.error('Error fetching products:', error); + } + }, fetchModule() { fetch('/AdminAPI/GetUserList', { method: 'POST' @@ -82,121 +119,39 @@ console.error('There was a problem with the fetch operation:', error); }); }, - editModule(module) { - // Check if the user ID exists - if (module.settingId) { - // Redirect the user to the edit user page - window.location.href = 'ModuleSetting/' + module.settingId; - } else { - console.error('Module ID not found'); - } - }, - deleteModule(module) { - this.selectedModule = module; // Set selected user - $('#confirm-dialog').modal('show'); // Show the modal + async updateInfo() { + const uid = @Model?.Id; + try { + // Show the loading modal + $('#loadingModal').modal('show'); - // console.log(this.selectedModule); - }, - confirmDelete(module) { - fetch(`/ModuleAPI/DeleteModule/${module.settingId}`, { - method: 'POST' - }) - .then(response => { - if (!response.ok) { - throw new Error('Failed to delete module'); - } - // Remove the deleted user from the userData array - const index = this.moduleData.findIndex(u => u.settingId === module.settingId); - if (index !== -1) { - alert("Module deleted successfully"); - this.moduleData.splice(index, 1); - } - this.hideModal(); // Hide the modal after deletion - }) - .catch(error => { - console.error('Failed to delete module with status:', error); + // Perform the fetch request + const response = await fetch(`/IdentityAPI/UserComptDeptAssignment/${uid}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(this.selectedDepartment), }); - }, - hideModal() { - $('#confirm-dialog').modal('hide'); - }, - initiateTable() { - self = this; - this.itemDatatable = $('#userDatatable').DataTable({ - "data": this.userList, - "columns": [ - { - "title": "UID", - "data": "id", - "createdCell": function (td, cellData, rowData, row, col) { - // Assign a unique ID to the element - $(td).attr('id', `qr${cellData}`); - }, - }, - { - "title": "Email", - "data": "email", - }, - { - "title": "Company Name", - "data": "company", - }, - { - "title": "Department", - "data": "department", - }, - { - "title": "Role", - "data": "role", - }, - { - "title": "Delete", - "data": "id", - "render": function (data) { - var deleteButton = ``; - return deleteButton; - }, - } - ], - responsive: true, - drawCallback: function (settings) { - // Generate QR codes after rows are rendered - const api = this.api(); - api.rows().every(function () { - const data = this.data(); // Row data - const containerId = `qr${data.uniqueID}`; - const container = $(`#${containerId}`); - // console.log(container[0]); - if (container) { - // Generate QR code only if not already generated - new QRCode(container[0], { - text: data.qrString, - width: 150, - height: 150, - colorDark: "#000000", - colorLight: "#ffffff", - correctLevel: QRCode.CorrectLevel.H - }); - } - }); - }, - }) - // Attach click event listener to the delete buttons - $('#itemDatatable tbody').on('click', '.delete-btn', function () { - const itemId = $(this).data('id'); - self.deleteItem(itemId); - }); + // Check if the response is OK + if (!response.ok) { + const errorData = await response.json(); + throw new Error(errorData.message); + } - $('#itemDatatable tbody').on('click', '.print-btn', function () { - const itemId = $(this).data('id'); - var $row = $(this).closest('tr'); // get the row containing the button - var imageSrc = $row.find('img').attr('src'); // find the img element in the row and get its src - // console.log(imageSrc); - self.printItem(itemId, imageSrc); - }); - - this.loading = false; + const data = await response.json(); + this.fetchCompDept(); + $('#registerCompDept').modal('hide'); + alert("Company and department successfully added"); + } + catch (error) { + console.error('Failed to add company and department:', error); + alert(error.message); + } + finally { + $('#loadingModal').modal('hide'); + } }, } }) diff --git a/Views/Shared/_Layout.cshtml b/Views/Shared/_Layout.cshtml index 0a5cbb7..25d73ed 100644 --- a/Views/Shared/_Layout.cshtml +++ b/Views/Shared/_Layout.cshtml @@ -70,7 +70,7 @@
-