package orderman import ( "encoding/json" "fmt" "math" "strconv" "strings" "time" "git.rosy.net.cn/jx-callback/business/jxstore/permission" beego "github.com/astaxie/beego/server/web" "git.rosy.net.cn/jx-callback/business/jxutils/tasksch" "git.rosy.net.cn/baseapi/platformapi/jdapi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/business/jxutils/excel" "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/globals" "git.rosy.net.cn/jx-callback/globals/api/apimanager" ) const ( maxLastHours = 7 * 24 // 最多只能查询7天内的订单数据 defLastHours = 2 * 24 // 缺省是两天内的订单 orderSubTimeImmediatelyArrive = 8 orderSubTimeDelayArrive = 5 ) type tWaybillExt struct { model.Waybill StoreName string `json:"storeName"` StoreID int `json:"storeID" orm:"column(store_id)"` } type StoresOrderSaleInfo struct { StoreID int `orm:"column(store_id)" json:"storeID"` VendorID int `orm:"column(vendor_id)" json:"vendorID"` Status int `json:"status"` Count int `json:"count"` ShopPrice int64 `json:"shopPrice"` VendorPrice int64 `json:"vendorPrice"` SalePrice int64 `json:"salePrice"` ActualPayPrice int64 `json:"actualPayPrice"` EarningPrice int64 `json:"earningPrice"` // 预估结算给门店老板的钱 } type OrderSkusAccept struct { model.SkuAndName SumWeight int `json:"sumWeight"` SumCount int `json:"sumCount"` Img string `json:"img"` } type OrderCount struct { Count int `json:"count"` //销量 Flag bool `json:"flag"` //true表示可以买 } func (c *OrderManager) GetStoreOrderCountInfo(ctx *jxcontext.Context, storeID, lastHours, lastMinutes int, isIncludeFake bool) (countInfo []*model.GoodsOrderCountInfo, err error) { globals.SugarLogger.Debugf("GetStoreOrderCountInfo storeID:%d", storeID) if lastHours > maxLastHours { lastHours = maxLastHours } else if lastHours == 0 && lastMinutes == 0 { lastHours = defLastHours } //权限 if permission.IsRoled(ctx) { if storeIDsMap, err := permission.GetUserStoresResultMap(ctx.GetUserID()); err == nil { if storeIDsMap[storeID] == 0 { storeID = -1 } } } db := dao.GetDB() sql := ` SELECT t1.lock_status, t1.status, COUNT(*) count FROM goods_order t1 WHERE t1.vendor_id <> 2 AND IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) = ? AND t1.order_created_at >= ?` sqlParams := []interface{}{ storeID, // time.Now().Add(-time.Duration(lastHours) * time.Hour), } if lastMinutes != 0 { sqlParams = append(sqlParams, time.Now().Add(-time.Duration(lastMinutes)*time.Minute)) } else { sqlParams = append(sqlParams, time.Now().Add(-time.Duration(lastHours)*time.Hour)) } if !isIncludeFake { sql += " AND (t1.flag & ?) = 0" sqlParams = append(sqlParams, model.OrderFlagMaskFake) } sql += ` GROUP BY 1,2 ORDER BY 1,2` err = dao.GetRows(db, &countInfo, sql, sqlParams...) if err == nil { return countInfo, nil } globals.SugarLogger.Infof("GetStoreOrderCountInfo storeID:%d failed with error:%v", storeID, err) return nil, err } func (c *OrderManager) GetOrderSkuInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int) (skus []*model.OrderSkuExt, err error) { globals.SugarLogger.Debugf("GetOrderSkuInfo orderID:%s", vendorOrderID) fullSkuNameSQL := "t1.sku_name" if vendorID == model.VendorIDJD { fullSkuNameSQL = "CONCAT(t1.sku_name, IF(t3.is_spu = 1 AND LOCATE(';', t1.sku_name) = 0, CONCAT('[约', t2.spec_quality, t2.spec_unit, '/', t3.unit, ']'), ''))" } // IF(t1.shop_price = 0, t1.sale_price, t1.shop_price) shop_price, sql := fmt.Sprintf(` SELECT t1.id, t1.vendor_order_id, t1.vendor_id, t1.count, t1.vendor_sku_id, t1.sku_id, t1.jx_sku_id, t1.sku_name, t1.sale_price, t1.shop_price, CAST(IF(t1.earning_price <> 0, t1.earning_price, IF(t1.shop_price <> 0 && t1.shop_price < t1.sale_price, t1.shop_price, t1.sale_price) * IF(t5.pay_percentage > 0, t5.pay_percentage, ?) / 100) AS SIGNED) earning_price, t1.weight, t1.sku_type, t1.promotion_type, t1.order_created_at, t1.store_sub_id, t1.store_sub_name, t1.vendor_price, %s full_sku_name, t2.name_id, t3.img image FROM order_sku t1 LEFT JOIN goods_order t6 ON t6.vendor_order_id = t1.vendor_order_id AND t6.vendor_id = t1.vendor_id LEFT JOIN store t5 ON t5.id = IF(t6.jx_store_id <> 0, t6.jx_store_id, t6.store_id) LEFT JOIN sku t2 ON IF(t1.jx_sku_id != 0, t1.jx_sku_id, t1.sku_id) = t2.id/* AND t2.deleted_at = ?*/ LEFT JOIN sku_name t3 ON t2.name_id = t3.id/* AND t3.deleted_at = ?*/ WHERE t1.vendor_order_id = ? AND t1.vendor_id = ? ORDER BY t1.sku_name `, fullSkuNameSQL) err = dao.GetRows(dao.GetDB(), &skus, sql /*, utils.DefaultTimeValue, utils.DefaultTimeValue*/, model.DefaultEarningPricePercentage, vendorOrderID, vendorID) if err != nil { globals.SugarLogger.Infof("GetOrderSkuInfo orderID:%s vendorID:%d failed with error:%v", vendorOrderID, vendorID, err) return nil, err } if len(skus) == 0 { return nil, ErrCanNotFindOrder } return skus, nil } func (c *OrderManager) GetOrderInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isRefresh bool) (order *model.GoodsOrderExt, err error) { globals.SugarLogger.Debugf("GetOrderInfo orderID:%s", vendorOrderID) db := dao.GetDB() orders := []*model.GoodsOrderExt{} rorder, _ := dao.GetSimpleOrder(db, vendorOrderID) sqlParams := []interface{}{} // 这里用QueryRows而不用QueryRow的原因是用QueryRow在这种情况下不能将数据读出,很奇怪。大概的原因是QueryRow对于GoodsOrderExt这种有嵌入的struct处理有问题 sql := ` SELECT ` if rorder.VendorUserID != "" { sql += ` t3.*,ROUND(t3.shop_sum_price/t3.count) avg_price, ` } sql += ` t1.*, t2.status waybill_status, t2.courier_name, t2.courier_mobile, t2.desired_fee, CAST(t1.consignee_lng AS DECIMAL(15,6))/1000000 float_lng, CAST(t1.consignee_lat AS DECIMAL(15,6))/1000000 float_lat FROM goods_order t1 LEFT JOIN waybill t2 ON t1.vendor_waybill_id = t2.vendor_waybill_id AND t1.waybill_vendor_id = t2.waybill_vendor_id ` if rorder.VendorUserID != "" { sql += ` JOIN ( SELECT count(a.vendor_order_id) count,SUM(a.shop_price) - IFNULL(SUM(c.sku_user_money+c.freight_user_money+c.afs_freight_money+c.box_money+c.tongcheng_freight_money+c.sku_box_money),0) shop_sum_price,a.vendor_user_id,count(d.score < 3 or NULL) bad_comment_count FROM goods_order a LEFT JOIN afs_order c ON a.vendor_order_id = c.vendor_order_id AND c.vendor_id = a.vendor_id LEFT JOIN jx_bad_comments d ON d.order_id = a.vendor_order_id AND d.order_flag = a.vendor_id WHERE a.vendor_user_id = (SELECT vendor_user_id FROM goods_order WHERE vendor_order_id = ?) GROUP BY a.vendor_user_id )t3 ON t3.vendor_user_id = t1.vendor_user_id ` sqlParams = append(sqlParams, vendorOrderID) } sql += ` WHERE t1.vendor_order_id = ? AND vendor_id = ? ` sqlParams = append(sqlParams, vendorOrderID, vendorID) err = dao.GetRows(db, &orders, sql, sqlParams) if err == nil { order = orders[0] if isRefresh && vendorID == model.VendorIDJD { tmpOrder, err2 := partner.GetPurchaseOrderHandlerFromVendorID(vendorID).GetOrder(order.VendorOrgCode, vendorOrderID, order.VendorStoreID) if err = err2; err == nil { order.CurrentConsigneeMobile = tmpOrder.ConsigneeMobile } else { order.CurrentConsigneeMobile = "Error" globals.SugarLogger.Infof("GetOrderInfo GetOrder failed with error:%v", err2) } } return order, nil } if err == nil { err = ErrCanNotFindOrder } globals.SugarLogger.Infof("GetOrderInfo orderID:%s failed with error:%v", vendorOrderID, err) return nil, err } func (c *OrderManager) GetOrderWaybillInfo(ctx *jxcontext.Context, vendorOrderID string, vendorID int, isNotEnded, isGetPos bool) (bills []*model.WaybillExt, err error) { globals.SugarLogger.Debugf("GetOrderWaybillInfo orderID:%s", vendorOrderID) db := dao.GetDB() sql := ` SELECT t1.* FROM waybill t1 WHERE t1.vendor_order_id = ? AND order_vendor_id = ? ` sqlParams := []interface{}{ vendorOrderID, vendorID, } if isNotEnded { sql += " AND t1.status < ?" sqlParams = append(sqlParams, model.OrderStatusEndBegin) } err = dao.GetRows(db, &bills, sql, sqlParams...) if err == nil && isGetPos { var taskBills []*model.WaybillExt for _, v := range bills { if true /*v.Status >= model.WaybillStatusAccepted && v.Status <= model.WaybillStatusDelivering*/ { if handler := partner.GetRidderPositionGetter(v.WaybillVendorID); handler != nil { taskBills = append(taskBills, v) } } } if len(taskBills) > 0 { task := tasksch.NewParallelTask("GetOrderWaybillInfo", nil, ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { waybill := batchItemList[0].(*model.WaybillExt) waybill.Lng, waybill.Lat, err = partner.GetRidderPositionGetter(waybill.WaybillVendorID).GetRidderPosition(ctx, waybill.VendorOrderID, waybill.VendorOrderID, waybill.VendorWaybillID, waybill.VendorWaybillID2) return nil, err }, taskBills) tasksch.HandleTask(task, nil, false).Run() task.GetResult(0) } } return bills, err } func (c *OrderManager) ExportMTWaybills(ctx *jxcontext.Context, fromDateStr, toDateStr string) (excelContent []byte, err error) { globals.SugarLogger.Debugf("ExportMTWaybills from:%s to:%s", fromDateStr, toDateStr) fromDate, err := utils.TryStr2Time(fromDateStr) if err != nil { return nil, err } if toDateStr == "" { toDateStr = fromDateStr } toDate, err := utils.TryStr2Time(toDateStr) if err != nil { return nil, err } toDate = toDate.Add(24 * time.Hour) var waybills []*tWaybillExt sql := ` SELECT t1.*, t2.store_name, IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) store_id FROM waybill t1 JOIN goods_order t2 ON t1.vendor_order_id = t2.vendor_order_id WHERE t1.waybill_vendor_id = 102 AND t1.status = 105 AND t1.waybill_created_at >= ? AND t1.waybill_created_at <= ? ORDER BY t1.id ` db := dao.GetDB() if err = dao.GetRows(db, &waybills, sql, fromDate, toDate); err == nil { config := []*excel.Obj2ExcelSheetConfig{ &excel.Obj2ExcelSheetConfig{ Title: "Sheet1", Data: waybills, CaptionList: []string{ "vendorWaybillID", "waybillVendorID", "vendorOrderID", "orderVendorID", "storeName", "storeID", "courierName", "status", "desiredFee", "waybillCreatedAt", }, }, } return excel.Obj2Excel(config), nil } return nil, err } func (c *OrderManager) GetOrders(ctx *jxcontext.Context, isIncludeFake bool, fromDateStr, toDateStr string, isDateFinish bool, skuIDs []int, isJxFirst bool, params map[string]interface{}, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { globals.SugarLogger.Debugf("GetOrders from:%s to:%s", fromDateStr, toDateStr) //权限 if permission.IsRoled(ctx) { if storeIDsMap, err := permission.GetUserStoresResultMap(ctx.GetUserID()); err == nil { var storeIDs2 []int if params["storeIDs"] != nil { var storeIDs []int if err = utils.UnmarshalUseNumber([]byte(params["storeIDs"].(string)), &storeIDs); err == nil { for _, v := range storeIDs { if storeIDsMap[v] != 0 { storeIDs2 = append(storeIDs2, v) } } } if len(storeIDs2) == 0 { storeIDs2 = append(storeIDs2, -1) } } else { for k, _ := range storeIDsMap { storeIDs2 = append(storeIDs2, k) } } if data, err := json.Marshal(storeIDs2); err == nil { params["storeIDs"] = string(data) } } } orders, totalCount, err := dao.GetOrders(dao.GetDB(), nil, false, isIncludeFake, fromDateStr, toDateStr, isDateFinish, skuIDs, isJxFirst, "", params, offset, pageSize) if err == nil { pagedInfo = &model.PagedInfo{ TotalCount: totalCount, Data: orders, } } return pagedInfo, err } func (c *OrderManager) ExportOrders(ctx *jxcontext.Context, fromDateStr, toDateStr string, mapParams map[string]interface{}) (hint string, err error) { globals.SugarLogger.Debugf("ExportOrders from:%s to:%s", fromDateStr, toDateStr) var ( orders []*model.GoodsOrderExt afsSkuMap map[string]map[int]*model.OrderSkuFinancial excelBin []byte ) task := tasksch.NewSeqTask("导出订单SKU信息", ctx, func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { switch step { case 0: //权限 if permission.IsRoled(ctx) { if storeIDsMap, err := permission.GetUserStoresResultMap(ctx.GetUserID()); err == nil { var storeIDs2 []int if mapParams["storeIDs"] != nil { var storeIDs []int if err = utils.UnmarshalUseNumber([]byte(mapParams["storeIDs"].(string)), &storeIDs); err == nil { for _, v := range storeIDs { if storeIDsMap[v] != 0 { storeIDs2 = append(storeIDs2, v) } } } if len(storeIDs2) == 0 { storeIDs2 = append(storeIDs2, -1) } } else { for k, _ := range storeIDsMap { storeIDs2 = append(storeIDs2, k) } } if data, err := json.Marshal(storeIDs2); err == nil { mapParams["storeIDs"] = string(data) } } } orders, _, err = dao.GetOrders(dao.GetDB(), nil, true, true, fromDateStr, toDateStr, true, nil, false, "", mapParams, 0, model.UnlimitedPageSize) globals.SugarLogger.Debugf("orders:%d, er:%v", len(orders), err) case 1: afsSkuMap, err = c.getAfsOrderSkuInfo4ExportOrders(ctx, fromDateStr, toDateStr) case 2: var order *model.GoodsOrderExt var orders2 []*model.GoodsOrderExt for _, v := range orders { if afsInfo := afsSkuMap[jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID)]; afsInfo != nil { if afsInfo[v.SkuID] != nil && afsInfo[v.SkuID].Count > 0 { minus := afsInfo[v.SkuID].Count if minus > v.SkuCount2 { minus = v.SkuCount2 } v.SkuCount2 -= minus afsInfo[v.SkuID].Count -= minus } } if v.SkuCount2 > 0 { var skuStr string if beego.BConfig.RunMode == "jxgy" { skuStr = strings.Join([]string{ utils.Int2Str(v.SkuID), utils.Int2Str(v.SkuCount2), utils.Int2Str(v.SkuShopPrice), utils.Int2Str(v.SkuSalePrice), utils.Int2Str(v.SkuEarningPrice), }, ",") } else { if v.EarningType == model.EarningTypeQuote { earningPrice := 0 if v.SkuEarningPrice != 0 { earningPrice = v.SkuEarningPrice } else { earningPrice = v.SkuShopPrice } skuStr = strings.Join([]string{ utils.Int2Str(v.SkuID), utils.Int2Str(v.SkuCount2), utils.Int2Str(v.SkuShopPrice), utils.Int2Str(v.SkuSalePrice), utils.Int2Str(earningPrice), }, ",") } else { skuStr = strings.Join([]string{ utils.Int2Str(v.SkuID), utils.Int2Str(v.SkuCount2), utils.Int2Str(v.SkuShopPrice), utils.Int2Str(v.SkuSalePrice), utils.Int2Str(v.SkuEarningPrice), }, ",") } } if order == nil || v.ID != order.ID { order = v v.CourierVendorName = model.VendorChineseNames[v.WaybillVendorID] v.Status2 = model.OrderStatusName[v.Status] v.SkuInfo = skuStr orders2 = append(orders2, v) } else { order.SkuInfo += ";" + skuStr } } } orders = orders2 case 3: excelConf := &excel.Obj2ExcelSheetConfig{ Title: "订单导出", Data: orders, CaptionList: []string{ "vendorOrderID", "vendorOrderID2", "vendorID", "vendorStoreID", "jxStoreID", "storeName", "salePrice", "shopPrice", "weight", "consigneeName", "consigneeMobile", "consigneeMobile2", "consigneeAddress", "skuCount", "status", "orderSeq", "buyerComment", "businessType", "expectedDeliveredTime", "vendorWaybillID", "waybillVendorID", "orderCreatedAt", "orderFinishedAt", "courierVendorName", "courierName", "courierMobile", "courierMobile", "desiredFee", "waybillCreatedAt", "waybillFinishedAt", "status2", "skuInfo", "waybillTipMoney", "orderPayPercentage", // "skuInfo2", }, } excelBin = excel.Obj2Excel([]*excel.Obj2ExcelSheetConfig{excelConf}) case 4: keyPart := []string{ ctx.GetUserName(), } if fromDateStr != "" { keyPart = append(keyPart, fromDateStr) } if toDateStr != "" { keyPart = append(keyPart, toDateStr) } keyPart = append(keyPart, time.Now().Format("20060102T150405")+".xlsx") key := "export/" + strings.Join(keyPart, "_") excelURL, err2 := jxutils.UploadExportContent(excelBin, key) if err = err2; err == nil { task.SetNoticeMsg(excelURL) } globals.SugarLogger.Debugf("导出订单SKU信息excelURL:%s, err:%v", excelURL, err) } return nil, err }, 5) tasksch.ManageTask(task).Run() hint = task.GetID() return hint, err } func (c *OrderManager) GetWaybills(ctx *jxcontext.Context, fromDateStr, toDateStr string, params map[string]interface{}, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { globals.SugarLogger.Debugf("GetWaybills from:%s to:%s", fromDateStr, toDateStr) fromDate, err := utils.TryStr2Time(fromDateStr) if err != nil { return nil, err } if toDateStr == "" { toDateStr = fromDateStr } toDate, err := utils.TryStr2Time(toDateStr) if err != nil { return nil, err } toDate = toDate.Add(24 * time.Hour) pageSize = jxutils.FormalizePageSize(pageSize) offset = jxutils.FormalizePageOffset(offset) sql := ` SELECT SQL_CALC_FOUND_ROWS t1.*, t2.store_name, IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) store_id FROM waybill t1 JOIN goods_order t2 ON t1.vendor_order_id = t2.vendor_order_id WHERE t1.status = 105 AND t1.waybill_created_at >= ? AND t1.waybill_created_at < ? ` sqlParams := []interface{}{ fromDate, toDate, } if params["keyword"] != nil { keyword := params["keyword"].(string) keywordLike := "%" + keyword + "%" sql += ` AND (t2.store_name LIKE ? OR t1.vendor_order_id LIKE ? OR t2.vendor_waybill_id LIKE ? OR t2.courier_name LIKE ? OR t2.courier_mobile LIKE ? ` sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike) if keywordInt64, err2 := strconv.ParseInt(keyword, 10, 64); err2 == nil { sql += " OR t2.store_id = ? OR t2.jx_store_id = ?" sqlParams = append(sqlParams, keywordInt64, keywordInt64) } sql += ")" } if params["waybillVendorIDs"] != nil { var waybillVendorIDs []int if err = utils.UnmarshalUseNumber([]byte(params["waybillVendorIDs"].(string)), &waybillVendorIDs); err != nil { return nil, err } if len(waybillVendorIDs) > 0 { sql += " AND t2.waybill_vendor_id IN (" + dao.GenQuestionMarks(len(waybillVendorIDs)) + ")" sqlParams = append(sqlParams, waybillVendorIDs) } } if params["statuss"] != nil { var statuss []int if err = utils.UnmarshalUseNumber([]byte(params["statuss"].(string)), &statuss); err != nil { return nil, err } if len(statuss) > 0 { sql += " AND t1.status IN (" + dao.GenQuestionMarks(len(statuss)) + ")" sqlParams = append(sqlParams, statuss) } } sql += ` ORDER BY t1.id LIMIT ? OFFSET ? ` sqlParams = append(sqlParams, pageSize, offset) var waybills []*tWaybillExt db := dao.GetDB() txDB, _ := dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db, txDB) panic(r) } }() if err = dao.GetRowsTx(txDB, &waybills, sql, sqlParams...); err == nil { pagedInfo = &model.PagedInfo{ TotalCount: dao.GetLastTotalRowCount2(db, txDB), Data: waybills, } } dao.Commit(db, txDB) return pagedInfo, err } func (c *OrderManager) GetOrderStatusList(ctx *jxcontext.Context, vendorOrderID string, vendorID int, orderType int) (statusList []*model.OrderStatus, err error) { sql := ` SELECT * FROM order_status t1 WHERE t1.ref_vendor_order_id = ? AND t1.ref_vendor_id = ? ` sqlParams := []interface{}{ vendorOrderID, vendorID, } if orderType > 0 { sql += " AND t1.order_type = ?" sqlParams = append(sqlParams, orderType) } sql += " ORDER BY t1.status_time, t1.order_type DESC, t1.status" db := dao.GetDB() if err = dao.GetRows(db, &statusList, sql, sqlParams...); err != nil { return nil, err } return statusList, nil } func (c *OrderManager) GetOrdersFinancial(ctx *jxcontext.Context, fromDateStr, toDateStr string, params map[string]interface{}, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { globals.SugarLogger.Debugf("GetOrdersFinancial from:%s to:%s", fromDateStr, toDateStr) pageSize = jxutils.FormalizePageSize(pageSize) offset = jxutils.FormalizePageOffset(offset) sql := ` SELECT SQL_CALC_FOUND_ROWS t1.*, t2.store_name,t2.vendor_store_id,t2.store_id,t2.jx_store_id,t2.status,t2.order_finished_at FROM order_financial t1 LEFT JOIN goods_order t2 ON t1.vendor_order_id = t2.vendor_order_id ` var ( sqlWhere string sqlParams []interface{} ) if params["orderID"] != nil { sqlWhere = " WHERE (t1.vendor_order_id = ? OR t1.vendor_order_id2 = ?)" sqlParams = []interface{}{ params["orderID"], params["orderID"], } } else { fromDate, err2 := utils.TryStr2Time(fromDateStr) if err = err2; err != nil { return nil, err } if toDateStr == "" { toDateStr = fromDateStr } toDate, err2 := utils.TryStr2Time(toDateStr) if err = err2; err != nil { return nil, err } toDate = toDate.Add(24 * time.Hour) // order_finished_at sqlWhere = ` WHERE t2.order_created_at >= ? AND t2.order_created_at < ? ` sqlParams = []interface{}{ fromDate, toDate, } if params["vendorIDs"] != nil { var vendorIDs []int if err = utils.UnmarshalUseNumber([]byte(params["vendorIDs"].(string)), &vendorIDs); err != nil { return nil, err } if len(vendorIDs) > 0 { sqlWhere += " AND t1.vendor_id IN (" + dao.GenQuestionMarks(len(vendorIDs)) + ")" sqlParams = append(sqlParams, vendorIDs) } } if params["storeIDs"] != nil { var storeIDs []int if err = utils.UnmarshalUseNumber([]byte(params["storeIDs"].(string)), &storeIDs); err != nil { return nil, err } if len(storeIDs) > 0 { sqlWhere += " AND IF(t2.jx_store_id != 0, t2.jx_store_id, t2.store_id) IN (" + dao.GenQuestionMarks(len(storeIDs)) + ")" sqlParams = append(sqlParams, storeIDs) } } if params["statuss"] != nil { var statuss []int if err = utils.UnmarshalUseNumber([]byte(params["statuss"].(string)), &statuss); err != nil { return nil, err } if len(statuss) > 0 { sqlWhere += " AND t2.status IN (" + dao.GenQuestionMarks(len(statuss)) + ")" sqlParams = append(sqlParams, statuss) } } if params["cities"] != nil { var cities []int if err = utils.UnmarshalUseNumber([]byte(params["cities"].(string)), &cities); err != nil { return nil, err } if len(cities) > 0 { sql += "JOIN store st ON t2.store_id = st.id" sqlWhere += " AND st.city_code IN (" + dao.GenQuestionMarks(len(cities)) + ")" sqlParams = append(sqlParams, cities) } } } sql += sqlWhere sql += ` ORDER BY t2.order_created_at DESC LIMIT ? OFFSET ? ` sqlParams = append(sqlParams, pageSize, offset) var orders []*model.OrderFinancialExt db := dao.GetDB() txDB, _ := dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db, txDB) panic(r) } }() if err = dao.GetRowsTx(txDB, &orders, sql, sqlParams...); err == nil { pagedInfo = &model.PagedInfo{ TotalCount: dao.GetLastTotalRowCount2(db, txDB), Data: orders, } } dao.Commit(db, txDB) return pagedInfo, err } func (c *OrderManager) GetStoresOrderSaleInfo(ctx *jxcontext.Context, storeIDList []int, fromTime time.Time, toTime time.Time, statusList []int) (saleInfoList []*dao.StoresOrderSaleInfo, err error) { // if globals.IsProductEnv() { // return dao.GetStoresOrderSaleInfo(dao.GetDB(), storeIDList, fromTime, toTime, statusList) // } return c.GetStoresOrderSaleInfoNew(ctx, storeIDList, fromTime, toTime, statusList) } func (c *OrderManager) GetStoresOrderSaleInfoNew(ctx *jxcontext.Context, storeIDList []int, fromTime time.Time, toTime time.Time, statusList []int) (saleInfoList []*dao.StoresOrderSaleInfo, err error) { db := dao.GetDB() var isLongTime = false if toTime.Sub(fromTime).Hours() > 24 { isLongTime = true } orderSkuList, err := dao.GetStoreOrderSkuList(db, storeIDList, fromTime, toTime, statusList, true) if err != nil { return nil, err } afsSkuList, err := dao.GetStoreAfsOrderSkuList(db, storeIDList, fromTime, toTime, []int{model.AfsOrderStatusFinished}, true) if err != nil { return nil, err } orderSkuList4Afs, err := dao.GetStoreOrderSkuList4Afs(db, storeIDList, fromTime, toTime, true) if err != nil { return nil, err } orderSkuHandler := func(skuList []*dao.OrderSkuWithActualPayPrice) (orderMap map[string]*model.GoodsOrder, orderSkuMap map[string]*dao.OrderSkuWithActualPayPrice, saleInfoMap map[int64]*dao.StoresOrderSaleInfo) { orderMap = make(map[string]*model.GoodsOrder) orderSkuMap = make(map[string]*dao.OrderSkuWithActualPayPrice) saleInfoMap = make(map[int64]*dao.StoresOrderSaleInfo) var flagVendorOrderID string if len(skuList) > 0 { flagVendorOrderID = skuList[0].VendorOrderID } for k, v := range skuList { storeDetail, _ := dao.GetStoreDetail(db, v.StoreID, v.VendorID, "") if v.EarningPrice == 0 { v.EarningPrice = jxutils.CaculateSkuEarningPrice(v.ShopPrice, v.SalePrice, v.PayPercentage) } status := v.Status if status < model.OrderStatusEndBegin { status = 0 } index := jxutils.Combine2Int(v.StoreID, v.VendorID)*1000 + int64(status) saleInfo := saleInfoMap[index] if saleInfo == nil { saleInfo = &dao.StoresOrderSaleInfo{ StoreID: v.StoreID, VendorID: v.VendorID, Status: status, } saleInfoMap[index] = saleInfo } //成都菜市 if beego.BConfig.RunMode == "prod" || beego.BConfig.RunMode == "beta" { if v.EarningType == model.EarningTypeQuote { saleInfo.RealEarningPrice += v.EarningPrice * int64(v.Count) } } else { if v.OrderPayPercentage == 100 { saleInfo.RealEarningPrice += v.ShopPrice * int64(v.Count) } } saleInfo.ShopPrice += v.ShopPrice * int64(v.Count) saleInfo.VendorPrice += v.VendorPrice * int64(v.Count) saleInfo.SalePrice += v.SalePrice * int64(v.Count) // saleInfo.EarningPrice += v.EarningPrice * int64(v.Count) if v.VendorOrderID == flagVendorOrderID { if k == 0 { saleInfo.EarningPrice = v.NewEarningPrice if beego.BConfig.RunMode == "prod" || beego.BConfig.RunMode == "beta" { if v.EarningType == model.EarningTypePoints { if storeDetail.VendorPayPercentage != 0 && !isLongTime { saleInfo.RealEarningPrice += 0 } else { saleInfo.RealEarningPrice += v.NewEarningPrice } } } else { if v.OrderPayPercentage < 100 { saleInfo.RealEarningPrice += v.NewEarningPrice } } } } else { flagVendorOrderID = v.VendorOrderID saleInfo.EarningPrice += v.NewEarningPrice if beego.BConfig.RunMode == "prod" || beego.BConfig.RunMode == "beta" { if v.EarningType == model.EarningTypePoints { if storeDetail.VendorPayPercentage != 0 && !isLongTime { saleInfo.RealEarningPrice += 0 } else { // && v.VendorID != model.VendorIDJD && v.CityCode != 510100 saleInfo.RealEarningPrice += v.NewEarningPrice } } } else { if v.OrderPayPercentage < 100 { saleInfo.RealEarningPrice += v.NewEarningPrice } } } universalOrderID := jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID) if orderMap[universalOrderID] == nil { orderMap[universalOrderID] = &model.GoodsOrder{ StoreID: v.StoreID, VendorID: v.VendorID, ActualPayPrice: v.ActualPayPrice, } saleInfo.ActualPayPrice += v.ActualPayPrice saleInfo.Count++ saleInfo.DistanceFreightMoney += v.DistanceFreightMoney saleInfo.WaybillTipMoney += v.WaybillTipMoney } orderMap[universalOrderID].SkuCount += v.Count universalOrderSkuID := universalOrderID + "/" + utils.Int2Str(jxutils.GetSkuIDFromOrderSku(&v.OrderSku)) if orderSkuMap[universalOrderSkuID] == nil { orderSkuMap[universalOrderSkuID] = v } } return orderMap, orderSkuMap, saleInfoMap } _, _, saleInfoMap := orderSkuHandler(orderSkuList) orderMap, orderSkuMap, _ := orderSkuHandler(orderSkuList4Afs) afsOrderMap := make(map[string]*model.GoodsOrder) for _, v := range afsSkuList { universalOrderID := jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID) universalOrderSkuID := universalOrderID + "/" + utils.Int2Str(jxutils.GetSkuIDFromOrderSkuFinancial(v)) order := afsOrderMap[universalOrderID] if order == nil { order = &model.GoodsOrder{ StoreID: v.JxStoreID, VendorID: v.VendorID, } if order.StoreID == 0 { order.StoreID = v.StoreID } if orderSku := orderSkuMap[universalOrderSkuID]; orderSku != nil { order.ActualPayPrice = orderSku.ActualPayPrice } afsOrderMap[universalOrderID] = order } order.SkuCount += v.Count if orderSku := orderSkuMap[universalOrderSkuID]; orderSku != nil { order.ShopPrice += orderSku.ShopPrice * int64(v.Count) order.VendorPrice += orderSku.VendorPrice * int64(v.Count) order.SalePrice += orderSku.SalePrice * int64(v.Count) order.EarningPrice += orderSku.EarningPrice * int64(v.Count) } else { // globals.SugarLogger.Debug(utils.Format4Output(v, true)) } } for universalOrderID, v := range afsOrderMap { if orderMap[universalOrderID] != nil && orderMap[universalOrderID].SkuCount == v.SkuCount { v.EarningPrice = orderMap[universalOrderID].ActualPayPrice } status := -1 index := jxutils.Combine2Int(v.StoreID, v.VendorID)*1000 + int64(status) saleInfo := saleInfoMap[index] if saleInfo == nil { saleInfo = &dao.StoresOrderSaleInfo{ StoreID: v.StoreID, VendorID: v.VendorID, Status: status, } saleInfoMap[index] = saleInfo } saleInfo.ActualPayPrice += v.ActualPayPrice saleInfo.ShopPrice += v.ShopPrice saleInfo.VendorPrice += v.VendorPrice saleInfo.SalePrice += v.SalePrice saleInfo.EarningPrice += v.EarningPrice saleInfo.Count++ } for _, v := range saleInfoMap { saleInfoList = append(saleInfoList, v) } return saleInfoList, err } type GetAfsOrdersResult struct { model.AfsOrder StoreName string `json:"storeName"` } func (c *OrderManager) GetAfsOrders(ctx *jxcontext.Context, keyword, afsOrderID, vendorOrderID string, vendorIDList, appealTypeList, storeIDList, statusList, skuIDs []int, fromTime, toTime time.Time, offset, pageSize int) (pagedInfo *model.PagedInfo, err error) { globals.SugarLogger.Debugf("GetAfsOrders") //权限 if permission.IsRoled(ctx) { if storeIDsMap, err := permission.GetUserStoresResultMap(ctx.GetUserID()); err == nil { var storeIDs2 []int if len(storeIDList) > 0 { for _, v := range storeIDList { if storeIDsMap[v] != 0 { storeIDs2 = append(storeIDs2, v) } } if len(storeIDs2) == 0 { storeIDs2 = append(storeIDs2, -1) } } else { for k, _ := range storeIDsMap { storeIDs2 = append(storeIDs2, k) } } storeIDList = nil storeIDList = storeIDs2 } } pageSize = jxutils.FormalizePageSize(pageSize) offset = jxutils.FormalizePageOffset(offset) sql := ` SELECT SQL_CALC_FOUND_ROWS t1.*, t2.name store_name FROM afs_order t1 LEFT JOIN store t2 ON t2.id = IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) ` var ( sqlWhere string sqlParams []interface{} ) // 如果搜索关键字可能为订单或售后单号,则当成订单或售后单查询 if keyword != "" { if jxutils.GetPossibleVendorIDFromAfsOrderID(keyword) > model.VendorIDUnknown && afsOrderID == "" { afsOrderID = keyword } if jxutils.GetPossibleVendorIDFromVendorOrderID(keyword) > model.VendorIDUnknown && vendorOrderID == "" { vendorOrderID = keyword } } if vendorOrderID != "" || afsOrderID != "" { sqlWhere = "WHERE (0 = 1" if vendorOrderID != "" { sqlWhere += " OR (t1.vendor_order_id = ? OR t1.vendor_order_id2 = ?)" sqlParams = append(sqlParams, []interface{}{ vendorOrderID, vendorOrderID, }) } if afsOrderID != "" { sqlWhere += " OR (t1.afs_order_id = ?)" sqlParams = append(sqlParams, []interface{}{ afsOrderID, }) } sqlWhere += ")" } else { if toTime.Sub(fromTime) > 24*time.Hour*60 { return nil, fmt.Errorf("售后单查询时间不能超过60天") } sqlWhere = ` WHERE t1.afs_created_at >= ? AND t1.afs_created_at <= ? ` sqlParams = []interface{}{ fromTime, toTime, } if keyword != "" { keywordLike := "%" + keyword + "%" sqlWhere += ` AND (t1.vendor_order_id2 LIKE ? OR t1.vendor_order_id LIKE ? OR t1.afs_order_id LIKE ? OR t1.vendor_store_id LIKE ? OR t1.reason_desc LIKE ? ` sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike, keywordLike) if keywordInt64 := utils.Str2Int64WithDefault(keyword, 0); keywordInt64 > 0 { sqlWhere += " OR t1.store_id = ? OR t1.jx_store_id = ?" sqlParams = append(sqlParams, keywordInt64, keywordInt64) } sqlWhere += ")" } if len(storeIDList) > 0 { sqlWhere += " AND IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) IN (" + dao.GenQuestionMarks(len(storeIDList)) + ")" sqlParams = append(sqlParams, storeIDList) } if len(statusList) > 0 { sqlWhere += " AND t1.status IN (" + dao.GenQuestionMarks(len(statusList)) + ")" sqlParams = append(sqlParams, statusList) } if len(appealTypeList) > 0 { sqlWhere += " AND t1.appeal_type IN (" + dao.GenQuestionMarks(len(appealTypeList)) + ")" sqlParams = append(sqlParams, appealTypeList) } if len(skuIDs) > 0 { sqlWhere += " AND (SELECT COUNT(*) FROM order_sku_financial t11 WHERE t11.is_afs_order = 1 AND t11.afs_order_id = t1.afs_order_id AND t11.vendor_id = t1.vendor_id AND t11.jx_sku_id IN (" + dao.GenQuestionMarks(len(skuIDs)) + ")) > 0" sqlParams = append(sqlParams, skuIDs) } if len(vendorIDList) > 0 { sqlWhere += " AND t1.vendor_id IN (" + dao.GenQuestionMarks(len(vendorIDList)) + ")" sqlParams = append(sqlParams, vendorIDList) } } sql += sqlWhere sql += ` ORDER BY t1.afs_created_at DESC LIMIT ? OFFSET ? ` sqlParams = append(sqlParams, pageSize, offset) var orders []*GetAfsOrdersResult db := dao.GetDB() txDB, _ := dao.Begin(db) defer func() { if r := recover(); r != nil || err != nil { dao.Rollback(db, txDB) if r != nil { panic(r) } } }() if err = dao.GetRowsTx(txDB, &orders, sql, sqlParams...); err == nil { pagedInfo = &model.PagedInfo{ TotalCount: dao.GetLastTotalRowCount2(db, txDB), Data: orders, } dao.Commit(db, txDB) } return pagedInfo, err } func (c *OrderManager) getAfsOrderSkuInfo4ExportOrders(ctx *jxcontext.Context, fromDateStr, toDateStr string) (skuMap map[string]map[int]*model.OrderSkuFinancial, err error) { fromDate, err2 := utils.TryStr2Time(fromDateStr) if err = err2; err != nil { return nil, err } if utils.IsTimeZero(fromDate) { return nil, fmt.Errorf("在没有指定订单号时,必须指定查询日期范围") } if toDateStr == "" { toDateStr = fromDateStr } toDate, err2 := utils.TryStr2Time(toDateStr) if err = err2; err != nil { return nil, err } toDate = toDate.Add(30 * 24 * time.Hour) // todo 售后单最多只可能延后7天吧 sql := ` SELECT t2.* FROM afs_order t1 JOIN order_sku_financial t2 ON t2.vendor_order_id = t1.vendor_order_id AND t2.vendor_id = t1.vendor_id AND t2.is_afs_order = 1 AND t1.afs_order_id = t2.afs_order_id WHERE t1.afs_finished_at >= ? AND t1.afs_finished_at <= ? AND t1.status = ? ` sqlParams := []interface{}{ fromDate, toDate, model.AfsOrderStatusFinished, } var skus []*model.OrderSkuFinancial if err = dao.GetRows(dao.GetDB(), &skus, sql, sqlParams...); err == nil { skuMap = make(map[string]map[int]*model.OrderSkuFinancial) for _, v := range skus { key := jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID) if skuMap[key] == nil { skuMap[key] = make(map[int]*model.OrderSkuFinancial) } if skuID := jxutils.GetSkuIDFromOrderSkuFinancial(v); skuID > 0 { if skuMap[key][skuID] == nil { skuMap[key][skuID] = v } else { skuMap[key][skuID].Count += v.Count } } } } return skuMap, err } func (c *OrderManager) GetStoreAfsOrderCountInfo(ctx *jxcontext.Context, storeID, lastHours int) (countInfo []*model.GoodsOrderCountInfo, err error) { globals.SugarLogger.Debugf("GetStoreAfsOrderCountInfo storeID:%d", storeID) if lastHours > maxLastHours { lastHours = maxLastHours } else if lastHours == 0 { lastHours = defLastHours } db := dao.GetDB() err = dao.GetRows(db, &countInfo, ` SELECT 0 lock_status, t1.status, COUNT(*) count FROM afs_order t1 WHERE t1.vendor_id <> 2 AND IF(t1.jx_store_id != 0, t1.jx_store_id, t1.store_id) = ? AND t1.afs_created_at >= ? GROUP BY 1,2 ORDER BY 1,2 `, storeID, time.Now().Add(-time.Duration(lastHours)*time.Hour)) if err == nil { return countInfo, nil } globals.SugarLogger.Infof("GetStoreAfsOrderCountInfo storeID:%d failed with error:%v", storeID, err) return nil, err } func (c *OrderManager) AmendMissingOrders(ctx *jxcontext.Context, vendorIDs []int, storeID int, fromDate, toDate time.Time, isAsync, isContinueWhenError bool) (hint string, err error) { if utils.IsTimeZero(fromDate) { return "", fmt.Errorf("fromDate必须指定") } if len(vendorIDs) == 0 { for vendorID := range partner.PurchasePlatformHandlers { vendorIDs = append(vendorIDs, vendorID) } } if len(vendorIDs) == 0 { return "", fmt.Errorf("找不到指定的平台") } fromDate = utils.Time2Date(fromDate) if utils.IsTimeZero(toDate) { toDate = fromDate } toDate = utils.Time2Date(toDate) curDate := utils.Time2Date(time.Now()) if toDate.Sub(curDate) > 0 { toDate = curDate } if toDate.Sub(fromDate) > 7*24*time.Hour { return "", fmt.Errorf("最多一次一周,请调整时间") } type tDateVendorPair struct { QueryDate time.Time VendorID int VendorOrgCode string } var dateVendorList []*tDateVendorPair for _, vendorID := range vendorIDs { for _, vendorOrgCode := range apimanager.CurAPIManager.GetAppOrgCodeList(vendorID) { for tmpDate := fromDate; tmpDate.Sub(toDate) <= 0; tmpDate = tmpDate.Add(24 * time.Hour) { dateVendorList = append(dateVendorList, &tDateVendorPair{ QueryDate: tmpDate, VendorID: vendorID, VendorOrgCode: vendorOrgCode, }) } } } type tOrderVendorPair struct { VendorOrderID string VendorID int VendorOrgCode string VendorStoreID string } if len(dateVendorList) > 0 { var missingOrderList []*tOrderVendorPair var updateOrderStatusList []*model.GoodsOrder db := dao.GetDB() vendorStoreIDMap := make(map[int]string) if storeID > 0 { for _, vendorID := range vendorIDs { storeDetail, err2 := dao.GetStoreDetail(db, storeID, vendorID, "") if err = err2; err != nil { return "", err } vendorStoreIDMap[vendorID] = storeDetail.VendorStoreID } } task := tasksch.NewSeqTask("AmendMissingOrders", ctx, func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) { switch step { case 0: task1 := tasksch.NewParallelTask("AmendMissingOrders ListOrders", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { vendorDate := batchItemList[0].(*tDateVendorPair) if handler, _ := partner.GetPurchaseOrderHandlerFromVendorID(vendorDate.VendorID).(partner.IPurchasePlatformStoreSkuHandler); handler != nil { orderIDs, err2 := handler.ListOrders(ctx, vendorDate.VendorOrgCode, task, vendorDate.QueryDate, vendorStoreIDMap[vendorDate.VendorID]) if err = err2; err == nil && len(orderIDs) > 0 { var orderList []*tOrderVendorPair for _, v := range orderIDs { var vendorStoreID string if orders, _ := dao.QueryOrders(db, v, 0, nil, 0, utils.ZeroTimeValue, utils.ZeroTimeValue); len(orders) > 0 { vendorStoreID = orders[0].VendorStoreID } orderList = append(orderList, &tOrderVendorPair{ VendorOrderID: v, VendorID: vendorDate.VendorID, VendorOrgCode: vendorDate.VendorOrgCode, VendorStoreID: vendorStoreID, }) } retVal = orderList } } return retVal, err }, dateVendorList) tasksch.HandleTask(task1, task, true).Run() orderList, err2 := task1.GetResult(0) if err = err2; err != nil && !isContinueWhenError { return "", err } localOrders, err2 := dao.QueryOrders(db, "", 0, vendorIDs, storeID, fromDate, toDate.Add(24*time.Hour-time.Second)) if err = err2; err != nil { return "", err } localOrderMap := make(map[string]*model.GoodsOrder) for _, v := range localOrders { localOrderMap[jxutils.ComposeUniversalOrderID(v.VendorOrderID, v.VendorID)] = v } for _, v := range orderList { pair := v.(*tOrderVendorPair) goodsOrder := localOrderMap[jxutils.ComposeUniversalOrderID(pair.VendorOrderID, pair.VendorID)] if goodsOrder == nil { missingOrderList = append(missingOrderList, pair) } else { if !model.IsOrderFinalStatus(goodsOrder.Status) { if goodsOrder.BusinessType == model.BusinessTypeImmediate { if time.Now().Sub(goodsOrder.CreatedAt).Hours() >= orderSubTimeImmediatelyArrive { updateOrderStatusList = append(updateOrderStatusList, goodsOrder) } } else { if time.Now().Sub(goodsOrder.ExpectedDeliveredTime).Hours() >= orderSubTimeDelayArrive { updateOrderStatusList = append(updateOrderStatusList, goodsOrder) } } } } } case 1: task2 := tasksch.NewParallelTask("AmendMissingOrders GetOrders", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { pair := batchItemList[0].(*tOrderVendorPair) if handler := partner.GetPurchaseOrderHandlerFromVendorID(pair.VendorID); handler != nil { order, err2 := handler.GetOrder(pair.VendorOrgCode, pair.VendorOrderID, pair.VendorStoreID) if err = err2; err == nil { if order.VendorStoreID == "2391979" { return retVal, err } isDuplicated, err2 := c.SaveOrder(order, false, dao.GetDB()) if err2 == nil && !isDuplicated { retVal = []int{1} if order.Status == model.OrderStatusNew { err = handler.AcceptOrRefuseOrder(order, true, ctx.GetUserName()) } } } } return retVal, err }, missingOrderList) tasksch.HandleTask(task2, task, true).Run() result, err = task2.GetResult(0) case 2: task3 := tasksch.NewParallelTask("AmendMissingOrders UpdateOrders", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { goodsOrder := batchItemList[0].(*model.GoodsOrder) if handler := partner.GetPurchaseOrderHandlerFromVendorID(goodsOrder.VendorID); handler != nil { order, err2 := handler.GetOrder(goodsOrder.VendorOrgCode, goodsOrder.VendorOrderID, goodsOrder.VendorStoreID) if err = err2; err == nil { if model.IsOrderFinalStatus(order.Status) { goodsOrder.Status = order.Status goodsOrder.OrderFinishedAt = order.OrderFinishedAt if goodsOrder.OrderFinishedAt == utils.DefaultTimeValue || goodsOrder.OrderFinishedAt == utils.ZeroTimeValue { goodsOrder.OrderFinishedAt = goodsOrder.OrderCreatedAt.Add(time.Hour) } _, err = dao.UpdateEntity(db, goodsOrder, "Status", "OrderFinishedAt") } } } return retVal, err }, updateOrderStatusList) tasksch.HandleTask(task3, task, true).Run() _, err = task3.GetResult(0) } return result, err }, 3) tasksch.HandleTask(task, nil, true).Run() if !isAsync { result, err2 := task.GetResult(0) if err = err2; err == nil { hint = utils.Int2Str(len(result)) } } else { hint = task.GetID() } } return hint, err } func (c *OrderManager) RefreshOrderFinancial(ctx *jxcontext.Context, fromTime, toTime time.Time, isAsync, isContinueWhenError bool) (hint string, err error) { sql := ` SELECT * FROM goods_order WHERE status = ? AND total_shop_money = 0 ` sqlParams := []interface{}{ model.OrderStatusFinished, } if !utils.IsTimeZero(fromTime) { sql += " AND order_created_at >= ?" sqlParams = append(sqlParams, fromTime) } if !utils.IsTimeZero(toTime) { sql += " AND order_created_at <= ?" sqlParams = append(sqlParams, toTime) } var orderList []*model.GoodsOrder db := dao.GetDB() if err = dao.GetRows(db, &orderList, sql, sqlParams...); err == nil && len(orderList) > 0 { task := tasksch.NewParallelTask("RefreshOrderFinancial", tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx, func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) { order := batchItemList[0].(*model.GoodsOrder) handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID) if handler != nil { remoteOrder, err2 := handler.GetOrder(order.VendorOrgCode, order.VendorOrderID, order.VendorStoreID) if err = err2; err == nil { order.TotalShopMoney = remoteOrder.TotalShopMoney order.PmSubsidyMoney = remoteOrder.PmSubsidyMoney err = partner.CurOrderManager.UpdateOrderFields(order, []string{"TotalShopMoney", "PmSubsidyMoney"}) } } return nil, err }, orderList) tasksch.HandleTask(task, nil, true).Run() hint = task.ID if !isAsync { _, err = task.GetResult(0) } } return hint, err } func GetOrdersAccept(ctx *jxcontext.Context, storeID int) (result []*OrderSkusAccept, err error) { db := dao.GetDB() sql := ` SELECT SUM(a.count) sum_count, SUM(a.weight*a.count) sum_weight, c.*, d.name, d.unit, d.prefix, d.img FROM order_sku a JOIN goods_order b ON b.vendor_order_id = a.vendor_order_id AND b.vendor_id = a.vendor_id JOIN sku c ON c.id = a.sku_id JOIN sku_name d ON d.id = c.name_id WHERE IF(b.store_id = 0,b.jx_store_id,b.store_id) = ? AND b.status = ? AND b.order_created_at <= NOW() AND b.order_created_at >= ? GROUP BY 3 ORDER BY sum_weight DESC ` sqlParams := []interface{}{ storeID, model.OrderStatusAccepted, time.Now().AddDate(0, 0, -1), } err = dao.GetRows(db, &result, sql, sqlParams) return result, err } func GetMatterStoreOrderCount(ctx *jxcontext.Context, storeID int) (result *OrderCount, err error) { var ( db = dao.GetDB() orderPays []*model.OrderPay orderCount = &OrderCount{} orderTime time.Time flag = false ) 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 = ? ORDER BY b.pay_finished_at DESC LIMIT 1 ` sqlParams := []interface{}{storeID, model.OrderStatusDelivering, model.OrderStatusCanceled, model.PayStatusYes} err = dao.GetRows(db, &orderPays, sql, sqlParams) if len(orderPays) != 0 { orderPay := orderPays[0] stores, _ := dao.GetStoreList(db, []int{storeID}, nil, nil, nil, nil, "") if len(stores) > 0 { store := stores[0] if store.IsBoughtMatter == model.YES { flag = false } else { flag = true } } else { flag = false } orderTime = *orderPay.PayFinishedAt } else { orderTime = time.Now().AddDate(0, -1, 0) flag = true } sql2 := ` SELECT COUNT(*) count FROM goods_order WHERE IF(store_id = 0,jx_store_id,store_id) = ? AND order_created_at <= NOW() AND order_created_at >= ? AND status = ? ` sqlParams2 := []interface{}{ storeID, orderTime, model.OrderStatusFinished, } err = dao.GetRow(db, &orderCount, sql2, sqlParams2) if err != nil { return nil, err } orderCount.Count = int(utils.Float64TwoInt64(math.Ceil(utils.Int2Float64(orderCount.Count) * 1.5))) orderCount.Flag = flag // orderCount.Count = 1000 return orderCount, err } func RefreshJdShopOrdersEarningPrice(ctx *jxcontext.Context, orderStartTime, orderEndTime string) (err error) { var ( db = dao.GetDB() appOrgCode string ) if beego.BConfig.RunMode == "jxgy" { appOrgCode = "339032" } else { appOrgCode = "320406" } jdapi := partner.CurAPIManager.GetAPI(model.VendorIDJD, appOrgCode).(*jdapi.API) results, err := jdapi.GetJdShopOrders(utils.Str2Time(orderStartTime).Format("20060102"), utils.Str2Time(orderEndTime).Format("20060102"), globals.JdOrgCode, globals.JdLoginName) if err != nil { return err } for _, v := range results.BillList.Result { if v.DueAmount != 0 { order, err := partner.CurOrderManager.LoadOrder(utils.Int64ToStr(v.OrderID), model.VendorIDJD) if order == nil || err != nil { continue } store, _ := dao.GetStoreDetail(db, jxutils.GetSaleStoreIDFromOrder(order), order.VendorID, order.VendorOrgCode) // stores, _ := dao.GetStoreList(db, []int{jxutils.GetSaleStoreIDFromOrder(order)}, nil, nil, nil, nil, "") if store != nil { if order.TotalShopMoney == 0 { order.TotalShopMoney = utils.Float64TwoInt64(v.DueAmount * 100) } if order.NewEarningPrice == 0 { jxutils.RefreshOrderEarningPrice2(order, store.PayPercentage) } dao.UpdateEntity(db, order, "TotalShopMoney", "NewEarningPrice") } } } return err } func GetOrderUserBuyFirst(ctx *jxcontext.Context, vendorOrderID string) (isFirst bool, err error) { var orderPays []*model.OrderPay sql := ` SELECT b.* FROM goods_order a, order_pay b WHERE a.vendor_order_id = b.vendor_order_id AND a.vendor_id = b.vendor_id AND b.pay_finished_at <> 0 AND a.vendor_id = ? AND a.user_id = ( SELECT user_id FROM goods_order WHERE vendor_order_id = ?) AND a.vendor_order_id <> ? ` sqlParams := []interface{}{model.VendorIDJX, vendorOrderID, vendorOrderID} err = dao.GetRows(dao.GetDB(), &orderPays, sql, sqlParams) if len(orderPays) > 0 { return false, err } else { return true, err } return isFirst, err }