package orderman import ( "strings" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxcallback/scheduler" "git.rosy.net.cn/jx-callback/business/jxutils" "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" "github.com/astaxie/beego/client/orm" ) func (c *OrderManager) LoadAfsOrder(vendorAfsOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) { return c.loadAfsOrder(dao.GetDB(), vendorAfsOrderID, vendorID) } func (c *OrderManager) loadAfsOrder(db *dao.DaoDB, vendorAfsOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) { afsOrder = &model.AfsOrder{ AfsOrderID: vendorAfsOrderID, VendorID: vendorID, } if err = dao.GetEntity(db, afsOrder, "AfsOrderID", "VendorID"); err != nil { afsOrder = nil } return afsOrder, err } func (c *OrderManager) OnAfsOrderAdjust(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error) { return c.onAfsOrderNew(afsOrder, orderStatus, true) } func (c *OrderManager) OnAfsOrderNew(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus) (err error) { return c.onAfsOrderNew(afsOrder, orderStatus, false) } func (c *OrderManager) onAfsOrderNew(afsOrder *model.AfsOrder, orderStatus *model.OrderStatus, isAdjust bool) (err error) { db := dao.GetDB() globals.SugarLogger.Debugf("onAfsOrderNew1 orderID:%s", afsOrder.VendorOrderID) c.setAfsOrderID(db, orderStatus) if afsOrder.AfsOrderID == "" { afsOrder.AfsOrderID = orderStatus.VendorOrderID } if afsOrder.VendorStatus == "" { afsOrder.VendorStatus = orderStatus.VendorStatus } if afsOrder.Status == model.OrderStatusUnknown { afsOrder.Status = orderStatus.Status } globals.SugarLogger.Debugf("onAfsOrderNew2 orderID:%s", afsOrder.VendorOrderID) // if order, _ := c.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID); order != nil { if order.ConsigneeMobile2 == "" { if handler := partner.GetPurchaseOrderHandlerFromVendorID(order.VendorID); handler != nil { if order2, _ := handler.GetOrder(order.VendorOrgCode, order.VendorOrderID, order.VendorStoreID); order2 != nil && order.ConsigneeMobile != order2.ConsigneeMobile { order.ConsigneeMobile = order2.ConsigneeMobile c.UpdateOrderFields(order, []string{"ConsigneeMobile"}) } } } } // txDB , _ := dao.Begin(db) defer func() { if r := recover(); r != nil || err != nil { dao.Rollback(db, txDB) panic(r) } }() isDuplicated, err := addOrderOrWaybillStatus(orderStatus, db) globals.SugarLogger.Debugf("onAfsOrderNew afsOrderID:%s, isDuplicated:%t", afsOrder.AfsOrderID, isDuplicated) if err != nil || isDuplicated { if err == nil { dao.Commit(db, txDB) } return err } var existAfsOrder *model.AfsOrder if existAfsOrder, err = c.loadAfsOrder(db, afsOrder.AfsOrderID, afsOrder.VendorID); err != nil { if !dao.IsNoRowsError(err) { return err } } if existAfsOrder != nil { // todo 可能导致状态回绕 existAfsOrder.Status = afsOrder.Status existAfsOrder.VendorStatus = afsOrder.VendorStatus if _, err = dao.UpdateEntity(db, existAfsOrder, "Status", "VendorStatus"); err != nil { return err } afsOrder = existAfsOrder } else { // 全退都要先全删除再建 if afsOrder.RefundType == model.AfsTypeFullRefund { isAdjust = true } if err = c.SaveAfsOrder(db, afsOrder, isAdjust); err != nil { return err } } dao.Commit(db, txDB) scheduler.CurrentScheduler.OnAfsOrderNew(afsOrder, false) return err } func (c *OrderManager) SaveAfsOrder(db *dao.DaoDB, afsOrder *model.AfsOrder, isDeleteFirst bool) (err error) { globals.SugarLogger.Debug(afsOrder.AfsOrderID) if db == nil { db = dao.GetDB() } if err = c.updateAfsOrderOtherInfo(db, afsOrder); err != nil { return err } txDB , _ := dao.Begin(db) defer func() { if r := recover(); r != nil || err != nil { dao.Rollback(db, txDB) if r != nil { panic(r) } } }() if isDeleteFirst { err = utils.CallFuncLogError(func() error { _, err = dao.DeleteEntity(db, afsOrder, "VendorOrderID", "VendorID") return err }, "SaveAfsOrder delete AfsOrder, afsOrderID:%s", afsOrder.AfsOrderID) if err != nil { return err } err = utils.CallFuncLogError(func() error { _, err = dao.DeleteEntity(db, &model.OrderSkuFinancial{ VendorOrderID: afsOrder.VendorOrderID, VendorID: afsOrder.VendorID, IsAfsOrder: 1, }, "VendorOrderID", "VendorID", "IsAfsOrder") return err }, "SaveAfsOrder delete OrderSkuFinancial, afsOrderID:%s", afsOrder.AfsOrderID) if err != nil { return err } } // 平台结算扣除汇总--平台补贴,售后产生运费,平台收包装费,同城运费、、、 deductionsByPm := afsOrder.PmSubsidyMoney + afsOrder.AfsFreightMoney + afsOrder.BoxMoney + afsOrder.TongchengFreightMoney afsOrder.RefundMoneyByCal = afsOrder.SkuUserMoney + afsOrder.FreightUserMoney + deductionsByPm - afsOrder.PmRefundMoney // order.TotalMoney += order.SkuJxMoney // 退款单京西补贴部分先不作计算 if err = dao.CreateEntity(db, afsOrder); err != nil { globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err:%v", afsOrder.AfsOrderID, err) return err } // 京西结算扣除汇总,先不作计算,计算单条sku最终扣款金额(+该条sku承担的平台结算扣除金额) for _, orderSku := range afsOrder.Skus[1:] { orderSku.RefundMoneyByCal = orderSku.PmSkuSubsidyMoney + utils.Float64TwoInt64(float64(afsOrder.RefundMoneyByCal-afsOrder.PmSkuSubsidyMoney)*float64(orderSku.UserMoney+orderSku.PmSubsidyMoney-orderSku.PmSkuSubsidyMoney)/float64(afsOrder.SkuUserMoney+afsOrder.PmSubsidyMoney-afsOrder.PmSkuSubsidyMoney)) afsOrder.Skus[0].RefundMoneyByCal += orderSku.RefundMoneyByCal if err = dao.CreateEntity(db, orderSku); err != nil { globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err:%v, orderSku:%s", afsOrder.AfsOrderID, err, utils.Format4Output(orderSku, true)) return err } } if len(afsOrder.Skus) > 0 { orderSku := afsOrder.Skus[0] orderSku.RefundMoneyByCal = afsOrder.RefundMoneyByCal - orderSku.RefundMoneyByCal if err = dao.CreateEntity(db, orderSku); err != nil { globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err:%v, orderSku:%s", afsOrder.AfsOrderID, err, utils.Format4Output(orderSku, true)) return err } } else { globals.SugarLogger.Warnf("On SaveAfsOrder afsOrder.AfsOrderID:%s err: afsOrder have no sku", afsOrder.AfsOrderID) } dao.Commit(db, txDB) return err } func (c *OrderManager) OnAfsOrderStatusChanged(orderStatus *model.OrderStatus) (err error) { db := dao.GetDB() c.setAfsOrderID(db, orderStatus) txDB , _ := dao.Begin(db) defer func() { if r := recover(); r != nil { dao.Rollback(db, txDB) panic(r) } }() isDuplicated, afsOrder, err := c.addAfsOrderStatus(db, orderStatus) if err != nil || isDuplicated { if err == nil { dao.Commit(db, txDB) } else { dao.Rollback(db, txDB) } return err } dao.Commit(db, txDB) scheduler.CurrentScheduler.OnAfsOrderStatusChanged(afsOrder, orderStatus, false) return err } func (c *OrderManager) addAfsOrderStatus(db *dao.DaoDB, orderStatus *model.OrderStatus) (isDuplicated bool, order *model.AfsOrder, err error) { globals.SugarLogger.Debugf("addAfsOrderStatus refOrderID:%s, orderID:%s", orderStatus.RefVendorOrderID, orderStatus.VendorOrderID) if db == nil { db = dao.GetDB() } isDuplicated, err = addOrderOrWaybillStatus(orderStatus, db) if err == nil && !isDuplicated && (orderStatus.Status != model.OrderStatusUnknown && orderStatus.Status != model.OrderStatusMsg) { order = &model.AfsOrder{ AfsOrderID: orderStatus.VendorOrderID, VendorID: orderStatus.VendorID, } if err = db.Db.ReadForUpdate(order, "AfsOrderID", "VendorID"); err == nil { if orderStatus.Status > model.OrderStatusUnknown { // todo 要求status不能回绕 order.VendorStatus = orderStatus.VendorStatus order.Status = orderStatus.Status updateFields := []string{ "VendorStatus", "Status", } if model.IsAfsOrderFinalStatus(orderStatus.Status) { order.AfsFinishedAt = orderStatus.StatusTime updateFields = append(updateFields, "AfsFinishedAt") } utils.CallFuncLogError(func() error { _, err = dao.UpdateEntity(db, order, updateFields...) return err }, "addAfsOrderStatus update orderID:%s, status:%v", order.VendorOrderID, orderStatus) } else { isDuplicated = true } } else { if dao.IsNoRowsError(err) { // todo 消息错序 err = nil } else { globals.SugarLogger.Warnf("addAfsOrderStatus orderID:%s read failed with error:%v", order.VendorOrderID, err) } } } return isDuplicated, order, err } func (c *OrderManager) updateAfsOrderSkuOtherInfo(db *dao.DaoDB, order *model.AfsOrder) (err error) { globals.SugarLogger.Debugf("updateAfsOrderSkuOtherInfo orderID:%s, VendorStoreID:%s", order.VendorOrderID, order.VendorStoreID) jxStoreID := jxutils.GetSaleStoreIDFromAfsOrder(order) opNumStr := "2" if jxStoreID == 0 { globals.SugarLogger.Infof("updateAfsOrderSkuOtherInfo [运营%s]订单在京西与平台都找不到京西门店信息orderID:%s, VendorStoreID:%s", opNumStr, order.VendorOrderID, order.VendorStoreID) return nil } orderSkus := order.Skus var vendorSkuIDs []string skuIDMap := make(map[int]int) for _, v := range orderSkus { if v.VendorSkuID != "" { vendorSkuIDs = append(vendorSkuIDs, v.VendorSkuID) } if skuID := jxutils.GetSkuIDFromOrderSkuFinancial(v); skuID > 0 { skuIDMap[skuID] = 1 } } if len(vendorSkuIDs) > 0 { var vendorStoreID string if order.VendorID == model.VendorIDJDShop { vendorStoreID = model.JdShopMainVendorStoreID } else { vendorStoreID = order.VendorStoreID } l, err := dao.GetStoreSkuPriceAndWeight(db, vendorStoreID, order.VendorID, vendorSkuIDs) if err != nil { globals.SugarLogger.Warnf("updateAfsOrderSkuOtherInfo orderID:%s failed with err:%v", order.VendorOrderID, err) return err } skumapper := storeSkuPriceAndWeight2Map(l) var actStoreSkuMap *jxutils.ActStoreSkuMap if len(skuIDMap) > 0 { if order2, err2 := c.LoadOrder(order.VendorOrderID, order.VendorID); err2 == nil { actStoreSkuList, err := dao.GetEffectiveActStoreSkuInfo(db, 0, []int{order.VendorID}, model.ActTypeAll, []int{jxStoreID}, jxutils.IntMap2List(skuIDMap), order2.OrderCreatedAt, order2.OrderCreatedAt) if err != nil { globals.SugarLogger.Errorf("updateAfsOrderSkuOtherInfo can not get sku promotion info for error:%v", err) return err } actStoreSkuMap = jxutils.NewActStoreSkuMap(actStoreSkuList, false) } } for _, v := range orderSkus { v.AfsOrderID = order.AfsOrderID v.VendorID = order.VendorID v.VendorOrderID = order.VendorOrderID v.IsAfsOrder = 1 v.VendorStoreID = order.VendorStoreID v.StoreID = order.StoreID v.JxStoreID = jxStoreID intVendorSkuID := utils.Str2Int64WithDefault(v.VendorSkuID, 0) if intVendorSkuID != 0 && v.VendorSkuID != "-70000" { // todo hard code skuBindInfo := skumapper[v.VendorSkuID] if skuBindInfo == nil { globals.SugarLogger.Infof("updateAfsOrderSkuOtherInfo [运营%s]%s订单sku找不到门店价格(或商品映射),orderID:%s, StoreID:%d, VendorSkuID:%s, sku:%v", opNumStr, model.VendorChineseNames[order.VendorID], order.VendorOrderID, jxStoreID, v.VendorSkuID, v) } else { v.JxSkuID = skuBindInfo.SkuID v.ShopPrice = int64(skuBindInfo.Price) } } if actStoreSkuMap != nil { if skuID := jxutils.GetSkuIDFromOrderSkuFinancial(v); skuID > 0 && v.StoreSubName != "" { if actStoreSku := actStoreSkuMap.GetActStoreSku(jxStoreID, skuID, order.VendorID); actStoreSku != nil { v.StoreSubID = actStoreSku.ActID } } } } } return nil } func (c *OrderManager) updateAfsOrderOtherInfo(db *dao.DaoDB, afsOrder *model.AfsOrder) (err error) { globals.SugarLogger.Debugf("updateAfsOrderOtherInfo orderID:%s, VendorStoreID:%s", afsOrder.VendorOrderID, afsOrder.VendorStoreID) if afsOrder.VendorStoreID != "" { if storeDetail, err := dao.GetStoreDetailByVendorStoreID(db, afsOrder.VendorStoreID, 0, ""); err == nil { afsOrder.JxStoreID = storeDetail.Store.ID } } if afsOrder.StoreID == 0 && afsOrder.JxStoreID == 0 { if order, err2 := c.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID); err2 == nil { afsOrder.JxStoreID = order.JxStoreID if afsOrder.StoreID == 0 { afsOrder.StoreID = order.StoreID } if afsOrder.VendorStoreID == "" { afsOrder.VendorStoreID = order.VendorStoreID } } } if err == nil { if err = c.updateAfsOrderSkuOtherInfo(db, afsOrder); err == nil { jxutils.RefreshAfsOrderSkuRelated(afsOrder) } } return err } func (c *OrderManager) UpdateAfsOrderFields(afsOrder *model.AfsOrder, fieldList []string) (err error) { db := orm.NewOrm() utils.CallFuncLogError(func() error { _, err = db.Update(afsOrder, fieldList...) return err }, "UpdateAfsOrderFields orderID:%s failed with error:%v", afsOrder.VendorOrderID, err) return err } func (c *OrderManager) setAfsOrderID(db *dao.DaoDB, orderStatus *model.OrderStatus) { // globals.SugarLogger.Debugf("setAfsOrderID1 orderStatus:%v", utils.Format4Output(orderStatus, true)) if dao.IsVendorThingIDEmpty(orderStatus.VendorOrderID) { index := 1 if afsOrderList, err2 := dao.GetAfsOrders(db, orderStatus.RefVendorID, orderStatus.RefVendorOrderID, ""); err2 == nil { if len(afsOrderList) > 0 { list := strings.Split(afsOrderList[0].AfsOrderID, "-") if len(list) > 1 { index = int(utils.Str2Int64WithDefault(list[1], 0)) if afsOrderList[0].Status >= model.AfsOrderStatusFinished { index++ } } } } else { globals.SugarLogger.Warnf("setAfsOrderID err2:%v", err2) } orderStatus.VendorOrderID = composeAfsOrderID(orderStatus.RefVendorOrderID, index) } // globals.SugarLogger.Debugf("setAfsOrderID2 orderStatus:%v", utils.Format4Output(orderStatus, true)) } func composeAfsOrderID(vendorOrderID string, index int) (afsOrderID string) { return strings.Join([]string{ vendorOrderID, utils.Int2Str(index), }, "-") } func (c *OrderManager) CreateAfsOrderFromOrder(vendorOrderID string, vendorID int) (afsOrder *model.AfsOrder, err error) { order, err := c.LoadOrder(vendorOrderID, vendorID) // globals.SugarLogger.Debug(utils.Format4Output(order, false)) if err == nil { afsOrder = &model.AfsOrder{ VendorID: vendorID, VendorOrderID: vendorOrderID, JxStoreID: order.JxStoreID, VendorStoreID: order.VendorStoreID, StoreID: order.StoreID, VendorOrgCode: order.VendorOrgCode, } } else { globals.SugarLogger.Warnf("CreateAfsOrderFromOrder, orderID:%s is not found from partner.CurOrderManager.LoadOrder", vendorOrderID) return nil, err } for _, sku := range order.Skus { orderSkuFinancial := &model.OrderSkuFinancial{ VendorID: sku.VendorID, VendorOrderID: sku.VendorOrderID, // OrderFinancialID: sku.VendorOrderID, // ConfirmTime: afsOrder.AfsCreateAt, VendorStoreID: afsOrder.VendorStoreID, StoreID: afsOrder.StoreID, JxStoreID: afsOrder.JxStoreID, VendorSkuID: sku.VendorSkuID, SkuID: sku.SkuID, PromotionType: sku.PromotionType, Name: sku.SkuName, ShopPrice: sku.ShopPrice, SalePrice: sku.SalePrice, Count: sku.Count, // UserMoney: sku.UserMoney, // PmSubsidyMoney: sku.PmSubsidyMoney, IsAfsOrder: 1, } afsOrder.Skus = append(afsOrder.Skus, orderSkuFinancial) } return afsOrder, nil }