charge_bill_pay_by_household.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. // Copyright 2019 getensh.com. All rights reserved.
  2. // Use of this source code is governed by getensh.com.
  3. package charge
  4. import (
  5. "context"
  6. "encoding/json"
  7. "fmt"
  8. "property-garden/errors"
  9. "property-garden/impl/v1/charge_utils"
  10. dbmodel "property-garden/model"
  11. "property-garden/pb"
  12. pb_v1 "property-garden/pb/v1"
  13. "property-garden/utils"
  14. "strings"
  15. "time"
  16. "git.getensh.com/common/gopkgs/database"
  17. "git.getensh.com/common/gopkgs/logger"
  18. "go.uber.org/zap"
  19. "google.golang.org/grpc/status"
  20. )
  21. func checkChargeBillPayByHouseholdParam(req *pb_v1.ChargeBillPayByHouseholdRequest) error {
  22. switch {
  23. case req.GardenId == 0:
  24. return status.Error(10003, "小区不能为空")
  25. case req.PayType == 0:
  26. return status.Error(10003, "缴费方式不能为空")
  27. case req.ShouldPayAmount == 0:
  28. return status.Error(10003, "应缴金额不能为空")
  29. case req.PayAmount == 0:
  30. return status.Error(10003, "实缴金额不能为空")
  31. case len(req.BillIds) == 0 && len(req.BindIds) == 0:
  32. return status.Error(10003, "缴费对象不能为空")
  33. case req.HouseholdUid == 0 && !req.Native:
  34. return status.Error(10003, "住户id不能为空")
  35. }
  36. return nil
  37. }
  38. func ThirdpartyPay(openId string, inputIp string, amount int64, orderId string, product string, mchid string, native bool) (string, string, string, error) {
  39. mreq := pb_v1.WxAppletPrepayRequest{
  40. Order: orderId,
  41. Product: product,
  42. OpenId: openId,
  43. Amount: amount,
  44. InputIp: inputIp,
  45. MchId: mchid,
  46. Native: native,
  47. }
  48. mreply, err := pb.Thirdparty.WxAppletPrepay(context.Background(), &mreq)
  49. if err != nil {
  50. return "", "", "", err
  51. }
  52. return mreply.PrepayId, mreply.Prepay, mreply.CodeUrl, nil
  53. }
  54. func householdChargeBillPayByBindIds(req *pb_v1.ChargeBillPayByHouseholdRequest, dbname string, mchId string) (reply *pb_v1.ChargeBillPayByHouseholdReply, err error) {
  55. reply = &pb_v1.ChargeBillPayByHouseholdReply{}
  56. bill := dbmodel.NewChargeBill(dbname)
  57. where := map[string]interface{}{
  58. "charge_bind_id in": req.BindIds,
  59. }
  60. chargeInfoM, err := charge_utils.GetAllChargeInfos(dbname)
  61. if err != nil {
  62. return nil, err
  63. }
  64. db := database.DB().Begin()
  65. defer func() {
  66. if err != nil {
  67. db.Rollback()
  68. }
  69. }()
  70. list, err := bill.List(db, where, nil, -1, -1, "")
  71. if err != nil {
  72. return nil, errors.DataBaseError
  73. }
  74. amount := int64(0)
  75. billIds := []string{}
  76. billIdsInt := []int64{}
  77. objName := ""
  78. productM := map[string]bool{}
  79. lateFeeBool := false
  80. orders := []string{}
  81. for i, v := range list {
  82. billIds = append(billIds, fmt.Sprintf("%v", v.ID))
  83. productM[charge_utils.ChargeTypeM[v.ChargeType]] = true
  84. objName = v.ObjName
  85. chargeInfo := chargeInfoM[v.ChargeId]
  86. billIdsInt = append(billIdsInt, v.ID)
  87. amount += v.Amount
  88. list[i].LateFee, _ = charge_utils.GetLateFee(v.Amount, v.ChargeEnd, &chargeInfo)
  89. amount += list[i].LateFee
  90. if list[i].LateFee > 0 {
  91. lateFeeBool = true
  92. }
  93. if v.OrderId != "" {
  94. orders = append(orders, v.OrderId)
  95. }
  96. }
  97. isPaying := false
  98. isPaying, err = charge_utils.IsOrderPaying(orders, dbname, db)
  99. if err != nil {
  100. return nil, err
  101. }
  102. if isPaying {
  103. return nil, status.Error(10003, "无法支付,有订单正在支付中")
  104. }
  105. product := ""
  106. for k, _ := range productM {
  107. product = product + k + ";"
  108. }
  109. if amount != req.ShouldPayAmount {
  110. return nil, status.Error(10003, "应缴错误")
  111. }
  112. if req.ShouldPayAmount != req.PayAmount && req.Comment == "" {
  113. return nil, status.Error(10003, "应缴金额与实缴金额不一致,需添加备注")
  114. }
  115. //生成订单
  116. orderId, err := GenerateOrderId(req.GardenId, OrderTypeLife)
  117. if err != nil {
  118. return nil, err
  119. }
  120. //调用三方预支付
  121. thirdPrepayId, thirdPrepayInfo, codeUrl, err := ThirdpartyPay(req.OpenId, req.InputIp, req.ShouldPayAmount, orderId, product, mchId, req.Native)
  122. if err != nil {
  123. return nil, err
  124. }
  125. // 更新订单状态
  126. now := time.Now()
  127. values := map[string]interface{}{
  128. "comment": req.Comment,
  129. "pay_time": now.Unix(),
  130. "pay_mode": 1,
  131. "uid": req.HouseholdUid,
  132. "order_id": orderId,
  133. "pay_type": req.PayType,
  134. "status": charge_utils.PayStatusUnPay,
  135. }
  136. // 没有滞纳金批量更新
  137. if !lateFeeBool {
  138. bill.SetTable(dbname)
  139. err = bill.Update(db, where, values)
  140. if err != nil {
  141. return nil, errors.DataBaseError
  142. }
  143. } else {
  144. // 有滞纳金逐个更新
  145. for _, v := range list {
  146. values["late_fee"] = v.LateFee
  147. where = map[string]interface{}{
  148. "id": v.ID,
  149. }
  150. bill.SetTable(dbname)
  151. err = bill.Update(db, where, values)
  152. if err != nil {
  153. return nil, errors.DataBaseError
  154. }
  155. }
  156. }
  157. // 插入订单
  158. order := dbmodel.TChargeOrder{
  159. OrderId: orderId,
  160. Comment: req.Comment,
  161. Amount: req.ShouldPayAmount,
  162. PayAmount: req.PayAmount,
  163. PayType: req.PayType,
  164. CreatedAt: now,
  165. Uid: req.HouseholdUid,
  166. PackageId: 0,
  167. PrepayId: thirdPrepayId,
  168. TransactionId: "",
  169. Status: charge_utils.PayStatusUnPay,
  170. PayingDesc: "生活缴费",
  171. PayTime: now.Unix(),
  172. BillIds: strings.Join(billIds, ","),
  173. ObjName: objName,
  174. }
  175. order.SetTable(dbname)
  176. err = order.Insert(db)
  177. if err != nil {
  178. return nil, errors.DataBaseError
  179. }
  180. db.Commit()
  181. reply.OrderId = orderId
  182. reply.PrepayInfo = thirdPrepayInfo
  183. reply.CodeUrl = codeUrl
  184. return reply, nil
  185. }
  186. func householdChargeBillPayByBillIds(req *pb_v1.ChargeBillPayByHouseholdRequest, dbname string, mchId string) (reply *pb_v1.ChargeBillPayByHouseholdReply, err error) {
  187. reply = &pb_v1.ChargeBillPayByHouseholdReply{}
  188. chargeInfoM, err := charge_utils.GetAllChargeInfos(dbname)
  189. if err != nil {
  190. return nil, err
  191. }
  192. bill := dbmodel.NewChargeBill(dbname)
  193. where := map[string]interface{}{
  194. "id in": req.BillIds,
  195. }
  196. db := database.DB().Begin()
  197. defer func() {
  198. if err != nil {
  199. db.Rollback()
  200. }
  201. }()
  202. list, err := bill.List(db, where, nil, -1, -1, "")
  203. if err != nil {
  204. return nil, errors.DataBaseError
  205. }
  206. if len(list) == 0 {
  207. return nil, status.Error(10003, "没有账单")
  208. }
  209. amount := int64(0)
  210. billIds := []string{}
  211. productM := map[string]bool{}
  212. lateFeeBool := false
  213. orders := []string{}
  214. for i, v := range list {
  215. billIds = append(billIds, fmt.Sprintf("%v", v.ID))
  216. productM[charge_utils.ChargeTypeM[v.ChargeType]] = true
  217. chargeInfo := chargeInfoM[v.ChargeId]
  218. amount += v.Amount
  219. list[i].LateFee, _ = charge_utils.GetLateFee(v.Amount, v.ChargeEnd, &chargeInfo)
  220. amount += list[i].LateFee
  221. if list[i].LateFee > 0 {
  222. lateFeeBool = true
  223. }
  224. if v.OrderId != "" {
  225. orders = append(orders, v.OrderId)
  226. }
  227. }
  228. isPaying := false
  229. isPaying, err = charge_utils.IsOrderPaying(orders, dbname, db)
  230. if err != nil {
  231. return nil, err
  232. }
  233. if isPaying {
  234. return nil, status.Error(10003, "无法支付,有订单正在支付中")
  235. }
  236. if amount != req.ShouldPayAmount {
  237. return nil, status.Error(10003, "应缴错误")
  238. }
  239. if req.ShouldPayAmount != req.PayAmount && req.Comment == "" {
  240. return nil, status.Error(10003, "应缴金额与实缴金额不一致,需添加备注")
  241. }
  242. product := ""
  243. for k, _ := range productM {
  244. product = product + k + ";"
  245. }
  246. // 生成订单
  247. orderId, err := GenerateOrderId(req.GardenId, OrderTypeLife)
  248. if err != nil {
  249. return nil, err
  250. }
  251. //调用三方预支付
  252. thirdPrepayId, thirdPrepayInfo, codeUrl, err := ThirdpartyPay(req.OpenId, req.InputIp, req.ShouldPayAmount, orderId, product, mchId, req.Native)
  253. if err != nil {
  254. return nil, err
  255. }
  256. // 更新订单状态
  257. now := time.Now()
  258. values := map[string]interface{}{
  259. "comment": req.Comment,
  260. "pay_time": now.Unix(),
  261. "pay_mode": 1,
  262. "uid": req.HouseholdUid,
  263. "order_id": orderId,
  264. "pay_type": req.PayType,
  265. "status": charge_utils.PayStatusUnPay,
  266. }
  267. // 没有滞纳金批量更新
  268. if !lateFeeBool {
  269. bill.SetTable(dbname)
  270. err = bill.Update(db, where, values)
  271. if err != nil {
  272. return nil, errors.DataBaseError
  273. }
  274. } else {
  275. // 有滞纳金逐个更新
  276. for _, v := range list {
  277. values["late_fee"] = v.LateFee
  278. where = map[string]interface{}{
  279. "id": v.ID,
  280. }
  281. bill.SetTable(dbname)
  282. err = bill.Update(db, where, values)
  283. if err != nil {
  284. return nil, errors.DataBaseError
  285. }
  286. }
  287. }
  288. order := dbmodel.TChargeOrder{
  289. OrderId: orderId,
  290. Comment: req.Comment,
  291. Amount: req.ShouldPayAmount,
  292. PayAmount: req.PayAmount,
  293. PayType: req.PayType,
  294. CreatedAt: now,
  295. Uid: req.HouseholdUid,
  296. PackageId: 0,
  297. PrepayId: thirdPrepayId,
  298. TransactionId: "",
  299. Status: charge_utils.PayStatusUnPay,
  300. PayingDesc: "生活缴费",
  301. PayTime: now.Unix(),
  302. BillIds: strings.Join(billIds, ","),
  303. ObjName: list[0].ObjName,
  304. }
  305. order.SetTable(dbname)
  306. err = order.Insert(db)
  307. if err != nil {
  308. return nil, errors.DataBaseError
  309. }
  310. db.Commit()
  311. reply.OrderId = orderId
  312. reply.PrepayInfo = thirdPrepayInfo
  313. reply.CodeUrl = codeUrl
  314. return reply, nil
  315. }
  316. func ChargeBillPayByHousehold(ctx context.Context, req *pb_v1.ChargeBillPayByHouseholdRequest) (reply *pb_v1.ChargeBillPayByHouseholdReply, err error) {
  317. reply = &pb_v1.ChargeBillPayByHouseholdReply{}
  318. // 捕获各个task中的异常并返回给调用者
  319. defer func() {
  320. if r := recover(); r != nil {
  321. err = fmt.Errorf("%+v", r)
  322. e := &status.Status{}
  323. if er := json.Unmarshal([]byte(err.Error()), e); er != nil {
  324. logger.Error("err",
  325. zap.String("system_err", err.Error()),
  326. zap.Stack("stacktrace"))
  327. }
  328. }
  329. }()
  330. // 参数检查
  331. err = checkChargeBillPayByHouseholdParam(req)
  332. if err != nil {
  333. return nil, err
  334. }
  335. mchId, err := charge_utils.CheckMchPayMode(req.GardenId)
  336. if err != nil {
  337. return nil, err
  338. }
  339. dbname := utils.GetGardenDbName(req.GardenId)
  340. if len(req.BillIds) > 0 {
  341. return householdChargeBillPayByBillIds(req, dbname, mchId)
  342. }
  343. return householdChargeBillPayByBindIds(req, dbname, mchId)
  344. }