diff --git a/business/jxcallback/orderman/financial.go b/business/jxcallback/orderman/financial.go index e7e915a86..c9b9a3b61 100644 --- a/business/jxcallback/orderman/financial.go +++ b/business/jxcallback/orderman/financial.go @@ -258,3 +258,5 @@ func (c *OrderManager) UpdataOrderFinancialInfo(orderFinancial *model.OrderFinan // orderFinancial 和 OrderSkuFinancial 数据计算完毕,准备进行更新 return err } + + diff --git a/business/jxcallback/orderman/order.go b/business/jxcallback/orderman/order.go index 25e67d2fc..f6f45e484 100644 --- a/business/jxcallback/orderman/order.go +++ b/business/jxcallback/orderman/order.go @@ -383,7 +383,10 @@ func ModifyOrderSkusStock(db *dao.DaoDB, order *model.GoodsOrder, isAdd bool) (e dao.SetStoreSkuSyncStatus(db, order.VendorID, []int{order.FromStoreID}, []int{sku.SkuID}, model.SyncFlagStockMask) } } - checkDefendPriceOrder(db, jxutils.GetSaleStoreIDFromOrder(order), sku.SkuID) + realStock := checkPriceDefendOrderByStock(db, jxutils.GetSaleStoreIDFromOrder(order), sku.SkuID, stock, storeSku.JxPrice) + if realStock != -1 { + stock = realStock + } } storeSku.Stock = stock dao.UpdateEntity(db, storeSku, "Stock") @@ -400,15 +403,44 @@ func filterOrderInfo(order *model.GoodsOrder) { order.ConsigneeAddress = strings.ReplaceAll(order.ConsigneeAddress, "·", "") } -func checkDefendPriceOrder(db *dao.DaoDB, storeID, skuID int) { +func checkPriceDefendOrderByStock(db *dao.DaoDB, storeID, skuID, stock, jxPrice int) (realStock int) { var ( - issue = 0 + sumStock = 0 ) - if time.Now().Hour() >= 22 { - issue = utils.Str2Int(time.Now().AddDate(0, 0, 1).Format("20060102")) - } else { - issue = utils.Str2Int(time.Now().Format("20060102")) + priceDefends, _ := dao.GetPriceDefendOrder(db, []int{storeID}, []int{skuID}, []int{jxutils.GetDefendPriceIssue()}, 0, 1, 0) + if len(priceDefends) == 0 { + return -1 } + for _, v := range priceDefends { + sumStock += v.Count + } + //如果现库存小于等于用户守价的库存,就要开始了 + //如果小于,要按照守价时间的先后来决定 + //如果等于,就刚好全部成功,然后库存清0 + if stock < sumStock { + tStock := stock + for _, v := range priceDefends { + if tStock <= v.Count { + tStock -= v.Count + v.IsSuccess = model.YES + v.RealPrice = int64(jxPrice) + dao.UpdateEntity(db, v, "IsSuccess", "RealPrice") + } else { + continue + } + } + realStock = tStock + } else if stock == sumStock { + for _, v := range priceDefends { + v.IsSuccess = model.YES + v.RealPrice = int64(jxPrice) + dao.UpdateEntity(db, v, "IsSuccess", "RealPrice") + } + realStock = 0 //库存清0 + } else { + realStock = -1 + } + return realStock } func (c *OrderManager) updateOrderSkuOtherInfo(order *model.GoodsOrder, db *dao.DaoDB, storePayPercentage, changePriceType int) (err error) { diff --git a/business/jxstore/act/act.go b/business/jxstore/act/act.go index d2a2f64df..84fc01e53 100644 --- a/business/jxstore/act/act.go +++ b/business/jxstore/act/act.go @@ -1557,6 +1557,7 @@ func ChangeJxPriceByDiscountAct(ctx *jxcontext.Context) { storeSku.JxPrice = storeSku.JxPrice + int(actualPrice) } else if actStoreSku.TrendType == model.TrendTypeDown { storeSku.JxPrice = storeSku.JxPrice - int(actualPrice) + storeSku.Stock = checkPriceDefendOrderByPrice(db, storeSku.StoreID, storeSku.SkuID, storeSku.Stock, storeSku.JxPrice) } if storeSku.JxPrice >= int(actStoreSku.OriginalPrice) { storeSku.JxPrice = int(actStoreSku.OriginalPrice) @@ -1570,7 +1571,7 @@ func ChangeJxPriceByDiscountAct(ctx *jxcontext.Context) { if storeSku.JxPrice <= int(minJxPrice) { storeSku.JxPrice = int(minJxPrice) } - if _, err = dao.UpdateEntity(db, storeSku, "JxPrice"); err != nil { + if _, err = dao.UpdateEntity(db, storeSku, "JxPrice", "Stock"); err != nil { dao.Rollback(db) } //C >= 2N 涨价趋势,最高涨价到无折扣 @@ -1615,3 +1616,26 @@ func ChangeJxPriceByDiscountAct(ctx *jxcontext.Context) { } } } + +func checkPriceDefendOrderByPrice(db *dao.DaoDB, storeID, skuID, stock, jxPrice int) (realStock int) { + priceDefends, _ := dao.GetPriceDefendOrder(db, []int{storeID}, []int{skuID}, []int{jxutils.GetDefendPriceIssue()}, 0, 0, 0) + if len(priceDefends) == 0 { + return + } + for _, v := range priceDefends { + //如果刚好守的价和降的价一样,再判断库存够不够 + if v.DefendPrice <= int64(jxPrice) { + if v.Count <= stock { + stock -= v.Count + v.IsSuccess = model.YES + v.RealPrice = int64(jxPrice) + dao.UpdateEntity(db, v, "IsSuccess", "RealPrice") + } else { + continue + } + } else { + continue + } + } + return stock +} diff --git a/business/jxstore/misc/misc.go b/business/jxstore/misc/misc.go index 4aa61d2ec..41bf96f54 100644 --- a/business/jxstore/misc/misc.go +++ b/business/jxstore/misc/misc.go @@ -268,6 +268,12 @@ func Init() { act.ChangeJxPriceByDiscountAct(jxcontext.AdminCtx) }, discountActJxList) + ScheduleTimerFunc("CreateOrderByPriceDefend", func() { + localjx.CreateOrderByPriceDefend(jxcontext.AdminCtx) + }, []string{ + "22:00:00", + }) + if beego.BConfig.RunMode == "jxgy" { ScheduleTimerFunc("SyncMatterC4ToGy", func() { cms.SyncMatterC4ToGy(jxcontext.AdminCtx, true, true) diff --git a/business/jxutils/jxutils.go b/business/jxutils/jxutils.go index c7288df87..86f23f26e 100644 --- a/business/jxutils/jxutils.go +++ b/business/jxutils/jxutils.go @@ -961,3 +961,12 @@ func MixWatermarkImg(imgWatermark, img string, exPrefixBegin, exPrefixEnd *time. } return imgMix } + +func GetDefendPriceIssue() (issue int) { + if time.Now().Hour() >= 22 { + issue = utils.Str2Int(time.Now().AddDate(0, 0, 1).Format("20060102")) + } else { + issue = utils.Str2Int(time.Now().Format("20060102")) + } + return issue +} diff --git a/business/model/dao/dao_order.go b/business/model/dao/dao_order.go index 90b7f8aa1..a0989fe48 100644 --- a/business/model/dao/dao_order.go +++ b/business/model/dao/dao_order.go @@ -1397,7 +1397,7 @@ func GetSupplySupportStoreSkus(db *DaoDB, fromDate, toDate time.Time, fromStoreI return orderSkus, err } -func GetPriceDefendOrder(db *DaoDB, storeIDs, skuIDs, issues []int) (priceDefendOrders []*model.PriceDefendOrder, err error) { +func GetPriceDefendOrder(db *DaoDB, storeIDs, skuIDs, issues []int, defendPrice, isBuyNowPrice, isSuccess int) (priceDefendOrders []*model.PriceDefendOrder, err error) { sql := ` SELECT * FROM price_defend_order @@ -1416,6 +1416,19 @@ func GetPriceDefendOrder(db *DaoDB, storeIDs, skuIDs, issues []int) (priceDefend sql += " AND issue IN (" + GenQuestionMarks(len(issues)) + ")" sqlParams = append(sqlParams, issues) } + if defendPrice != 0 { + sql += " AND defend_price = ?" + sqlParams = append(sqlParams, defendPrice) + } + if isBuyNowPrice != -1 { + sql += " AND is_buy_now_price = ?" + sqlParams = append(sqlParams, isBuyNowPrice) + } + if isSuccess != -1 { + sql += " AND is_success = ?" + sqlParams = append(sqlParams, isSuccess) + } + sql += " ORDER BY created_at" err = GetRows(db, &priceDefendOrders, sql, sqlParams) return priceDefendOrders, err } diff --git a/business/model/order.go b/business/model/order.go index f1a579df5..d51a93d83 100644 --- a/business/model/order.go +++ b/business/model/order.go @@ -28,7 +28,7 @@ const ( const ( OrderTypeNormal = 0 //普通订单 - OrderTypeMatter = 0 //物料订单 + OrderTypeMatter = 1 //物料订单 OrderTypeSupplyGoods = 2 //进货订单 OrderTypeDefendPrice = 3 //守价订单 ) @@ -392,6 +392,7 @@ type PriceDefendOrder struct { Count int `json:"count"` DefendPrice int64 `json:"defendPrice"` //守的价格 ActualPayPrice int64 `json:"actualPayPrice"` //单位为分 顾客实际支付 + RealPrice int64 `json:"realPrice"` //实际成交价 IsBuyNowPrice int `json:"isBuyNowPrice"` //库存剩x(x=当前客户购买的数量)时以当时价抢购 Issue int `json:"issue"` //期数,每晚22:00以后的守价单是归在第二天的期数中 IsSuccess int `json:"isSuccess"` //是否抢购成功 diff --git a/business/partner/purchase/jx/localjx/order.go b/business/partner/purchase/jx/localjx/order.go index 61a880098..22e63c69d 100644 --- a/business/partner/purchase/jx/localjx/order.go +++ b/business/partner/purchase/jx/localjx/order.go @@ -46,8 +46,9 @@ const ( wxAppID = "wx4b5930c13f8b1170" - autoCancelOrderReason = "支付超时,系统自动取消!" - cancelMatterOrderReason = "失败重发!" + autoCancelOrderReason = "支付超时,系统自动取消!" + cancelMatterOrderReason = "失败重发!" + settleDiscountActRefundReason = "守价订单生成补退款" splitMatterOrderMinWeight = 4500 //物料订单分包最少要4.5kg jxwxfMatterEclpID = "EMG4418113943423" //京西五香粉物料编码 @@ -113,6 +114,7 @@ type JxOrderInfo struct { EarningType int `json:"earningType"` OrderType int `json:"orderType"` IsBuyNowPrice int `json:"isBuyNowPrice"` + IsPriceDefend int `json:"isPriceDefend"` } type DeliveryTimeItem struct { @@ -242,11 +244,19 @@ func CreateOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, addressID int64, if outJxOrder.TotalPrice != jxOrder.TotalPrice { return nil, fmt.Errorf("商品或配送信息发生改变,请重新下单") } - outJxOrder.OrderID = GenOrderNo(ctx) + if jxOrder.IsPriceDefend == model.YES { + outJxOrder.OrderID = jxOrder.OrderID + } else { + outJxOrder.OrderID = GenOrderNo(ctx) + } order, err2 := jxOrder2GoodsOrder(ctx, outJxOrder, deliveryAddress, "", IsDeliverySelf) if err = err2; err == nil { order.AddressID = addressID - order.Status = model.OrderStatusWait4Pay + if jxOrder.IsPriceDefend == model.YES { + order.Status = model.OrderStatusNew + } else { + order.Status = model.OrderStatusWait4Pay + } callNewOrder(order) } } @@ -258,12 +268,7 @@ func buildDefendPriceOrder(ctx *jxcontext.Context, jxOrder *JxOrderInfo, address issue = 0 db = dao.GetDB() ) - //属于下一期 - if time.Now().Hour() >= 22 { - issue = utils.Str2Int(time.Now().AddDate(0, 0, 1).Format("20060102")) - } else { - issue = utils.Str2Int(time.Now().Format("20060102")) - } + issue = jxutils.GetDefendPriceIssue() priceDefendOrder := &model.PriceDefendOrder{ VendorOrderID: utils.Int64ToStr(GenOrderNo(ctx)), StoreID: jxOrder.StoreID, @@ -406,12 +411,12 @@ func OnPayFinished(orderPay *model.OrderPay) (err error) { order.StatusTime = *orderPay.PayFinishedAt err = callNewOrder(order) //如果是物料的订单,直接到拣货完成,配送中的状态 - // if order.OrderType != model.OrderTypeNormal { - if order.FromStoreID != 0 { + if order.OrderType != model.OrderTypeNormal { + // if order.FromStoreID != 0 { netprinter.PrintOrderByOrder(jxcontext.AdminCtx, order) PickupGoods(order, false, "jxadmin") + // } } - // } } return err } @@ -920,7 +925,9 @@ func PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) err = changeOrderStatus(order.VendorOrderID, model.OrderStatusFinishedPickup, "") //如果是物料订单则直接进行京东物流的发单,并且状态直接变为配送中 //如果是进货的订单,直接变为配送中 - err = orderSolutionForWuLiao(order) + if order.OrderType != model.OrderTypeNormal { + err = orderSolutionForWuLiao(order) + } return err } @@ -1854,3 +1861,52 @@ func GetSupplySupportStoreSkus(ctx *jxcontext.Context, fromDate, toDate string, orderSkus, err = dao.GetSupplySupportStoreSkus(db, utils.Str2Time(fromDate), utils.Str2Time(toDate), fromStoreID, storeID, utils.Str2Float64(percentage)) return orderSkus, err } + +func CreateOrderByPriceDefend(ctx *jxcontext.Context) { + var ( + db = dao.GetDB() + ) + priceDefends, _ := dao.GetPriceDefendOrder(db, nil, nil, []int{jxutils.GetDefendPriceIssue()}, 0, -1, 1) + if len(priceDefends) == 0 { + return + } + for _, v := range priceDefends { + jxOrder := &JxOrderInfo{ + BuyerComment: "守价订单", + StoreID: v.StoreID, + Skus: []*JxSkuInfo{ + &JxSkuInfo{ + SkuID: v.SkuID, + Count: v.Count, + }, + }, + IsPriceDefend: model.YES, + OrderID: utils.Str2Int64(v.VendorOrderID), + } + if _, err := CreateOrder(ctx, jxOrder, v.AddressID, OrderCreateTypeNormal, 0, false); err == nil { + err = SettleDiscountActByPriceDefend(ctx, v) + } + } +} + +//结算因京西折扣活动而参与守价的订单 +func SettleDiscountActByPriceDefend(ctx *jxcontext.Context, order *model.PriceDefendOrder) (err error) { + var ( + 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 := order.VendorOrderID + if orderPay.PayType == model.PayTypeTL { + _, err = RefundOrderByTL(ctx, orderPay, refundID, int(order.ActualPayPrice-order.RealPrice), settleDiscountActRefundReason) + } + } else { + orderPay.Status = model.PayStatusCanceled + _, err = dao.UpdateEntity(db, orderPay) + } + } + } + return err +}