package entity import ( "fmt" "strconv" "strings" "time" "unicode" ) type GoodsItemSize struct { Width Dimension Height Dimension Length Dimension UnmatchedDepth Dimension } func FixupSizes(s GoodsItemSize) (GoodsItemSize, bool) { // Nothing to substitute if s.UnmatchedDepth.IsZero() { return s, false } var count int for _, d := range []Dimension{ s.Width, s.Height, s.Length, } { if d.IsZero() { count++ } } // Can only replace one dimension if count != 1 { return s, false } switch { case s.Width.IsZero(): s.Width = s.UnmatchedDepth case s.Height.IsZero(): s.Height = s.UnmatchedDepth case s.Length.IsZero(): s.Length = s.UnmatchedDepth } s.UnmatchedDepth = Dimension{} return s, true } func (s GoodsItemSize) GetSum(kind DimensionKind) float64 { var value float64 sum := func(ds ...Dimension) { for _, d := range ds { value += d.AdjustTo(kind).Value } } sum(s.Height, s.Length, s.Length) return value } type GoodsItem struct { Articul string `json:"sku"` PhotoURLs []string `json:"photo"` Name string `json:"name"` Description string `json:"description"` Category string `json:"category"` Type string `json:"type"` Producer string `json:"producer"` Pack int `json:"pack"` Step int `json:"step"` Price float64 `json:"price"` TariffPrice float64 `json:"tariff_price"` Cart int64 `json:"cart"` Stock int `json:"stock"` Sizes GoodsItemSize `json:"sizes"` Parameters map[string]string `json:"parameters"` CreatedAt time.Time `json:"created_at"` } type GoodsItemRaw struct { SKU string // or articul Photo string Certificate string Configurator []string Name []string // first element is name, second is description Category string Type string Producer string Storage string // ? Pack string // like "20 шт." Step string Price string // float actually TariffPrice string // float SpecialOffers []any Cart float64 Other string } type GoodsItemInfo struct { Parameters map[string]string PhotoURLs []string } type MappedGoodsRemnants map[int]GoodsRemnant type GoodsRemnant [4]int32 func MakeGoodsItem( gi GoodsItemRaw, remnants MappedGoodsRemnants, info GoodsItemInfo, ) (out GoodsItem, err error) { var name, desc string var pack, step int var price, tariffPrice float64 if len(gi.Name) >= 2 { name = gi.Name[0] desc = gi.Name[1] } fixSpace := func(in string) string { return strings.ReplaceAll(in, " ", "") } price, err = strconv.ParseFloat(fixSpace(gi.Price), 64) if err != nil { return out, fmt.Errorf("parsing price: %w", err) } tariffPrice, err = strconv.ParseFloat(fixSpace(gi.TariffPrice), 64) if err != nil { return out, fmt.Errorf("parsing tariff_price: %w", err) } getDigits := func(in string) string { var sb strings.Builder sb.Grow(len(in)) for _, c := range in { if unicode.IsDigit(c) { sb.WriteRune(c) continue } break } return sb.String() } const countTemplate = "%d" _, err = fmt.Sscanf(getDigits(gi.Pack), countTemplate, &pack) if err != nil { return out, fmt.Errorf("getting pack count (%s): %w", gi.Pack, err) } _, err = fmt.Sscanf(getDigits(gi.Step), countTemplate, &step) if err != nil { return out, fmt.Errorf("getting step count (%s): %w", gi.Step, err) } photoURLs := info.PhotoURLs if len(photoURLs) > 7 { photoURLs = info.PhotoURLs[:7] } return GoodsItem{ Articul: gi.SKU, Name: name, Description: desc, Category: gi.Category, Type: gi.Type, Producer: gi.Producer, Pack: pack, Step: step, Price: price, TariffPrice: tariffPrice, Cart: int64(gi.Cart), Stock: int(remnants[int(gi.Cart)][0]), PhotoURLs: photoURLs, Parameters: info.Parameters, }, nil }