From 41c56aa13c70919c762307c947d50001c9fe8f2f Mon Sep 17 00:00:00 2001 From: Olukeye Date: Tue, 13 Feb 2024 23:35:19 +0100 Subject: [PATCH] Implemented Product api and client side product integration. --- .../Controllers/CouponController.cs | 24 +- .../Controllers/ProductController.cs | 95 +++++++ JendStore.Client/Models/ProductDto.cs | 17 ++ JendStore.Client/Program.cs | 2 + .../Service/IService/IProductService.cs | 13 + JendStore.Client/Service/ProductService.cs | 63 +++++ JendStore.Client/Utilities/HttpVerbs.cs | 1 + .../Views/Product/ProductIndex.cshtml | 2 + JendStore.Client/appsettings.json | 1 + .../Controllers/ProductController.cs | 251 +++++++++--------- .../Properties/launchSettings.json | 2 +- .../Controllers/CouponController.cs | 30 +-- 12 files changed, 359 insertions(+), 142 deletions(-) create mode 100644 JendStore.Client/Controllers/ProductController.cs create mode 100644 JendStore.Client/Models/ProductDto.cs create mode 100644 JendStore.Client/Service/IService/IProductService.cs create mode 100644 JendStore.Client/Service/ProductService.cs create mode 100644 JendStore.Client/Views/Product/ProductIndex.cshtml diff --git a/JendStore.Client/Controllers/CouponController.cs b/JendStore.Client/Controllers/CouponController.cs index 2d2123f..270a310 100644 --- a/JendStore.Client/Controllers/CouponController.cs +++ b/JendStore.Client/Controllers/CouponController.cs @@ -24,6 +24,10 @@ public async Task CouponIndex() { list = JsonConvert.DeserializeObject>(Convert.ToString(response.Result)); } + else + { + TempData["success"] = response?.Message; + } return View(list); } @@ -43,6 +47,10 @@ public async Task CreateCoupon(CouponDTO create) { return RedirectToAction(nameof(CouponIndex)); } + else + { + TempData["success"] = response?.Message; + } } return View(create); } @@ -57,6 +65,10 @@ public async Task DeleteCoupon(int couponId) CouponDTO? model = JsonConvert.DeserializeObject(Convert.ToString(response.Result)); return View(model); } + else + { + TempData["success"] = response?.Message; + } return NotFound(); } @@ -65,10 +77,14 @@ public async Task DeleteCoupon(CouponDTO couponDTO) { ResponsDto? response = await _couponService.DeleteCouponAsync(couponDTO.CouponId); - if (response != null && response.IsSuccess) - { - return RedirectToAction(nameof(CouponIndex)); - } + if (response != null && response.IsSuccess) + { + return RedirectToAction(nameof(CouponIndex)); + } + else + { + TempData["success"] = response?.Message; + } return View(couponDTO); } diff --git a/JendStore.Client/Controllers/ProductController.cs b/JendStore.Client/Controllers/ProductController.cs new file mode 100644 index 0000000..018510c --- /dev/null +++ b/JendStore.Client/Controllers/ProductController.cs @@ -0,0 +1,95 @@ +using JendStore.Client.Models; +using JendStore.Client.Service.IService; +using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; + +namespace JendStore.Client.Controllers +{ + public class ProductController : Controller + { + private readonly IProductService _productService; + + public ProductController(IProductService productService) + { + _productService = productService; + } + + public async Task ProductIndex() + { + List? list = new(); + + ResponsDto? response = await _productService.GetAllProductAsync(); + + if (response != null && response.IsSuccess) + { + list = JsonConvert.DeserializeObject>(Convert.ToString(response.Result)); + } + else + { + TempData["success"] = response?.Message; + } + + return View(list); + } + + public async Task CreateProduct() + { + return View(); + } + + [HttpPost] + public async Task CreateProduct(ProductDto create) + { + if (ModelState.IsValid) + { + ResponsDto? response = await _productService.CreateProductAsync(create); + + if (response != null && response.IsSuccess) + { + return RedirectToAction(nameof(ProductIndex)); + } + else + { + TempData["success"] = response?.Message; + } + } + return View(create); + } + + public async Task DeleteProduct(int productDto) + { + + ResponsDto? response = await _productService.GetProductAsync(productDto); + + if (response != null && response.IsSuccess) + { + ProductDto? model = JsonConvert.DeserializeObject(Convert.ToString(response.Result)); + return View(model); + } + else + { + TempData["success"] = response?.Message; + } + + return NotFound(); + } + + [HttpPost] + public async Task DeleteProduct(ProductDto productDto) + { + ResponsDto? response = await _productService.DeleteProductAsync(productDto.ProductId); + + if (response != null && response.IsSuccess) + { + TempData["success"] = "Registration Successful"; + return RedirectToAction(nameof(ProductIndex)); + } + else + { + TempData["success"] = response?.Message; + } + + return View(productDto); + } + } +} diff --git a/JendStore.Client/Models/ProductDto.cs b/JendStore.Client/Models/ProductDto.cs new file mode 100644 index 0000000..d1c0b4f --- /dev/null +++ b/JendStore.Client/Models/ProductDto.cs @@ -0,0 +1,17 @@ +namespace JendStore.Client.Models +{ + public class ProductDto + { + public int ProductId { get; set; } + + public string Name { get; set; } + + public double Price { get; set; } + + public string Description { get; set; } + + public string CategoryName { get; set; } + + public string ImageUrl { get; set; } + } +} diff --git a/JendStore.Client/Program.cs b/JendStore.Client/Program.cs index 1f6a622..0925759 100644 --- a/JendStore.Client/Program.cs +++ b/JendStore.Client/Program.cs @@ -14,6 +14,7 @@ builder.Services.AddHttpContextAccessor(); builder.Services.AddHttpClient(); builder.Services.AddHttpClient(); +builder.Services.AddHttpClient(); builder.Services.AddHttpClient(); HttpVerbs.CouponAPIBase = builder.Configuration["ServiceUrls:CouponAPI"]; HttpVerbs.AuthAPIBase = builder.Configuration["ServiceUrls:AuthAPI"]; @@ -21,6 +22,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options => diff --git a/JendStore.Client/Service/IService/IProductService.cs b/JendStore.Client/Service/IService/IProductService.cs new file mode 100644 index 0000000..2d791b6 --- /dev/null +++ b/JendStore.Client/Service/IService/IProductService.cs @@ -0,0 +1,13 @@ +using JendStore.Client.Models; + +namespace JendStore.Client.Service.IService +{ + public interface IProductService + { + Task GetAllProductAsync(); + Task GetProductAsync(int id); + Task UpdateProductAsync(int id); + Task CreateProductAsync(ProductDto productDto); + Task DeleteProductAsync(int id); + } +} diff --git a/JendStore.Client/Service/ProductService.cs b/JendStore.Client/Service/ProductService.cs new file mode 100644 index 0000000..5b3ebb8 --- /dev/null +++ b/JendStore.Client/Service/ProductService.cs @@ -0,0 +1,63 @@ +using JendStore.Client.Models; +using JendStore.Client.Service.IService; +using JendStore.Client.Sevice.IService; +using JendStore.Client.Utilities; + +namespace JendStore.Client.Service +{ + public class ProductService: IProductService + { + private readonly IBaseService _baseService; + public ProductService(IBaseService baseService) + { + _baseService = baseService; + } + + + public async Task GetAllProductAsync() + { + return await _baseService.SendAsync(new RequestDto() + { + ApiType = HttpVerbs.ApiType.GET, + Url = HttpVerbs.ProductAPIBase + "/api/product" + }); + } + + public async Task CreateProductAsync(ProductDto productDto) + { + return await _baseService.SendAsync(new RequestDto() + { + ApiType = HttpVerbs.ApiType.POST, + Data = productDto, + Url = HttpVerbs.ProductAPIBase + "/api/product" + }); + } + + public async Task GetProductAsync(int id) + { + return await _baseService.SendAsync(new RequestDto() + { + ApiType = HttpVerbs.ApiType.GET, + Url = HttpVerbs.ProductAPIBase + "/api/product/" + id + }); + } + + public async Task UpdateProductAsync(int id) + { + return await _baseService.SendAsync(new RequestDto() + { + ApiType = HttpVerbs.ApiType.PUT, + Url = HttpVerbs.ProductAPIBase + "/api/product/" + id + }); + } + + public async Task DeleteProductAsync(int id) + { + return await _baseService.SendAsync(new RequestDto() + { + ApiType = HttpVerbs.ApiType.DELETE, + Url = HttpVerbs.ProductAPIBase + "/api/product/" + id + }); + } + } +} diff --git a/JendStore.Client/Utilities/HttpVerbs.cs b/JendStore.Client/Utilities/HttpVerbs.cs index 0438b14..8160584 100644 --- a/JendStore.Client/Utilities/HttpVerbs.cs +++ b/JendStore.Client/Utilities/HttpVerbs.cs @@ -3,6 +3,7 @@ public class HttpVerbs { public static string CouponAPIBase{get; set;} + public static string ProductAPIBase { get; set; } public static string AuthAPIBase{ get; set; } public const string RoleAdmin = "ADMIN"; public const string RoleUser = "USER"; diff --git a/JendStore.Client/Views/Product/ProductIndex.cshtml b/JendStore.Client/Views/Product/ProductIndex.cshtml new file mode 100644 index 0000000..1eef66b --- /dev/null +++ b/JendStore.Client/Views/Product/ProductIndex.cshtml @@ -0,0 +1,2 @@ +@* +*@ diff --git a/JendStore.Client/appsettings.json b/JendStore.Client/appsettings.json index 1eccf32..d5cb0e9 100644 --- a/JendStore.Client/appsettings.json +++ b/JendStore.Client/appsettings.json @@ -8,6 +8,7 @@ "AllowedHosts": "*", "ServiceUrls": { "CouponAPI": "https://localhost:2001", + "ProductAPI": "https://localhost:2004", "AuthAPI": "https://localhost:2003" } } diff --git a/JendStore.Products.Service.API/Controllers/ProductController.cs b/JendStore.Products.Service.API/Controllers/ProductController.cs index 013a260..ae5468a 100644 --- a/JendStore.Products.Service.API/Controllers/ProductController.cs +++ b/JendStore.Products.Service.API/Controllers/ProductController.cs @@ -1,120 +1,131 @@ -//using AutoMapper; -//using JendStore.Products.Service.API.DTO; -//using JendStore.Products.Service.API.Models; -//using JendStore.Products.Service.API.Repository.Interface; -//using JendStore.PRoducts.Service.API.DTO; -//using Microsoft.AspNetCore.Authorization; -//using Microsoft.AspNetCore.Mvc; - -//namespace JendStore.Products.Service.API.Controllers -//{ -// [Route("api/product")] -// [ApiController] -// public class ProductController : ControllerBase -// { -// private readonly IUnitOfWork _unitOfWork; -// private readonly IMapper _mapper; -// private readonly ILogger _logger; -// protected ResponseDTOStatus _response; - -// public ProductController(IUnitOfWork unitOfWork, IMapper mapper, ILogger logger) -// { -// _unitOfWork = unitOfWork; -// _mapper = mapper; -// _logger = logger; -// _response = new(); -// } - -// [HttpGet] -// public async Task Get() -// { -// var product = await _unitOfWork.Products.GetAll(); -// _response.Result = _mapper.Map>(product); - -// return Ok(_response); -// } - -// [HttpGet("{productId:int}")] -// public async Task Get(int productId) -// { -// try -// { -// if (!ModelState.IsValid) -// { -// _response.Result = ModelState; -// } - -// var product = await _unitOfWork.Products.Get(c => c.ProductId == productId); - -// _response.Result = _mapper.Map(product); - -// } -// catch (Exception ex) -// { -// _response.IsSuccess = false; -// _response.Message = ex.Message; -// } - -// return Ok(_response); -// } - -// [HttpPost] -// public async Task Post([FromBody] CreateProductDto createDto) -// { -// try -// { -// if (!ModelState.IsValid) -// { -// _logger.LogError($"Invalid Post Action in {nameof(Post)}"); -// _response.Result = ModelState; -// } -// //var product = _mapper.Map(createDto); - -// //await _unitOfWork.Products.Insert(product); - -// await _unitOfWork.Save(); - -// //_response.Result = product; - -// } -// catch (Exception ex) -// { -// _response.IsSuccess = false; -// _response.Message = ex.Message; -// } -// return Ok(_response); -// } - -// [HttpPut("{productId:int}")] -// public async Task Put(int productId, [FromBody] UpdateProduct update) -// { -// try -// { -// if (!ModelState.IsValid && productId < 1) -// { -// _logger.LogError($"Invalid Update Action in {nameof(Put)}"); -// _response.Result = ModelState; -// } - -// var product = await _unitOfWork.Products.Get(c => c.ProductId == productId); - -// if (product == null) -// { -// _logger.LogError($"Invalid action in {nameof(Put)}"); -// } - -// var result = _mapper.Map(update, product); -// _unitOfWork.Products.Update(product); -// await _unitOfWork.Save(); - -// _response.Result = result; -// } -// catch (Exception ex) -// { -// _response.IsSuccess = false; -// _response.Message = ex.Message; -// } -// return Ok(_response); -// } -// } -//} \ No newline at end of file +using AutoMapper; +using JendStore.Products.Service.API.DTO; +using JendStore.Products.Service.API.Models; +using JendStore.Products.Service.API.Repository.Interface; +using JendStore.PRoducts.Service.API.DTO; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace JendStore.Products.Service.API.Controllers +{ + [Route("api/product")] + [ApiController] + public class ProductController : ControllerBase + { + private readonly IUnitOfWork _unitOfWork; + private readonly IMapper _mapper; + private readonly ILogger _logger; + protected ResponseDTOStatus _response; + + public ProductController(IUnitOfWork unitOfWork, IMapper mapper, ILogger logger) + { + _unitOfWork = unitOfWork; + _mapper = mapper; + _logger = logger; + _response = new(); + } + + [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task Get() + { + var product = await _unitOfWork.Products.GetAll(); + _response.Result = _mapper.Map>(product); + + return Ok(_response); + } + + [HttpGet("{productId:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task Get(int productId) + { + var product = await _unitOfWork.Products.Get(c => c.ProductId == productId); + _response.Result = _mapper.Map(product); + + return Ok(_response); + } + + [HttpPost] + [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task Post([FromBody] CreateProductDto createDto) + { + if (!ModelState.IsValid) + { + _logger.LogError($"Invalid Post Action in {nameof(Post)}"); + _response.Result = ModelState; + } + var product = _mapper.Map(createDto); + + await _unitOfWork.Products.Insert(product); + + await _unitOfWork.Save(); + + _response.Result = product; + + return Ok(_response); + } + + [HttpPut("{productId:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task Put(int productId, [FromBody] UpdateProduct update) + { + if (!ModelState.IsValid && productId < 1) + { + _logger.LogError($"Invalid Update Action in {nameof(Put)}"); + return BadRequest(ModelState); + } + + var product = await _unitOfWork.Products.Get(c => c.ProductId == productId); + + if (product == null) + { + _logger.LogError($"Invalid action in {nameof(Put)}"); + return BadRequest("Wrong Data Submitted"); + } + + var result = _mapper.Map(update, product); + _unitOfWork.Products.Update(product); + await _unitOfWork.Save(); + + _response.Result = result; + + return Ok(_response); + + } + + [HttpDelete("{productId:int}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task Delete(int productId) + { + if (!ModelState.IsValid && productId < 1) + { + _logger.LogError($"Invalid Update Action in {nameof(Delete)}"); + return BadRequest(ModelState); + } + + var product = await _unitOfWork.Products.Get(c => c.ProductId == productId); + + if (product == null) + { + _logger.LogError($"Invalid action in {nameof(Delete)}"); + return BadRequest("Wrong Data Submitted"); + } + + await _unitOfWork.Products.Delete(productId); + await _unitOfWork.Save(); + + return Ok(_response); + + } + } +} \ No newline at end of file diff --git a/JendStore.Products.Service.API/Properties/launchSettings.json b/JendStore.Products.Service.API/Properties/launchSettings.json index c983bc6..2201fdd 100644 --- a/JendStore.Products.Service.API/Properties/launchSettings.json +++ b/JendStore.Products.Service.API/Properties/launchSettings.json @@ -24,7 +24,7 @@ "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "swagger", - "applicationUrl": "https://localhost:7144;http://localhost:5230", + "applicationUrl": "https://localhost:2004;http://localhost:5230", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/JendStore.Services.API/Controllers/CouponController.cs b/JendStore.Services.API/Controllers/CouponController.cs index 8d63eb6..fc1692f 100644 --- a/JendStore.Services.API/Controllers/CouponController.cs +++ b/JendStore.Services.API/Controllers/CouponController.cs @@ -27,6 +27,9 @@ public CouponController(IUnitOfWork unitOfWork, ILogger logger } [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task Get() { var coupon = await _unitOfWork.Coupons.GetAll(); @@ -37,30 +40,23 @@ public async Task Get() } [HttpGet("{couponId:int}")] - public async Task Get(int couponId) + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task Get(int couponId) { - try - { - if (!ModelState.IsValid) - { - _response.Result = ModelState; - } - - var coupon = await _unitOfWork.Coupons.Get(c => c.CouponId == couponId); - - _response.Result = _mapper.Map(coupon); - - } - catch (Exception ex) + var coupon = await _unitOfWork.Coupons.Get(c => c.CouponId == couponId); + if (coupon == null) { + _logger.LogError($"Invalid action in {nameof(Get)}"); _response.IsSuccess = false; - _response.Message = ex.Message; + _response.Message = "coupon Id is Invalid"; } - return Ok(_response); + _response.Result = _mapper.Map(coupon); + return _response; } - [HttpGet("code/{code}")] public async Task GetCode(string code) {