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.

343 lines
9.2 KiB

4 years ago
package aftersales
import (
"fmt"
"recook/internal/back"
"recook/internal/dbc"
4 years ago
"recook/internal/libs/snow"
4 years ago
"recook/internal/model/aftersales"
"recook/internal/model/goods"
"recook/internal/model/order"
"recook/internal/v2/hook"
"recook/internal/v2/lib/common"
"recook/internal/v2/lib/jcook"
"recook/internal/v2/model/recook/after"
"recook/tools"
"time"
"github.com/gin-gonic/gin"
"github.com/golangkit/formatime"
"github.com/shopspring/decimal"
)
type applyRefundParam struct {
UserID uint `json:"userId"`
OrderGoodsIDs []uint `json:"orderGoodsIds"`
Coin decimal.Decimal `json:"coin"` //允许发货订单发起仅退款的数字,
ReasonContent string `json:"reasonContent"` //如果是已发货的话,必须填写申请理由
ReasonImg string `json:"reasonImg"`
}
4 years ago
// RefundOrder 退款
//
//标记订单有售后痕迹
//生成退款记录
//
//钱包支付;退回商品用过的的余额
//退回优惠券
//退回运费
4 years ago
func RefundOrder(c *gin.Context) {
var p applyRefundParam
err := tools.ParseParams(&p, c)
if err != nil {
back.Fail(c, err.Error())
return
}
if len(p.OrderGoodsIDs) == 0 {
back.Fail(c, "参数不完整")
return
}
var temp order.GoodsDetail
err = dbc.DB.First(&temp, p.OrderGoodsIDs[0]).Error
if err != nil {
back.Fail(c, err.Error())
return
}
var orderTemp order.Information
err = dbc.DB.First(&orderTemp, temp.OrderID).Error
if err != nil {
back.Fail(c, err.Error())
return
}
4 years ago
if (orderTemp.Kind == 1 || orderTemp.Kind == 2) && orderTemp.JCookStatus == 0 {
4 years ago
var ogs []order.GoodsDetail
err = dbc.DB.Find(&ogs, "order_id = ?", orderTemp.ID).Error
if err != nil {
back.Fail(c, err.Error())
return
}
ids := make([]uint, 0)
for _, v := range ogs {
ids = append(ids, v.ID)
}
p.OrderGoodsIDs = ids
}
orderGoodsList := make([]order.GoodsDetail, 0, 0)
for _, v := range p.OrderGoodsIDs {
var one order.GoodsDetail
err = dbc.DB.First(&one, v).Error
if err != nil {
back.Fail(c, err.Error())
return
}
var count uint
dbc.DB.Table((&aftersales.Goods{}).TableName()).Where(aftersales.Goods{
OrderGoodsID: v,
}).Count(&count)
if count >= 3 {
back.Fail(c, one.GoodsName+"已超过三次售后申请,不可再次申请")
return
}
orderGoodsList = append(orderGoodsList, one)
}
var orderInfo order.Information
if err = dbc.DB.First(&orderInfo, orderGoodsList[0].OrderID).Error; err != nil {
back.Fail(c, err.Error())
return
}
if orderInfo.Status == 4 {
back.Fail(c, "已超过售后期限")
return
}
if time.Now().Unix() >= orderInfo.CreatedAt.Time.AddDate(0, 0, 18).Unix() {
back.Fail(c, "关账时间已过,无法发起售后")
return
}
var asCount uint
dbc.DB.Table((&aftersales.Goods{}).TableName()).Where("order_id = ?", orderInfo.ID).Count(&asCount)
if asCount > 20 {
back.Fail(c, "单笔订单售后次数最多20次您已经超过上线")
return
}
for _, v := range orderGoodsList {
if v.PayStatus == 0 {
back.Fail(c, "当前订单未支付")
return
}
if v.AssType != 0 {
back.Fail(c, "请勿重复申请")
return
}
if v.GoodsAmount.LessThan(p.Coin) {
back.Err(c, "计算错误!!! 退款金额大于总金额")
return
}
//如果是已经发货的
if v.ExpressStatus == 1 {
if len(p.ReasonContent) == 0 {
back.Fail(c, "请填写申请理由")
return
}
if p.Coin.LessThanOrEqual(decimal.NewFromInt(0)) {
back.Fail(c, "申请补偿订单必须大于0")
return
}
}
}
var goodsIds []uint
for _, detail := range orderGoodsList {
goodsIds = append(goodsIds, detail.GoodsID)
}
var goodsInfos []goods.Information
dbc.DB.Model(&goods.Information{}).Find(&goodsInfos, "id in (?)", goodsIds)
goodsInfoMap := map[uint]goods.Information{}
for _, info := range goodsInfos {
goodsInfoMap[info.ID] = info
}
4 years ago
var ids []uint
4 years ago
for i, v := range orderGoodsList {
goodsDetail := orderGoodsList[i]
asGoods := aftersales.Goods{
AncestorID: v.AncestorID,
ParentID: v.ParentID,
SharerID: orderInfo.SharerID,
UserID: v.UserID,
UserRole: orderInfo.UserRole,
OrderID: v.OrderID,
OrderGoodsID: v.ID,
VendorID: v.VendorID,
VendorName: v.VendorName,
BrandName: v.BrandName,
CategoryName: v.CategoryName,
GoodsID: v.GoodsID,
GoodsName: v.GoodsName,
SkuName: v.SkuName,
SkuCode: v.SkuCode,
MainPhotoURL: v.MainPhotoURL,
Quantity: v.Quantity,
OrderTime: v.OrderTime,
OrderTotalAmount: orderInfo.ActualTotalAmount,
RefundAmount: v.ActualAmount, //这个就是最后实际支付的价格
RefundCoin: v.CoinAmount,
TradeNo: orderInfo.TradeNo,
PayMethod: orderInfo.PayMethod,
ThirdPartyType: goodsInfoMap[v.GoodsID].ThirdPartyType,
IsShip: v.ExpressStatus,
AssType: 1,
ReturnStatus: 1,
ApplyTime: formatime.NewSecondNow(),
ReasonImg: p.ReasonImg,
ReasonContent: p.ReasonContent,
RefundNo: fmt.Sprintf("%d_%vA%d", time.Now().Unix(), orderInfo.TradeNo, goodsDetail.ID),
}
//如果是已经发货的订单需要在售后里面把实际支付改成功0将瑞币改成提交过来的数字
if asGoods.IsShip == 1 {
// 认为是补偿订单
asGoods.AssType = 3
if p.Coin.GreaterThan(v.ActualAmount.Add(v.CoinAmount)) {
back.Fail(c, "补偿金额超过最大金额")
return
}
if p.Coin.GreaterThan(v.ActualAmount) && p.Coin.LessThanOrEqual(v.ActualAmount.Add(v.CoinAmount)) {
asGoods.RefundAmount = v.ActualAmount.Truncate(2)
asGoods.RefundCoin = p.Coin.Sub(v.ActualAmount).Truncate(2)
}
if p.Coin.LessThan(v.ActualAmount) {
asGoods.RefundAmount = p.Coin.Truncate(2)
asGoods.RefundCoin = decimal.NewFromInt(0)
}
}
tx := dbc.DB.Begin()
{
4 years ago
lastID, e := snow.GetAfsWorker().NextID()
if e != nil {
back.Err(c, "网络异常,请稍后重试")
4 years ago
tx.Rollback()
return
}
4 years ago
asGoods.ID = uint(lastID)
4 years ago
if asGoods.IsShip == 1 {
tx.Model(&goodsDetail).Updates(order.GoodsDetail{
AssType: 3,
})
} else {
tx.Model(&goodsDetail).Updates(order.GoodsDetail{
AssType: 1,
})
}
if err = tx.Create(&asGoods).Error; err != nil {
back.Err(c, err.Error())
tx.Rollback()
return
}
4 years ago
ids = append(ids, asGoods.ID)
4 years ago
if err := hook.AfterHook.Create(&goodsDetail, &asGoods); err != nil {
back.Err(c, err.Error())
tx.Rollback()
return
}
//这里插入日志
user, _ := common.GetManageUser(c)
4 years ago
Log := aftersales.AftersalesLog{
AsId: uint(lastID),
4 years ago
Title: "买家申请仅退款",
Content: "退款原因:" + p.ReasonContent + "|退款金额:" + (asGoods.RefundAmount).String() + "|退回瑞币:" + asGoods.RefundCoin.String(),
Ctime: formatime.NewSecondNow(),
User: user.Name,
UserId: user.Id,
}
4 years ago
tx.Create(&Log)
4 years ago
4 years ago
if (orderInfo.Kind == 1 || orderInfo.Kind == 2) && orderInfo.ApplyStatus != 11 && orderInfo.ApplyStatus != 12 && orderInfo.JCookStatus == 0 {
4 years ago
client := jcook.GetClient()
req := jcook.OrderCancelReq{
OrderID: orderInfo.JCookOrderID,
CancelReasonCode: 100,
}
var resp jcook.OrderCancelResp
if err = client.Exec(req, &resp); err != nil {
tx.Rollback()
back.Suc(c, "申请失败", nil)
return
}
if resp.CancelStatus == 1 {
tx.Model(orderInfo).Update("apply_status", 12) // 取消申请失败
} else {
tx.Model(orderInfo).Update("apply_status", 11) // 取消申请成功
}
}
}
tx.Commit()
}
c.Set("status", "AfterApply")
4 years ago
c.Set("id", ids)
4 years ago
back.Suc(c, "申请成功,请等待商家审核", nil)
}
type CannelAfterOrderPem struct {
ID uint `json:"orderGoodsId"`
}
//撤销售后的申请
//有售后,且售后未完结,才能撤销
//refund_status=1,express_status=1ass_type=0才能申请撤销退款
func CannelAfterOrder(c *gin.Context) {
var p CannelAfterOrderPem
err := tools.ParseParams(&p, c)
if err != nil {
back.Fail(c, err.Error())
return
}
userlog, _ := common.GetManageUser(c)
var orderGoodsDea order.GoodsDetail
dbc.DB.First(&orderGoodsDea, "id=? and express_status=1 and ass_type!=0", p.ID)
if orderGoodsDea.ID <= 0 {
back.Fail(c, "该订单无法撤销售后")
return
}
//去撤销售后
dbc.DB.Table("recook_order_goods_detail").Where("id=?", p.ID).Update(map[string]interface{}{
"ass_type": 0,
})
var idlist []uint
var afterOrder after.RecookAfterSalesGoodsModel
dbc.DB.Order("id desc").First(&afterOrder, "order_goods_id=?", p.ID)
if afterOrder.Id > 0 {
dbc.DB.Model(&afterOrder).Updates(aftersales.Goods{
ReturnStatus: 6,
RejectReason: "买家主动撤销",
FinishTime: formatime.NewSecondNow(),
IsClosed: 1,
})
hook.AfterHook.Close(&afterOrder)
aftersalesLog := aftersales.AftersalesLog{
AsId: afterOrder.Id,
Title: "主动撤销",
Content: "买家主动撤销售后",
Ctime: formatime.NewSecondNow(),
User: userlog.Name,
UserId: userlog.Id,
}
dbc.DB.Create(&aftersalesLog)
}
idlist = append(idlist, afterOrder.Id)
c.Set("status", "AfterApply")
c.Set("id", idlist)
back.Suc(c, "", nil)
}