package controller import ( gm "db_service/gorm_models" "db_service/models" helper "db_service/pkg" "encoding/json" "errors" "fmt" "log" "math/big" "net/http" "os" "strconv" "sync" "sync/atomic" "time" "gorm.io/driver/mysql" "gorm.io/gorm" ) var ( mainCategories []gm.Category baza *gorm.DB mainImportWG, famAndSellerWG sync.WaitGroup families []gm.AttributeFamily sellers = make(map[string]gm.MarketplaceSeller) AttributesMap = make(map[string]gm.Attribute) locker = stateUnlocked ) const ( stateUnlocked uint32 = iota stateLocked ) func StartImport(w http.ResponseWriter, route *http.Request) { // lock the request if !atomic.CompareAndSwapUint32(&locker, stateUnlocked, stateLocked) { w.WriteHeader(http.StatusTooManyRequests) err := json.NewEncoder(w).Encode(map[string]string{ "msg": "Product import in progress!", }) log.Println(err) return } defer atomic.StoreUint32(&locker, stateUnlocked) start := time.Now() r := new(big.Int) fmt.Println("start import", r.Binomial(1000, 10)) baza, err := gorm.Open(mysql.Open(os.Getenv("database_url")), &gorm.Config{SkipDefaultTransaction: true}) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } //get categories from mysql on main thread mainCategories = gm.GetMainCategories(baza) famAndSellerWG.Add(3) //get attribute families from mysql go func() { defer famAndSellerWG.Done() families, err = gm.GetFamilies(baza) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }() //get sellers families from mysql go func() { defer famAndSellerWG.Done() var vendors, err = gm.GetSellers(baza) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } for _, vendor := range vendors { sellers[vendor.Url] = vendor } }() go func() { defer famAndSellerWG.Done() var attributes, err = gm.GetAttributes(baza) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } for _, attribute := range attributes { AttributesMap[attribute.Code] = attribute } }() mainImportWG.Add(len(mainCategories)) log.Println("Start Product delete") deleteTime := time.Now() errDel := gm.DeleteProducts(baza) deleteElapsed := time.Since(deleteTime) log.Printf("Delete products took %s", deleteElapsed) if errDel != nil { http.Error(w, errDel.Error(), http.StatusInternalServerError) return } for _, element := range mainCategories { slug := element.Translations[0].Slug go importCategoryProducts("ty_db_"+slug, baza) // fmt.Println(<-result) } mainImportWG.Wait() err = gm.Flush() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } elapsed := time.Since(start) log.Printf("end import took %s", elapsed) http.Error(w, fmt.Sprintf("end import took %s", elapsed), http.StatusOK) } func importCategoryProducts(dbName string, db *gorm.DB) { defer mainImportWG.Done() if dbExists := helper.CheckDBExists(os.Getenv("couch_db_source") + dbName); dbExists { totalDocCount := getTotalDocumentCount(dbName) skip := 0 limit := 100 totalImport := 0 for skip < totalDocCount { var response models.BagistoModelResponse url := fmt.Sprintf("%s%s/_all_docs?include_docs=true&limit=%v&skip=%v", os.Getenv("couch_db_source"), dbName, limit, skip) fmt.Println(url) skip += limit body, err := helper.SendRequest("GET", url, nil, "") if err != nil { fmt.Println(err.Error()) continue } if err = json.Unmarshal(body, &response); err != nil { log.Println(err.Error()) continue } //iterate 100 row products for _, element := range response.Rows { if err := ImportProduct(element.Doc, db); err != nil { log.Println(err) } else { totalImport++ } } log.Printf("%s total imported documents count %d \n", dbName, totalImport) } } else { fmt.Println(dbName + "+doesnt exist") } } func getTotalDocumentCount(db string) int { var response models.DBDocCountResponse url := os.Getenv("couch_db_source") + db body, err := helper.SendRequest("GET", url, nil, "") if err != nil { log.Println(err.Error()) return 0 } err = json.Unmarshal(body, &response) if err != nil { log.Println(err.Error()) return 0 } return response.DocCount } func getCats(db *gorm.DB, catIDs []int) ([]gm.Category, string, error) { var categories []gm.Category var keywords string if errCat := db.Preload("Translations").Find(&categories, catIDs).Error; errCat != nil { log.Println(errCat) return categories, keywords, errCat } for _, cat := range categories { if len(cat.Translations) > 0 && cat.Translations[0].MetaKeywords != "" { translation := cat.Translations[0] keywords += "," + translation.MetaKeywords } } log.Println(keywords) return categories, keywords, nil } func ImportProduct(product models.Product, db *gorm.DB) error { famAndSellerWG.Wait() //wait until attribute families and sellers are not get from mysql //BEGIN TRANSACTION tx := *db.Begin() categories, keywords, errCat := getCats(&tx, product.Categories) if errCat != nil { log.Println("ERR0 Categories" + errCat.Error()) tx.Rollback() return errCat } return tx.Rollback().Error brand, err := gm.FindOrCreateBrand(&tx, product.Brand, categories) if err != nil { tx.Rollback() log.Println("ERR BRAND" + err.Error()) return err } attributes, mainProductFlat := prepearAttributesWithFlat(&product) colorOption := gm.GetAttributeOption(&tx, AttributesMap["color"].ID, product.Color) cinsiyetOption := gm.GetAttributeOption(&tx, AttributesMap["cinsiyet"].ID, product.Cinsiyet) mainProductFlat.Color = int(colorOption.ID) mainProductFlat.ColorLabel = product.Color attributes = append(attributes, []gm.ProductAttributeValue{ {AttributeID: AttributesMap["color"].ID, IntegerValue: int(colorOption.ID)}, {AttributeID: AttributesMap["cinsiyet"].ID, IntegerValue: int(cinsiyetOption.ID)}, {AttributeID: AttributesMap["meta_keywords"].ID, TextValue: keywords, Channel: "default", Locale: "tm"}}...) var productImages []gm.ProductImage for _, element := range product.Images { productImages = append(productImages, gm.ProductImage{Type: "cdn", Path: element}) } var famID uint = 1 if len(families) > 0 { famID = families[0].ID } iproduct := gm.Product{ Sku: product.ProductGroupID, Type: "simple", AttributeFamilyID: famID, BrandID: brand.ID, Categories: categories, AttributeValues: attributes, Images: productImages, } if len(product.ColorVariants) > 0 { iproduct.SuperAttributes = append(iproduct.SuperAttributes, AttributesMap["color"]) } if len(product.SizeVariants) > 0 { iproduct.SuperAttributes = append(iproduct.SuperAttributes, AttributesMap["size"]) } if len(iproduct.SuperAttributes) > 0 { iproduct.Type = "configurable" famID = 2 if len(families) > 1 { famID = families[1].ID } iproduct.AttributeFamilyID = famID } if errMainProduct := tx.Omit("Categories.*", "SuperAttributes.*", "ParentID").Create(&iproduct).Error; errMainProduct != nil { log.Println("ERR1" + errMainProduct.Error()) tx.Rollback() return errMainProduct } mainProductFlat.ProductID = iproduct.ID mainProductFlat.BrandID = brand.ID mainProductFlat.MetaKeywords = keywords if errProductMainFlat := tx.Create(&mainProductFlat).Error; errProductMainFlat != nil { tx.Rollback() log.Println("ERR2" + errProductMainFlat.Error()) return errProductMainFlat } if len(product.ColorVariants) > 0 { product.ColorVariants = append([]models.Product{product}, product.ColorVariants...) for colorIndex, colorVariant := range product.ColorVariants { weight, _ := strconv.ParseFloat(colorVariant.Weight, 64) var description string for _, desc := range colorVariant.Descriptions { description += "
" + desc.Description + "
" } colorOption := gm.GetAttributeOption(&tx, AttributesMap["color"].ID, colorVariant.Color) if len(colorVariant.SizeVariants) > 0 { for index, sizeVariant := range colorVariant.SizeVariants { savePoint := "Size" + strconv.Itoa(colorIndex) + "sp" + strconv.Itoa(index) tx.SavePoint(savePoint) if sizeVariant.ItemNumber == 0 { sizeVariant.ItemNumber = index } sku := fmt.Sprintf("%s-%s-%d-%d", colorVariant.ProductGroupID, colorVariant.ProductNumber, sizeVariant.ItemNumber, index) productVariant := gm.Product{ ParentID: mainProductFlat.ProductID, Type: "simple", AttributeFamilyID: iproduct.AttributeFamilyID, Sku: sku, BrandID: mainProductFlat.BrandID, Categories: categories, } for _, element := range colorVariant.Images { productVariant.Images = append(productVariant.Images, gm.ProductImage{Type: "cdn", Path: element}) } if errProdVariant := tx.Omit("Categories.*").Create(&productVariant).Error; errProdVariant != nil { log.Println("ERR3" + errProdVariant.Error()) tx.RollbackTo(savePoint) continue } sizeOption := gm.GetAttributeOption(&tx, AttributesMap["size"].ID, sizeVariant.AttributeValue) productNumber := fmt.Sprintf("%s-%d", colorVariant.ProductNumber, sizeVariant.ItemNumber) attributes := []gm.ProductAttributeValue{ {ProductID: productVariant.ID, AttributeID: AttributesMap["source"].ID, TextValue: colorVariant.URLKey}, {ProductID: productVariant.ID, AttributeID: AttributesMap["favoritesCount"].ID, IntegerValue: colorVariant.FavoriteCount}, {ProductID: productVariant.ID, AttributeID: AttributesMap["sku"].ID, TextValue: sku}, {ProductID: productVariant.ID, AttributeID: AttributesMap["product_number"].ID, TextValue: productNumber}, {ProductID: productVariant.ID, AttributeID: AttributesMap["name"].ID, TextValue: colorVariant.Name, Channel: "default", Locale: "tm"}, {ProductID: productVariant.ID, AttributeID: AttributesMap["weight"].ID, TextValue: colorVariant.Weight}, {ProductID: productVariant.ID, AttributeID: AttributesMap["status"].ID, BooleanValue: true}, {ProductID: productVariant.ID, AttributeID: AttributesMap["url_key"].ID, TextValue: sku}, {ProductID: productVariant.ID, AttributeID: AttributesMap["meta_keywords"].ID, TextValue: keywords, Channel: "default", Locale: "tm"}, {ProductID: productVariant.ID, AttributeID: AttributesMap["description"].ID, TextValue: description, Channel: "default", Locale: "tm"}, {ProductID: productVariant.ID, AttributeID: AttributesMap["color"].ID, IntegerValue: int(colorOption.ID)}, {ProductID: productVariant.ID, AttributeID: AttributesMap["cinsiyet"].ID, IntegerValue: int(cinsiyetOption.ID)}, {ProductID: productVariant.ID, AttributeID: AttributesMap["size"].ID, IntegerValue: int(sizeOption.ID)}, } flatVariant := gm.ProductFlat{ //ProductID: productVariant.ID, BrandID: mainProductFlat.BrandID, Status: true, //VisibleIndividually: false, Name: colorVariant.Name, Sku: sku, ProductNumber: productNumber, Description: description, UrlKey: sku, Weight: weight, // Source: colorVariant.URLKey, FavoritesCount: uint(colorVariant.FavoriteCount), Color: int(colorOption.ID), Size: int(sizeOption.ID), ColorLabel: colorOption.AdminName, SizeLabel: sizeOption.AdminName, MetaKeywords: keywords, ParentID: mainProductFlat.ID, ProductID: productVariant.ID, } if sizeVariant.Price.OriginalPrice.Value > sizeVariant.Price.DiscountedPrice.Value { attributes = append(attributes, []gm.ProductAttributeValue{ {ProductID: productVariant.ID, AttributeID: AttributesMap["price"].ID, FloatValue: sizeVariant.Price.OriginalPrice.Value}, {ProductID: productVariant.ID, AttributeID: AttributesMap["special_price"].ID, FloatValue: sizeVariant.Price.DiscountedPrice.Value}, }...) flatVariant.Price = sizeVariant.Price.OriginalPrice.Value flatVariant.SpecialPrice = sizeVariant.Price.DiscountedPrice.Value flatVariant.MinPrice = sizeVariant.Price.DiscountedPrice.Value flatVariant.MaxPrice = sizeVariant.Price.OriginalPrice.Value } else { attributes = append(attributes, gm.ProductAttributeValue{ProductID: productVariant.ID, AttributeID: AttributesMap["price"].ID, FloatValue: sizeVariant.Price.DiscountedPrice.Value}) flatVariant.Price = sizeVariant.Price.DiscountedPrice.Value flatVariant.MinPrice = sizeVariant.Price.DiscountedPrice.Value flatVariant.MaxPrice = sizeVariant.Price.DiscountedPrice.Value } if attError := tx.Create(&attributes).Error; attError != nil { tx.RollbackTo(savePoint) log.Println("ERR4" + attError.Error()) continue } if errVariant := tx.Create(&flatVariant).Error; errVariant != nil { log.Println("ERR5" + errVariant.Error()) tx.RollbackTo(savePoint) continue } if mainProductFlat.MinPrice > flatVariant.MinPrice || mainProductFlat.MinPrice == 0.0 { mainProductFlat.MinPrice = flatVariant.MinPrice } if mainProductFlat.MaxPrice < flatVariant.MaxPrice { mainProductFlat.MaxPrice = flatVariant.MaxPrice } mainProductFlat.Variants = append(mainProductFlat.Variants, flatVariant) } } else { colorSavePoint := "ColorSavePoint" + strconv.Itoa(colorIndex) tx.SavePoint(colorSavePoint) colorOption := gm.GetAttributeOption(&tx, AttributesMap["color"].ID, colorVariant.Color) cinsiyetOption := gm.GetAttributeOption(&tx, AttributesMap["cinsiyet"].ID, colorVariant.Cinsiyet) attributes, variantFlat := collectAttributes(&colorVariant, &colorOption) attributes = append(attributes, []gm.ProductAttributeValue{ {AttributeID: AttributesMap["meta_keywords"].ID, TextValue: keywords, Channel: "default", Locale: "tm"}, {AttributeID: AttributesMap["cinsiyet"].ID, IntegerValue: int(cinsiyetOption.ID)}, }...) sku := fmt.Sprintf("%s-%s-%d-%s", iproduct.Sku, colorVariant.ProductNumber, colorIndex, colorVariant.Color) productVariant := gm.Product{ ParentID: mainProductFlat.ProductID, Type: "simple", Sku: sku, BrandID: mainProductFlat.BrandID, AttributeValues: attributes, AttributeFamilyID: iproduct.AttributeFamilyID, Categories: categories, } for _, element := range colorVariant.Images { productVariant.Images = append(productVariant.Images, gm.ProductImage{Type: "cdn", Path: element}) } if errProdVariant := tx.Omit("Categories.*").Create(&productVariant).Error; errProdVariant != nil { log.Println("ERR55" + errProdVariant.Error()) tx.RollbackTo(colorSavePoint) continue } variantFlat.ProductID = productVariant.ID variantFlat.Color = int(colorOption.ID) variantFlat.ColorLabel = colorOption.AdminName variantFlat.MetaKeywords = keywords variantFlat.ParentID = mainProductFlat.ID if errVariant := tx.Create(&variantFlat).Error; errVariant != nil { log.Println("ERR6" + errVariant.Error()) tx.RollbackTo(colorSavePoint) continue } if mainProductFlat.MinPrice > variantFlat.MinPrice || mainProductFlat.MinPrice == 0 { mainProductFlat.MinPrice = variantFlat.MinPrice } if mainProductFlat.MaxPrice < variantFlat.MaxPrice { mainProductFlat.MaxPrice = variantFlat.MaxPrice } mainProductFlat.Variants = append(mainProductFlat.Variants, variantFlat) } } if len(mainProductFlat.Variants) == 0 { return tx.Rollback().Error } } else if len(product.SizeVariants) > 0 { weight, _ := strconv.ParseFloat(product.Weight, 64) colorOption := gm.GetAttributeOption(&tx, AttributesMap["color"].ID, product.Color) for index, sizeVariant := range product.SizeVariants { sizeSavePoint := "size" + strconv.Itoa(index) tx.SavePoint(sizeSavePoint) if sizeVariant.ItemNumber == 0 { sizeVariant.ItemNumber = index } sku := fmt.Sprintf("%s-%s-%d-%d", iproduct.Sku, product.ProductNumber, sizeVariant.ItemNumber, index) sizeOption := gm.GetAttributeOption(&tx, AttributesMap["size"].ID, sizeVariant.AttributeValue) attributes := []gm.ProductAttributeValue{ {AttributeID: AttributesMap["source"].ID, TextValue: product.URLKey}, {AttributeID: AttributesMap["favoritesCount"].ID, IntegerValue: product.FavoriteCount}, {AttributeID: AttributesMap["sku"].ID, TextValue: sku}, {AttributeID: AttributesMap["product_number"].ID, TextValue: fmt.Sprint(sizeVariant.ItemNumber)}, {AttributeID: AttributesMap["name"].ID, TextValue: product.Name, Channel: "default", Locale: "tm"}, {AttributeID: AttributesMap["weight"].ID, TextValue: product.Weight}, {AttributeID: AttributesMap["status"].ID, BooleanValue: true}, //{AttributeID: AttributesMap["visible_individually"].ID, BooleanValue: true}, {AttributeID: AttributesMap["url_key"].ID, TextValue: sku}, {AttributeID: AttributesMap["meta_keywords"].ID, TextValue: keywords, Channel: "default", Locale: "tm"}, {AttributeID: AttributesMap["size"].ID, IntegerValue: int(sizeOption.ID)}, {AttributeID: AttributesMap["description"].ID, TextValue: mainProductFlat.Description, Channel: "default", Locale: "tm"}, {AttributeID: AttributesMap["color"].ID, IntegerValue: int(colorOption.ID)}, {AttributeID: AttributesMap["cinsiyet"].ID, IntegerValue: int(cinsiyetOption.ID)}, } flatVariant := gm.ProductFlat{ Status: true, VisibleIndividually: false, Name: product.Name, Sku: sku, ProductNumber: fmt.Sprint(sizeVariant.ItemNumber), UrlKey: sku, Weight: weight, Size: int(sizeOption.ID), SizeLabel: sizeOption.AdminName, MetaKeywords: keywords, Description: mainProductFlat.Description, Color: int(colorOption.ID), ColorLabel: product.Color, FavoritesCount: uint(product.FavoriteCount), ParentID: mainProductFlat.ID, } if sizeVariant.Price.OriginalPrice.Value > sizeVariant.Price.DiscountedPrice.Value { attributes = append(attributes, []gm.ProductAttributeValue{ {AttributeID: AttributesMap["price"].ID, FloatValue: sizeVariant.Price.OriginalPrice.Value}, {AttributeID: AttributesMap["special_price"].ID, FloatValue: sizeVariant.Price.DiscountedPrice.Value}, }...) flatVariant.Price = sizeVariant.Price.OriginalPrice.Value flatVariant.SpecialPrice = sizeVariant.Price.DiscountedPrice.Value flatVariant.MinPrice = sizeVariant.Price.DiscountedPrice.Value flatVariant.MaxPrice = sizeVariant.Price.OriginalPrice.Value } else { attributes = append(attributes, gm.ProductAttributeValue{AttributeID: AttributesMap["price"].ID, FloatValue: sizeVariant.Price.DiscountedPrice.Value}) flatVariant.Price = sizeVariant.Price.DiscountedPrice.Value flatVariant.MinPrice = sizeVariant.Price.DiscountedPrice.Value flatVariant.MaxPrice = sizeVariant.Price.DiscountedPrice.Value } sizeVariantProduct := gm.Product{ ParentID: mainProductFlat.ProductID, Type: "simple", Sku: sku, BrandID: mainProductFlat.BrandID, AttributeValues: attributes, AttributeFamilyID: iproduct.AttributeFamilyID, Categories: categories, } for _, element := range product.Images { sizeVariantProduct.Images = append(sizeVariantProduct.Images, gm.ProductImage{Type: "cdn", Path: element}) } if errSizeVar := tx.Omit("Categories.*").Create(&sizeVariantProduct).Error; errSizeVar != nil { log.Println("ERR7" + errSizeVar.Error()) tx.RollbackTo(sizeSavePoint) continue } flatVariant.ProductID = sizeVariantProduct.ID if errVariant := tx.Create(&flatVariant).Error; errVariant != nil { log.Println("ERR8" + errVariant.Error()) tx.RollbackTo(sizeSavePoint) continue } if mainProductFlat.MinPrice > flatVariant.MinPrice || mainProductFlat.MinPrice == 0 { mainProductFlat.MinPrice = flatVariant.MinPrice } if mainProductFlat.MaxPrice < flatVariant.MaxPrice { mainProductFlat.MaxPrice = flatVariant.MaxPrice } mainProductFlat.Variants = append(mainProductFlat.Variants, flatVariant) } if len(mainProductFlat.Variants) == 0 { return tx.Rollback().Error } } var errFlat error if mainProductFlat.SpecialPrice != 0 { errFlat = tx.Omit("ParentID", "CreatedAt", "Variants").Save(&mainProductFlat).Error } else { errFlat = tx.Omit("ParentID", "CreatedAt", "Variants", "SpecialPrice").Save(&mainProductFlat).Error } if errFlat != nil { log.Println("ERR9" + errFlat.Error()) tx.Rollback() return errFlat } sProduct := createSellerProduct(&mainProductFlat, product.Vendor) errSProduct := tx.Create(&sProduct).Error if errSProduct != nil { log.Println("ERR10" + errSProduct.Error()) tx.Rollback() return errSProduct } else { return tx.Commit().Error } } func createSellerProduct(flat *gm.ProductFlat, sellerURL string) gm.MarketplaceProduct { sellerID := sellers[sellerURL].ID if sellerID == 0 { sellerID = 1 } sellerProduct := gm.MarketplaceProduct{ MarketplaceSellerID: sellerID, IsApproved: true, Condition: "new", Description: "scraped", IsOwner: true, ProductID: flat.ProductID, } for _, variant := range flat.Variants { sellerProduct.Variants = append(sellerProduct.Variants, gm.MarketplaceProduct{ ProductID: variant.ProductID, IsOwner: true, IsApproved: true, MarketplaceSellerID: sellerID, Condition: "new", }) } return sellerProduct } func collectAttributes(variant *models.Product, option *gm.AttributeOption) ([]gm.ProductAttributeValue, gm.ProductFlat) { sku := fmt.Sprintf("%s-%s", variant.ProductGroupID, variant.ProductNumber) weight, _ := strconv.ParseFloat(variant.Weight, 64) var description string for _, desc := range variant.Descriptions { description += "" + desc.Description + "
" } flat := gm.ProductFlat{ Status: true, //VisibleIndividually: true, Name: variant.Name, Sku: sku, ProductNumber: variant.ProductNumber, UrlKey: sku, Weight: weight, FavoritesCount: uint(variant.FavoriteCount), Description: description, MinPrice: 0, MaxPrice: 0, } attributes := []gm.ProductAttributeValue{ {AttributeID: AttributesMap["favoritesCount"].ID, IntegerValue: variant.FavoriteCount}, {AttributeID: AttributesMap["source"].ID, TextValue: variant.URLKey}, {AttributeID: AttributesMap["sku"].ID, TextValue: sku}, {AttributeID: AttributesMap["product_number"].ID, TextValue: variant.ProductNumber}, {AttributeID: AttributesMap["name"].ID, TextValue: variant.Name, Channel: "default", Locale: "tm"}, {AttributeID: AttributesMap["weight"].ID, TextValue: variant.Weight}, {AttributeID: AttributesMap["status"].ID, BooleanValue: true}, //{AttributeID: AttributesMap["visible_individually"].ID, BooleanValue: true}, {AttributeID: AttributesMap["url_key"].ID, TextValue: sku}, {AttributeID: option.AttributeID, IntegerValue: int(option.ID)}, {AttributeID: AttributesMap["description"].ID, TextValue: description, Channel: "default", Locale: "tm"}, } if variant.Price.OriginalPrice.Value > variant.Price.DiscountedPrice.Value { attributes = append(attributes, []gm.ProductAttributeValue{ {AttributeID: AttributesMap["price"].ID, FloatValue: variant.Price.OriginalPrice.Value}, {AttributeID: AttributesMap["special_price"].ID, FloatValue: variant.Price.DiscountedPrice.Value}, }...) flat.Price = variant.Price.OriginalPrice.Value flat.SpecialPrice = variant.Price.DiscountedPrice.Value flat.MinPrice = variant.Price.DiscountedPrice.Value flat.MaxPrice = variant.Price.OriginalPrice.Value } else { attributes = append(attributes, gm.ProductAttributeValue{AttributeID: AttributesMap["price"].ID, FloatValue: variant.Price.DiscountedPrice.Value}) flat.Price = variant.Price.DiscountedPrice.Value flat.MinPrice = variant.Price.DiscountedPrice.Value flat.MaxPrice = variant.Price.DiscountedPrice.Value } return attributes, flat } func prepearAttributesWithFlat(data *models.Product) ([]gm.ProductAttributeValue, gm.ProductFlat) { weight, wError := strconv.ParseFloat(data.Weight, 64) if wError != nil || weight == 0 { weight = 0.5 } var description string for _, desc := range data.Descriptions { description += "" + desc.Description + "
" } //$desc = implode(array_map(fn($value): string => '' . $value['description'] . '
', $data['descriptions'])); var productAttributeValues = []gm.ProductAttributeValue{ {AttributeID: AttributesMap["source"].ID, TextValue: data.URLKey}, {AttributeID: AttributesMap["favoritesCount"].ID, IntegerValue: data.FavoriteCount}, {AttributeID: AttributesMap["sku"].ID, TextValue: data.ProductGroupID}, {AttributeID: AttributesMap["product_number"].ID, TextValue: data.ProductNumber}, {AttributeID: AttributesMap["name"].ID, TextValue: data.Name, Channel: "default", Locale: "tm"}, {AttributeID: AttributesMap["weight"].ID, TextValue: data.Weight}, {AttributeID: AttributesMap["status"].ID, BooleanValue: true}, {AttributeID: AttributesMap["visible_individually"].ID, BooleanValue: true}, {AttributeID: AttributesMap["url_key"].ID, TextValue: data.ProductGroupID}, {AttributeID: AttributesMap["description"].ID, TextValue: description, Channel: "default", Locale: "tm"}, } flat := gm.ProductFlat{ Status: true, VisibleIndividually: true, Name: data.Name, Sku: data.ProductGroupID, ProductNumber: data.ProductNumber, Description: description, UrlKey: data.ProductGroupID, Weight: weight, //Source: data.URLKey, FavoritesCount: uint(data.FavoriteCount), MaxPrice: 0, MinPrice: 0, Price: 0, } if len(data.ColorVariants) == 0 && len(data.SizeVariants) == 0 { if data.Price.OriginalPrice.Value > data.Price.DiscountedPrice.Value { productAttributeValues = append(productAttributeValues, []gm.ProductAttributeValue{ {AttributeID: AttributesMap["price"].ID, FloatValue: data.Price.OriginalPrice.Value}, {AttributeID: AttributesMap["special_price"].ID, FloatValue: data.Price.DiscountedPrice.Value}, }...) flat.Price = data.Price.OriginalPrice.Value flat.SpecialPrice = data.Price.DiscountedPrice.Value flat.MinPrice = data.Price.DiscountedPrice.Value flat.MaxPrice = data.Price.OriginalPrice.Value } else { productAttributeValues = append(productAttributeValues, gm.ProductAttributeValue{AttributeID: AttributesMap["price"].ID, FloatValue: data.Price.DiscountedPrice.Value}) flat.Price = data.Price.DiscountedPrice.Value flat.MinPrice = data.Price.DiscountedPrice.Value flat.MaxPrice = data.Price.DiscountedPrice.Value } } return productAttributeValues, flat } func UpdateProduct(product models.Product, db *gorm.DB, productFlat gm.ProductFlat) error { productFlat.Status = true minPrice := 0.0 maxPrice := 0.0 if len(product.ColorVariants) == 0 && len(product.SizeVariants) == 0 { if product.Price.OriginalPrice.Value > product.Price.DiscountedPrice.Value { //productAttributeValues = append(productAttributeValues, []gm.ProductAttributeValue{ // {AttributeID: AttributesMap["price"].ID, FloatValue: data.Price.OriginalPrice.Value}, // {AttributeID: AttributesMap["special_price"].ID, FloatValue: data.Price.DiscountedPrice.Value}, //}...) if productFlat.Price != product.Price.OriginalPrice.Value { productFlat.Price = product.Price.OriginalPrice.Value productFlat.MaxPrice = product.Price.OriginalPrice.Value //db.Model(&User{}).Where("active = ?", true).Update("name", "hello") err := db.Model(gm.ProductAttributeValue{}). Where("attribute_id = ? AND product_id = ?", 11, productFlat.ProductID). Update("float_value", product.Price.OriginalPrice.Value).Error if err != nil { return err } } if productFlat.SpecialPrice != product.Price.DiscountedPrice.Value { productFlat.SpecialPrice = product.Price.DiscountedPrice.Value productFlat.MinPrice = product.Price.DiscountedPrice.Value err := db.Model(gm.ProductAttributeValue{}). Where("attribute_id = ? AND product_id = ?", 13, productFlat.ProductID). Update("float_value", product.Price.OriginalPrice.Value).Error if err != nil { return err } } } else { if productFlat.Price != product.Price.OriginalPrice.Value { productFlat.Price = product.Price.OriginalPrice.Value productFlat.MaxPrice = product.Price.OriginalPrice.Value productFlat.MinPrice = product.Price.OriginalPrice.Value err := db.Model(gm.ProductAttributeValue{}). Where("attribute_id = ? AND product_id = ?", 11, productFlat.ProductID). Update("float_value", product.Price.OriginalPrice.Value).Error if err != nil { return err } } } } else if len(product.ColorVariants) > 0 { //todo update configurable product product.ColorVariants = append(product.ColorVariants, product) //tx := db.Begin() for _, colorVariant := range product.ColorVariants { if len(colorVariant.SizeVariants) > 0 { for _, sizeVariant := range colorVariant.SizeVariants { sku := fmt.Sprintf("%s-%s-%d-col-size", colorVariant.ProductGroupID, colorVariant.ProductNumber, sizeVariant.ItemNumber) var variantFlat gm.ProductFlat err := db.Where("sku=?", sku).First(&variantFlat).Error if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { //todo insert variant continue } if !sizeVariant.Sellable { variantFlat.Status = false errVar := db.Save(&variantFlat).Error if errVar != nil { log.Println(errVar.Error()) } continue } prices := sizeVariant.Price if prices.OriginalPrice.Value > prices.DiscountedPrice.Value { variantFlat.Price = prices.OriginalPrice.Value variantFlat.SpecialPrice = prices.DiscountedPrice.Value variantFlat.MinPrice = prices.DiscountedPrice.Value variantFlat.MaxPrice = prices.OriginalPrice.Value errVar := db.Omit("CreatedAt").Save(&variantFlat).Error if errVar != nil { log.Println(errVar.Error()) } } else { variantFlat.MinPrice = prices.DiscountedPrice.Value variantFlat.MaxPrice = prices.DiscountedPrice.Value errVar := db.Exec("Update product_flat set price = ?,min_price=?, max_price=?, special_price = NULL where id = ?", prices.DiscountedPrice.Value, variantFlat.MinPrice, variantFlat.MaxPrice, variantFlat.ID).Error if errVar != nil { log.Println(errVar.Error()) } } if minPrice == 0 || minPrice > variantFlat.MinPrice { minPrice = variantFlat.MinPrice } if maxPrice == 0 || maxPrice < variantFlat.MaxPrice { maxPrice = variantFlat.MaxPrice } } } else { sku := fmt.Sprintf("%s-%s-%s-%s", product.ProductGroupID, colorVariant.ProductNumber, colorVariant.ProductCode, colorVariant.Color) var variantFlat gm.ProductFlat err := db.Where("sku=?", sku).First(&variantFlat).Error if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { //todo insert variant continue } if !colorVariant.IsSellable { variantFlat.Status = false errVar := db.Save(&variantFlat).Error if errVar != nil { log.Println(errVar.Error()) } continue } prices := colorVariant.Price if prices.OriginalPrice.Value > prices.DiscountedPrice.Value { variantFlat.Price = prices.OriginalPrice.Value variantFlat.SpecialPrice = prices.DiscountedPrice.Value variantFlat.MinPrice = prices.DiscountedPrice.Value variantFlat.MaxPrice = prices.OriginalPrice.Value errVar := db.Omit("CreatedAt").Save(&variantFlat).Error if errVar != nil { log.Println(errVar.Error()) } } else { variantFlat.MinPrice = prices.DiscountedPrice.Value variantFlat.MaxPrice = prices.DiscountedPrice.Value errVar := db.Exec("Update product_flat set price = ?,min_price=?, max_price=?, special_price = NULL where id = ?", prices.DiscountedPrice.Value, variantFlat.MinPrice, variantFlat.MaxPrice, variantFlat.ID).Error if errVar != nil { log.Println(errVar.Error()) } } if minPrice == 0 || minPrice > variantFlat.MinPrice { minPrice = variantFlat.MinPrice } if maxPrice == 0 || maxPrice < variantFlat.MaxPrice { maxPrice = variantFlat.MaxPrice } } } productFlat.MinPrice = minPrice productFlat.MaxPrice = maxPrice } else if len(product.SizeVariants) > 0 { for _, sizeVariant := range product.SizeVariants { sku := fmt.Sprintf("%s-%s-%d-size", product.ProductGroupID, product.ProductNumber, sizeVariant.ItemNumber) var variantFlat gm.ProductFlat err := db.Where("sku=?", sku).First(&variantFlat).Error if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { //todo insert variant continue } if !sizeVariant.Sellable { variantFlat.Status = false errVar := db.Save(&variantFlat).Error if errVar != nil { log.Println(errVar.Error()) } continue } prices := sizeVariant.Price if prices.OriginalPrice.Value > prices.DiscountedPrice.Value { variantFlat.Price = prices.OriginalPrice.Value variantFlat.SpecialPrice = prices.DiscountedPrice.Value variantFlat.MinPrice = prices.DiscountedPrice.Value variantFlat.MaxPrice = prices.OriginalPrice.Value errVar := db.Omit("CreatedAt").Save(&variantFlat).Error if errVar != nil { log.Println(errVar.Error()) } } else { variantFlat.MinPrice = prices.DiscountedPrice.Value variantFlat.MaxPrice = prices.DiscountedPrice.Value errVar := db.Exec("Update product_flat set price = ?,min_price=?, max_price=?, special_price = NULL where id = ?", prices.DiscountedPrice.Value, variantFlat.MinPrice, variantFlat.MaxPrice, variantFlat.ID).Error if errVar != nil { log.Println(errVar.Error()) } } if minPrice == 0 || minPrice > variantFlat.MinPrice { minPrice = variantFlat.MinPrice } if maxPrice == 0 || maxPrice < variantFlat.MaxPrice { maxPrice = variantFlat.MaxPrice } } productFlat.MinPrice = minPrice productFlat.MaxPrice = maxPrice } var errFlat error if productFlat.SpecialPrice != 0 { errFlat = db.Omit("Product", "ParentID", "CreatedAt").Save(&productFlat).Error } else { errFlat = db.Omit("Product", "ParentID", "CreatedAt", "SpecialPrice").Save(&productFlat).Error } return errFlat } //func productAttributesAndFlat(data *models.Product) ([]gm.ProductAttributeValue,gm.ProductFlat){ // // var description string // // for _, desc := range data.Descriptions { // description += "" + desc.Description + "
" // } // // weight, _ := strconv.ParseFloat(data.Weight, 64) // // flat := gm.ProductFlat{ // Status: true, // VisibleIndividually: true, // Name: data.Name, // Sku: data.ProductGroupID, // ProductNumber: data.ProductNumber, // Description: description, // UrlKey: data.ProductGroupID, // Weight: weight, // FavoritesCount: uint(data.FavoriteCount), // } // return []gm.ProductAttributeValue{ // {AttributeID: AttributesMap["favoritesCount"].ID, IntegerValue: data.FavoriteCount}, // {AttributeID: AttributesMap["source"].ID, TextValue: data.URLKey}, // {AttributeID: AttributesMap["product_number"].ID, TextValue: data.ProductNumber}, // {AttributeID: AttributesMap["name"].ID, TextValue: data.Name, Channel: "default", Locale: "tm"}, // {AttributeID: AttributesMap["weight"].ID, TextValue: data.Weight}, // {AttributeID: AttributesMap["status"].ID, BooleanValue: true}, // {AttributeID: AttributesMap["visible_individually"].ID, BooleanValue: true}, // {AttributeID: AttributesMap["description"].ID, TextValue: description, Channel: "default", Locale: "tm"}, // },flat //}