< Summary

Class:SVETA.Api.Controllers.CategoriesController
Assembly:SVETA.Api
File(s):/opt/dev/sveta_api_build/SVETA.Api/Controllers/CategoriesController.cs
Covered lines:0
Uncovered lines:112
Coverable lines:112
Total lines:333
Line coverage:0% (0 of 112)
Covered branches:0
Total branches:44
Branch coverage:0% (0 of 44)

Metrics

MethodLine coverage Branch coverage
.ctor(...)0%100%
GetCategoriesCount()0%100%
GetCategoriesParent()0%0%
GetChildCategoriesCount()0%0%
GetCategory()0%0%
CreateCategory()0%0%
UpdateCategory()0%0%
DeleteCategory()0%100%
GetParent()0%0%
ToDtoMapper()0%0%

File(s)

/opt/dev/sveta_api_build/SVETA.Api/Controllers/CategoriesController.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Threading.Tasks;
 5using AutoMapper;
 6using Microsoft.AspNetCore.Mvc;
 7using Microsoft.Extensions.Logging;
 8using SVETA.Api.Data.DTO;
 9using WinSolutions.Sveta.Server.Data.DataModel.Entities;
 10using WinSolutions.Sveta.Server.Services.Interfaces;
 11using Swashbuckle.AspNetCore.Annotations;
 12using SVETA.Api.Helpers;
 13using Microsoft.AspNetCore.Authorization;
 14using WinSolutions.Sveta.Common.Extensions;
 15using SVETA.Api.Services.Interfaces;
 16
 17namespace SVETA.Api.Controllers
 18{
 19    [Route("api/v1/Categories")]
 20    [ApiController]
 21    [Authorize]
 22    public class CategoriesController : SvetaController
 23    {
 24        ICategoryWorker _categoryWorker;
 25        private readonly ICategoryService _service;
 26        private readonly ILogger<CategoriesController> _logger;
 027        public CategoriesController(ICategoryService service, ILogger<CategoriesController> logger, ICategoryWorker cate
 028        {
 029            _service = service;
 030            _logger = logger;
 031            _categoryWorker = categoryWorker;
 032        }
 33
 34        /// <summary>
 35        /// Получить категории по фильтру
 36        /// </summary>
 37        /// <param name="parentId">Идентифиатор родительской категории: null - все категории, 0 - корневые категории, 1.
 38        /// <param name="page">Любое значение ниже нуля изменится на 1, номер страницы</param>
 39        /// <param name="limit">Любое значение ниже нуля изменится на 10, лимит выдачи</param>
 40        /// <param name="filter">фильтр по имени, гуглкоду или коду</param>
 41        /// <remarks>author: oboligatov\aabelentsov</remarks>
 42        /// <returns>List of category</returns>
 43        [HttpGet]
 44        [SwaggerResponse(200, "Успешно", typeof(List<CategoryResponseDTO>))]
 45        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 46        [AllowAnonymous]
 47        public async Task<IActionResult> GetCategories(long? parentId, int page = 1, int limit = 16, string filter = "")
 48        {
 49            filter = filter.NormalizeName();
 50            page = page < 1 ? 1 : page;
 51            limit = limit < 1 ? 10 : limit;
 52            var categories = await _service.GetCategories(page, limit, filter, parentId);
 53            var itemIds = categories.Select(x => x.Id).ToArray();
 54
 55            var parentsId = await _service.CheckParentIds(itemIds);
 056            var result = categories.Select(x => new CategoryResponseDTO(x)
 057            {
 058                Expandable = parentsId.Count != 0 && parentsId.Contains(x.Id)
 059            });
 60            return Ok(result);
 61        }
 62
 63        /// <summary>
 64        /// Получить количество категорий по фильтру
 65        /// </summary>
 66        /// <param name="parentId">Идентифиатор родительской категории: null - все категории, 0 - корневые категории, 1.
 67        /// <param name="filter">фильтр по имени, гуглкоду или коду</param>
 68        /// <remarks>author: oboligatov\aabelentsov</remarks>
 69        /// <returns>List of category</returns>
 70        [HttpGet("Count")]
 71        [SwaggerResponse(200, "Успешно", typeof(CountDTO))]
 72        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 73        [AllowAnonymous]
 74        public async Task<IActionResult> GetCategoriesCount(long? parentId,string filter = "")
 075        {
 076            filter = filter.NormalizeName();
 077            return Ok(new CountDTO(await _service.GetCategoriesCount(filter, parentId)));
 078        }
 79
 80        /// <summary>
 81        /// Возвращает группы, расположенные над категорией
 82        /// </summary>
 83        /// <remarks>author: oboligatov\IPod</remarks>
 84        /// <param name="id">Id категории</param>
 85        [HttpGet("{id}/ParentCategories")]
 86        [SwaggerResponse(200, "Успешно", typeof(IEnumerable<CategoryResponseDTO>))]
 87        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 88        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 89        [AllowAnonymous]
 90        public async Task<IActionResult> GetCategoriesParent(long id)
 091        {
 092            var category = await _service.GetCategory(id);
 093            if (category == null)
 094            {
 095                return NotFoundResult("Категория не найдена");
 96            }
 97
 098            List<CategoryResponseDTO> categories = new List<CategoryResponseDTO>();
 99
 0100            var config = new MapperConfiguration(cfg =>
 101            {
 102                cfg.CreateMap<Category, CategoryResponseDTO>()
 103                    .ForMember(d => d.ParentId, e => e.MapFrom(s => s.Parent != null ? s.Parent.Id : 0));
 104            });
 0105            IMapper mapper = config.CreateMapper();
 106
 0107            while (category != null)
 0108            {
 0109                CategoryResponseDTO categoryDto = mapper.Map<Category, CategoryResponseDTO>(category);
 0110                categories.Add(categoryDto);
 0111                category = category.Parent != null ? await _service.GetCategory(category.Parent.Id) : null;
 0112            }
 113
 0114            return Ok(categories);
 0115        }
 116
 117        #region Obsolete
 118        /// <summary>
 119        /// Возвращает дочерние категории для родителя
 120        /// Устаревший - использовать Get с параметром parentId
 121        /// </summary>
 122        /// <param name="parentId">код родителя, -1 если возвратить корневые категории</param>
 123        /// <param name="page">Любое значение ниже нуля изменится на 1, номер страницы</param>
 124        /// <param name="limit">Любое значение ниже нуля изменится на 10, лимит выдачи</param>
 125        /// <remarks>author: oboligatov</remarks>
 126        /// <returns></returns>
 127        [HttpGet("{parentId}/Childs")]
 128        [Obsolete("Устаревший - использовать Get с параметром parentId")]
 129        [SwaggerResponse(200, "Успешно", typeof(IEnumerable<CategoryResponseDTO>))]
 130        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 131        [Authorize(Roles = Role.SystemAdmin)]
 132        public async Task<IActionResult> GetChildCategories(long parentId = -1, int page = 1, int limit = 16)
 133        {
 134            try
 135            {
 136                page = page < 1 ? 1 : page;
 137                limit = limit < 1 ? 10 : limit;
 138                var categories = await _service.GetChildCategories(page - 1, limit, parentId != -1 ? parentId : (long?)n
 139                var itemIds = categories.Select(x => x.Id).ToArray();
 140
 141                var parentsId = await _service.CheckParentIds(itemIds);
 0142                var result = categories.Select(x => new CategoryResponseDTO(x)
 0143                {
 0144                    Expandable = parentsId.Count != 0 && parentsId.Contains(x.Id)
 0145                });
 146                return Ok(result);
 147            }
 148            catch (Exception ex)
 149            {
 150                return ServerError(ex);
 151            }
 152        }
 153
 154        /// <summary>
 155        /// Возвращает количество дочерних категорий для родителя
 156        /// Устаревший - использовать Count с параметром parentId
 157        /// </summary>
 158        /// <param name="parentId">код родителя, -1 если возвратить корневые категории</param>
 159        /// <remarks>author: oboligatov</remarks>
 160        /// <returns></returns>
 161        [HttpGet("{parentId}/Childs/Count")]
 162        [Obsolete("Устаревший - использовать Count с параметром parentId")]
 163        [SwaggerResponse(200, "Успешно", typeof(CountDTO))]
 164        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 165        [Authorize(Roles = Role.SystemAdmin)]
 166        public async Task<IActionResult> GetChildCategoriesCount(long parentId = -1)
 0167        {
 0168            return Ok(new CountDTO(await _service.GetChildCategoriesCount(parentId != -1 ? parentId : (long?)null)));
 0169        }
 170        #endregion
 171
 172        /// <summary>
 173        /// Возвращает категрию по ее Id
 174        /// </summary>
 175        /// <param name="id">Id категории</param>
 176        /// <remarks>author: oboligatov</remarks>
 177        /// <returns></returns>
 178        [HttpGet("{id}")]
 179        [SwaggerResponse(200, "Успешно", typeof(CategoryResponseDTO))]
 180        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 181        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 182        [AllowAnonymous]
 183        public async Task<IActionResult> GetCategory(long id)
 0184        {
 0185            var category = await _service.GetCategory(id);
 0186            if (category == null)
 0187            {
 0188                return NotFoundResult("Категория не найдена");
 189            }
 190
 0191            long[] itemIds = {category.Id};
 192
 0193            var parentsId = await _service.CheckParentIds(itemIds);
 0194            var result = new CategoryResponseDTO(category)
 0195            {
 0196                Expandable = parentsId.Count != 0 && parentsId.Contains(category.Id)
 0197            };
 0198            return Ok(result);
 0199        }
 200
 201        /// <summary>
 202        /// Ищет категорию по точному совпадению кода категории
 203        /// </summary>
 204        /// <param name="code">код категории, если пустой то возвращает все категории</param>
 205        /// <remarks>author: oboligatov</remarks>
 206        /// <returns></returns>
 207        [HttpGet("ByCode")]
 208        [SwaggerResponse(200, "Успешно", typeof(List<CategoryResponseDTO>))]
 209        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 210        [AllowAnonymous]
 211        public async Task<IActionResult> FindCategoryByCode(string code)
 212        {
 213            code = code.NormalizeName();
 214            var categories = await _service.FindCategory(code);
 215            var itemIds = categories.Select(x => x.Id).ToArray();
 216
 217            var parentsId = await _service.CheckParentIds(itemIds);
 0218            var result = categories.Select(x => new CategoryResponseDTO(x)
 0219            {
 0220                Expandable = parentsId.Count != 0 && parentsId.Contains(x.Id)
 0221            });
 222            return Ok(result);
 223        }
 224
 225        /// <summary>
 226        /// Создает категорию
 227        /// </summary>
 228        /// <param name="dto">поля категории</param>
 229        /// <remarks>author: oboligatov</remarks>
 230        /// <returns>Created category</returns>
 231        [HttpPost]
 232        [SwaggerResponse(200, "Успешно", typeof(CategoryResponseDTO))]
 233        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 234        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 235        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 236        [Authorize(Roles = Role.SystemAdmin)]
 237        public async Task<IActionResult> CreateCategory([FromBody] CategoryRequestDTO dto)
 0238        {
 0239            var category = new Category
 0240            {
 0241                Parent = await GetParent(dto.ParentId),
 0242                Name = dto.Name,
 0243                Code = dto.Code,
 0244                GUID = Guid.NewGuid(),
 0245                GoogleProductCategoryCode = dto.GoogleProductCategoryCode,
 0246                ExcludeFromGoogleFeed = dto.ExcludeFromGoogleFeed,
 0247                ExcludeFromYandexFeed = dto.ExcludeFromYandexFeed
 0248            };
 0249            await _service.CreateCategory(category);
 250
 0251            return Ok(ToDtoMapper().Map<CategoryResponseDTO>(category));
 0252        }
 253
 254
 255        /// <summary>
 256        /// Обновляет категорию
 257        /// </summary>
 258        /// <param name="id">Id категории</param>
 259        /// <param name="dto">поля категории</param>
 260        /// <remarks>author: oboligatov</remarks>
 261        /// <returns>No Content</returns>
 262        [HttpPut("{id}")]
 263        [SwaggerResponse(200, "Успешно", typeof(CategoryResponseDTO))]
 264        [SwaggerResponse(400, "Ошибка валидации входных параметров", typeof(ErrorDTO))]
 265        [SwaggerResponse(404, "Нет записей", typeof(ErrorDTO))]
 266        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 267        [Authorize(Roles = Role.SystemAdmin)]
 268        public async Task<IActionResult> UpdateCategory(long id, [FromBody] CategoryRequestDTO dto)
 0269        {
 0270            var category = await _service.FindCategory(id);
 0271            if(category == null)
 0272            {
 0273                return NotFoundResult("Категория не найдена");
 274            }
 0275            category.Name = dto.Name;
 0276            category.Code = dto.Code;
 0277            category.GoogleProductCategoryCode = dto.GoogleProductCategoryCode;
 0278            category.ExcludeFromGoogleFeed = dto.ExcludeFromGoogleFeed;
 0279            category.ExcludeFromYandexFeed = dto.ExcludeFromYandexFeed;
 0280            var isCollisium = await _service.CheckCollision(category.Id, dto.ParentId);
 0281            if (/*category.Id > dto.ParentId || */isCollisium)
 0282                return BadRequestResult("Невозможно привязать категорию, так как она является родителем по отношению к в
 0283            category.Parent = await GetParent(dto.ParentId);
 0284            await _service.UpdateCategory(category);
 285
 0286            return Ok(ToDtoMapper().Map<CategoryResponseDTO>(category));
 0287        }
 288
 289        /// <summary>
 290        /// Удаляет категорию
 291        /// </summary>
 292        /// <remarks>author: oboligatov</remarks>
 293        /// <param name="id">Id категории</param>
 294        [HttpDelete("{id}")]
 295        [SwaggerResponse(200, "Успешно", typeof(EmptyResult))]
 296        [SwaggerResponse(404, "Нет записей", typeof(EmptyResult))]
 297        [SwaggerResponse(500, "Ошибка на стороне сервера", typeof(ErrorDTO))]
 298        [Authorize(Roles = Role.SystemAdmin)]
 299        public async Task<IActionResult> DeleteCategory(long id)
 0300        {
 0301            await _categoryWorker.Delete(id);
 0302            return Ok();
 0303        }
 304
 305        private async Task<Category> GetParent(long id)
 0306        {
 0307            Category parent = null;
 0308            if (id > 0)
 0309            {
 0310                parent = await _service.GetCategory(id);
 0311                if (parent == null)
 0312                {
 0313                    throw new ArgumentException("Категория не найдена");
 314                }
 0315            }
 0316            return parent;
 0317        }
 318
 319        private static IMapper ToDtoMapper()
 0320        {
 0321            var config = new MapperConfiguration(cfg =>
 0322            {
 0323                cfg.CreateMap<Category, CategoryResponseDTO>()
 0324                    .ForMember(d => d.Name, e => e.MapFrom(s => s.Name.Elipsist(200)))
 0325                    .ForMember(d => d.Code, e => e.MapFrom(s => s.Code))
 0326                    .ForMember(d => d.ParentCode, e => e.MapFrom(s => s.Parent.Code))
 0327                    .ForMember(d => d.ParentId, e => e.MapFrom(s => s.Parent.Id));
 0328            });
 0329            IMapper mapper = config.CreateMapper();
 0330            return mapper;
 0331        }
 332    }
 333}