using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using LittleShop.Services; using LittleShop.DTOs; namespace LittleShop.Areas.Admin.Controllers; [Area("Admin")] [Authorize(Policy = "AdminOnly")] public class OrdersController : Controller { private readonly IOrderService _orderService; public OrdersController(IOrderService orderService) { _orderService = orderService; } public async Task Index(string tab = "accept") { ViewData["CurrentTab"] = tab; switch (tab.ToLower()) { case "pending": ViewData["Orders"] = await _orderService.GetOrdersByStatusAsync(LittleShop.Enums.OrderStatus.PendingPayment); ViewData["TabTitle"] = "Pending Payment"; break; case "accept": ViewData["Orders"] = await _orderService.GetOrdersRequiringActionAsync(); ViewData["TabTitle"] = "Orders to Accept"; break; case "packing": ViewData["Orders"] = await _orderService.GetOrdersForPackingAsync(); ViewData["TabTitle"] = "Orders for Packing"; break; case "dispatched": ViewData["Orders"] = await _orderService.GetOrdersByStatusAsync(LittleShop.Enums.OrderStatus.Dispatched); ViewData["TabTitle"] = "Dispatched Orders"; break; case "delivered": ViewData["Orders"] = await _orderService.GetOrdersByStatusAsync(LittleShop.Enums.OrderStatus.Delivered); ViewData["TabTitle"] = "Delivered Orders"; break; case "onhold": ViewData["Orders"] = await _orderService.GetOrdersOnHoldAsync(); ViewData["TabTitle"] = "Orders On Hold"; break; case "cancelled": ViewData["Orders"] = await _orderService.GetOrdersByStatusAsync(LittleShop.Enums.OrderStatus.Cancelled); ViewData["TabTitle"] = "Cancelled Orders"; break; default: ViewData["Orders"] = await _orderService.GetAllOrdersAsync(); ViewData["TabTitle"] = "All Orders"; break; } // Get workflow counts for tab badges ViewData["PendingCount"] = (await _orderService.GetOrdersByStatusAsync(LittleShop.Enums.OrderStatus.PendingPayment)).Count(); ViewData["AcceptCount"] = (await _orderService.GetOrdersRequiringActionAsync()).Count(); ViewData["PackingCount"] = (await _orderService.GetOrdersForPackingAsync()).Count(); ViewData["DispatchedCount"] = (await _orderService.GetOrdersByStatusAsync(LittleShop.Enums.OrderStatus.Dispatched)).Count(); ViewData["OnHoldCount"] = (await _orderService.GetOrdersOnHoldAsync()).Count(); return View(); } public async Task Details(Guid id) { var order = await _orderService.GetOrderByIdAsync(id); if (order == null) { return NotFound(); } return View(order); } public IActionResult Create() { return View(new CreateOrderDto()); } [HttpPost] [ValidateAntiForgeryToken] public async Task Create(CreateOrderDto model) { if (!ModelState.IsValid) { return View(model); } var order = await _orderService.CreateOrderAsync(model); return RedirectToAction(nameof(Details), new { id = order.Id }); } public async Task Edit(Guid id) { var order = await _orderService.GetOrderByIdAsync(id); if (order == null) { return NotFound(); } return View(order); } [HttpPost] [ValidateAntiForgeryToken] public async Task Edit(Guid id, OrderDto model) { if (!ModelState.IsValid) { return View(model); } var updateDto = new UpdateOrderStatusDto { Status = model.Status, TrackingNumber = model.TrackingNumber, Notes = model.Notes }; var success = await _orderService.UpdateOrderStatusAsync(id, updateDto); if (!success) { return NotFound(); } return RedirectToAction(nameof(Details), new { id }); } [HttpPost] [ValidateAntiForgeryToken] public async Task UpdateStatus(Guid id, UpdateOrderStatusDto model) { var success = await _orderService.UpdateOrderStatusAsync(id, model); if (!success) { return NotFound(); } return RedirectToAction(nameof(Details), new { id }); } // Workflow action methods [HttpPost] [ValidateAntiForgeryToken] public async Task AcceptOrder(Guid id, string? notes) { var userName = User.Identity?.Name ?? "Unknown"; var acceptDto = new AcceptOrderDto { Notes = notes }; var success = await _orderService.AcceptOrderAsync(id, userName, acceptDto); if (!success) { TempData["Error"] = "Could not accept order. Check order status."; } else { TempData["Success"] = "Order accepted successfully."; } return RedirectToAction(nameof(Details), new { id }); } [HttpPost] [ValidateAntiForgeryToken] public async Task StartPacking(Guid id, string? notes) { var userName = User.Identity?.Name ?? "Unknown"; var packingDto = new StartPackingDto { Notes = notes }; var success = await _orderService.StartPackingAsync(id, userName, packingDto); if (!success) { TempData["Error"] = "Could not start packing. Check order status."; } else { TempData["Success"] = "Packing started successfully."; } return RedirectToAction(nameof(Details), new { id }); } [HttpPost] [ValidateAntiForgeryToken] public async Task DispatchOrder(Guid id, string trackingNumber, int estimatedDays = 3, string? notes = null) { var userName = User.Identity?.Name ?? "Unknown"; var dispatchDto = new DispatchOrderDto { TrackingNumber = trackingNumber, EstimatedDeliveryDays = estimatedDays, Notes = notes }; var success = await _orderService.DispatchOrderAsync(id, userName, dispatchDto); if (!success) { TempData["Error"] = "Could not dispatch order. Check order status."; } else { TempData["Success"] = $"Order dispatched with tracking {trackingNumber}."; } return RedirectToAction(nameof(Details), new { id }); } [HttpPost] [ValidateAntiForgeryToken] public async Task PutOnHold(Guid id, string reason, string? notes) { var userName = User.Identity?.Name ?? "Unknown"; var holdDto = new PutOnHoldDto { Reason = reason, Notes = notes }; var success = await _orderService.PutOnHoldAsync(id, userName, holdDto); if (!success) { TempData["Error"] = "Could not put order on hold."; } else { TempData["Success"] = "Order put on hold."; } return RedirectToAction(nameof(Details), new { id }); } [HttpPost] [ValidateAntiForgeryToken] public async Task RemoveFromHold(Guid id) { var userName = User.Identity?.Name ?? "Unknown"; var success = await _orderService.RemoveFromHoldAsync(id, userName); if (!success) { TempData["Error"] = "Could not remove order from hold."; } else { TempData["Success"] = "Order removed from hold and returned to workflow."; } return RedirectToAction(nameof(Details), new { id }); } [HttpPost] [ValidateAntiForgeryToken] public async Task MarkDelivered(Guid id, DateTime? actualDeliveryDate, string? notes) { var deliveredDto = new MarkDeliveredDto { ActualDeliveryDate = actualDeliveryDate, Notes = notes }; var success = await _orderService.MarkDeliveredAsync(id, deliveredDto); if (!success) { TempData["Error"] = "Could not mark order as delivered."; } else { TempData["Success"] = "Order marked as delivered."; } return RedirectToAction(nameof(Details), new { id }); } }