package storage import ( "context" "crypto/md5" "encoding/hex" "fmt" "relynolli-server/internal" "relynolli-server/models/cart" "time" ) type StorageCart interface { CreateFuser(ctx context.Context) (int64, *cart.DBFuser, error) GetCartItems(ctx context.Context, fuserId int64) (*[]cart.DBCart, error) GetCartItem(ctx context.Context, fuserId, productId int64) (*cart.DBCart, error) AddItemToCart(ctx context.Context, fuserId, productId int64) error UpdateCartItem(ctx context.Context, fuserId, productId, quantity int64) error DeleteCartItem(ctx context.Context, fuserId, productId int64) error } func NewStorageCart() StorageCart { if instance == nil { instance = &storage{ db: internal.InitDatabase().GetInstance(), rdb: internal.InitRedis(), } } return instance } func (s *storage) CreateFuser(ctx context.Context) (int64, *cart.DBFuser, error) { //stmt := "insert into b_sale_fuser (DATE_INSERT, DATE_UPDATE, CODE) values (now(), now(), md5(rand()));" hash := md5.Sum([]byte(fmt.Sprintf("%d", time.Now().Unix()))) model := &cart.DBFuser{ Code: hex.EncodeToString(hash[:]), DateInserted: time.Now().UTC(), DateUpdated: time.Now().UTC(), } res, err := s.db.NewInsert().Model(model).Exec(ctx) id, _ := res.LastInsertId() s.db.NewSelect().Model(model).Where("id = ?", id).Scan(ctx) if err != nil { return 0, nil, err } return model.Id, model, nil } func (s *storage) GetCartItems(ctx context.Context, fuserId int64) (*[]cart.DBCart, error) { result := new([]cart.DBCart) err := s.db.NewSelect().Model(result).Relation("Product").Relation("Fuser").Where("fuser_id = ?", fuserId).Scan(ctx) if err != nil { return nil, err } return result, nil } func (s *storage) GetCartItem(ctx context.Context, fuserId, productId int64) (*cart.DBCart, error) { result := new(cart.DBCart) err := s.db.NewSelect().Model(result).Relation("Product").Relation("Fuser").Where("fuser_id = ?", fuserId).Where("product_id = ?", productId).Scan(ctx) if err != nil { return nil, err } return result, nil } func (s *storage) AddItemToCart(ctx context.Context, fuserId, productId int64) error { item, _ := s.GetCatalogItem(ctx, &productId) isExists, err := s.db.NewSelect().Model((*cart.DBCart)(nil)).Where("fuser_id = ?", fuserId).Where("product_id = ?", productId).Exists(ctx) if isExists || item.AvailableQuantity < 1 { return nil } if err != nil { panic(err.Error()) } newItem := &cart.DBCart{ FuserId: fuserId, ProductId: productId, PriceTypeId: 1, Quantity: 1, } _, err = s.db.NewInsert().Model(newItem).Exec(ctx) if err != nil { return nil } return nil } func (s *storage) UpdateCartItem(ctx context.Context, fuserId, productId, quantity int64) error { if quantity <= 0 { return s.DeleteCartItem(ctx, fuserId, productId) } item, _ := s.GetCartItem(ctx, fuserId, productId) if item.Product.AvailableQuantity < quantity { return fmt.Errorf("Available quantity is less than requested. Available %d, requested %d", item.Product.AvailableQuantity, quantity) } item.Quantity = quantity s.db.NewUpdate().Model(item).Where("id = ?", item.Id).Exec(ctx) return nil } func (s *storage) DeleteCartItem(ctx context.Context, fuserId, productId int64) error { _, err := s.db.NewDelete().Model((*cart.DBCart)(nil)).Where("fuser_id = ?", fuserId).Where("product_id = ?", productId).Exec(ctx) if err != nil { return err } return nil }