using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using KernelRecordsMVC.Data; using KernelRecordsMVC.Models; using KernelRecordsMVC.Domain.Enums; using KernelRecordsMVC.Application.ViewModels; using Microsoft.AspNetCore.Http; namespace KernelRecordsMVC.Controllers; public class AdminController : Controller { private readonly KernelRecordsContext _context; public AdminController(KernelRecordsContext context) { _context = context; } // ========================================== // ADMIN DASHBOARD // ========================================== [HttpGet] public IActionResult Index() { if (!IsAdmin()) return Forbid(); return View(); } // ========================================== // UC008 // NEW PRODUCT - GET // ========================================== [HttpGet] public IActionResult CreateProduct() { if (!IsProductManager()) return Forbid(); ViewBag.Releases = _context.Releases .OrderBy(x => x.Title) .ToList(); return View(new CreateProductViewModel()); } // ========================================== // UC008 // NEW PRODUCT - POST // ========================================== [HttpPost] [ValidateAntiForgeryToken] public IActionResult CreateProduct( CreateProductViewModel model) { if (!IsProductManager()) return Forbid(); if (!ModelState.IsValid) { LoadReleases(); return View(model); } // Make sure the release actually exists. var release = _context.Releases .FirstOrDefault(x => x.ReleaseId == model.ReleaseId); if (release == null) { ModelState.AddModelError( "ReleaseId", "The selected release does not exist."); LoadReleases(); return View(model); } // Don't allow duplicate format for // the same release. var alreadyExists = _context.Products.Any(p => p.ReleaseId == model.ReleaseId && p.Format == model.Format); if (alreadyExists) { ModelState.AddModelError( "Format", "This release already has a product in this format."); LoadReleases(); return View(model); } var product = new Product { ProductId = GetNextProductId(), ReleaseId = model.ReleaseId, Format = model.Format, Price = model.Price, ProductDescription = model.ProductDescription, Stock = model.Stock }; _context.Products.Add(product); _context.SaveChanges(); // Record the modification. CreateModification( ModificationType.CREATE, product.ProductId); TempData["Success"] = "Product created successfully."; return RedirectToAction( nameof(Index)); } // ========================================== // HELPERS // ========================================== private bool IsAdmin() { return HttpContext.Session .GetString("Role") == "Admin"; } private bool IsProductManager() { var role = HttpContext.Session .GetString("Role"); var adminType = HttpContext.Session .GetString("AdminType"); return role == "Admin" && (adminType == "PRODUCT_MANAGER" || adminType == "SUPER_ADMIN"); } private long? GetCurrentUserId() { var value = HttpContext.Session .GetString("UserId"); if (long.TryParse(value, out var userId)) return userId; return null; } private long GetNextProductId() { var maxId = _context.Products .Select(x => (long?)x.ProductId) .Max(); return (maxId ?? 0) + 1; } private void LoadReleases() { ViewBag.Releases = _context.Releases .OrderBy(x => x.Title) .ToList(); } private void CreateModification( ModificationType type, long productId, decimal? discount = null) { var adminId = GetCurrentUserId(); if (adminId == null) return; var modification = new Modification { ModificationId = GetNextModificationId(), AdminId = adminId.Value, DateModified = DateTime.Today, TypeOfModification = type, Discount = discount }; _context.Modifications.Add(modification); _context.SaveChanges(); var modificationProduct = new ModificationProduct { ModificationId = modification.ModificationId, ProductId = productId }; _context.ModificationProducts.Add( modificationProduct); _context.SaveChanges(); } private long GetNextModificationId() { var maxId = _context.Modifications .Select(x => (long?)x.ModificationId) .Max(); return (maxId ?? 0) + 1; } // ========================================== // UC009 // MODIFY PRODUCT - GET // ========================================== [HttpGet] public IActionResult EditProduct(long id) { if (!IsProductManager()) return Forbid(); var product = _context.Products .Include(p => p.Release) .FirstOrDefault(p => p.ProductId == id); if (product == null) return NotFound(); var model = new EditProductViewModel { ProductId = product.ProductId, ReleaseId = product.ReleaseId, ReleaseTitle = product.Release.Title, Format = product.Format, Price = product.Price, ProductDescription = product.ProductDescription, Stock = product.Stock }; return View(model); } // ========================================== // UC009 // MODIFY PRODUCT - POST // ========================================== [HttpPost] [ValidateAntiForgeryToken] public IActionResult EditProduct( EditProductViewModel model) { if (!IsProductManager()) return Forbid(); var product = _context.Products .Include(p => p.Release) .FirstOrDefault(p => p.ProductId == model.ProductId); if (product == null) return NotFound(); if (!ModelState.IsValid) { model.ReleaseTitle = product.Release.Title; model.ReleaseId = product.ReleaseId; model.Format = product.Format; return View(model); } // ========================================== // DISCOUNT // ========================================== if (model.ModificationType == ModificationType.DISCOUNT) { if (!model.Discount.HasValue) { ModelState.AddModelError( "Discount", "Please enter a discount percentage."); model.ReleaseTitle = product.Release.Title; model.ReleaseId = product.ReleaseId; model.Format = product.Format; return View(model); } product.Price = product.Price * (1 - model.Discount.Value / 100m); } else { // ========================================== // NORMAL UPDATE // ========================================== product.Price = model.Price; product.ProductDescription = model.ProductDescription; product.Stock = model.Stock; } _context.SaveChanges(); // ========================================== // RECORD MODIFICATION // ========================================== CreateModification( model.ModificationType, product.ProductId, model.Discount); TempData["Success"] = "Product modified successfully."; return RedirectToAction(nameof(Index)); } [HttpGet] public IActionResult Products() { if (!IsProductManager()) return Forbid(); var products = _context.Products .Include(p => p.Release) .OrderBy(p => p.Release.Title) .ThenBy(p => p.Format) .ToList(); return View(products); } }