96 lines
2.8 KiB
Go
96 lines
2.8 KiB
Go
package storage
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"relynolli-server/internal"
|
|
"relynolli-server/models/catalog"
|
|
filters2 "relynolli-server/models/filters"
|
|
"slices"
|
|
|
|
cmap "github.com/orcaman/concurrent-map/v2"
|
|
"github.com/uptrace/bun"
|
|
)
|
|
|
|
type StorageCatalog interface {
|
|
GetCatalogItem(ctx context.Context, id *int64) (*catalog.DBCatalog, error)
|
|
GetCatalogItemByCode(ctx context.Context, code string) (*catalog.DBCatalog, error)
|
|
|
|
GetCatalogItems(ctx context.Context, filters cmap.ConcurrentMap[string, []string], limit int, offset int) (int, *[]catalog.DBCatalog, error)
|
|
GetFilters(ctx context.Context) (int, *[]filters2.DBFilter, error)
|
|
}
|
|
|
|
func NewStorageCatalog() StorageCatalog {
|
|
if instance == nil {
|
|
instance = &storage{
|
|
db: internal.InitDatabase().GetInstance(),
|
|
rdb: internal.InitRedis(),
|
|
}
|
|
}
|
|
return instance
|
|
}
|
|
|
|
func (s *storage) GetCatalogItemByCode(ctx context.Context, code string) (*catalog.DBCatalog, error) {
|
|
model := new(catalog.DBCatalog)
|
|
|
|
err := s.db.NewSelect().Model(model).Where("code = ?", code).Where("available_quantity > 0").Where("is_active = 1").Scan(ctx)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return model, nil
|
|
}
|
|
|
|
func (s *storage) GetCatalogItem(ctx context.Context, id *int64) (*catalog.DBCatalog, error) {
|
|
model := new(catalog.DBCatalog)
|
|
|
|
err := s.db.NewSelect().Model(model).Where("id = ?", id).Where("available_quantity > 0").Where("is_active = 1").Scan(ctx)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return model, nil
|
|
}
|
|
|
|
func (s *storage) buildFilterGroup(ctx context.Context, q *bun.SelectQuery, filters *cmap.ConcurrentMap[string, []string]) *bun.SelectQuery {
|
|
availableFilters := new([]filters2.DBFilter)
|
|
|
|
//Get filters
|
|
s.db.NewSelect().Model(availableFilters).Scan(ctx)
|
|
|
|
for _, filter := range filters.Keys() {
|
|
filter = filter[0 : len(filter)-2]
|
|
if !slices.ContainsFunc(*availableFilters, func(elem filters2.DBFilter) bool {
|
|
return elem.Code == filter
|
|
}) {
|
|
continue
|
|
}
|
|
q = q.WhereGroup(" AND ", func(query *bun.SelectQuery) *bun.SelectQuery {
|
|
values, _ := filters.Get(filter + "[]")
|
|
for _, val := range values {
|
|
query = q.WhereOr(fmt.Sprintf("properties->>'$.%s' = ?", filter), val)
|
|
}
|
|
return query
|
|
})
|
|
}
|
|
return q
|
|
|
|
}
|
|
|
|
func (s *storage) GetCatalogItems(ctx context.Context, filters cmap.ConcurrentMap[string, []string], limit int, offset int) (int, *[]catalog.DBCatalog, error) {
|
|
model := new([]catalog.DBCatalog)
|
|
filterQuery := s.db.NewSelect().Model(model).Where("is_active = 1").Where("available_quantity > 0")
|
|
count, _ := s.buildFilterGroup(ctx, filterQuery, &filters).Limit(limit).Offset(offset).Order("code").ScanAndCount(ctx)
|
|
|
|
return count, model, nil
|
|
}
|
|
|
|
func (s *storage) GetFilters(ctx context.Context) (int, *[]filters2.DBFilter, error) {
|
|
models := new([]filters2.DBFilter)
|
|
count, err := s.db.NewSelect().Model(models).ScanAndCount(ctx)
|
|
if err != nil {
|
|
return 0, nil, err
|
|
}
|
|
return count, models, nil
|
|
}
|