hospital-admin-api/api/service/doctorWithdrawa.go

302 lines
9.1 KiB
Go

package service
import (
"errors"
"hospital-admin-api/api/dao"
"hospital-admin-api/api/dto"
"hospital-admin-api/api/requests"
"hospital-admin-api/global"
"hospital-admin-api/utils"
"math"
"time"
)
type DoctorWithdrawaService struct {
}
// GetDoctorWithdrawal 提现详情
func (r *DoctorWithdrawaService) GetDoctorWithdrawal(withdrawalId int64) (g *dto.DoctorWithdrawalDto, err error) {
doctorWithdrawalDao := dao.DoctorWithdrawalDao{}
doctorWithdrawal, err := doctorWithdrawalDao.GetDoctorWithdrawalById(withdrawalId)
if doctorWithdrawal == nil {
return nil, errors.New("数据错误")
}
// 获取医生数据
userDoctorDao := dao.UserDoctorDao{}
userDoctor, err := userDoctorDao.GetUserDoctorById(doctorWithdrawal.DoctorId)
if err != nil || userDoctor == nil {
return nil, errors.New("医生数据错误")
}
// 获取医生详情数据
userDoctorInfoDao := dao.UserDoctorInfoDao{}
userDoctorInfo, err := userDoctorInfoDao.GetUserDoctorInfoByUserId(userDoctor.UserId)
if err != nil || userDoctorInfo == nil {
return nil, errors.New("医生详情数据错误")
}
// 获取提现关联银行数据
doctorWithdrawalBankDao := dao.DoctorWithdrawalBankDao{}
doctorWithdrawalBank, err := doctorWithdrawalBankDao.GetDoctorWithdrawalBankByWithdrawalId(doctorWithdrawal.WithdrawalId)
if err != nil || doctorWithdrawalBank == nil {
return nil, errors.New("银行卡数据错误")
}
// 获取基础银行数据
basicBankDao := dao.BasicBankDao{}
basicBank, err := basicBankDao.GetBasicBankById(doctorWithdrawalBank.BankId)
if err != nil || basicBank == nil {
return nil, errors.New("银行数据错误")
}
// 处理返回值
g = dto.GetDoctorWithdrawalDto(doctorWithdrawal)
// 加载医生名称
g.LoadDoctorName(userDoctor)
// 加载医生证件号码(掩码)
g.LoadDoctorCardNumMask(userDoctorInfo)
// 加载审核人员名称
g.LoadExamineByName(doctorWithdrawal.ExamineBy)
// 加载打款人员名称
g.LoadPaymentByName(doctorWithdrawal.ExamineBy)
// 加载提现关联银行数据
g.LoadDoctorWithdrawalBank(doctorWithdrawalBank)
// 加载基础银行数据
g.LoadBasicBank(basicBank)
return g, nil
}
// PutDoctorWithdrawalIncome 修改提现个人所得税
func (r *DoctorWithdrawaService) PutDoctorWithdrawalIncome(req requests.PutDoctorWithdrawalIncome, withdrawalId int64) (bool, error) {
doctorWithdrawalDao := dao.DoctorWithdrawalDao{}
doctorWithdrawal, _ := doctorWithdrawalDao.GetDoctorWithdrawalById(withdrawalId)
if doctorWithdrawal == nil {
return false, errors.New("数据错误")
}
// 判断审核状态
if doctorWithdrawal.ExamineStatus == 2 {
return false, errors.New("提现申请已审核通过,请勿再次操作")
}
if doctorWithdrawal.ExamineStatus == 3 {
return false, errors.New("提现申请已被驳回,请勿再次操作")
}
if doctorWithdrawal.PaymentStatus == 1 {
return false, errors.New("已打款,请勿再次操作")
}
if req.IncomeTax >= doctorWithdrawal.AppliedWithdrawalAmount {
return false, errors.New("个人所得税金额不可超出申请提现金额")
}
// 开始事务
tx := global.Db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
// 计算实际提现金额
actualWithdrawalAmount := math.Floor((doctorWithdrawal.AppliedWithdrawalAmount-req.IncomeTax)*0.75*100) / 100
// 提现申请修改数据-提现金额固定不动,修改个人所得税,实际提现金额跟随变动
doctorWithdrawalData := make(map[string]interface{})
doctorWithdrawalData["income_tax"] = req.IncomeTax // 提现所得税金额
doctorWithdrawalData["actual_withdrawal_amount"] = actualWithdrawalAmount // 实际提现金额
err := doctorWithdrawalDao.EditDoctorWithdrawalById(tx, doctorWithdrawal.WithdrawalId, doctorWithdrawalData)
if err != nil {
tx.Rollback()
return false, errors.New(err.Error())
}
tx.Commit()
return true, nil
}
// PutDoctorWithdrawalExamine 修改提现审核状态
func (r *DoctorWithdrawaService) PutDoctorWithdrawalExamine(req requests.PutDoctorWithdrawalExamine, withdrawalId, adminUserId int64) (bool, error) {
doctorWithdrawalDao := dao.DoctorWithdrawalDao{}
doctorWithdrawal, _ := doctorWithdrawalDao.GetDoctorWithdrawalById(withdrawalId)
if doctorWithdrawal == nil {
return false, errors.New("数据错误")
}
// 判断审核状态
if doctorWithdrawal.ExamineStatus == 2 {
return false, errors.New("提现申请已审核通过,无法操作")
}
if doctorWithdrawal.ExamineStatus == 3 {
return false, errors.New("提现申请已被驳回,请勿再次操作")
}
if doctorWithdrawal.PaymentStatus == 1 {
return false, errors.New("已打款,请勿再次操作")
}
if req.ExamineStatus == 3 {
if req.ExamineFailReason == "" {
return false, errors.New("请填写拒绝原因")
}
}
// 开始事务
tx := global.Db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
// 提现申请修改数据
doctorWithdrawalData := make(map[string]interface{})
doctorWithdrawalData["examine_status"] = req.ExamineStatus
if req.ExamineFailReason == "" {
doctorWithdrawalData["examine_fail_reason"] = req.ExamineFailReason
}
doctorWithdrawalData["examine_time"] = time.Now().Format("2006-01-02 15:04:05")
doctorWithdrawalData["examine_by"] = adminUserId
err := doctorWithdrawalDao.EditDoctorWithdrawalById(tx, doctorWithdrawal.WithdrawalId, doctorWithdrawalData)
if err != nil {
tx.Rollback()
return false, errors.New(err.Error())
}
// 返还医生账户金额-审核不通过
if req.ExamineStatus == 3 {
// 获取医生账户数据
doctorAccountDao := dao.DoctorAccountDao{}
doctorAccount, err := doctorAccountDao.GetDoctorAccountByDoctorId(doctorWithdrawal.DoctorId)
if err != nil {
tx.Rollback()
return false, errors.New("医生账户数据错误")
}
// 获取提现关联订单医生分成总金额
amountTotal, err := r.getDoctorWithdrawalOrderAmountTotal(withdrawalId)
if err != nil {
tx.Rollback()
return false, err
}
// 重新计算医生个人所得税
incomeTax := utils.ComputeIndividualIncomeTax(amountTotal)
// 重新计算实际提现金额
withdrawalAmount := math.Floor((amountTotal-incomeTax)*0.75*100) / 100
incomeTax = math.Floor(incomeTax*100) / 100
// 账户余额-增加
maps := make(map[string]interface{})
maps["account_id"] = doctorAccount.AccountId
err = doctorAccountDao.Inc(tx, maps, amountTotal, "balance_account")
if err != nil {
tx.Rollback()
return false, err
}
// 实际提现金额-减少
maps = make(map[string]interface{})
maps["account_id"] = doctorAccount.AccountId
err = doctorAccountDao.Dec(tx, maps, withdrawalAmount, "applied_withdrawal_amount")
if err != nil {
tx.Rollback()
return false, err
}
// 提现所得税金额-减少
maps = make(map[string]interface{})
maps["account_id"] = doctorAccount.AccountId
err = doctorAccountDao.Dec(tx, maps, incomeTax, "income_tax")
if err != nil {
tx.Rollback()
return false, err
}
// 获取医生提现-关联订单数据
doctorWithdrawalOrderDao := dao.DoctorWithdrawalOrderDao{}
doctorWithdrawalOrders, err := doctorWithdrawalOrderDao.GetDoctorWithdrawalOrderByWithdrawalId(withdrawalId)
if err != nil {
tx.Rollback()
return false, errors.New("关联订单数据错误")
}
// 修改问诊订单提现状态
for _, v := range doctorWithdrawalOrders {
// 获取订单数据
orderInquiryDao := dao.OrderInquiryDao{}
orderInquiry, err := orderInquiryDao.GetOrderInquiryById(v.OrderInquiryId)
if err != nil {
tx.Rollback()
return false, errors.New("关联订单数据错误")
}
orderInquiryData := make(map[string]interface{})
orderInquiryData["is_withdrawal"] = 0
orderInquiryData["withdrawal_time"] = nil
err = orderInquiryDao.EditOrderInquiryById(tx, orderInquiry.OrderInquiryId, orderInquiryData)
if err != nil {
tx.Rollback()
return false, errors.New("回滚关联订单数据失败")
}
}
}
tx.Commit()
return true, nil
}
// 获取提现关联订单医生分成总金额
func (r *DoctorWithdrawaService) getDoctorWithdrawalOrderAmountTotal(withdrawalId int64) (float64, error) {
// 获取医生提现-关联订单数据
doctorWithdrawalOrderDao := dao.DoctorWithdrawalOrderDao{}
doctorWithdrawalOrders, err := doctorWithdrawalOrderDao.GetDoctorWithdrawalOrderByWithdrawalId(withdrawalId)
if err != nil {
return 0, errors.New("关联订单数据错误")
}
// 总金额
var amountTotal float64
for _, v := range doctorWithdrawalOrders {
// 获取订单数据
orderInquiryDao := dao.OrderInquiryDao{}
orderInquiry, err := orderInquiryDao.GetOrderInquiryById(v.OrderInquiryId)
if err != nil {
return 0, errors.New("订单数据错误")
}
if orderInquiry.InquiryStatus != 6 {
return 0, errors.New("存在未结束订单,数据错误")
}
if orderInquiry.IsWithdrawal != 0 {
return 0, errors.New("存在已被提现订单,数据错误")
}
if orderInquiry.InquiryPayStatus != 2 {
return 0, errors.New("存在支付状态错误订单,数据错误")
}
amountTotal = amountTotal + orderInquiry.AmountTotal
}
// 医生分成金额
if amountTotal > 0 {
amountTotal = math.Floor(amountTotal*0.75*100) / 100
}
return amountTotal, nil
}