1098 lines
35 KiB
Go
1098 lines
35 KiB
Go
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)
|
|
json.NewEncoder(w).Encode(map[string]string{
|
|
"msg": "Scraper or Updater in progress!",
|
|
})
|
|
|
|
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{})
|
|
|
|
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 with gorutine
|
|
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 with gorutine
|
|
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 _, atrattribute := range attributes {
|
|
AttributesMap[atrattribute.Code] = atrattribute
|
|
}
|
|
}()
|
|
|
|
mainImportWG.Add(len(mainCategories))
|
|
|
|
log.Println("Start Product delete")
|
|
delete := time.Now()
|
|
errDel := gm.DeleteProducts(baza)
|
|
deleteElapsed := time.Since(delete)
|
|
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()
|
|
|
|
dbExists := helper.CheckDBExists(os.Getenv("couch_db_source") + dbName)
|
|
fmt.Println(dbName)
|
|
|
|
if dbExists {
|
|
|
|
totalDocCount := getTotalDocumentCount(dbName)
|
|
skip := 0
|
|
limit := 500
|
|
|
|
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
|
|
}
|
|
|
|
err = json.Unmarshal(body, &response)
|
|
|
|
if err != nil {
|
|
log.Println(err.Error())
|
|
continue
|
|
}
|
|
|
|
//itearate 100 row products
|
|
for _, element := range response.Rows {
|
|
err := ImportProduct(element.Doc, db)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
} 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
|
|
}
|
|
|
|
// todo defailt variant
|
|
// productflat
|
|
|
|
func getCats(db *gorm.DB, catIDs []int) ([]gm.Category, string, error) {
|
|
var categories []gm.Category
|
|
var keywords string
|
|
|
|
if len(mainCategories) > 0 {
|
|
for _, item := range mainCategories {
|
|
for _, id := range catIDs {
|
|
if item.ID == uint(id) {
|
|
categories = append(categories, item)
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
errCat := db.Preload("Translations").Find(&categories, catIDs).Error
|
|
|
|
if errCat != nil {
|
|
return categories, keywords, errCat
|
|
}
|
|
}
|
|
|
|
for _, cat := range categories {
|
|
if len(cat.Translations) > 0 && cat.Translations[0].MetaKeywords != "" {
|
|
translation := cat.Translations[0]
|
|
|
|
keywords += "," + translation.MetaKeywords
|
|
}
|
|
}
|
|
|
|
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
|
|
|
|
categories, keywords, errCat := getCats(db, product.Categories)
|
|
|
|
if errCat != nil {
|
|
log.Println("ERR0001" + errCat.Error())
|
|
return errCat
|
|
} else {
|
|
log.Println("Import" + product.Name)
|
|
}
|
|
|
|
var brand gm.Brand
|
|
|
|
if product.Brand != "" {
|
|
brand = gm.FindOrCreateBrand(db, product.Brand, categories)
|
|
}
|
|
|
|
attributes, mainProductFlat := prepearAttributesWithFlat(&product)
|
|
|
|
colorOption := gm.GetAttributeOption(db, AttributesMap["color"].ID, product.Color)
|
|
|
|
mainProductFlat.Color = int(colorOption.ID)
|
|
mainProductFlat.ColorLabel = product.Color
|
|
|
|
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})
|
|
}
|
|
|
|
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
|
|
}
|
|
//BEGIN TRANSACTION
|
|
// begin a transaction
|
|
|
|
tx := db.Begin()
|
|
|
|
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 += "<p>" + desc.Description + "</p>"
|
|
}
|
|
|
|
colorOption := gm.GetAttributeOption(db, AttributesMap["color"].ID, colorVariant.Color)
|
|
|
|
colorSavePoint := "ColorSavePoint" + strconv.Itoa(colorIndex)
|
|
|
|
if len(colorVariant.SizeVariants) > 0 {
|
|
|
|
for index, sizeVariant := range colorVariant.SizeVariants {
|
|
|
|
savePoint := "Size" + strconv.Itoa(colorIndex) + "sp" + strconv.Itoa(index)
|
|
|
|
log.Println(savePoint)
|
|
|
|
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("ERR3" + errProdVariant.Error())
|
|
tx.RollbackTo(savePoint)
|
|
return errProdVariant
|
|
}
|
|
|
|
log.Println("Variant product saved")
|
|
|
|
sizeOption := gm.GetAttributeOption(db, 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["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 mainProductFlat.MinPrice > flatVariant.MinPrice || mainProductFlat.MinPrice == 0.0 {
|
|
mainProductFlat.MinPrice = flatVariant.MinPrice
|
|
}
|
|
|
|
if mainProductFlat.MaxPrice < flatVariant.MaxPrice {
|
|
mainProductFlat.MaxPrice = flatVariant.MaxPrice
|
|
}
|
|
|
|
if errVariant := tx.Create(&flatVariant).Error; errVariant != nil {
|
|
log.Println("ERR5" + errVariant.Error())
|
|
tx.RollbackTo(savePoint)
|
|
continue
|
|
}
|
|
|
|
mainProductFlat.Variants = append(mainProductFlat.Variants, flatVariant)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
colorOption := gm.GetAttributeOption(db, AttributesMap["color"].ID, colorVariant.Color)
|
|
attributes, variantFlat := collectAttributes(&colorVariant, &colorOption)
|
|
attributes = append(attributes, gm.ProductAttributeValue{AttributeID: AttributesMap["meta_keywords"].ID, TextValue: keywords, Channel: "default", Locale: "tm"})
|
|
|
|
if mainProductFlat.MinPrice > variantFlat.MinPrice || mainProductFlat.MinPrice == 0 {
|
|
mainProductFlat.MinPrice = variantFlat.MinPrice
|
|
}
|
|
|
|
if mainProductFlat.MaxPrice < variantFlat.MaxPrice {
|
|
mainProductFlat.MaxPrice = variantFlat.MaxPrice
|
|
}
|
|
|
|
sku := fmt.Sprintf("%s-%s-%s-%s", iproduct.Sku, colorVariant.ProductNumber, colorVariant.ProductCode, 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("ERR5" + errProdVariant.Error())
|
|
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
|
|
}
|
|
|
|
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 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-size", iproduct.Sku, product.ProductNumber, sizeVariant.ItemNumber)
|
|
sizeOption := gm.GetAttributeOption(db, 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)},
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
if mainProductFlat.MinPrice > flatVariant.MinPrice || mainProductFlat.MinPrice == 0 {
|
|
mainProductFlat.MinPrice = flatVariant.MinPrice
|
|
}
|
|
|
|
if mainProductFlat.MaxPrice < flatVariant.MaxPrice {
|
|
mainProductFlat.MaxPrice = flatVariant.MaxPrice
|
|
}
|
|
|
|
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())
|
|
continue
|
|
}
|
|
|
|
flatVariant.ProductID = sizeVariantProduct.ID
|
|
|
|
if errVariant := tx.Create(&flatVariant).Error; errVariant != nil {
|
|
log.Println("ERR8" + errVariant.Error())
|
|
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 = 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
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
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 += "<p>" + desc.Description + "</p>"
|
|
}
|
|
|
|
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, wEror := strconv.ParseFloat(data.Weight, 64)
|
|
|
|
if wEror != nil || weight == 0 {
|
|
weight = 0.5
|
|
}
|
|
|
|
var description string
|
|
|
|
for _, desc := range data.Descriptions {
|
|
description += "<p>" + desc.Description + "</p>"
|
|
}
|
|
//$desc = implode(array_map(fn($value): string => '<p>' . $value['description'] . '</p>', $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 += "<p>" + desc.Description + "</p>"
|
|
// }
|
|
//
|
|
// 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
|
|
//}
|