finish before delete && flush
This commit is contained in:
parent
2697692b57
commit
6a15c0ff69
|
|
@ -23,6 +23,12 @@ type Product struct {
|
||||||
Categories []Category `gorm:"many2many:product_categories;"`
|
Categories []Category `gorm:"many2many:product_categories;"`
|
||||||
AttributeValues []ProductAttributeValue
|
AttributeValues []ProductAttributeValue
|
||||||
SuperAttributes []Attribute `gorm:"many2many:product_super_attributes;"`
|
SuperAttributes []Attribute `gorm:"many2many:product_super_attributes;"`
|
||||||
|
//Variants []*Product `gorm:"many2many:product_relations;foreignKey:child_id;primaryKey:parent_id;"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProductRelation struct {
|
||||||
|
ParentID uint
|
||||||
|
ChildID uint
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductFlat struct {
|
type ProductFlat struct {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -25,6 +26,8 @@ type Importer struct {
|
||||||
ImportWGroup sync.WaitGroup
|
ImportWGroup sync.WaitGroup
|
||||||
ColorOptions map[string]gm.AttributeOption
|
ColorOptions map[string]gm.AttributeOption
|
||||||
SexOptions map[string]gm.AttributeOption
|
SexOptions map[string]gm.AttributeOption
|
||||||
|
ColorMutex sync.Mutex
|
||||||
|
SexMutex sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func ImporterInstance() (instance *Importer, err error) {
|
func ImporterInstance() (instance *Importer, err error) {
|
||||||
|
|
@ -205,21 +208,37 @@ func getTotalDocumentCount(db string) int {
|
||||||
func (importer *Importer) ImportProduct(product models.Product) (instance *Importer) {
|
func (importer *Importer) ImportProduct(product models.Product) (instance *Importer) {
|
||||||
|
|
||||||
var linkedProducts []gm.Product
|
var linkedProducts []gm.Product
|
||||||
if firstProduct, err := importer.importVariant(product); err == nil {
|
var firstProduct *gm.Product
|
||||||
|
if firstProduct, importer.Error = importer.importVariant(product); importer.Error != nil {
|
||||||
|
return importer
|
||||||
|
} else if product.ColorVariants != nil && len(*product.ColorVariants) > 0 {
|
||||||
linkedProducts = append(linkedProducts, *firstProduct)
|
linkedProducts = append(linkedProducts, *firstProduct)
|
||||||
}
|
|
||||||
|
|
||||||
if product.ColorVariants != nil && len(*product.ColorVariants) > 0 {
|
|
||||||
for _, colorVariant := range *product.ColorVariants {
|
for _, colorVariant := range *product.ColorVariants {
|
||||||
|
|
||||||
|
if !colorVariant.IsSellable {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if variant, err := importer.importVariant(colorVariant); err == nil {
|
if variant, err := importer.importVariant(colorVariant); err == nil {
|
||||||
linkedProducts = append(linkedProducts, *variant)
|
linkedProducts = append(linkedProducts, *variant)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(linkedProducts) > 0 {
|
if len(linkedProducts) > 1 {
|
||||||
//todo link products
|
//todo link products
|
||||||
|
var relation []gm.ProductRelation
|
||||||
|
for index, variant := range linkedProducts {
|
||||||
|
//spoint := "color" + strconv.Itoa(index)
|
||||||
|
for _, item := range append(linkedProducts[:index], linkedProducts[index+1:]...) {
|
||||||
|
relation = append(relation, gm.ProductRelation{ParentID: variant.ID, ChildID: item.ID})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := importer.baza.Create(&relation).Error; err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return importer
|
return importer
|
||||||
|
|
@ -243,9 +262,7 @@ func (importer *Importer) importVariant(product models.Product) (*gm.Product, er
|
||||||
mainPorduct := productRepo.makeProduct(importer)
|
mainPorduct := productRepo.makeProduct(importer)
|
||||||
|
|
||||||
//BEGIN TRANSACTION
|
//BEGIN TRANSACTION
|
||||||
tx := *importer.baza.Begin()
|
tx := importer.baza.Begin()
|
||||||
|
|
||||||
importer.Error = tx.Omit("Categories.*", "SuperAttributes.*", "ParentID").Create(&mainPorduct).Error
|
|
||||||
|
|
||||||
if err := tx.Omit("Categories.*", "SuperAttributes.*", "ParentID").Create(&mainPorduct).Error; err != nil {
|
if err := tx.Omit("Categories.*", "SuperAttributes.*", "ParentID").Create(&mainPorduct).Error; err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
|
|
@ -261,32 +278,37 @@ func (importer *Importer) importVariant(product models.Product) (*gm.Product, er
|
||||||
|
|
||||||
if productRepo.HasSizeVariants() {
|
if productRepo.HasSizeVariants() {
|
||||||
var sizeVariants []gm.ProductFlat
|
var sizeVariants []gm.ProductFlat
|
||||||
for _, variant := range *product.SizeVariants {
|
for index, variant := range *product.SizeVariants {
|
||||||
tx.SavePoint(variant.ListingID)
|
if !variant.Sellable {
|
||||||
sizeOPtion := gm.GetAttributeOption(&tx, importer.AttributesMap["size"].ID, variant.AttributeValue)
|
continue
|
||||||
|
}
|
||||||
|
savePoint := "size" + strconv.Itoa(index)
|
||||||
|
tx.SavePoint(savePoint)
|
||||||
|
sizeOPtion := gm.GetAttributeOption(tx, importer.AttributesMap["size"].ID, variant.AttributeValue)
|
||||||
|
|
||||||
variantProduct := productRepo.makeVariant(mainPorduct.ID, mainPorduct.AttributeFamilyID)
|
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)
|
variantProduct.AttributeValues = productRepo.getVariantAttributes(importer.AttributesMap, &variant, sizeOPtion.ID)
|
||||||
|
|
||||||
if err := tx.Omit("Categories.*").Create(&variantProduct).Error; err != nil {
|
if err := tx.Omit("Categories.*").Create(&variantProduct).Error; err != nil {
|
||||||
log.Println("Variant Product Create Error: " + err.Error())
|
log.Println("Variant Product Create Error: " + err.Error())
|
||||||
tx.RollbackTo(variant.ListingID)
|
tx.RollbackTo(savePoint)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
variantFlat := productRepo.makeVariantFlat(variant, sizeOPtion.ID, mainFlat.ID)
|
variantFlat := productRepo.makeVariantFlat(variant, sizeOPtion.ID, mainFlat.ID, variantProduct.ID)
|
||||||
|
|
||||||
if err := tx.Create(&variantFlat).Error; err != nil {
|
if err := tx.Create(&variantFlat).Error; err != nil {
|
||||||
log.Println("Variant Flat Create Error: " + err.Error())
|
log.Println("Variant Flat Create Error: " + err.Error())
|
||||||
tx.RollbackTo(variant.ListingID)
|
tx.RollbackTo(savePoint)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
sizeVariants = append(sizeVariants, variantFlat)
|
sizeVariants = append(sizeVariants, variantFlat)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(sizeVariants) > 0 {
|
if len(sizeVariants) == 0 {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return nil, errors.New("siz variantlary yok bolsa main productam girayenok")
|
return nil, errors.New("siz variantlary yok bolsa main productam girayenok")
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -324,27 +346,31 @@ func (importer *Importer) GetColorOption(optionName string) gm.AttributeOption {
|
||||||
return gm.AttributeOption{}
|
return gm.AttributeOption{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if option, ok := importer.ColorOptions[optionName]; ok {
|
importer.ColorMutex.Lock()
|
||||||
return option
|
var option gm.AttributeOption
|
||||||
} else {
|
var ok bool
|
||||||
|
|
||||||
|
if option, ok = importer.ColorOptions[optionName]; !ok {
|
||||||
option := gm.GetAttributeOption(importer.baza, importer.AttributesMap["color"].ID, optionName)
|
option := gm.GetAttributeOption(importer.baza, importer.AttributesMap["color"].ID, optionName)
|
||||||
|
|
||||||
importer.ColorOptions[optionName] = option
|
importer.ColorOptions[optionName] = option
|
||||||
return option
|
|
||||||
}
|
}
|
||||||
|
importer.ColorMutex.Unlock()
|
||||||
|
return option
|
||||||
}
|
}
|
||||||
|
|
||||||
func (importer *Importer) GetSexOption(optionName string) gm.AttributeOption {
|
func (importer *Importer) GetSexOption(optionName string) gm.AttributeOption {
|
||||||
if optionName == "" {
|
if optionName == "" {
|
||||||
return gm.AttributeOption{}
|
return gm.AttributeOption{}
|
||||||
}
|
}
|
||||||
|
importer.SexMutex.Lock()
|
||||||
|
var option gm.AttributeOption
|
||||||
|
var ok bool
|
||||||
|
|
||||||
if option, ok := importer.ColorOptions[optionName]; ok {
|
if option, ok = importer.ColorOptions[optionName]; !ok {
|
||||||
return option
|
option = gm.GetAttributeOption(importer.baza, importer.AttributesMap["cinsiyet"].ID, optionName)
|
||||||
} else {
|
|
||||||
option := gm.GetAttributeOption(importer.baza, importer.AttributesMap["cinsiyet"].ID, optionName)
|
|
||||||
|
|
||||||
importer.SexOptions[optionName] = option
|
importer.SexOptions[optionName] = option
|
||||||
return option
|
|
||||||
}
|
}
|
||||||
|
importer.SexMutex.Unlock()
|
||||||
|
return option
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package repositories
|
||||||
import (
|
import (
|
||||||
gm "db_service/gorm_models"
|
gm "db_service/gorm_models"
|
||||||
"db_service/models"
|
"db_service/models"
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
@ -110,10 +111,10 @@ func (pr *ProductRepo) makeProduct(imp *Importer) gm.Product {
|
||||||
return product
|
return product
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *ProductRepo) makeVariant(parentID, famID uint) gm.Product {
|
func (pr *ProductRepo) makeVariant(parentID, famID uint, sku string) gm.Product {
|
||||||
|
|
||||||
product := gm.Product{
|
product := gm.Product{
|
||||||
Sku: pr.Data.ProductNumber,
|
Sku: sku,
|
||||||
Type: "simple",
|
Type: "simple",
|
||||||
AttributeFamilyID: famID,
|
AttributeFamilyID: famID,
|
||||||
Categories: pr.Categories,
|
Categories: pr.Categories,
|
||||||
|
|
@ -134,7 +135,7 @@ func (pr *ProductRepo) makeProductFlat(productId uint) gm.ProductFlat {
|
||||||
Status: true,
|
Status: true,
|
||||||
VisibleIndividually: true,
|
VisibleIndividually: true,
|
||||||
Name: pr.Data.Name,
|
Name: pr.Data.Name,
|
||||||
Sku: pr.Data.ProductGroupID,
|
Sku: pr.Data.ProductNumber,
|
||||||
//ProductNumber: pr.Data.ProductNumber,
|
//ProductNumber: pr.Data.ProductNumber,
|
||||||
Description: pr.Description,
|
Description: pr.Description,
|
||||||
//UrlKey: pr.Data.ProductGroupID,
|
//UrlKey: pr.Data.ProductGroupID,
|
||||||
|
|
@ -184,16 +185,17 @@ func (pr *ProductRepo) makeProductFlat(productId uint) gm.ProductFlat {
|
||||||
return flat
|
return flat
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pr *ProductRepo) makeVariantFlat(variant models.Variant, SizID, parentID uint) gm.ProductFlat {
|
func (pr *ProductRepo) makeVariantFlat(variant models.Variant, SizID, parentID, productID uint) gm.ProductFlat {
|
||||||
|
|
||||||
maxPRice := math.Max(variant.Price.OriginalPrice.Value, variant.Price.DiscountedPrice.Value)
|
maxPRice := math.Max(variant.Price.OriginalPrice.Value, variant.Price.DiscountedPrice.Value)
|
||||||
|
sku := fmt.Sprintf("%s-%d", pr.Data.ProductNumber, variant.ItemNumber)
|
||||||
|
|
||||||
flat := gm.ProductFlat{
|
flat := gm.ProductFlat{
|
||||||
ParentID: parentID,
|
ParentID: parentID,
|
||||||
Status: true,
|
Status: true,
|
||||||
Name: pr.Data.Name,
|
Name: pr.Data.Name,
|
||||||
Sku: pr.Data.ProductGroupID,
|
Sku: sku,
|
||||||
ProductNumber: pr.Data.ProductNumber,
|
ProductNumber: fmt.Sprintf("%d", variant.ItemNumber),
|
||||||
Weight: pr.Weight,
|
Weight: pr.Weight,
|
||||||
FavoritesCount: uint(pr.Data.FavoriteCount),
|
FavoritesCount: uint(pr.Data.FavoriteCount),
|
||||||
SizeLabel: variant.AttributeValue,
|
SizeLabel: variant.AttributeValue,
|
||||||
|
|
@ -201,6 +203,7 @@ func (pr *ProductRepo) makeVariantFlat(variant models.Variant, SizID, parentID u
|
||||||
MaxPrice: maxPRice,
|
MaxPrice: maxPRice,
|
||||||
MinPrice: variant.Price.DiscountedPrice.Value,
|
MinPrice: variant.Price.DiscountedPrice.Value,
|
||||||
Price: maxPRice,
|
Price: maxPRice,
|
||||||
|
ProductID: productID,
|
||||||
}
|
}
|
||||||
|
|
||||||
if flat.MaxPrice > flat.MinPrice {
|
if flat.MaxPrice > flat.MinPrice {
|
||||||
|
|
@ -242,11 +245,11 @@ func (pr *ProductRepo) getProductAttributes(AttributesMap map[string]gm.Attribut
|
||||||
func (pr *ProductRepo) getVariantAttributes(AttributesMap map[string]gm.Attribute, product *models.Variant, SizID uint) []gm.ProductAttributeValue {
|
func (pr *ProductRepo) getVariantAttributes(AttributesMap map[string]gm.Attribute, product *models.Variant, SizID uint) []gm.ProductAttributeValue {
|
||||||
|
|
||||||
price := math.Max(product.Price.OriginalPrice.Value, product.Price.DiscountedPrice.Value)
|
price := math.Max(product.Price.OriginalPrice.Value, product.Price.DiscountedPrice.Value)
|
||||||
|
sku := fmt.Sprintf("%s-%d", pr.Data.ProductNumber, product.ItemNumber)
|
||||||
attributes := []gm.ProductAttributeValue{
|
attributes := []gm.ProductAttributeValue{
|
||||||
{AttributeID: AttributesMap["source"].ID, TextValue: pr.Data.URLKey},
|
{AttributeID: AttributesMap["source"].ID, TextValue: pr.Data.URLKey},
|
||||||
{AttributeID: AttributesMap["sku"].ID, TextValue: string(rune(product.ItemNumber))}, //todo unique
|
{AttributeID: AttributesMap["sku"].ID, TextValue: sku}, //todo unique
|
||||||
{AttributeID: AttributesMap["product_number"].ID, TextValue: string(rune(product.ItemNumber))}, //todo unique
|
{AttributeID: AttributesMap["product_number"].ID, TextValue: fmt.Sprintf("%d", product.ItemNumber)}, //todo unique
|
||||||
{AttributeID: AttributesMap["name"].ID, TextValue: pr.Data.Name, Channel: "default", Locale: "tm"},
|
{AttributeID: AttributesMap["name"].ID, TextValue: pr.Data.Name, Channel: "default", Locale: "tm"},
|
||||||
{AttributeID: AttributesMap["weight"].ID, TextValue: pr.Data.Weight},
|
{AttributeID: AttributesMap["weight"].ID, TextValue: pr.Data.Weight},
|
||||||
{AttributeID: AttributesMap["status"].ID, BooleanValue: true},
|
{AttributeID: AttributesMap["status"].ID, BooleanValue: true},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue