Files
jx-callback/business/partner/purchase/jx/localjx/order.go
2020-06-27 10:51:34 +08:00

1783 lines
63 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 localjx
import (
"crypto/md5"
"fmt"
"math"
"regexp"
"sort"
"strings"
"time"
"git.rosy.net.cn/jx-callback/business/jxcallback/orderman"
"git.rosy.net.cn/jx-callback/business/jxstore/event"
"git.rosy.net.cn/jx-callback/globals"
"git.rosy.net.cn/baseapi/platformapi/jdeclpapi"
"git.rosy.net.cn/baseapi/platformapi/wxpayapi"
"git.rosy.net.cn/jx-callback/globals/api"
"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
"git.rosy.net.cn/jx-callback/business/jxutils/netprinter"
"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/baseapi/utils/errlist"
"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/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/delivery"
)
const (
OrderCreateTypePre = 0 // 预创建
OrderCreateTypeNormal = 1 // 正常创建
PayWaitingTime = 10 * time.Minute // 等待支付的最长时间
DingShiDaMinTime = 1 * time.Hour
specialStoreID = 100274
specialFreightPrice = 1500
wxAppID = "wx4b5930c13f8b1170"
autoCancelOrderReason = "支付超时,系统自动取消!"
cancelMatterOrderReason = "失败重发!"
splitMatterOrderMinWeight = 4500 //物料订单分包最少要4.5kg
jxwxfMatterEclpID = "EMG4418113943423" //京西五香粉物料编码
)
type JxSkuInfo struct {
SkuID int `json:"skuID"`
Count int `json:"count"`
Price int64 `json:"price,omitempty"` // 原价
SalePrice int64 `json:"salePrice,omitempty"` // 售卖价
Name string `json:"name"`
Weight int `json:"weight"`
GroupSign bool `json:"groupSign"`
}
type JxSkuInfo2 struct {
SkuID int `json:"skuID"`
Count int `json:"count"`
Price int64 `json:"price,omitempty"` // 原价
SalePrice int64 `json:"salePrice,omitempty"` // 售卖价
Name string `json:"name"`
Weight int `json:"weight"`
GroupSign bool `json:"groupSign"`
}
type JxSkuInfoList []*JxSkuInfo
func (l JxSkuInfoList) Len() int {
return len(l)
}
func (l JxSkuInfoList) Less(i, j int) bool {
if l[i].SkuID == l[j].SkuID {
return l[i].SalePrice < l[j].SalePrice
}
return l[i].SkuID < l[j].SkuID
}
func (l JxSkuInfoList) Swap(i, j int) {
l[i], l[j] = l[j], l[i]
}
type JxOrderInfo struct {
BuyerComment string `json:"buyerComment"`
StoreID int `json:"storeID"`
Skus []*JxSkuInfo `json:"skus"`
ExpectedDeliveredTimestamp int64 `json:"expectedDeliveredTimestamp"` // 预期送达时间
TotalPrice int64 `json:"totalPrice"` // 单位为分 订单总价
FreightPrice int64 `json:"freightPrice"` // 单位为分 订单配送费
OrderPrice int64 `json:"orderPrice"` // 单位为分 订单商品价格
ActualPayPrice int64 `json:"actualPayPrice"` // 单位为分 顾客实际支付
OrderID int64 `json:"orderID"`
StoreName string `json:"storeName"`
Weight int `json:"weight"`
FromStoreID int `json:"fromStoreID"`
}
type DeliveryTimeItem struct {
ViewTime string `json:"viewTime"`
UnixTime int64 `json:"unixTime"`
ViewShippingFee string `json:"viewShippingFee"`
}
type DeliveryDayTimeInfo struct {
Date string `json:"date"`
TimeList []*DeliveryTimeItem `json:"timeList"`
}
type MatterOrderStatus struct {
Time time.Time `json:"time"`
Status string `json:"status"`
Name string `json:"name"`
Sign int `sign`
}
var (
orderNoBeginTimestamp int64
weekdayMap = map[int]string{
1: "一",
2: "二",
3: "三",
4: "四",
5: "五",
6: "六",
0: "日",
}
dayList = []string{"今天", "明天", "后天"}
bagMap = map[int]int{
6039382: 100,
6039383: 200,
6039384: 200,
6039387: 200,
6039390: 200,
}
regexpCnameAndCmobile = regexp.MustCompile(`配送员,(.*),手机号,(.*)`)
regexpCnameAndCmobile2 = regexp.MustCompile(`(快递员:(.*),联系电话:(.*)`)
bagSkuMap = map[int]int{ //京西物料袋子skuid
6039382: 6039382,
6039383: 6039383,
6039384: 6039384,
6039387: 6039387,
6039390: 6039390,
}
)
func init() {
orderNoBeginTimestamp = utils.Str2Time("2010-01-01 00:00:00").Unix()
}
func GetMyOrders(ctx *jxcontext.Context, fromDateStr, toDateStr string, params map[string]interface{}, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
db := dao.GetDB()
params["vendorIDs"] = string(utils.MustMarshal([]int{model.VendorIDJX}))
tmpOrderList, totalCount, err := dao.GetOrders(db, nil, false, false, fromDateStr, toDateStr, false, nil, false, ctx.GetUserID(), params, offset, pageSize)
if err == nil {
pagedInfo = &model.PagedInfo{
TotalCount: totalCount,
}
if totalCount > 0 {
var ids []int64
for _, v := range tmpOrderList {
ids = append(ids, v.ID)
}
orderSkuList, _, err2 := dao.GetOrders(db, ids, true, false, "", "", false, nil, false, "", nil, 0, model.UnlimitedPageSize)
if err = err2; err == nil {
orderMap := make(map[string]*model.GoodsOrderExt)
var orderList []*model.GoodsOrderExt
for _, v := range orderSkuList {
universalOrderID := jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID)
if orderMap[universalOrderID] == nil {
orderMap[universalOrderID] = v
orderList = append(orderList, v)
}
orderMap[universalOrderID].SkuList = append(orderMap[universalOrderID].SkuList, &v.ShortSkuInfo)
}
pagedInfo.Data = orderList
} else {
pagedInfo = nil
}
}
}
return pagedInfo, err
}
func GetMyAfsOrders(ctx *jxcontext.Context, fromDateStr, toDateStr string, params map[string]interface{}, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) {
return pagedInfo, err
}
func GetMyOrderCountInfo(ctx *jxcontext.Context, fromDate, toDate time.Time, statuss []int) (countInfo []*model.GoodsOrderCountInfo, err error) {
countInfo, err = dao.GetMyOrderCountInfo(dao.GetDB(), ctx.GetUserID(), fromDate, toDate, statuss)
return countInfo, err
}
//fromStoreID 为0 表示非物料订单(京西商城订单等)
//fromStoreID 为 门店ID 表示是物料订单fromStoreID表示是哪个门店申请的物料
//fromStoreID 为-1 表示也是物料订单,但是不是门店申请,是个人申请的
//fromStoreID 在后面 generateOrder中有用
func CreateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64, createType int, fromStoreID int, IsDeliverySelf bool) (outJxOrder *JxOrderInfo, err error) {
outJxOrder, deliveryAddress, err := generateOrder(ctx, jxOrder, addressID, fromStoreID, "", IsDeliverySelf)
if err != nil {
return nil, err
}
if fromStoreID != 0 {
checkMatterDeliveryAddress(deliveryAddress)
}
if createType != OrderCreateTypePre {
if outJxOrder.TotalPrice != jxOrder.TotalPrice {
return nil, fmt.Errorf("商品或配送信息发生改变,请重新下单")
}
outJxOrder.OrderID = GenOrderNo(ctx)
order, err2 := jxOrder2GoodsOrder(ctx, outJxOrder, deliveryAddress, "", IsDeliverySelf)
if err = err2; err == nil {
order.AddressID = addressID
order.Status = model.OrderStatusWait4Pay
callNewOrder(order)
}
}
return outJxOrder, err
}
// 买家取消(或申请取消)订单
func BuyerCancelOrder(ctx *jxcontext.Context, orderID int64, reason string) (canceled bool, err error) {
order, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(orderID), model.VendorIDJX)
if err == nil {
if order.Status < model.OrderStatusNew {
order.Status = model.OrderStatusCanceled
order.VendorStatus = utils.Int2Str(model.OrderStatusCanceled)
if err = partner.CurOrderManager.UpdateOrderFields(order, []string{model.FieldStatus, "VendorStatus"}); err == nil {
canceled = true
}
} else {
err = fmt.Errorf("暂不支持自行取消订单,请联系商家取消")
// err = changeOrderStatus(utils.Int64ToStr(orderID), model.OrderStatusApplyCancel, fmt.Sprintf("用户%s主动取消", ctx.GetUserName()))
}
}
return canceled, err
}
func Pay4Order(ctx *jxcontext.Context, orderID int64, payType int, vendorPayType string) (orderPay *model.OrderPay, err error) {
order, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(orderID), model.VendorIDJX)
if err == nil {
switch payType {
case model.PayTypeWX:
if orderPay, err = pay4OrderByWX(ctx, order, vendorPayType); err == nil {
dao.WrapAddIDCULDEntity(orderPay, ctx.GetUserName())
err = dao.CreateEntity(dao.GetDB(), orderPay)
}
case model.PayTypeTL:
if orderPay, err = pay4OrderByTL(ctx, order, vendorPayType); err == nil && orderPay != nil {
dao.WrapAddIDCULDEntity(orderPay, ctx.GetUserName())
err = dao.CreateEntity(dao.GetDB(), orderPay)
}
default:
err = fmt.Errorf("支付方式:%d当前不支持", payType)
}
}
return orderPay, err
}
func time2ShortTimeStr(t time.Time) string {
return t.Format("15:04")
}
func GetAvailableDeliverTime(ctx *jxcontext.Context, storeID int) (deliverTimerList []*DeliveryDayTimeInfo, err error) {
db := dao.GetDB()
storeDetail, err := dao.GetStoreDetail(db, storeID, model.VendorIDJX)
if err != nil {
return nil, err
}
if storeDetail.Status != model.StoreStatusOpened {
return nil, fmt.Errorf("门店:%s不是营业状态,状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status])
}
// now := utils.Str2Time(timeStr)
now := time.Now()
// beginDate := utils.Time2Date(utils.Str2Time(timeStr))
beginDate := utils.Time2Date(now)
minDingShiDaTime := now.Add(DingShiDaMinTime)
viewShippingFee := "约6.6元配送费"
if storeID == specialStoreID {
viewShippingFee = "免费配送"
}
var isOrder = false
if storeDetail.IsOrder == model.YES {
isOrder = true
beginDate = beginDate.AddDate(0, 0, 1)
}
for i, dayStr := range dayList {
if isOrder {
isOrder = false
continue
}
openTime1 := jxutils.JxOperationTime2TimeByDate(storeDetail.OpenTime1, beginDate)
closeTime1 := jxutils.JxOperationTime2TimeByDate(storeDetail.CloseTime1, beginDate)
openTime2 := jxutils.JxOperationTime2TimeByDate(storeDetail.OpenTime2, beginDate)
closeTime2 := jxutils.JxOperationTime2TimeByDate(storeDetail.CloseTime2, beginDate)
timeInfo := &DeliveryDayTimeInfo{
Date: fmt.Sprintf("%s(周%s)", dayStr, weekdayMap[int(beginDate.Weekday())]),
}
if i == 0 {
if isTimeInOpTime(storeDetail.OpenTime1, storeDetail.CloseTime1, storeDetail.OpenTime2, storeDetail.CloseTime2, now) {
timeInfo.TimeList = append(timeInfo.TimeList, &DeliveryTimeItem{
ViewTime: "立即送出",
UnixTime: 0,
ViewShippingFee: viewShippingFee,
})
}
}
for j := 0; j < 24*3; j++ {
deliveryTime := beginDate.Add(time.Duration(j) * 20 * time.Minute)
if deliveryTime.Sub(minDingShiDaTime) >= 0 {
if (deliveryTime.Sub(openTime1) >= 0 && deliveryTime.Sub(closeTime1) <= 0) ||
(storeDetail.OpenTime2 > 0 && deliveryTime.Sub(openTime2) >= 0 && deliveryTime.Sub(closeTime2) <= 0) {
timeInfo.TimeList = append(timeInfo.TimeList, &DeliveryTimeItem{
ViewTime: time2ShortTimeStr(deliveryTime),
UnixTime: deliveryTime.Unix(),
ViewShippingFee: viewShippingFee,
})
}
}
}
if len(timeInfo.TimeList) > 0 {
deliverTimerList = append(deliverTimerList, timeInfo)
}
beginDate = beginDate.Add(24 * time.Hour)
}
if len(deliverTimerList) > 0 {
if deliverTimerList[0].TimeList[0].UnixTime != 0 {
deliverTimerList[0].TimeList[0].ViewTime = "营业即送"
}
}
return deliverTimerList, err
}
func OnPayFinished(orderPay *model.OrderPay) (err error) {
order, err := partner.CurOrderManager.LoadOrder(orderPay.VendorOrderID, orderPay.VendorID)
if err == nil {
db := dao.GetDB()
dao.UpdateEntity(db, orderPay)
if count, err2 := dao.GetJxOrderCount(db, jxutils.GetSaleStoreIDFromOrder(order), order.VendorOrderID, order.OrderCreatedAt); err2 == nil {
order.OrderSeq = count + 1
partner.CurOrderManager.UpdateOrderFields(order, []string{"OrderSeq"})
}
order.Status = model.OrderStatusNew
order.VendorStatus = utils.Int2Str(model.OrderStatusNew)
order.StatusTime = *orderPay.PayFinishedAt
err = callNewOrder(order)
//如果是物料的订单,直接到拣货完成,配送中的状态
if order.FromStoreID != 0 {
netprinter.PrintOrderByOrder(jxcontext.AdminCtx, order)
PickupGoods(order, false, "jxadmin")
}
}
return err
}
func GenOrderNo(ctx *jxcontext.Context) (orderNo int64) {
const prefix = 88
const randPartNum = 1000
orderNo = time.Now().Unix() - orderNoBeginTimestamp
// fmt.Println(orderNo)
orderNo = orderNo * randPartNum
md5Bytes := md5.Sum([]byte(utils.GetUUID()))
randPart := 0
for k, v := range md5Bytes {
randPart += int(v) << ((k % 3) * 8)
}
orderNo += int64(randPart % randPartNum)
orderNo += int64(math.Pow10(int(math.Log10(float64(orderNo)))+1)) * prefix
return orderNo
}
func GenAfsOrderNo(ctx *jxcontext.Context) (orderNo int64) {
const prefix = 80
const randPartNum = 100
orderNo = time.Now().Unix() - orderNoBeginTimestamp
orderNo = orderNo * randPartNum
md5Bytes := md5.Sum([]byte(utils.GetUUID()))
randPart := 0
for k, v := range md5Bytes {
randPart += int(v) << ((k % 3) * 8)
}
orderNo += int64(randPart % randPartNum)
orderNo += int64(math.Pow10(int(math.Log10(float64(orderNo)))+1)) * prefix
return orderNo
}
func GenPayOrderID(order *model.GoodsOrder) (payOrderID int64) {
return utils.Str2Int64(order.VendorOrderID)
}
func GenRefundID(order *model.GoodsOrder) (refundID int64) {
const suffix = 100000
refundID = utils.Str2Int64(order.VendorOrderID) * suffix
refundID += int64(time.Now().Sub(order.OrderFinishedAt) / time.Minute)
return refundID
}
func formalizeSkus(skus []*JxSkuInfo) (outSkus []*JxSkuInfo) {
skuMap := make(map[int]int)
for _, v := range skus {
skuMap[v.SkuID] += v.Count
}
for skuID, skuCount := range skuMap {
outSkus = append(outSkus, &JxSkuInfo{
SkuID: skuID,
Count: skuCount,
})
}
return outSkus
}
func isTimeInOpTime(openTime1, closeTime1, openTime2, closeTime2 int16, time2Check time.Time) bool {
timeStrList := []string{
jxutils.OperationTime2StrWithSecond(openTime1),
jxutils.OperationTime2StrWithSecond(closeTime1),
}
if openTime1 > 0 {
timeStrList = append(timeStrList,
jxutils.OperationTime2StrWithSecond(openTime2),
jxutils.OperationTime2StrWithSecond(closeTime2),
)
}
checkTimeStr := utils.Time2TimeStr(time2Check)
for i := 0; i < len(timeStrList); i += 2 {
if checkTimeStr >= timeStrList[i] && checkTimeStr <= timeStrList[i+1] {
return true
}
}
return false
}
func generateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64, fromStoreID int, userID string, IsDeliverySelf bool) (outJxOrder *JxOrderInfo, deliveryAddress *dao.UserDeliveryAddressEx, err error) {
db := dao.GetDB()
if jxOrder.StoreID == 0 {
return nil, nil, fmt.Errorf("没有指定门店信息")
}
// 配送范围检查
storeDetail, err := dao.GetStoreDetail(db, jxOrder.StoreID, model.VendorIDJX)
if err != nil {
return nil, nil, err
}
var addressList []*dao.UserDeliveryAddressEx
if userID == "" {
addressList, _, err = dao.QueryUserDeliveryAddress(db, addressID, nil, 0, 0)
} else {
addressList, _, err = dao.QueryUserDeliveryAddress(db, addressID, []string{userID}, 0, 0)
}
if err != nil {
return nil, nil, err
}
if len(addressList) == 0 {
return nil, nil, fmt.Errorf("地址ID不正确")
}
deliveryAddress = addressList[0]
if distance := jxutils.Point2StoreDistance(deliveryAddress.Lng, deliveryAddress.Lat, storeDetail.Lng, storeDetail.Lat, storeDetail.DeliveryRangeType, storeDetail.DeliveryRange); distance == 0 {
return nil, nil, fmt.Errorf("当前送货地址不在门店%s的配送范围", storeDetail.Name)
}
// 营业状态及时间检查
if storeDetail.Status != model.StoreStatusOpened { // model.StoreStatusDisabled {
return nil, nil, fmt.Errorf("门店:%s状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status])
}
checkTime := time.Now()
if jxOrder.ExpectedDeliveredTimestamp == 0 {
if storeDetail.Status != model.StoreStatusOpened {
return nil, nil, fmt.Errorf("门店:%s不是营业状态,状态是:%s", storeDetail.Name, model.StoreStatusName[storeDetail.Status])
}
} else {
checkTime = utils.Timestamp2Time(jxOrder.ExpectedDeliveredTimestamp)
if checkTime.Sub(time.Now()) < DingShiDaMinTime {
return nil, nil, fmt.Errorf("预订单只能在1小时后")
}
if utils.Time2Date(time.Now()).Sub(utils.Time2Date(checkTime)) > 24*time.Hour {
return nil, nil, fmt.Errorf("预订单只能预定当天或第二天")
}
}
// if !isTimeInOpTime(storeDetail.OpenTime1, storeDetail.CloseTime1, storeDetail.OpenTime2, storeDetail.CloseTime2, checkTime) {
// return nil, nil, fmt.Errorf("门店:%s不在营业时间范围", storeDetail.Name)
// }
outJxOrder2 := *jxOrder
outJxOrder2.Skus = nil
outJxOrder2.OrderPrice = 0
outJxOrder2.Weight = 0
outJxOrder = &outJxOrder2
outJxOrder.StoreName = storeDetail.Name
skus := formalizeSkus(jxOrder.Skus)
// 允许空商品列表(一般用于测试配送地址,门店信息是否合适)
if len(skus) > 0 {
var skuIDs []int
for _, v := range skus {
skuIDs = append(skuIDs, v.SkuID)
}
storeSkuInfo, err := cms.GetStoreSkus(ctx, jxOrder.StoreID, skuIDs, true, "", true, false, map[string]interface{}{
"actVendorID": model.VendorIDJX,
}, 0, model.UnlimitedPageSize)
if err != nil {
return nil, nil, err
}
storeSkuMap := make(map[int]*dao.StoreSkuExt)
for _, v1 := range storeSkuInfo.SkuNames {
for _, v2 := range v1.Skus {
if v2.StoreSkuStatus != model.SkuStatusNormal {
return nil, nil, fmt.Errorf("此商品已下架请联系管理员skuID:[%v]", v2.SkuID)
}
storeSkuMap[v2.SkuID] = v2
}
}
skuList, err := dao.GetSkus(db, skuIDs, nil, nil, nil, nil)
if err != nil {
return nil, nil, err
}
skuMap := make(map[int]*model.SkuAndName)
for _, v := range skuList {
if fromStoreID != 0 {
if v.EclpID == "" {
return nil, nil, fmt.Errorf("此商品物料编码为空请联系管理员skuID:[%v]", v.ID)
}
}
skuMap[v.ID] = v
}
var (
result *orderman.OrderCount
sum int //申请物料的店的最近销量,以下会根据销量计算具体袋子的价格
flag = false //新店袋子拆分当个参数
)
if fromStoreID != 0 && fromStoreID != -1 {
result, _ = orderman.GetMatterStoreOrderCount(nil, fromStoreID)
sum = result.Count
}
if jxOrder.Weight == 0 {
for _, v := range jxOrder.Skus {
v.Weight = storeSkuMap[v.SkuID].Weight
jxOrder.Weight += v.Weight * v.Count
}
}
for _, v := range skus {
if storeSkuBind := storeSkuMap[v.SkuID]; storeSkuBind != nil {
if fromStoreID != 0 {
result2, _ := api.JdEclpAPI.QueryStock(storeSkuBind.EclpID)
if len(result2) > 0 {
if result2[0].UsableNum < v.Count {
return nil, nil, fmt.Errorf("此商品库存不足无法购买请联系管理员skuID:[%v]", v.SkuID)
}
}
}
if sku := skuMap[v.SkuID]; sku != nil {
jxSku := &JxSkuInfo{
SkuID: v.SkuID,
Price: int64(storeSkuBind.JxPrice),
Count: v.Count,
SalePrice: int64(storeSkuBind.JxPrice), // todo 考虑活动价
Weight: sku.Weight,
Name: jxutils.ComposeSkuName(sku.Prefix, sku.Name, sku.Comment, sku.Unit, sku.SpecQuality, sku.SpecUnit, 0, sku.ExPrefix, sku.ExPrefixBegin, sku.ExPrefixEnd),
}
if fromStoreID != -1 {
//活动商品要拆分,一分钱的单独列一个(count为1),正常价格的列在一起(count叠加)
if storeSkuBind.ActPrice != 0 && storeSkuBind.ActPrice < storeSkuBind.JxPrice {
jxSku.SalePrice = int64(storeSkuBind.ActPrice)
jxSku.Count = 1
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice
outJxOrder.Weight += jxSku.Count * jxSku.Weight
if v.Count-1 > 0 {
jxSku2 := *jxSku
jxSku2.SalePrice = jxSku.Price
jxSku2.Count = v.Count - 1
jxSku = &jxSku2
} else {
jxSku = nil
}
}
}
if jxSku != nil {
if fromStoreID == 0 || fromStoreID == -1 {
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice
} else { //以下else为物料订单袋子金额和数量处理
if !result.Flag { //只要flag是false就按原价申请是true再按订单量
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice
} else {
if result.Count == 0 { //这个条件被认为是新店,袋子限量
if bagMap[jxSku.SkuID] != 0 { //如果他买了袋子第一个袋子算1分钱其余按原价包括所有袋子
if !flag {
salePirce := jxSku.SalePrice
count := jxSku.Count
jxSku.SalePrice = 1
jxSku.Count = 1
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice
if count > 1 {
jxSku2 := *jxSku
jxSku2.SalePrice = salePirce
jxSku2.Count = count - 1
outJxOrder.Skus = append(outJxOrder.Skus, &jxSku2)
outJxOrder.OrderPrice += int64(jxSku2.Count) * jxSku2.SalePrice
outJxOrder.Weight += jxSku2.Count * jxSku2.Weight
}
flag = true
} else {
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice
}
} else {
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice
}
} else {
//袋子总数小于等于销量就是1分钱只要大于销量其他就按原价
//这个袋子规格是一份100个
if jxSku.SkuID == 6039382 {
if bagMap[jxSku.SkuID] != 0 {
if sum > 0 {
if bagMap[jxSku.SkuID]*jxSku.Count <= sum+100 {
jxSku.SalePrice = 1
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
outJxOrder.OrderPrice += int64(1 * jxSku.Count)
} else {
jxSku2 := *jxSku
jxSku2.SalePrice = jxSku.SalePrice
jxSku2.Count = int(int64(jxSku.Count) - utils.Float64TwoInt64(math.Ceil(utils.Int2Float64(sum)/100)))
outJxOrder.Weight += jxSku2.Count * jxSku2.Weight
jxSku.SalePrice = 1
jxSku.Count = int(utils.Float64TwoInt64(math.Ceil(utils.Int2Float64(sum) / 100)))
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
outJxOrder.Skus = append(outJxOrder.Skus, &jxSku2)
outJxOrder.OrderPrice += jxSku.SalePrice * int64(jxSku.Count)
outJxOrder.OrderPrice += jxSku2.SalePrice * int64(jxSku2.Count)
}
} else {
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice
}
sum = sum - bagMap[jxSku.SkuID]*jxSku.Count
}
} else if jxSku.SkuID == 6039383 || jxSku.SkuID == 6039384 || jxSku.SkuID == 6039387 || jxSku.SkuID == 6039390 { //这些袋子是一份200个
if bagMap[jxSku.SkuID] != 0 {
if sum > 0 {
if bagMap[jxSku.SkuID]*jxSku.Count <= sum+200 {
jxSku.SalePrice = 1
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
outJxOrder.OrderPrice += int64(1 * jxSku.Count)
} else {
jxSku2 := *jxSku
jxSku2.SalePrice = jxSku.SalePrice
jxSku2.Count = int(int64(jxSku.Count) - utils.Float64TwoInt64(math.Ceil(utils.Int2Float64(sum)/200)))
outJxOrder.Weight += jxSku2.Count * jxSku2.Weight
jxSku.SalePrice = 1
jxSku.Count = int(utils.Float64TwoInt64(math.Ceil(utils.Int2Float64(sum) / 200)))
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
outJxOrder.Skus = append(outJxOrder.Skus, &jxSku2)
outJxOrder.OrderPrice += jxSku.SalePrice * int64(jxSku.Count)
outJxOrder.OrderPrice += jxSku2.SalePrice * int64(jxSku2.Count)
}
} else {
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice
}
sum = sum - bagMap[jxSku.SkuID]*jxSku.Count
}
} else {
outJxOrder.Skus = append(outJxOrder.Skus, jxSku)
outJxOrder.OrderPrice += int64(jxSku.Count) * jxSku.SalePrice
}
}
}
}
outJxOrder.Weight += jxSku.Count * jxSku.Weight
}
}
}
}
//物料订单的配送费另算,所以排除了免得多算一次
if fromStoreID == 0 {
sort.Sort(JxSkuInfoList(outJxOrder.Skus))
outJxOrder.FreightPrice, _, err = delivery.CalculateDeliveryFee(dao.GetDB(), jxOrder.StoreID, "",
jxutils.StandardCoordinate2Int(deliveryAddress.Lng), jxutils.StandardCoordinate2Int(deliveryAddress.Lat),
model.CoordinateTypeMars, outJxOrder.Weight, checkTime)
}
// if jxOrder.StoreID == specialStoreID {
// outJxOrder.FreightPrice = 0
// }
} else {
outJxOrder.FreightPrice = 0
}
//表示此订单为物料配送订单
if fromStoreID != 0 {
storeDetail2, err2 := dao.GetStoreDetail(db, fromStoreID, model.VendorIDJX)
if err = err2; err != nil {
return nil, nil, fmt.Errorf("fromStoreID有误,[%v]", fromStoreID)
}
//要求配送人姓名填门店名
if fromStoreID != -1 {
deliveryAddress.ConsigneeName = storeDetail2.Name
}
outJxOrder.FromStoreID = fromStoreID
//TODO 修改配送费规则2020-04-28
//3kg 5元每多1kg加2元
//配送费要按分包规则计算
if outJxOrder.Weight <= 3000 {
outJxOrder.FreightPrice = 500
} else if outJxOrder.Weight > 3000 && outJxOrder.Weight <= splitMatterOrderMinWeight {
outJxOrder.FreightPrice = utils.Float64TwoInt64(500 + math.Ceil((utils.Int2Float64(outJxOrder.Weight)-3000)/1000)*200)
} else {
_, freightPrice, _ := tryToSplitMatterOrder(jxOrder)
outJxOrder.FreightPrice = freightPrice
}
///规则为: 配送费用规则。起价5元(含2kg)之后每kg+2元不足1kg按1kg计算。
// if outJxOrder.Weight <= 2000 {
// outJxOrder.FreightPrice = 500
// } else {
// outJxOrder.FreightPrice = utils.Float64TwoInt64(500 + math.Ceil((utils.Int2Float64(outJxOrder.Weight)-2000)/1000)*200)
// }
} else {
if outJxOrder.FreightPrice > specialFreightPrice {
outJxOrder.FreightPrice = specialFreightPrice
}
if outJxOrder.OrderPrice >= int64(storeDetail.DeliveryFeeDeductionSill) {
outJxOrder.FreightPrice -= int64(storeDetail.DeliveryFeeDeductionFee)
if outJxOrder.FreightPrice < 0 || IsDeliverySelf {
outJxOrder.FreightPrice = 0
}
}
}
if err == nil {
outJxOrder.TotalPrice = outJxOrder.OrderPrice + outJxOrder.FreightPrice
outJxOrder.ActualPayPrice = outJxOrder.TotalPrice
} else {
outJxOrder = nil
deliveryAddress = nil
}
return outJxOrder, deliveryAddress, err
}
//根据销量限制门店申请袋子数,现暂不使用该判断,万一以后要用就先没删
func matterSkusLimited(skus []*JxSkuInfo, storeID int) (err error) {
result, err := orderman.GetMatterStoreOrderCount(nil, storeID)
sum := 0
if result.Count != 0 {
for _, sku := range skus {
if sku.SkuID == 6039382 {
sum1 := 0
if bagMap[sku.SkuID] != 0 {
sum1 += bagMap[sku.SkuID] * sku.Count
sum += sum1
}
if utils.Int2Float64(sum1/100) >= math.Ceil(utils.Int2Float64(result.Count)/100) {
return fmt.Errorf("订单100个一份背心袋订购数量过多请按照实际销量购买大概销量[%v],购买数量:[%v]", result.Count, sum1)
}
}
if sku.SkuID == 6039383 || sku.SkuID == 6039384 || sku.SkuID == 6039387 || sku.SkuID == 6039390 {
sum2 := 0
if bagMap[sku.SkuID] != 0 {
sum2 += bagMap[sku.SkuID] * sku.Count
sum += sum2
}
if utils.Int2Float64(sum2/200) >= math.Ceil(utils.Int2Float64(result.Count)/200) {
return fmt.Errorf("订单200个一份背心袋订购数量过多请按照实际销量购买大概销量[%v],购买数量:[%v]", result.Count, sum2)
}
}
}
if sum-result.Count > 100 {
return fmt.Errorf("订单背心袋订购数量过多,请按照实际销量购买!,大概销量:[%v],购买数量:[%v]", result.Count, sum)
}
}
return err
}
func jxOrder2GoodsOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, deliveryAddress *dao.UserDeliveryAddressEx, userID string, IsDeliverySelf bool) (order *model.GoodsOrder, err error) {
order = &model.GoodsOrder{
VendorOrderID: utils.Int64ToStr(jxOrder.OrderID),
VendorID: model.VendorIDJX,
VendorStoreID: utils.Int2Str(jxOrder.StoreID),
StoreID: jxOrder.StoreID,
StoreName: jxOrder.StoreName,
// UserID: ctx.GetUserID(),
ConsigneeName: deliveryAddress.ConsigneeName,
ConsigneeMobile: deliveryAddress.ConsigneeMobile,
ConsigneeMobile2: deliveryAddress.ConsigneeMobile,
ConsigneeAddress: fmt.Sprintf("%s%s", deliveryAddress.Address, deliveryAddress.DetailAddress),
CoordinateType: model.CoordinateTypeMars,
ConsigneeLng: jxutils.StandardCoordinate2Int(deliveryAddress.Lng),
ConsigneeLat: jxutils.StandardCoordinate2Int(deliveryAddress.Lat),
Status: model.OrderStatusUnknown,
VendorStatus: "realnew",
OrderSeq: 0,
BuyerComment: jxOrder.BuyerComment,
DeliveryType: model.OrderDeliveryTypeStoreSelf,
StatusTime: time.Now(),
}
if userID == "" {
order.UserID = ctx.GetUserID()
} else {
order.UserID = userID
}
order.OrderCreatedAt = order.StatusTime
order.VendorUserID = order.UserID
if jxOrder.ExpectedDeliveredTimestamp != 0 {
order.ExpectedDeliveredTime = utils.Timestamp2Time(jxOrder.ExpectedDeliveredTimestamp)
order.BusinessType = model.BusinessTypeDingshida
} else {
order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
order.BusinessType = model.BusinessTypeImmediate
}
for _, sku := range jxOrder.Skus {
order.Skus = append(order.Skus, &model.OrderSku{
Count: sku.Count,
VendorSkuID: utils.Int2Str(sku.SkuID),
SkuID: sku.SkuID,
SkuName: sku.Name,
VendorPrice: sku.Price,
SalePrice: sku.SalePrice,
})
order.TotalShopMoney += int64(sku.Count) * sku.SalePrice
}
order.TotalShopMoney += jxOrder.FreightPrice
order.ActualPayPrice = order.TotalShopMoney
if jxOrder.FromStoreID != 0 {
order.FromStoreID = jxOrder.FromStoreID
order.WaybillVendorID = model.VendorIDJDWL
order.DeliveryFlag = model.OrderDeliveryFlagMaskScheduleDisabled
order.ConsigneeAddress = deliveryAddress.Address
order.Flag = 1
}
//如果是自提单就设置
if IsDeliverySelf {
order.DeliveryType = model.OrderDeliveryTypeSelfTake
}
return order, err
}
func AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
var status int
if isAcceptIt {
status = model.OrderStatusAccepted
} else {
status = model.OrderStatusCanceled
}
return changeOrderStatus(order.VendorOrderID, status, "")
}
func AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
return err
}
func PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
err = changeOrderStatus(order.VendorOrderID, model.OrderStatusFinishedPickup, "")
//如果是物料订单则直接进行京东物流的发单,并且状态直接变为配送中
err = orderSolutionForWuLiao(order)
return err
}
func orderSolutionForWuLiao(order *model.GoodsOrder) (err error) {
if order.FromStoreID != 0 {
var (
db = dao.GetDB()
)
err = changeOrderStatus(order.VendorOrderID, model.OrderStatusDelivering, "")
goods, err := dao.QueryOrders(db, order.VendorOrderID, -1, []int{model.VendorIDJX}, -1, utils.ZeroTimeValue, utils.ZeroTimeValue)
if err != nil || len(goods) == 0 {
return err
}
order.WaybillVendorID = model.VendorIDJDWL
dao.UpdateEntity(db, order, "WaybillVendorID")
orderSkus := goods[0].Skus
if order.Weight <= splitMatterOrderMinWeight { //2020-04-26, 从5kg 改为小于4.5kg
var (
goodsNos []string
prices []string
quantities []string
countSum int
)
for _, v := range orderSkus {
skus, err := dao.GetSkus(db, []int{v.SkuID}, nil, nil, nil, nil)
if err != nil || len(skus) == 0 {
continue
}
goodsNos = append(goodsNos, skus[0].EclpID)
prices = append(prices, "0")
quantities = append(quantities, utils.Int2Str(v.Count))
countSum += v.Count
}
//总订单不足3kg && 商品数量不足3个 && 五香粉有库存要送五香粉补足3个
stockResult, err := api.JdEclpAPI.QueryStock(jxwxfMatterEclpID)
if err == nil && len(stockResult) > 0 && stockResult[0].UsableNum > 0 {
if order.Weight < 3000 && countSum < 3 {
//要判断他本身买没买五香粉EMG4418113943423
var index = 9999
for k, v := range goodsNos {
if v == jxwxfMatterEclpID {
index = k
}
}
//说明他买了五香粉
if index != 9999 {
quantities[index] = utils.Int2Str(utils.Str2Int(quantities[index]) + 3 - countSum)
} else {
goodsNos = append(goodsNos, jxwxfMatterEclpID)
prices = append(prices, "0")
quantities = append(quantities, utils.Int2Str(3-countSum))
}
}
}
result, err := api.JdEclpAPI.AddOrder(&jdeclpapi.AddOrderParam{
IsvUUID: order.VendorOrderID,
IsvSource: jdeclpapi.IsvSource,
ShopNo: jdeclpapi.ShopNo,
DepartmentNo: jdeclpapi.DepartmentNo,
WarehouseNo: jdeclpapi.WarehouseNo,
SalesPlatformOrderNo: order.VendorOrderID,
SalePlatformSource: jdeclpapi.SalePlatformSource,
ConsigneeName: order.ConsigneeName,
ConsigneeMobile: order.ConsigneeMobile,
ConsigneeAddress: order.ConsigneeAddress,
OrderMark: jdeclpapi.OrderMark,
GoodsNo: strings.Join(goodsNos, ","),
Price: strings.Join(prices, ","),
Quantity: strings.Join(quantities, ","),
})
if err != nil {
return err
}
order.EclpOutID = result
dao.UpdateEntity(db, order, "EclpOutID")
waybill := &model.Waybill{
VendorOrderID: order.VendorOrderID,
OrderVendorID: model.VendorIDJX,
VendorWaybillID: order.EclpOutID,
WaybillVendorID: model.VendorIDJDWL,
Status: model.WaybillStatusDelivering,
WaybillCreatedAt: time.Now(),
StatusTime: time.Now(),
WaybillFinishedAt: utils.DefaultTimeValue,
DeliveryFlag: model.OrderDeliveryFlagMaskScheduleDisabled,
}
dao.CreateEntity(db, waybill)
} else { //如果重量超过5kg则需要进行拆单分包商品分包规则。最后一个包不超过5kg,其他包不超过3kg
outOrders, _, _ := tryToSplitMatterOrder(buildJxOrderInfo(order, orderSkus))
//以下为仿照CreateOrder改了一些参数
for k, v := range outOrders {
outJxOrder, deliveryAddress, err := generateOrder(jxcontext.AdminCtx, v, order.AddressID, order.FromStoreID, order.UserID, false)
if err != nil {
return err
}
//分包后的子订单ID默认是后面加两位目前的规则要改的话要注意取消订单那的判断
outJxOrder.OrderID = utils.Str2Int64(order.VendorOrderID)*100 + int64(k+1)
checkMatterDeliveryAddress(deliveryAddress)
order2, err2 := jxOrder2GoodsOrder(jxcontext.AdminCtx, outJxOrder, deliveryAddress, order.UserID, false)
if err = err2; err == nil {
order2.AddressID = order.AddressID
order2.Status = model.OrderStatusDelivering
err = partner.CurOrderManager.OnOrderNew(order2, model.Order2Status(order2))
orderSolutionForWuLiao(order2)
}
}
//刷新一下库存
for _, v := range goods[0].Skus {
cms.RefreshMatterStock(jxcontext.AdminCtx, v.SkuID)
}
}
for _, v := range order.Skus {
if bagSkuMap[v.SkuID] != 0 {
stores, _ := dao.GetStoreList(db, []int{order.FromStoreID}, nil, nil, nil, "")
if len(stores) > 0 {
store := stores[0]
store.IsBoughtMatter = model.YES
dao.UpdateEntity(db, store, "IsBoughtMatter")
}
}
}
}
return err
}
func SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
return changeOrderStatus(order.VendorOrderID, model.OrderStatusDelivering, "")
}
func SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) {
return changeOrderStatus(order.VendorOrderID, model.OrderStatusFinished, "")
}
func CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
if true { //order.Status < model.OrderStatusDelivering {
errList := errlist.New()
db := dao.GetDB()
payList, err2 := dao.GetOrderPayList(db, order.VendorOrderID, jxutils.GetPossibleVendorIDFromVendorOrderID(order.VendorOrderID))
if err = err2; err == nil {
for _, orderPay := range payList {
if orderPay.Status == model.PayStatusYes {
// refundID := utils.Int64ToStr(GenRefundID(order))
refundID := order.VendorOrderID
var orderPayRefund *model.OrderPayRefund
if orderPay.PayType == model.PayTypeWX {
orderPayRefund, err = refundOrderByWX(ctx, orderPay, refundID, orderPay.TotalFee, reason)
if err == nil {
dao.WrapAddIDCULDEntity(orderPayRefund, ctx.GetUserName())
errList.AddErr(dao.CreateEntity(dao.GetDB(), orderPayRefund))
} else {
errList.AddErr(err)
}
} else if orderPay.PayType == model.PayTypeTL {
orderPayRefund, err = RefundOrderByTL(ctx, orderPay, refundID, orderPay.TotalFee, reason)
if err != nil {
errList.AddErr(err)
}
}
if err == nil {
MarkArrears(db, order, orderPay)
err2 := CancelMatterOrder(db, order, reason)
errList.AddErr(err2)
}
} else {
orderPay.Status = model.PayStatusCanceled
_, err2 := dao.UpdateEntity(db, orderPay)
errList.AddErr(err2)
}
}
} else if dao.IsNoRowsError(err) {
err = nil
} else {
errList.AddErr(err)
}
if errList.GetErrListAsOne() == nil {
errList.AddErr(changeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, reason))
}
err = errList.GetErrListAsOne()
if len(payList) == 0 {
err = CancelMatterOrder(db, order, "")
}
} else {
err = fmt.Errorf("当前订单状态:%s不允许取消", model.OrderStatusName[order.Status])
}
return err
}
func CancelMatterOrder(db *dao.DaoDB, order *model.GoodsOrder, reason string) (err error) {
if order.FromStoreID != 0 {
if order.EclpOutID != "" {
//表示是京西的物料订单的子订单(拆分后的订单)
if len(order.VendorOrderID) == 16 && order.VendorID == model.VendorIDJX {
return fmt.Errorf("不允许取消该子订单请取消主订单进行退货退款主订单ID :[%v]", order.VendorOrderID[:len(order.VendorOrderID)-2])
}
_, err = api.JdEclpAPI.CancelOrder(order.EclpOutID)
} else {
goodsList, err := dao.GetMatterChildOrders(db, order.VendorOrderID)
if err == nil && len(goodsList) > 0 {
for _, v := range goodsList {
_, err = api.JdEclpAPI.CancelOrder(v.EclpOutID)
changeOrderStatus(v.VendorOrderID, model.OrderStatusCanceled, reason)
}
}
}
stores, _ := dao.GetStoreList(db, []int{order.FromStoreID}, nil, nil, nil, "")
if len(stores) > 0 {
//如果这周还买过其他物料,则不刷新是否购买标志
var (
orderPays []*model.OrderPay
day int
)
sql := `
SELECT b.*
FROM goods_order a
JOIN order_pay b ON a.vendor_order_id = b.vendor_order_id
WHERE IF(a.store_id = 0, a.jx_store_id, a.store_id) = 666666
AND a.from_store_id = ?
AND a.status >= ? AND a.status <> ?
AND b.status = ?
AND b.pay_finished_at <= NOW() AND b.pay_finished_at >= ?
`
weekInt := int(time.Now().Weekday())
if weekInt == 0 {
day = 7
} else {
day = weekInt
}
lastTime := utils.Str2Time(time.Now().AddDate(0, 0, -(day-1)).Format("2006-01-02") + " 01:00:00")
sqlParams := []interface{}{order.FromStoreID, model.OrderStatusDelivering, model.OrderStatusCanceled, model.PayStatusYes, lastTime}
err = dao.GetRows(db, &orderPays, sql, sqlParams)
if len(orderPays) == 0 {
store := stores[0]
store.IsBoughtMatter = model.NO
dao.UpdateEntity(db, store, "IsBoughtMatter")
}
}
}
return err
}
func MarkArrears(db *dao.DaoDB, order *model.GoodsOrder, orderPay *model.OrderPay) {
//退款后,若此订单下单用户有推广人,则需要将分给推广人的金额记录到该推广人的欠款中
orders, _ := dao.QueryOrders(db, order.VendorOrderID, 0, []int{model.VendorIDJX}, 0, utils.DefaultTimeValue, utils.DefaultTimeValue)
if len(orders) > 0 {
user, _ := dao.GetUserByID(db, "user_id", orders[0].UserID)
if user.ParentMobile != "" {
user2, _ := dao.GetUserByID(db, "mobile", user.ParentMobile)
user2.Arrears = user2.Arrears + (orderPay.TotalFee * user2.DividePercentage / 100)
dao.UpdateEntity(db, user2, "Arrears")
if user2.ParentMobile != "" {
user3, _ := dao.GetUserByID(db, "mobile", user2.ParentMobile)
user3.Arrears = user3.Arrears + ((orderPay.TotalFee - user2.Arrears) * user3.DividePercentage / 100)
dao.UpdateEntity(db, user3, "Arrears")
}
}
}
}
func AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string) (err error) {
if isAgree {
err = CancelOrder(ctx, order, reason)
} else {
err = changeOrderStatus(order.VendorOrderID, model.OrderStatusVendorRejectCancel, reason)
}
return err
}
// todo 消息用异步可能导致丢失,单同步又有重入相关的问题
func callNewOrder(order *model.GoodsOrder) (err error) {
jxutils.CallMsgHandlerAsync(func() {
err = partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order))
}, jxutils.ComposeUniversalOrderID(order.VendorOrderID, model.VendorIDJX))
return err
}
func changeOrderStatus(vendorOrderID string, status int, remark string) (err error) {
orderStatus := &model.OrderStatus{
VendorOrderID: vendorOrderID,
VendorID: model.VendorIDJX,
OrderType: model.OrderTypeOrder,
RefVendorOrderID: vendorOrderID,
RefVendorID: model.VendorIDJX,
VendorStatus: utils.Int2Str(status),
Status: status,
StatusTime: time.Now(),
Remark: remark,
}
jxutils.CallMsgHandlerAsync(func() {
err = partner.CurOrderManager.OnOrderStatusChanged("", orderStatus)
}, jxutils.ComposeUniversalOrderID(vendorOrderID, model.VendorIDJX))
return err
}
func GetOrderPay(ctx *jxcontext.Context, vendorOrderID string) (payList []*model.OrderPay, err error) {
db := dao.GetDB()
payList, err = dao.GetOrderPayList(db, vendorOrderID, jxutils.GetPossibleVendorIDFromVendorOrderID(vendorOrderID))
return payList, err
}
func PayForPopluarMan(ctx *jxcontext.Context, vendorOrderID, userID string, price int) (err error) {
db := dao.GetDB()
user, err := dao.GetUserByID(db, "user_id", userID)
if user == nil {
return fmt.Errorf("未找到此用户用户ID[%v]\n", userID)
}
auth, err := dao.GetUserBindAuthInfo(db, userID, model.AuthBindTypeAuth, []string{"weixinmini"}, "", "", "wx4b5930c13f8b1170")
if len(auth) == 0 {
return fmt.Errorf("未找到此用户的微信验证方式用户ID[%v]\n", userID)
}
goods, err := dao.QueryOrders(db, vendorOrderID, 0, []int{model.VendorIDJX}, 0, utils.ZeroTimeValue, utils.ZeroTimeValue)
if len(goods) == 0 {
return fmt.Errorf("未找到此订单订单ID[%v]\n", vendorOrderID)
}
param := &wxpayapi.TransfersParam{
CheckName: wxpayapi.CheckName,
PartnerTradeNo: vendorOrderID,
Desc: "每日推广人订单分成分到个人",
SpbillCreateIP: ctx.GetRealRemoteIP(),
OpenID: auth[0].AuthID,
Amount: price,
}
_, err = api.WxpayAPI.Transfers(param)
return err
}
//自动打款给市场推广人
func AutoPayForPopluarMan(ctx *jxcontext.Context) (err error) {
var (
errMsg string
errCode string
db = dao.GetDB()
fromDateStr = time.Now().AddDate(0, 0, -1).Format("2006-1-2") + " 00:00:00"
toDateStr = time.Now().AddDate(0, 0, -1).Format("2006-1-2") + " 23:59:59"
mapResult = make(map[string]interface{})
)
result, err := dao.GetOrdersForJxPay(db, utils.Str2Time(fromDateStr), utils.Str2Time(toDateStr))
for _, goods := range result {
var (
param = &wxpayapi.TransfersParam{
CheckName: wxpayapi.CheckName,
Desc: "每日推广人订单分成分到个人",
SpbillCreateIP: ctx.GetRealRemoteIP(),
}
payPrice1 int
payPrice2 int
)
user, err := dao.GetUserByID(db, "user_id", goods.UserID)
if user.ParentMobile == "" {
return err
}
user2, err := dao.GetUserByID(db, "mobile", user.ParentMobile)
auths, err := dao.GetUserBindAuthInfo(db, user2.UserID, model.AuthBindTypeAuth, []string{"weixinmini"}, "", "", "wx4b5930c13f8b1170")
if err != nil {
return err
}
if len(auths) == 0 {
errMsg += fmt.Sprintf("打款失败!未找到此用户的微信验证方式!订单号:[%v]用户ID[%v]\n", goods.VendorOrderID, user2.UserID)
} else {
var openID string
for _, auth := range auths {
if auth.TypeID == wxAppID {
openID = auth.AuthID
}
}
payPrice1 = int(goods.ActualPayPrice) * user2.DividePercentage / 100
//表示这个人之前有欠款,意思是取消订单退款时,这个推广人的分成收不回来,算作欠款,打钱的时候要扣除
//表示这个人之前有小于3毛钱的款没有打微信付款api付款最低3毛记录下来加到以后的款项中
rPrice := payPrice1 - user2.Arrears + user2.Profit
err = updateUserAndTransfers(db, param, user2, openID, rPrice)
if err != nil {
errMsg += err.Error()
}
mapResult["打款人1"] = user2.Name
mapResult["打款人金额1"] = rPrice
mapResult["打款人电话1"] = user2.Mobile
mapResult["打款人1userID"] = user2.UserID
}
if user2.ParentMobile != "" {
user3, err := dao.GetUserByID(db, "mobile", user2.ParentMobile)
auths, err := dao.GetUserBindAuthInfo(db, user3.UserID, model.AuthBindTypeAuth, []string{"weixinmini"}, "", "", "wx4b5930c13f8b1170")
if err != nil {
return err
}
if len(auths) == 0 {
errMsg += fmt.Sprintf("打款失败!未找到此用户的微信验证方式!订单号:[%v]用户ID[%v]\n", goods.VendorOrderID, user3.UserID)
} else {
var openID string
for _, auth := range auths {
if auth.TypeID == wxAppID {
openID = auth.AuthID
}
}
payPrice2 = (int(goods.ActualPayPrice) - payPrice1) * user3.DividePercentage / 100
rPrice := payPrice2 - user3.Arrears + user3.Profit
err = updateUserAndTransfers(db, param, user3, openID, rPrice)
if err != nil {
errMsg += err.Error()
}
mapResult["打款人2"] = user3.Name
mapResult["打款人金额2"] = rPrice
mapResult["打款人电话2"] = user3.Mobile
mapResult["打款人2userID"] = user3.UserID
}
}
}
user, _ := dao.GetUserByID(dao.GetDB(), "mobile", "18160030913")
if user != nil && errMsg != "" {
ddmsg.SendUserMessage(dingdingapi.MsgTyeText, user.UserID, "每日打款错误", errMsg)
}
if err != nil || errMsg != "" {
errMsg += err.Error()
errCode = model.ErrCodeGeneralFailed
} else {
errCode = model.ErrCodeSuccess
}
err = event.AddOperateEvent(ctx, ctx.GetTrackInfo(), cms.BuildDiffData(mapResult), errCode, errMsg, 0, "AutoPayForPopluarMan")
globals.SugarLogger.Debugf("每日订单打款:[%v]", cms.BuildDiffData(mapResult))
return err
}
func updateUserAndTransfers(db *dao.DaoDB, param *wxpayapi.TransfersParam, user *model.User, authID string, rPrice int) (err error) {
if rPrice >= 30 {
param.OpenID = authID
param.Amount = rPrice
param.PartnerTradeNo = utils.GetUUID()
_, err = api.WxpayAPI.Transfers(param)
user.ProfitSum = user.ProfitSum + rPrice
user.Profit = 0
user.Arrears = 0
} else if rPrice >= 0 && rPrice < 30 {
user.Profit = rPrice
user.Arrears = 0
} else {
user.Profit = 0
user.Arrears = int(utils.Float64TwoInt64(math.Abs(utils.Int2Float64(rPrice))))
}
_, err = dao.UpdateEntity(db, user, "ProfitSum", "Profit", "Arrears")
return err
}
func CancelPayTimeOutOrder(ctx *jxcontext.Context) (err error) {
db := dao.GetDB()
var orders []*model.GoodsOrder
sql := `
SELECT *
FROM goods_order
WHERE order_created_at >= ? AND order_created_at <= NOW()
AND status = ?
AND vendor_id = ?
`
sqlParams := []interface{}{
time.Now().Add(-time.Minute * 30),
model.OrderStatusWait4Pay,
model.VendorIDJX,
}
err = dao.GetRows(db, &orders, sql, sqlParams)
for _, v := range orders {
if v.OrderCreatedAt.Add(PayWaitingTime).Before(time.Now()) {
err2 := changeOrderStatus(v.VendorOrderID, model.OrderStatusCanceled, autoCancelOrderReason)
err = err2
}
}
return err
}
func GetHalfHoursList() (strs []string) {
for k := 0; k < 3; k++ {
for i := 0; i < 10; i++ {
for j := 0; j < 4; j += 3 {
if k == 2 && i > 3 {
break
}
strs = append(strs, utils.Int2Str(k)+utils.Int2Str(i)+":"+utils.Int2Str(j)+"0"+":00")
}
}
}
return strs
}
func RefreshAllMatterOrderStatus(ctx *jxcontext.Context) (err error) {
var (
db = dao.GetDB()
goodsList []*model.GoodsOrder
realTime time.Time
)
realTime = time.Now().AddDate(0, 0, -7)
//有分包的主订单
sql := `
SELECT * FROM goods_order WHERE store_id = 666666 AND order_created_at >= ? AND status < ? AND vendor_id = ? AND LENGTH(vendor_order_id) = 14
`
sqlParams := []interface{}{realTime, model.OrderStatusEndBegin, model.VendorIDJX}
err = dao.GetRows(db, &goodsList, sql, sqlParams)
for _, v := range goodsList {
if v.EclpOutID == "" {
var (
goodsList2 []*model.GoodsOrder
cancelCount int
deliveringCount int
)
sql2 := "SELECT * FROM goods_order WHERE vendor_order_id LIKE ? OR vendor_order_id LIKE ? AND vendor_id = ? AND eclp_out_id <> '' AND LENGTH(vendor_order_id) = 16"
sqlParams2 := []interface{}{v.VendorOrderID + "0%", v.VendorOrderID + "1%", model.VendorIDJX}
err = dao.GetRows(db, &goodsList2, sql2, sqlParams2)
for _, vv := range goodsList2 {
if vv.Status < model.OrderStatusFinished {
queryOrderStatus, _ := api.JdEclpAPI.QueryOrderStatus(vv.EclpOutID)
if len(queryOrderStatus.OrderStatusList) > 0 {
if queryOrderStatus.OrderStatusList[len(queryOrderStatus.OrderStatusList)-1].SoStatusCode == jdeclpapi.SoStatusCode10034 {
dao.Begin(db)
defer func() {
if r := recover(); r != nil {
dao.Rollback(db)
panic(r)
}
}()
vv.Status = model.OrderStatusFinished
dao.UpdateEntity(db, vv, "Status")
waybills, err := dao.GetWaybills(db, vv.VendorOrderID)
if err == nil && len(waybills) > 0 {
waybills[0].Status = model.WaybillStatusDelivered
dao.UpdateEntity(db, waybills[0], "Status")
}
dao.Commit(db)
changeOrderStatus(vv.VendorOrderID, model.OrderStatusFinished, "")
getTrackMessagePlusByOrderResult, _ := api.JdEclpAPI.GetTrackMessagePlusByOrder(vv.VendorOrderID)
updateJdWayBillInfo(db, vv, getTrackMessagePlusByOrderResult)
} else {
deliveringCount++
}
}
} else if vv.Status == model.OrderStatusCanceled {
cancelCount++
}
}
dao.Begin(db)
defer func() {
if r := recover(); r != nil {
dao.Rollback(db)
panic(r)
}
}()
if deliveringCount == 0 {
v.Status = model.OrderStatusFinished
} else {
if cancelCount == len(goodsList2) {
v.Status = model.OrderStatusCanceled
}
}
if v.Status < model.OrderStatusDelivering {
v.Status = model.OrderStatusCanceled
}
dao.UpdateEntity(db, v, "Status")
dao.Commit(db)
changeOrderStatus(v.VendorOrderID, v.Status, "")
} else {
queryOrderStatus, _ := api.JdEclpAPI.QueryOrderStatus(v.EclpOutID)
getTrackMessagePlusByOrderResult, _ := api.JdEclpAPI.GetTrackMessagePlusByOrder(v.VendorOrderID)
updateMatterOrderStatus(db, v, queryOrderStatus)
updateJdWayBillInfo(db, v, getTrackMessagePlusByOrderResult)
}
}
return err
}
func GetMatterOrderStatus(ctx *jxcontext.Context, vendorOrderID string) (result []*MatterOrderStatus, err error) {
var (
db = dao.GetDB()
)
order, err := dao.GetSimpleOrder(db, vendorOrderID)
if err != nil {
return nil, err
}
if order.EclpOutID == "" {
return nil, err
}
queryOrderStatus, err := api.JdEclpAPI.QueryOrderStatus(order.EclpOutID)
getTrackMessagePlusByOrderResult, err := api.JdEclpAPI.GetTrackMessagePlusByOrder(vendorOrderID)
if err != nil {
return nil, err
}
for _, v := range queryOrderStatus.OrderStatusList {
matter := &MatterOrderStatus{}
matter.Time = utils.Str2Time(v.OperateTime)
matter.Status = v.SoStatusName
matter.Name = v.SoStatusName
matter.Sign = 1
result = append(result, matter)
}
if len(getTrackMessagePlusByOrderResult.ResultData) > 0 {
for _, vv := range getTrackMessagePlusByOrderResult.ResultData {
matter := &MatterOrderStatus{}
matter.Time = utils.Str2Time(strings.ReplaceAll(vv.OpeTime, "/", "-"))
matter.Status = vv.OpeTitle
matter.Name = vv.OpeRemark
matter.Sign = 2
result = append(result, matter)
}
}
for i := 0; i < len(result)-1; i++ {
for j := 0; j < len(result)-i-1; j++ {
if result[j].Time.Unix() > result[j+1].Time.Unix() || (result[j].Time.Unix() == result[j+1].Time.Unix() && result[j].Sign > result[j+1].Sign) {
tmp := result[j]
result[j] = result[j+1]
result[j+1] = tmp
}
}
}
if len(queryOrderStatus.OrderStatusList) > 0 {
updateMatterOrderStatus(db, order, queryOrderStatus)
}
if len(getTrackMessagePlusByOrderResult.ResultData) > 0 {
updateJdWayBillInfo(db, order, getTrackMessagePlusByOrderResult)
}
return result, err
}
func updateMatterOrderStatus(db *dao.DaoDB, order *model.GoodsOrder, queryOrderStatus *jdeclpapi.QueryOrderStatusResult) {
code := queryOrderStatus.OrderStatusList[len(queryOrderStatus.OrderStatusList)-1].SoStatusCode
if code == jdeclpapi.SoStatusCode10034 || code == jdeclpapi.SoStatusCode10038 {
dao.Begin(db)
defer func() {
if r := recover(); r != nil {
dao.Rollback(db)
panic(r)
}
}()
order.Status = model.OrderStatusFinished
dao.UpdateEntity(db, order, "Status")
waybills, err := dao.GetWaybills(db, order.VendorOrderID)
if err == nil && len(waybills) > 0 {
waybills[0].Status = model.WaybillStatusDelivered
dao.UpdateEntity(db, waybills[0], "Status")
}
dao.Commit(db)
changeOrderStatus(order.VendorOrderID, model.OrderStatusFinished, "")
}
}
func updateJdWayBillInfo(db *dao.DaoDB, order *model.GoodsOrder, getTrackMessagePlusByOrderResult *jdeclpapi.GetTrackMessagePlusByOrderResult) (err error) {
var (
waybillCode string
cName string
cMobile string
waybills []*model.Waybill
)
if len(getTrackMessagePlusByOrderResult.ResultData) > 0 {
waybillCode = getTrackMessagePlusByOrderResult.ResultData[0].WaybillCode
} else {
return err
}
for _, vv := range getTrackMessagePlusByOrderResult.ResultData {
if vv.OpeTitle == "配送员收货" {
result := regexpCnameAndCmobile.FindAllStringSubmatch(vv.OpeRemark, -1)
if len(result) > 0 {
cName = result[0][1]
cMobile = result[0][2]
} else {
result2 := regexpCnameAndCmobile2.FindAllStringSubmatch(vv.OpeRemark, -1)
if len(result2) > 0 {
cName = result2[0][1]
cMobile = result2[0][2]
}
}
break
}
}
waybills, err = dao.GetWaybills(db, order.VendorOrderID)
if len(waybills) > 0 {
waybills[0].VendorWaybillID = waybillCode
waybills[0].CourierName = cName
waybills[0].CourierMobile = cMobile
order.VendorWaybillID = waybillCode
order.WaybillVendorID = model.VendorIDJDWL
dao.UpdateEntity(db, order, "VendorWaybillID", "WaybillVendorID")
dao.UpdateEntity(db, waybills[0], "VendorWaybillID", "CourierName", "CourierMobile")
}
return err
}
func tryToSplitMatterOrder(jxOrder *JxOrderInfo) (outOrders []*JxOrderInfo, freightPrice int64, err error) {
var (
skus = jxOrder.Skus
weightList []*JxSkuInfo2
)
//我的思路为把所有商品依次按重量销量从大到小排列然后第一个包尽量分出3kg后面分出4.5kg
//但是我把JxSkuInfo放进list的时候想根据一个参数GroupSign判断是否这个商品已经分出去了
//但是在list中同一个商品通过以下方式放进去的地址是一样的我改了一个商品的GroupSign所有的都变了所以只有分出一个JxSkuInfo2去弄。。
//要做优化的话更好
for _, v := range skus {
for i := 0; i < v.Count; i++ {
var sku2 = &JxSkuInfo2{}
sku2.Count = v.Count
sku2.Name = v.Name
sku2.Price = v.Price
sku2.SalePrice = v.SalePrice
sku2.Weight = v.Weight
sku2.SkuID = v.SkuID
weightList = append(weightList, sku2)
}
}
for i := 0; i < len(weightList)-1; i++ {
for j := 0; j < len(weightList)-i-1; j++ {
if weightList[j].Weight < weightList[j+1].Weight {
tmp := weightList[j]
weightList[j] = weightList[j+1]
weightList[j+1] = tmp
}
}
}
weight := jxOrder.Weight
for {
//每拿出一组就删掉list里的值
outOrders = append(outOrders, loop2(weightList, jxOrder.StoreID, &weight))
for i := 0; i < len(weightList); {
if weightList[i].GroupSign {
var weightList3 []*JxSkuInfo2
weightList3 = append(weightList[:i], weightList[i+1:]...)
weightList = weightList3
} else {
i++
}
}
if len(weightList) == 0 {
break
}
}
for _, v := range outOrders {
if v.Weight <= 3000 {
freightPrice += 500
} else if v.Weight > 3000 && v.Weight <= splitMatterOrderMinWeight {
freightPrice += utils.Float64TwoInt64(500 + math.Ceil((utils.Int2Float64(v.Weight)-3000)/1000)*200)
}
}
return outOrders, freightPrice, err
}
func jxOrderChange(sku2 *JxSkuInfo2) *JxSkuInfo {
sku := &JxSkuInfo{}
sku.Count = 1
sku.Name = sku2.Name
sku.Price = sku2.Price
sku.SalePrice = sku2.SalePrice
sku.SkuID = sku2.SkuID
sku.Weight = sku2.Weight
return sku
}
//TODO 修改为4.5kg 2020-04-2?
//商品分包规则2。最后一个包不超过5kg,其他包不超过3kg
// 举例15.1kg,分为 2.5kg,2.6kg,确保每个包不超过3kg,最后一个包不超过5kg
// 举例24kg,分为4kg
// 举例310kg分为 3kg,3kg,4kg
// 举例48.1kg,分为 3kg,3kg,2.1kg ; 不能分为3kg,5.1kg
//sum3表示3kg的计算
func loop2(weightList []*JxSkuInfo2, storeID int, weight *int) (outOrder *JxOrderInfo) {
outOrder = &JxOrderInfo{}
outOrder.StoreID = storeID
sum3 := 0
if *weight <= splitMatterOrderMinWeight {
for i := 0; i < len(weightList); i++ {
buildOutOrderSkus(weightList[i], outOrder)
}
} else {
for i := 0; i < len(weightList); i++ {
if weightList[i].Weight+sum3 <= 3000 {
sum3 += weightList[i].Weight
*weight -= weightList[i].Weight
buildOutOrderSkus(weightList[i], outOrder)
} else {
if sum3 >= 3000 {
break
}
continue
}
}
}
return outOrder
}
func buildOutOrderSkus(weightp *JxSkuInfo2, outOrder *JxOrderInfo) {
weightp.GroupSign = true
outOrder.Weight += weightp.Weight
if len(outOrder.Skus) > 0 {
var flag = false
for _, v := range outOrder.Skus {
if v.SkuID == weightp.SkuID {
v.Count++
flag = true
}
}
if !flag {
outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightp))
}
} else {
outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightp))
}
}
func checkMatterDeliveryAddress(deliveryAddress *dao.UserDeliveryAddressEx) {
var (
db = dao.GetDB()
)
if !strings.Contains(deliveryAddress.Address, "区") {
deliveryAddress.Address = deliveryAddress.DistrictName + deliveryAddress.Address
}
if !strings.Contains(deliveryAddress.Address, "市") {
deliveryAddress.Address = deliveryAddress.CityName + deliveryAddress.Address
}
if !strings.Contains(deliveryAddress.Address, "省") {
if place1, err := dao.GetPlaceByCode(db, deliveryAddress.CityCode); err == nil {
if place2, err2 := dao.GetPlaceByCode(db, place1.ParentCode); err2 == nil {
deliveryAddress.Address = place2.Name + deliveryAddress.Address
}
}
}
}
func SendFailedMatterOrder(ctx *jxcontext.Context, vendorOrderID string) (err error) {
var (
db = dao.GetDB()
)
order, err := partner.CurOrderManager.LoadOrder(vendorOrderID, model.VendorIDJX)
if err != nil {
return err
}
if order == nil || order.StoreID != model.MatterStoreID || order.FromStoreID == 0 {
return fmt.Errorf("只允许物料店重发物料订单调用此接口!")
}
queryOrderStatus, err := api.JdEclpAPI.QueryOrderStatus(order.EclpOutID)
if len(queryOrderStatus.OrderStatusList) > 0 {
code := queryOrderStatus.OrderStatusList[len(queryOrderStatus.OrderStatusList)-1].SoStatusCode
if code == jdeclpapi.SoStatusCode10022 || code == jdeclpapi.SoStatusCode10038 { //表示该订单在京东物流为暂停或已经逆向发货完成
if len(order.VendorOrderID) == 14 && order.EclpOutID != "" { //这是不分包的订单
_, err = createMatterOrder(buildJxOrderInfo(order, order.Skus), order, int64(00))
err = CancelMatterOrder(db, order, cancelMatterOrderReason)
changeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, cancelMatterOrderReason)
for _, v := range order.Skus {
cms.RefreshMatterStock(jxcontext.AdminCtx, v.SkuID)
}
} else if len(order.VendorOrderID) == 14 && order.EclpOutID == "" { //这是分包的主订单
goodsList, err := dao.GetMatterChildOrders(db, order.VendorOrderID)
if err != nil {
return err
}
if len(goodsList) > 0 {
for _, v := range goodsList {
cOrder, err := partner.CurOrderManager.LoadOrder(v.VendorOrderID, model.VendorIDJX)
if err != nil {
return err
}
suffix := utils.Str2Int64(cOrder.VendorOrderID[len(cOrder.VendorOrderID)-2:]) + int64(len(goodsList))
_, err = createMatterOrder(buildJxOrderInfo(cOrder, cOrder.Skus), cOrder, suffix)
for _, v := range cOrder.Skus {
cms.RefreshMatterStock(jxcontext.AdminCtx, v.SkuID)
}
}
}
err = CancelMatterOrder(db, order, cancelMatterOrderReason)
changeOrderStatus(order.VendorOrderID, model.OrderStatusCanceled, cancelMatterOrderReason)
} else if len(order.VendorOrderID) == 16 && order.EclpOutID != "" { // 这是分包的子订单
return fmt.Errorf("请重发主订单!主订单号:[%v]", order.VendorOrderID[len(order.VendorOrderID)-2:])
}
} else {
return fmt.Errorf("只允许物流订单为暂停或逆向完成才能调用此接口!")
}
}
return err
}
func createMatterOrder(jxOrder *JxOrderInfo, order *model.GoodsOrder, newOrderIDSuffix int64) (order2 *model.GoodsOrder, err error) {
outJxOrder, deliveryAddress, err := generateOrder(jxcontext.AdminCtx, jxOrder, order.AddressID, order.FromStoreID, order.UserID, false)
if err != nil {
return nil, err
}
outJxOrder.OrderID = utils.Str2Int64(order.VendorOrderID)*100 + newOrderIDSuffix
checkMatterDeliveryAddress(deliveryAddress)
order2, err2 := jxOrder2GoodsOrder(jxcontext.AdminCtx, outJxOrder, deliveryAddress, order.UserID, false)
if err = err2; err == nil {
order2.AddressID = order.AddressID
order2.Status = model.OrderStatusDelivering
err = partner.CurOrderManager.OnOrderNew(order2, model.Order2Status(order2))
err = orderSolutionForWuLiao(order2)
}
return order2, err
}
func buildJxOrderInfo(order *model.GoodsOrder, orderSkus []*model.OrderSku) (jxOrder *JxOrderInfo) {
jxOrder = &JxOrderInfo{}
jxOrder.StoreID = order.StoreID
weight := 0
var skus []*JxSkuInfo
for _, v := range orderSkus {
weight += v.Weight * v.Count
sku := &JxSkuInfo{}
sku.SkuID = v.SkuID
sku.SalePrice = v.SalePrice
sku.Name = v.SkuName
sku.Weight = v.Weight
sku.Count = v.Count
skus = append(skus, sku)
}
jxOrder.Skus = skus
jxOrder.Weight = weight
return jxOrder
}