218 lines
7.8 KiB
Go
218 lines
7.8 KiB
Go
package phpjx
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||
"strings"
|
||
"time"
|
||
|
||
"git.rosy.net.cn/baseapi/platformapi/jdapi"
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
"git.rosy.net.cn/jx-callback/business/model"
|
||
"git.rosy.net.cn/jx-callback/business/partner"
|
||
)
|
||
|
||
type Data4AfsOrderSku struct {
|
||
VendorSkuID string `orm:"column(vendor_sku_id);size(48)" json:"vendorSkuID"` // 平台skuid
|
||
PromotionType int `json:"promotionType"` // 商品级别促销类型 (1、无优惠;2、秒杀(已经下线);3、单品直降;4、限时抢购;1202、加价购;1203、满赠(标识商品);6、买赠(买A送B,标识B);9999、表示一个普通商品参与捆绑促销,设置的捆绑类型;9998、表示一个商品参与了捆绑促销,并且还参与了其他促销类型;9997、表示一个商品参与了捆绑促销,但是金额拆分不尽,9996:组合购,8001:轻松购会员价,8:第二件N折,9:拼团促销)
|
||
Name string `orm:"size(255)" json:"name"` // 商品名
|
||
SalePrice int64 `json:"salePrice"` // 售卖价
|
||
Count int `json:"count"` // 订单下单数量
|
||
}
|
||
|
||
type Data4AfsOrder struct {
|
||
VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` // 关联原始订单ID
|
||
AfsOrderID string `orm:"column(afs_order_id);size(48)" json:"afsOrderID"` // 售后订单ID
|
||
AfsCreatedAt time.Time `orm:"type(datetime);null;index" json:"afsCreatedAt"` // 售后单生成时间
|
||
VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` // 外部系统里记录的storeid
|
||
|
||
VendorStatus string `orm:"size(255)" json:"vendorStatus"`
|
||
VendorReasonType string `orm:"size(255)" json:"vendorReasonType"` // 原始售后原因
|
||
ReasonDesc string `orm:"size(1024)" json:"reasonDesc"` // 售后原因描述
|
||
ReasonImgList string `orm:"size(1024)" json:"reasonImgList"` // 售后描述图片
|
||
VendorAppealType string `orm:"size(255)" json:"vendorAppealType"` // 原始售后方式
|
||
Skus []*Data4AfsOrderSku
|
||
}
|
||
|
||
func OnAfsOrderMsg(msg *CallbackMsg) (err error) {
|
||
//jxutils.CallMsgHandlerAsync(func() {
|
||
err = onAfsOrderMsg(msg)
|
||
//}, jxutils.ComposeUniversalOrderID(msg.ThingID, model.VendorIDJX))
|
||
return err
|
||
}
|
||
|
||
func CheckOrderSkuCanRefund(db *dao.DaoDB, afsOrder *Data4AfsOrder) error {
|
||
// 获取此订单商品吃否存在售后单
|
||
refundFinancial, err := dao.GetOrderRefundSkuList(db, []string{afsOrder.VendorOrderID})
|
||
if err != nil && !strings.Contains(err.Error(), "no row found") {
|
||
return nil
|
||
}
|
||
|
||
if len(refundFinancial) == model.NO {
|
||
return nil
|
||
}
|
||
|
||
for _, r := range refundFinancial {
|
||
for _, s := range afsOrder.Skus {
|
||
if r.SkuID == utils.Str2Int(s.VendorSkuID) {
|
||
return fmt.Errorf("商品:[%s],已经存在售后单无法重复申请", s.Name)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取用户下单商品列表
|
||
skuList, err := dao.GetSimpleOrderSkus(dao.GetDB(), afsOrder.VendorOrderID, nil)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
var really = make(map[int]bool, 0)
|
||
for _, s := range skuList {
|
||
really[s.SkuID] = true
|
||
}
|
||
for _, v := range afsOrder.Skus {
|
||
if _, ok := really[utils.Str2Int(v.VendorSkuID)]; !ok {
|
||
return fmt.Errorf("商品:[%s],不是购买商品", v.Name)
|
||
}
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
func buildAfsOrder(msg *CallbackMsg) (outAfsOrder *model.AfsOrder, err error) {
|
||
var afsOrder *Data4AfsOrder
|
||
var db = dao.GetDB()
|
||
if err = utils.UnmarshalUseNumber([]byte(msg.Data), &afsOrder); err == nil {
|
||
if err := CheckOrderSkuCanRefund(db, afsOrder); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
outAfsOrder = &model.AfsOrder{
|
||
VendorID: model.VendorIDJX,
|
||
AfsOrderID: afsOrder.AfsOrderID,
|
||
VendorOrderID: afsOrder.VendorOrderID,
|
||
VendorStoreID: afsOrder.VendorStoreID,
|
||
StoreID: int(utils.Str2Int64WithDefault(afsOrder.VendorStoreID, 0)),
|
||
AfsCreatedAt: afsOrder.AfsCreatedAt,
|
||
|
||
VendorStatus: afsOrder.VendorStatus,
|
||
VendorReasonType: afsOrder.VendorReasonType,
|
||
ReasonType: int8(utils.Str2Int64WithDefault(afsOrder.VendorReasonType, 0)),
|
||
ReasonDesc: utils.LimitUTF8StringLen(afsOrder.ReasonDesc, 1024),
|
||
ReasonImgList: afsOrder.ReasonImgList,
|
||
VendorAppealType: afsOrder.VendorAppealType,
|
||
AppealType: int8(utils.Str2Int64WithDefault(afsOrder.VendorAppealType, 0)),
|
||
Flag: model.OrderFlagMaskTempJX,
|
||
}
|
||
outAfsOrder.Status = int(utils.Str2Int64WithDefault(afsOrder.VendorStatus, 0))
|
||
|
||
skuNumber := 0 // 申请退款商品种类个数
|
||
skuCount := 0 // 申请商品退款总条数
|
||
refundMoney := 0
|
||
// 当前申请退款的商品
|
||
for _, x := range afsOrder.Skus {
|
||
orderSku := &model.OrderSkuFinancial{
|
||
Count: x.Count,
|
||
VendorSkuID: x.VendorSkuID,
|
||
SkuID: int(utils.Str2Int64WithDefault(x.VendorSkuID, 0)),
|
||
Name: x.Name,
|
||
UserMoney: x.SalePrice * int64(x.Count),
|
||
}
|
||
if x.PromotionType != 0 && x.PromotionType != jdapi.PromotionTypeNormal {
|
||
orderSku.StoreSubName = utils.Int2Str(x.PromotionType)
|
||
}
|
||
outAfsOrder.Skus = append(outAfsOrder.Skus, orderSku)
|
||
skuCount += orderSku.Count
|
||
skuNumber++
|
||
refundMoney += x.Count * int(x.SalePrice)
|
||
}
|
||
// 已经退款商品
|
||
refundFinancial, err := dao.GetStoreAfsOrderSkuList2(db, []string{afsOrder.VendorOrderID})
|
||
if err != nil && !dao.IsNoRowsError(err) {
|
||
return nil, err
|
||
}
|
||
for _, f := range refundFinancial {
|
||
skuCount += f.Count
|
||
skuNumber++
|
||
refundMoney += f.Count * int(f.SalePrice)
|
||
}
|
||
|
||
// 获取订单商品列表(所有的订单商品)
|
||
skuList, err := dao.GetSimpleOrderSkus(dao.GetDB(), afsOrder.VendorOrderID, nil)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// 最后一个商品
|
||
if len(skuList) == len(refundFinancial)+len(afsOrder.Skus) && len(skuList) != model.YES {
|
||
return nil, errors.New("如需整单退款,请使用整单退,无法分批次整单退款")
|
||
}
|
||
|
||
orderSkuNumber := 0
|
||
orderSkuCount := 0
|
||
for _, v := range skuList {
|
||
orderSkuNumber++
|
||
orderSkuCount += v.Count
|
||
}
|
||
if skuNumber == orderSkuNumber && skuCount == orderSkuCount {
|
||
outAfsOrder.RefundType = model.AfsTypeFullRefund
|
||
} else { // 部分退款,只退还商品部分
|
||
outAfsOrder.RefundType = model.AfsTypePartRefund
|
||
}
|
||
}
|
||
return outAfsOrder, err
|
||
}
|
||
|
||
func callbackAfsMsg2Status(msg *CallbackMsg) *model.OrderStatus {
|
||
orderStatus := &model.OrderStatus{
|
||
VendorOrderID: msg.ThingID2, // 是售后单ID,不是订单ID,订单ID在RefVendorOrderID中
|
||
VendorID: model.VendorIDJX,
|
||
OrderType: model.OrderTypeAfsOrder,
|
||
RefVendorOrderID: msg.ThingID,
|
||
RefVendorID: model.VendorIDJX,
|
||
VendorStatus: msg.SubMsgType,
|
||
Status: int(utils.Str2Int64WithDefault(msg.SubMsgType, 0)),
|
||
StatusTime: time.Now(),
|
||
Remark: "",
|
||
}
|
||
return orderStatus
|
||
}
|
||
|
||
func onAfsOrderMsg(msg *CallbackMsg) (err error) {
|
||
subMsgType := int(utils.Str2Int64WithDefault(msg.SubMsgType, 0))
|
||
status := callbackAfsMsg2Status(msg)
|
||
if subMsgType == model.AfsOrderStatusWait4Approve || subMsgType == model.AfsOrderStatusNew {
|
||
afsOrder, err2 := buildAfsOrder(msg)
|
||
if err = err2; err == nil {
|
||
err = partner.CurOrderManager.OnAfsOrderNew(afsOrder, status)
|
||
}
|
||
} else {
|
||
err = partner.CurOrderManager.OnOrderStatusChanged("", status)
|
||
}
|
||
return err
|
||
}
|
||
|
||
func postFakeAfsMsg(orderNo, afsOrderID string, status int) {
|
||
msg := &CallbackMsg{
|
||
AppKey: appKey,
|
||
MsgType: MsgTypeAfsOrder,
|
||
SubMsgType: utils.Int2Str(status),
|
||
ThingID: orderNo,
|
||
ThingID2: afsOrderID,
|
||
Timestamp: time.Now().Unix(),
|
||
}
|
||
utils.CallFuncAsync(func() {
|
||
OnCallbackMsg(msg)
|
||
})
|
||
}
|
||
|
||
func NotifyAfsOrderStatusChanged(order *model.AfsOrder, status int) (err error) {
|
||
orderMsg := *order
|
||
orderMsg.Status = status
|
||
if err = jxAPI.NotifyAfsOrderStatusChanged(&orderMsg); err == nil {
|
||
postFakeAfsMsg(orderMsg.VendorOrderID, orderMsg.AfsOrderID, orderMsg.Status)
|
||
}
|
||
return err
|
||
}
|