charge_pre_pay.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  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. "git.getensh.com/common/gopkgs/database"
  9. "git.getensh.com/common/gopkgs/logger"
  10. "go.uber.org/zap"
  11. "google.golang.org/grpc/status"
  12. "gorm.io/gorm"
  13. "property-garden/errors"
  14. "property-garden/impl/v1/charge_utils"
  15. dbmodel "property-garden/model"
  16. pb_v1 "property-garden/pb/v1"
  17. "property-garden/utils"
  18. "time"
  19. )
  20. func checkChargePrePayParam(req *pb_v1.ChargePrePayRequest) error {
  21. switch {
  22. case req.GardenId == 0:
  23. return status.Error(10003, "小区不能为空")
  24. case req.BindId == 0:
  25. return status.Error(10003, "房屋/车位/车辆没有绑定费用")
  26. case req.Months == 0:
  27. return status.Error(10003, "月数不能为空")
  28. case req.ShouldPayAmount == 0:
  29. return status.Error(10003, "应收金额不能为空")
  30. case req.PayAmount == 0:
  31. return status.Error(10003, "实收金额不能为空")
  32. }
  33. return nil
  34. }
  35. type PrePayBillParam struct {
  36. ChargeInfo *dbmodel.TChargeConf
  37. BindInfo *dbmodel.TChargeBind
  38. Start int64
  39. End int64
  40. Amount int64
  41. Desc string
  42. Comment string
  43. PayTime int64
  44. Order string
  45. PayType int32
  46. }
  47. func PrePayBillAdd(param *PrePayBillParam, db *gorm.DB, dbname string) (int64, error) {
  48. bill := dbmodel.TChargeBill{
  49. ObjType: param.BindInfo.ObjType,
  50. ObjId: param.BindInfo.ObjId,
  51. ChargeId: param.BindInfo.ChargeId,
  52. ChargeBindId: param.BindInfo.ID,
  53. ChargeTimeType: param.ChargeInfo.ChargeTimeType,
  54. ChargeDesc: param.Desc,
  55. Comment: param.Comment,
  56. Amount: param.Amount,
  57. ChargePowerId: 0,
  58. ChargeType: param.ChargeInfo.ChargeType,
  59. ChargeName: param.ChargeInfo.ChargeName,
  60. Uid: 0,
  61. PayMode: 2,
  62. PackageId: 0,
  63. ChargeEnd: param.Start,
  64. ChargeStart: param.End,
  65. OrderId: param.Order,
  66. PayTime: param.PayTime,
  67. HouseId: param.BindInfo.HouseId,
  68. ObjName: param.BindInfo.ObjName,
  69. LateFee: 0,
  70. PayType: param.PayType,
  71. Status: charge_utils.PayStatusPayed,
  72. }
  73. bill.SetTablePayed(dbname)
  74. err := bill.Insert(db)
  75. if err != nil {
  76. return 0, errors.DataBaseError
  77. }
  78. return bill.ID, nil
  79. }
  80. func PrePayOrderAdd(req *pb_v1.ChargePrePayRequest, now time.Time, billId int64, orderId string, objName string, db *gorm.DB, dbname string, desc string) (dbmodel.TChargeOrder, error) {
  81. order := dbmodel.TChargeOrder{
  82. OrderId: orderId,
  83. Comment: req.Comment,
  84. Amount: req.ShouldPayAmount,
  85. PayAmount: req.PayAmount,
  86. PayType: req.PayType,
  87. CreatedAt: now,
  88. Uid: 0,
  89. PackageId: 0,
  90. PrepayId: "",
  91. TransactionId: "",
  92. Status: charge_utils.PayStatusPayed,
  93. PayingDesc: desc,
  94. PayTime: now.Unix(),
  95. BillIds: fmt.Sprintf("%d", billId),
  96. ObjName: objName,
  97. }
  98. order.SetTable(dbname)
  99. err := order.Insert(db)
  100. if err != nil {
  101. return order, errors.DataBaseError
  102. }
  103. return order, nil
  104. }
  105. func ChargePrePay(ctx context.Context, req *pb_v1.ChargePrePayRequest) (reply *pb_v1.ChargePrePayReply, err error) {
  106. reply = &pb_v1.ChargePrePayReply{}
  107. // 捕获各个task中的异常并返回给调用者
  108. defer func() {
  109. if r := recover(); r != nil {
  110. err = fmt.Errorf("%+v", r)
  111. e := &status.Status{}
  112. if er := json.Unmarshal([]byte(err.Error()), e); er != nil {
  113. logger.Error("err",
  114. zap.String("system_err", err.Error()),
  115. zap.Stack("stacktrace"))
  116. }
  117. }
  118. }()
  119. // 参数检查
  120. err = checkChargePrePayParam(req)
  121. if err != nil {
  122. return nil, err
  123. }
  124. dbname := utils.GetGardenDbName(req.GardenId)
  125. // 绑定关系信息
  126. bind := dbmodel.NewChargeBind(dbname)
  127. where := map[string]interface{}{
  128. "id": req.BindId,
  129. }
  130. err = bind.Find(database.DB(), where)
  131. if err != nil && err != gorm.ErrRecordNotFound {
  132. return nil, errors.DataBaseError
  133. }
  134. if bind.ID == 0 {
  135. return nil, errors.ErrRecordNotFound
  136. }
  137. // 是否有未缴账单
  138. bill := dbmodel.NewChargeBill(dbname)
  139. where = map[string]interface{}{
  140. "charge_bind_id": req.BindId,
  141. }
  142. count, err := bill.Count(database.DB(), where, nil)
  143. if err != nil {
  144. return nil, errors.DataBaseError
  145. }
  146. if count > 0 {
  147. return nil, status.Error(10003, "当前费用有未缴账单,请先缴清欠费")
  148. }
  149. // 费用信息
  150. chargeInfo := dbmodel.NewChargeConf(dbname)
  151. where = map[string]interface{}{
  152. "id": bind.ChargeId,
  153. }
  154. err = chargeInfo.Find(database.DB(), where)
  155. if err != nil && err != gorm.ErrRecordNotFound {
  156. return nil, errors.DataBaseError
  157. }
  158. if chargeInfo.ID == 0 {
  159. return nil, errors.ErrRecordNotFound
  160. }
  161. // 获取月数对应的应缴费用
  162. shouldPayAmount, _, chargeDesc := charge_utils.PrePayInfo(chargeInfo, bind, req.Months)
  163. if req.ShouldPayAmount != shouldPayAmount {
  164. return nil, status.Error(10003, "应缴费用不一致")
  165. }
  166. // 账单开始和截止月份
  167. start := int64(0)
  168. end := int64(0)
  169. if bind.BillLastTime > 0 {
  170. start = bind.BillLastTime
  171. end = time.Unix(bind.BillLastTime, 0).AddDate(0, int(req.Months), 0).Unix()
  172. } else {
  173. if bind.Start == 0 {
  174. return nil, status.Error(10003, "当前费用未生效,请先变更开始时间")
  175. }
  176. start = bind.Start
  177. end = time.Unix(start, 0).AddDate(0, int(req.Months), 0).Unix()
  178. }
  179. // 新增已缴账单
  180. now := time.Now()
  181. oid, err := GenerateOrderId(req.GardenId, OrderTypeLife)
  182. if err != nil {
  183. return nil, err
  184. }
  185. param := PrePayBillParam{
  186. ChargeInfo: chargeInfo,
  187. BindInfo: bind,
  188. Start: start,
  189. End: end,
  190. Amount: req.ShouldPayAmount,
  191. Desc: chargeDesc,
  192. Comment: req.Comment,
  193. PayTime: now.Unix(),
  194. Order: oid,
  195. PayType: req.PayType,
  196. }
  197. db := database.DB().Begin()
  198. defer func() {
  199. if err != nil {
  200. db.Rollback()
  201. }
  202. }()
  203. billId, err := PrePayBillAdd(&param, db, dbname)
  204. if err != nil {
  205. return nil, err
  206. }
  207. desc := ""
  208. if bind.ChargeType == charge_utils.ChargeTypeProperty {
  209. desc = "预存物业费"
  210. } else if bind.ChargeType == charge_utils.ChargeTypeSpace {
  211. desc = "预存车位管理费"
  212. }
  213. // 新增对应订单
  214. order, err := PrePayOrderAdd(req, now, billId, param.Order, bind.ObjName, db, dbname, desc)
  215. if err != nil {
  216. return nil, err
  217. }
  218. // 修改绑定关系里的账单截止时间戳
  219. where = map[string]interface{}{
  220. "id": req.BindId,
  221. }
  222. values := map[string]interface{}{
  223. "bill_last_time": end,
  224. }
  225. err = bind.Update(db, where, values)
  226. if err != nil {
  227. return nil, errors.DataBaseError
  228. }
  229. if err = charge_utils.CompanyDealIncrease(req.GardenId, order.PayAmount, order.PayTime); err != nil {
  230. return nil, err
  231. }
  232. db.Commit()
  233. reply.OrderId = param.Order
  234. return reply, nil
  235. }