123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- // Copyright 2019 getensh.com. All rights reserved.
- // Use of this source code is governed by getensh.com.
- package charge
- import (
- "context"
- "encoding/json"
- "fmt"
- "git.getensh.com/common/gopkgs/database"
- "git.getensh.com/common/gopkgs/logger"
- "go.uber.org/zap"
- "google.golang.org/grpc/status"
- "gorm.io/gorm"
- "property-garden/errors"
- "property-garden/impl/v1/charge_utils"
- dbmodel "property-garden/model"
- pb_v1 "property-garden/pb/v1"
- "property-garden/utils"
- "time"
- )
- func checkChargePrePayByHouseholdParam(req *pb_v1.ChargePrePayByHouseholdRequest) error {
- switch {
- case req.GardenId == 0:
- return status.Error(10003, "小区不能为空")
- case req.BindId == 0:
- return status.Error(10003, "房屋/车位/车辆没有绑定费用")
- case req.Months == 0:
- return status.Error(10003, "月数不能为空")
- case req.ShouldPayAmount == 0:
- return status.Error(10003, "应收金额不能为空")
- case req.PayAmount == 0:
- return status.Error(10003, "实收金额不能为空")
- case req.OpenId == "" || req.HouseholdUid == 0:
- return status.Error(10003, "用户信息不能为空")
- }
- return nil
- }
- type HouseholdPrePayBillParam struct {
- ChargeInfo *dbmodel.TChargeConf
- BindInfo *dbmodel.TChargeBind
- Start int64
- End int64
- Amount int64
- Desc string
- Comment string
- PayTime int64
- Order string
- PayType int32
- HouseholdUid int64
- PropertyPackageId int64
- PropertyPackageGiveMonths int64
- }
- func HouseholdPrePayBillAdd(param *HouseholdPrePayBillParam, db *gorm.DB, dbname string) (string, error) {
- ob := dbmodel.NewChargeBill(dbname)
- where := map[string]interface{}{
- "charge_bind_id": param.BindInfo.ID,
- "charge_end >=": param.End,
- }
- count, err := ob.Count(db, where, nil)
- if err != nil {
- return "", errors.DataBaseError
- }
- if count > 0 {
- return "", status.Error(10003, "待缴账单中已存在相同账单")
- }
- ob.SetTablePayed(dbname)
- count, err = ob.Count(db, where, nil)
- if err != nil {
- return "", errors.DataBaseError
- }
- if count > 0 {
- return "", status.Error(10003, "已缴账单中已存在相同账单")
- }
- bill := dbmodel.TChargeBill{
- ObjType: param.BindInfo.ObjType,
- ObjId: param.BindInfo.ObjId,
- ChargeId: param.BindInfo.ChargeId,
- ChargeBindId: param.BindInfo.ID,
- ChargeTimeType: param.ChargeInfo.ChargeTimeType,
- ChargeDesc: param.Desc,
- Comment: param.Comment,
- Amount: param.Amount,
- ChargePowerId: 0,
- ChargeType: param.ChargeInfo.ChargeType,
- ChargeName: param.ChargeInfo.ChargeName,
- Uid: param.HouseholdUid,
- PayMode: 2,
- PackageId: 0,
- ChargeEnd: param.End,
- ChargeStart: param.Start,
- OrderId: param.Order,
- PayTime: param.PayTime,
- HouseId: param.BindInfo.HouseId,
- ObjName: param.BindInfo.ObjName,
- LateFee: 0,
- PayType: param.PayType,
- Status: charge_utils.PayStatusUnPay,
- }
- if bill.ChargeType == charge_utils.ChargeTypeProperty &&
- param.PropertyPackageId > 0 &&
- param.PropertyPackageGiveMonths > 0 {
- bill.PackageId = param.PropertyPackageId
- bill.ChargeEnd = time.Unix(bill.ChargeEnd, 0).AddDate(0, int(param.PropertyPackageGiveMonths), 0).Unix()
- }
- bytes, _ := json.Marshal(bill)
- return string(bytes), nil
- }
- type HouseholdPrePayOrderParam struct {
- BillInfo string
- OrderId string
- ObjName string
- Now time.Time
- PrepayId string
- PropertyPackageId int64
- PropertyPackageGiveMonths int64
- ChargeType int32
- }
- func HouseholdPrePayOrderAdd(req *pb_v1.ChargePrePayByHouseholdRequest, param *HouseholdPrePayOrderParam, db *gorm.DB, dbname string, desc string) error {
- order := dbmodel.TChargeOrder{
- OrderId: param.OrderId,
- Comment: req.Comment,
- Amount: req.ShouldPayAmount,
- PayAmount: req.PayAmount,
- PayType: req.PayType,
- CreatedAt: param.Now,
- Uid: req.HouseholdUid,
- PackageId: 0,
- PrepayId: param.PrepayId,
- TransactionId: "",
- Status: charge_utils.PayStatusUnPay,
- PayingDesc: desc,
- PayTime: param.Now.Unix(),
- BillIds: "",
- OnlinePay: 1,
- OnlinePayBill: param.BillInfo,
- ObjName: param.ObjName,
- }
- if param.ChargeType == charge_utils.ChargeTypeProperty &&
- param.PropertyPackageId > 0 &&
- param.PropertyPackageGiveMonths > 0 {
- order.PackageId = param.PropertyPackageId
- }
- order.SetTable(dbname)
- err := order.Insert(db)
- if err != nil {
- return errors.DataBaseError
- }
- return nil
- }
- func ChargePrePayByHouseholdForVehicle(req *pb_v1.ChargePrePayByHouseholdRequest, bind *dbmodel.TChargeBind, dbname string, mchid string) (reply *pb_v1.ChargePrePayByHouseholdReply, err error) {
- // 是否有未缴账单
- reply = &pb_v1.ChargePrePayByHouseholdReply{}
- bill := dbmodel.NewChargeBill(dbname)
- where := map[string]interface{}{
- "charge_bind_id": req.BindId,
- }
- count, err := bill.Count(database.DB(), where, nil)
- if err != nil {
- return nil, errors.DataBaseError
- }
- if count > 0 {
- return nil, status.Error(10003, "当前费用有未缴账单,请先缴清欠费")
- }
- // 费用信息
- chargeInfo := dbmodel.NewChargeConf(dbname)
- where = map[string]interface{}{
- "id": bind.ChargeId,
- }
- err = chargeInfo.Find(database.DB(), where)
- if err != nil && err != gorm.ErrRecordNotFound {
- return nil, errors.DataBaseError
- }
- if chargeInfo.ID == 0 {
- return nil, errors.ErrRecordNotFound
- }
- // 获取月数对应的应缴费用
- shouldPayAmount, _, chargeDesc := charge_utils.PrePayInfo(chargeInfo, bind, req.Months)
- if req.ShouldPayAmount != shouldPayAmount {
- return nil, status.Error(10003, "应缴费用不一致")
- }
- // 账单开始和截止月份
- now := time.Now()
- start := int64(0)
- end := int64(0)
- if bind.Start == 0 {
- start = getTimeDayTimestamp(now)
- end = time.Unix(start, 0).AddDate(0, int(req.Months), 0).Unix()
- } else {
- if bind.End < getTimeDayTimestamp(now) {
- return nil, status.Error(10003, "当前费用已断缴,请到物业缴费")
- }
- start = bind.End
- end = time.Unix(start, 0).AddDate(0, int(req.Months), 0).Unix()
- }
- // 新增支付中账单
- oid, err := GenerateOrderId(req.GardenId, OrderTypeLife)
- if err != nil {
- return nil, err
- }
- param := HouseholdPrePayBillParam{
- ChargeInfo: chargeInfo,
- BindInfo: bind,
- Start: start,
- End: end,
- Amount: req.ShouldPayAmount,
- Desc: chargeDesc,
- Comment: req.Comment,
- PayTime: now.Unix(),
- Order: oid,
- PayType: req.PayType,
- HouseholdUid: req.HouseholdUid,
- }
- thirdPrepayId, thirdPrepayInfo, _, err := ThirdpartyPay(req.OpenId, req.InputIp, req.ShouldPayAmount, param.Order, charge_utils.ChargeTypeM[bind.ChargeType], mchid, false)
- if err != nil {
- return nil, err
- }
- db := database.DB().Begin()
- defer func() {
- if err != nil {
- db.Rollback()
- }
- }()
- billInfo, err := HouseholdPrePayBillAdd(¶m, db, dbname)
- if err != nil {
- return nil, err
- }
- // 新增对应订单
- orderParam := HouseholdPrePayOrderParam{
- BillInfo: billInfo,
- OrderId: param.Order,
- ObjName: bind.ObjName,
- Now: now,
- PrepayId: thirdPrepayId,
- }
- err = HouseholdPrePayOrderAdd(req, &orderParam, db, dbname, "停车收费")
- if err != nil {
- return nil, err
- }
- // 修改绑定关系里的账单截止时间戳(收到回调后再修改)
- db.Commit()
- reply.OrderId = param.Order
- reply.PrepayInfo = thirdPrepayInfo
- return reply, nil
- }
- func GetPropertyPackageInfo(payMonths int64, packageId int64, dbname string) (int64, int64, error) {
- if packageId == 0 {
- return 0, 0, nil
- }
- p := dbmodel.NewPropertyPackage(dbname)
- where := map[string]interface{}{
- "id": packageId,
- }
- err := p.Find(database.DB(), where)
- if err != nil && err != gorm.ErrRecordNotFound {
- return 0, 0, errors.DataBaseError
- }
- if p.ID == 0 {
- return 0, 0, errors.ErrRecordNotFound
- }
- if p.Enable == 2 {
- return 0, 0, status.Error(10003, "套餐已禁用")
- }
- if p.PayMonths != payMonths {
- return 0, 0, status.Error(10003, "套餐不一致")
- }
- return packageId, p.GiveMonths, nil
- }
- func ChargePrePayByHousehold(ctx context.Context, req *pb_v1.ChargePrePayByHouseholdRequest) (reply *pb_v1.ChargePrePayByHouseholdReply, err error) {
- reply = &pb_v1.ChargePrePayByHouseholdReply{}
- // 捕获各个task中的异常并返回给调用者
- defer func() {
- if r := recover(); r != nil {
- err = fmt.Errorf("%+v", r)
- e := &status.Status{}
- if er := json.Unmarshal([]byte(err.Error()), e); er != nil {
- logger.Error("err",
- zap.String("system_err", err.Error()),
- zap.Stack("stacktrace"))
- }
- }
- }()
- // 参数检查
- err = checkChargePrePayByHouseholdParam(req)
- if err != nil {
- return nil, err
- }
- mchId, err := charge_utils.CheckMchPayMode(req.GardenId)
- if err != nil {
- return nil, err
- }
- dbname := utils.GetGardenDbName(req.GardenId)
- // 绑定关系信息
- bind := dbmodel.NewChargeBind(dbname)
- where := map[string]interface{}{
- "id": req.BindId,
- }
- err = bind.Find(database.DB(), where)
- if err != nil && err != gorm.ErrRecordNotFound {
- return nil, errors.DataBaseError
- }
- if bind.ID == 0 {
- return nil, errors.ErrRecordNotFound
- }
- if bind.ChargeType == charge_utils.ChargeTypeVehicle {
- return ChargePrePayByHouseholdForVehicle(req, bind, dbname, mchId)
- }
- propertyPackageId, propertyPackageGiveMonths := int64(0), int64(0)
- desc := ""
- if bind.ChargeType == charge_utils.ChargeTypeSpace {
- desc = "预存车位管理费"
- }
- if bind.ChargeType == charge_utils.ChargeTypeProperty {
- desc = "预存物业费"
- propertyPackageId, propertyPackageGiveMonths, err = GetPropertyPackageInfo(req.Months, req.PackageId, dbname)
- if err != nil {
- return nil, err
- }
- }
- // 是否有未缴账单
- bill := dbmodel.NewChargeBill(dbname)
- where = map[string]interface{}{
- "charge_bind_id": req.BindId,
- }
- count, err := bill.Count(database.DB(), where, nil)
- if err != nil {
- return nil, errors.DataBaseError
- }
- if count > 0 {
- return nil, status.Error(10003, "当前费用有未缴账单,请先缴清欠费")
- }
- // 费用信息
- chargeInfo := dbmodel.NewChargeConf(dbname)
- where = map[string]interface{}{
- "id": bind.ChargeId,
- }
- err = chargeInfo.Find(database.DB(), where)
- if err != nil && err != gorm.ErrRecordNotFound {
- return nil, errors.DataBaseError
- }
- if chargeInfo.ID == 0 {
- return nil, errors.ErrRecordNotFound
- }
- // 获取月数对应的应缴费用
- shouldPayAmount, _, chargeDesc := charge_utils.PrePayInfo(chargeInfo, bind, req.Months)
- if req.ShouldPayAmount != shouldPayAmount {
- return nil, status.Error(10003, "应缴费用不一致")
- }
- // 账单开始和截止月份
- start := int64(0)
- end := int64(0)
- if bind.BillLastTime > 0 {
- start = bind.BillLastTime
- end = time.Unix(bind.BillLastTime, 0).AddDate(0, int(req.Months), 0).Unix()
- } else {
- if bind.Start == 0 {
- return nil, status.Error(10003, "当前费用未生效,请先变更开始时间")
- }
- start = bind.Start
- end = time.Unix(start, 0).AddDate(0, int(req.Months), 0).Unix()
- }
- // 新增支付中账单
- now := time.Now()
- oid, err := GenerateOrderId(req.GardenId, OrderTypeLife)
- if err != nil {
- return nil, err
- }
- param := HouseholdPrePayBillParam{
- ChargeInfo: chargeInfo,
- BindInfo: bind,
- Start: start,
- End: end,
- Amount: req.ShouldPayAmount,
- Desc: chargeDesc,
- Comment: req.Comment,
- PayTime: now.Unix(),
- Order: oid,
- PayType: req.PayType,
- HouseholdUid: req.HouseholdUid,
- PropertyPackageId: propertyPackageId,
- PropertyPackageGiveMonths: propertyPackageGiveMonths,
- }
- thirdPrepayId, thirdPrepayInfo, _, err := ThirdpartyPay(req.OpenId, req.InputIp, req.ShouldPayAmount, param.Order, charge_utils.ChargeTypeM[bind.ChargeType], mchId, false)
- if err != nil {
- return nil, err
- }
- db := database.DB().Begin()
- defer func() {
- if err != nil {
- db.Rollback()
- }
- }()
- billInfo, err := HouseholdPrePayBillAdd(¶m, db, dbname)
- if err != nil {
- return nil, err
- }
- // 新增对应订单
- orderParam := HouseholdPrePayOrderParam{
- BillInfo: billInfo,
- OrderId: param.Order,
- ObjName: bind.ObjName,
- Now: now,
- PrepayId: thirdPrepayId,
- PropertyPackageId: propertyPackageId,
- PropertyPackageGiveMonths: propertyPackageGiveMonths,
- ChargeType: bind.ChargeType,
- }
- err = HouseholdPrePayOrderAdd(req, &orderParam, db, dbname, desc)
- if err != nil {
- return nil, err
- }
- // 修改绑定关系里的账单截止时间戳(收到回调后再改)
- db.Commit()
- reply.OrderId = param.Order
- reply.PrepayInfo = thirdPrepayInfo
- return reply, nil
- }
|