new v3 productrepo ready
This commit is contained in:
parent
f7d9921a54
commit
773183c9b3
|
|
@ -61,8 +61,12 @@ func StartImport(w http.ResponseWriter, route *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//get categories from mysql on main thread
|
//get categories from mysql on main thread
|
||||||
mainCategories = gm.GetMainCategories(baza)
|
mainCategories, err = gm.GetMainCategories(baza)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
famAndSellerWG.Add(3)
|
famAndSellerWG.Add(3)
|
||||||
//get attribute families from mysql
|
//get attribute families from mysql
|
||||||
go func() {
|
go func() {
|
||||||
|
|
@ -215,12 +219,12 @@ func getCats(db *gorm.DB, catIDs []int) ([]gm.Category, string, error) {
|
||||||
var keywords string
|
var keywords string
|
||||||
|
|
||||||
if errCat := db.Preload("Translations", "locale=?", "tm").Find(&categories, catIDs).Error; errCat != nil {
|
if errCat := db.Preload("Translations", "locale=?", "tm").Find(&categories, catIDs).Error; errCat != nil {
|
||||||
//log.Println(errCat)
|
log.Println(errCat)
|
||||||
return categories, keywords, errCat
|
return categories, keywords, errCat
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cat := range categories {
|
for _, cat := range categories {
|
||||||
log.Println(cat)
|
//log.Println(cat)
|
||||||
if len(cat.Translations) > 0 && cat.Translations[0].MetaKeywords != "" {
|
if len(cat.Translations) > 0 && cat.Translations[0].MetaKeywords != "" {
|
||||||
translation := cat.Translations[0]
|
translation := cat.Translations[0]
|
||||||
|
|
||||||
|
|
@ -289,11 +293,11 @@ func ImportProduct(product models.Product, db *gorm.DB) error {
|
||||||
Images: productImages,
|
Images: productImages,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(product.ColorVariants) > 0 {
|
if len(*product.ColorVariants) > 0 {
|
||||||
iproduct.SuperAttributes = append(iproduct.SuperAttributes, AttributesMap["color"])
|
iproduct.SuperAttributes = append(iproduct.SuperAttributes, AttributesMap["color"])
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(product.SizeVariants) > 0 {
|
if len(*product.SizeVariants) > 0 {
|
||||||
iproduct.SuperAttributes = append(iproduct.SuperAttributes, AttributesMap["size"])
|
iproduct.SuperAttributes = append(iproduct.SuperAttributes, AttributesMap["size"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -323,10 +327,10 @@ func ImportProduct(product models.Product, db *gorm.DB) error {
|
||||||
return errProductMainFlat
|
return errProductMainFlat
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(product.ColorVariants) > 0 {
|
if len(*product.ColorVariants) > 0 {
|
||||||
product.ColorVariants = append([]models.Product{product}, product.ColorVariants...)
|
*product.ColorVariants = append([]models.Product{product}, *product.ColorVariants...)
|
||||||
|
|
||||||
for colorIndex, colorVariant := range product.ColorVariants {
|
for colorIndex, colorVariant := range *product.ColorVariants {
|
||||||
weight, _ := strconv.ParseFloat(colorVariant.Weight, 64)
|
weight, _ := strconv.ParseFloat(colorVariant.Weight, 64)
|
||||||
var description string
|
var description string
|
||||||
for _, desc := range colorVariant.Descriptions {
|
for _, desc := range colorVariant.Descriptions {
|
||||||
|
|
@ -335,9 +339,9 @@ func ImportProduct(product models.Product, db *gorm.DB) error {
|
||||||
|
|
||||||
colorOption := gm.GetAttributeOption(&tx, AttributesMap["color"].ID, colorVariant.Color)
|
colorOption := gm.GetAttributeOption(&tx, AttributesMap["color"].ID, colorVariant.Color)
|
||||||
|
|
||||||
if len(colorVariant.SizeVariants) > 0 {
|
if len(*colorVariant.SizeVariants) > 0 {
|
||||||
|
|
||||||
for index, sizeVariant := range colorVariant.SizeVariants {
|
for index, sizeVariant := range *colorVariant.SizeVariants {
|
||||||
|
|
||||||
savePoint := "Size" + strconv.Itoa(colorIndex) + "sp" + strconv.Itoa(index)
|
savePoint := "Size" + strconv.Itoa(colorIndex) + "sp" + strconv.Itoa(index)
|
||||||
|
|
||||||
|
|
@ -516,11 +520,11 @@ func ImportProduct(product models.Product, db *gorm.DB) error {
|
||||||
return tx.Rollback().Error
|
return tx.Rollback().Error
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if len(product.SizeVariants) > 0 {
|
} else if len(*product.SizeVariants) > 0 {
|
||||||
|
|
||||||
weight, _ := strconv.ParseFloat(product.Weight, 64)
|
weight, _ := strconv.ParseFloat(product.Weight, 64)
|
||||||
colorOption := gm.GetAttributeOption(&tx, AttributesMap["color"].ID, product.Color)
|
colorOption := gm.GetAttributeOption(&tx, AttributesMap["color"].ID, product.Color)
|
||||||
for index, sizeVariant := range product.SizeVariants {
|
for index, sizeVariant := range *product.SizeVariants {
|
||||||
|
|
||||||
sizeSavePoint := "size" + strconv.Itoa(index)
|
sizeSavePoint := "size" + strconv.Itoa(index)
|
||||||
tx.SavePoint(sizeSavePoint)
|
tx.SavePoint(sizeSavePoint)
|
||||||
|
|
@ -792,7 +796,7 @@ func prepearAttributesWithFlat(data *models.Product) ([]gm.ProductAttributeValue
|
||||||
Price: 0,
|
Price: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(data.ColorVariants) == 0 && len(data.SizeVariants) == 0 {
|
if len(*data.ColorVariants) == 0 && len(*data.SizeVariants) == 0 {
|
||||||
|
|
||||||
if data.Price.OriginalPrice.Value > data.Price.DiscountedPrice.Value {
|
if data.Price.OriginalPrice.Value > data.Price.DiscountedPrice.Value {
|
||||||
productAttributeValues = append(productAttributeValues, []gm.ProductAttributeValue{
|
productAttributeValues = append(productAttributeValues, []gm.ProductAttributeValue{
|
||||||
|
|
@ -822,7 +826,7 @@ func UpdateProduct(product models.Product, db *gorm.DB, productFlat gm.ProductFl
|
||||||
minPrice := 0.0
|
minPrice := 0.0
|
||||||
maxPrice := 0.0
|
maxPrice := 0.0
|
||||||
|
|
||||||
if len(product.ColorVariants) == 0 && len(product.SizeVariants) == 0 {
|
if len(*product.ColorVariants) == 0 && len(*product.SizeVariants) == 0 {
|
||||||
|
|
||||||
if product.Price.OriginalPrice.Value > product.Price.DiscountedPrice.Value {
|
if product.Price.OriginalPrice.Value > product.Price.DiscountedPrice.Value {
|
||||||
//productAttributeValues = append(productAttributeValues, []gm.ProductAttributeValue{
|
//productAttributeValues = append(productAttributeValues, []gm.ProductAttributeValue{
|
||||||
|
|
@ -869,15 +873,15 @@ func UpdateProduct(product models.Product, db *gorm.DB, productFlat gm.ProductFl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if len(product.ColorVariants) > 0 {
|
} else if len(*product.ColorVariants) > 0 {
|
||||||
//todo update configurable product
|
//todo update configurable product
|
||||||
product.ColorVariants = append(product.ColorVariants, product)
|
*product.ColorVariants = append(*product.ColorVariants, product)
|
||||||
//tx := db.Begin()
|
//tx := db.Begin()
|
||||||
for _, colorVariant := range product.ColorVariants {
|
for _, colorVariant := range *product.ColorVariants {
|
||||||
|
|
||||||
if len(colorVariant.SizeVariants) > 0 {
|
if len(*colorVariant.SizeVariants) > 0 {
|
||||||
|
|
||||||
for _, sizeVariant := range colorVariant.SizeVariants {
|
for _, sizeVariant := range *colorVariant.SizeVariants {
|
||||||
sku := fmt.Sprintf("%s-%s-%d-col-size", colorVariant.ProductGroupID, colorVariant.ProductNumber, sizeVariant.ItemNumber)
|
sku := fmt.Sprintf("%s-%s-%d-col-size", colorVariant.ProductGroupID, colorVariant.ProductNumber, sizeVariant.ItemNumber)
|
||||||
|
|
||||||
var variantFlat gm.ProductFlat
|
var variantFlat gm.ProductFlat
|
||||||
|
|
@ -992,9 +996,9 @@ func UpdateProduct(product models.Product, db *gorm.DB, productFlat gm.ProductFl
|
||||||
productFlat.MinPrice = minPrice
|
productFlat.MinPrice = minPrice
|
||||||
productFlat.MaxPrice = maxPrice
|
productFlat.MaxPrice = maxPrice
|
||||||
|
|
||||||
} else if len(product.SizeVariants) > 0 {
|
} else if len(*product.SizeVariants) > 0 {
|
||||||
|
|
||||||
for _, sizeVariant := range product.SizeVariants {
|
for _, sizeVariant := range *product.SizeVariants {
|
||||||
sku := fmt.Sprintf("%s-%s-%d-size", product.ProductGroupID, product.ProductNumber, sizeVariant.ItemNumber)
|
sku := fmt.Sprintf("%s-%s-%d-size", product.ProductGroupID, product.ProductNumber, sizeVariant.ItemNumber)
|
||||||
var variantFlat gm.ProductFlat
|
var variantFlat gm.ProductFlat
|
||||||
err := db.Where("sku=?", sku).First(&variantFlat).Error
|
err := db.Where("sku=?", sku).First(&variantFlat).Error
|
||||||
|
|
|
||||||
|
|
@ -1 +1,50 @@
|
||||||
package controller
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"db_service/repositories"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"math/big"
|
||||||
|
"net/http"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func StartProductImport(w http.ResponseWriter, _ *http.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))
|
||||||
|
|
||||||
|
importRepo, err := repositories.ImporterInstance()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//wait until initialization data is loaded to memory
|
||||||
|
importRepo.ImportWGroup.Wait()
|
||||||
|
|
||||||
|
if err = importRepo.Start().Error; err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
importRepo.ImportWGroup.Wait()
|
||||||
|
|
||||||
|
elapsed := time.Since(start)
|
||||||
|
log.Printf("end import took %s", elapsed)
|
||||||
|
http.Error(w, fmt.Sprintf("end import took %s", elapsed), http.StatusOK)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,14 +24,25 @@ type Category struct {
|
||||||
Translations []CategoryTranslation
|
Translations []CategoryTranslation
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMainCategories(db *gorm.DB) []Category {
|
func GetMainCategories(db *gorm.DB) ([]Category, error) {
|
||||||
var categories []Category
|
var categories []Category
|
||||||
err := db.Model(&Category{}).Preload("Translations").Find(&categories, "status=1 AND parent_id=1 AND display_mode!='promotion'").Error
|
err := db.Model(&Category{}).Preload("Translations").Find(&categories, "status=1 AND parent_id=1 AND display_mode!='promotion'").Error
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err.Error())
|
log.Println(err.Error())
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return categories
|
return categories, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCatKeywords(db *gorm.DB, catIDs []int) ([]Category, error) {
|
||||||
|
var categories []Category
|
||||||
|
|
||||||
|
if errCat := db.Preload("Translations", "locale=?", "tm").Find(&categories, catIDs).Error; errCat != nil {
|
||||||
|
log.Println(errCat)
|
||||||
|
return categories, errCat
|
||||||
|
}
|
||||||
|
|
||||||
|
return categories, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,3 +68,16 @@ func GetAttributeOption(db *gorm.DB, attrbuteID uint, value string) AttributeOpt
|
||||||
}
|
}
|
||||||
return option
|
return option
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetAttrOptions(db *gorm.DB, attrbuteID uint) ([]AttributeOption, error) {
|
||||||
|
|
||||||
|
var options []AttributeOption
|
||||||
|
|
||||||
|
err := db.Find(&options, AttributeOption{AttributeID: attrbuteID}).Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return options, err
|
||||||
|
}
|
||||||
|
|
|
||||||
3
main.go
3
main.go
|
|
@ -46,7 +46,8 @@ func InitCouchDbServer() error {
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
route := mux.NewRouter()
|
route := mux.NewRouter()
|
||||||
route.HandleFunc("/init-importer", controller.StartImport)
|
//route.HandleFunc("/init-importer", controller.StartImport)
|
||||||
|
route.HandleFunc("/init-importer", controller.StartProductImport)
|
||||||
route.HandleFunc("/parse-link", controller.ParseLink)
|
route.HandleFunc("/parse-link", controller.ParseLink)
|
||||||
err := http.ListenAndServe(os.Getenv("port"), route)
|
err := http.ListenAndServe(os.Getenv("port"), route)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ type Product struct {
|
||||||
Cinsiyet string `json:"cinsiyet"`
|
Cinsiyet string `json:"cinsiyet"`
|
||||||
Color string `json:"color"`
|
Color string `json:"color"`
|
||||||
ColorVariantCount int `json:"color_variant_count"`
|
ColorVariantCount int `json:"color_variant_count"`
|
||||||
ColorVariants []Product `json:"color_variants"`
|
ColorVariants *[]Product `json:"color_variants"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
IsSellable bool `json:"sellable"`
|
IsSellable bool `json:"sellable"`
|
||||||
FavoriteCount int `json:"favorite_count"`
|
FavoriteCount int `json:"favorite_count"`
|
||||||
|
|
@ -23,7 +23,7 @@ type Product struct {
|
||||||
ProductGroupID string `json:"product_group_id"`
|
ProductGroupID string `json:"product_group_id"`
|
||||||
ProductNumber string `json:"product_number"`
|
ProductNumber string `json:"product_number"`
|
||||||
ShortDescription string `json:"short_description"`
|
ShortDescription string `json:"short_description"`
|
||||||
SizeVariants []Variant `json:"size_variants"`
|
SizeVariants *[]Variant `json:"size_variants"`
|
||||||
Sku string `json:"sku"`
|
Sku string `json:"sku"`
|
||||||
Stock interface{} `json:"stock"`
|
Stock interface{} `json:"stock"`
|
||||||
URLKey string `json:"url_key"`
|
URLKey string `json:"url_key"`
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,253 @@ package repositories
|
||||||
|
|
||||||
import (
|
import (
|
||||||
gm "db_service/gorm_models"
|
gm "db_service/gorm_models"
|
||||||
|
"db_service/models"
|
||||||
|
helper "db_service/pkg"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"gorm.io/driver/mysql"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Importer struct {
|
type Importer struct {
|
||||||
mainCategories []gm.Category
|
mainCategories []gm.Category
|
||||||
baza *gorm.DB
|
baza *gorm.DB
|
||||||
families []gm.AttributeFamily
|
families []gm.AttributeFamily
|
||||||
|
sellers map[string]gm.MarketplaceSeller
|
||||||
|
AttributesMap map[string]gm.Attribute
|
||||||
|
Error error
|
||||||
|
ImportWGroup sync.WaitGroup
|
||||||
|
ColorOptions map[string]gm.AttributeOption
|
||||||
|
SexOptions map[string]gm.AttributeOption
|
||||||
}
|
}
|
||||||
|
|
||||||
func ImporterInstance() Importer {
|
func ImporterInstance() (instance *Importer, err error) {
|
||||||
return Importer{}
|
|
||||||
|
db, err := gorm.Open(mysql.Open(os.Getenv("database_url")), &gorm.Config{SkipDefaultTransaction: true})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
instance = &Importer{baza: db}
|
||||||
|
|
||||||
|
instance.ImportWGroup.Add(4)
|
||||||
|
|
||||||
|
//load main categories to memory
|
||||||
|
go func(db *gorm.DB) {
|
||||||
|
defer instance.ImportWGroup.Done()
|
||||||
|
instance.mainCategories, instance.Error = gm.GetMainCategories(db)
|
||||||
|
}(db)
|
||||||
|
|
||||||
|
//load families to memory
|
||||||
|
go func() {
|
||||||
|
defer instance.ImportWGroup.Done()
|
||||||
|
instance.families, instance.Error = gm.GetFamilies(db)
|
||||||
|
}()
|
||||||
|
|
||||||
|
//load attributes to memory
|
||||||
|
go func() {
|
||||||
|
defer instance.ImportWGroup.Done()
|
||||||
|
|
||||||
|
if attributes, err := gm.GetAttributes(db); err != nil {
|
||||||
|
instance.Error = err
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
instance.AttributesMap = make(map[string]gm.Attribute, len(attributes))
|
||||||
|
|
||||||
|
for _, attribute := range attributes {
|
||||||
|
instance.AttributesMap[attribute.Code] = attribute
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if colorOptions, err := gm.GetAttrOptions(db, instance.AttributesMap["color"].ID); err != nil {
|
||||||
|
instance.Error = err
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
instance.ColorOptions = make(map[string]gm.AttributeOption, len(colorOptions))
|
||||||
|
|
||||||
|
for _, option := range colorOptions {
|
||||||
|
instance.ColorOptions[option.AdminName] = option
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if sexOPtions, err := gm.GetAttrOptions(db, instance.AttributesMap["cinsiyet"].ID); err != nil {
|
||||||
|
instance.Error = err
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
instance.SexOptions = make(map[string]gm.AttributeOption, len(sexOPtions))
|
||||||
|
|
||||||
|
for _, option := range sexOPtions {
|
||||||
|
instance.SexOptions[option.AdminName] = option
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}()
|
||||||
|
|
||||||
|
//load sellers to memory
|
||||||
|
go func() {
|
||||||
|
defer instance.ImportWGroup.Done()
|
||||||
|
|
||||||
|
var vendors, err = gm.GetSellers(db)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
instance.Error = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//init sellers map
|
||||||
|
instance.sellers = make(map[string]gm.MarketplaceSeller, len(vendors))
|
||||||
|
|
||||||
|
for _, vendor := range vendors {
|
||||||
|
instance.sellers[vendor.Url] = vendor
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if instance.Error != nil {
|
||||||
|
log.Println(instance.Error)
|
||||||
|
return nil, instance.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (importer *Importer) Start() (instance *Importer) {
|
||||||
|
//init wait group to main categories length
|
||||||
|
importer.ImportWGroup.Add(len(importer.mainCategories))
|
||||||
|
//start gorutines for each main category
|
||||||
|
for _, element := range importer.mainCategories {
|
||||||
|
|
||||||
|
slug := element.Translations[0].Slug
|
||||||
|
|
||||||
|
go importer.categoryRoutine("ty_db_" + slug)
|
||||||
|
}
|
||||||
|
|
||||||
|
return importer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (importer *Importer) categoryRoutine(dbName string) {
|
||||||
|
defer importer.ImportWGroup.Done()
|
||||||
|
|
||||||
|
if dbExists := helper.CheckDBExists(os.Getenv("couch_db_source") + dbName); dbExists {
|
||||||
|
|
||||||
|
totalDocCount := getTotalDocumentCount(dbName)
|
||||||
|
skip := 0
|
||||||
|
limit := 200
|
||||||
|
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 := importer.ImportProduct(element.Doc).Error; err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
} else {
|
||||||
|
totalImport++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("%s total imported documents count %d \n", dbName, totalImport)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.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 (importer *Importer) ImportProduct(product models.Product) (instance *Importer) {
|
||||||
|
|
||||||
|
productRepo := InitProductRepo(&product, importer.GetColorOption(product.Color), importer.GetSexOption(product.Cinsiyet))
|
||||||
|
var categories []gm.Category
|
||||||
|
|
||||||
|
if categories, importer.Error = gm.GetCatKeywords(importer.baza, product.Categories); importer.Error != nil {
|
||||||
|
log.Println("ERR0 Categories" + importer.Error.Error())
|
||||||
|
return importer
|
||||||
|
}
|
||||||
|
|
||||||
|
productRepo.SetCategories(categories)
|
||||||
|
|
||||||
|
if productRepo.Brand, importer.Error = gm.FindOrCreateBrand(importer.baza, product.Brand, productRepo.Categories); importer.Error != nil {
|
||||||
|
log.Println("ERR BRAND" + importer.Error.Error())
|
||||||
|
return importer
|
||||||
|
}
|
||||||
|
|
||||||
|
//BEGIN TRANSACTION
|
||||||
|
//tx := *importer.baza.Begin()
|
||||||
|
|
||||||
|
return importer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (importer *Importer) GetColorOption(optionName string) gm.AttributeOption {
|
||||||
|
if optionName == "" {
|
||||||
|
return gm.AttributeOption{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if option, ok := importer.ColorOptions[optionName]; ok {
|
||||||
|
return option
|
||||||
|
} else {
|
||||||
|
option := gm.GetAttributeOption(importer.baza, importer.AttributesMap["color"].ID, optionName)
|
||||||
|
|
||||||
|
importer.ColorOptions[optionName] = option
|
||||||
|
return option
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (importer *Importer) GetSexOption(optionName string) gm.AttributeOption {
|
||||||
|
if optionName == "" {
|
||||||
|
return gm.AttributeOption{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if option, ok := importer.ColorOptions[optionName]; ok {
|
||||||
|
return option
|
||||||
|
} else {
|
||||||
|
option := gm.GetAttributeOption(importer.baza, importer.AttributesMap["cinsiyet"].ID, optionName)
|
||||||
|
|
||||||
|
importer.SexOptions[optionName] = option
|
||||||
|
return option
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,251 @@
|
||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
gm "db_service/gorm_models"
|
||||||
|
"db_service/models"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProductRepo struct {
|
||||||
|
Categories []gm.Category
|
||||||
|
Brand gm.Brand
|
||||||
|
Weight float64
|
||||||
|
Description string
|
||||||
|
Keywords string
|
||||||
|
Data *models.Product
|
||||||
|
Error error
|
||||||
|
ColorOption gm.AttributeOption
|
||||||
|
SexOption gm.AttributeOption
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitProductRepo(data *models.Product, color, sex gm.AttributeOption) *ProductRepo {
|
||||||
|
|
||||||
|
weight, wError := strconv.ParseFloat(data.Weight, 64)
|
||||||
|
|
||||||
|
if wError != nil || weight == 0 {
|
||||||
|
weight = 0.5
|
||||||
|
}
|
||||||
|
|
||||||
|
var description string
|
||||||
|
|
||||||
|
for _, desc := range data.Descriptions {
|
||||||
|
description += "<p>" + desc.Description + "</p>"
|
||||||
|
}
|
||||||
|
|
||||||
|
instance := &ProductRepo{
|
||||||
|
Weight: weight,
|
||||||
|
Description: description,
|
||||||
|
Data: data,
|
||||||
|
ColorOption: color,
|
||||||
|
SexOption: sex,
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *ProductRepo) SetCategories(categories []gm.Category) {
|
||||||
|
pr.Categories = categories
|
||||||
|
pr.Keywords = pr.Data.Brand
|
||||||
|
|
||||||
|
for _, cat := range categories {
|
||||||
|
//log.Println(cat)
|
||||||
|
if len(cat.Translations) > 0 && cat.Translations[0].MetaKeywords != "" {
|
||||||
|
translation := cat.Translations[0]
|
||||||
|
|
||||||
|
pr.Keywords += "," + translation.MetaKeywords
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *ProductRepo) makeProduct(imp *Importer) gm.Product {
|
||||||
|
var famID uint = 1
|
||||||
|
|
||||||
|
if len(imp.families) > 0 { //todo make real fam function
|
||||||
|
famID = imp.families[0].ID
|
||||||
|
}
|
||||||
|
|
||||||
|
product := gm.Product{
|
||||||
|
Sku: pr.Data.ProductNumber,
|
||||||
|
Type: "simple",
|
||||||
|
AttributeFamilyID: famID,
|
||||||
|
BrandID: pr.Brand.ID,
|
||||||
|
Categories: pr.Categories,
|
||||||
|
AttributeValues: pr.getProductAttributes(imp.AttributesMap, pr.Data),
|
||||||
|
}
|
||||||
|
|
||||||
|
if pr.Data.SizeVariants != nil && len(*pr.Data.SizeVariants) > 0 {
|
||||||
|
product.Type = "configurable"
|
||||||
|
product.SuperAttributes = []gm.Attribute{imp.AttributesMap["size"]}
|
||||||
|
} else {
|
||||||
|
price := pr.Data.Price
|
||||||
|
|
||||||
|
if price.OriginalPrice.Value > price.DiscountedPrice.Value {
|
||||||
|
product.AttributeValues = append(product.AttributeValues, []gm.ProductAttributeValue{
|
||||||
|
{AttributeID: imp.AttributesMap["price"].ID, FloatValue: price.OriginalPrice.Value},
|
||||||
|
{AttributeID: imp.AttributesMap["special_price"].ID, FloatValue: price.DiscountedPrice.Value},
|
||||||
|
}...)
|
||||||
|
} else {
|
||||||
|
product.AttributeValues = append(product.AttributeValues, gm.ProductAttributeValue{
|
||||||
|
AttributeID: imp.AttributesMap["price"].ID, FloatValue: price.DiscountedPrice.Value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, element := range pr.Data.Images {
|
||||||
|
product.Images = append(product.Images, gm.ProductImage{Type: "cdn", Path: element})
|
||||||
|
}
|
||||||
|
|
||||||
|
return product
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *ProductRepo) makeVariant(parentID, famID uint) gm.Product {
|
||||||
|
|
||||||
|
//todo
|
||||||
|
product := gm.Product{
|
||||||
|
Sku: pr.Data.ProductNumber,
|
||||||
|
Type: "simple",
|
||||||
|
AttributeFamilyID: famID,
|
||||||
|
BrandID: pr.Brand.ID,
|
||||||
|
Categories: pr.Categories,
|
||||||
|
ParentID: parentID,
|
||||||
|
}
|
||||||
|
|
||||||
|
return product
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *ProductRepo) makeProductFlat(im *Importer) gm.ProductFlat {
|
||||||
|
|
||||||
|
flat := gm.ProductFlat{
|
||||||
|
|
||||||
|
Status: true,
|
||||||
|
VisibleIndividually: true,
|
||||||
|
Name: pr.Data.Name,
|
||||||
|
Sku: pr.Data.ProductGroupID,
|
||||||
|
//ProductNumber: pr.Data.ProductNumber,
|
||||||
|
Description: pr.Description,
|
||||||
|
//UrlKey: pr.Data.ProductGroupID,
|
||||||
|
Weight: pr.Weight,
|
||||||
|
FavoritesCount: uint(pr.Data.FavoriteCount),
|
||||||
|
MaxPrice: 0,
|
||||||
|
MinPrice: 0,
|
||||||
|
Price: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
if pr.Data.Color != "" {
|
||||||
|
flat.Color = int(im.GetColorOption(pr.Data.Color).ID)
|
||||||
|
flat.ColorLabel = pr.Data.Color
|
||||||
|
}
|
||||||
|
|
||||||
|
if pr.Data.SizeVariants != nil && len(*pr.Data.SizeVariants) > 0 {
|
||||||
|
|
||||||
|
for _, variant := range *pr.Data.SizeVariants {
|
||||||
|
price := variant.Price
|
||||||
|
|
||||||
|
if flat.MinPrice == 0 || flat.MinPrice > price.DiscountedPrice.Value {
|
||||||
|
flat.MaxPrice = price.DiscountedPrice.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
maxPrice := math.Max(price.OriginalPrice.Value, price.DiscountedPrice.Value)
|
||||||
|
if flat.MaxPrice == 0 || flat.MaxPrice < maxPrice {
|
||||||
|
flat.MaxPrice = maxPrice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
flat.MinPrice = pr.Data.Price.DiscountedPrice.Value
|
||||||
|
flat.MaxPrice = math.Max(pr.Data.Price.OriginalPrice.Value, pr.Data.Price.DiscountedPrice.Value)
|
||||||
|
flat.Price = flat.MaxPrice
|
||||||
|
|
||||||
|
if flat.MinPrice < flat.MaxPrice {
|
||||||
|
flat.SpecialPrice = flat.MinPrice
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return flat
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *ProductRepo) makeVariantFlat(variant models.Variant, SizID int) gm.ProductFlat {
|
||||||
|
|
||||||
|
maxPRice := math.Max(variant.Price.OriginalPrice.Value, variant.Price.DiscountedPrice.Value)
|
||||||
|
|
||||||
|
flat := gm.ProductFlat{
|
||||||
|
Status: true,
|
||||||
|
Name: pr.Data.Name,
|
||||||
|
Sku: pr.Data.ProductGroupID,
|
||||||
|
ProductNumber: pr.Data.ProductNumber,
|
||||||
|
Weight: pr.Weight,
|
||||||
|
FavoritesCount: uint(pr.Data.FavoriteCount),
|
||||||
|
SizeLabel: variant.AttributeValue,
|
||||||
|
Size: SizID,
|
||||||
|
MaxPrice: maxPRice,
|
||||||
|
MinPrice: variant.Price.DiscountedPrice.Value,
|
||||||
|
Price: maxPRice,
|
||||||
|
}
|
||||||
|
|
||||||
|
if flat.MaxPrice > flat.MinPrice {
|
||||||
|
flat.SpecialPrice = flat.MinPrice
|
||||||
|
}
|
||||||
|
|
||||||
|
if pr.Data.Color != "" {
|
||||||
|
flat.Color = int(pr.ColorOption.ID)
|
||||||
|
flat.ColorLabel = pr.Data.Color
|
||||||
|
}
|
||||||
|
|
||||||
|
return flat
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *ProductRepo) getProductAttributes(AttributesMap map[string]gm.Attribute, product *models.Product) []gm.ProductAttributeValue {
|
||||||
|
attributes := []gm.ProductAttributeValue{
|
||||||
|
{AttributeID: AttributesMap["source"].ID, TextValue: product.URLKey},
|
||||||
|
{AttributeID: AttributesMap["favoritesCount"].ID, IntegerValue: product.FavoriteCount},
|
||||||
|
{AttributeID: AttributesMap["sku"].ID, TextValue: product.ProductNumber},
|
||||||
|
{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["description"].ID, TextValue: pr.Description, Channel: "default", Locale: "tm"},
|
||||||
|
{AttributeID: AttributesMap["meta_keywords"].ID, TextValue: pr.Keywords, Channel: "default", Locale: "tm"},
|
||||||
|
}
|
||||||
|
|
||||||
|
if product.Color != "" {
|
||||||
|
attributes = append(attributes, gm.ProductAttributeValue{AttributeID: AttributesMap["color"].ID, IntegerValue: int(pr.ColorOption.ID)})
|
||||||
|
}
|
||||||
|
|
||||||
|
if product.Cinsiyet != "" {
|
||||||
|
attributes = append(attributes, gm.ProductAttributeValue{AttributeID: AttributesMap["cinsiyet"].ID, IntegerValue: int(pr.SexOption.ID)})
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributes
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pr *ProductRepo) getVariantAttributes(AttributesMap map[string]gm.Attribute, product *models.Variant, SizID int) []gm.ProductAttributeValue {
|
||||||
|
|
||||||
|
price := math.Max(product.Price.OriginalPrice.Value, product.Price.DiscountedPrice.Value)
|
||||||
|
|
||||||
|
attributes := []gm.ProductAttributeValue{
|
||||||
|
{AttributeID: AttributesMap["source"].ID, TextValue: pr.Data.URLKey},
|
||||||
|
{AttributeID: AttributesMap["sku"].ID, TextValue: string(rune(product.ItemNumber))}, //todo unique
|
||||||
|
{AttributeID: AttributesMap["product_number"].ID, TextValue: string(rune(product.ItemNumber))}, //todo unique
|
||||||
|
{AttributeID: AttributesMap["name"].ID, TextValue: pr.Data.Name, Channel: "default", Locale: "tm"},
|
||||||
|
{AttributeID: AttributesMap["weight"].ID, TextValue: pr.Data.Weight},
|
||||||
|
{AttributeID: AttributesMap["status"].ID, BooleanValue: true},
|
||||||
|
{AttributeID: AttributesMap["size"].ID, IntegerValue: SizID},
|
||||||
|
{AttributeID: AttributesMap["price"].ID, FloatValue: price},
|
||||||
|
}
|
||||||
|
|
||||||
|
if pr.Data.Color != "" {
|
||||||
|
attributes = append(attributes, gm.ProductAttributeValue{AttributeID: AttributesMap["color"].ID, IntegerValue: int(pr.ColorOption.ID)})
|
||||||
|
}
|
||||||
|
|
||||||
|
if pr.Data.Cinsiyet != "" {
|
||||||
|
attributes = append(attributes, gm.ProductAttributeValue{AttributeID: AttributesMap["cinsiyet"].ID, IntegerValue: int(pr.SexOption.ID)})
|
||||||
|
}
|
||||||
|
|
||||||
|
if product.Price.OriginalPrice.Value > product.Price.DiscountedPrice.Value {
|
||||||
|
attributes = append(attributes, gm.ProductAttributeValue{AttributeID: AttributesMap["special_price"].ID, FloatValue: product.Price.DiscountedPrice.Value})
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributes
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue