package cart import ( "context" "errors" "strconv" "cake_crm/internal/modules/storage" "cake_crm/proto" ) type ProductAndCount struct { product *proto.Product count int64 } type Service struct { storage storage.IStorage } func NewService(storage storage.IStorage) *Service { return &Service{ storage: storage, } } func (s *Service) GetCart(ctx context.Context, items []*proto.OrderItem) (*proto.CartRsp, error) { var cartAmount int64 var cartAmountOld int64 res := make([]*proto.CartItem, 0, len(items)) for _, item := range items { product, err := s.storage.GetProduct(ctx, item.ProductId) if err != nil { return nil, err } amount, amountOld, err := calcItemAmount( &ProductAndCount{ product: product, count: item.Count, }, ) if err != nil { return nil, err } res = append( res, &proto.CartItem{ Id: product.Id, Article: product.Article, Name: product.Name, Uri: product.Uri, Images: product.Images, Unit: product.Unit, Inventory: product.Inventory, Count: item.Count, Amount: amount, AmountOld: amountOld, Discount: amountOld - amount, Variants: product.Variants, Labels: product.Labels, }, ) cartAmount += amount cartAmountOld += amountOld } return &proto.CartRsp{ Items: res, Amount: cartAmount, AmountOld: cartAmountOld, Discount: cartAmountOld - cartAmount, }, nil } func calcItemAmount(item *ProductAndCount) (int64, int64, error) { variantOld := item.product.Variants[0] var variant *proto.Variant for _, v := range item.product.Variants { check := true for _, property := range v.Properties { if property.Name == "min" { minBorder, err := strconv.ParseInt(property.Value, 10, 64) if err != nil { return 0, 0, err } if item.count < minBorder { check = false } } if property.Name == "max" { maxBorder, err := strconv.ParseInt(property.Value, 10, 64) if err != nil { return 0, 0, err } if item.count > maxBorder { check = false } } if check { variant = v break } } } variant.Active = true if variant == nil { return 0, 0, errors.New("variant not found") } return variant.Price * item.count, variantOld.Price * item.count, nil }