//controller using av_motion_api.Data; using av_motion_api.Models; using av_motion_api.ViewModels; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Security.Claims; // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 namespace av_motion_api.Controllers { [Route("api/supplier/[controller]")] [ApiController] public class SupplierController : ControllerBase { private readonly AppDbContext _appContext; private readonly ILogger<SupplierController> _logger; public SupplierController(AppDbContext context, ILogger<SupplierController> logger) { _appContext = context; _logger = logger; } // GET: api/supplier/GetSuppliers [HttpGet] [Route("GetSuppliers")] //[Authorize(Roles = "Administrator")] public async Task<ActionResult<IEnumerable<Supplier>>> GetSuppliers() { var suppliers = await _appContext.Suppliers.ToListAsync(); return suppliers; } // GET: api/supplier/GetSupplier/{id} [HttpGet] [Route("GetSupplier/{id}")] //[Authorize(Roles = "Administrator")] public async Task<ActionResult<Supplier>> GetSupplier(int id) { if (_appContext.Suppliers == null) { return NotFound(); } var supplier = await _appContext.Suppliers.FindAsync(id); if (supplier == null) { return NotFound(); } return supplier; } // POST: api/supplier/PostSupplier [HttpPost] [Route("PostSupplier")] //[Authorize(Roles = "Administrator")] public async Task<ActionResult<Supplier>> PostSupplier([FromBody] Supplier supplier) { if (_appContext.Suppliers == null) { return Problem("Entity set 'AppDbContext.Suppliers' is null."); } var supplierEntity = new Supplier { Name = supplier.Name, Contact_Number = supplier.Contact_Number, Email_Address = supplier.Email_Address, Physical_Address = supplier.Physical_Address, }; _appContext.Suppliers.Add(supplierEntity); await _appContext.SaveChangesAsync(); return Ok(supplier); } // PUT: api/supplier/PutSupplier/{id} [HttpPut] [Route("PutSupplier/{id}")] //[Authorize(Roles = "Administrator")] public async Task<IActionResult> PutSupplier(int id, [FromBody] SupplierViewModel supplier) { var supplierEntity = await _appContext.Suppliers.FindAsync(id); if (supplierEntity == null) { return NotFound(); } supplierEntity.Name = supplier.Name; supplierEntity.Contact_Number = supplier.Contact_Number; supplierEntity.Email_Address = supplier.Email_Address; supplierEntity.Physical_Address = supplier.Physical_Address; try { _appContext.Suppliers.Update(supplierEntity); await _appContext.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!SupplierExists(id)) { return NotFound(); } else { throw; } } return NoContent(); } // DELETE: api/supplier/DeleteSupplier/{id} [HttpDelete] [Route("DeleteSupplier/{id}")] //[Authorize(Roles = "Administrator")] public async Task<IActionResult> DeleteSupplier(int id) { if (_appContext.Suppliers == null) { return NotFound(); } var supplier = await _appContext.Suppliers.FindAsync(id); if (supplier == null) { return NotFound(); } _appContext.Suppliers.Remove(supplier); await _appContext.SaveChangesAsync(); return NoContent(); } private bool SupplierExists(int id) { return (_appContext.Suppliers?.Any(e => e.Supplier_ID == id)).GetValueOrDefault(); } // GET: api/supplier/GetAllSupplierOrders [HttpGet] [Route("GetAllSupplierOrders")] //[Authorize(Roles = "Administrator")] public async Task<IActionResult> GetAllSupplierOrders() { var orders = await _appContext.Supplier_Orders .Include(o => o.Supplier) .Include(o => o.Owner) .Include(o => o.Supplier_Order_Lines) .ThenInclude(sol => sol.Product) .ToListAsync(); var supplierOrderViewModels = orders.Select(order => new SupplierOrderViewModel { Supplier_Order_ID = order.Supplier_Order_ID, Date = order.Date, Supplier_ID = order.Supplier_ID, Supplier_Name = order.Supplier.Name, Owner_ID = order.Owner_ID, Status = order.Status, Supplier_Order_Details = order.Supplier_Order_Details, OrderLines = order.Supplier_Order_Lines.Select(sol => new SupplierOrderLineViewModel { Supplier_Order_Line_ID = sol.Supplier_Order_Line_ID, Product_ID = sol.Product_ID, Product_Name = sol.Product.Product_Name, Supplier_Quantity = sol.Supplier_Quantity, Purchase_Price = sol.Purchase_Price }).ToList(), Total_Price = (decimal)order.Supplier_Order_Lines.Sum(sol => sol.Supplier_Quantity * sol.Purchase_Price) }).ToList(); return Ok(supplierOrderViewModels); } // GET: api/supplier/GetSupplierOrderById/{id} [HttpGet] [Route("GetSupplierOrderById/{id}")] //[Authorize(Roles = "Administrator")] public async Task<IActionResult> GetSupplierOrderById(int id) { try { var order = await _appContext.Supplier_Orders .Include(o => o.Supplier) .Include(o => o.Owner) .Include(o => o.Supplier_Order_Lines) .ThenInclude(sol => sol.Product) .FirstOrDefaultAsync(o => o.Supplier_Order_ID == id); if (order == null) { return NotFound("Supplier order not found."); } return Ok(order); } catch (Exception ex) { _logger.LogError(ex, "Error fetching supplier order by ID."); return StatusCode(StatusCodes.Status500InternalServerError, "An error occurred while processing your request."); } } // GET: api/supplier/GetSupplierOrderDetails/{orderId} [HttpGet] [Route("GetSupplierOrderDetails/{orderId}")] public async Task<IActionResult> GetSupplierOrderDetails(int orderId) { try { var orderDetails = await (from sol in _appContext.Supplier_Order_Lines join p in _appContext.Products on sol.Product_ID equals p.Product_ID where sol.Supplier_Order_ID == orderId select new SupplierOrderDetailsViewModel { Supplier_Order_Line_ID = sol.Supplier_Order_Line_ID, Supplier_Order_ID = sol.Supplier_Order_ID, Product_ID = sol.Product_ID, Supplier_Quantity = sol.Supplier_Quantity, Purchase_Price = p.Purchase_Price ?? 0, // Handle nullable Purchase_Price Total_Price = (sol.Supplier_Quantity * (p.Purchase_Price ?? 0)), // Calculate Total_Price Product_Name = p.Product_Name }).ToListAsync(); if (orderDetails == null || orderDetails.Count == 0) { return NotFound("No order details found for the given order ID."); } return Ok(orderDetails); } catch (Exception ex) { _logger.LogError(ex, "Error retrieving supplier order details."); return StatusCode(StatusCodes.Status500InternalServerError, "An error occurred while processing your request."); } } [HttpGet] [Route("GetProductCategories")] public async Task<IActionResult> GetProductCategories() { var categories = await _appContext.Product_Categories.ToListAsync(); return Ok(categories); } // Controller to fetch products by category ID [HttpGet] [Route("GetProductsByCategory/{categoryId}")] public async Task<IActionResult> GetProductsByCategory(int categoryId) { var products = await _appContext.Products.Where(p => p.Product_Category_ID == categoryId).ToListAsync(); return Ok(products); } [HttpPost] [Route("PlaceSupplierOrder")] public async Task<IActionResult> PlaceSupplierOrder([FromBody] SupplierOrderViewModel orderVm) { if (!ModelState.IsValid) { return BadRequest(ModelState); } // Create a new supplier order var supplierOrder = new Supplier_Order { Date = DateTime.UtcNow, Supplier_Order_Details = orderVm.Supplier_Order_Details, Supplier_ID = orderVm.Supplier_ID, Owner_ID = orderVm.Owner_ID, Status = orderVm.Status, Supplier_Order_Lines = new List<Supplier_Order_Line>() }; decimal totalOrderPrice = 0; Console.WriteLine($"Creating Supplier_Order with ID {supplierOrder.Supplier_Order_ID}"); Console.WriteLine($"OrderLines count: {orderVm.OrderLines?.Count ?? 0}"); // Process each order line foreach (var orderLine in orderVm.OrderLines) { // Fetch the product details var product = await _appContext.Products.FindAsync(orderLine.Product_ID); if (product == null) { return BadRequest($"Product with ID {orderLine.Product_ID} not found."); } if (product != null) { var purchasePrice = product.Purchase_Price; if (purchasePrice == null) { return BadRequest($"Purchase price for product ID {orderLine.Product_ID} is not set."); } // Create a new supplier order line var supplierOrderLine = new Supplier_Order_Line { Product_ID = orderLine.Product_ID, Supplier_Quantity = orderLine.Supplier_Quantity, Purchase_Price = purchasePrice // Set the purchase price from product }; // Add the order line to the supplier order supplierOrder.Supplier_Order_Lines.Add(supplierOrderLine); // Calculate total price totalOrderPrice += orderLine.Supplier_Quantity * (decimal)purchasePrice; } Console.WriteLine($"Processing OrderLine: Product_ID = {orderLine.Product_ID}, Quantity = {orderLine.Supplier_Quantity}"); } // Set total price on supplier order supplierOrder.Total_Price = totalOrderPrice; // Save the supplier order to the database _appContext.Supplier_Orders.Add(supplierOrder); await _appContext.SaveChangesAsync(); return Ok(supplierOrder); } // PUT: api/supplier/updateinventory [HttpPut] [Route("updateinventory")] //[Authorize(Roles = "Administrator")] public async Task<IActionResult> UpdateInventory([FromBody] UpdateInventoryViewModel updateInventoryVm) { if (!ModelState.IsValid) { return BadRequest(ModelState); } try { var receivedSupplierOrder = new Received_Supplier_Order { Supplies_Received_Date = updateInventoryVm.Supplies_Received_Date }; _appContext.Received_Supplier_Orders.Add(receivedSupplierOrder); await _appContext.SaveChangesAsync(); foreach (var line in updateInventoryVm.ReceivedOrderLines) { var receivedOrderLine = new Received_Supplier_Order_Line { Received_Supplier_Order_ID = receivedSupplierOrder.Received_Supplier_Order_ID, Received_Supplies_Quantity = line.Received_Supplies_Quantity, Supplier_Order_Line_ID = line.Supplier_Order_Line_ID, }; var product = await _appContext.Products.FindAsync(line.Product_ID); if (product != null) { product.Quantity += line.Received_Supplies_Quantity; _appContext.Products.Update(product); } _appContext.Received_Supplier_Order_Lines.Add(receivedOrderLine); } await _appContext.SaveChangesAsync(); return Ok("Inventory updated successfully."); } catch (Exception ex) { _logger.LogError(ex, "Error updating inventory."); return StatusCode(StatusCodes.Status500InternalServerError, "An error occurred while processing your request."); } } // POST: api/supplier/receivesupplierorder [HttpPost] [Route("receivesupplierorder")] public async Task<IActionResult> ReceiveSupplierOrder([FromBody] ReceivedSupplierOrderViewModel receiveOrderVm) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var receivedSupplierOrder = new Received_Supplier_Order { Supplies_Received_Date = receiveOrderVm.Supplies_Received_Date, Discrepancies = receiveOrderVm.Discrepancies, Accepted = receiveOrderVm.Accepted ?? false, Received_Supplier_Order_Lines = new List<Received_Supplier_Order_Line>() }; _appContext.Received_Supplier_Orders.Add(receivedSupplierOrder); await _appContext.SaveChangesAsync(); if (receivedSupplierOrder.Accepted) { foreach (var line in receiveOrderVm.Received_Supplier_Order_Lines) { var product = await _appContext.Products.FindAsync(line.Product_ID); // Debugging and Logging Console.WriteLine($"Processing Product ID: {line.Product_ID}"); if (product == null) { Console.WriteLine($"Product ID {line.Product_ID} not found."); return BadRequest($"Product ID {line.Product_ID} not found."); } product.Quantity += line.Received_Supplies_Quantity; _appContext.Products.Update(product); var receivedOrderLine = new Received_Supplier_Order_Line { Received_Supplier_Order_ID = receivedSupplierOrder.Received_Supplier_Order_ID, Received_Supplies_Quantity = line.Received_Supplies_Quantity, Supplier_Order_Line_ID = line.Supplier_Order_Line_ID, Product_ID = line.Product_ID // Ensure this is set }; _appContext.Received_Supplier_Order_Lines.Add(receivedOrderLine); } await _appContext.SaveChangesAsync(); } return Ok(receivedSupplierOrder); } [HttpPost] [Route("UpdateSupplierOrderStatus")] public async Task<IActionResult> UpdateSupplierOrderStatus([FromBody] UpdateSupplierOrderStatusViewModel statusUpdateVm) { if (!ModelState.IsValid) { return BadRequest(ModelState); } // Fetch the specific supplier order entry var supplierOrder = await _appContext.Supplier_Orders .FirstOrDefaultAsync(o => o.Supplier_Order_ID == statusUpdateVm.Supplier_Order_ID); if (supplierOrder == null) { return BadRequest($"Supplier order with ID {statusUpdateVm.Supplier_Order_ID} not found."); } // Update the status based on the Accepted boolean supplierOrder.Status = statusUpdateVm.Status; // Ensure this is directly assigned // Save changes to the database await _appContext.SaveChangesAsync(); return Ok(supplierOrder); } } } //models public class Supplier_Order { [Key] public int Supplier_Order_ID { get; set; } //[Required] public DateTime Date { get; set; } //[Required] public string? Supplier_Order_Details { get; set; } //[Required] public decimal Total_Price { get; set; } public int Status { get; set; } public int Supplier_ID { get; set; } [ForeignKey(nameof(Supplier_ID))] public Supplier Supplier { get; set; } public int Owner_ID { get; set; } [ForeignKey(nameof(Owner_ID))] public Owner Owner { get; set; } public ICollection<Supplier_Order_Line> Supplier_Order_Lines { get; set; } } public class Supplier_Order_Line { [Key] public int Supplier_Order_Line_ID { get; set; } public int Supplier_Quantity { get; set; } public int Product_ID { get; set; } [ForeignKey(nameof(Product_ID))] public Product Product { get; set; } public decimal? Purchase_Price { get; set; } public decimal? Unit_Price { get; set; } public int Supplier_Order_ID { get; set; } [ForeignKey(nameof(Supplier_Order_ID))] public Supplier_Order Supplier_Order { get; set; } } public class Received_Supplier_Order { [Key] public int Received_Supplier_Order_ID { get; set; } [Required] public DateTime Supplies_Received_Date { get; set; } public bool Accepted { get; set; } // Indicates if the order was accepted public string? Discrepancies { get; set; } // Nullable attribute for discrepancies public ICollection<Received_Supplier_Order_Line> Received_Supplier_Order_Lines { get; set; } } public class Received_Supplier_Order_Line { [Key] public int Received_Supplier_Order_Line_ID { get; set; } public int Received_Supplier_Order_ID { get; set; } [ForeignKey(nameof(Received_Supplier_Order_ID))] public Received_Supplier_Order Received_Supplier_Order { get; set; } public int Supplier_Order_Line_ID { get; set; } [ForeignKey(nameof(Supplier_Order_Line_ID))] public Supplier_Order_Line Supplier_Order_Line { get; set; } public int Product_ID { get; set; } [ForeignKey(nameof(Product_ID))] public Product Product { get; set; } public int Received_Supplies_Quantity { get; set; } } //viewmodels public class SupplierOrderViewModel { public int Supplier_Order_ID { get; set; } public DateTime Date { get; set; } public string Supplier_Order_Details { get; set; } public decimal Total_Price { get; set; } public int Supplier_ID { get; set; } public string Supplier_Name { get; set; } public int Owner_ID { get; set; } public int Status { get; set; } public ICollection<SupplierOrderLineViewModel> OrderLines { get; set; } } public class SupplierOrderLineViewModel { public int Supplier_Order_Line_ID { get; set; } public int Product_ID { get; set; } public string Product_Name { get; set; } public int Supplier_Quantity { get; set; } public decimal? Purchase_Price { get; set; } } public class UpdateSupplierOrderStatusViewModel { public int Supplier_Order_ID { get; set; } public int Status { get; set; } // Boolean to indicate acceptance/rejection } public class ReceivedSupplierOrderViewModel { public DateTime Supplies_Received_Date { get; set; } public bool? Accepted { get; set; } // Nullable bool to indicate acceptance/rejection public string? Discrepancies { get; set; } // Nullable attribute for discrepancies public List<ReceivedSupplierOrderLineViewModel> Received_Supplier_Order_Lines { get; set; } } public class ReceivedSupplierOrderLineViewModel { public int Product_ID { get; set; } public int Received_Supplies_Quantity { get; set; } public int Supplier_Order_Line_ID { get; set; } }