From 221e8cf45f45819a33fe7d5bb6c4a58eab0194ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8B=8F=E5=B0=B9=E5=B2=9A?= <770236076@qq.com> Date: Fri, 8 May 2020 09:40:51 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BE=8E=E5=9B=A2=E9=85=8D=E9=80=81=E7=8A=B6?= =?UTF-8?q?=E6=80=81=EF=BC=8C=E4=BA=AC=E4=B8=9C=E5=95=86=E5=9F=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- platformapi/jdeclpapi/jdeclpapi.go | 102 ++++++++++++- platformapi/jdeclpapi/jdeclpapi_test.go | 191 ++++++++++++++++-------- platformapi/mtpsapi/mtpsapi.go | 4 +- platformapi/mtpsapi/mtpsapi_test.go | 2 +- platformapi/mtpsapi/shop_page.go | 44 +++++- platformapi/mtpsapi/shop_page_test.go | 12 +- 6 files changed, 285 insertions(+), 70 deletions(-) diff --git a/platformapi/jdeclpapi/jdeclpapi.go b/platformapi/jdeclpapi/jdeclpapi.go index 47035dba..d259e69e 100644 --- a/platformapi/jdeclpapi/jdeclpapi.go +++ b/platformapi/jdeclpapi/jdeclpapi.go @@ -27,10 +27,11 @@ const ( // CustomerCode2 = "028K588716" - state = "1212" - orderType10 = "10" //订单号类型(10:代表ECLP订单号, 20:代表商家订单号) - orderType20 = "20" - SalePlatformSource = "6" + state = "1212" + orderType10 = "10" //订单号类型(10:代表ECLP订单号, 20:代表商家订单号) + orderType20 = "20" + SalePlatformSource = "6" + SalePlatSourceDelivery = "0030001" SoStatusCode10010 = "10010" //订单初始化 SoStatusCode10022 = "10022" //暂停 @@ -157,6 +158,85 @@ type QueryStockResult struct { GoodsName string `json:"goodsName"` } +type WaybillReceiveParam struct { + SalePlat string `json:"salePlat"` //是 无 销售平台 + CustomerCode string `json:"customerCode"` //是 无 商家编码 + OrderID string `json:"orderId"` //是 无 订单号 + // ThrOrderID string `json:"thrOrderId"` //否 无 销售平台订单号(例如京东订单号或天猫订单号等等。总长度不要超过100。如果有多个单号,用英文,间隔。例如:7898675,7898676) + SenderName string `json:"senderName"` //是 无 寄件人姓名,说明:不能为生僻字 + SenderAddress string `json:"senderAddress"` //是 无 寄件人地址,说明:不能为生僻字 + // SenderTel string `json:"senderTel"` //否 无 寄件人电话 + // SenderMobile string `json:"senderMobile"` //否 无 寄件人手机(寄件人电话、手机至少有一个不为空) + // SenderPostcode string `json:"senderPostcode"` //否 100000 寄件人邮编,长度:6位 + ReceiveName string `json:"receiveName"` //是 无 收件人名称,说明:不能为生僻字 + ReceiveAddress string `json:"receiveAddress"` //是 无 收件人地址,说明:不能为生僻字 + // Province string `json:"province"` //否 无 收件人省 + // City string `json:"city"` //否 无 收件人市 + // County string `json:"county"` //否 无 收件人县 + // Town string `json:"town"` //否 无 收件人镇 + // ProvinceID int `json:"provinceId"` //否 无 收件人省编码 + // CityID int `json:"cityId"` //否 无 收件人市编码 + // CountyID int `json:"countyId"` //否 无 收件人县编码 + // TownID int `json:"townId"` //否 无 收件人镇编码 + // SiteType int `json:"siteType"` //否 无 站点类型 + // SiteID int `json:"siteId"` //否 无 站点编码 + // SiteName string `json:"siteName"` //否 无 站点名称 + // ReceiveTel string `json:"receiveTel"` //否 无 收件人电话 + // ReceiveMobile string `json:"receiveMobile"` //否 无 收件人手机号(收件人电话、手机至少有一个不为空) + // Postcode string `json:"postcode"` //否 100000 收件人邮编,长度:6 + PackageCount int `json:"packageCount"` //是 无 包裹数(大于0,小于1000) + Weight int `json:"weight"` //是 2.5 重量(单位:kg,保留小数点后两位) + // VloumLong int `json:"vloumLong"` //否 无 包裹长(单位:cm,保留小数点后两位) + // VloumWidth int `json:"vloumWidth"` //否 无 包裹宽(单位:cm,保留小数点后两位) + // VloumHeight int `json:"vloumHeight"` //否 无 包裹高(单位:cm,保留小数点后两位) + Vloumn int `json:"vloumn"` //是 10000 体积(单位:cm3,保留小数点后两位) + // Description string `json:"description"` //否 无 商品描述 + // CollectionValue int `json:"collectionValue"` //否 1 是否代收货款(是:1,否:0。不填或者超出范围,默认是0) + // CollectionMoney int `json:"collectionMoney"` //否 98.00 代收货款金额(保留小数点后两位) + // GuaranteeValue int `json:"guaranteeValue"` //否 1 是否保价(是:1,否:0。不填或者超出范围,默认是0) + // GuaranteeValueAmount int `json:"guaranteeValueAmount"` //否 100.00 保价金额(保留小数点后两位) + // SignReturn int `json:"signReturn"` //否 1 签单返还(签单返还类型:0 不返单,1 普通返单,2 校验身份返单,3 电子签返单,4 电子返单+普通返单) + // Aging int `json:"aging"` //否 1 时效(普通:1,工作日:2,非工作日:3,晚间:4。O2O一小时达:5。O2O定时达:6。不填或者超出范围,默认是1) + // TransType int `json:"transType"` //否 1 运输类型(陆运:1,航空:2。不填或者超出范围,默认是1) + // Remark string `json:"remark"` //否 无 运单备注,长度:20,说明:打印面单时备注内容也会显示在快递面单上 + // GoodsType int `json:"goodsType"` //否 无 配送业务类型( 1:普通,3:填仓,4:特配,6:控温,7:冷藏,8:冷冻,9:深冷)默认是1 + // OrderType int `json:"orderType"` //否 无 运单类型。(普通外单:0,O2O外单:1)默认为0 + // ShopCode string `json:"shopCode"` //否 无 门店编码(只O2O运单需要传,普通运单不需要传) + // OrderSendTime string `json:"orderSendTime"` //否 2014 09 18 08:30:00 预约配送时间(格式:yyyy MM dd HH:mm:ss) + // WarehouseCode string `json:"warehouseCode"` //否 无 发货仓编码 + // AreaProvID int `json:"areaProvId"` //否 无 接货省ID + // AreaCityID int `json:"areaCityId"` //否 无 接货市ID + // ShipmentStartTime time.Time `json:"shipmentStartTime"` //否 1 配送起始时间 + // ShipmentEndTime time.Time `json:"shipmentEndTime"` //否 1 配送结束时间 + // Idint string `json:"idint"` //否 无 身份证号 + // AddedService string `json:"addedService"` //否 无 扩展服务 + // ExtendField1 string `json:"extendField1"` //否 无 扩展字段1 + // ExtendField2 string `json:"extendField2"` //否 无 扩展字段2 + // ExtendField3 string `json:"extendField3"` //否 无 扩展字段3 + // ExtendField4 int `json:"extendField4"` //否 无 扩展字段4 + // ExtendField5 int `json:"extendField5"` //否 无 扩展字段5 + // SenderCompany string `json:"senderCompany"` //否 北京市大兴区亦庄经济开发区京东大厦 寄件人公司,长度:50,说明:不能为生僻字 + // ReceiveCompany string `json:"receiveCompany"` //否 北京市大兴区亦庄经济开发区京东大厦 收件人公司,长度:50,说明:不能为生僻字 + // Goods string `json:"goods"` //否 服装、3C等 托寄物名称,长度:200,说明:为避免托运物品在铁路、航空安检中被扣押,请务必下传商品类目或名称,例如:服装、3C等 + // GoodsCount int `json:"goodsCount"` //否 无 寄托物数量 + // PromiseTimeType int `json:"promiseTimeType"` //否 无 产品类型(1:特惠送 2:特快送 4:城际闪送 5:同城当日达 6:次晨达 7:微小件 8: 生鲜专送 16:生鲜特快 17、生鲜特惠 21:特惠小包) + // Freight int `json:"freight"` //否 无 运费 + // PickUpStartTime time.Time `json:"pickUpStartTime"` //否 1 预约取件开始时间 + // PickUpEndTime time.Time `json:"pickUpEndTime"` //否 1 预约取件结束时间 + // UnpackingInspection string `json:"unpackingInspection"` //否 无 开箱验货标识 + // BoxCode []string `json:"boxCode"` //否 无 商家箱号,多个箱号请用逗号分隔,例如三个箱号为:a123,b456,c789 + // FileURL string `json:"fileUrl"` //否 无 文件url +} + +type CancelWayBillParam struct { + // UserPin string `json:"userPin"` //否 pin 用户唯一标识,与下单一致可不填写 + WaybillCode string `json:"waybillCode"` //是 VA12345678 运单号 + CustomerCode string `json:"customerCode"` //是 010K00000 商家编码 + Source string `json:"source"` //是 JOS 来源 + CancelReason string `json:"cancelReason"` //是 客户取消 取消原因 + OperatorName string `json:"operatorName"` //是 张三 操作人 +} + func New(accessToken, appKey, appSecret string, config ...*platformapi.APIConfig) *API { curConfig := platformapi.DefAPIConfig if len(config) > 0 { @@ -329,3 +409,17 @@ func (a *API) QueryStock(goodsNo string) (queryStockResult []*QueryStockResult, } return queryStockResult, err } + +//京东物流接单接口 +//https://open.jd.com/home/home#/doc/api?apiCateId=64&apiId=2122&apiName=jingdong.ldop.waybill.receive +func (a *API) WaybillReceive(waybillReceiveParam *WaybillReceiveParam) (err error) { + _, err = a.AccessAPI("jingdong.ldop.waybill.receive", prodURL, utils.Struct2FlatMap(waybillReceiveParam)) + return err +} + +//京东物流取消接口 +//https://open.jd.com/home/home#/doc/api?apiCateId=75&apiId=3482&apiName=jingdong.ldop.delivery.provider.cancelWayBill +func (a *API) CancelWayBill(cancelWayBillParam *CancelWayBillParam) (err error) { + _, err = a.AccessAPI("jingdong.ldop.delivery.provider.cancelWayBill", prodURL, utils.Struct2FlatMap(cancelWayBillParam)) + return err +} diff --git a/platformapi/jdeclpapi/jdeclpapi_test.go b/platformapi/jdeclpapi/jdeclpapi_test.go index cb364c20..dcd3bb00 100644 --- a/platformapi/jdeclpapi/jdeclpapi_test.go +++ b/platformapi/jdeclpapi/jdeclpapi_test.go @@ -2,8 +2,10 @@ package jdeclpapi import ( "fmt" + "math" "regexp" "testing" + "time" "git.rosy.net.cn/baseapi/utils" @@ -91,6 +93,39 @@ func TestQueryStock(t *testing.T) { t.Log(utils.Format4Output(result, false)) } +func TestWaybillReceive(t *testing.T) { + err := api.WaybillReceive(&WaybillReceiveParam{ + SalePlat: SalePlatSourceDelivery, + CustomerCode: CustomerCode, + OrderID: utils.GetUUID(), + SenderName: "测试", + SenderAddress: "测试地址1", + ReceiveName: "测试", + ReceiveAddress: "测试地址1", + PackageCount: 1, + Weight: 1, + Vloumn: 10000, + }) + if err != nil { + t.Fatal(err) + } + // t.Log(utils.Format4Output(result, false)) +} + +func TestCancelWayBill(t *testing.T) { + err := api.CancelWayBill(&CancelWayBillParam{ + WaybillCode: "11", + CustomerCode: CustomerCode, + Source: "JOS", + CancelReason: "测试", + OperatorName: "jxadmin", + }) + if err != nil { + t.Fatal(err) + } + // t.Log(utils.Format4Output(result, false)) +} + type JxOrderInfo struct { BuyerComment string `json:"buyerComment"` StoreID int `json:"storeID"` @@ -137,9 +172,9 @@ func TestAA(t *testing.T) { var skus []*JxSkuInfo weight := 0 sku1 := &JxSkuInfo{ - SkuID: 6039387, - Weight: 1400, - Count: 2, + SkuID: 6039507, + Weight: 2620, + Count: 1, } skus = append(skus, sku1) weight += sku1.Count * sku1.Weight @@ -151,9 +186,9 @@ func TestAA(t *testing.T) { skus = append(skus, sku2) weight += sku2.Count * sku2.Weight sku3 := &JxSkuInfo{ - SkuID: 6039381, - Weight: 280, - Count: 4, + SkuID: 6039393, + Weight: 2540, + Count: 1, } skus = append(skus, sku3) weight += sku3.Count * sku3.Weight @@ -214,59 +249,6 @@ func tryToSplitMatterOrder(jxOrder *JxOrderInfo) (outOrders []*JxOrderInfo, frei return outOrders, freightPrice, err } -func loop(weightList []*JxSkuInfo2, jxOrder *JxOrderInfo, flag bool) (outOrder *JxOrderInfo) { - outOrder = &JxOrderInfo{} - outOrder.StoreID = jxOrder.StoreID - sum5 := 0 - sum3 := 0 - for i := 0; i < len(weightList); i++ { - if flag { - if weightList[i].Weight+sum5 <= 5000 { - sum5 += weightList[i].Weight - weightList[i].GroupSign = true - if len(outOrder.Skus) > 0 { - for _, v := range outOrder.Skus { - if v.SkuID == weightList[i].SkuID { - v.Count++ - } else { - outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightList[i])) - } - } - } else { - outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightList[i])) - } - } else { - if sum5 >= 5000 { - break - } - continue - } - } else { - if weightList[i].Weight+sum3 <= 3000 { - sum3 += weightList[i].Weight - weightList[i].GroupSign = true - if len(outOrder.Skus) > 0 { - for _, v := range outOrder.Skus { - if v.SkuID == weightList[i].SkuID { - v.Count++ - } else { - outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightList[i])) - } - } - } else { - outOrder.Skus = append(outOrder.Skus, jxOrderChange(weightList[i])) - } - } else { - if sum3 >= 3000 { - break - } - continue - } - } - } - return outOrder -} - func jxOrderChange(sku2 *JxSkuInfo2) *JxSkuInfo { sku := &JxSkuInfo{} sku.Count = 1 @@ -291,7 +273,7 @@ func loop2(weightList []*JxSkuInfo2, storeID int, weight *int) (outOrder *JxOrde outOrder = &JxOrderInfo{} outOrder.StoreID = storeID sum3 := 0 - if *weight <= 5000 { + if *weight <= 4500 { for i := 0; i < len(weightList); i++ { weightList[i].GroupSign = true outOrder.Weight += weightList[i].Weight @@ -341,3 +323,92 @@ func loop2(weightList []*JxSkuInfo2, storeID int, weight *int) (outOrder *JxOrde } return outOrder } + +type OrderSku struct { + ID int64 `orm:"column(id)" json:"-"` + VendorOrderID string `orm:"column(vendor_order_id);size(48)" json:"vendorOrderID"` + VendorID int `orm:"column(vendor_id)" json:"vendorID"` + StoreSubID int `orm:"column(store_sub_id)" json:"storeSubID"` // EarningActID,当前这个字段被当成结算活动ID用 + StoreSubName string `orm:"size(64)" json:"storeSubName"` // 当前这个字段被用作vendorActType + Count int `json:"count"` + VendorSkuID string `orm:"column(vendor_sku_id);size(48)" json:"vendorSkuID"` + SkuID int `orm:"column(sku_id)" json:"skuID"` // 外部系统里记录的 jxskuid + JxSkuID int `orm:"column(jx_sku_id)" json:"jxSkuID"` // 根据VendorSkuID在本地系统里查询出来的 jxskuid + SkuName string `orm:"size(255)" json:"skuName"` + ShopPrice int64 `json:"shopPrice"` // 京西价 + VendorPrice int64 `json:"vendorPrice"` // 平台价 + SalePrice int64 `json:"salePrice"` // 售卖价 + EarningPrice int64 `json:"earningPrice"` // 活动商品设置,结算给门店老板的钱,如果结算活动ID为0,是按结算比例算的,否则就是结算表中的值 + Weight int `json:"weight"` // 单位为克 + SkuType int `json:"skuType"` // 当前如果为gift就为1,否则缺省为0 + PromotionType int `json:"promotionType"` // todo 当前是用于记录京东的PromotionType(生成jxorder用),没有做转换 + OrderCreatedAt time.Time `orm:"type(datetime);index" json:"-"` // 分区考虑 +} + +type tSkuCountPrice struct { + Count int `json:"count"` + SalePrice int64 `json:"salePrice"` +} + +func TestCC(t *testing.T) { + var orderSkus = []*OrderSku{ + &OrderSku{ + SkuID: 30783, + Count: 1, + ShopPrice: 438, + SalePrice: 390, + EarningPrice: 312, + }, + &OrderSku{ + SkuID: 30783, + Count: 2, + ShopPrice: 438, + SalePrice: 490, + EarningPrice: 312, + }, + &OrderSku{ + SkuID: 32914, + Count: 2, + ShopPrice: 400, + SalePrice: 660, + EarningPrice: 320, + }, + &OrderSku{ + SkuID: 32914, + Count: 1, + ShopPrice: 400, + SalePrice: 650, + EarningPrice: 320, + }, + } + var skuMultiCountMap = make(map[int][]*tSkuCountPrice) + for _, v := range orderSkus { + skuMultiCountMap[v.SkuID] = append(skuMultiCountMap[v.SkuID], &tSkuCountPrice{ + Count: v.Count, + SalePrice: v.SalePrice, + }) + } + var storePayPercentage int = 70 + for _, v := range orderSkus { + if v.EarningPrice > 0 { + if len(skuMultiCountMap[v.SkuID]) > 1 { + var price = 0 + for _, vv := range skuMultiCountMap[v.SkuID] { + if int(vv.SalePrice) > price { + price = int(vv.SalePrice) + } + } + if price == int(v.SalePrice) { + var earningPrice = 0 + if v.ShopPrice < v.SalePrice { + earningPrice = int(utils.Float64TwoInt64(math.Round(utils.Int2Float64(int(v.ShopPrice)) * utils.Int2Float64(storePayPercentage) / 100))) + } else { + earningPrice = int(utils.Float64TwoInt64(math.Round(utils.Int2Float64(int(v.SalePrice)) * utils.Int2Float64(storePayPercentage) / 100))) + } + v.EarningPrice = int64(earningPrice) + } + } + } + } + fmt.Println(utils.Format4Output(orderSkus, false)) +} diff --git a/platformapi/mtpsapi/mtpsapi.go b/platformapi/mtpsapi/mtpsapi.go index 7fb510ff..302ebd55 100644 --- a/platformapi/mtpsapi/mtpsapi.go +++ b/platformapi/mtpsapi/mtpsapi.go @@ -245,8 +245,8 @@ func (a *API) AccessAPI2(baseURL, action string, params map[string]interface{}) err = platformapi.AccessPlatformAPIWithRetry(a.client, func() *http.Request { request, _ := http.NewRequest(http.MethodPost, baseURL+"/"+action, strings.NewReader(params2.Encode())) - request.Header.Set("charset", "UTF-8") - request.Header.Set("Content-Type", "application/x-www-form-urlencoded") + request.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8") + request.Header.Set("Referer", "https://page.peisong.meituan.com/open/admin/poilist") if baseURL != mtpsAPIURL { a.FillRequestCookies(request) } diff --git a/platformapi/mtpsapi/mtpsapi_test.go b/platformapi/mtpsapi/mtpsapi_test.go index d06e2755..d6d1f5c9 100644 --- a/platformapi/mtpsapi/mtpsapi_test.go +++ b/platformapi/mtpsapi/mtpsapi_test.go @@ -25,7 +25,7 @@ func init() { // prod // api = New("3c0a05d464c247c19d7ec13accc78605", "b1M}9?:sTbsB[OF2gNORnN(|(iy9rB8(`7]|[wGLnbmt`evfM>E:A90DjHAW:UPE") - api.SetCookie("token", "M0p9VatZSeSHfrosD5IViAVl73IcA8mlcuHIV5sG6Zpv83a7JE0wY3t26aEhrrs_MR5gtLSFF1UIkt8HAjaXow") + api.SetCookie("token", "GsfR99YCT8leEBnY39YxPeWTJiSmetA3NGl8G8u1Mv29V4KLYIA9rH3fhw-uDL7VwM4jKPfNwH8D_vOPg3cRYg") } func handleError(t *testing.T, err error) { diff --git a/platformapi/mtpsapi/shop_page.go b/platformapi/mtpsapi/shop_page.go index 9ee49d58..e9357ac7 100644 --- a/platformapi/mtpsapi/shop_page.go +++ b/platformapi/mtpsapi/shop_page.go @@ -1,6 +1,10 @@ package mtpsapi -import "fmt" +import ( + "fmt" + + "git.rosy.net.cn/baseapi/utils" +) func (a *API) PagePoiUpdate(outerPoiID, contactName, contactPhone, contactEmail string) (err error) { if outerPoiID == "" || contactName == "" || contactPhone == "" || contactEmail == "" { @@ -12,7 +16,7 @@ func (a *API) PagePoiUpdate(outerPoiID, contactName, contactPhone, contactEmail "contactPhone": contactPhone, "contactEmail": contactEmail, } - _, err = a.AccessAPI2("https://peisong.meituan.com/api", "haikuiopen/haikui/open/partner/poi/update", params) + _, err = a.AccessAPI2("https://page.peisong.meituan.com/api", "haikuiopen/haikui/open/partner/poi/update", params) return err } @@ -21,3 +25,39 @@ func (a *API) GetAccountDetail() (err error) { _, err = a.AccessAPI2("https://peisong.meituan.com/api", "haikuiopen/haikui/open/partner/base/detail", params) return err } + +type GetStoreStatusResult struct { + PoiID int `json:"poiId"` + OuterPoiID string `json:"outerPoiId"` + AppkeyID int `json:"appkeyId"` + PoiName string `json:"poiName"` + CityID int `json:"cityId"` + CityName string `json:"cityName"` + ContactPhone string `json:"contactPhone"` + ContactName interface{} `json:"contactName"` + ContactEmail interface{} `json:"contactEmail"` + Address string `json:"address"` + AddressDetail interface{} `json:"addressDetail"` + OpenType int `json:"openType"` + CategoryID int `json:"categoryId"` + SecondCategoryID int `json:"secondCategoryId"` + PoiLat int `json:"poiLat"` + PoiLng int `json:"poiLng"` + SubBrandID int `json:"subBrandId"` + PoiType int `json:"poiType"` +} + +func (a *API) GetStoreStatus(poiName string) (getStoreStatusResult *GetStoreStatusResult, err error) { + params := map[string]interface{}{ + "poiName": poiName, + "openType": -1, + "cityId": -1, + "pageNum": 1, + "pageSize": 20, + } + result, err := a.AccessAPI2("https://page.peisong.meituan.com/api", "haikuiopen/haikui/open/partner/poi/search", params) + if err == nil { + utils.Map2StructByJson(result.Data, &getStoreStatusResult, false) + } + return getStoreStatusResult, err +} diff --git a/platformapi/mtpsapi/shop_page_test.go b/platformapi/mtpsapi/shop_page_test.go index eaf611cb..16c832e0 100644 --- a/platformapi/mtpsapi/shop_page_test.go +++ b/platformapi/mtpsapi/shop_page_test.go @@ -2,10 +2,12 @@ package mtpsapi import ( "testing" + + "git.rosy.net.cn/baseapi/utils" ) func TestPagePoiUpdate(t *testing.T) { - err := api.PagePoiUpdate("100082", "王海红", "16601189298", "727827081@qq.com") + err := api.PagePoiUpdate("666730", "任学梅", "15283376640", "feng.shi@rosy.net.cn") if err != nil { t.Fatal(err) } @@ -17,3 +19,11 @@ func TestGetAccountDetail(t *testing.T) { t.Fatal(err) } } + +func TestGetStoreStatus(t *testing.T) { + result, err := api.GetStoreStatus("肖坝路店") + if err != nil { + t.Fatal(err) + } + t.Log(utils.Format4Output(result, false)) +}