diff --git a/webapi/Core/DomainObjects/Documents/BlogItem.cs b/webapi/Core/DomainObjects/Documents/BlogItem.cs index 227b0a0..68ffcc9 100644 --- a/webapi/Core/DomainObjects/Documents/BlogItem.cs +++ b/webapi/Core/DomainObjects/Documents/BlogItem.cs @@ -1,7 +1,7 @@ using Core.Abstractions.DomainObjects; namespace Core.DomainObjects.Documents { - public class BlogItem : PostItemBase { + public class BlogItem : PostItemBase { public uint? ReadTime { get; set; } diff --git a/webapi/DataProviders/BlogCatalogDataProvider.cs b/webapi/DataProviders/BlogCatalogDataProvider.cs index 93d40d0..1d7ac0a 100644 --- a/webapi/DataProviders/BlogCatalogDataProvider.cs +++ b/webapi/DataProviders/BlogCatalogDataProvider.cs @@ -38,7 +38,7 @@ namespace DataProviders { public (BlogItem?, IDomainResult) Get(Guid siteId, string slug) { var (list, result) = GetWithPredicate(x => x.SiteId == siteId && x.L10n.Where(y => y.Slug == slug).Count() > 0, _collectionName); - if (!result.IsSuccess || list == null || list.Count == 0) + if (!result.IsSuccess || list == null) return (null, result); return (list.First(), result); diff --git a/webapi/DataProviders/CategoryDataProvider.cs b/webapi/DataProviders/CategoryDataProvider.cs index 3254c3b..a226f70 100644 --- a/webapi/DataProviders/CategoryDataProvider.cs +++ b/webapi/DataProviders/CategoryDataProvider.cs @@ -1,21 +1,25 @@ -using Core.DomainObjects; -using Core.Enumerations; -using DataProviders.Abstractions; -using DomainResults.Common; -using Microsoft.Extensions.Logging; -using MongoDB.Bson.Serialization; +using Microsoft.Extensions.Logging; + using MongoDB.Driver; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using MongoDB.Bson.Serialization; + +using DomainResults.Common; + +using DataProviders.Abstractions; +using Core.DomainObjects; namespace DataProviders { - public interface ICategoryDataProvider { - (Category?, IDomainResult) Get(Guid id, Guid siteId); + (Guid?, IDomainResult) Insert(Category obj); + (Category?, IDomainResult) Get(Guid siteId, Guid categoryId); + + (Category?, IDomainResult) Get(Guid siteId, List slugs); + + (List?, IDomainResult) GetAll(Guid siteId); + (Guid?, IDomainResult) Update(Category obj); + IDomainResult Delete(Guid id); + IDomainResult DeleteAll(Guid siteId); } public class CategoryDataProvider : DataProviderBase, ICategoryDataProvider { @@ -28,13 +32,46 @@ namespace DataProviders { ISessionService sessionService) : base(logger, client, idGenerator, sessionService) { } - public (Category?, IDomainResult) Get(Guid id, Guid siteId) { - var (list, result) = GetWithPredicate(x => x.Id == id && x.SiteId == siteId, 0, 0, _collectionName); + public (Guid?, IDomainResult) Insert(Category obj) => + Insert(obj, _collectionName); - if (!result.IsSuccess || list == null || list.Count == 0) + public (Category?, IDomainResult) Get(Guid siteId, Guid categoryId) { + var (list, result) = GetWithPredicate(x => x.SiteId == siteId && x.Id == categoryId, _collectionName); + + if (!result.IsSuccess || list == null) return (null, result); return (list.First(), result); } + + public (Category?, IDomainResult) Get(Guid siteId, List slugs) { + var (list, result) = GetWithPredicate(x => x.SiteId == siteId && x.L10n.Any(y => slugs.Contains(y.Slug)), _collectionName); + + if (!result.IsSuccess || list == null) + return (null, result); + + return (list.First(), result); + } + + public (Category?, IDomainResult) Get(Guid siteId, string slug) { + var (list, result) = GetWithPredicate(x => x.SiteId == siteId && x.L10n.Where(x => x.Slug == slug).Count() > 0 , _collectionName); + + if (!result.IsSuccess || list == null) + return (null, result); + + return (list.First(), result); + } + + public (List?, IDomainResult) GetAll(Guid siteId) => + GetWithPredicate(x => x.SiteId == siteId, _collectionName); + + public (Guid?, IDomainResult) Update(Category obj) => + UpdateWithPredicate(obj, x => x.Id == obj.Id, _collectionName); + + public IDomainResult Delete(Guid id) => + DeleteWithPredicate(x => x.Id == id, _collectionName); + + public IDomainResult DeleteAll(Guid siteId) => + DeleteWithPredicate(x => x.SiteId == siteId, _collectionName); } } diff --git a/webapi/DataProviders/ContentDataProvider.cs b/webapi/DataProviders/ContentDataProvider.cs index 75f1ac5..91d0bb4 100644 --- a/webapi/DataProviders/ContentDataProvider.cs +++ b/webapi/DataProviders/ContentDataProvider.cs @@ -25,7 +25,7 @@ namespace DataProviders { var (list, result) = GetWithPredicate(x => x.SiteId == siteId && (x.Localization.Locale == null || x.Localization.Locale.ToLower() == locale.ToLower()), 0, 0, _collectionName); - if (!result.IsSuccess || list == null || list.Count == 0) + if (!result.IsSuccess || list == null) return (null, result); return (list.First(), result); diff --git a/webapi/DataProviders/ShopCartDataProvider.cs b/webapi/DataProviders/ShopCartDataProvider.cs index db0e627..5db259c 100644 --- a/webapi/DataProviders/ShopCartDataProvider.cs +++ b/webapi/DataProviders/ShopCartDataProvider.cs @@ -36,7 +36,7 @@ namespace DataProviders { public (ShopCartItem?, IDomainResult) Get(Guid siteId, Guid userId, string sku) { var (list, result) = GetWithPredicate(x => x.SiteId == siteId && x.UserId == userId && x.Sku == sku, 0, 0, _collectionName); - if (!result.IsSuccess || list == null || list.Count == 0) + if (!result.IsSuccess || list == null) return (null, result); return (list.First(), result); diff --git a/webapi/DataProviders/ShopCatalogDataProvider.cs b/webapi/DataProviders/ShopCatalogDataProvider.cs index c3a5cbe..a150300 100644 --- a/webapi/DataProviders/ShopCatalogDataProvider.cs +++ b/webapi/DataProviders/ShopCatalogDataProvider.cs @@ -35,7 +35,7 @@ namespace DataProviders { public (ShopItem?, IDomainResult) Get(Guid siteId, string sku) { var (list, result) = GetWithPredicate(x => x.SiteId == siteId && x.Sku == sku, _collectionName); - if (!result.IsSuccess || list == null || list.Count == 0) + if (!result.IsSuccess || list == null) return (null, result); return (list.First(), result); diff --git a/webapi/WeatherForecast/Controllers/BlogCategoriesController.cs b/webapi/WeatherForecast/Controllers/BlogCategoriesController.cs deleted file mode 100644 index 92a38c7..0000000 --- a/webapi/WeatherForecast/Controllers/BlogCategoriesController.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Authorization; -using WeatherForecast.Models; -using WeatherForecast.Models.Responses; - -namespace WeatherForecast.Controllers { - - [AllowAnonymous] - [ApiController] - [Route("api/[controller]")] - public class BlogCategoriesController : ControllerBase { - - private readonly ILogger _logger; - - public BlogCategoriesController(ILogger logger) { - _logger = logger; - } - - /// - /// - /// - /// - //[HttpGet] - //public IActionResult Get() { - - // var categories = new List { - // new CategoryModel { - // Id = Guid.NewGuid(), - // Text = "Software" - // }, - // new CategoryModel { - // Id = Guid.NewGuid(), - // Text = "Hardware" - // }, - // }; - - // var response = new GetBlogCategoriesResponseModel { - // Items = categories - // }; - - // return Ok(response); - //} - } -} diff --git a/webapi/WeatherForecast/Controllers/BlogFeaturedController.cs b/webapi/WeatherForecast/Controllers/BlogFeaturedController.cs deleted file mode 100644 index aac1614..0000000 --- a/webapi/WeatherForecast/Controllers/BlogFeaturedController.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Authorization; -using WeatherForecast.Models; -using WeatherForecast.Models.Responses; - -namespace WeatherForecast.Controllers { - - [AllowAnonymous] - [ApiController] - [Route("api/[controller]")] - public class BlogFeaturedController : ControllerBase { - - private readonly ILogger _logger; - - public BlogFeaturedController(ILogger logger) { - _logger = logger; - } - - /// - /// - /// - /// - [HttpGet] - public IActionResult Get() { - - return Ok(); - - } - } -} diff --git a/webapi/WeatherForecast/Controllers/CategoryItemController.cs b/webapi/WeatherForecast/Controllers/CategoryItemController.cs new file mode 100644 index 0000000..ea271e2 --- /dev/null +++ b/webapi/WeatherForecast/Controllers/CategoryItemController.cs @@ -0,0 +1,49 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; +using WeatherForecast.Services; +using DomainResults.Mvc; +using WeatherForecast.Models.Requests; + +namespace WeatherForecast.Controllers { + + [AllowAnonymous] + [ApiController] + [Route("api/[controller]")] + public class CategoryItemController : ControllerBase { + + private readonly ILogger _logger; + private readonly ICategoryItemService _categoryItemService; + + public CategoryItemController( + ILogger logger, + ICategoryItemService categoryItemService) { + _logger = logger; + _categoryItemService = categoryItemService; + } + + + /// + /// + /// + /// + /// + /// + [HttpPost("{siteId}")] + public IActionResult Get([FromRoute] Guid siteId, [FromBody] PostCategoryItemRequestModel requestData) { + var result = _categoryItemService.Post(siteId, requestData); + return result.ToActionResult(); + } + + /// + /// + /// + /// + /// + /// + [HttpGet("{siteId}/{categoryId}")] + public IActionResult Get([FromRoute] Guid siteId, [FromRoute] Guid categoryId) { + var result = _categoryItemService.Get(siteId, categoryId); + return result.ToActionResult(); + } + } +} diff --git a/webapi/WeatherForecast/Controllers/CategoryItemsController.cs b/webapi/WeatherForecast/Controllers/CategoryItemsController.cs new file mode 100644 index 0000000..a2ee75c --- /dev/null +++ b/webapi/WeatherForecast/Controllers/CategoryItemsController.cs @@ -0,0 +1,56 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; + +using DomainResults.Mvc; + +using Core.Abstractions; +using Core.Enumerations; + +using WeatherForecast.Services; + +namespace WeatherForecast.Controllers { + + [AllowAnonymous] + [ApiController] + [Route("api/[controller]")] + public class CategoryItemsController : ControllerBase { + + private readonly ILogger _logger; + private readonly ICategoryItemsService _categoryItemsService; + + public CategoryItemsController( + ILogger logger, + ICategoryItemsService categoryItemsService + ) { + _logger = logger; + _categoryItemsService = categoryItemsService; + + + } + + /// + /// + /// + /// + /// + /// + [HttpGet("{siteId}")] + public IActionResult Get([FromRoute] Guid siteId, [FromQuery] string? locale) { + var result = _categoryItemsService.Get(siteId, locale != null + ? Enumeration.FromDisplayName(locale) + : Locales.Us); + return result.ToActionResult(); + } + + /// + /// + /// + /// + /// + [HttpDelete("{siteId}")] + public IActionResult Delete([FromRoute] Guid siteId) { + var result = _categoryItemsService.Delete(siteId); + return result.ToActionResult(); + } + } +} diff --git a/webapi/WeatherForecast/Controllers/ShopCategoriesController.cs b/webapi/WeatherForecast/Controllers/ShopCategoriesController.cs deleted file mode 100644 index 42a21a1..0000000 --- a/webapi/WeatherForecast/Controllers/ShopCategoriesController.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Authorization; -using WeatherForecast.Models; - -namespace WeatherForecast.Controllers { - - [AllowAnonymous] - [ApiController] - [Route("api/[controller]")] - public class ShopCategoriesController : ControllerBase { - - private readonly ILogger _logger; - - public ShopCategoriesController(ILogger logger) { - _logger = logger; - } - - ///// - ///// - ///// - ///// - //[HttpGet] - //public IActionResult Get() { - - // var categories = new List { - // new CategoryModel { - // Id = Guid.NewGuid(), - // Text = "Software" - // }, - // new CategoryModel { - // Id = Guid.NewGuid(), - // Text = "Hardware" - // }, - // }; - - // return Ok(categories); - //} - } -} diff --git a/webapi/WeatherForecast/Controllers/ShopFeaturedController.cs b/webapi/WeatherForecast/Controllers/ShopFeaturedController.cs deleted file mode 100644 index 13ffeb5..0000000 --- a/webapi/WeatherForecast/Controllers/ShopFeaturedController.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Authorization; - -namespace WeatherForecast.Controllers { - - [AllowAnonymous] - [ApiController] - [Route("api/[controller]")] - public class ShopFeaturedController : ControllerBase { - - private readonly ILogger _logger; - - public ShopFeaturedController(ILogger logger) { - _logger = logger; - } - - /// - /// - /// - /// - [HttpGet] - public IActionResult Get() { - return Ok(); - } - } -} diff --git a/webapi/WeatherForecast/Controllers/ShopRelatedController.cs b/webapi/WeatherForecast/Controllers/ShopRelatedController.cs deleted file mode 100644 index ba2d2b1..0000000 --- a/webapi/WeatherForecast/Controllers/ShopRelatedController.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Authorization; - -namespace WeatherForecast.Controllers { - - [AllowAnonymous] - [ApiController] - [Route("api/[controller]")] - public class ShopRelatedController : ControllerBase { - - private readonly ILogger _logger; - - - - - public ShopRelatedController(ILogger logger) { - _logger = logger; - } - - /// - /// - /// - /// - [HttpGet] - public IActionResult Get() { - return Ok(); - } - } -} diff --git a/webapi/WeatherForecast/Models/L10n/CategoryL10nModel.cs b/webapi/WeatherForecast/Models/L10n/CategoryL10nModel.cs new file mode 100644 index 0000000..13e6f85 --- /dev/null +++ b/webapi/WeatherForecast/Models/L10n/CategoryL10nModel.cs @@ -0,0 +1,19 @@ +using Core.Abstractions; +using Core.Abstractions.Models; +using Core.DomainObjects.L10n; +using Core.Enumerations; + +namespace WeatherForecast.Models.L10n { + public class CategoryL10nModel : RequestModelBase { + + public string Locale { get; set; } + public string Slug { get; set; } + public string Text { get; set; } + + public override CategoryL10n ToDomainObject() => new CategoryL10n { + Locale = Enumeration.FromDisplayName(Locale), + Slug = Slug, + Text = Text + }; + } +} diff --git a/webapi/WeatherForecast/Models/Requests/PostCategoryItemRequestModel.cs b/webapi/WeatherForecast/Models/Requests/PostCategoryItemRequestModel.cs new file mode 100644 index 0000000..9609226 --- /dev/null +++ b/webapi/WeatherForecast/Models/Requests/PostCategoryItemRequestModel.cs @@ -0,0 +1,13 @@ +using Core.Abstractions.Models; +using Core.DomainObjects; +using WeatherForecast.Models.L10n; + +namespace WeatherForecast.Models.Requests { + public class PostCategoryItemRequestModel : RequestModelBase { + + public List L10n { get; set; } + public override Category ToDomainObject() { + throw new NotImplementedException(); + } + } +} diff --git a/webapi/WeatherForecast/Models/Requests/PutCategoryItemRequestModel.cs b/webapi/WeatherForecast/Models/Requests/PutCategoryItemRequestModel.cs new file mode 100644 index 0000000..e1dc35a --- /dev/null +++ b/webapi/WeatherForecast/Models/Requests/PutCategoryItemRequestModel.cs @@ -0,0 +1,10 @@ +using Core.Abstractions.Models; +using Core.DomainObjects; + +namespace WeatherForecast.Models.Requests { + public class PutCategoryItemRequestModel : RequestModelBase { + public override Category ToDomainObject() { + throw new NotImplementedException(); + } + } +} diff --git a/webapi/WeatherForecast/Models/Responses/GetCategoryItemResponseModel.cs b/webapi/WeatherForecast/Models/Responses/GetCategoryItemResponseModel.cs new file mode 100644 index 0000000..a214788 --- /dev/null +++ b/webapi/WeatherForecast/Models/Responses/GetCategoryItemResponseModel.cs @@ -0,0 +1,19 @@ +using Core.Abstractions.Models; +using Core.DomainObjects; +using Core.Enumerations; + +namespace WeatherForecast.Models.Responses { + public class GetCategoryItemResponseModel : ResponseModelBase { + + public string Slug { get; set; } + public string Text { get; set; } + + public GetCategoryItemResponseModel(Category category, Locales locale) { + var l10n = category.L10n.SingleOrDefault(x => x.Locale == locale); + if (l10n != null) { + Slug = l10n.Slug; + Text = l10n.Text; + } + } + } +} diff --git a/webapi/WeatherForecast/Services/CategoryItemService.cs b/webapi/WeatherForecast/Services/CategoryItemService.cs new file mode 100644 index 0000000..d906218 --- /dev/null +++ b/webapi/WeatherForecast/Services/CategoryItemService.cs @@ -0,0 +1,84 @@ +using Core.Enumerations; +using DataProviders; +using DomainResults.Common; +using WeatherForecast.Models.Requests; +using WeatherForecast.Models.Responses; + +namespace WeatherForecast.Services { + public interface ICategoryItemService { + (Guid?, IDomainResult) Post(Guid siteId, PostCategoryItemRequestModel requestModel); + (GetCategoryItemResponseModel?, IDomainResult) Get(Guid siteId, Guid categoryId); + (Guid?, IDomainResult) Update(Guid siteId, Guid categoryId, PutCategoryItemRequestModel requestData); + IDomainResult Delete(Guid siteId, Guid categoryId); + } + + public class CategoryItemService : ICategoryItemService { + + ILogger _logger; + ICategoryDataProvider _categoryDataProvider; + + public CategoryItemService( + ILogger logger, + ICategoryDataProvider categoryDataProvider + ) { + _logger = logger; + _categoryDataProvider = categoryDataProvider; + } + + public (Guid?, IDomainResult) Post(Guid siteId, PostCategoryItemRequestModel requestModel) { + var (_, getResult) = _categoryDataProvider.Get(siteId, requestModel.L10n.Select(x => x.Slug).ToList()); + if (getResult.IsSuccess) + return IDomainResult.Failed(); + + var item = requestModel.ToDomainObject(); + item.SiteId = siteId; + + + var (id, insertResult) = _categoryDataProvider.Insert(item); + + if (!insertResult.IsSuccess) + return IDomainResult.Failed(); + + return IDomainResult.Success(id); + } + + public (GetCategoryItemResponseModel?, IDomainResult) Get(Guid siteId, Guid categoryId) { + var (item, result) = _categoryDataProvider.Get(siteId, categoryId); + if (!result.IsSuccess || item == null) + return (null, result); + + return IDomainResult.Success(new GetCategoryItemResponseModel(item, Locales.Us)); + } + + public (Guid?, IDomainResult) Update(Guid siteId, Guid categoryId, PutCategoryItemRequestModel requestData) { + var (item, result) = _categoryDataProvider.Get(siteId, categoryId); + if (!result.IsSuccess || item == null) + return (null, result); + + // construct domain object from model + var newItem = requestData.ToDomainObject(); + newItem.Id = item.Id; + newItem.SiteId = item.SiteId; + + if (!item.Equals(newItem)) { + var (id, updateResult) = _categoryDataProvider.Update(newItem); + if (!updateResult.IsSuccess || id == null) + return (null, updateResult); + } + + return IDomainResult.Success(item.Id); + } + + public IDomainResult Delete(Guid siteId, Guid categoryId) { + var (item, getResult) = _categoryDataProvider.Get(siteId, categoryId); + if (!getResult.IsSuccess || item == null) + return getResult; + + var result = _categoryDataProvider.Delete(item.Id); + if (!result.IsSuccess) + return result; + + return IDomainResult.Success(); + } + } +} diff --git a/webapi/WeatherForecast/Services/CategoryItemsService.cs b/webapi/WeatherForecast/Services/CategoryItemsService.cs new file mode 100644 index 0000000..9e67968 --- /dev/null +++ b/webapi/WeatherForecast/Services/CategoryItemsService.cs @@ -0,0 +1,40 @@ +using Core.Enumerations; +using DataProviders; +using DomainResults.Common; +using WeatherForecast.Models.Responses; + +namespace WeatherForecast.Services { + + public interface ICategoryItemsService { + (List?, IDomainResult) Get(Guid siteId, Locales locale); + IDomainResult Delete(Guid siteId); + } + + public class CategoryItemsService : ICategoryItemsService { + + private readonly ILogger _logger; + private readonly ICategoryDataProvider _categoryDataProvider; + + public CategoryItemsService( + ILogger logger, + ICategoryDataProvider categoryDataProvider + ) { + _logger = logger; + _categoryDataProvider = categoryDataProvider; + } + + public (List?, IDomainResult) Get(Guid siteId, Locales locale) { + var (items, result) = _categoryDataProvider.GetAll(siteId); + if (!result.IsSuccess || items == null) + return (null, result); + + return IDomainResult.Success(items.Select(x => new GetCategoryItemResponseModel(x, locale)).ToList()); + } + + public IDomainResult Delete(Guid siteId) { + var resutl = _categoryDataProvider.DeleteAll(siteId); + return resutl; + } + + } +} diff --git a/webapi/WeatherForecast/Startup.cs b/webapi/WeatherForecast/Startup.cs index 9b19182..524e6e1 100644 --- a/webapi/WeatherForecast/Startup.cs +++ b/webapi/WeatherForecast/Startup.cs @@ -64,6 +64,9 @@ namespace WeatherForecast { services.AddScoped(); //services.AddScoped(); services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.RegisterDataproviders(appSettings); #region Swagger