package menuService import ( "sort" "git.ma-al.com/goc_daniel/b2b/app/model" "git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors" "git.ma-al.com/goc_daniel/b2b/repository/categoriesRepo" ) type MenuService struct { categoriesRepo categoriesRepo.UICategoriesRepo } func New() *MenuService { return &MenuService{ categoriesRepo: categoriesRepo.New(), } } func (s *MenuService) GetMenu(id_shop uint, id_lang uint) (model.Category, error) { all_categories, err := s.categoriesRepo.GetAllCategories(id_shop, id_lang) if err != nil { return model.Category{}, err } // find the root root_index := 0 root_found := false for i := 0; i < len(all_categories); i++ { if all_categories[i].IsRoot == 1 { root_index = i root_found = true break } } if !root_found { return model.Category{}, responseErrors.ErrNoRootFound } // now create the children and reorder them according to position id_to_index := make(map[uint]int) for i := 0; i < len(all_categories); i++ { id_to_index[all_categories[i].CategoryID] = i } children_indices := make(map[int][]ChildWithPosition) for i := 0; i < len(all_categories); i++ { parent_index := id_to_index[all_categories[i].ParentID] children_indices[parent_index] = append(children_indices[parent_index], ChildWithPosition{Index: i, Position: all_categories[i].Position}) } for key := range children_indices { sort.Sort(ByPosition(children_indices[key])) } // finally, create the tree tree := s.createTree(root_index, &all_categories, &children_indices) return tree, nil } func (s *MenuService) createTree(index int, all_categories *([]model.ScannedCategory), children_indices *(map[int][]ChildWithPosition)) model.Category { node := s.scannedToNormalCategory((*all_categories)[index]) for i := 0; i < len((*children_indices)[index]); i++ { node.Subcategories = append(node.Subcategories, s.createTree((*children_indices)[index][i].Index, all_categories, children_indices)) } return node } func (s *MenuService) scannedToNormalCategory(scanned model.ScannedCategory) model.Category { var normal model.Category normal.Active = scanned.Active normal.CategoryID = scanned.CategoryID normal.Name = scanned.Name normal.Subcategories = []model.Category{} return normal } type ChildWithPosition struct { Index int Position uint } type ByPosition []ChildWithPosition func (a ByPosition) Len() int { return len(a) } func (a ByPosition) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByPosition) Less(i, j int) bool { return a[i].Position < a[j].Position }