//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; }
}