diff --git a/src/app/Repositories/IProductsRepository.cs b/src/app/Repositories/IProductsRepository.cs index 88c4869..06febfc 100644 --- a/src/app/Repositories/IProductsRepository.cs +++ b/src/app/Repositories/IProductsRepository.cs @@ -6,4 +6,6 @@ public interface IProductsRepository { IReadOnlyCollection GetAll(); Product? GetById(int Id); + void Add(Product product); + void Delete(int id); } diff --git a/src/app/Services/OrderService.cs b/src/app/Services/OrderService.cs index b707607..ddb8c6f 100644 --- a/src/app/Services/OrderService.cs +++ b/src/app/Services/OrderService.cs @@ -1,6 +1,7 @@ using app.Repositories; using models; + namespace app.Services; public sealed class OrderService @@ -26,20 +27,53 @@ public IReadOnlyCollection GetAll() return _orderRepository.GetAll(); } - public Task ProcessOrderAsync(int orderId) + public async Task ProcessOrderAsync(int orderId) + { + try { // Asynchronously process the order - // Simulates a long CPU bound calculation - // TODO: Retrieve the order with the corresponding Id from the repository - Thread.Sleep(1400); - // TODO: Change the status of this order - throw new NotImplementedException(); + await Task.Delay(1400); // Simule un traitement asynchrone + + // TODO: Retrieve the order with the corresponding Id from the repository +#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. + Order order = _orderRepository.GetById(orderId); +#pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type. + + if (order != null) + { + // TODO: Change the status of this order + order.ChangeOrderStatus(true); + + // Notify that the order has been processed + // OrderProcessed?.Invoke(order); + } + else + { + Console.WriteLine($"Order with Id {orderId} not found."); + } + } + catch (Exception ex) + { + // Handle exceptions appropriately + Console.WriteLine($"Error processing order: {ex.Message}"); + } + //throw new NotImplementedException(); } private void HandleOrderProcessed(Order order) { // Notify the user that an order has been processed - // TODO: Write the order informations to the console - throw new NotImplementedException(); - } + Console.WriteLine($"Order {order.Id} has been processed successfully!"); + Console.WriteLine($"Total Price: {order.TotalPrice:C}"); + Console.WriteLine("Ordered Products:"); + + foreach (var product in order.Products) + { + Console.WriteLine($" - {product.Name} ({product.Price:C})"); + } + + Console.WriteLine("___________________________________________"); + // TODO: Write the order informations to the console + //throw new NotImplementedException(); + } } diff --git a/src/app/Services/ProductService.cs b/src/app/Services/ProductService.cs index 91b239c..35e8328 100644 --- a/src/app/Services/ProductService.cs +++ b/src/app/Services/ProductService.cs @@ -3,9 +3,15 @@ namespace app.Services; -public class ProductService(IProductsRepository productsRepository) +public class ProductService { - private readonly IProductsRepository _productsRepository = productsRepository; + private readonly IProductsRepository _productsRepository; + + // Constructeur pour injecter le repository nécessaire lors de la création d'une instance de ProductService. + public ProductService(IProductsRepository productsRepository) + { + _productsRepository = productsRepository; + } public IReadOnlyCollection GetAll() { @@ -15,4 +21,13 @@ public IReadOnlyCollection GetAll() { return _productsRepository.GetById(Id); } + public void AddProduct(Product product) + { + _productsRepository.Add(product); + } + + public void DeleteProduct(int id) + { + _productsRepository.Delete(id); + } } diff --git a/src/lib/Repositories/OrderRepository.cs b/src/lib/Repositories/OrderRepository.cs index bf98970..340f121 100644 --- a/src/lib/Repositories/OrderRepository.cs +++ b/src/lib/Repositories/OrderRepository.cs @@ -3,7 +3,7 @@ namespace lib.Repositories; -internal class OrderRepository : IOrderRepository +public class OrderRepository : IOrderRepository { private readonly List _orders = []; public event Action OrderProcessed; @@ -22,18 +22,21 @@ public OrderRepository(IEnumerable orders) public IReadOnlyCollection GetAll() { // TODO: Implement the logic that returns all the registered orders - throw new NotImplementedException(); + return _orders.AsReadOnly(); + //throw new NotImplementedException(); } public Order? GetById(int id) { // TODO: Return the first or default order that matches the id - throw new NotImplementedException(); + return _orders.Find(p => p.Id == id); + // throw new NotImplementedException(); } public void Add(Order order) { - // TODO: Add the logic to processed the order and save it into the list of orders + _orders.Add(order); + OrderProcessed?.Invoke(order); } } diff --git a/src/lib/Repositories/ProductsRepository.cs b/src/lib/Repositories/ProductsRepository.cs index 2e75bee..6f3f891 100644 --- a/src/lib/Repositories/ProductsRepository.cs +++ b/src/lib/Repositories/ProductsRepository.cs @@ -3,7 +3,7 @@ namespace lib.Repositories.Concrete; -internal class ProductsRepository(IEnumerable products) +public class ProductsRepository(IEnumerable products) : IProductsRepository { private readonly List _products = products.ToList(); @@ -11,12 +11,28 @@ internal class ProductsRepository(IEnumerable products) public IReadOnlyCollection GetAll() { // TODO: Return all the products from the list - throw new NotImplementedException(); + return _products.AsReadOnly(); + // throw new NotImplementedException(); } public Product? GetById(int Id) { // TODO: Retrieve a single product or default from the _products database by its Id - throw new NotImplementedException(); + return _products.Find(p => p.Id == Id); + // throw new NotImplementedException(); } + + // Implémentation de la méthode Add + public void Add(Product product) + { + _products.Add(product); + } + + // Implémentation de la méthode Delete + public void Delete(int id) + { + var productToDelete = _products.Find(p => p.Id == id); + if (productToDelete != null) + _products.Remove(productToDelete); + } } diff --git a/src/models/Order.cs b/src/models/Order.cs index 946a3ca..4f98809 100644 --- a/src/models/Order.cs +++ b/src/models/Order.cs @@ -1,28 +1,53 @@ -namespace models; +using System; +using System.Collections.Generic; +using System.Linq; -public sealed class Order + +namespace models { - private static int _count = 0; - private readonly List _products = []; - public int Id { get; private init; } = ++_count; - public bool Processed { get; private set; } - public IReadOnlyList Products => _products.ToArray(); - public decimal TotalPrice => Products.Sum(p => p.Price); - public void AddProduct(Product product) + public sealed class Order { - // TODO: Implement the method that adds a product to this order - throw new NotImplementedException(); - } + private static int _count = 0; + private readonly List _products = new List(); + // private readonly List _products = []; + public int Id { get; private init; } = ++_count; + public bool Processed { get; private set; } + public IReadOnlyList Products => _products.ToArray(); + public decimal TotalPrice => Products.Sum(p => p.Price); - public void RemoveProduct(int id) - { - // TODO: Implement the method that removes a specific product from the order based on its Id - throw new NotImplementedException(); - } + public void AddProduct(Product product) + { + if (product == null) + { + throw new ArgumentNullException(nameof(product), "Product cannot be null"); + } + _products.Add(product); + // throw new NotImplementedException(); + } - public void ChangeOrderStatus(bool status) - { - Processed = status; + public void RemoveProduct(int id) + { +#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. + Product productToRemove = _products.FirstOrDefault(p => p.Id == id); +#pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type. + + if (productToRemove != null) + { + _products.Remove(productToRemove); + } + else + { + throw new ArgumentException($"Product with Id {id} not found in the order.", nameof(id)); + } + + + // throw new NotImplementedException(); + } + + public void ChangeOrderStatus(bool status) + { + Processed = status; + } } -} +} \ No newline at end of file diff --git a/src/ui/Features/AddProduct.cs b/src/ui/Features/AddProduct.cs new file mode 100644 index 0000000..f8ac074 --- /dev/null +++ b/src/ui/Features/AddProduct.cs @@ -0,0 +1,35 @@ +using app.Services; +using Microsoft.Extensions.DependencyInjection; +using models; +using ui.Utilities; + +namespace ui.Features +{ + internal static partial class Feature + { + // Méthode pour créer un nouveau produit. + public static Task CreateProduct(IServiceProvider sp) + { + var productService = sp.GetRequiredService(); + + Console.Write("Enter the name of the new product: "); + var name = Console.ReadLine(); + + Console.Write("Enter the price of the new product: "); + if (!decimal.TryParse(Console.ReadLine(), out decimal price)) + { + Display.WriteError("Invalid price. Retry after 1s ..."); + Thread.Sleep(1000); + return Task.FromResult(false); + } + +#pragma warning disable CS8604 // Possible null reference argument. + var newProduct = new Product(name, price); +#pragma warning restore CS8604 // Possible null reference argument. + productService.AddProduct(newProduct); + + Console.WriteLine($"New product created successfully. Id: {newProduct.Id}"); + return Task.FromResult(false); + } + } +} diff --git a/src/ui/Features/DeleteProduct.cs b/src/ui/Features/DeleteProduct.cs new file mode 100644 index 0000000..38ee3ea --- /dev/null +++ b/src/ui/Features/DeleteProduct.cs @@ -0,0 +1,37 @@ +using app.Services; +using Microsoft.Extensions.DependencyInjection; +using ui.Utilities; + +namespace ui.Features +{ + internal static partial class Feature + { + // Méthode pour supprimer un produit existant. + public static Task DeleteProduct(IServiceProvider sp) + { + var productService = sp.GetRequiredService(); + + Console.Write("Enter the Id of the product you want to delete: "); + if (!int.TryParse(Console.ReadLine(), out int productId)) + { + Display.WriteError("Invalid Id. Retry after 1s ..."); + Thread.Sleep(1000); + return Task.FromResult(false); + } + + var existingProduct = productService.GetById(productId); + if (existingProduct is null) + { + Display.WriteError($"Product with Id {productId} does not exist. Retry after 1s ..."); + Thread.Sleep(1000); + return Task.FromResult(false); + } + + productService.DeleteProduct(existingProduct.Id); + + Console.WriteLine($"Product with Id {productId} deleted successfully."); + + return Task.FromResult(false); + } + } +} diff --git a/src/ui/Program.cs b/src/ui/Program.cs index ffe4689..e137b5d 100644 --- a/src/ui/Program.cs +++ b/src/ui/Program.cs @@ -17,7 +17,9 @@ private static readonly Dictionary< { 1, ("See all products", Feature.ViewProducts) }, { 2, ("Make an order", Feature.MakeOrder) }, { 3, ("See all orders", Feature.ViewOrders) }, - { 4, ("Quit", Feature.Exit) }, + { 4, ("CreateProduct", Feature.CreateProduct) }, + { 5, ("DeleteProduct", Feature.DeleteProduct) }, + { 6, ("Quit", Feature.Exit) }, }; private static readonly (int, string)[] _options = _features