finish before delete && flush

This commit is contained in:
merdan 2022-10-08 15:57:03 +05:00
parent 2697692b57
commit 6a15c0ff69
3 changed files with 70 additions and 35 deletions

View File

@ -23,6 +23,12 @@ type Product struct {
Categories []Category `gorm:"many2many:product_categories;"`
AttributeValues []ProductAttributeValue
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 {

View File

@ -12,6 +12,7 @@ import (
"log"
"math"
"os"
"strconv"
"sync"
)
@ -25,6 +26,8 @@ type Importer struct {
ImportWGroup sync.WaitGroup
ColorOptions map[string]gm.AttributeOption
SexOptions map[string]gm.AttributeOption
ColorMutex sync.Mutex
SexMutex sync.Mutex
}
func ImporterInstance() (instance *Importer, err error) {
@ -205,21 +208,37 @@ func getTotalDocumentCount(db string) int {
func (importer *Importer) ImportProduct(product models.Product) (instance *Importer) {
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)
}
if product.ColorVariants != nil && len(*product.ColorVariants) > 0 {
for _, colorVariant := range *product.ColorVariants {
if !colorVariant.IsSellable {
continue
}
if variant, err := importer.importVariant(colorVariant); err == nil {
linkedProducts = append(linkedProducts, *variant)
}
}
}
if len(linkedProducts) > 0 {
if len(linkedProducts) > 1 {
//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
@ -243,9 +262,7 @@ func (importer *Importer) importVariant(product models.Product) (*gm.Product, er
mainPorduct := productRepo.makeProduct(importer)
//BEGIN TRANSACTION
tx := *importer.baza.Begin()
importer.Error = tx.Omit("Categories.*", "SuperAttributes.*", "ParentID").Create(&mainPorduct).Error
tx := importer.baza.Begin()
if err := tx.Omit("Categories.*", "SuperAttributes.*", "ParentID").Create(&mainPorduct).Error; err != nil {
tx.Rollback()
@ -261,32 +278,37 @@ func (importer *Importer) importVariant(product models.Product) (*gm.Product, er
if productRepo.HasSizeVariants() {
var sizeVariants []gm.ProductFlat
for _, variant := range *product.SizeVariants {
tx.SavePoint(variant.ListingID)
sizeOPtion := gm.GetAttributeOption(&tx, importer.AttributesMap["size"].ID, variant.AttributeValue)
for index, variant := range *product.SizeVariants {
if !variant.Sellable {
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)
if err := tx.Omit("Categories.*").Create(&variantProduct).Error; err != nil {
log.Println("Variant Product Create Error: " + err.Error())
tx.RollbackTo(variant.ListingID)
tx.RollbackTo(savePoint)
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 {
log.Println("Variant Flat Create Error: " + err.Error())
tx.RollbackTo(variant.ListingID)
tx.RollbackTo(savePoint)
continue
}
sizeVariants = append(sizeVariants, variantFlat)
}
if len(sizeVariants) > 0 {
if len(sizeVariants) == 0 {
tx.Rollback()
return nil, errors.New("siz variantlary yok bolsa main productam girayenok")
} else {
@ -324,27 +346,31 @@ func (importer *Importer) GetColorOption(optionName string) gm.AttributeOption {
return gm.AttributeOption{}
}
if option, ok := importer.ColorOptions[optionName]; ok {
return option
} else {
importer.ColorMutex.Lock()
var option gm.AttributeOption
var ok bool
if option, ok = importer.ColorOptions[optionName]; !ok {
option := gm.GetAttributeOption(importer.baza, importer.AttributesMap["color"].ID, optionName)
importer.ColorOptions[optionName] = option
return option
}
importer.ColorMutex.Unlock()
return option
}
func (importer *Importer) GetSexOption(optionName string) gm.AttributeOption {
if optionName == "" {
return gm.AttributeOption{}
}
importer.SexMutex.Lock()
var option gm.AttributeOption
var ok bool
if option, ok := importer.ColorOptions[optionName]; ok {
return option
} else {
option := gm.GetAttributeOption(importer.baza, importer.AttributesMap["cinsiyet"].ID, optionName)
if option, ok = importer.ColorOptions[optionName]; !ok {
option = gm.GetAttributeOption(importer.baza, importer.AttributesMap["cinsiyet"].ID, optionName)
importer.SexOptions[optionName] = option
return option
}
importer.SexMutex.Unlock()
return option
}

View File

@ -3,6 +3,7 @@ package repositories
import (
gm "db_service/gorm_models"
"db_service/models"
"fmt"
"math"
"strconv"
)
@ -110,10 +111,10 @@ func (pr *ProductRepo) makeProduct(imp *Importer) gm.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{
Sku: pr.Data.ProductNumber,
Sku: sku,
Type: "simple",
AttributeFamilyID: famID,
Categories: pr.Categories,
@ -134,7 +135,7 @@ func (pr *ProductRepo) makeProductFlat(productId uint) gm.ProductFlat {
Status: true,
VisibleIndividually: true,
Name: pr.Data.Name,
Sku: pr.Data.ProductGroupID,
Sku: pr.Data.ProductNumber,
//ProductNumber: pr.Data.ProductNumber,
Description: pr.Description,
//UrlKey: pr.Data.ProductGroupID,
@ -184,16 +185,17 @@ func (pr *ProductRepo) makeProductFlat(productId uint) gm.ProductFlat {
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)
sku := fmt.Sprintf("%s-%d", pr.Data.ProductNumber, variant.ItemNumber)
flat := gm.ProductFlat{
ParentID: parentID,
Status: true,
Name: pr.Data.Name,
Sku: pr.Data.ProductGroupID,
ProductNumber: pr.Data.ProductNumber,
Sku: sku,
ProductNumber: fmt.Sprintf("%d", variant.ItemNumber),
Weight: pr.Weight,
FavoritesCount: uint(pr.Data.FavoriteCount),
SizeLabel: variant.AttributeValue,
@ -201,6 +203,7 @@ func (pr *ProductRepo) makeVariantFlat(variant models.Variant, SizID, parentID u
MaxPrice: maxPRice,
MinPrice: variant.Price.DiscountedPrice.Value,
Price: maxPRice,
ProductID: productID,
}
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 {
price := math.Max(product.Price.OriginalPrice.Value, product.Price.DiscountedPrice.Value)
sku := fmt.Sprintf("%s-%d", pr.Data.ProductNumber, product.ItemNumber)
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["sku"].ID, TextValue: sku}, //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["weight"].ID, TextValue: pr.Data.Weight},
{AttributeID: AttributesMap["status"].ID, BooleanValue: true},