using Diligent.WebAPI.Contracts.DTOs.Categories; namespace Diligent.WebAPI.Business.Services { public class CategoryService : ICategoryService { private readonly DatabaseContext _context; private readonly IMapper _mapper; private readonly UserManager _userManager; private readonly IUserService _userService; public CategoryService(DatabaseContext context, IMapper mapper, UserManager userManager, IUserService userService) { _context = context; _mapper = mapper; _userManager = userManager; _userService = userService; } public async Task GetRootCategories(int userId,int parentCategoryId) { var user = await _userManager.FindByIdAsync(userId.ToString()); var role = (await _userManager.GetRolesAsync(user))[0]; if(parentCategoryId != -1 && role != "SuperAdmin") { var categories = await _context.UserCategories.Where(x => x.UserId == userId && x.CategoryId == parentCategoryId).ToListAsync(); if (categories.Count == 0) return null; } if (role == "SuperAdmin") if (parentCategoryId == -1) { return new CategoriesParentChild { Categories = _mapper.Map> (await _context.Categories.Where(k => k.ParentCategory == null).ToListAsync()), ChildParentRelations = await GetByParentChild(parentCategoryId) }; } else { return new CategoriesParentChild { Categories = await GetChildCategories(parentCategoryId, userId, role), ChildParentRelations = await GetByParentChild(parentCategoryId) }; } var userCategories = new List(); if(parentCategoryId == -1) userCategories = await _context.UserCategories .Where(k => k.UserId == userId && k.Category.ParentCategory == null) .Include(t => t.Category) .ToListAsync(); else return new CategoriesParentChild { Categories = await GetChildCategories(parentCategoryId, userId, role), ChildParentRelations = await GetByParentChild(parentCategoryId) }; return new CategoriesParentChild { Categories = GetCategoriesFromUserCategories(userCategories), ChildParentRelations = await GetByParentChild(parentCategoryId) }; } public async Task GetCategoryEntityById(int? id) => await _context.Categories.Where(x => x.Id == id).FirstOrDefaultAsync(); public async Task> GetCategories(int userId) { var grantedCategories = await _context.UserCategories.Where(k => k.UserId == userId).ToListAsync(); var allCategories = await _context.Categories.ToListAsync(); var result = new List(); for (int i = 0; i < allCategories.Count; i++) { var newCategory = new IsGrantedCategory { Id = allCategories[i].Id, Name = allCategories[i].Name, }; bool isGranted = false; for (int j = 0; j < grantedCategories.Count; j++) { if(grantedCategories[j].CategoryId == allCategories[i].Id && userId == grantedCategories[j].UserId) { isGranted = true; break; } } newCategory.IsChecked = isGranted; result.Add(newCategory); isGranted = false; } return result; } public async Task> GetAllCategories(int userId) { var user = await _userManager.FindByIdAsync(userId.ToString()); var role = (await _userManager.GetRolesAsync(user))[0]; List categories = new(); if(role == "SuperAdmin") { categories = await _context.Categories.Include(k => k.ParentCategory).ToListAsync(); } else { categories = await getCategoriesUserCanSee(user.Id); } List response = new(); foreach (var category in categories) { TreeViewCategoryResponse treeViewCategory = new(); if(category.ParentCategory == null) { treeViewCategory.Id = category.Id; treeViewCategory.Name = category.Name; treeViewCategory.TreeViewCategories = GetTreeCategoryItem(categories, category.Id); response.Add(treeViewCategory); } } return response; } private List GetCategoriesFromUserCategories(List userCategories) { var res = new List(); for (int i = 0; i < userCategories.Count; i++) { res.Add(_mapper.Map(userCategories[i].Category)); } return res; } private async Task> GetByParentChild(int categoryId) { var categories = await _context.Categories.Include(x => x.ParentCategory).ToListAsync(); var categoryById = categories.Where(x => x.Id == categoryId).FirstOrDefault(); List dto = new(); while (true) { if (categoryById == null) break; dto.Add(new CategoriesNamesResponse { Id = categoryById.Id, Name = categoryById.Name }); categoryById = categoryById.ParentCategory; } dto.Reverse(); return dto; } private async Task> GetChildCategories(int parentCategoryId, int userId, string role) { if (role == "SuperAdmin") return _mapper.Map>( await _context.Categories .Where(k => k.ParentCategory != null && k.ParentCategory.Id == parentCategoryId) .ToListAsync()); var userCategories = await _context.UserCategories .Where(k => k.UserId == userId && k.Category != null && k.Category.ParentCategory != null && k.Category.ParentCategory.Id == parentCategoryId) .Include(t => t.Category) .ToListAsync(); return GetCategoriesFromUserCategories(userCategories); } private async Task> getCategoriesUserCanSee(int userId) { var k = await _context.UserCategories.Include(c => c.Category).ThenInclude(p => p.ParentCategory).Where(t => t.UserId == userId).ToListAsync(); List t = new(); foreach (var m in k) { Category category = m.Category; while (true) { bool s = false; for (int i = 0; i < k.Count; i++) { if (category.Id == k[i].CategoryId) { s = true; break; } } if (s && category.ParentCategory is null) { t.Add(m.Category); break; } else if (!s && category.ParentCategory is null) { break; } else if (s == true) { category = category.ParentCategory; continue; } else { break; } } } return t; } private List GetTreeCategoryItem(List items, int id) { List response = new(); foreach (var item in items) { if(item.ParentCategory != null && item.ParentCategory.Id == id) { TreeViewCategoryResponse treeViewCategory = new(); treeViewCategory.Id = item.Id; treeViewCategory.Name = item.Name; treeViewCategory.TreeViewCategories = GetTreeCategoryItem(items, item.Id); response.Add(treeViewCategory); } } return response; } public async Task CreateAsync(CreateCategoryDto createCategoryDto, int userId) { Category category = null; if(createCategoryDto.ParentId != null) { category = await _context.Categories.Where(x => x.Id == createCategoryDto.ParentId).FirstOrDefaultAsync(); } var newCategory = new Category { Name = createCategoryDto.Name, ParentCategory = category }; await _context.Categories.AddAsync(newCategory); await _context.SaveChangesAsync(); await _userService.GrantCategoryToUserAsync(new GrantUserCategoryRequestDto { UserId = userId, Categories = new List { new GrantCategoryToUserRequestDto { Id = newCategory.Id, IsChecked = true } } }); } } }