From 0ee04cdd4d114b5ffe261bfeb81c704df0b2cafe Mon Sep 17 00:00:00 2001 From: renyutian Date: Thu, 21 Mar 2019 16:12:54 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E7=BB=93=E7=AE=97=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- business/jxcallback/orderman/financial.go | 64 ++++++++ business/model/order_financial.go | 116 ++++++++++++++ business/partner/purchase/ebai/financial.go | 126 ++++++++++++++- .../partner/purchase/ebai/financial_test.go | 19 +++ business/partner/purchase/jd/financial.go | 143 +++++++++++++++++- .../partner/purchase/jd/financial_test.go | 17 +++ business/partner/purchase/mtwm/financial.go | 122 ++++++++++++++- .../partner/purchase/mtwm/financial_test.go | 45 ++++++ globals/beegodb/beegodb.go | 3 + 9 files changed, 642 insertions(+), 13 deletions(-) create mode 100644 business/jxcallback/orderman/financial.go create mode 100644 business/model/order_financial.go create mode 100644 business/partner/purchase/ebai/financial_test.go create mode 100644 business/partner/purchase/jd/financial_test.go create mode 100644 business/partner/purchase/mtwm/financial_test.go diff --git a/business/jxcallback/orderman/financial.go b/business/jxcallback/orderman/financial.go new file mode 100644 index 000000000..e039d1887 --- /dev/null +++ b/business/jxcallback/orderman/financial.go @@ -0,0 +1,64 @@ +package orderman + +import ( + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/model/dao" + "git.rosy.net.cn/jx-callback/globals" +) + +const ( + PublicWelfareDonation = 1 // 美团公益捐款金额现阶段是每单一分钱 + TotalRate = 200 // 总费率(千分之200)= 第三方平台费+京西品牌费+京西服务费,现阶段都是合计200‰ +) + +// 处理正向订单结账信息 +func SaveOrderFinancialInfo(order *model.OrderFinancial) (err error) { + if order.VendorID == model.VendorIDJD { //京东订单单独处理部分 + } + if order.VendorID == model.VendorIDEBAI { //饿百订单单独处理部分 + order.FreightDiscountMoney = order.TotalDiscountMoney - order.DiscountMoney + } + if order.VendorID == model.VendorIDMTWM { //美团订单单独处理部分 + order.DonationMoney = PublicWelfareDonation + } + order.ShopMoneyByCal = order.SalePriceMoney - order.TotalDiscountMoney + order.VendorFreightDiscountMoney - order.DistanceFreightMoney - order.FreightTipsMoney - order.DonationMoney + order.SelfDeliveryDiscountMoney + order.PmSubsidyMoney + order.BoxMoney - order.PmMoney + order.PmMoneyFormJx = (order.ShopMoney+order.PmMoney)*TotalRate/1000 - order.PmMoney // 京西平台费 = 总金额*20%-第三方平台费 + if order.PmMoneyFormJx < 0 { // 如果算出京西平台费为负数,则置0 + order.PmMoneyFormJx = 0 + } + order.ShopMoneyFromJx = order.ShopMoney - order.PmMoneyFormJx + order.SubsidyMoneyFromJx - order.FreightMoneyFromJxByShop + err = dao.CreateEntity(dao.GetDB(), order) + return err +} + +// 处理售后订单结账信息 +func SaveAfsOrderFinancialInfo(afsOrder *model.AfterSalesOrder) (err error) { + db := dao.GetDB() + dao.Begin(db) + defer dao.Rollback(db) + if afsOrder.VendorID == model.VendorIDJD { //京东订单单独处理部分 + } + if afsOrder.VendorID == model.VendorIDEBAI { //饿百订单单独处理部分 + } + if afsOrder.VendorID == model.VendorIDMTWM { //美团订单单独处理部分 + } + globals.SugarLogger.Debug(afsOrder.Skus) + for _, orderSku := range afsOrder.Skus { + orderSku.SkuRefundMoneyByCal = orderSku.SkuUserMoney + orderSku.SkuVendorMoney + afsOrder.FreightUserMoney + afsOrder.AfsFreightMoney + afsOrder.BoxMoney + afsOrder.TongchengFreightMoney + afsOrder.MealBoxMoney + // orderSku.SkuTotalMoney+=orderSku.SkuJxMoney // 退款单京西补贴部分先不作计算 + afsOrder.SkuUserMoney += orderSku.SkuUserMoney + afsOrder.PmSubsidyMoney += orderSku.SkuVendorMoney + // order.SkuJxMoney += orderSku.SkuJxMoney // 退款单京西补贴部分先不作计算 + if err = dao.CreateEntity(db, orderSku); err != nil { + return err + } + } + afsOrder.RefundMoneyByCal = afsOrder.SkuUserMoney + afsOrder.PmSubsidyMoney + afsOrder.FreightUserMoney + afsOrder.AfsFreightMoney + afsOrder.BoxMoney + afsOrder.TongchengFreightMoney + afsOrder.MealBoxMoney + // order.TotalMoney += order.SkuJxMoney // 退款单京西补贴部分先不作计算 + if err = dao.CreateEntity(db, afsOrder); err != nil { + globals.SugarLogger.Warnf("On SaveAfsOrderFinancialInfo err: SaveAfsOrder is err") + return err + } + dao.Commit(db) + return err +} diff --git a/business/model/order_financial.go b/business/model/order_financial.go new file mode 100644 index 000000000..ba87e4fc0 --- /dev/null +++ b/business/model/order_financial.go @@ -0,0 +1,116 @@ +package model + +import "time" + +type OrderFinancial struct { + ModelIDCUL + + VendorID int `orm:"column(vendor_id)" json:"vendorID"` // 平台id + VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` // 订单ID + VendorOrderID2 string `orm:"column(vendor_order_id2);size(48);index" json:"vendorOrderID2"` // 订单ID2,饿百独有 + DeliveryConfirmTime time.Time `orm:"type(datetime);index" json:"deliveryConfirmTime"` // 订单妥投/完成时间 + ShopPriceMoney int64 `json:"shopPriceMoney"` // 门店价-左右商品在京西的价格总和(报价模式会用到)0 + SalePriceMoney int64 `json:"salePriceMoney"` // 商品标价总额(用户下单满减之前的商品售价)+ + ActualPayMoney int64 `json:"actualPayMoney"` // 用户实际支付金额0 + TotalDiscountMoney int64 `json:"totalDiscountMoney"` // 订单总优惠(订单主体+运费)- + DiscountMoney int64 `json:"discountMoney"` // 订单主体优惠0 + ReceivableFreight int64 `json:"receivableFreight"` // 订单应收运费0 + FreightMoney int64 `json:"freightMoney"` // 用户支付运费0 + FreightDiscountMoney int64 `json:"freightDiscountMoney"` // 订单运费优惠(商家设置满减discountType == 8)0 + VendorFreightDiscountMoney int64 `json:"vendorFreightDiscountMoney"` // 订单运费优惠(平台运费优惠discountType == 7/12/15)+ + DistanceFreightMoney int64 `json:"distanceFreightMoney"` // 订单远距离费- + FreightTipsMoney int64 `json:"freightTipsMoney"` // 订单小费- + DonationMoney int64 `json:"donationMoney"` // 公益捐款- + SelfDeliveryDiscountMoney int64 `json:"selfDeliveryDiscountMoney"` // 平台承担运费补贴(商家自送)+ + PmSubsidyMoney int64 `json:"pmSubsidyMoney"` // 平台订单活动补贴1+ + BoxMoney int64 `json:"boxMoney"` // 餐盒费1+ + PmMoney int64 `json:"pmMoney"` // 平台费1- + ShopMoney int64 `json:"shopMoney"` // 应结金额-第三方平台结算给京西的金额M + ShopMoneyByCal int64 `json:"shopMoneyByCal"` // 应结金额-通过公式计算平台结给京西的金额M + PmMoneyFormJx int64 `json:"pmMoneyFormJx"` // 京西平台费- + FreightMoneyFromJx int64 `json:"freightMoneyFromJx"` // 转自送-->美团/达达订单产生运费0 + FreightMoneyFromJxByShop int64 `json:"freightMoneyFromJxByShop"` // 转自送-->美团/达达订单产生运费,由商家承担的部分- + SubsidyMoneyFromJx int64 `json:"subsidyMoneyFromJx"` // 京西补贴,针对单品活动补贴+ + ShopMoneyFromJx int64 `json:"shopMoneyFromJx"` // 店铺应结金额-京西结算给店铺的金额M +} + +func (o *OrderFinancial) TableUnique() [][]string { + return [][]string{ + []string{"VendorOrderID", "VendorID"}, + } +} + +type AfterSalesOrder struct { + ModelIDCUL + + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` // 关联原始订单ID + VendorOrderID2 string `orm:"column(vendor_order_id2);size(48);index" json:"vendorOrderID2"` // 关联原始订单ID2,饿百独有 + AfterSalesOrderID string `orm:"column(after_sales_order_id);size(48)" json:"afterSalesOrderID"` // 售后订单ID + ConfirmTime time.Time `orm:"type(datetime);index" json:"confirmTime"` // 售后单完成时间 + VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` // 外部系统里记录的storeid + StoreID int `orm:"column(store_id)" json:"storeID"` // 接口返回的京西门店ID + JxStoreID int `orm:"column(jx_store_id)" json:"jxStoreID"` // 根据VendorStoreID在本地系统里查询出来的 jxstoreid + SkuUserMoney int64 `json:"skuUserMoney"` // 用户支付菜品金额 + FreightUserMoney int64 `json:"freightUserMoney"` // 用户支付运费金额 + AfsFreightMoney int64 `json:"afsFreightMoney"` // 退货取件费 + BoxMoney int64 `json:"boxMoney"` // 应退包装费金额 + TongchengFreightMoney int64 `json:"tongchengFreightMoney"` // 退货单产生的同城送费用 + MealBoxMoney int64 `json:"mealBoxMoney"` // 应退订单餐盒费 + PmSubsidyMoney int64 `json:"pmSubsidyMoney"` // 平台补贴金额 + RefundMoney int64 `json:"refundMoney"` // 平台扣款总额 1 + RefundMoneyByCal int64 `json:"refundMoneyByCal"` // 平台扣款总额-通过公式计算平台扣除京西的金额M + // SkuJxMoney int64 `json:"SkuJxMoney"` // 京西补贴金额,现阶段是平台扣京西多少钱,京西扣商家多少钱,暂不考虑撤回京西补贴 + Skus []*AfterSalesOrderSku `orm:"-" json:"-"` +} + +func (o *AfterSalesOrder) TableUnique() [][]string { + return [][]string{ + []string{"AfterSalesOrderID", "VendorID"}, + } +} + +type AfterSalesOrderSku struct { + ModelIDCUL + + VendorID int `orm:"column(vendor_id)" json:"vendorID"` // 平台id + VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` // 关联原始订单ID + VendorOrderID2 string `orm:"column(vendor_order_id2);size(48);index" json:"vendorOrderID2"` // 关联原始订单ID2,饿百独有 + AfterSalesOrderID string `orm:"column(after_sales_order_id);size(48)" json:"afterSalesOrderID"` // 售后订单ID + ConfirmTime time.Time `orm:"type(datetime)" json:"confirmTime"` // 订单完成时间 + VendorStoreID string `orm:"column(vendor_store_id);size(48)" json:"vendorStoreID"` // 外部系统里记录的storeid + StoreID int `orm:"column(store_id)" json:"storeID"` // 接口返回的京西门店ID + JxStoreID int `orm:"column(jx_store_id)" json:"jxStoreID"` // 根据VendorStoreID在本地系统里查询出来的 jxstoreid + VendorSkuID string `orm:"column(vendor_sku_id);size(48)" json:"vendorSkuID"` // 平台skuid + SkuID int `orm:"column(sku_id)" json:"skuID"` // 平台返回的京西skuid + JxSkuID int `orm:"column(jx_sku_id)" json:"jxSkuID"` // 京西skuid + Name string `orm:"size(255)" json:"name"` // 商品名 + SkuUserMoney int64 `json:"skuUserMoney"` // 用户支付金额 + SkuVendorMoney int64 `json:"skuVendorMoney"` // 平台补贴金额 + SkuRefundMoney int64 `json:"skuRefundMoney"` // 平台扣款总额 1 + SkuRefundMoneyByCal int64 `json:"skuRefundMoneyByCal"` // 平台扣款总额-通过公式计算平台扣除京西的金额M + // CreatedAt time.Time `orm:"type(datetime);index" json:"createdAt"` // 订单创建时间 + // SkuJxMoney int64 `json:"skuJxFee"` // 京西补贴金额,现阶段是平台扣京西多少钱,京西扣商家多少钱,暂不考虑撤回京西补贴 +} + +func (o *AfterSalesOrderSku) TableIndex() [][]string { + return [][]string{ + []string{"AfterSalesOrderID", "SkuID", "VendorID"}, + } +} + +// type ActivityForSku struct { +// ModelIDCUL + +// CityName string `json:"cityName"` // 活动所在城市 +// VendorID int `orm:"column(vendor_id)" json:"vendorID"` // 平台id +// ActivityCreatedAt time.Time `orm:"type(datetime);index" json:"activityCreatedAt"` // 活动开始时间时间 +// ActivityEndAt time.Time `orm:"type(datetime);index" json:"activityEndAt"` // 活动结束时间 +// VendorSkuID string `orm:"column(vendor_sku_id)" json:"vendorSkuID"` // 平台skuid +// SkuID int `orm:"column(sku_id)" json:"skuID"` // 平台返回的京西skuid +// JxSkuID int `orm:"column(jx_sku_id)" json:"jxSkuID"` // 京西本地系统查询到的skuid +// ActivityPrice int64 `json:"activityPrice"` // 活动价格 +// JxSubsidy int64 `json:"jxSubsidy"` // 京西补贴 +// ManagerSubsidy int64 `json:"managerSubsidy"` // 城市经理补贴 +// Remark string `json:"remark"` // 备注 +// } diff --git a/business/partner/purchase/ebai/financial.go b/business/partner/purchase/ebai/financial.go index 7784fb0ec..06828e8bf 100644 --- a/business/partner/purchase/ebai/financial.go +++ b/business/partner/purchase/ebai/financial.go @@ -1,11 +1,125 @@ package ebai -import "git.rosy.net.cn/baseapi/platformapi/ebaiapi" +import ( + "git.rosy.net.cn/baseapi/platformapi/ebaiapi" + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/partner" + "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" +) -func OnFinancialMsg(msg *ebaiapi.CallbackMsg) (response *ebaiapi.CallbackResponse) { - return response -} - -func (p *PurchaseHandler) OnOrderDetail(orderDetail map[string]interface{}) (err error) { +// 存储饿百退款订单结账信息 +func OnFinancialMsg(msg *ebaiapi.CallbackMsg) (err error) { + if msg.Cmd == ebaiapi.CmdOrderPartRefund { // 部分退款处理 + if utils.Interface2String(msg.Body["status"]) == ebaiapi.OrderPartRefundSuccess { + orderData, err2 := api.EbaiAPI.OrderPartrefundGet(utils.Interface2String(msg.Body["refund_id"])) + if err = err2; err == nil { + afsOrder := CurPurchaseHandler.AfsOrderDetail2Financial(orderData) + err = orderman.SaveAfsOrderFinancialInfo(afsOrder) + } + } + } else if msg.Cmd == ebaiapi.CmdOrderUserCancel { // 全额退款处理 + if utils.Interface2String(msg.Body["cancel_type"]) == ebaiapi.AfterOrderFinishedCancelType && (utils.Interface2String(msg.Body["type"]) == ebaiapi.OrderUserCancelSuccessA || utils.Interface2String(msg.Body["type"]) == ebaiapi.OrderUserCancelSuccessB) { + globals.SugarLogger.Debug(utils.Interface2String(msg.Body["refund_id"])) // 获得退款订单ID,去本地数据库拿?饿百消息推送只给了订单号,但是没有查询全额退款的接口,只有部分退款才可以查询 + } + } return err } + +func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData map[string]interface{}) (afsOrder *model.AfterSalesOrder) { + afsOrder = &model.AfterSalesOrder{ + VendorID: model.VendorIDEBAI, + AfterSalesOrderID: utils.Interface2String(orderData["order_id"]), + VendorOrderID: utils.Interface2String(orderData["order_id"]), + } + order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID) + if err == nil { + afsOrder.JxStoreID = order.JxStoreID + } else { + globals.SugarLogger.Warnf("ebai OnFinancialMsg, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrder", afsOrder.VendorOrderID) + err = nil + } + if orderData["refund_detail"] != nil { + refundDetail := orderData["refund_detail"].([]interface{}) + for _, refundInfo := range refundDetail { + xMap := refundInfo.(map[string]interface{}) + orderSku := &model.AfterSalesOrderSku{ + VendorID: model.VendorIDEBAI, + AfterSalesOrderID: afsOrder.AfterSalesOrderID, + VendorOrderID: afsOrder.VendorOrderID, + ConfirmTime: getTimeFromInterface(xMap["apply_time"]), + VendorSkuID: utils.Interface2String(xMap["sku_id"]), + SkuID: int(utils.Str2Int64(utils.Interface2String(xMap["custom_sku_id"]))), + Name: utils.Interface2String(xMap["name"]), + SkuUserMoney: utils.MustInterface2Int64(xMap["total_refund"]), + SkuVendorMoney: utils.MustInterface2Int64(xMap["shop_ele_refund"]), + } + afsOrder.Skus = append(afsOrder.Skus, orderSku) + } + if len(refundDetail) > 0 { + afsOrder.ConfirmTime = afsOrder.Skus[0].ConfirmTime + } else { + globals.SugarLogger.Warnf("ebai OnFinancialMsg, orderID:%s have no refund_detail", afsOrder.VendorOrderID) + } + } else { + globals.SugarLogger.Warnf("ebai OnFinancialMsg, orderID:% refund_detail is nil", afsOrder.VendorOrderID) + } + return afsOrder +} + +// 存储饿百正向订单结账信息 +func (p *PurchaseHandler) OnOrderDetail(result map[string]interface{}) (err error) { + err = orderman.SaveOrderFinancialInfo(p.OrderDetail2Financial(result)) + return err +} + +func (p *PurchaseHandler) OrderDetail2Financial(result map[string]interface{}) (orderDetail *model.OrderFinancial) { + orderDetail = &model.OrderFinancial{ + VendorID: model.VendorIDEBAI, + } + order1 := result["order"].(map[string]interface{}) + orderDetail.VendorOrderID = utils.Interface2String(order1["order_id"]) + orderDetail.VendorOrderID2 = utils.Interface2String(order1["eleme_order_id"]) + orderDetail.DeliveryConfirmTime = getTimeFromInterface(order1["finished_time"]) + orderDetail.TotalDiscountMoney = utils.MustInterface2Int64(order1["discount_fee"]) + orderDetail.ReceivableFreight = utils.MustInterface2Int64(order1["send_fee"]) + if int(utils.MustInterface2Int64(order1["send_immediately"])) == ebaiapi.SendImmediatelySelf { + orderDetail.SelfDeliveryDiscountMoney = orderDetail.ReceivableFreight + } + orderDetail.BoxMoney = utils.MustInterface2Int64(order1["package_fee"]) + orderDetail.ActualPayMoney = utils.MustInterface2Int64(order1["user_fee"]) + orderDetail.PmMoney = utils.MustInterface2Int64(order1["commission"]) + orderDetail.ShopMoney = utils.MustInterface2Int64(order1["shop_fee"]) + order, err := partner.CurOrderManager.LoadOrder(orderDetail.VendorOrderID, orderDetail.VendorID) + if err == nil { + skus := order.Skus + if skus != nil { + for _, x := range skus { + orderDetail.ShopPriceMoney += x.ShopPrice + } + } + } else { + globals.SugarLogger.Warnf("ebai OnOrderDetail, orderID:%s is not found from partner.CurOrderManager.LoadOrder", orderDetail.VendorOrderID) + err = nil + } + if result["products"] != nil { + products := result["products"].([]interface{}) + for _, x := range products { + for _, y := range x.([]interface{}) { + product := y.(map[string]interface{}) + orderDetail.SalePriceMoney += utils.MustInterface2Int64(product["product_price"]) * utils.MustInterface2Int64(product["product_amount"]) + } + } + } + if result["discount"] != nil { + discount := result["discount"].([]interface{}) + for _, x := range discount { + xMap := x.(map[string]interface{}) + orderDetail.DiscountMoney += utils.MustInterface2Int64(xMap["fee"]) + orderDetail.PmSubsidyMoney += utils.MustInterface2Int64(xMap["baidu_rate"]) // 平台承担补贴 + } + } + return orderDetail +} diff --git a/business/partner/purchase/ebai/financial_test.go b/business/partner/purchase/ebai/financial_test.go new file mode 100644 index 000000000..b466a4781 --- /dev/null +++ b/business/partner/purchase/ebai/financial_test.go @@ -0,0 +1,19 @@ +package ebai + +import ( + "fmt" + "testing" + + "git.rosy.net.cn/baseapi/platformapi/ebaiapi" +) + +func TestOnFinancialMsg(t *testing.T) { + msg := &ebaiapi.CallbackMsg{ + Cmd: "order.partrefund.push", + Body: make(map[string]interface{}), + } + msg.Body["refund_id"] = "15518443822344" + msg.Body["status"] = "20" + res := OnFinancialMsg(msg) + fmt.Println(res) +} diff --git a/business/partner/purchase/jd/financial.go b/business/partner/purchase/jd/financial.go index ee75dd8dc..a7cc8dfdf 100644 --- a/business/partner/purchase/jd/financial.go +++ b/business/partner/purchase/jd/financial.go @@ -1,7 +1,146 @@ package jd -import "git.rosy.net.cn/baseapi/platformapi/jdapi" +import ( + "git.rosy.net.cn/baseapi/platformapi/jdapi" + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/partner" + "git.rosy.net.cn/jx-callback/globals" + "git.rosy.net.cn/jx-callback/globals/api" +) +// 京东正向/退款订单类型处理--存储 func OnFinancialMsg(msg *jdapi.CallbackOrderMsg) (retVal *jdapi.CallbackResponse) { - return retVal + var err error + if msg.StatusID == jdapi.OrderStatusPayFinishedSettle || msg.StatusID == jdapi.OrderStatusAdjustSettle || msg.StatusID == jdapi.OrderStatusSwitch2SelfSettle { // 如果是正向单 + orderData, err2 := api.JdAPI.QuerySingleOrder(msg.BillID) + if err = err2; err == nil { + err = orderman.SaveOrderFinancialInfo(curPurchaseHandler.OrderDetail2Financial(orderData)) + } + } else if msg.StatusID == jdapi.SaleBillStatusRefundSuccess || msg.StatusID == jdapi.SaleBillStatusSaleReturnSuccess { // 如果是退款单 + orderData, err2 := api.JdAPI.GetAfsService(msg.BillID) + if err = err2; err == nil { + err = orderman.SaveAfsOrderFinancialInfo(curPurchaseHandler.AfsOrderDetail2Financial(orderData)) + } + } + return jdapi.Err2CallbackResponse(err, "jd OnFinancialMsg") +} + +// 处理京东正向订单信息 +func (p *PurchaseHandler) OrderDetail2Financial(orderData map[string]interface{}) (orderDetail *model.OrderFinancial) { + orderDetail = &model.OrderFinancial{ + VendorID: model.VendorIDJD, + VendorOrderID: utils.Int64ToStr(utils.MustInterface2Int64(orderData["orderId"])), + ReceivableFreight: utils.MustInterface2Int64(orderData["orderReceivableFreight"]), + FreightMoney: utils.MustInterface2Int64(orderData["orderFreightMoney"]), + ActualPayMoney: utils.MustInterface2Int64(orderData["orderBuyerPayableMoney"]), + DiscountMoney: utils.MustInterface2Int64(orderData["orderDiscountMoney"]), + DistanceFreightMoney: utils.MustInterface2Int64(orderData["merchantPaymentDistanceFreightMoney"]), + FreightTipsMoney: utils.MustInterface2Int64(orderData["tips"]), + // BoxFee: utils.MustInterface2Int64(orderData["packagingMoney"]), // 京东包装(塑料袋)由京东提供,相应钱款也归京东,不记录/记录之后优化算法 + } + order, err := partner.CurOrderManager.LoadOrder(orderDetail.VendorOrderID, orderDetail.VendorID) + if err == nil { + skus := order.Skus + if skus != nil { + for _, x := range skus { + orderDetail.ShopPriceMoney += x.ShopPrice + } + } + } else { + globals.SugarLogger.Warnf("jd OnJdOrderinfo, orderID:%s is not found from partner.CurOrderManager.LoadOrder", orderDetail.VendorOrderID) + } + if orderData["product"] != nil { + product := orderData["product"].([]interface{}) + for _, x := range product { + xMap := x.(map[string]interface{}) + orderDetail.SalePriceMoney += utils.MustInterface2Int64(xMap["skuJdPrice"]) * utils.MustInterface2Int64(xMap["skuCount"]) + } + } + orderDetail.DeliveryConfirmTime = utils.Str2TimeWithDefault(utils.Interface2String(orderData["deliveryConfirmTime"]), utils.DefaultTimeValue) + if utils.Interface2String(orderData["deliveryCarrierNo"]) == jdapi.SelfDeliveryCarrierNo { + orderDetail.SelfDeliveryDiscountMoney = utils.MustInterface2Int64(orderData["orderReceivableFreight"]) + orderDetail.DistanceFreightMoney = 0 + } + if orderData["discount"] != nil { + discount := orderData["discount"].([]interface{}) + for _, x := range discount { + xMap := x.(map[string]interface{}) + discountPrice := utils.MustInterface2Int64(xMap["discountPrice"]) + discountType := int(utils.MustInterface2Int64(xMap["discountType"])) + if discountType == jdapi.FreightDiscountTypeByShop { + orderDetail.FreightDiscountMoney = discountPrice + } + if discountType == jdapi.FreightDiscountTypeByVip || discountType == jdapi.FreightDiscountTypeByActivity || discountType == jdapi.FreightDiscountTypeByCoupons { + orderDetail.VendorFreightDiscountMoney = discountPrice + } + orderDetail.TotalDiscountMoney += discountPrice + } + } + order1, err2 := api.JdAPI.OrderShoudSettlementService(orderDetail.VendorOrderID) + if err2 == nil { + orderDetail.ShopMoney = utils.Interface2Int64WithDefault(order1["settlementAmount"], 0) + orderDetail.PmMoney += utils.Interface2Int64WithDefault(order1["goodsCommission"], 0) + orderDetail.PmMoney += utils.Interface2Int64WithDefault(order1["freightCommission"], 0) + orderDetail.PmMoney += utils.Interface2Int64WithDefault(order1["packageCommission"], 0) + orderDetail.PmMoney += utils.Interface2Int64WithDefault(order1["guaranteedCommission"], 0) + orderDetail.PmSubsidyMoney += utils.Interface2Int64WithDefault(order1["platOrderGoodsDiscountMoney"], 0) + orderDetail.PmSubsidyMoney += utils.Interface2Int64WithDefault(order1["platSkuGoodsDiscountMoney"], 0) + } + return orderDetail +} + +// 处理京东售后订单结账信息 +func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData map[string]interface{}) (afsOrder *model.AfterSalesOrder) { + afsOrder = &model.AfterSalesOrder{ + VendorID: model.VendorIDJD, + AfterSalesOrderID: utils.Interface2String(orderData["afsServiceOrder"]), + VendorOrderID: utils.Interface2String(orderData["orderId"]), + VendorStoreID: utils.Interface2String(orderData["stationId"]), + StoreID: int(utils.Str2Int64(utils.Interface2String(orderData["stationNumOutSystem"]))), + ConfirmTime: utils.Timestamp2Time(utils.MustInterface2Int64(orderData["updateTime"].(map[string]interface{})["time"])), + FreightUserMoney: utils.MustInterface2Int64(orderData["orderFreightMoney"]), + AfsFreightMoney: utils.MustInterface2Int64(orderData["afsFreight"]), + BoxMoney: utils.MustInterface2Int64(orderData["packagingMoney"]), + TongchengFreightMoney: utils.MustInterface2Int64(orderData["tongchengFreightMoney"]), + MealBoxMoney: utils.MustInterface2Int64(orderData["mealBoxMoney"]), + } + order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID) + if err == nil { + afsOrder.JxStoreID = order.JxStoreID + } else { + globals.SugarLogger.Warnf("jd OnFinancialMsg, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrder", afsOrder.VendorOrderID) + } + if orderData["afsDetailList"] != nil { + refundDetail := orderData["afsDetailList"].([]interface{}) + for _, x := range refundDetail { + xMap := x.(map[string]interface{}) + orderSku := &model.AfterSalesOrderSku{ + VendorID: model.VendorIDJD, + AfterSalesOrderID: afsOrder.AfterSalesOrderID, + VendorOrderID: afsOrder.VendorOrderID, + VendorStoreID: afsOrder.VendorStoreID, + StoreID: afsOrder.StoreID, + ConfirmTime: afsOrder.ConfirmTime, + VendorSkuID: utils.Int64ToStr(utils.MustInterface2Int64(xMap["wareId"])), + SkuID: int(utils.Str2Int64(utils.Interface2String(xMap["skuIdIsv"]))), + Name: utils.Interface2String(xMap["wareName"]), + SkuUserMoney: utils.MustInterface2Int64(xMap["afsMoney"]), + } + if xMap["afsSkuDiscountList"] != nil { + afsSkuDiscountList := xMap["afsSkuDiscountList"].([]interface{}) + for _, y := range afsSkuDiscountList { + orderSku.SkuVendorMoney += utils.MustInterface2Int64(y.(map[string]interface{})["platPayMoney"]) + } + } + afsOrder.Skus = append(afsOrder.Skus, orderSku) + } + if len(refundDetail) <= 0 { + globals.SugarLogger.Warnf("ebai OnFinancialMsg, orderID:%s have no refund_detail", afsOrder.VendorOrderID) + } + } else { + globals.SugarLogger.Warnf("ebai OnFinancialMsg, orderID:% refund_detail is nil", afsOrder.VendorOrderID) + } + return afsOrder } diff --git a/business/partner/purchase/jd/financial_test.go b/business/partner/purchase/jd/financial_test.go new file mode 100644 index 000000000..f4c265b2a --- /dev/null +++ b/business/partner/purchase/jd/financial_test.go @@ -0,0 +1,17 @@ +package jd + +import ( + "fmt" + "testing" + + "git.rosy.net.cn/baseapi/platformapi/jdapi" +) + +func TestOnFinancialMsg(t *testing.T) { + msg := &jdapi.CallbackOrderMsg{ + BillID: "817102100000041", + StatusID: "330901", + } + res := OnFinancialMsg(msg) + fmt.Println(res) +} diff --git a/business/partner/purchase/mtwm/financial.go b/business/partner/purchase/mtwm/financial.go index ef9147f78..5a9933325 100644 --- a/business/partner/purchase/mtwm/financial.go +++ b/business/partner/purchase/mtwm/financial.go @@ -1,11 +1,123 @@ package mtwm -import "git.rosy.net.cn/baseapi/platformapi/mtwmapi" +import ( + "net/url" -func OnFinancialMsg(msg *mtwmapi.CallbackMsg) (response *mtwmapi.CallbackResponse) { - return response -} + "git.rosy.net.cn/baseapi/platformapi/mtwmapi" + "git.rosy.net.cn/baseapi/utils" + "git.rosy.net.cn/jx-callback/business/jxcallback/orderman" + "git.rosy.net.cn/jx-callback/business/jxutils" + "git.rosy.net.cn/jx-callback/business/model" + "git.rosy.net.cn/jx-callback/business/partner" + "git.rosy.net.cn/jx-callback/globals" +) -func (p *PurchaseHandler) OnOrderDetail(orderDetail map[string]interface{}) (err error) { +// 存储美团退款订单结账信息 +func OnFinancialMsg(msg *mtwmapi.CallbackMsg) (err error) { + if msg.Cmd == mtwmapi.MsgTypeOrderPartialRefund { // 部分退款处理 + orderData := msg.Data + if orderData.Get("notify_type") == mtwmapi.NotifyTypeSuccess { + err = orderman.SaveAfsOrderFinancialInfo(curPurchaseHandler.AfsOrderDetail2Financial(orderData)) + } + } + if msg.Cmd == mtwmapi.MsgTypeOrderRefund { // todo 全额退款处理 + orderData := msg.Data + if orderData.Get("notify_type") == mtwmapi.NotifyTypeSuccess { + globals.SugarLogger.Debug(orderData.Get("order_id")) // 获得退款订单ID,去本地数据库拿?饿百消息推送只给了订单号,也没有通过订单号查询退款信息的接口 + } + } return err } + +func (p *PurchaseHandler) AfsOrderDetail2Financial(orderData url.Values) (afsOrder *model.AfterSalesOrder) { + afsOrder = &model.AfterSalesOrder{ + VendorID: model.VendorIDMTWM, + AfterSalesOrderID: orderData.Get("order_id"), + VendorOrderID: orderData.Get("order_id"), + ConfirmTime: utils.Timestamp2Time(utils.Str2Int64(orderData.Get("timestamp"))), + RefundMoney: jxutils.StandardPrice2Int(utils.Str2Float64(orderData.Get("money"))), + } + order, err := partner.CurOrderManager.LoadOrder(afsOrder.VendorOrderID, afsOrder.VendorID) + if err == nil { + afsOrder.JxStoreID = order.JxStoreID + } else { + globals.SugarLogger.Warnf("mtwm OnFinancialMsg, afsOrderID:%s is not found from partner.CurOrderManager.LoadOrder", afsOrder.VendorOrderID) + err = nil + } + food := orderData.Get("food") + var refundDetail []map[string]interface{} + utils.UnmarshalUseNumber([]byte(food), &refundDetail) + for _, xMap := range refundDetail { + orderSku := &model.AfterSalesOrderSku{ + VendorID: model.VendorIDMTWM, + AfterSalesOrderID: afsOrder.AfterSalesOrderID, + VendorOrderID: afsOrder.VendorOrderID, + ConfirmTime: afsOrder.ConfirmTime, + VendorSkuID: utils.Interface2String(xMap["app_food_code"]), + SkuID: int(utils.Str2Int64(utils.Interface2String(xMap["sku_id"]))), + Name: utils.Interface2String(xMap["food_name"]), + SkuUserMoney: jxutils.StandardPrice2Int(utils.MustInterface2Float64(xMap["refund_price"]))*utils.MustInterface2Int64(xMap["count"]) + jxutils.StandardPrice2Int(utils.MustInterface2Float64(xMap["box_price"]))*int64(utils.MustInterface2Float64(xMap["box_num"])), + } + afsOrder.Skus = append(afsOrder.Skus, orderSku) + } + if len(refundDetail) <= 0 { + globals.SugarLogger.Warnf("ebai OnFinancialMsg, orderID:%s have no refund_detail", afsOrder.VendorOrderID) + } + return afsOrder +} + +// 存储美团正向订单结账信息 +func (p *PurchaseHandler) OnOrderDetail(result map[string]interface{}) (err error) { + err = orderman.SaveOrderFinancialInfo(p.OrderDetail2Financial(result)) + return err +} + +func (p *PurchaseHandler) OrderDetail2Financial(result map[string]interface{}) (orderDetail *model.OrderFinancial) { + orderDetail = &model.OrderFinancial{ + VendorID: model.VendorIDMTWM, + VendorOrderID: utils.Int64ToStr(utils.MustInterface2Int64(result["order_id"])), + } + orderDetail.DeliveryConfirmTime = utils.Str2TimeWithDefault(utils.Interface2String(result["order_completed_time"]), utils.DefaultTimeValue) + order, err := partner.CurOrderManager.LoadOrder(orderDetail.VendorOrderID, orderDetail.VendorID) + if err == nil { + if order.Skus != nil { + for _, x := range order.Skus { + orderDetail.ShopPriceMoney += x.ShopPrice + } + } + } else { + globals.SugarLogger.Warnf("mtwm OrderDetail2Financial, orderID:%s is not found from partner.CurOrderManager.LoadOrder", orderDetail.VendorOrderID) + err = nil + } + detail := result["detail"] + if detail != nil { + var data []map[string]interface{} + utils.UnmarshalUseNumber([]byte(utils.Interface2String(detail)), &data) + for _, x := range data { + orderDetail.SalePriceMoney += jxutils.StandardPrice2Int(utils.MustInterface2Float64(x["price"])) * utils.MustInterface2Int64(x["quantity"]) + orderDetail.BoxMoney += jxutils.StandardPrice2Int(utils.MustInterface2Float64(x["box_price"])) * utils.MustInterface2Int64(x["box_num"]) + } + } else { + globals.SugarLogger.Warnf("mtwm OrderDetail2Financial, orderID:%s have no detail", orderDetail.VendorOrderID) + } + poiReceiveDetail := result["poi_receive_detail"] + if poiReceiveDetail != nil { + var data map[string]interface{} + utils.UnmarshalUseNumber([]byte(utils.Interface2String(poiReceiveDetail)), &data) + orderDetail.ReceivableFreight = utils.MustInterface2Int64(data["logisticsFee"]) + orderDetail.FreightMoney = utils.MustInterface2Int64(data["logisticsFee"]) + orderDetail.ActualPayMoney = utils.MustInterface2Int64(data["onlinePayment"]) + orderDetail.PmMoney = utils.MustInterface2Int64(data["foodShareFeeChargeByPoi"]) + orderDetail.ShopMoney = utils.MustInterface2Int64(data["wmPoiReceiveCent"]) + for _, x := range data["actOrderChargeByMt"].([]interface{}) { + orderDetail.TotalDiscountMoney += utils.MustInterface2Int64(x.(map[string]interface{})["moneyCent"]) + orderDetail.PmSubsidyMoney += utils.MustInterface2Int64(x.(map[string]interface{})["moneyCent"]) + } + for _, x := range data["actOrderChargeByPoi"].([]interface{}) { + orderDetail.TotalDiscountMoney += utils.MustInterface2Int64(x.(map[string]interface{})["moneyCent"]) + } + } else { + globals.SugarLogger.Warnf("mtwm OrderDetail2Financial, orderID:%s have no poi_receive_detail", orderDetail.VendorOrderID) + } + return orderDetail +} diff --git a/business/partner/purchase/mtwm/financial_test.go b/business/partner/purchase/mtwm/financial_test.go new file mode 100644 index 000000000..843983ef9 --- /dev/null +++ b/business/partner/purchase/mtwm/financial_test.go @@ -0,0 +1,45 @@ +package mtwm + +import ( + "fmt" + "net/url" + "testing" + "time" + + "git.rosy.net.cn/baseapi/platformapi/mtwmapi" + "git.rosy.net.cn/baseapi/utils" +) + +func TestOnFinancialMsg(t *testing.T) { + msg := &mtwmapi.CallbackMsg{ + Cmd: "orderPartialRefund", + Data: url.Values{}, + } + msg.Data.Set("timestamp", utils.Int64ToStr(time.Now().Unix())) + msg.Data.Set("order_id", "123458") + msg.Data.Set("notify_type", "agree") + msg.Data.Set("money", "23.56") + food := []map[string]interface{}{ + map[string]interface{}{ + "app_food_code": "123", + "food_name": "商品1", + "sku_id": "123", + "refund_price": 3.14, + "count": 2, + "box_num": 1, + "box_price": 1, + }, + map[string]interface{}{ + "app_food_code": "124", + "food_name": "商品2", + "sku_id": "124", + "refund_price": 3.15, + "count": 2, + "box_num": 1, + "box_price": 1, + }, + } + msg.Data.Set("food", string(utils.MustMarshal(food))) + res := OnFinancialMsg(msg) + fmt.Println(res) +} diff --git a/globals/beegodb/beegodb.go b/globals/beegodb/beegodb.go index 074aaa385..a60b89d4e 100644 --- a/globals/beegodb/beegodb.go +++ b/globals/beegodb/beegodb.go @@ -37,6 +37,9 @@ func Init() { orm.RegisterModel(&model.Promotion{}, &model.PromotionStore{}, &model.PromotionSku{}) orm.RegisterModel(&model.AuthBind{}, &model.User{}) + orm.RegisterModel(&model.OrderFinancial{}, &model.AfterSalesOrder{}, &model.AfterSalesOrderSku{}) + // orm.RegisterModel(&model.ActivityForSku{}) + // orm.RegisterModel(&legacymodel.JxBadComments2{}) if globals.EnablePendingChange {