diff --git a/Areas/Inventory/Controllers/Admin/InventoryMasterController.cs b/Areas/Inventory/Controllers/Admin/InventoryMasterController.cs index af6d221..69301e1 100644 --- a/Areas/Inventory/Controllers/Admin/InventoryMasterController.cs +++ b/Areas/Inventory/Controllers/Admin/InventoryMasterController.cs @@ -1,9 +1,10 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; namespace PSTW_CentralSystem.Areas.Inventory.Controllers.Admin { [Area("Inventory")] - //[Authorize(Policy = "RoleModulePolicy")] + [Authorize(Policy = "RoleModulePolicy")] public class InventoryMasterController : Controller { public IActionResult AdminDashboard() diff --git a/Areas/Inventory/Controllers/ItemMovementController.cs b/Areas/Inventory/Controllers/ItemMovementController.cs index ba17a0e..2da7e77 100644 --- a/Areas/Inventory/Controllers/ItemMovementController.cs +++ b/Areas/Inventory/Controllers/ItemMovementController.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using PSTW_CentralSystem.Areas.Inventory.Models; namespace PSTW_CentralSystem.Areas.Inventory.Controllers { @@ -15,5 +16,12 @@ namespace PSTW_CentralSystem.Areas.Inventory.Controllers return View(); } + [Authorize] + [HttpPost("/i/{id}")] + public IActionResult ItemRecognization(string id, [FromBody] ItemModel item) + { + return View(); + } + } } diff --git a/Areas/Inventory/Controllers/MainController.cs b/Areas/Inventory/Controllers/MainController.cs index 2872cf2..3f9bbe3 100644 --- a/Areas/Inventory/Controllers/MainController.cs +++ b/Areas/Inventory/Controllers/MainController.cs @@ -14,14 +14,5 @@ namespace PSTW_CentralSystem.Areas.Inventory.Controllers return View(); } - public IActionResult SupplierRegistration() - { - return View(); - } - public IActionResult ManifacturerRegistration() - { - return View(); - } - } } diff --git a/Areas/Inventory/Models/ItemModel.cs b/Areas/Inventory/Models/ItemModel.cs index 1ec16a4..a9c4a4a 100644 --- a/Areas/Inventory/Models/ItemModel.cs +++ b/Areas/Inventory/Models/ItemModel.cs @@ -33,6 +33,7 @@ namespace PSTW_CentralSystem.Areas.Inventory.Models [Comment("1 = In stock; 2 = Item Moving; 3 = Item Out; 4 = Item Broken; 5 = Item Lost; 6 = Item Stolen; 7 = Item Damaged; 8 = Item Discarded; 9 = Item Destroyed; 10 = Item Finished;")] public int ItemStatus { get; set; } = 1; public int? MovementId { get; set; } + public string PartNumber { get; set; } = string.Empty; public int CreatedByUserId { get; set; } [ForeignKey("CreatedByUserId")] public virtual UserModel? CreatedBy { get; set; } diff --git a/Areas/Inventory/Views/InventoryMaster/ItemRegistration.cshtml b/Areas/Inventory/Views/InventoryMaster/ItemRegistration.cshtml index 2d2cff5..9ca2f4d 100644 --- a/Areas/Inventory/Views/InventoryMaster/ItemRegistration.cshtml +++ b/Areas/Inventory/Views/InventoryMaster/ItemRegistration.cshtml @@ -177,6 +177,14 @@ + @* Part Number Coding *@ +
+ +
+ +
+
+ @* Serial Number and Quantity Coding *@
@@ -199,7 +207,7 @@
- + @* Supplier coding *@
@@ -394,6 +402,7 @@ EndWDate: null, invoiceNo: null, invoiceDate: null, + partNumber: null, products: [], depts: [], suppliers: [ @@ -478,6 +487,7 @@ InvoiceDate: this.invoiceDate, CreatedByUserId: this.currentUser.id, TeamType: this.selectedTeamType, + PartNumber: this.partNumber, }; try { @@ -789,6 +799,7 @@ this.selectedCompany = this.currentUserCompanyDept.companyId; this.selectedDepartment = ''; this.selectedTeamType = ''; + this.partNumber = null; }, // FRONT END FUNCTIONS @@ -925,7 +936,7 @@ // Populate the virtual DOM with content virtualElement.innerHTML = `
-
+
diff --git a/Areas/Inventory/Views/InventoryMaster/ProductRegistration.cshtml b/Areas/Inventory/Views/InventoryMaster/ProductRegistration.cshtml index c6b98ef..0aed882 100644 --- a/Areas/Inventory/Views/InventoryMaster/ProductRegistration.cshtml +++ b/Areas/Inventory/Views/InventoryMaster/ProductRegistration.cshtml @@ -216,11 +216,11 @@ } }, async addProduct() { - const existingProduct = this.products.find(p => p.modelNo === this.modelNo); - if (existingProduct) { - alert(`Product Error: The model number ${this.modelNo} already exists.`, 'error'); - return; // Exit early if the modelNo exists - } + // const existingProduct = this.products.find(p => p.modelNo === this.modelNo); + // if (existingProduct) { + // alert(`Product Error: The model number ${this.modelNo} already exists.`, 'error'); + // return; // Exit early if the modelNo exists + // } // Create the payload const formData = { diff --git a/Areas/Inventory/Views/Item/Qr.cshtml b/Areas/Inventory/Views/ItemMovement/Qr.cshtml similarity index 100% rename from Areas/Inventory/Views/Item/Qr.cshtml rename to Areas/Inventory/Views/ItemMovement/Qr.cshtml diff --git a/Areas/Inventory/Views/_InventoryPartial.cshtml b/Areas/Inventory/Views/_InventoryPartial.cshtml index fcad2ed..3d6b01b 100644 --- a/Areas/Inventory/Views/_InventoryPartial.cshtml +++ b/Areas/Inventory/Views/_InventoryPartial.cshtml @@ -1,7 +1,31 @@ @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
+ +
+

@@ -14,7 +38,7 @@

\ No newline at end of file diff --git a/Controllers/JSA/JSAController.cs b/Areas/JSA/Controllers/JSAController.cs similarity index 85% rename from Controllers/JSA/JSAController.cs rename to Areas/JSA/Controllers/JSAController.cs index b6d1e42..776f320 100644 --- a/Controllers/JSA/JSAController.cs +++ b/Areas/JSA/Controllers/JSAController.cs @@ -1,8 +1,8 @@ -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; -namespace PSTW_CentralSystem.Controllers.JSA +namespace PSTW_CentralSystem.Areas.JSA.Controllers { + [Area("JSA")] public class JSAController : Controller { // GET: JSAController diff --git a/Areas/Report/Controllers/ReportingController.cs b/Areas/Report/Controllers/ReportingController.cs new file mode 100644 index 0000000..5e61a3c --- /dev/null +++ b/Areas/Report/Controllers/ReportingController.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Mvc; + +namespace PSTW_CentralSystem.Areas.Report.Controllers +{ + [Area("Report")] + public class ReportingController : Controller + { + public IActionResult Index() + { + return View(); + } + public IActionResult InventoryReport() + { + return View(); + } + } +} diff --git a/Areas/Report/Views/Reporting/Index.cshtml b/Areas/Report/Views/Reporting/Index.cshtml new file mode 100644 index 0000000..e1dd794 --- /dev/null +++ b/Areas/Report/Views/Reporting/Index.cshtml @@ -0,0 +1,5 @@ +@* + For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 +*@ +@{ +} diff --git a/Areas/Report/Views/Reporting/InventoryReport.cshtml b/Areas/Report/Views/Reporting/InventoryReport.cshtml new file mode 100644 index 0000000..5798427 --- /dev/null +++ b/Areas/Report/Views/Reporting/InventoryReport.cshtml @@ -0,0 +1,160 @@ +@{ + ViewData["Title"] = "Dashboard"; + Layout = "~/Views/Shared/_Layout.cshtml"; +} +
+
+
+

Reporting Dashboard

+

Store: {{ currentUserCompanyDept.departmentName }}

+
+
+
+
+

Report Filter

+
+
+
+
+
+

Statistic

+
+
+

Item Registered

+
+
+

Item Stock Out

+
+
+
+
+
+
+
+

Inventory Report

+
+
+
+
+
+

Statistic

+

Total Number of Item Registered: {{ reportData.itemCountRegistered }}

+

Total Number of Item Still in Stock: {{ reportData.itemCountStillInStock }}

+
+
+

Item Registered

+

This Month: {{ reportData.itemCountRegisteredThisMonth }}

+

Last Month: {{ reportData.itemCountRegisteredLastMonth }}

+
+
+

Item Stock Out

+

This Month: {{ reportData.itemCountStockOutThisMonth }}

+

Last Month: {{ reportData.itemCountStockOutLastMonth }}

+
+
+
+
+
+
+@section Scripts { +@{ + await Html.RenderPartialAsync("_ValidationScriptsPartial"); +} + +} \ No newline at end of file diff --git a/Controllers/API/AdminAPI.cs b/Controllers/API/AdminAPI.cs index a37eb17..2761fc3 100644 --- a/Controllers/API/AdminAPI.cs +++ b/Controllers/API/AdminAPI.cs @@ -75,7 +75,15 @@ namespace PSTW_CentralSystem.Controllers.API var controllerTypes = await Task.Run(() => assembly.GetTypes().Where(type => typeof(ControllerBase).IsAssignableFrom(type) && type.IsClass && !type.Name.Contains("API") && !type.Name.Contains("Admin")).ToList()); // Iterate over the controller types and get their methods - foreach (var controllerType in controllerTypes) { + foreach (var controllerType in controllerTypes) { + + // Get the [Area] attribute, if it exists + var areaAttribute = controllerType.GetCustomAttributes(true) + .OfType() + .FirstOrDefault(); + + var areaName = areaAttribute?.RouteValue ?? null; + var methods = controllerType?.GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(m => m.DeclaringType == controllerType) // Filter methods declared directly in the controller (ignoring inherited ones) .Select(m => m.Name) // Get the method names @@ -83,6 +91,7 @@ namespace PSTW_CentralSystem.Controllers.API controllerAndMethodList.Add(new { + Module = areaName, Controller = controllerType?.Name.Replace("Controller", string.Empty), Methods = methods }); @@ -103,7 +112,7 @@ namespace PSTW_CentralSystem.Controllers.API // Fetch all users excluding those with roles SuperAdmin or SystemAdmin var allUsers = await _centralDbContext.Users - .Include(u => u.Department.Company) + .Include(u => u.Department!.Company) .ToListAsync(); if (userRole == null || userRole.Count == 0) @@ -200,7 +209,7 @@ namespace PSTW_CentralSystem.Controllers.API .Select(c => new { c.CompanyId, c.CompanyName, - Departments = c.Departments + Departments = c.Departments! .OrderBy(d => d.DepartmentId) .Select(d => new { d.DepartmentId, d.DepartmentName, d.DepartmentCode }) }) diff --git a/Controllers/API/Inventory/InvMainAPI.cs b/Controllers/API/Inventory/InvMainAPI.cs index 5e3eb52..cbd2d0e 100644 --- a/Controllers/API/Inventory/InvMainAPI.cs +++ b/Controllers/API/Inventory/InvMainAPI.cs @@ -318,6 +318,7 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory item.ConvertPrice, item.DODate, item.Warranty, + item.PartNumber, EndWDate = item.EndWDate.ToString("dd/MM/yyyy"), InvoiceDate = item.InvoiceDate?.ToString("dd/MM/yyyy"), item.Department?.DepartmentName, @@ -439,6 +440,7 @@ namespace PSTW_CentralSystem.Controllers.API.Inventory savedItem.Warranty, savedItem.EndWDate, savedItem.InvoiceDate, + savedItem.PartNumber, }; return Json(updatedItem); } diff --git a/Controllers/API/Reporting/ReportingAPI.cs b/Controllers/API/Reporting/ReportingAPI.cs new file mode 100644 index 0000000..cd1777c --- /dev/null +++ b/Controllers/API/Reporting/ReportingAPI.cs @@ -0,0 +1,120 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using PSTW_CentralSystem.Areas.Inventory.Models; +using PSTW_CentralSystem.DBContext; +using PSTW_CentralSystem.Models; + +namespace PSTW_CentralSystem.Controllers.API.Reporting +{ + [ApiController] + [Route("[controller]")] + [Authorize] + public class ReportingAPI : Controller + { + private readonly ILogger _logger; + private readonly CentralSystemContext _centralDbContext; + private readonly UserManager _userManager; + private readonly RoleManager _roleManager; + + public ReportingAPI(ILogger logger, CentralSystemContext centralDbContext, UserManager userManager, RoleManager roleManager) + { + _logger = logger; + _centralDbContext = centralDbContext; + _userManager = userManager; + _roleManager = roleManager; + } + + #region ItemReport + + [HttpPost("GetInventoryReport/{deptId}")] + public async Task GetInventoryReport(int? deptId) + { + try + { + var user = await _userManager.GetUserAsync(User); + + List items = new List(); + if (deptId == null || deptId == 0) + { + items = await _centralDbContext.Items + .Include("CreatedBy") + .Include("Department") + .Include("Product") + .ToListAsync(); + } + else + { + items = await _centralDbContext.Items + .Include("CreatedBy") + .Include("Department") + .Include("Product") + .Where(i => i.DepartmentId == deptId) + .ToListAsync(); + } + var itemListWithDetails = items.Select(item => new + { + item.ItemID, + item.UniqueID, + item.CompanyId, + item.DepartmentId, + item.ProductId, + item.SerialNumber, + item.Quantity, + item.Supplier, + PurchaseDate = item.PurchaseDate.ToString("dd/MM/yyyy"), + item.PONo, + item.Currency, + item.DefaultPrice, + item.CurrencyRate, + item.ConvertPrice, + item.DODate, + item.Warranty, + EndWDate = item.EndWDate.ToString("dd/MM/yyyy"), + InvoiceDate = item.InvoiceDate?.ToString("dd/MM/yyyy"), + item.Department?.DepartmentName, + CreatedBy = item.CreatedBy!.UserName, + item.Product!.ProductName, + item.Product!.Category, + //CurrentUser = item.Movement?.FromUser?.UserName, + CurrentUser = item.Movement?.FromUser?.UserName, + CurrentStore = item.Movement?.FromStore?.StoreName, + CurrentStation = item.Movement?.FromStation?.StationName, + + QRString = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host.Value}/I/{item.UniqueID}" // Generate QR String + }).ToList(); + + int itemCountRegistered = items.Count; + int itemCountStillInStock = items.Where(i => i.Quantity > 0).Count(); + var itemsMovementsThisMonth = _centralDbContext.ItemMovements + .Where(i => i.Date.Month == DateTime.Now.Month); + int itemCountRegisteredThisMonth = itemsMovementsThisMonth.Count(i => i.Action == "Register"); + int itemCountStockOutThisMonth = itemsMovementsThisMonth.Count(i => i.Action == "Stock Out"); + + var lastMonth = DateTime.Now.AddMonths(-1).Month; + var itemsMovementsLastMonth = _centralDbContext.ItemMovements + .Where(i => i.Date.Month == lastMonth); + int itemCountRegisteredLastMonth = itemsMovementsLastMonth.Count(i => i.Action == "Register"); + int itemCountStockOutLastMonth = itemsMovementsLastMonth.Count(i => i.Action == "Stock Out"); + + var report = new + { + itemCountRegistered, + itemCountStillInStock, + itemCountRegisteredThisMonth, + itemCountStockOutThisMonth, + itemCountRegisteredLastMonth, + itemCountStockOutLastMonth + }; + return Json(report); + } + catch (Exception ex) + { + return BadRequest(ex.Message); + } + } + + #endregion + } +} diff --git a/Controllers/API/RoleAPI.cs b/Controllers/API/RoleAPI.cs index 0ac8133..278e20f 100644 --- a/Controllers/API/RoleAPI.cs +++ b/Controllers/API/RoleAPI.cs @@ -14,13 +14,13 @@ namespace PSTW_CentralSystem.Controllers.API public class RoleAPI : Controller { private readonly ILogger _logger; - private readonly CentralSystemContext _authDbContext; + private readonly CentralSystemContext _centralDbContext; private readonly RoleManager _roleManager; - public RoleAPI(ILogger logger, CentralSystemContext authDbContext, RoleManager roleManager) + public RoleAPI(ILogger logger, CentralSystemContext centralDbContext, RoleManager roleManager) { _logger = logger; - _authDbContext = authDbContext; + _centralDbContext = centralDbContext; _roleManager = roleManager; } diff --git a/Controllers/InventoryController.cs b/Controllers/PublicInventoryController.cs similarity index 62% rename from Controllers/InventoryController.cs rename to Controllers/PublicInventoryController.cs index 426f202..2cd6254 100644 --- a/Controllers/InventoryController.cs +++ b/Controllers/PublicInventoryController.cs @@ -8,11 +8,11 @@ using PSTW_CentralSystem.Models; namespace PSTW_CentralSystem.Controllers { - public class InventoryController : Controller + public class PublicInventoryController : Controller { - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly CentralSystemContext _centralDbContext; - public InventoryController(ILogger logger, CentralSystemContext centralDbContext) + public PublicInventoryController(ILogger logger, CentralSystemContext centralDbContext) { _logger = logger; _centralDbContext = centralDbContext; @@ -24,12 +24,5 @@ namespace PSTW_CentralSystem.Controllers ViewData["ItemId"] = Id; return View("ItemInformation"); } - - [Authorize] - [HttpPost("/i/{id}")] - public IActionResult ItemRecognization(string id, [FromBody] ItemModel item) - { - return View(); - } } } diff --git a/PSTW_CentralSystem.csproj b/PSTW_CentralSystem.csproj index 5bd3f49..5d87e57 100644 --- a/PSTW_CentralSystem.csproj +++ b/PSTW_CentralSystem.csproj @@ -27,13 +27,11 @@ - - - - + + + - diff --git a/Views/Admin/ModuleCreate.cshtml b/Views/Admin/ModuleCreate.cshtml index 551bed9..2147d94 100644 --- a/Views/Admin/ModuleCreate.cshtml +++ b/Views/Admin/ModuleCreate.cshtml @@ -18,7 +18,7 @@
@@ -182,10 +182,14 @@ throw new Error('Name module already exist'); } alert('Module information saved successfully'); + window.history.back(); }) .catch(error => { console.error('There was a problem with the update operation:', error); alert('Failed to save data: ' + error.message); + }) + .finally(() => { + }); }, fetchControllerMethodList() { diff --git a/Views/Admin/RoleAdmin.cshtml b/Views/Admin/RoleAdmin.cshtml index be3cf9f..56e4631 100644 --- a/Views/Admin/RoleAdmin.cshtml +++ b/Views/Admin/RoleAdmin.cshtml @@ -156,7 +156,12 @@ "title": "Delete", "data": "id", "render": function (data, type, row, meta) { - var deleteButton = ``; + if(row.name != "Inventory Master"){ + var deleteButton = ``; + } + else{ + var deleteButton = "" + } return deleteButton; }, } diff --git a/Views/Inventory/ItemInformation.cshtml b/Views/PublicInventory/ItemInformation.cshtml similarity index 100% rename from Views/Inventory/ItemInformation.cshtml rename to Views/PublicInventory/ItemInformation.cshtml diff --git a/Views/Shared/_Layout.cshtml b/Views/Shared/_Layout.cshtml index e56a132..9a3bc50 100644 --- a/Views/Shared/_Layout.cshtml +++ b/Views/Shared/_Layout.cshtml @@ -438,20 +438,39 @@ +