You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1099 lines
38 KiB

package third
import (
"errors"
"fmt"
"git.oa00.com/go/mysql"
"github.com/golangkit/formatime"
"github.com/shopspring/decimal"
"gorm.io/gorm"
"log"
"path"
"recook/internal/dbc"
"recook/internal/libs/bean"
order4 "recook/internal/model/order"
"recook/internal/v2/lib/supply"
after2 "recook/internal/v2/logic/manage/after"
order2 "recook/internal/v2/logic/manage/order"
"recook/internal/v2/model/recook/after"
"recook/internal/v2/model/recook/goods"
manage3 "recook/internal/v2/model/recook/manage"
manage2 "recook/internal/v2/model/recook/order"
manage "recook/internal/v2/model/third"
"recook/tools"
"sort"
"strconv"
"strings"
)
var SupplyLogic = &supplyLogic{}
type supplyLogic struct {
}
type skuItem struct {
Id uint `json:"id"`
Name string `json:"name"`
ImgUrl string `json:"imgUrl"`
SupplyStatus uint `json:"supplyStatus"`
SupplySkuId uint `json:"supplySkuId"`
FirstCategoryName string `json:"firstCategoryName"`
SecondCategoryName string `json:"secondCategoryName"`
ThirdCategoryName string `json:"thirdCategoryName"`
BrandName string `json:"brandName"`
Price decimal.Decimal `json:"price"`
GuidePrice decimal.Decimal `json:"guidePrice"`
}
type SupplySearch struct {
Status uint
Name string
SupplySkuId uint
IsExport bool
}
// Lists @Title 商品列表
func (s *supplyLogic) Lists(search SupplySearch, page bean.Page) (lists []skuItem, total int64) {
var thirdPartySupplies []manage.RecookThirdPartySupply
where := mysql.Db
// 入库状态
switch search.Status {
case manage.RecookThirdPartySupplyStatusNone: // 未入库
where = where.Where("status = ?", manage.RecookThirdPartySupplyStatusNone)
case manage.RecookThirdPartySupplyStatusAdopt: // 已入库
where = where.Where("status = ?", manage.RecookThirdPartySupplyStatusAdopt)
}
// 商品名称
if search.Name != "" {
where = where.Where("name like ?", fmt.Sprintf("%%%s%%", search.Name))
}
// 供应商skuId
if search.SupplySkuId > 0 {
where = where.Where("supply_sku_id = ?", search.SupplySkuId)
}
if search.IsExport {
mysql.Db.Where(where).Order("id desc").Find(&thirdPartySupplies)
} else {
mysql.Db.Model(thirdPartySupplies).Where(where).Count(&total)
if page.HasPage(total) {
mysql.Db.Where(where).Offset(page.GetStart()).Limit(page.GetLimit()).Order("id desc").Find(&thirdPartySupplies)
}
}
for _, thirdPartySupply := range thirdPartySupplies {
lists = append(lists, skuItem{
Id: thirdPartySupply.Id,
Name: thirdPartySupply.Name,
ImgUrl: thirdPartySupply.ImgUrl,
SupplyStatus: thirdPartySupply.SupplyStatus,
SupplySkuId: thirdPartySupply.SupplySkuId,
FirstCategoryName: thirdPartySupply.FirstCategoryName,
SecondCategoryName: thirdPartySupply.SecondCategoryName,
ThirdCategoryName: thirdPartySupply.ThirdCategoryName,
BrandName: thirdPartySupply.BrandName,
Price: thirdPartySupply.Price,
GuidePrice: thirdPartySupply.GuidePrice,
})
}
return
}
type supplySkuDetail struct {
Id uint `json:"id"`
Name string `json:"name"`
ImgUrl string `json:"imgUrl"`
Status uint `json:"status"`
SupplyStatus uint `json:"supplyStatus"`
SupplySkuId uint `json:"supplySkuId"`
FirstCategoryName string `json:"firstCategoryName"`
SecondCategoryName string `json:"secondCategoryName"`
ThirdCategoryName string `json:"thirdCategoryName"`
BrandName string `json:"brandName"`
Price decimal.Decimal `json:"price"`
GuidePrice decimal.Decimal `json:"guidePrice"`
CategoryId uint `json:"categoryId"`
CategoryName string `json:"categoryName"`
CategoryParentName string `json:"categoryParentName"`
Color string `json:"color"`
Size string `json:"size"`
UpcCode string `json:"upcCode"`
Imgs []string `json:"imgs"`
Content string `json:"content"`
Unit string `json:"unit"`
TaxCode string `json:"taxCode"`
TaxName string `json:"taxName"`
Tax string `json:"tax"`
}
// Detail @Title 商品详情
func (s *supplyLogic) Detail(supplySkuId uint) (result supplySkuDetail, err error) {
thirdPartySupply := manage.RecookThirdPartySupply{}
if mysql.Db.Preload("ThirdPartySupplyCategory.Category.Parent").
Preload("Imgs").
Where("supply_sku_id = ?", supplySkuId).First(&thirdPartySupply).Error != nil {
return result, errors.New("商品错误")
}
result = supplySkuDetail{
Id: thirdPartySupply.Id,
Name: thirdPartySupply.Name,
ImgUrl: thirdPartySupply.ImgUrl,
Status: thirdPartySupply.Status,
SupplyStatus: thirdPartySupply.SupplyStatus,
SupplySkuId: thirdPartySupply.SupplySkuId,
FirstCategoryName: thirdPartySupply.FirstCategoryName,
SecondCategoryName: thirdPartySupply.SecondCategoryName,
ThirdCategoryName: thirdPartySupply.ThirdCategoryName,
CategoryId: thirdPartySupply.ThirdPartySupplyCategory.CategoryId,
BrandName: thirdPartySupply.BrandName,
Price: thirdPartySupply.Price,
GuidePrice: thirdPartySupply.GuidePrice,
Color: thirdPartySupply.Color,
Size: thirdPartySupply.Size,
UpcCode: thirdPartySupply.UpcCode,
Content: thirdPartySupply.Content,
Unit: thirdPartySupply.Unit,
TaxCode: thirdPartySupply.TaxCode,
TaxName: thirdPartySupply.TaxName,
Tax: thirdPartySupply.Tax,
}
if thirdPartySupply.ThirdPartySupplyCategory.CategoryId > 0 {
result.CategoryName = thirdPartySupply.ThirdPartySupplyCategory.Category.Name
result.CategoryParentName = thirdPartySupply.ThirdPartySupplyCategory.Category.Parent.Name
}
for _, thirdPartySupplyImg := range thirdPartySupply.Imgs {
result.Imgs = append(result.Imgs, thirdPartySupplyImg.Path)
}
return
}
type AdoptSkuInfo struct {
SupplySkuId uint
DiscountPrice decimal.Decimal // 售价
Coupon decimal.Decimal // 商品券
}
// Adopt @Title 商品入库
func (s *supplyLogic) Adopt(data AdoptSkuInfo) error {
thirdPartySupply := manage.RecookThirdPartySupply{}
if mysql.Db.Preload("ThirdPartySupplyCategory.Category").
Preload("Imgs").
Where("supply_sku_id = ?", data.SupplySkuId).First(&thirdPartySupply).Error != nil {
return errors.New("商品错误")
}
if thirdPartySupply.GoodsId > 0 {
return errors.New("商品已入库")
}
groups, err := supply.Api.Sku.Groups([]uint{data.SupplySkuId})
if err != nil {
return err
}
var recookGoodsSkuModels []goods.RecookGoodsSkuModel
mysql.Db.Where("third_party_type = ? and third_party_sku_id in ?", goods.RecookGoodsInfoThirdPartyTypeSupply, groups[0].GroupSkuIds).Find(&recookGoodsSkuModels)
if len(recookGoodsSkuModels) > 0 {
// 已添加过商品
return mysql.Db.Transaction(func(tx *gorm.DB) error {
// 原数据处理
if tx.Model(&manage.RecookThirdPartySupply{}).Where("id = ?", thirdPartySupply.Id).Updates(map[string]interface{}{
"status": manage.RecookThirdPartySupplyStatusAdopt,
"goods_id": recookGoodsSkuModels[0].GoodsId,
}).RowsAffected != 1 {
return errors.New("入库失败")
}
// 详情
if thirdPartySupply.Content != "" {
if tx.Model(&goods.RecookGoodsContentModel{}).Where("goods_id = ?", recookGoodsSkuModels[0].GoodsId).Update("content", thirdPartySupply.Content).Error != nil {
return errors.New("入库失败")
}
}
// 商品图片
var mainPhotoModels []goods.RecookGoodsMainPhotoModel
for key, skuImg := range thirdPartySupply.Imgs {
isMaster := 0
if key == 0 {
isMaster = 1
}
mainPhotoModels = append(mainPhotoModels, goods.RecookGoodsMainPhotoModel{
GoodsId: recookGoodsSkuModels[0].GoodsId,
Url: skuImg.Path,
Name: path.Base(skuImg.Path),
IsMaster: isMaster,
OrderNo: key,
Width: 800,
Height: 800,
})
}
if len(mainPhotoModels) > 0 {
if len(mainPhotoModels) == 1 {
mainPhotoModels = append(mainPhotoModels, goods.RecookGoodsMainPhotoModel{
GoodsId: mainPhotoModels[0].GoodsId,
Url: mainPhotoModels[0].Url,
Name: mainPhotoModels[0].Name,
IsMaster: 0,
OrderNo: mainPhotoModels[0].OrderNo,
Width: mainPhotoModels[0].Width,
Height: mainPhotoModels[0].Height,
})
}
if tx.Where("goods_id = ?", recookGoodsSkuModels[0].GoodsId).Delete(&goods.RecookGoodsMainPhotoModel{}).Error != nil {
return errors.New("更新失败")
}
if tx.Create(&mainPhotoModels).Error != nil {
return errors.New("更新失败")
}
}
// 多规格处理
var goodsAttributeModels, recookGoodsAttributeModel []goods.RecookGoodsAttributeModel
mysql.Db.Where("goods_id = ?", recookGoodsSkuModels[0].GoodsId).Find(&recookGoodsAttributeModel)
if thirdPartySupply.Color != "" {
attItem := goods.RecookGoodsAttributeModel{
GoodsId: recookGoodsSkuModels[0].GoodsId,
Name: "规格",
Value: thirdPartySupply.Color,
}
for _, item := range recookGoodsAttributeModel {
if item.Name == "规格" && item.Value == thirdPartySupply.Color {
attItem = item
break
}
}
if attItem.Id == 0 {
if tx.Create(&attItem).Error != nil {
return errors.New("入库失败")
}
}
goodsAttributeModels = append(goodsAttributeModels, attItem)
}
if thirdPartySupply.Size != "" {
attItem := goods.RecookGoodsAttributeModel{
GoodsId: recookGoodsSkuModels[0].GoodsId,
Name: "尺寸",
Value: thirdPartySupply.Size,
}
for _, item := range recookGoodsAttributeModel {
if item.Name == "规格" && item.Value == thirdPartySupply.Size {
attItem = item
break
}
}
if attItem.Id == 0 {
if tx.Create(&attItem).Error != nil {
return errors.New("入库失败")
}
}
goodsAttributeModels = append(goodsAttributeModels, attItem)
}
if len(goodsAttributeModels) == 0 {
attItem := goods.RecookGoodsAttributeModel{
GoodsId: recookGoodsSkuModels[0].GoodsId,
Name: "规格",
Value: "标准",
}
if attItem.Id == 0 {
if tx.Create(&attItem).Error != nil {
return errors.New("入库失败")
}
}
goodsAttributeModels = append(goodsAttributeModels, attItem)
}
sort.Slice(goodsAttributeModels, func(i, j int) bool {
return goodsAttributeModels[i].Id < goodsAttributeModels[j].Id
})
var combineId []string
var skuName []string
for _, goodsAttributeModel := range goodsAttributeModels {
combineId = append(combineId, strconv.Itoa(int(goodsAttributeModel.Id)))
skuName = append(skuName, goodsAttributeModel.Value)
}
inventory := 0
if thirdPartySupply.SupplyStatus == manage.RecookThirdPartySupplySupplyStatusUp {
inventory = 500
}
// sku信息处理
sku := goods.RecookGoodsSkuModel{
GoodsId: recookGoodsSkuModels[0].GoodsId,
Name: strings.Join(skuName, "+"),
CombineId: strings.Join(combineId, ","),
PicURL: thirdPartySupply.ImgUrl,
Code: thirdPartySupply.UpcCode,
PurchasePrice: thirdPartySupply.Price,
OriginalPrice: data.DiscountPrice.Add(data.Coupon),
DiscountPrice: data.DiscountPrice,
Coupon: data.Coupon,
ControlPrice: thirdPartySupply.GuidePrice,
Inventory: uint(inventory),
ThirdPartySkuId: fmt.Sprintf("%d", thirdPartySupply.SupplySkuId),
ThirdPartyType: goods.RecookGoodsInfoThirdPartyTypeSupply,
}
// 税率
tax, err := decimal.NewFromString(thirdPartySupply.Tax)
if err == nil {
// 发票税率
sku.Invoice = goods.RecookSkuInvoiceModel{
GoodsId: recookGoodsSkuModels[0].GoodsId,
GoodsName: thirdPartySupply.Name,
TaxSn: thirdPartySupply.TaxCode,
TaxName: thirdPartySupply.TaxName,
Unit: thirdPartySupply.Unit,
TaxRate: tax,
PlatformRate: tax,
DeductionRate: tax,
}
}
if tx.Create(&sku).Error != nil {
return errors.New("入库失败")
}
return nil
})
} else {
// 未添加过商品
if thirdPartySupply.ThirdPartySupplyCategory.CategoryId == 0 {
return errors.New("分类未匹配")
}
return mysql.Db.Transaction(func(tx *gorm.DB) error {
goodsBrandModel := goods.RecookGoodsBrandModel{
Name: thirdPartySupply.BrandName,
}
if tx.Where(&goodsBrandModel).FirstOrCreate(&goodsBrandModel).Error != nil {
return errors.New("入库失败")
}
recookGoodsInfoModel := goods.RecookGoodsInfoModel{
BrandID: goodsBrandModel.Id,
VendorID: manage.RecookThirdPartySupplyVendorId,
GoodsName: thirdPartySupply.Name,
FirstCategoryID: thirdPartySupply.ThirdPartySupplyCategory.Category.ParentId,
SecondCategoryID: thirdPartySupply.ThirdPartySupplyCategory.CategoryId,
Hash: tools.GenerateGoodsHashSign(),
CreatedAt: formatime.NewSecondNow(),
UpdatedAt: formatime.NewSecondNow(),
ThirdPartyType: goods.RecookGoodsInfoThirdPartyTypeSupply,
}
if tx.Create(&recookGoodsInfoModel).Error != nil {
return errors.New("入库失败")
}
// 原数据处理
if tx.Model(&manage.RecookThirdPartySupply{}).Where("id = ?", thirdPartySupply.Id).Updates(map[string]interface{}{
"status": manage.RecookThirdPartySupplyStatusAdopt,
"goods_id": recookGoodsInfoModel.Id,
}).RowsAffected != 1 {
return errors.New("入库失败")
}
// 商品详情
recookGoodsContentModel := goods.RecookGoodsContentModel{
GoodsId: recookGoodsInfoModel.Id,
Content: thirdPartySupply.Content,
}
if tx.Create(&recookGoodsContentModel).Error != nil {
return errors.New("入库失败")
}
// 商品图片
var mainPhotoModels []goods.RecookGoodsMainPhotoModel
for key, skuImg := range thirdPartySupply.Imgs {
isMaster := 0
if key == 0 {
isMaster = 1
}
mainPhotoModels = append(mainPhotoModels, goods.RecookGoodsMainPhotoModel{
GoodsId: recookGoodsInfoModel.Id,
Url: skuImg.Path,
Name: path.Base(skuImg.Path),
IsMaster: isMaster,
OrderNo: key,
Width: 800,
Height: 800,
})
}
if len(mainPhotoModels) > 0 {
if len(mainPhotoModels) == 1 {
mainPhotoModels = append(mainPhotoModels, goods.RecookGoodsMainPhotoModel{
GoodsId: mainPhotoModels[0].GoodsId,
Url: mainPhotoModels[0].Url,
Name: mainPhotoModels[0].Name,
IsMaster: 0,
OrderNo: mainPhotoModels[0].OrderNo,
Width: mainPhotoModels[0].Width,
Height: mainPhotoModels[0].Height,
})
}
if tx.Create(&mainPhotoModels).Error != nil {
return errors.New("更新失败")
}
} else {
return errors.New("商品图片错误")
}
// 多规格处理
var goodsAttributeModels []goods.RecookGoodsAttributeModel
if thirdPartySupply.Color != "" {
goodsAttributeModels = append(goodsAttributeModels, goods.RecookGoodsAttributeModel{
GoodsId: recookGoodsInfoModel.Id,
Name: "规格",
Value: thirdPartySupply.Color,
})
}
if thirdPartySupply.Size != "" {
goodsAttributeModels = append(goodsAttributeModels, goods.RecookGoodsAttributeModel{
GoodsId: recookGoodsInfoModel.Id,
Name: "尺寸",
Value: thirdPartySupply.Size,
})
}
if len(goodsAttributeModels) == 0 {
goodsAttributeModels = append(goodsAttributeModels, goods.RecookGoodsAttributeModel{
GoodsId: recookGoodsInfoModel.Id,
Name: "规格",
Value: "标准",
})
}
if tx.Create(&goodsAttributeModels).Error != nil {
return errors.New("入库失败")
}
var combineId []string
var skuName []string
for _, goodsAttributeModel := range goodsAttributeModels {
combineId = append(combineId, strconv.Itoa(int(goodsAttributeModel.Id)))
skuName = append(skuName, goodsAttributeModel.Value)
}
inventory := 0
if thirdPartySupply.SupplyStatus == manage.RecookThirdPartySupplySupplyStatusUp {
inventory = 500
}
// sku信息处理
sku := goods.RecookGoodsSkuModel{
GoodsId: recookGoodsInfoModel.Id,
Name: strings.Join(skuName, "+"),
CombineId: strings.Join(combineId, ","),
PicURL: thirdPartySupply.ImgUrl,
Code: thirdPartySupply.UpcCode,
PurchasePrice: thirdPartySupply.Price,
ControlPrice: thirdPartySupply.GuidePrice,
OriginalPrice: data.DiscountPrice.Add(data.Coupon),
DiscountPrice: data.DiscountPrice,
Coupon: data.Coupon,
Inventory: uint(inventory),
ThirdPartySkuId: fmt.Sprintf("%d", thirdPartySupply.SupplySkuId),
ThirdPartyType: goods.RecookGoodsInfoThirdPartyTypeSupply,
}
// 税率
tax, err := decimal.NewFromString(thirdPartySupply.Tax)
if err == nil {
// 发票税率
sku.Invoice = goods.RecookSkuInvoiceModel{
GoodsId: recookGoodsInfoModel.Id,
GoodsName: thirdPartySupply.Name,
TaxSn: thirdPartySupply.TaxCode,
TaxName: thirdPartySupply.TaxName,
Unit: thirdPartySupply.Unit,
TaxRate: tax,
PlatformRate: tax,
DeductionRate: tax,
}
}
if tx.Create(&sku).Error != nil {
return errors.New("入库失败")
}
return nil
})
}
}
// SyncPrice @Title 同步价格
func (s *supplyLogic) SyncPrice(skuIds []uint) error {
prices, err := supply.Api.Sku.Prices(skuIds)
if err != nil {
return err
}
mSkuPrice := map[uint]supply.SkuPrice{}
for _, price := range prices {
mSkuPrice[price.Id] = price
}
var thirdPartySupplies []manage.RecookThirdPartySupply
mysql.Db.Where("supply_sku_id in ?", skuIds).Find(&thirdPartySupplies)
for _, partySupply := range thirdPartySupplies {
mysql.Db.Transaction(func(tx *gorm.DB) error {
if tx.Model(&partySupply).Updates(map[string]interface{}{
"price": mSkuPrice[partySupply.SupplySkuId].Price,
"guide_price": mSkuPrice[partySupply.SupplySkuId].GuidePrice,
"supply_status": mSkuPrice[partySupply.SupplySkuId].Status,
}).Error != nil {
return errors.New("更新失败")
}
// 入库商品同步价格
if partySupply.Status == manage.RecookThirdPartySupplyStatusAdopt {
// 上游上下架修改库存
inventory := 0
if mSkuPrice[partySupply.SupplySkuId].Status == manage.RecookThirdPartySupplySupplyStatusUp {
inventory = 500
}
if tx.Model(&goods.RecookGoodsSkuModel{}).Where("third_party_type = ? and third_party_sku_id = ?", goods.RecookGoodsInfoThirdPartyTypeSupply, partySupply.SupplySkuId).Updates(map[string]interface{}{
"purchase_price": partySupply.Price,
"inventory": inventory,
}).Error != nil {
return errors.New("更新失败")
}
}
return nil
})
}
return nil
}
// SyncData @Title 同步商品信息
func (s *supplyLogic) SyncData(skuIds []uint) error {
details, err := supply.Api.Sku.Details(skuIds)
if err != nil {
return err
}
var thirdPartySupplies []manage.RecookThirdPartySupply
mysql.Db.Where("supply_sku_id in ?", skuIds).Find(&thirdPartySupplies)
mThirdPartySupply := map[uint]manage.RecookThirdPartySupply{}
for _, partySupply := range thirdPartySupplies {
mThirdPartySupply[partySupply.SupplySkuId] = partySupply
}
for _, skuInfo := range details {
if partySupply, ok := mThirdPartySupply[skuInfo.Id]; ok {
// 更新商品
mysql.Db.Transaction(func(tx *gorm.DB) error {
if tx.Model(&partySupply).Updates(map[string]interface{}{
"name": skuInfo.Name,
"brand_id": skuInfo.BrandId,
"brand_name": skuInfo.BrandName,
"first_category_id": skuInfo.FirstCategoryId,
"first_category_name": skuInfo.FirstCategoryName,
"second_category_id": skuInfo.SecondCategoryId,
"second_category_name": skuInfo.SecondCategoryName,
"third_category_id": skuInfo.ThirdCategoryId,
"third_category_name": skuInfo.ThirdCategoryName,
"price": skuInfo.Price,
"guide_price": skuInfo.GuidePrice,
"img_url": skuInfo.ImgUrl,
"profit": skuInfo.Profit,
"size": skuInfo.Size,
"color": skuInfo.Color,
"tax": skuInfo.Tax,
"tax_code": skuInfo.TaxCode,
"tax_name": skuInfo.TaxName,
"unit": skuInfo.Unit,
"upc_code": skuInfo.UpcCode,
"content": skuInfo.Content,
"supply_status": skuInfo.Status,
}).Error != nil {
return errors.New("更新失败")
}
var thirdPartySupplyImgs []manage.RecookThirdPartySupplyImg
for _, skuImg := range skuInfo.Imgs {
thirdPartySupplyImgs = append(thirdPartySupplyImgs, manage.RecookThirdPartySupplyImg{
SupplySkuId: skuInfo.Id,
Path: skuImg.Path,
})
}
if len(thirdPartySupplyImgs) > 0 {
if tx.Where("supply_sku_id = ?", partySupply.SupplySkuId).Delete(&manage.RecookThirdPartySupplyImg{}).Error != nil {
return errors.New("更新失败")
}
if tx.Create(&thirdPartySupplyImgs).Error != nil {
return errors.New("更新失败")
}
}
var thirdPartySupplySpecifications []manage.RecookThirdPartySupplySpecification
for _, specification := range skuInfo.Specifications {
for _, attribute := range specification.Attributes {
thirdPartySupplySpecifications = append(thirdPartySupplySpecifications, manage.RecookThirdPartySupplySpecification{
SupplySkuId: skuInfo.Id,
Name: attribute.Name,
Value: strings.Join(attribute.Value, ";"),
GroupName: specification.Name,
})
}
}
if len(thirdPartySupplySpecifications) > 0 {
if tx.Where("supply_sku_id = ?", partySupply.SupplySkuId).Delete(&manage.RecookThirdPartySupplySpecification{}).Error != nil {
return errors.New("更新失败")
}
if tx.Create(&thirdPartySupplySpecifications).Error != nil {
return errors.New("更新失败")
}
}
// 入库商品同步信息
if partySupply.Status == manage.RecookThirdPartySupplyStatusAdopt {
// 商品信息同步
// 详情
if skuInfo.Content != "" {
if tx.Model(&goods.RecookGoodsContentModel{}).Where("goods_id = ?", partySupply.GoodsId).Update("content", skuInfo.Content).Error != nil {
return errors.New("更新失败")
}
}
// 商品图片
var mainPhotoModels []goods.RecookGoodsMainPhotoModel
for key, skuImg := range skuInfo.Imgs {
isMaster := 0
if key == 0 {
isMaster = 1
}
mainPhotoModels = append(mainPhotoModels, goods.RecookGoodsMainPhotoModel{
GoodsId: partySupply.GoodsId,
Url: skuImg.Path,
Name: path.Base(skuImg.Path),
IsMaster: isMaster,
OrderNo: key,
Width: 800,
Height: 800,
})
}
if len(mainPhotoModels) > 0 {
if len(mainPhotoModels) == 1 {
mainPhotoModels = append(mainPhotoModels, goods.RecookGoodsMainPhotoModel{
GoodsId: mainPhotoModels[0].GoodsId,
Url: mainPhotoModels[0].Url,
Name: mainPhotoModels[0].Name,
IsMaster: 0,
OrderNo: mainPhotoModels[0].OrderNo,
Width: mainPhotoModels[0].Width,
Height: mainPhotoModels[0].Height,
})
}
if tx.Where("goods_id = ?", partySupply.GoodsId).Delete(&goods.RecookGoodsMainPhotoModel{}).Error != nil {
return errors.New("更新失败")
}
if tx.Create(&mainPhotoModels).Error != nil {
return errors.New("更新失败")
}
}
// 税率
tax, err := decimal.NewFromString(skuInfo.Tax)
if err == nil {
// 获取sku信息
recookGoodsSkuModel := goods.RecookGoodsSkuModel{}
mysql.Db.Where("third_party_type = ? and third_party_sku_id = ?", goods.RecookGoodsInfoThirdPartyTypeSupply, partySupply.SupplySkuId).First(&recookGoodsSkuModel)
if recookGoodsSkuModel.Id > 0 {
// 发票税率
skuInvoiceModel := goods.RecookSkuInvoiceModel{}
mysql.Db.Where("sku_id = ?", recookGoodsSkuModel.Id).First(&skuInvoiceModel)
if skuInvoiceModel.Id > 0 {
if tx.Model(&skuInvoiceModel).Updates(map[string]interface{}{
"goods_name": skuInfo.Name,
"tax_sn": skuInfo.TaxCode,
"tax_name": skuInfo.TaxName,
"unit": skuInfo.Unit,
"tax_rate": tax,
"platform_rate": tax,
"deduction_rate": tax,
}).Error != nil {
return errors.New("更新失败")
}
} else {
skuInvoiceModel = goods.RecookSkuInvoiceModel{
SkuId: recookGoodsSkuModel.Id,
GoodsId: recookGoodsSkuModel.GoodsId,
GoodsName: skuInfo.Name,
TaxSn: skuInfo.TaxCode,
TaxName: skuInfo.TaxName,
Unit: skuInfo.Unit,
TaxRate: tax,
PlatformRate: tax,
DeductionRate: tax,
}
if tx.Create(&skuInvoiceModel).Error != nil {
return errors.New("更新失败")
}
}
}
}
// 上游上下架修改库存
inventory := 0
if skuInfo.Status == manage.RecookThirdPartySupplySupplyStatusUp {
inventory = 500
}
if tx.Model(&goods.RecookGoodsSkuModel{}).Where("third_party_type = ? and third_party_sku_id = ?", goods.RecookGoodsInfoThirdPartyTypeSupply, partySupply.SupplySkuId).Updates(map[string]interface{}{
"purchase_price": partySupply.Price,
"inventory": inventory,
"pic_url": skuInfo.ImgUrl,
"code": skuInfo.UpcCode,
}).Error != nil {
return errors.New("更新失败")
}
}
return nil
})
} else {
// 分类处理
category := manage.RecookThirdPartySupplyCategory{
FirstCategoryName: skuInfo.FirstCategoryName,
SecondCategoryName: skuInfo.SecondCategoryName,
ThirdCategoryName: skuInfo.ThirdCategoryName,
}
mysql.Db.Where(&category).FirstOrCreate(&category)
// 添加商品
thirdPartySupply := manage.RecookThirdPartySupply{
SupplySkuId: skuInfo.Id,
Name: skuInfo.Name,
BrandId: skuInfo.BrandId,
BrandName: skuInfo.BrandName,
ThirdPartySupplyCategoryId: category.Id,
FirstCategoryId: skuInfo.FirstCategoryId,
FirstCategoryName: skuInfo.FirstCategoryName,
SecondCategoryId: skuInfo.SecondCategoryId,
SecondCategoryName: skuInfo.SecondCategoryName,
ThirdCategoryId: skuInfo.ThirdCategoryId,
ThirdCategoryName: skuInfo.ThirdCategoryName,
Price: decimal.NewFromFloat(skuInfo.Price),
GuidePrice: decimal.NewFromFloat(skuInfo.GuidePrice),
ImgUrl: skuInfo.ImgUrl,
Profit: decimal.NewFromFloat(skuInfo.Profit),
Size: skuInfo.Size,
Color: skuInfo.Color,
Tax: skuInfo.Tax,
Unit: skuInfo.Unit,
UpcCode: skuInfo.UpcCode,
TaxName: skuInfo.TaxName,
TaxCode: skuInfo.TaxCode,
Content: skuInfo.Content,
Status: manage.RecookThirdPartySupplyStatusNone,
SupplyStatus: skuInfo.Status,
}
for _, skuImg := range skuInfo.Imgs {
thirdPartySupply.Imgs = append(thirdPartySupply.Imgs, manage.RecookThirdPartySupplyImg{
SupplySkuId: skuInfo.Id,
Path: skuImg.Path,
})
}
for _, specification := range skuInfo.Specifications {
for _, attribute := range specification.Attributes {
thirdPartySupply.Specifications = append(thirdPartySupply.Specifications, manage.RecookThirdPartySupplySpecification{
SupplySkuId: skuInfo.Id,
Name: attribute.Name,
Value: strings.Join(attribute.Value, ";"),
GroupName: specification.Name,
})
}
}
mysql.Db.Create(&thirdPartySupply)
}
}
return nil
}
// OrderSplit @Title 拆单
func (s *supplyLogic) OrderSplit(orderSplit supply.OrderSplit) error {
var orderInfo manage2.RecookOrderInfoModel
mysql.Db.Preload("OrderSku").First(&orderInfo, "third_party_order_sn = ? and third_party_type = ?", orderSplit.OrderSn, goods.RecookGoodsInfoThirdPartyTypeSupply)
if orderInfo.Id > 0 {
log.Println("重复拆单请求")
return nil
}
var parentOrderInfo manage2.RecookOrderInfoModel
if err := mysql.Db.Preload("OrderSku").First(&parentOrderInfo, "third_party_order_sn = ? and third_party_type = ?", orderSplit.ParentOrderSn, goods.RecookGoodsInfoThirdPartyTypeSupply).Error; err != nil {
return err
}
var rod manage2.RecookOrderInfoModel
if err := mysql.Db.Preload("OrderSku").First(&rod, "third_party_order_sn = ? and third_party_type = ?", orderSplit.RootOrderSn, goods.RecookGoodsInfoThirdPartyTypeSupply).Error; err != nil {
return err
}
return mysql.Db.Transaction(func(tx *gorm.DB) error {
parentOrderInfo.IsSplit = true
parentOrderInfo.Status = 3
tx.Model(manage2.RecookOrderInfoModel{}).Where("id = ?", parentOrderInfo.Id).Updates(map[string]interface{}{
"is_split": true,
"status": 3,
})
if err := tx.Table((&order4.Profit{}).TableName()).Where("order_id = ?", rod.Id).Update("status", 1).Error; err != nil {
return err
}
if err := tx.Table((&order4.Profit{}).TableName()).Where("order_id = ?", parentOrderInfo.Id).Update("status", 1).Error; err != nil {
return err
}
var skuIds []uint
for _, sku := range orderSplit.Skus {
skuIds = append(skuIds, sku.SkuId)
}
var orderSku []manage2.RecookOrderGoodsDetailModel
var sku []goods.RecookGoodsSkuModel
sub := tx.Select("id").Find(&sku, "third_party_sku_id in (?)", skuIds)
if err := tx.Find(&orderSku, "sku_id in (?) AND order_id = ?", sub, rod.Id).Error; err != nil {
log.Println(err.Error())
return err
}
// 拆分拆单运费
unit := orderSplit.FreightFee.Div(decimal.NewFromInt(int64(len(orderSku)))).Round(2)
fee := orderSplit.FreightFee
unitMap := make(map[uint]decimal.Decimal)
var orderSkuNew []manage2.RecookOrderGoodsDetailModel
for i := 0; i < len(orderSku); i++ {
if i == len(orderSku)-1 {
unitMap[orderSku[i].SkuId] = fee
break
}
fee = fee.Sub(unit)
unitMap[orderSku[i].SkuId] = unit
}
coinTotal := decimal.Zero
goodsTotalAmount := decimal.Zero
goodsTotalCommission := decimal.Zero
actualAmount := decimal.Zero
for _, v := range orderSku {
actualAmount = actualAmount.Add(v.GoodsAmount).Add(unitMap[v.SkuId]).Sub(v.CoinAmount)
coinTotal = coinTotal.Add(v.CoinAmount)
goodsTotalAmount = goodsTotalAmount.Add(v.GoodsAmount)
}
orderNew := manage2.RecookOrderInfoModel{
AncestorId: rod.AncestorId,
ParentId: rod.ParentId,
SharerId: rod.SharerId,
LiveId: rod.LiveId,
UserId: rod.UserId,
UserRole: rod.UserRole,
Title: "",
CoinTotalAmount: coinTotal,
ExpressTotalFee: orderSplit.FreightFee,
GoodsTotalAmount: goodsTotalAmount,
GoodsTotalCommission: goodsTotalCommission,
ActualTotalAmount: actualAmount,
Channel: rod.Channel,
ShippingMethod: rod.ShippingMethod,
StoreId: rod.StoreId,
BuyerMessage: rod.BuyerMessage,
Status: 1,
ExpressStatus: rod.ExpressStatus,
InvoiceStatus: rod.InvoiceStatus,
CreatedAt: rod.CreatedAt,
ExpireTime: rod.ExpireTime,
PayIP: rod.PayIP,
TradeNo: rod.TradeNo,
PayTime: rod.PayTime,
PayMethod: rod.PayMethod,
RbacId: rod.RbacId,
IsFirst: rod.IsFirst,
VirtualID: rod.VirtualID,
PayType: rod.PayType,
Kind: rod.Kind,
ThirdPartyType: rod.ThirdPartyType,
ThirdPartyOrderSn: fmt.Sprintf("%d", orderSplit.OrderSn),
OrderType: rod.OrderType,
}
var orderAddr manage2.RecookOrderAddrModel
tx.First(&orderAddr, "order_id = ?", rod.Id)
if err := tx.Create(&orderNew).Error; err != nil {
log.Println(err.Error())
return err
}
orderAddr.Id = 0
orderAddr.OrderId = orderNew.Id
if err := tx.Create(&orderAddr).Error; err != nil {
log.Println(err.Error())
return err
}
cost := decimal.Zero
total := decimal.Zero
for _, v := range orderSku {
cost = cost.Add(v.PurchasePrice).Mul(decimal.NewFromInt(int64(v.Quantity)))
total = total.Add(v.GoodsAmount)
v.Id = 0
v.OrderId = orderNew.Id
v.ExpressFee = unitMap[v.SkuId]
//v.CoinAmount = decimal.Zero
v.ActualAmount = v.GoodsAmount.Add(v.ExpressFee).Sub(v.CoinAmount)
//coinTotal = decimal.Zero
orderSkuNew = append(orderSkuNew, v)
}
//orderNew.CoinTotalAmount = coinTotal
if err := tx.Save(orderNew).Error; err != nil {
log.Println(err.Error())
return err
}
if err := tx.Create(orderSkuNew).Error; err != nil {
log.Println(err.Error())
return err
}
var rp []order4.Profit
if err := tx.Table((&order4.Profit{}).TableName()).Find(&rp, "order_id = ?", rod.Id).Error; err != nil {
return err
}
profitNew := make([]*order4.Profit, 0)
b2 := decimal.Zero
for _, k := range orderSkuNew {
b2 = b2.Add(k.GetBase().Mul(decimal.NewFromInt(int64(k.Quantity))))
}
for _, v := range rp {
temp := order4.CreateProfit(v.UserID, v.Type, b2, orderNew.Id)
profitNew = append(profitNew, temp)
}
if len(profitNew) != 0 {
if err := tx.Create(profitNew).Error; err != nil {
log.Println(err.Error())
return err
}
}
return nil
})
}
// OrderCancel @Title 订单取消
func (s *supplyLogic) OrderCancel(orderCancel supply.OrderCancel) error {
var orderInfo manage2.RecookOrderInfoModel
if err := mysql.Db.First(&orderInfo, "third_party_order_sn = ? and third_party_type = ?", orderCancel.OrderSn, goods.RecookGoodsInfoThirdPartyTypeSupply).Error; err != nil {
if err != gorm.ErrRecordNotFound {
log.Println(err.Error())
return err
} else {
return nil
}
}
switch orderCancel.Status {
case supply.OrderCancelSuccess: // 取消成功
if orderInfo.Status == 0 {
// 未支付订单直接取消
return nil
} else {
tx := dbc.DB.Begin()
{
var asGoods []after.RecookAfterSalesGoodsModel
tx.Find(&asGoods, "order_id = ?", orderInfo.Id)
for _, v := range asGoods {
if v.RefundStatus == 1 {
continue
}
t := &after2.UpdateOrderCheckStatusReq{
AsID: v.Id,
}
if err := after2.Refund(tx, v, orderInfo, t, manage3.RecookManageUserInfoModel{}); err != nil {
tx.Rollback()
return err
}
}
}
if err := tx.Model(orderInfo).Update("deal_status", 11).Error; err != nil {
return err
}
tx.Commit()
}
case supply.OrderCancelFail: // 取消失败
tx := dbc.DB.Begin()
{
orderInfo.DealStatus = 12
if err := tx.Save(&orderInfo).Error; err != nil {
return err
}
var asGoods []after.RecookAfterSalesGoodsModel
if err := tx.Find(&asGoods, "order_id = ?", orderInfo.Id).Error; err != nil {
return err
}
for _, v := range asGoods {
if err := tx.Model(v).Updates(after.RecookAfterSalesGoodsModel{
ReturnStatus: 2,
RejectReason: "系统自动拒绝",
FinishTime: formatime.NewSecondNow(),
}).Error; err != nil {
tx.Rollback()
return err
}
if err := tx.Model(&manage2.RecookOrderGoodsDetailModel{Id: v.OrderGoodsId}).Updates(map[string]interface{}{
"ass_type": 0,
}).Error; err != nil {
tx.Rollback()
return err
}
//这里插入日志
Log1 := after.RecookAfterSalesLogsModel{
AsID: v.Id,
Title: "平台拒绝退款",
Content: "拒绝买家退款申请,如有疑问,请联系客服",
CTime: formatime.NewSecondNow(),
User: "系统",
UserId: 0,
}
tx.Create(&Log1)
Log2 := after.RecookAfterSalesLogsModel{
AsID: v.Id,
Title: "退款关闭",
Content: "系统自动关闭",
CTime: formatime.NewSecondNow(),
User: "系统",
UserId: 0,
}
tx.Create(&Log2)
}
}
tx.Commit()
case supply.OrderCancelReject: // 拒收/商家主动取消case supply.
}
return nil
}
// OrderStockOut @Title 订单出库
func (s *supplyLogic) OrderStockOut(orderStockOut supply.OrderStockOut) error {
var orderInfo manage2.RecookOrderInfoModel
if err := mysql.Db.First(&orderInfo, "third_party_order_sn = ? and third_party_type = ?", orderStockOut.OrderSn, goods.RecookGoodsInfoThirdPartyTypeSupply).Error; err != nil {
if err != gorm.ErrRecordNotFound {
log.Println(err.Error())
return err
} else {
return nil
}
}
var orderSku []manage2.RecookOrderGoodsDetailModel
if err := mysql.Db.Find(&orderSku, "order_id =? ", orderInfo.Id).Error; err != nil {
log.Println(err.Error())
return err
}
ep := make([]order2.ExpressInfo, 0)
for _, v := range orderStockOut.Packages {
ep = append(ep, order2.ExpressInfo{
ExpressCompName: v.LogisticsName,
ExpressNo: v.WaybillCode,
})
}
for index, j := range orderSku {
if j.ExpressStatus == manage2.RecookOrderGoodsDetailExpressStatusTrue {
continue
}
if err := order2.Expresslogic.Express(j.VendorId, "third_api", orderSku[index], ep); err != nil {
return err
}
}
return nil
}
// OrderFinish @Title 订单完成
func (s *supplyLogic) OrderFinish(orderFinish supply.OrderFinish) error {
var orderInfo manage2.RecookOrderInfoModel
if err := mysql.Db.First(&orderInfo, "third_party_order_sn = ? and third_party_type = ?", orderFinish.OrderSn, goods.RecookGoodsInfoThirdPartyTypeSupply).Error; err != nil {
if err != gorm.ErrRecordNotFound {
log.Println(err.Error())
return err
} else {
return nil
}
}
if mysql.Db.Model(&orderInfo).Updates(map[string]interface{}{
"third_party_status": 1,
}).Error != nil {
return errors.New("保存失败")
}
return nil
}