charge_bill_pay.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  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. gid "git.getensh.com/common/gopkgs/id"
  9. "property-garden/errors"
  10. "property-garden/impl/v1/charge_utils"
  11. dbmodel "property-garden/model"
  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 checkChargeBillPayParam(req *pb_v1.ChargeBillPayRequest) 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. }
  34. return nil
  35. }
  36. func chargeBillPayByBindIds(req *pb_v1.ChargeBillPayRequest, dbname string) (reply *pb_v1.ChargeBillPayReply, err error) {
  37. reply = &pb_v1.ChargeBillPayReply{}
  38. bill := dbmodel.NewChargeBill(dbname)
  39. where := map[string]interface{}{
  40. "charge_bind_id in": req.BindIds,
  41. }
  42. chargeInfoM, err := charge_utils.GetAllChargeInfos(dbname)
  43. if err != nil {
  44. return nil, err
  45. }
  46. db := database.DB().Begin()
  47. defer func() {
  48. if err != nil {
  49. db.Rollback()
  50. }
  51. }()
  52. list, err := bill.List(db, where, nil, -1, -1, "")
  53. if err != nil {
  54. return nil, errors.DataBaseError
  55. }
  56. amount := int64(0)
  57. billIds := []string{}
  58. billIdsInt := []int64{}
  59. objName := ""
  60. orders := []string{}
  61. for i, v := range list {
  62. objName = v.ObjName
  63. chargeInfo := chargeInfoM[v.ChargeId]
  64. billIdsInt = append(billIdsInt, v.ID)
  65. amount += v.Amount
  66. list[i].LateFee, _ = charge_utils.GetLateFee(v.Amount, v.ChargeEnd, &chargeInfo)
  67. amount += list[i].LateFee
  68. if v.OrderId != "" {
  69. orders = append(orders, v.OrderId)
  70. }
  71. }
  72. isPaying := false
  73. isPaying, err = charge_utils.IsOrderPaying(orders, dbname, db)
  74. if err != nil {
  75. return nil, err
  76. }
  77. if isPaying {
  78. return nil, status.Error(10003, "无法支付,有订单正在支付中")
  79. }
  80. if amount != req.ShouldPayAmount {
  81. return nil, status.Error(10003, "应缴错误")
  82. }
  83. if req.ShouldPayAmount != req.PayAmount && req.Comment == "" {
  84. //return nil, status.Error(10003, "应缴金额与实缴金额不一致,需添加备注")
  85. }
  86. //生成订单
  87. orderId, err := GenerateOrderId(req.GardenId, OrderTypeLife)
  88. if err != nil {
  89. return nil, err
  90. }
  91. now := time.Now()
  92. for i, _ := range list {
  93. list[i].ID = 0
  94. list[i].Comment = req.Comment
  95. list[i].PayTime = now.Unix()
  96. list[i].PayMode = 1
  97. list[i].OrderId = orderId
  98. list[i].PayType = req.PayType
  99. list[i].Status = charge_utils.PayStatusPayed
  100. }
  101. bill.SetTablePayed(dbname)
  102. err = bill.InsertMulti(db, &list)
  103. if err != nil {
  104. return nil, errors.DataBaseError
  105. }
  106. for _, v := range list {
  107. billIds = append(billIds, fmt.Sprintf("%v", v.ID))
  108. }
  109. order := dbmodel.TChargeOrder{
  110. OrderId: orderId,
  111. Comment: req.Comment,
  112. Amount: req.ShouldPayAmount,
  113. PayAmount: req.PayAmount,
  114. PayType: req.PayType,
  115. CreatedAt: now,
  116. Uid: 0,
  117. PackageId: 0,
  118. PrepayId: "",
  119. TransactionId: "",
  120. Status: charge_utils.PayStatusPayed,
  121. PayingDesc: "生活缴费",
  122. PayTime: now.Unix(),
  123. BillIds: strings.Join(billIds, ","),
  124. ObjName: objName,
  125. }
  126. order.SetTable(dbname)
  127. err = order.Insert(db)
  128. if err != nil {
  129. return nil, errors.DataBaseError
  130. }
  131. bill.SetTable(dbname)
  132. where = map[string]interface{}{
  133. "id in": billIdsInt,
  134. }
  135. err = bill.Delete(db, where)
  136. if err != nil {
  137. return nil, errors.DataBaseError
  138. }
  139. if err = charge_utils.CompanyDealIncrease(req.GardenId, order.PayAmount, order.PayTime); err != nil {
  140. return nil, err
  141. }
  142. db.Commit()
  143. reply.OrderId = orderId
  144. return reply, nil
  145. }
  146. func chargeBillPayByBillIds(req *pb_v1.ChargeBillPayRequest, dbname string) (reply *pb_v1.ChargeBillPayReply, err error) {
  147. reply = &pb_v1.ChargeBillPayReply{}
  148. chargeInfoM, err := charge_utils.GetAllChargeInfos(dbname)
  149. if err != nil {
  150. return nil, err
  151. }
  152. bill := dbmodel.NewChargeBill(dbname)
  153. where := map[string]interface{}{
  154. "id in": req.BillIds,
  155. }
  156. db := database.DB().Begin()
  157. defer func() {
  158. if err != nil {
  159. db.Rollback()
  160. }
  161. }()
  162. list, err := bill.List(db, where, nil, -1, -1, "")
  163. if err != nil {
  164. return nil, errors.DataBaseError
  165. }
  166. if len(list) == 0 {
  167. return nil, status.Error(10003, "没有账单")
  168. }
  169. amount := int64(0)
  170. billIds := []string{}
  171. orders := []string{}
  172. for i, v := range list {
  173. chargeInfo := chargeInfoM[v.ChargeId]
  174. amount += v.Amount
  175. list[i].LateFee, _ = charge_utils.GetLateFee(v.Amount, v.ChargeEnd, &chargeInfo)
  176. amount += list[i].LateFee
  177. if v.OrderId != "" {
  178. orders = append(orders, v.OrderId)
  179. }
  180. }
  181. isPaying := false
  182. isPaying, err = charge_utils.IsOrderPaying(orders, dbname, db)
  183. if err != nil {
  184. return nil, err
  185. }
  186. if isPaying {
  187. return nil, status.Error(10003, "无法支付,有订单正在支付中")
  188. }
  189. if amount != req.ShouldPayAmount {
  190. return nil, status.Error(10003, "应缴错误")
  191. }
  192. if req.ShouldPayAmount != req.PayAmount && req.Comment == "" {
  193. //return nil, status.Error(10003, "应缴金额与实缴金额不一致,需添加备注")
  194. }
  195. // 生成订单
  196. orderId, err := GenerateOrderId(req.GardenId, OrderTypeLife)
  197. if err != nil {
  198. return nil, err
  199. }
  200. now := time.Now()
  201. for i, _ := range list {
  202. list[i].ID = 0
  203. list[i].Comment = req.Comment
  204. list[i].PayTime = now.Unix()
  205. list[i].PayMode = 1
  206. list[i].OrderId = orderId
  207. list[i].PayType = req.PayType
  208. list[i].Status = charge_utils.PayStatusPayed
  209. }
  210. bill.SetTablePayed(dbname)
  211. err = bill.InsertMulti(db, &list)
  212. if err != nil {
  213. return nil, errors.DataBaseError
  214. }
  215. for _, v := range list {
  216. billIds = append(billIds, fmt.Sprintf("%v", v.ID))
  217. }
  218. order := dbmodel.TChargeOrder{
  219. OrderId: orderId,
  220. Comment: req.Comment,
  221. Amount: req.ShouldPayAmount,
  222. PayAmount: req.PayAmount,
  223. PayType: req.PayType,
  224. CreatedAt: now,
  225. Uid: 0,
  226. PackageId: 0,
  227. PrepayId: "",
  228. TransactionId: "",
  229. Status: charge_utils.PayStatusPayed,
  230. PayingDesc: "生活缴费",
  231. PayTime: now.Unix(),
  232. BillIds: strings.Join(billIds, ","),
  233. ObjName: list[0].ObjName,
  234. }
  235. order.SetTable(dbname)
  236. err = order.Insert(db)
  237. if err != nil {
  238. return nil, errors.DataBaseError
  239. }
  240. bill.SetTable(dbname)
  241. where = map[string]interface{}{
  242. "id in": req.BillIds,
  243. }
  244. err = bill.Delete(db, where)
  245. if err != nil {
  246. return nil, errors.DataBaseError
  247. }
  248. if err = charge_utils.CompanyDealIncrease(req.GardenId, order.PayAmount, order.PayTime); err != nil {
  249. return nil, err
  250. }
  251. db.Commit()
  252. reply.OrderId = orderId
  253. return reply, nil
  254. }
  255. const (
  256. OrderTypeLife = 5
  257. )
  258. func GenerateOrderId(gardenId int64, orderType int) (string, error) {
  259. str := fmt.Sprintf("%d%07d-", orderType, gardenId)
  260. tmp, err := gid.GetUniqueID()
  261. if err != nil {
  262. return "", status.Error(10003, "订单号生成失败:"+err.Error())
  263. }
  264. str += fmt.Sprintf("%d", tmp)
  265. return str, nil
  266. }
  267. func ChargeBillPay(ctx context.Context, req *pb_v1.ChargeBillPayRequest) (reply *pb_v1.ChargeBillPayReply, err error) {
  268. reply = &pb_v1.ChargeBillPayReply{}
  269. // 捕获各个task中的异常并返回给调用者
  270. defer func() {
  271. if r := recover(); r != nil {
  272. err = fmt.Errorf("%+v", r)
  273. e := &status.Status{}
  274. if er := json.Unmarshal([]byte(err.Error()), e); er != nil {
  275. logger.Error("err",
  276. zap.String("system_err", err.Error()),
  277. zap.Stack("stacktrace"))
  278. }
  279. }
  280. }()
  281. // 参数检查
  282. err = checkChargeBillPayParam(req)
  283. if err != nil {
  284. return nil, err
  285. }
  286. dbname := utils.GetGardenDbName(req.GardenId)
  287. if len(req.BillIds) > 0 {
  288. return chargeBillPayByBillIds(req, dbname)
  289. }
  290. return chargeBillPayByBindIds(req, dbname)
  291. }