diff --git a/controllers/ParseController.go b/controllers/ParseController.go index 0239e64..054df43 100644 --- a/controllers/ParseController.go +++ b/controllers/ParseController.go @@ -45,7 +45,7 @@ func ParseLinkLCW(link string,w http.ResponseWriter) { } ///////////////////////////// - importRepo, err := repositories.ParseImporterInstannce() + importRepo, err := repositories.ParseImporterInstance() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) @@ -56,11 +56,11 @@ func ParseLinkLCW(link string,w http.ResponseWriter) { importRepo.ImportWGroup.Wait() log.Println(product); - //if err = importRepo.UpdateOrCreate(product).Error; err != nil { - // http.Error(w, err.Error(), http.StatusInternalServerError) - // fmt.Println(err) - // return - //} + if err = importRepo.UpdateOrCreateLCW(product).Error; err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + fmt.Println(err) + return + } w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(map[string]string{ "msg": "Link parsed successfully", diff --git a/gorm_models/product.go b/gorm_models/product.go index 8b60494..0d69293 100644 --- a/gorm_models/product.go +++ b/gorm_models/product.go @@ -143,6 +143,7 @@ func GetWishlistProducts(db *gorm.DB) ([]Product, error){ // return db.Error //} + func Flush() error { _, err := helper.SendRequest("GET", os.Getenv("scout_flash"), nil, "") diff --git a/repositories/ImportRepository.go b/repositories/ImportRepository.go index fa4ca72..104a8aa 100644 --- a/repositories/ImportRepository.go +++ b/repositories/ImportRepository.go @@ -144,7 +144,7 @@ func ImporterInstance() (instance *Importer, err error) { return instance, nil } -func ParseImporterInstannce() (instance *Importer, err error) { +func ParseImporterInstance() (instance *Importer, err error) { db, err := gorm.Open(mysql.Open(os.Getenv("database_url")), &gorm.Config{SkipDefaultTransaction: true}) if err != nil { @@ -773,3 +773,263 @@ func (importer *Importer) UpdateOrCreate(product models.Product) (instance *Impo } return importer } + +func (importer *Importer) importParsedVariant(product models.Product)(gm.Product, error) { + + //todo search if exists + + productRepo := InitProductRepo(&product, importer.GetColorOption(product.Color), importer.GetSexOption(product.Cinsiyet)) + productRepo.ImageType = "lcw" + if brand, err := gm.FindOrCreateBrand(importer.baza, product.Brand, productRepo.Categories); err != nil { + return gm.Product{}, err + } else { + productRepo.Brand = brand + } + mainPorduct := productRepo.makeProduct(importer) + + //BEGIN TRANSACTION + tx := importer.baza.Begin() + + if err := tx.Omit("Categories", "SuperAttributes.*", "ParentID").Create(&mainPorduct).Error; err != nil { + tx.Rollback() + return gm.Product{}, err + + } + + mainFlat := productRepo.makeProductFlat(mainPorduct.ID) + + if err := tx.Create(&mainFlat).Error; err != nil { + tx.Rollback() + return gm.Product{}, err + } + + if productRepo.HasSizeVariants() { + var sizeVariants []gm.ProductFlat + for index, variant := range *product.SizeVariants { + if !variant.Sellable { + continue + } + savePoint := "size" + strconv.Itoa(index) + tx.SavePoint(savePoint) + + var sizeOPtion gm.AttributeOption + + if variant.AttributeName == "Beden" { + sizeOPtion = gm.GetAttributeOption(tx, importer.AttributesMap["size"].ID, variant.AttributeValue) + } else { + sizeOPtion = gm.GetAttributeOption(tx, importer.AttributesMap["boyut"].ID, variant.AttributeValue) + } + + sku := fmt.Sprintf("%s-%d", product.ProductNumber, variant.ItemNumber) + variantProduct := productRepo.makeVariant(mainPorduct.ID, mainPorduct.AttributeFamilyID, sku) + + variantProduct.AttributeValues = productRepo.getVariantAttributes(importer.AttributesMap, &variant, sizeOPtion.ID) + + if err := tx.Omit("Categories.*").Create(&variantProduct).Error; err != nil { + log.Println("Variant Product Create Error: " + err.Error()) + tx.RollbackTo(savePoint) + continue + } + + variantFlat := productRepo.makeVariantFlat(variant, sizeOPtion.ID, mainFlat.ID, variantProduct.ID) + + if err := tx.Create(&variantFlat).Error; err != nil { + log.Println("Variant Flat Create Error: " + err.Error()) + tx.RollbackTo(savePoint) + continue + } + + sizeVariants = append(sizeVariants, variantFlat) + } + + if len(sizeVariants) == 0 { + tx.Rollback() + return gm.Product{}, errors.New("siz variantlary yok bolsa main productam girayenok") + } else { + calcPrice(sizeVariants, &mainFlat) + + err := tx.Omit("ParentID", "CreatedAt", "Variants", "SpecialPrice").Save(&mainFlat).Error + + mainFlat.Variants = sizeVariants + + if err != nil { + tx.Rollback() + return gm.Product{}, err + } + } + + } + + sProduct := importer.createSellerProduct(&mainFlat, product.Vendor) + + if errSProduct := tx.Create(&sProduct).Error; errSProduct != nil { + tx.Rollback() + return gm.Product{}, errSProduct + } + + if err := tx.Commit().Error; err != nil { + return gm.Product{}, err + } + + return mainPorduct, nil + +} + +func (importer *Importer) updateParsedVariant(product models.Product) (gm.Product, error){ + var flat gm.ProductFlat + err := importer.baza.Preload("Product").Preload("Variants").First(&flat, "sku = ?", product.ProductNumber).Error + if err != nil { + if errors.Is(err,gorm.ErrRecordNotFound) { + return importer.importParsedVariant(product) + } + //todo not found bolsa create etmeli + return gm.Product{}, err + } + + if flat.Product.Type == "configurable" { + + productRepo := InitProductRepo(&product, importer.GetColorOption(product.Color), importer.GetSexOption(product.Cinsiyet)) + productRepo.ImageType = "lcw" + if brand, err := gm.FindOrCreateBrand(importer.baza, product.Brand, productRepo.Categories); err != nil { + return gm.Product{}, err + } else { + productRepo.Brand = brand + } + + for _, variant := range *product.SizeVariants { + + found := false + for _, flatVariant := range flat.Variants { + + if variant.AttributeValue == flatVariant.BoyutLabel || variant.AttributeValue == flatVariant.SizeLabel { + + if !variant.Sellable { + importer.baza.Model(&flatVariant).Update("status", false) + } else { + + importer.updatePrice(variant.Price, &flatVariant) + + if !flatVariant.Status { + + importer.baza.Model(&flatVariant).Update("status", true) + } + } + found = true + break + } + } + + if variant.Sellable && !found { + // insert variant + var sizeOPtion gm.AttributeOption + + if variant.AttributeName == "Beden" { + sizeOPtion = gm.GetAttributeOption(importer.baza, importer.AttributesMap["size"].ID, variant.AttributeValue) + } else { + sizeOPtion = gm.GetAttributeOption(importer.baza, importer.AttributesMap["boyut"].ID, variant.AttributeValue) + } + + sku := fmt.Sprintf("%s-%d", product.ProductNumber, variant.ItemNumber) + variantProduct := productRepo.makeVariant(flat.ProductID, flat.Product.AttributeFamilyID, sku) + + variantProduct.AttributeValues = productRepo.getVariantAttributes(importer.AttributesMap, &variant, sizeOPtion.ID) + + if err := importer.baza.Omit("Categories").Create(&variantProduct).Error; err != nil { + log.Println("Variant Product Create Error: " + err.Error()) + } + + variantFlat := productRepo.makeVariantFlat(variant, sizeOPtion.ID, flat.ID, variantProduct.ID) + + if err := importer.baza.Create(&variantFlat).Error; err != nil { + log.Println("Variant Flat Create Error: " + err.Error()) + + } + flat.Variants = append(flat.Variants, variantFlat) + } + } + + calcPrice(flat.Variants, &flat) + importer.baza.Omit("ParentID", "CreatedAt", "Variants", "SpecialPrice").Save(&flat) + + } else { //simple + + importer.updatePrice(product.Price, &flat) + + } + return flat.Product, nil +} + +func (importer *Importer) UpdateOrCreateLCW(product models.Product) (instance *Importer){ + var firstProduct gm.Product + result := importer.baza.First(&firstProduct,"sku=?",product.ProductNumber) + + if errors.Is(result.Error, gorm.ErrRecordNotFound){ + firstProduct, importer.Error = importer.importParsedVariant(product) + + }else{ + firstProduct, importer.Error = importer.updateParsedVariant(product) + + } + + var newProducts []gm.Product + + if importer.Error != nil { + return importer + }else if &firstProduct != nil { + newProducts = append(newProducts, firstProduct) + } + + if product.ColorVariants != nil && len(*product.ColorVariants) > 0 { + linkedProducts := []gm.Product{firstProduct} + + for _, colorVariant := range *product.ColorVariants { + + var ( + variant *gm.Product + err error + ) + if !colorVariant.IsSellable { + + if err = importer.baza.Model(&gm.ProductFlat{}).Where("sku=?", colorVariant.ProductNumber).Update("status", false).Error; err != nil { + log.Println(err) + } + continue + + } else { + + //todo check parsed import variant + if variant, err = importer.importVariant(colorVariant); err != nil { + + if variant, importer.Error = importer.updateVariant(colorVariant); importer.Error != nil { + return importer + } + + linkedProducts = append(linkedProducts, *variant) + + } else { + newProducts = append(newProducts, *variant) + } + } + + } + + if len(newProducts) > 0 { + // relation + + var relation []gm.ProductRelation + for _, linkedProduct := range linkedProducts { + + for _, newProd := range newProducts { + relation = append(relation, gm.ProductRelation{ParentID: linkedProduct.ID, ChildID: newProd.ID}) + relation = append(relation, gm.ProductRelation{ParentID: newProd.ID, ChildID: linkedProduct.ID}) + } + } + + if err := importer.baza.Create(&relation).Error; err != nil { + log.Println(err) + } + } + + } + return importer +} diff --git a/repositories/ProductRepository.go b/repositories/ProductRepository.go index 2350348..ddc66f9 100644 --- a/repositories/ProductRepository.go +++ b/repositories/ProductRepository.go @@ -18,6 +18,7 @@ type ProductRepo struct { Error error ColorOption gm.AttributeOption SexOption gm.AttributeOption + ImageType string } func InitProductRepo(data *models.Product, color, sex gm.AttributeOption) *ProductRepo { @@ -40,6 +41,7 @@ func InitProductRepo(data *models.Product, color, sex gm.AttributeOption) *Produ Data: data, ColorOption: color, SexOption: sex, + ImageType: "cdn", } return instance @@ -111,7 +113,7 @@ func (pr *ProductRepo) makeProduct(imp *Importer) gm.Product { } for _, element := range pr.Data.Images { - product.Images = append(product.Images, gm.ProductImage{Type: "cdn", Path: element}) + product.Images = append(product.Images, gm.ProductImage{Type: pr.ImageType, Path: element}) } return product diff --git a/repositories/scraper_lcw.go b/repositories/scraper_lcw.go index fd9370f..c19a105 100644 --- a/repositories/scraper_lcw.go +++ b/repositories/scraper_lcw.go @@ -92,7 +92,7 @@ func parseDocument(doc *goquery.Document, primaryModel bool) models.Product { product.ProductGroupID = content case "OptionId": product.Sku = "p-" + content - product.ProductNumber = content + product.ProductNumber = "lcw-"+content case "ProductCode": product.ProductCode = content case "ProductName":