Files
jx-callback/business/partner/purchase/jx/phpjx/order_afs.go
邹宗楠 eccfb45dc6 1
2023-04-13 14:52:22 +08:00

218 lines
7.8 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 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
}