123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544 |
- package charge_utils
- import (
- "context"
- "encoding/json"
- "fmt"
- "git.getensh.com/common/gopkgs/database"
- "google.golang.org/grpc/status"
- "gorm.io/gorm"
- "property-garden/errors"
- dbmodel "property-garden/model"
- "property-garden/parser"
- "property-garden/pb"
- pb_v1 "property-garden/pb/v1"
- "strings"
- "time"
- )
- func GetGardenInfos(ids []int64) (map[int64]pb_v1.GardenItem, error) {
- ret := map[int64]pb_v1.GardenItem{}
- if len(ids) == 0 {
- return ret, nil
- }
- mreq := pb_v1.GardenInfosRequest{Ids: ids}
- mreply, err := pb.System.GardenInfos(context.Background(), &mreq)
- if err != nil {
- return ret, err
- }
- for _, v := range mreply.List {
- ret[v.Id] = *v
- }
- return ret, nil
- }
- func GetCompanyInfo(id int64) (*pb_v1.CompanyInfoReply, error) {
- mreq := pb_v1.CompanyInfoRequest{Id: id}
- mreply, err := pb.Company.CompanyInfo(context.Background(), &mreq)
- if err != nil {
- return nil, err
- }
- return mreply, nil
- }
- func CheckMchPayMode(gardenId int64) (string, error) {
- infoM, err := GetGardenInfos([]int64{gardenId})
- if err != nil {
- return "", err
- }
- info, ok := infoM[gardenId]
- if !ok {
- return "", status.Error(10003, "获取小区信息失败")
- }
- if info.PayMode == 1 {
- return "", status.Error(10003, "暂不支持线上缴费")
- }
- if info.PayMode == 2 {
- if info.MchId == "" {
- return "", status.Error(10003, "暂不支持线上缴费")
- }
- return info.MchId, nil
- }
- return parser.Conf.ThirdParty.Wx.AppletMchId, nil
- }
- func GetHouseInfos(ids []int64, dbname string) (map[int64]dbmodel.THouseUnitBuilding, error) {
- ret := map[int64]dbmodel.THouseUnitBuilding{}
- if len(ids) == 0 {
- return ret, nil
- }
- p := dbmodel.NewHouseUnitBuilding(dbname)
- where := map[string]interface{}{
- "id in": ids,
- }
- list, err := p.List(database.DB(), where, nil, -1, -1)
- if err != nil {
- return nil, errors.DataBaseError
- }
- for _, v := range list {
- ret[v.ID] = v
- }
- return ret, nil
- }
- func GetChargeInfos(ids []int64, dbname string) (map[int64]dbmodel.TChargeConf, error) {
- ret := map[int64]dbmodel.TChargeConf{}
- if len(ids) == 0 {
- return ret, nil
- }
- p := dbmodel.NewChargeConf(dbname)
- where := map[string]interface{}{
- "id in": ids,
- }
- list, err := p.List(database.DB(), where, nil, -1, -1)
- if err != nil {
- return nil, errors.DataBaseError
- }
- for _, v := range list {
- ret[v.ID] = v
- }
- return ret, nil
- }
- func GetAllChargeInfos(dbname string) (map[int64]dbmodel.TChargeConf, error) {
- ret := map[int64]dbmodel.TChargeConf{}
- p := dbmodel.NewChargeConf(dbname)
- list, err := p.List(database.DB(), nil, nil, -1, -1)
- if err != nil {
- return nil, errors.DataBaseError
- }
- for _, v := range list {
- ret[v.ID] = v
- }
- return ret, nil
- }
- func IsChargeBindObj(chargeId int64, dbname string) (bool, error) {
- p := dbmodel.NewChargeBind(dbname)
- where := map[string]interface{}{
- "charge_id": chargeId,
- }
- count, err := p.Count(database.DB(), where, nil)
- if err != nil {
- return false, errors.DataBaseError
- }
- if count > 0 {
- return true, nil
- }
- return false, nil
- }
- func IsObjBindCharge(objId int64, objType int32, dbname string) (bool, error) {
- p := dbmodel.NewChargeBind(dbname)
- where := map[string]interface{}{
- "obj_id": objId,
- "obj_type": objType,
- }
- count, err := p.Count(database.DB(), where, nil)
- if err != nil {
- return false, errors.DataBaseError
- }
- if count > 0 {
- return true, nil
- }
- return false, nil
- }
- func IsObjsBindCharge(objIds []int64, objType int32, dbname string) (bool, error) {
- p := dbmodel.NewChargeBind(dbname)
- where := map[string]interface{}{
- "obj_id in": objIds,
- "obj_type": objType,
- }
- count, err := p.Count(database.DB(), where, nil)
- if err != nil {
- return false, errors.DataBaseError
- }
- if count > 0 {
- return true, nil
- }
- return false, nil
- }
- func CompanyDealIncrease(gardenId int64, amount int64, timestamp int64) error {
- mreq := pb_v1.CompanyDealStatisticSetRequest{GardenId: gardenId, Amount: amount, DateTimestamp: timestamp}
- _, err := pb.Company.CompanyDealStatisticSet(context.Background(), &mreq)
- return err
- }
- /*
- func IsBillPaying(billId int64, dbname string) (bool, string, error) {
- p := dbmodel.NewChargeBill(dbname)
- where := map[string]interface{}{
- "id":billId,
- "status":PayStatusPaying,
- }
- err := p.Find(database.DB(), where)
- if err != nil && err != gorm.ErrRecordNotFound{
- return false, "", errors.DataBaseError
- }
- if p.ID == 0 {
- return false, "", nil
- }
- return true, p.OrderId, nil
- }
- */
- /*
- func IsPowerPaying(powerId int64, dbname string) (bool, string, error) {
- p := dbmodel.NewChargeBill(dbname)
- where := map[string]interface{}{
- "charge_power_id":powerId,
- "status":PayStatusPaying,
- }
- err := p.Find(database.DB(), where)
- if err != nil && err != gorm.ErrRecordNotFound{
- return false, "", errors.DataBaseError
- }
- if p.ID == 0 {
- return false, "", nil
- }
- return true, p.OrderId, nil
- }
- */
- /*
- func IsBillsPaying(billIds []int64, dbname string) (bool, string, error) {
- p := dbmodel.NewChargeBill(dbname)
- where := map[string]interface{}{
- "id in":billIds,
- "status":PayStatusPaying,
- }
- err := p.Find(database.DB(), where)
- if err != nil && err != gorm.ErrRecordNotFound{
- return false, "", errors.DataBaseError
- }
- if p.ID == 0 {
- return false, "", nil
- }
- return true, p.OrderId, nil
- }
- */
- /*
- func IsChargesPaying(bindIds []int64, dbname string) (bool, string, error) {
- p := dbmodel.NewChargeBill(dbname)
- where := map[string]interface{}{
- "charge_bind_id in":bindIds,
- "status":PayStatusPaying,
- }
- err := p.Find(database.DB(), where)
- if err != nil && err != gorm.ErrRecordNotFound{
- return false, "", errors.DataBaseError
- }
- if p.ID == 0 {
- return false, "", nil
- }
- return true, p.OrderId, nil
- }
- */
- /*
- func IsObjPaying(objId int64, objType int32, dbname string) (bool, string, error) {
- p := dbmodel.NewChargeBill(dbname)
- where := map[string]interface{}{
- "obj_id":objId,
- "obj_type":objType,
- "status":PayStatusPaying,
- }
- err := p.Find(database.DB(), where)
- if err != nil && err != gorm.ErrRecordNotFound{
- return false, "", errors.DataBaseError
- }
- if p.ID == 0 {
- return false, "", nil
- }
- return true, p.OrderId, nil
- }
- */
- func ThirdpartyCheckPayingOrder(orderNo string, gardenId int64) (string, string, string, int64, int64) {
- //TODO 当前只有微信小程序,后续会有其他方式
- orderId := fmt.Sprintf("%d-%s", gardenId, orderNo)
- mreq := &pb_v1.WxAppletQueryRequest{Order: orderId}
- mreply, err := pb.Thirdparty.WxAppletQuery(context.Background(), mreq)
- if err != nil {
- return "", "", "", 0, 0
- }
- return mreply.TradeState, mreply.TradeStateDesc, mreply.TransactionId, mreply.PayTime, mreply.Amount
- }
- func SetOrderPayingDesc(orderNo string, payingDesc string, dbname string) error {
- p := dbmodel.NewChargeOrder(dbname)
- where := map[string]interface{}{
- "order_id": orderNo,
- }
- values := map[string]interface{}{
- "paying_desc": payingDesc,
- }
- err := p.Update(database.DB(), where, values)
- if err != nil {
- return errors.DataBaseError
- }
- return nil
- }
- func SetOrderPayed(payTime int64, orderNo string, transId string, dbname string) error {
- p := dbmodel.NewChargeOrder(dbname)
- var err error
- // 更新订单
- where := map[string]interface{}{
- "order_id": orderNo,
- }
- values := map[string]interface{}{
- "status": PayStatusPayed,
- "pay_time": payTime,
- "transaction_id": transId,
- }
- db := database.DB().Begin()
- defer func() {
- if err != nil {
- db.Rollback()
- }
- }()
- err = p.Update(db, where, values)
- if err != nil {
- return errors.DataBaseError
- }
- // 插入已付费账单表
- bill := dbmodel.NewChargeBill(dbname)
- where = map[string]interface{}{
- "order": orderNo,
- }
- var list []dbmodel.TChargeBill
- list, err = bill.List(database.DB(), where, nil, -1, -1, "")
- if err != nil {
- return errors.DataBaseError
- }
- for i, _ := range list {
- list[i].Status = PayStatusPayed
- list[i].PayTime = payTime
- }
- bill.SetTablePayed(dbname)
- err = bill.InsertMulti(db, &list)
- if err != nil {
- return errors.DataBaseError
- }
- // 删除待缴表中记录
- bill.SetTable(dbname)
- err = bill.Delete(db, where)
- if err != nil {
- return errors.DataBaseError
- }
- db.Commit()
- return nil
- }
- func IsOrderPaying(orders []string, dbname string, db *gorm.DB) (bool, error) {
- if len(orders) == 0 {
- return false, nil
- }
- order := dbmodel.NewChargeOrder(dbname)
- where := map[string]interface{}{
- "order_id in": orders,
- "deleted": 0,
- }
- count, err := order.Count(db, where, nil)
- if err != nil {
- return false, errors.DataBaseError
- }
- return count > 0, nil
- }
- /*
- func CheckPayingOrder(orderNo string, gardenId int64, dbname string) error {
- p := dbmodel.NewChargeOrder(dbname)
- where := map[string]interface{}{
- "order_id":orderNo,
- }
- err := p.Find(database.DB(), where)
- if err != nil && err != gorm.ErrRecordNotFound{
- return errors.DataBaseError
- }
- if p.OrderId == "" {
- return status.Error(10003, "订单不存在")
- }
- if p.Status != PayStatusPaying {
- return nil
- }
- if time.Now().Unix() - p.CreatedAt.Unix() < 60 {
- return nil
- }
- state, desc, transId, payTime, amount := ThirdpartyCheckPayingOrder(orderNo, gardenId)
- if state == "" {
- return nil
- }
- if state != "SUCCESS" {
- return SetOrderPayingDesc(orderNo, fmt.Sprintf("%s-%s", state, desc), dbname)
- }
- if p.Amount != amount {
- return SetOrderPayingDesc(orderNo, fmt.Sprintf("三方状态已支付,金额不一致%d", amount), dbname)
- }
- return SetOrderPayed(payTime, orderNo, transId, dbname)
- }
- */
- func PrePayInfo(chargeInfo *dbmodel.TChargeConf, bindInfo *dbmodel.TChargeBind, months int64) (int64, string, string) {
- array := []string{}
- amount := int64(0)
- chargeDesc := dbmodel.ChargeDesc{
- ChargeBasis: chargeInfo.ChargeBasis,
- UnitPrice: chargeInfo.UnitPrice,
- FixAmount: chargeInfo.FixAmount,
- FixAmountName: chargeInfo.FixAmountName,
- CustomFee: bindInfo.CustomFee,
- }
- switch chargeInfo.ChargeBasis {
- case ChargeBasisUsedArea:
- amount += int64(float64(chargeInfo.UnitPrice*months) * bindInfo.ObjArea)
- array = append(array, fmt.Sprintf("使用面积:%f", bindInfo.ObjArea))
- array = append(array, fmt.Sprintf("单价:%.2f元", float64(chargeInfo.UnitPrice)/100.00))
- if chargeInfo.FixAmount > 0 {
- amount += (chargeInfo.FixAmount * months)
- array = append(array, fmt.Sprintf("附加费用(%s)每月:%.2f元", chargeInfo.FixAmountName, float64(chargeInfo.FixAmount)/100.00))
- }
- case ChargeBasisArea:
- amount += int64(float64(chargeInfo.UnitPrice*months) * bindInfo.ObjArea)
- array = append(array, fmt.Sprintf("建筑面积:%f", bindInfo.ObjArea))
- array = append(array, fmt.Sprintf("单价:%.2f元", float64(chargeInfo.UnitPrice)/100.00))
- if chargeInfo.FixAmount > 0 {
- amount += (chargeInfo.FixAmount * months)
- array = append(array, fmt.Sprintf("附加费用(%s)每月:%.2f元", chargeInfo.FixAmountName, float64(chargeInfo.FixAmount)/100.00))
- }
- case ChargeBasisSpaceArea:
- amount += int64(float64(chargeInfo.UnitPrice*months) * bindInfo.ObjArea)
- array = append(array, fmt.Sprintf("车位面积:%f", bindInfo.ObjArea))
- array = append(array, fmt.Sprintf("单价:%.2f元", float64(chargeInfo.UnitPrice)/100.00))
- if chargeInfo.FixAmount > 0 {
- amount += (chargeInfo.FixAmount * months)
- array = append(array, fmt.Sprintf("附加费用(%s)每月:%.2f元", chargeInfo.FixAmountName, float64(chargeInfo.FixAmount)/100.00))
- }
- case ChargeBasisFix:
- amount += (chargeInfo.FixAmount * months)
- array = append(array, fmt.Sprintf("固定费用(%s)每月:%.2f元", chargeInfo.FixAmountName, float64(chargeInfo.FixAmount)/100.00))
- case ChargeBasisSelf:
- amount += (bindInfo.CustomFee * months)
- array = append(array, fmt.Sprintf("自定义费用每月:%.2f元", float64(bindInfo.CustomFee)/100.00))
- }
- desc := strings.Join(array, "\n")
- bytes, _ := json.Marshal(chargeDesc)
- return amount, desc, string(bytes)
- }
- func GetMonths(start int64, end int64) int64 {
- startT := time.Unix(start, 0)
- endT := time.Unix(end, 0)
- startT = time.Date(startT.Year(), startT.Month(), 1, 0, 0, 0, 0, startT.Location())
- endT = time.Date(endT.Year(), startT.Month(), 1, 0, 0, 0, 0, endT.Location())
- ret := int64(1)
- for i := 0; i < 1200; i++ {
- startT = startT.AddDate(0, 1, 0)
- if startT.Unix() >= endT.Unix() {
- return ret
- }
- ret++
- }
- return ret
- }
- func GetChargeDesc(chargeDesc dbmodel.ChargeDesc) string {
- array := []string{}
- switch chargeDesc.ChargeBasis {
- case ChargeBasisArea:
- array = append(array, fmt.Sprintf("建筑面积:%.2f", chargeDesc.ObjArea))
- array = append(array, fmt.Sprintf("单价:%.2f", float64(chargeDesc.UnitPrice)/100.00))
- if chargeDesc.FixAmount > 0 {
- array = append(array, fmt.Sprintf("附加费用(%s)每月:%.2f元", chargeDesc.FixAmountName, float64(chargeDesc.FixAmount)/100.00))
- }
- case ChargeBasisUsedArea:
- array = append(array, fmt.Sprintf("使用面积:%.2f", chargeDesc.ObjArea))
- array = append(array, fmt.Sprintf("单价:%.2f", float64(chargeDesc.UnitPrice)/100.00))
- if chargeDesc.FixAmount > 0 {
- array = append(array, fmt.Sprintf("附加费用(%s)每月:%.2f元", chargeDesc.FixAmountName, float64(chargeDesc.FixAmount)/100.00))
- }
- case ChargeBasisSpaceArea:
- array = append(array, fmt.Sprintf("车位面积:%.2f", chargeDesc.ObjArea))
- array = append(array, fmt.Sprintf("单价:%.2f", float64(chargeDesc.UnitPrice)/100.00))
- if chargeDesc.FixAmount > 0 {
- array = append(array, fmt.Sprintf("附加费用(%s)每月:%.2f元", chargeDesc.FixAmountName, float64(chargeDesc.FixAmount)/100.00))
- }
- case ChargeBasisFix:
- array = append(array, fmt.Sprintf("固定费用(%s)每月:%.2f元", chargeDesc.FixAmountName, float64(chargeDesc.FixAmount)/100.00))
- case ChargeBasisUsed:
- array = append(array, fmt.Sprintf("上期用量:%.2f", chargeDesc.PowerLastUsed))
- array = append(array, fmt.Sprintf("本期用量:%.2f", chargeDesc.PowerCurrentUsed))
- array = append(array, fmt.Sprintf("单价:%.2f", float64(chargeDesc.UnitPrice)/100.00))
- if chargeDesc.FixAmount > 0 {
- array = append(array, fmt.Sprintf("附加费用(%s)每月:%.2f元", chargeDesc.FixAmountName, float64(chargeDesc.FixAmount)/100.00))
- }
- case ChargeBasisSelf:
- array = append(array, fmt.Sprintf("费用每月:%.2f元", float64(chargeDesc.CustomFee)/100.00))
- }
- return strings.Join(array, "\n")
- }
- func GetLateFee(amount int64, billTime int64, chargeInfo *dbmodel.TChargeConf) (int64, int64) {
- if chargeInfo.LateFeeEnable != 1 {
- return 0, 0
- }
- if chargeInfo.LateFeePercent == 0 {
- return 0, 0
- }
- now := time.Now()
- billt := time.Unix(billTime, 0)
- // 账单日期
- billDay := time.Date(billt.Year(), billt.Month(), billt.Day(), 0, 0, 0, 0, billt.Location())
- // 当天日期
- nowDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
- // 超期开始日期
- expireDay := billDay.AddDate(0, 0, int(chargeInfo.LateFeeDay))
- if expireDay.Unix() >= nowDay.Unix() {
- return 0, 0
- }
- days := (nowDay.Unix() - expireDay.Unix()) / (3600 * 24)
- if chargeInfo.LateFeeMaxDays > 0 && days > chargeInfo.LateFeeMaxDays {
- days = chargeInfo.LateFeeMaxDays
- }
- ret := float64(amount*days*chargeInfo.LateFeePercent) / 1000.00
- if ret == 0 {
- return 0, 0
- }
- return int64(ret), days
- }
|