From 42253f230f1fde08f12b9202fcdb3adf0a546d53 Mon Sep 17 00:00:00 2001 From: merdan Date: Thu, 22 Sep 2022 16:22:16 +0500 Subject: [PATCH] seller id deadlock and delete elapsed time --- controllers/ImportController.go | 168 ++++++++++++++++++-------------- 1 file changed, 96 insertions(+), 72 deletions(-) diff --git a/controllers/ImportController.go b/controllers/ImportController.go index 2c308fa..cfe1b16 100644 --- a/controllers/ImportController.go +++ b/controllers/ImportController.go @@ -248,14 +248,17 @@ func ImportProduct(product models.Product, db *gorm.DB) error { } attributes, mainProductFlat := prepearAttributesWithFlat(&product) + colorOption := gm.GetAttributeOption(db, AttributesMap["color"].ID, product.Color) + mainProductFlat.Color = int(colorOption.ID) mainProductFlat.ColorLabel = product.Color - var productImages []gm.ProductImage + attributes = append(attributes, []gm.ProductAttributeValue{ {AttributeID: AttributesMap["color"].ID, IntegerValue: int(colorOption.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}) } @@ -293,10 +296,13 @@ func ImportProduct(product models.Product, db *gorm.DB) error { } iproduct.AttributeFamilyID = famID } + //BEGIN TRANSACTION + // begin a transaction + tx := db.Begin() - errMainProduct := db.Omit("Categories.*", "SuperAttributes.*", "ParentID").Create(&iproduct).Error - if errMainProduct != nil { + if errMainProduct := tx.Omit("Categories.*", "SuperAttributes.*", "ParentID").Create(&iproduct).Error; errMainProduct != nil { log.Println(errMainProduct.Error()) + tx.Rollback() return errMainProduct } @@ -304,9 +310,8 @@ func ImportProduct(product models.Product, db *gorm.DB) error { mainProductFlat.BrandID = brand.ID mainProductFlat.MetaKeywords = keywords - errProductMainFlat := db.Create(&mainProductFlat).Error - - if errProductMainFlat != nil { + if errProductMainFlat := tx.Create(&mainProductFlat).Error; errProductMainFlat != nil { + tx.Rollback() log.Println(errProductMainFlat) return errProductMainFlat } @@ -314,7 +319,7 @@ func ImportProduct(product models.Product, db *gorm.DB) error { if len(product.ColorVariants) > 0 { product.ColorVariants = append([]models.Product{product}, product.ColorVariants...) - for _, colorVariant := range product.ColorVariants { + for colorIndex, colorVariant := range product.ColorVariants { weight, _ := strconv.ParseFloat(colorVariant.Weight, 64) var description string for _, desc := range colorVariant.Descriptions { @@ -323,33 +328,54 @@ func ImportProduct(product models.Product, db *gorm.DB) error { colorOption := gm.GetAttributeOption(db, AttributesMap["color"].ID, colorVariant.Color) + colorSavePoint := string(colorIndex) if len(colorVariant.SizeVariants) > 0 { - for _, sizeVariant := range colorVariant.SizeVariants { + for index, sizeVariant := range colorVariant.SizeVariants { + + savePoint := string(colorIndex) + "sp" + string(index) + tx.SavePoint(savePoint) sku := fmt.Sprintf("%s-%s-%d-col-size", colorVariant.ProductGroupID, colorVariant.ProductNumber, sizeVariant.ItemNumber) + 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(errProdVariant) + tx.RollbackTo(savePoint) + continue + } + sizeOption := gm.GetAttributeOption(db, AttributesMap["size"].ID, sizeVariant.AttributeValue) productNumber := fmt.Sprintf("%s-%d", colorVariant.ProductNumber, sizeVariant.ItemNumber) attributes := []gm.ProductAttributeValue{ - {AttributeID: AttributesMap["source"].ID, TextValue: colorVariant.URLKey}, - {AttributeID: AttributesMap["favoritesCount"].ID, IntegerValue: colorVariant.FavoriteCount}, - {AttributeID: AttributesMap["sku"].ID, TextValue: sku}, - {AttributeID: AttributesMap["product_number"].ID, TextValue: productNumber}, - {AttributeID: AttributesMap["name"].ID, TextValue: colorVariant.Name, Channel: "default", Locale: "tm"}, - {AttributeID: AttributesMap["weight"].ID, TextValue: colorVariant.Weight}, - {AttributeID: AttributesMap["status"].ID, BooleanValue: true}, - //{AttributeID: AttributesMap["visible_individually"].ID, BooleanValue: true, Channel: "default", Locale: "tm"}, - {AttributeID: AttributesMap["url_key"].ID, TextValue: sku}, - {AttributeID: AttributesMap["meta_keywords"].ID, TextValue: keywords, Channel: "default", Locale: "tm"}, - {AttributeID: AttributesMap["description"].ID, TextValue: description, Channel: "default", Locale: "tm"}, - {AttributeID: AttributesMap["color"].ID, IntegerValue: int(colorOption.ID)}, - {AttributeID: AttributesMap["size"].ID, IntegerValue: int(sizeOption.ID)}, + {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["size"].ID, IntegerValue: int(sizeOption.ID)}, } - //todo assign images flatVariant := gm.ProductFlat{ //ProductID: productVariant.ID, BrandID: mainProductFlat.BrandID, @@ -369,12 +395,13 @@ func ImportProduct(product models.Product, db *gorm.DB) error { 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{ - {AttributeID: AttributesMap["price"].ID, FloatValue: sizeVariant.Price.OriginalPrice.Value}, - {AttributeID: AttributesMap["special_price"].ID, FloatValue: sizeVariant.Price.DiscountedPrice.Value}, + {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 @@ -383,13 +410,19 @@ func ImportProduct(product models.Product, db *gorm.DB) error { flatVariant.MaxPrice = sizeVariant.Price.OriginalPrice.Value } else { - attributes = append(attributes, gm.ProductAttributeValue{AttributeID: AttributesMap["price"].ID, FloatValue: sizeVariant.Price.DiscountedPrice.Value}) + 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(attError) + continue + } + if mainProductFlat.MinPrice > flatVariant.MinPrice || mainProductFlat.MinPrice == 0.0 { mainProductFlat.MinPrice = flatVariant.MinPrice } @@ -398,34 +431,10 @@ func ImportProduct(product models.Product, db *gorm.DB) error { mainProductFlat.MaxPrice = flatVariant.MaxPrice } - productVariant := gm.Product{ - ParentID: mainProductFlat.ProductID, - Type: "simple", - AttributeFamilyID: iproduct.AttributeFamilyID, - Sku: sku, - BrandID: mainProductFlat.BrandID, - AttributeValues: attributes, - Categories: categories, - } - - for _, element := range colorVariant.Images { - productVariant.Images = append(productVariant.Images, gm.ProductImage{Type: "cdn", Path: element}) - } - - errProdVariant := db.Omit("Categories.*").Create(&productVariant).Error - - if errProdVariant != nil { - log.Println(errProdVariant) - return errProdVariant - } - - flatVariant.ProductID = productVariant.ID - - errVariant := db.Create(&flatVariant).Error - - if errVariant != nil { + if errVariant := tx.Create(&flatVariant).Error; errVariant != nil { log.Println(errVariant) - return errVariant + tx.RollbackTo(savePoint) + continue } mainProductFlat.Variants = append(mainProductFlat.Variants, flatVariant) @@ -462,11 +471,9 @@ func ImportProduct(product models.Product, db *gorm.DB) error { productVariant.Images = append(productVariant.Images, gm.ProductImage{Type: "cdn", Path: element}) } - errProdVariant := db.Omit("Categories.*").Create(&productVariant).Error - - if errProdVariant != nil { + if errProdVariant := tx.Omit("Categories.*").Create(&productVariant).Error; errProdVariant != nil { log.Println(errProdVariant) - return errProdVariant + continue } variantFlat.ProductID = productVariant.ID @@ -475,22 +482,34 @@ func ImportProduct(product models.Product, db *gorm.DB) error { variantFlat.MetaKeywords = keywords variantFlat.ParentID = mainProductFlat.ID - errVariant := db.Create(&variantFlat).Error - - if errVariant != nil { + if errVariant := tx.Create(&variantFlat).Error; errVariant != nil { log.Println(errVariant) - return errVariant + tx.RollbackTo(colorSavePoint) + continue } mainProductFlat.Variants = append(mainProductFlat.Variants, variantFlat) } + + } + + if len(mainProductFlat.Variants) == 0 { + tx.Rollback() + return nil } } else if len(product.SizeVariants) > 0 { weight, _ := strconv.ParseFloat(product.Weight, 64) colorOption := gm.GetAttributeOption(db, AttributesMap["color"].ID, product.Color) - for _, sizeVariant := range product.SizeVariants { + for index, sizeVariant := range product.SizeVariants { + + sizeSavePoint := "size" + string(index) + tx.SavePoint(sizeSavePoint) + + if sizeVariant.ItemNumber == 0 { + sizeVariant.ItemNumber = index + } sku := fmt.Sprintf("%s-%s-%d-size", iproduct.Sku, product.ProductNumber, sizeVariant.ItemNumber) sizeOption := gm.GetAttributeOption(db, AttributesMap["size"].ID, sizeVariant.AttributeValue) @@ -571,44 +590,49 @@ func ImportProduct(product models.Product, db *gorm.DB) error { sizeVariantProduct.Images = append(sizeVariantProduct.Images, gm.ProductImage{Type: "cdn", Path: element}) } - errSizeVar := db.Omit("Categories.*").Create(&sizeVariantProduct).Error - - if errSizeVar != nil { + if errSizeVar := tx.Omit("Categories.*").Create(&sizeVariantProduct).Error; errSizeVar != nil { log.Println(errSizeVar) - return errSizeVar + continue } flatVariant.ProductID = sizeVariantProduct.ID - errVariant := db.Create(&flatVariant).Error - - if errVariant != nil { + if errVariant := db.Create(&flatVariant).Error; errVariant != nil { log.Println(errVariant) - return errVariant + tx.RollbackTo(sizeSavePoint) + continue } mainProductFlat.Variants = append(mainProductFlat.Variants, flatVariant) } + if len(mainProductFlat.Variants) == 0 { + tx.Rollback() + return nil + } } var errFlat error if mainProductFlat.SpecialPrice != 0 { - errFlat = db.Omit("ParentID", "CreatedAt", "Variants").Save(&mainProductFlat).Error + errFlat = tx.Omit("ParentID", "CreatedAt", "Variants").Save(&mainProductFlat).Error } else { - errFlat = db.Omit("ParentID", "CreatedAt", "Variants", "SpecialPrice").Save(&mainProductFlat).Error + errFlat = tx.Omit("ParentID", "CreatedAt", "Variants", "SpecialPrice").Save(&mainProductFlat).Error } if errFlat != nil { log.Println(errFlat) + tx.Rollback() + return errFlat } sProduct := createSellerProduct(&mainProductFlat, product.Vendor) - errSProduct := db.Create(&sProduct).Error + errSProduct := tx.Create(&sProduct).Error if errSProduct != nil { log.Println(errSProduct) + tx.Rollback() + return errSProduct } return nil