Files
SkyArtShop/Controllers/AdminProductsController.cs

266 lines
8.4 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using SkyArtShop.Models;
using SkyArtShop.Services;
namespace SkyArtShop.Controllers;
[Route("admin/products")]
[Authorize(Roles = "Admin,MasterAdmin")]
public class AdminProductsController : Controller
{
private readonly PostgreSQLService _pgService;
private readonly SlugService _slugService;
private readonly string _productsCollection = "Products";
public AdminProductsController(PostgreSQLService pgService, SlugService slugService)
{
_pgService = pgService;
_slugService = slugService;
}
[HttpGet("")]
public async Task<IActionResult> Index()
{
return View((await _pgService.GetAllAsync<Product>(_productsCollection)).OrderByDescending((Product p) => p.CreatedAt).ToList());
}
[HttpGet("create")]
public IActionResult Create()
{
return View(new Product());
}
[HttpPost("create")]
public async Task<IActionResult> Create(Product product, string? ProductVariantsJson)
{
try
{
base.ModelState.Remove("ShortDescription");
base.ModelState.Remove("Description");
base.ModelState.Remove("ProductVariantsJson");
base.ModelState.Remove("Id");
base.ModelState.Remove("Slug");
base.ModelState.Remove("ImageUrl");
base.ModelState.Remove("Images");
if (!base.ModelState.IsValid)
{
foreach (ModelError item in base.ModelState.Values.SelectMany((ModelStateEntry v) => v.Errors))
{
Console.WriteLine("[CREATE] Validation Error: " + item.ErrorMessage);
}
return View(product);
}
}
catch (Exception ex)
{
Console.WriteLine("[CREATE] Error: " + ex.Message);
Console.WriteLine("[CREATE] Stack: " + ex.StackTrace);
base.TempData["ErrorMessage"] = "Error creating product: " + ex.Message;
return View(product);
}
if (!base.Request.Form.ContainsKey("IsActive"))
{
product.IsActive = false;
}
if (!base.Request.Form.ContainsKey("IsFeatured"))
{
product.IsFeatured = false;
}
if (!base.Request.Form.ContainsKey("IsTopSeller"))
{
product.IsTopSeller = false;
}
Console.WriteLine("[CREATE] ProductVariantsJson received: '" + (ProductVariantsJson ?? "NULL") + "'");
if (!string.IsNullOrEmpty(ProductVariantsJson))
{
try
{
product.Variants = JsonSerializer.Deserialize<List<ProductVariant>>(ProductVariantsJson) ?? new List<ProductVariant>();
Console.WriteLine($"[CREATE] Variants deserialized successfully: {product.Variants.Count} variants");
foreach (ProductVariant variant in product.Variants)
{
Console.WriteLine($" - {variant.ColorName} ({variant.ColorHex}) with {variant.Images?.Count ?? 0} images, Stock: {variant.StockQuantity}");
}
}
catch (Exception ex2)
{
Console.WriteLine("[CREATE] Error parsing variants: " + ex2.Message);
Console.WriteLine("[CREATE] JSON was: " + ProductVariantsJson);
product.Variants = new List<ProductVariant>();
}
}
else
{
Console.WriteLine("[CREATE] No variants provided - ProductVariantsJson is null or empty");
product.Variants = new List<ProductVariant>();
}
product.Colors = new List<string>();
product.Color = string.Empty;
try
{
product.CreatedAt = DateTime.UtcNow;
product.UpdatedAt = DateTime.UtcNow;
product.Slug = _slugService.GenerateSlug(product.Name);
await _pgService.InsertAsync(_productsCollection, product);
base.TempData["SuccessMessage"] = "Product created successfully!";
return RedirectToAction("Index");
}
catch (Exception ex3)
{
Console.WriteLine("[CREATE] Database Error: " + ex3.Message);
Console.WriteLine("[CREATE] Stack: " + ex3.StackTrace);
base.TempData["ErrorMessage"] = "Error saving product: " + ex3.Message;
return View(product);
}
}
[HttpGet("edit/{id}")]
public async Task<IActionResult> Edit(string id)
{
Product product = await _pgService.GetByIdAsync<Product>(_productsCollection, id);
if (product == null)
{
return NotFound();
}
return View("Create", product);
}
[HttpPost("edit/{id}")]
public async Task<IActionResult> Edit(string id, Product product, string? ProductVariantsJson)
{
try
{
base.ModelState.Remove("Images");
base.ModelState.Remove("Slug");
base.ModelState.Remove("ShortDescription");
base.ModelState.Remove("Description");
base.ModelState.Remove("ProductVariantsJson");
base.ModelState.Remove("Id");
base.ModelState.Remove("ImageUrl");
if (!base.ModelState.IsValid)
{
foreach (ModelError item in base.ModelState.Values.SelectMany((ModelStateEntry v) => v.Errors))
{
Console.WriteLine("[EDIT] Validation Error: " + item.ErrorMessage);
}
return View("Create", product);
}
}
catch (Exception ex)
{
Console.WriteLine("[EDIT] Error: " + ex.Message);
Console.WriteLine("[EDIT] Stack: " + ex.StackTrace);
base.TempData["ErrorMessage"] = "Error updating product: " + ex.Message;
return View("Create", product);
}
if (!base.Request.Form.ContainsKey("IsActive"))
{
product.IsActive = false;
}
if (!base.Request.Form.ContainsKey("IsFeatured"))
{
product.IsFeatured = false;
}
if (!base.Request.Form.ContainsKey("IsTopSeller"))
{
product.IsTopSeller = false;
}
Product existingProduct = await _pgService.GetByIdAsync<Product>(_productsCollection, id);
if (existingProduct == null)
{
base.TempData["ErrorMessage"] = "Product not found.";
return RedirectToAction("Index");
}
existingProduct.Name = product.Name;
existingProduct.ShortDescription = product.ShortDescription;
existingProduct.Description = product.Description;
existingProduct.Price = product.Price;
existingProduct.Category = product.Category;
existingProduct.Color = product.Color;
Console.WriteLine("[EDIT] ProductVariantsJson received: '" + (ProductVariantsJson ?? "NULL") + "'");
if (!string.IsNullOrEmpty(ProductVariantsJson))
{
try
{
existingProduct.Variants = JsonSerializer.Deserialize<List<ProductVariant>>(ProductVariantsJson) ?? new List<ProductVariant>();
Console.WriteLine($"[EDIT] Variants deserialized successfully: {existingProduct.Variants.Count} variants");
foreach (ProductVariant variant in existingProduct.Variants)
{
Console.WriteLine($" - {variant.ColorName} ({variant.ColorHex}) with {variant.Images?.Count ?? 0} images, Stock: {variant.StockQuantity}");
}
}
catch (Exception ex2)
{
Console.WriteLine("[EDIT] Error parsing variants: " + ex2.Message);
Console.WriteLine("[EDIT] JSON was: " + ProductVariantsJson);
existingProduct.Variants = new List<ProductVariant>();
}
}
else
{
Console.WriteLine("[EDIT] No variants provided - ProductVariantsJson is null or empty");
existingProduct.Variants = new List<ProductVariant>();
}
existingProduct.Colors = new List<string>();
existingProduct.Color = string.Empty;
existingProduct.StockQuantity = product.StockQuantity;
existingProduct.IsFeatured = product.IsFeatured;
existingProduct.IsTopSeller = product.IsTopSeller;
existingProduct.IsActive = product.IsActive;
existingProduct.UpdatedAt = DateTime.UtcNow;
existingProduct.Slug = _slugService.GenerateSlug(product.Name);
if (base.Request.Form.ContainsKey("Images"))
{
List<string> list = (existingProduct.Images = (from img in base.Request.Form["Images"]
where !string.IsNullOrEmpty(img)
select (img)).ToList());
if (list.Any() && string.IsNullOrEmpty(product.ImageUrl))
{
existingProduct.ImageUrl = list[0] ?? "";
}
}
if (!string.IsNullOrEmpty(product.ImageUrl))
{
existingProduct.ImageUrl = product.ImageUrl;
}
if (!string.IsNullOrEmpty(product.SKU))
{
existingProduct.SKU = product.SKU;
}
if (product.CostPrice > 0m)
{
existingProduct.CostPrice = product.CostPrice;
}
try
{
await _pgService.UpdateAsync(_productsCollection, id, existingProduct);
base.TempData["SuccessMessage"] = "Product updated successfully!";
return RedirectToAction("Index");
}
catch (Exception ex3)
{
Console.WriteLine("[EDIT] Database Error: " + ex3.Message);
Console.WriteLine("[EDIT] Stack: " + ex3.StackTrace);
base.TempData["ErrorMessage"] = "Error saving product changes: " + ex3.Message;
return View("Create", existingProduct);
}
}
[HttpPost("delete/{id}")]
public async Task<IActionResult> Delete(string id)
{
await _pgService.DeleteAsync<Product>(_productsCollection, id);
base.TempData["SuccessMessage"] = "Product deleted successfully!";
return RedirectToAction("Index");
}
}