new v3 import save product ready

This commit is contained in:
merdan 2022-10-03 17:32:27 +05:00
parent 773183c9b3
commit 2697692b57
2 changed files with 154 additions and 39 deletions

View File

@ -5,10 +5,12 @@ import (
"db_service/models"
helper "db_service/pkg"
"encoding/json"
"errors"
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"log"
"math"
"os"
"sync"
)
@ -202,27 +204,121 @@ func getTotalDocumentCount(db string) int {
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
var linkedProducts []gm.Product
if firstProduct, err := importer.importVariant(product); err == nil {
linkedProducts = append(linkedProducts, *firstProduct)
}
productRepo.SetCategories(categories)
if product.ColorVariants != nil && len(*product.ColorVariants) > 0 {
for _, colorVariant := range *product.ColorVariants {
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
if variant, err := importer.importVariant(colorVariant); err == nil {
linkedProducts = append(linkedProducts, *variant)
}
}
}
//BEGIN TRANSACTION
//tx := *importer.baza.Begin()
if len(linkedProducts) > 0 {
//todo link products
}
return importer
}
func (importer *Importer) importVariant(product models.Product) (*gm.Product, error) {
productRepo := InitProductRepo(&product, importer.GetColorOption(product.Color), importer.GetSexOption(product.Cinsiyet))
if categories, err := gm.GetCatKeywords(importer.baza, product.Categories); err != nil {
return nil, err
} else {
productRepo.SetCategories(categories)
}
if brand, err := gm.FindOrCreateBrand(importer.baza, product.Brand, productRepo.Categories); err != nil {
return nil, err
} else {
productRepo.Brand = brand
}
mainPorduct := productRepo.makeProduct(importer)
//BEGIN TRANSACTION
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 {
tx.Rollback()
return nil, err
}
mainFlat := productRepo.makeProductFlat(mainPorduct.ID)
if err := tx.Create(&mainFlat).Error; err != nil {
tx.Rollback()
return nil, err
}
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)
variantProduct := productRepo.makeVariant(mainPorduct.ID, mainPorduct.AttributeFamilyID)
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)
continue
}
variantFlat := productRepo.makeVariantFlat(variant, sizeOPtion.ID, mainFlat.ID)
if err := tx.Create(&variantFlat).Error; err != nil {
log.Println("Variant Flat Create Error: " + err.Error())
tx.RollbackTo(variant.ListingID)
continue
}
sizeVariants = append(sizeVariants, variantFlat)
}
if len(sizeVariants) > 0 {
tx.Rollback()
return nil, errors.New("siz variantlary yok bolsa main productam girayenok")
} else {
calcPrice(sizeVariants, &mainFlat)
err := tx.Omit("ParentID", "CreatedAt", "Variants", "SpecialPrice").Save(&mainFlat).Error
if err != nil {
tx.Rollback()
return nil, err
}
}
}
if err := tx.Commit().Error; err != nil {
return nil, err
}
return &mainPorduct, nil
}
func calcPrice(variants []gm.ProductFlat, flat *gm.ProductFlat) {
for _, variant := range variants {
if flat.MinPrice == 0 || flat.MinPrice > variant.MinPrice {
flat.MinPrice = variant.MinPrice
}
flat.MaxPrice = math.Max(flat.MaxPrice, variant.MaxPrice)
}
}
func (importer *Importer) GetColorOption(optionName string) gm.AttributeOption {
if optionName == "" {
return gm.AttributeOption{}

View File

@ -58,6 +58,14 @@ func (pr *ProductRepo) SetCategories(categories []gm.Category) {
}
}
func (pr *ProductRepo) HasSizeVariants() bool {
return pr.Data.SizeVariants != nil && len(*pr.Data.SizeVariants) > 0
}
func (pr *ProductRepo) HasColorVariants() bool {
return pr.Data.ColorVariants != nil && len(*pr.Data.ColorVariants) > 0
}
func (pr *ProductRepo) makeProduct(imp *Importer) gm.Product {
var famID uint = 1
@ -67,17 +75,20 @@ func (pr *ProductRepo) makeProduct(imp *Importer) gm.Product {
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 {
if pr.Data.Brand != "" {
product.BrandID = pr.Brand.ID
}
if pr.HasSizeVariants() {
product.Type = "configurable"
product.SuperAttributes = []gm.Attribute{imp.AttributesMap["size"]}
} else {
product.Type = "simple"
price := pr.Data.Price
if price.OriginalPrice.Value > price.DiscountedPrice.Value {
@ -101,23 +112,25 @@ func (pr *ProductRepo) makeProduct(imp *Importer) gm.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,
}
if pr.Data.Brand != "" {
product.BrandID = pr.Brand.ID
}
return product
}
func (pr *ProductRepo) makeProductFlat(im *Importer) gm.ProductFlat {
func (pr *ProductRepo) makeProductFlat(productId uint) gm.ProductFlat {
flat := gm.ProductFlat{
ProductID: productId,
Status: true,
VisibleIndividually: true,
Name: pr.Data.Name,
@ -127,32 +140,22 @@ func (pr *ProductRepo) makeProductFlat(im *Importer) gm.ProductFlat {
//UrlKey: pr.Data.ProductGroupID,
Weight: pr.Weight,
FavoritesCount: uint(pr.Data.FavoriteCount),
MetaKeywords: pr.Keywords,
MaxPrice: 0,
MinPrice: 0,
Price: 0,
}
if pr.Data.Color != "" {
flat.Color = int(im.GetColorOption(pr.Data.Color).ID)
flat.Color = int(pr.ColorOption.ID)
flat.ColorLabel = pr.Data.Color
}
if pr.Data.SizeVariants != nil && len(*pr.Data.SizeVariants) > 0 {
if pr.Data.Brand != "" {
flat.BrandID = pr.Brand.ID
}
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 {
if !pr.HasSizeVariants() {
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
@ -162,15 +165,31 @@ func (pr *ProductRepo) makeProductFlat(im *Importer) gm.ProductFlat {
}
}
//else {//todo calculate price after variants inserted
// 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
// }
// }
//
//}
return flat
}
func (pr *ProductRepo) makeVariantFlat(variant models.Variant, SizID int) gm.ProductFlat {
func (pr *ProductRepo) makeVariantFlat(variant models.Variant, SizID, parentID uint) gm.ProductFlat {
maxPRice := math.Max(variant.Price.OriginalPrice.Value, variant.Price.DiscountedPrice.Value)
flat := gm.ProductFlat{
ParentID: parentID,
Status: true,
Name: pr.Data.Name,
Sku: pr.Data.ProductGroupID,
@ -178,7 +197,7 @@ func (pr *ProductRepo) makeVariantFlat(variant models.Variant, SizID int) gm.Pro
Weight: pr.Weight,
FavoritesCount: uint(pr.Data.FavoriteCount),
SizeLabel: variant.AttributeValue,
Size: SizID,
Size: int(SizID),
MaxPrice: maxPRice,
MinPrice: variant.Price.DiscountedPrice.Value,
Price: maxPRice,
@ -220,7 +239,7 @@ func (pr *ProductRepo) getProductAttributes(AttributesMap map[string]gm.Attribut
return attributes
}
func (pr *ProductRepo) getVariantAttributes(AttributesMap map[string]gm.Attribute, product *models.Variant, SizID int) []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)
@ -231,7 +250,7 @@ func (pr *ProductRepo) getVariantAttributes(AttributesMap map[string]gm.Attribut
{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["size"].ID, IntegerValue: int(SizID)},
{AttributeID: AttributesMap["price"].ID, FloatValue: price},
}