Files
jx-callback/business/partner/purchase/yb/store_sku.go
2020-07-01 11:57:56 +08:00

599 lines
19 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package yb
import (
"fmt"
"regexp"
"strings"
"git.rosy.net.cn/baseapi/platformapi/yinbaoapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/jxstore/cms"
"git.rosy.net.cn/jx-callback/business/jxutils"
"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
"git.rosy.net.cn/jx-callback/business/model"
"git.rosy.net.cn/jx-callback/business/model/dao"
"git.rosy.net.cn/jx-callback/business/partner"
"git.rosy.net.cn/jx-callback/business/partner/putils"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/jx-callback/globals/api"
)
var (
sensitiveWordRegexp = regexp.MustCompile(`商品名称中含有敏感词(\[.*\])`)
)
const (
addErr1 = "商品已存在"
)
func (p *PurchaseHandler) CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if globals.EnableYbStoreWrite {
storeSku := storeSkuList[0]
var result *yinbaoapi.AddProductInfoResult
flag, err2 := checkYbSku(storeSku) //flag为true表示是标品标品不用更新称编码
if err2 != nil {
err = err2
} else {
result, err = api.YinBaoAPI.AddProductInfo(buildProductInfoParam(storeSku))
}
if err != nil {
// if strings.Contains(err.Error(), addErr1) {
// queryProductByBarcodeResult, err := api.YinBaoAPI.QueryProductByBarcodes([]string{storeSku.YbBarCode})
// if err != nil && len(queryProductByBarcodeResult) > 0 {
// if queryProductByBarcodeResult[0].Enable == model.SkuStatusDeleted {
// api.YinBaoAPI.SaveProduct(userId, keyword, saveProductParam)
// }
// }
// }
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "创建商品")
} else {
storeSku.VendorSkuID = utils.Int64ToStr(result.UID)
err = uploadYbImage(vendorStoreID, storeSku.YbBarCode, storeSku.Img)
if !flag {
err = updateYbSku(vendorStoreID, storeSku.YbBarCode, nil)
}
if err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "创建商品")
}
}
}
return failedList, err
}
func (p *PurchaseHandler) UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if globals.EnableYbStoreWrite {
for _, v := range storeSkuList {
saveProductParam := &yinbaoapi.SaveProductParam{
CategoryUid: v.VendorCatID,
}
_, err = checkYbSku(v)
if err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "修改商品")
return failedList, err
}
err = updateYbImage(vendorStoreID, v)
if err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "修改商品")
return failedList, err
}
err = updateYbSku(vendorStoreID, v.YbBarCode, saveProductParam)
if err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "修改商品")
}
}
}
return failedList, err
}
func (p *PurchaseHandler) DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if globals.EnableYbStoreWrite {
for _, v := range storeSkuList {
var productInfo = &yinbaoapi.ProductInfo{
UID: utils.Str2Int64(v.VendorSkuID),
Enable: utils.Int2Pointer(yinbaoapi.SkuStatusDeleted),
}
err = api.YinBaoAPI.UpdateProductInfo(productInfo)
if err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "删除商品")
}
}
}
return failedList, err
}
func (p *PurchaseHandler) GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (skuNameList []*partner.SkuNameInfo, err error) {
storeDetail, _ := dao.GetStoreDetail(dao.GetDB(), storeID, model.VendorIDYB)
api.YinBaoAPI = yinbaoapi.New(storeDetail.YbAppKey, storeDetail.YbAppID)
if configs, err := dao.QueryConfigs(dao.GetDB(), "yinbaoCookie", model.ConfigTypeCookie, ""); err == nil {
yinbaoCookie := configs[0].Value
api.YinBaoAPI.SetCookie(".POSPALAUTH30220", yinbaoCookie)
}
if storeSkuList != nil {
if len(storeSkuList) == 1 {
storeSku := storeSkuList[0]
result, err := api.YinBaoAPI.QueryProductByBarcode(storeSku.VendorSkuID)
if err != nil || result == nil {
return nil, err
}
resultp, err := api.YinBaoAPI.QueryProductImagesByBarcode(result.Barcode)
// resultp, err := getProductImages(vendorStoreID, storeSku.VendorSkuID)
if err != nil {
return nil, err
}
if skuName := vendorSku2Jx(result, resultp); skuName != nil {
skuNameList = append(skuNameList, skuName)
}
} else {
var barcodes []string
for _, v := range storeSkuList {
barcodes = append(barcodes, v.VendorSkuID)
}
results, err := api.YinBaoAPI.QueryProductByBarcodes(barcodes)
if err != nil {
return nil, err
}
for _, v := range results {
resultp, err := api.YinBaoAPI.QueryProductImagesByBarcode(v.Barcode)
// resultp, err := getProductImages(vendorStoreID, v.Barcode)
if err != nil {
return nil, err
}
if skuName := vendorSku2Jx(v, resultp); skuName != nil {
skuNameList = append(skuNameList, skuName)
}
}
}
} else {
result, err := api.YinBaoAPI.QueryProductPages(nil)
if err != nil {
return nil, err
}
if len(result.Result) < result.PageSize {
for _, v := range result.Result {
resultp, err := api.YinBaoAPI.QueryProductImagesByBarcode(v.Barcode)
// resultp, err := getProductImages(vendorStoreID, v.Barcode)
if err != nil {
return nil, err
}
vv := &yinbaoapi.QueryProductByBarcodeResult{}
err = utils.Map2StructByJson(utils.Struct2MapByJson(v), vv, false)
if skuName := vendorSku2Jx(vv, resultp); skuName != nil {
skuNameList = append(skuNameList, skuName)
}
}
} else {
for _, v := range result.Result {
resultp, err := api.YinBaoAPI.QueryProductImagesByBarcode(v.Barcode)
// resultp, err := getProductImages(vendorStoreID, v.Barcode)
if err != nil {
return nil, err
}
vv := &yinbaoapi.QueryProductByBarcodeResult{}
err = utils.Map2StructByJson(utils.Struct2MapByJson(v), vv, false)
if skuName := vendorSku2Jx(vv, resultp); skuName != nil {
skuNameList = append(skuNameList, skuName)
}
}
loopPages(result.PostBackParameter.ParameterType, result.PostBackParameter.ParameterValue, &skuNameList, vendorStoreID)
}
}
return skuNameList, err
}
func getProductImages(vendorStoreID, barCode string) (findProductResult *yinbaoapi.FindProductResult, err error) {
for {
ybSkuID, err := api.YinBaoAPI.LoadProductsByPage(vendorStoreID, barCode)
findProductResult, err = api.YinBaoAPI.FindProduct(ybSkuID)
if err == nil {
break
} else {
if yinbaoapi.IsErrCookie(err) {
err = cms.ChangeYbCookie()
if err != nil {
break
}
findProductResult, err = getProductImages(vendorStoreID, barCode)
} else {
break
}
}
}
return findProductResult, err
}
func (p *PurchaseHandler) UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo, status int) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if globals.EnableYbStoreWrite {
for _, v := range storeSkuList {
var productInfo = &yinbaoapi.ProductInfo{
UID: utils.Str2Int64(v.VendorSkuID),
Enable: utils.Int2Pointer(ybSkuStatus2Jx(v.Status)),
}
err = api.YinBaoAPI.UpdateProductInfo(productInfo)
if err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "更新商品状态")
}
}
}
return failedList, err
}
func (p *PurchaseHandler) UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if globals.EnableYbStoreWrite {
for _, v := range storeSkuList {
var productInfo = &yinbaoapi.ProductInfo{
UID: utils.Str2Int64(v.VendorSkuID),
SellPrice: utils.Float64ToPointer(jxutils.IntPrice2Standard(v.VendorPrice)),
BuyPrice: utils.Float64ToPointer(jxutils.IntPrice2Standard(v.JxPrice)),
}
err = api.YinBaoAPI.UpdateProductInfo(productInfo)
if err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "更新商品价格")
}
}
}
return failedList, err
}
func (p *PurchaseHandler) UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*partner.StoreSkuInfo) (failedList []*partner.StoreSkuInfoWithErr, err error) {
if globals.EnableYbStoreWrite {
for _, v := range storeSkuList {
var productInfo = &yinbaoapi.ProductInfo{
UID: utils.Str2Int64(v.VendorSkuID),
Stock: utils.Float64ToPointer(utils.Str2Float64(utils.Int2Str(v.Stock))),
}
err = api.YinBaoAPI.UpdateProductInfo(productInfo)
if err != nil {
failedList = putils.GetErrMsg2FailedSingleList(storeSkuList, err, storeID, model.VendorChineseNames[model.VendorIDYB], "更新商品库存")
}
}
}
return failedList, err
}
func (p *PurchaseHandler) GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*partner.BareCategoryInfo, err error) {
remoteCats, err := loadCategorysWithOption(vendorStoreID)
cats = convertVendorCatList(remoteCats)
return cats, err
}
func loadCategorysWithOption(vendorStoreID string) (remoteCats []*yinbaoapi.LoadCategorysWithOptionResult, err error) {
for {
remoteCats, err = api.YinBaoAPI.LoadCategorysWithOption(vendorStoreID)
if err == nil {
break
} else {
if yinbaoapi.IsErrCookie(err) {
err = cms.ChangeYbCookie()
if err != nil {
break
}
remoteCats, err = loadCategorysWithOption(vendorStoreID)
} else {
break
}
}
}
return remoteCats, err
}
func (p *PurchaseHandler) CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) {
if globals.EnableYbStoreWrite {
var (
catName = utils.FilterEmoji(storeCat.Name)
parentCatName = utils.FilterEmoji(storeCat.ParentCatName)
)
vendorCatID, err := addNewCategory(vendorStoreID, catName, parentCatName)
if err == nil {
storeCat.VendorCatID = vendorCatID
}
return err
}
return err
}
func addNewCategory(vendorStoreID, catName, parentCatName string) (vendorCatID string, err error) {
for {
vendorCatID, err = api.YinBaoAPI.AddNewCategory(vendorStoreID, catName, parentCatName)
if err == nil {
break
} else {
if yinbaoapi.IsErrCookie(err) {
err = cms.ChangeYbCookie()
if err != nil {
break
}
vendorCatID, err = addNewCategory(vendorStoreID, catName, parentCatName)
} else {
break
}
}
}
return vendorCatID, err
}
func (p *PurchaseHandler) UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error) {
if globals.EnableYbStoreWrite {
var (
catName = utils.FilterEmoji(storeCat.Name)
parentCatName = utils.FilterEmoji(storeCat.ParentCatName)
)
err = updateCategory(vendorStoreID, storeCat.VendorCatID, catName, parentCatName)
}
return err
}
func updateCategory(vendorStoreID, vendorCatID, catName, parentCatName string) (err error) {
for {
err = api.YinBaoAPI.UpdateCategory(vendorStoreID, vendorCatID, catName, parentCatName)
if err == nil {
break
} else {
if yinbaoapi.IsErrCookie(err) {
err = cms.ChangeYbCookie()
if err != nil {
break
}
err = updateCategory(vendorStoreID, vendorCatID, catName, parentCatName)
} else {
break
}
}
}
return err
}
func (p *PurchaseHandler) DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error) {
if globals.EnableYbStoreWrite {
err = deleteCategory(vendorStoreID, []string{vendorCatID})
}
return err
}
func deleteCategory(vendorStoreID string, vendorCatIDs []string) (err error) {
for {
err = api.YinBaoAPI.DeleteCategory(vendorStoreID, vendorCatIDs)
if err == nil {
break
} else {
if yinbaoapi.IsErrCookie(err) {
err = cms.ChangeYbCookie()
if err != nil {
break
}
err = api.YinBaoAPI.DeleteCategory(vendorStoreID, vendorCatIDs)
} else {
break
}
}
}
return err
}
func (p *PurchaseHandler) IsErrSkuExist(err error) (isExist bool) {
return yinbaoapi.IsErrSkuExist(err)
}
func (p *PurchaseHandler) IsErrCategoryExist(err error) (isExist bool) {
return yinbaoapi.IsErrCategoryExist(err)
}
func (p *PurchaseHandler) IsErrCategoryNotExist(err error) (isNotExist bool) {
return false
}
func (p *PurchaseHandler) GetStoreSkusBatchSize(funcID int) (batchSize int) {
return 1
}
func (p *PurchaseHandler) GetSensitiveWordRegexp() *regexp.Regexp {
return sensitiveWordRegexp
}
func (p *PurchaseHandler) IsErrSkuNotExist(err error) (isNotExist bool) {
return yinbaoapi.IsErrSkuNotExist(err)
}
func ybSkuStatus2Jx(ybStatus int) (jxSkuStatus int) {
if ybStatus == yinbaoapi.SkuStatusEnable {
jxSkuStatus = model.SkuStatusNormal
} else if ybStatus == yinbaoapi.SkuStatusDisabled {
jxSkuStatus = model.SkuStatusDontSale
} else if ybStatus == yinbaoapi.SkuStatusDeleted {
jxSkuStatus = model.SkuStatusDeleted
}
return jxSkuStatus
}
func vendorSku2Jx(result *yinbaoapi.QueryProductByBarcodeResult, resultp []*yinbaoapi.QueryProductImagesByBarcodeResult) (skuName *partner.SkuNameInfo) {
var picList []string
if result == nil {
globals.SugarLogger.Warnf("vendorSku2Jx, strange result:%s", utils.Format4Output(result, true))
return nil
}
if len(resultp) > 0 {
if resultp[0].ImageURL != "" {
// for _, v := range resultp.Productimages {
picList = append(picList, resultp[0].ImageURL)
// }
}
}
prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(result.Name)
skuName = &partner.SkuNameInfo{
Prefix: prefix,
Name: name,
Unit: unit,
YbBarCode: result.Barcode,
SkuList: []*partner.SkuInfo{
&partner.SkuInfo{
StoreSkuInfo: partner.StoreSkuInfo{
VendorSkuID: utils.Int64ToStr(result.UID),
Stock: int(utils.Float64TwoInt64(result.Stock)),
VendorPrice: jxutils.StandardPrice2Int(result.SellPrice),
Status: ybSkuStatus2Jx(result.Enable),
},
SkuName: result.Name,
Comment: comment,
SpecQuality: float64(specQuality),
SpecUnit: specUnit,
Weight: int(utils.Float64TwoInt64(float64(specQuality))),
},
},
PictureList: picList,
}
return skuName
}
func loopPages(parameterType, parameterValue string, skuNameList *[]*partner.SkuNameInfo, vendorStoreID string) (err error) {
var postBackParameter = &yinbaoapi.PostBackParameter{
ParameterType: parameterType,
ParameterValue: parameterValue,
}
resultPages, err := api.YinBaoAPI.QueryProductPages(postBackParameter)
if err != nil {
return err
}
for _, v := range resultPages.Result {
// resultp, err := api.YinBaoAPI.QueryProductImagesByBarcode(v.Barcode)
// resultp, err := getProductImages(vendorStoreID, v.Barcode)
if err != nil {
return err
}
var resultp []*yinbaoapi.QueryProductImagesByBarcodeResult
vv := &yinbaoapi.QueryProductByBarcodeResult{}
err = utils.Map2StructByJson(utils.Struct2MapByJson(v), vv, false)
if skuName := vendorSku2Jx(vv, resultp); skuName != nil {
*skuNameList = append(*skuNameList, skuName)
}
}
if len(resultPages.Result) >= resultPages.PageSize {
err = loopPages(resultPages.PostBackParameter.ParameterType, resultPages.PostBackParameter.ParameterValue, skuNameList, vendorStoreID)
}
return err
}
func buildProductInfoParam(storeSku *dao.StoreSkuSyncInfo) (productInfoParam *yinbaoapi.ProductInfoParam) {
var (
buyPrice float64 = utils.Str2Float64(utils.Int64ToStr(storeSku.Price)) / 100
sellPrice float64 = utils.Str2Float64(utils.Int64ToStr(storeSku.VendorPrice)) / 100
// _, name, _, _, _, _ = jxutils.SplitSkuName()
)
productInfoParam = &yinbaoapi.ProductInfoParam{}
productInfo := &yinbaoapi.ProductInfo{
Stock: utils.Float64ToPointer(utils.Str2Float64(utils.Int2Str(model.MaxStoreSkuStockQty))),
Name: storeSku.Name,
Barcode: storeSku.YbBarCode,
BuyPrice: &buyPrice,
SellPrice: &sellPrice,
CategoryUID: utils.Str2Int64(storeSku.VendorCatID),
}
productInfoParam.ProductInfo = productInfo
return productInfoParam
}
func convertVendorCatList(remoteCats []*yinbaoapi.LoadCategorysWithOptionResult) (cats []*partner.BareCategoryInfo) {
for _, rCat := range remoteCats {
cat := &partner.BareCategoryInfo{
VendorCatID: rCat.TxtUID,
Name: rCat.Name,
}
if rCat.TxtParentUID == "" {
cat.Level = 1
} else {
cat.Level = 2
}
cats = append(cats, cat)
}
return cats
}
func updateYbSku(vendorStoreID, ybBarCode string, saveProductParam *yinbaoapi.SaveProductParam) (err error) {
for {
err = api.YinBaoAPI.SaveProduct(vendorStoreID, ybBarCode, saveProductParam)
if err == nil {
break
} else {
if yinbaoapi.IsErrCookie(err) {
err = cms.ChangeYbCookie()
if err != nil {
break
}
err = updateYbSku(vendorStoreID, ybBarCode, saveProductParam)
} else {
break
}
}
}
return err
}
func checkYbSku(storeSku *dao.StoreSkuSyncInfo) (flag bool, err error) {
skuID := storeSku.SkuID
skus, _ := dao.GetSkus(dao.GetDB(), []int{skuID}, nil, nil, nil, nil)
if len(skus) > 0 {
if skus[0].Unit != model.UnitNames[0] {
flag = true
if skus[0].Upc == "" {
return flag, fmt.Errorf("标品必须指定upc码skuID[%v]", skuID)
} else {
storeSku.YbBarCode = skus[0].Upc
}
}
}
return flag, err
}
func uploadYbImage(vendorStoreID, ybBarCode, img string) (err error) {
ybSkuID, err := api.YinBaoAPI.LoadProductsByPage(vendorStoreID, ybBarCode)
resBinary, _, err := jxutils.DownloadFileByURL(img)
fileName := img[strings.LastIndex(img, "/")+1:]
err = uploadYbImageLoop(vendorStoreID, ybSkuID, resBinary, fileName)
return err
}
func uploadYbImageLoop(vendorStoreID, ybSkuID string, resBinary []byte, fileName string) (err error) {
for {
err = api.YinBaoAPI.UploadProductImage(vendorStoreID, ybSkuID, resBinary, fileName)
if err == nil {
break
} else {
if yinbaoapi.IsErrCookie(err) {
err = cms.ChangeYbCookie()
if err != nil {
break
}
err = uploadYbImageLoop(vendorStoreID, ybSkuID, resBinary, fileName)
} else {
break
}
}
}
return err
}
func updateYbImage(vendorStoreID string, v *dao.StoreSkuSyncInfo) (err error) {
err = uploadYbImage(vendorStoreID, v.YbBarCode, v.Img)
err = resetCoverImageLoop(vendorStoreID, v.YbBarCode)
return err
}
func resetCoverImageLoop(vendorStoreID, ybBarCode string) (err error) {
for {
err = api.YinBaoAPI.ResetCoverImage(vendorStoreID, ybBarCode)
if err == nil {
break
} else {
if yinbaoapi.IsErrCookie(err) {
err = cms.ChangeYbCookie()
if err != nil {
break
}
err = resetCoverImageLoop(vendorStoreID, ybBarCode)
} else {
break
}
}
}
return err
}