package service

import (
	"XT_New/models"
	"XT_New/utils"
	"fmt"
	"github.com/jinzhu/gorm"
	"github.com/shopspring/decimal"
	"math/rand"
	"strconv"
	"strings"
	"time"
)

// 生成编号?+yymmdd+随机数(4位)
// 新增参数为CP
// 退款参数为AF
func CreateCPCode(str string) string {
	s := fmt.Sprintf("%04v", rand.New(rand.NewSource(time.Now().UnixNano())).Int63n(10000))
	t := time.Now().Format("20060102")
	code := str + t + s
	return code
}

// 获取his中的有效患者
func GetHisUser(orgid int64) (hisname []models.GetHisName, err error) {
	err = XTReadDB().Model(&models.GetHisName{}).Where("status = 1 and user_org_id = ?", orgid).Find(&hisname).Error
	return
}

// 获取his中的有效患者去除了转出和死亡的
func GetHisUserToAlive(orgid int64) (hisname []models.GetHisName, err error) {
	err = XTReadDB().Model(&models.GetHisName{}).Where("status = 1 and user_org_id = ? and lapseto = 1", orgid).Find(&hisname).Error
	return
}

// 获取his中的有效患者
func GetHisUserName(orgid, id int64) (hisname models.GetHisName, err error) {
	err = XTReadDB().Model(&models.GetHisName{}).Where("status = 1 and user_org_id = ? and id = ?", orgid, id).Find(&hisname).Error
	return
}

// 添加押金(开始)调用接口前记得判断审核状态,确认通过审核后在调用
func UpDeposit(code, remarks string, his_patient_id, orgid, trial_status, createid int64, deposit decimal.Decimal) (err error) {
	//查押金表是否存在记录
	tmp, tmpdeposit := IsHisPatientId(his_patient_id, orgid)
	if tmp == 0 {
		//需要生成一条数据
		de := models.Deposit{
			UserOrgId:    orgid,
			HisPatientId: his_patient_id,
			Ctime:        time.Now().Unix(),
			Mtime:        time.Now().Unix(),
			Status:       1,
		}
		i, d, err := AddDeposit(de)
		if err != nil || i == 0 {
			utils.ErrorLog("添加用户押金记录失败: %v", err.Error())
			return err
		}
		tmp = i
		tmpdeposit = d
	}
	s_deposit := tmpdeposit
	if trial_status == 1 {
		de := models.Deposit{
			ID:      tmp,
			Mtime:   time.Now().Unix(),
			Deposit: deposit.Add(tmpdeposit),
		}
		err = UpdateDeposit(de)
		if err != nil {
			utils.ErrorLog("添加用户押金失败: %v", err.Error())
			return
		}
		s_deposit = deposit.Add(tmpdeposit)
	}
	dehistory := models.DepositHistory{
		UserOrgId:      orgid,
		HisPatientId:   his_patient_id,
		DepositCode:    code,
		Deposit:        deposit,   //本次操作的押金
		SurplusDeposit: s_deposit, //剩余金额
		DepositStatus:  1,
		Status:         1,
		CreateId:       createid,
		Ctime:          time.Now().Unix(),
		Mtime:          time.Now().Unix(),
		TrialStatus:    trial_status,
		Remarks:        remarks,
	}
	err = AddDepositHistory(dehistory)
	if err != nil {
		utils.ErrorLog("添加用户押金历史记录失败: %v", err.Error())
	}
	return
}

// 添加押金记录
func AddDepositHistory(dh models.DepositHistory) error {
	err := XTWriteDB().Create(&dh).Error
	return err
}

// 押金中添加一条记录,并返回该数据的id和押金余额(当没有该用户记录时调用)
func AddDeposit(de models.Deposit) (int64, decimal.Decimal, error) {
	var tmp models.Deposit
	err := XTWriteDB().Create(&de).Find(&tmp).Error
	if err != nil {
		return 0, decimal.NewFromFloat(0.00), err
	}
	return tmp.ID, tmp.Deposit, err
}

// 更改押金记录
func UpdateDeposit(de models.Deposit) (err error) {
	err = XTWriteDB().Model(&models.Deposit{}).Where("id = ? and status = 1", de.ID).Updates(map[string]interface{}{
		"mtime":   de.Mtime,
		"deposit": de.Deposit,
	}).Error
	return
}

// 判断押金表是否存在当前的患者的一条有效数据,如果有返回id和押金余额,没有返回0
func IsHisPatientId(his_patient_id, orgid int64) (int64, decimal.Decimal) {
	var tmp []models.Deposit
	XTReadDB().Model(&models.Deposit{}).Where("user_org_id = ? and his_patient_id = ? and status = 1", orgid, his_patient_id).Find(&tmp)
	if len(tmp) != 1 {
		return 0, decimal.NewFromFloat(0.00)
	}
	return tmp[0].ID, tmp[0].Deposit
}

// 查询押金编号是否重复
func FindDecimalCode(orgid int64, code string) bool {
	var total int
	XTReadDB().Model(&models.DepositHistory{}).Where("user_org_id = ? and deposit_code = ? and status = 1", orgid, code).Count(&total)
	if total > 0 {
		return true
	} else {
		return false
	}
}

// 充值明细列表
func DetailsList(orgid, stime, etime int64, keyword string, slicekey []int64) (deposithistory []models.DepositHistoryname, err error) {
	db := XTReadDB().Model(&models.DepositHistory{}).Where("status = 1 and user_org_id = ? and deposit_status = 1 ", orgid).Where("ctime >= ? and ctime <= ?", stime, etime)
	if len(keyword) > 0 {
		var tmp string = "deposit_code like ?"
		if len(slicekey) > 0 {
			for i := 0; i < len(slicekey); i++ {
				tmp = tmp + " or his_patient_id = " + strconv.FormatInt(slicekey[i], 10)
			}
		}
		keyword = "%" + keyword + "%"
		db = db.Where(tmp, keyword)
	}
	err = db.Order("ctime desc").Find(&deposithistory).Error
	return
}

// 充值汇总列表
func SummaryList(orgid, stime, etime int64, keyword string, slicekey []int64) (deposithistory []models.DepositHistory, err error) {
	db := XTReadDB().Model(&models.DepositHistory{}).Where("status = 1 and trial_status = 1 and user_org_id = ? and deposit_status = 1 ", orgid).Where("ctime >= ? and ctime <= ?", stime, etime)
	if len(slicekey) > 0 {
		tmp := ""
		for i := 0; i < len(slicekey); i++ {
			tmp = tmp + " his_patient_id = " + strconv.FormatInt(slicekey[i], 10)
			if i < len(slicekey)-1 {
				tmp = tmp + " or "
			}
		}
		db = db.Where(tmp)
	} else {
		if len(keyword) > 0 {
			return
		}
	}
	err = db.Order("ctime desc").Find(&deposithistory).Error
	return
}

// 获取本周周一和周日的起止时间戳
func GetMondayOfWeek() (int64, int64) {
	t := time.Now()
	dayObj := GetZeroTime(t)
	var dayStr string
	loc, _ := time.LoadLocation("Local")
	if t.Weekday() == time.Monday {
		dayStr = dayObj.Format("2006-01-02")
	} else {
		offset := int(time.Monday - t.Weekday())
		if offset > 0 {
			offset = -6
		}
		dayStr = dayObj.AddDate(0, 0, offset).Format("2006-01-02")
	}
	dayStr = dayStr + " 00:00:00"
	stime, _ := time.ParseInLocation("2006-01-02 15:04:05", dayStr, loc)
	return stime.Unix(), stime.Unix() + 604799
}

// 获取本月的起止时间戳
func GetMonth() (int64, int64) {
	timeNow := time.Now()
	timeToday := time.Date(timeNow.Year(), timeNow.Month(), timeNow.Day(), 0, 0, 0, 0, timeNow.Location()) // 获取当天0点时间 time类型
	timeMonthStartUnix1 := timeToday.AddDate(0, 0, -timeToday.Day()+1).Unix()                              // 获取本月第一天0点 时间戳类型
	timeMonthEndUnix1 := timeToday.AddDate(0, 1, -timeToday.Day()+1).Unix() - 1                            // 获取下个月第一天/ 本月最后一天24点 时间戳类型
	return timeMonthStartUnix1, timeMonthEndUnix1
}

// 获取当天起止时间戳
func GetNowTime() (int64, int64) {
	t := time.Now()
	addTime := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
	timesamp := addTime.Unix()
	return timesamp, timesamp + 86399
}

// 获取创建者的姓名
// 原先的(sgj_users.sgj_user_admin)
// 新加的(sgj_users.sgj_user_admin_role)
func GetCreateidName(id, orgid int64) string {
	//var tmp models.CreateUser
	//XTReadDB().Select("name").Where("id = ?", id).Find(&tmp)
	//return tmp.Name

	var tmp models.CreateUserNames
	XTReadDB().Select("user_name").Where("admin_user_id = ? and org_id = ?", id, orgid).Order("ctime desc").Find(&tmp)
	return tmp.UserName
}

// 审核通过
func UpDecimalHistory(id int64) (err error) {
	//开事务
	tx := XTWriteDB().Begin()
	defer func() {
		if err != nil {
			utils.ErrorLog("事务失败,原因为: %v", err)
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()

	//查记录x2
	var history models.DepositHistory
	var detmp models.Deposit
	err = tx.Model(&models.DepositHistory{}).Where("id = ?", id).Find(&history).Error
	if err != nil {
		return
	}
	err = tx.Model(&models.Deposit{}).Where("user_org_id = ? and his_patient_id = ? and status = 1 ", history.UserOrgId, history.HisPatientId).Find(&detmp).Error
	if err != nil {
		return
	}
	//改状态,=====剩余押金
	err = tx.Model(models.DepositHistory{}).Where("id = ?", id).Updates(map[string]interface{}{
		"trial_status":    1,
		"surplus_deposit": detmp.Deposit.Add(history.Deposit),
		"mtime":           time.Now().Unix(),
	}).Error
	if err != nil {
		return
	}
	//相加
	err = tx.Model(&models.Deposit{}).Where("id = ? and status = 1", detmp.ID).Updates(map[string]interface{}{
		"mtime":   time.Now().Unix(),
		"deposit": detmp.Deposit.Add(history.Deposit),
	}).Error

	return
}

// 删除本次记录
func DelDecimalHistory(id int64) (err error) {
	err = XTWriteDB().Model(models.DepositHistory{}).Where("id = ?", id).Updates(map[string]interface{}{
		"status": 0,
		"mtime":  time.Now().Unix(),
	}).Error
	return
}

// 根据id获取一条押金历史记录
func GetDecimalHistoryOne(id int64) (history models.DepositHistory, err error) {
	err = XTReadDB().Model(&models.DepositHistory{}).Where("id = ?", id).Find(&history).Error
	return
}

// 根据患者id获取该患者当前剩余的押金
func GetUserMoney(id, orgid int64) decimal.Decimal {
	tmp := models.Deposit{}
	err := XTReadDB().Model(&models.Deposit{}).Where("his_patient_id = ? and user_org_id = ? and status = 1", id, orgid).Find(&tmp).Error
	if err != nil {
		return decimal.NewFromFloat(0)
	}
	return tmp.Deposit
}

// 查询时间段内患者的余额
func GetMoneyforTime(id, orgid, etime int64) decimal.Decimal {
	tmp := models.DepositHistory{}
	XTReadDB().Model(&models.DepositHistory{}).Where("his_patient_id = ? and user_org_id = ? and status = 1 and mtime <= ?", id, orgid, etime).Order("mtime").Find(&tmp)
	return tmp.SurplusDeposit
}

// 押金流水
func GetFlowList(page, limit, id, orgid, stime, etime, deposit_status int64) (deposit []models.DepositHistory, total int64, err error) {
	s := "status = 1 and trial_status = 1 and user_org_id = ? and his_patient_id = ? and mtime >= ? and mtime <= ?"
	offset := (page - 1) * limit
	if deposit_status != 0 {
		s = s + " and deposit_status = " + strconv.FormatInt(deposit_status, 10)
	}
	err = XTReadDB().Model(&models.DepositHistory{}).Where(s, orgid, id, stime, etime).Count(&total).Offset(offset).Order("mtime desc").Limit(limit).Find(&deposit).Error
	return
}

// 获取患者押金列表
func GetUserList(page, limit, orgid int64, keyword string, slicekey []int64) (m []models.Deposit1, total int64, err error) {
	db := XTReadDB().Model(&models.Deposit{}).Where("status = 1 and user_org_id = ? ", orgid)
	offset := (page - 1) * limit
	if len(keyword) > 0 {
		db = db.Where(" his_patient_id = ? ", keyword)
	}
	err = db.Count(&total).Offset(offset).Order("mtime desc").Limit(limit).Find(&m).Error
	return
}

// 扣费明细列表
func DeductionList(orgid, stime, etime int64, keyword string, slicekey []int64) (deposithistory []models.DepositHistory, err error) {
	db := XTReadDB().Model(&models.DepositHistory{}).Where("status = 1 and user_org_id = ? and deposit_status = 2 ", orgid).Where("ctime >= ? and ctime <= ?", stime, etime)
	if len(keyword) > 0 {
		var tmp string = "deposit_code like ?"
		if len(slicekey) > 0 {
			for i := 0; i < len(slicekey); i++ {
				tmp = tmp + " or his_patient_id = " + strconv.FormatInt(slicekey[i], 10)
			}
		}
		keyword = "%" + keyword + "%"
		db = db.Where(tmp, keyword)
	}
	err = db.Order("ctime desc").Find(&deposithistory).Error
	return
}

// 获取医疗费总额
func MedicalTotal(orgid, id int64) decimal.Decimal {
	tmp := models.HisChargeSettleOrder{}
	//and status = 1 and order_status = 2
	XTReadDB().Model(&models.HisChargeSettleOrder{}).Where("id = ? and user_org_id = ? ", id, orgid).Find(&tmp)
	return decimal.NewFromFloat(tmp.MedfeeSumamt)
}

// 根据就诊号查询出医收费类型
func CodeToChargetype(orgid int64, code string) (s string) {
	tmp := models.HisPrintPatient{}
	tmp_hhcr := models.HisHospitalCheckRecordTwo{}
	XTReadDB().Model(&models.HisPrintPatient{}).Where("number = ? and user_org_id = ?", code, orgid).Find(&tmp)
	//tmp.BalanceAccountsType
	if tmp.BalanceAccountsType == 0 {
		XTReadDB().Model(&models.HisHospitalCheckRecordTwo{}).Where("number = ? and user_org_id = ?", code, orgid).Find(&tmp_hhcr)
		tmp.BalanceAccountsType = tmp_hhcr.BalanceAccountsType
	}
	switch tmp.BalanceAccountsType {
	case 1:
		s = "医保"
	case 2:
		s = "自费"
	case 3:
		s = "公费"
	case 4:
		s = "农保"
	case 5:
		s = "会员"
	case 6:
		s = "职工"
	case 7:
		s = "合同"
	case 8:
		s = "医保自费"
	default:
		s = "类型未定义"
	}

	return
}

// 扣除患者的押金,并生成一条扣费历史记录
// orgid 机构id;
// his_user_id	患者id;
// create_id		创建者id;
// code		就诊号;
// deposit	本次使用的押金金额,支持float64、int、int64、decimal.Decimal类型
func SpendDeposit(orgid, his_user_id, create_id int64, code string, deposit interface{}) (err error) {
	tmp_deposit := decimal.Decimal{} //本次患者使用的押金
	tmp_deposit, err = ToDecimal(deposit)
	if err != nil {
		return
	}
	////开事务
	//tx := XTWriteDB().Begin()
	//defer func() {
	//	if err != nil {
	//		utils.ErrorLog("事务失败,原因为: %v", err.Error())
	//		tx.Rollback()
	//	} else {
	//		tx.Commit()
	//	}
	//}()
	//查询患者押金
	tmp := models.Deposit{}
	err = readDb.Model(&models.Deposit{}).Where("his_patient_id = ? and user_org_id = ? and status = 1", his_user_id, orgid).Find(&tmp).Error
	if err != nil {
		err = fmt.Errorf("押金余额不足")
		return
	}
	//判断能否扣除
	if tmp.Deposit.Cmp(tmp_deposit) == -1 {
		err = fmt.Errorf("押金余额不足")
		return
	}
	//扣除患者押金
	err = readDb.Model(&models.Deposit{}).Where("id = ? and status = 1", tmp.ID).Updates(map[string]interface{}{
		"mtime":   time.Now().Unix(),
		"deposit": tmp.Deposit.Sub(tmp_deposit),
	}).Error
	if err != nil {
		return
	}
	//生成一条历史记录
	dehistory := models.DepositHistory{
		UserOrgId:      orgid,
		HisPatientId:   his_user_id,
		DepositCode:    code,
		Deposit:        tmp_deposit,
		SurplusDeposit: tmp.Deposit.Sub(tmp_deposit),
		DepositStatus:  2,
		Status:         1,
		CreateId:       create_id,
		Ctime:          time.Now().Unix(),
		Mtime:          time.Now().Unix(),
		TrialStatus:    1,
	}
	err = readDb.Create(&dehistory).Error
	return
}

// 新增一条退款申请
func RefundApplication(orgid, his_patient_id, trial_status, createid int64, code string, deposit decimal.Decimal) (err error) {
	//开事务
	tx := XTWriteDB().Begin()
	defer func() {
		if err != nil {
			utils.ErrorLog("事务失败,原因为: %v", err.Error())
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	//获取患者当前余额
	tmp := models.Deposit{}
	err = tx.Model(&models.Deposit{}).Where("his_patient_id = ? and user_org_id = ? and status = 1", his_patient_id, orgid).Find(&tmp).Error
	if err != nil {
		if err.Error() == "record not found" {
			err = fmt.Errorf("没有可退押金,保存失败")
		}
		return
	}
	//判断是否可以退款
	if tmp.Deposit.Cmp(deposit) == -1 {
		err = fmt.Errorf("退款金额不得大于押金余额!")
		return
	}
	s_deposit := tmp.Deposit
	//判断是否审核通过,通过更新当前押金,否则只新增一条历史记录
	if trial_status == 1 {
		//更新患者当前押金余额
		err = tx.Model(&models.Deposit{}).Where("id = ? and status = 1", tmp.ID).Updates(map[string]interface{}{
			"mtime":   time.Now().Unix(),
			"deposit": tmp.Deposit.Sub(deposit),
		}).Error
		if err != nil {
			return
		}
		s_deposit = tmp.Deposit.Sub(deposit)
	}
	//生成一条历史记录
	dehistory := models.DepositHistory{
		UserOrgId:      orgid,
		HisPatientId:   his_patient_id,
		DepositCode:    code,
		Deposit:        deposit,
		SurplusDeposit: s_deposit,
		DepositStatus:  3, //3退款,4退费
		Status:         1,
		CreateId:       createid,
		Ctime:          time.Now().Unix(),
		Mtime:          time.Now().Unix(),
		TrialStatus:    trial_status,
	}
	err = tx.Create(&dehistory).Error
	return
}

// 退款审核通过/拒绝批量处理
func RefundReviewMore(orgid, trial_status int64, ids string) (err error) {
	//处理下字符串
	t_ids := ""
	if ids[len(ids)-1] == 44 {
		t_ids = ids[:len(ids)-1]
	} else {
		t_ids = ids
	}
	tmp_id := strings.Split(t_ids, ",")
	//开事务
	tx := XTWriteDB().Begin()
	defer func() {
		if err != nil {
			utils.ErrorLog("事务失败,原因为: %v", err.Error())
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	//循环处理id
	for i := 0; i < len(tmp_id); i++ {
		var id int64
		id, err = strconv.ParseInt(tmp_id[i], 10, 64)
		if err != nil {
			return err
		}
		err = RefundReview(orgid, id, trial_status, tx)
		if err != nil {
			return err
		}
	}
	return err
}

// 退款审核通过/拒绝
func RefundReview(orgid, id, trial_status int64, tx *gorm.DB) (err error) {
	//根据id查询该条历史记录
	history := models.DepositHistory{}
	err = tx.Model(&models.DepositHistory{}).Where("id = ? and status = 1", id).Find(&history).Error
	if err != nil {
		return err
	}
	//判断状态是否为未审核
	if history.TrialStatus != 0 {
		err = fmt.Errorf("所选单据中包含了无需审核的单据")
		return err
	}
	//判断类型是否为3,3代表退款,4为退费
	if history.DepositStatus != 3 {
		err = fmt.Errorf("所选单据中包含了无需审核的单据")
		return err
	}
	up := make(map[string]interface{})
	//通过
	if trial_status == 1 {
		//拿患者的id和机构id在去查患者的余额
		tt := models.Deposit{}
		err = tx.Model(&models.Deposit{}).Where("his_patient_id = ? and user_org_id = ? and status = 1", history.HisPatientId, orgid).Find(&tt).Error
		if err != nil {
			return err
		}
		//判断是否可以修改患者押金
		if tt.Deposit.Cmp(history.Deposit) == -1 {
			err = fmt.Errorf("当前押金余额小于退款金额,无法完成退款")
			return err
		}
		//修改患者押金
		err = tx.Model(&models.Deposit{}).Where("id = ? and status = 1", tt.ID).Updates(map[string]interface{}{
			"mtime":   time.Now().Unix(),
			"deposit": tt.Deposit.Sub(history.Deposit),
		}).Error
		if err != nil {
			return err
		}
		up = map[string]interface{}{
			"mtime":           time.Now().Unix(),
			"surplus_deposit": tt.Deposit.Sub(history.Deposit),
			"trial_status":    1,
		}
	} else {
		up = map[string]interface{}{
			"mtime":        time.Now().Unix(),
			"trial_status": 2,
		}
	}
	//修改一条历史记录
	err = tx.Model(&models.DepositHistory{}).Where("id = ? and status = 1", id).Updates(up).Error
	return err
}

// 退款删除
func DeleteRefund(orgid, id int64) (err error) {
	//根据id查询历史记录
	history := models.DepositHistory{}
	err = XTReadDB().Model(&models.DepositHistory{}).Where("id = ?", id).Find(&history).Error
	if err != nil {
		return
	}
	//判断是否可以删除
	if history.TrialStatus == 1 || history.DepositStatus != 3 {
		err = fmt.Errorf("当前状态不可删除!")
		return
	}
	//删除
	err = XTWriteDB().Model(&models.DepositHistory{}).Where("id = ?", id).Updates(map[string]interface{}{
		"mtime":  time.Now().Unix(),
		"status": 0,
	}).Error

	return
}

// 更改退款申请
func ChangeRefund(orgid, his_patient_id, trial_status, id int64, code string, deposit decimal.Decimal) (err error) {
	//开事务
	tx := XTWriteDB().Begin()
	defer func() {
		if err != nil {
			utils.ErrorLog("事务失败,原因为: %v", err.Error())
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	//获取患者当前余额
	tmp := models.Deposit{}
	err = tx.Model(&models.Deposit{}).Where("his_patient_id = ? and user_org_id = ? and status = 1", his_patient_id, orgid).Find(&tmp).Error
	if err != nil {
		return
	}
	//判断是否可以退款
	if tmp.Deposit.Cmp(deposit) == -1 {
		err = fmt.Errorf("退款金额不得大于押金余额!")
		return
	}
	up := make(map[string]interface{})
	//判断是否审核通过,通过更新当前押金,否则只新增一条历史记录
	if trial_status == 1 {
		//更新患者当前押金余额
		err = tx.Model(&models.Deposit{}).Where("id = ? and status = 1", tmp.ID).Updates(map[string]interface{}{
			"mtime":   time.Now().Unix(),
			"deposit": tmp.Deposit.Sub(deposit),
		}).Error
		if err != nil {
			return
		}
		up = map[string]interface{}{
			"mtime":           time.Now().Unix(),
			"deposit_code":    code,
			"his_patient_id":  his_patient_id,
			"surplus_deposit": tmp.Deposit.Sub(deposit),
			"deposit":         deposit,
			"trial_status":    trial_status,
		}
	} else {
		up = map[string]interface{}{
			"mtime":          time.Now().Unix(),
			"deposit_code":   code,
			"his_patient_id": his_patient_id,
			"deposit":        deposit,
			"trial_status":   trial_status,
		}
	}
	//更新一条历史记录
	err = tx.Model(&models.DepositHistory{}).Where("id = ? and status = 1", id).Updates(up).Error
	return
}

// 退款分页
func RefundList(page, limit, orgid, stime, etime, refundtype, examinetype int64, keyword string, slicekey []int64) (depo []models.RefundList, total int64, err error) {
	db := XTReadDB().Model(&models.DepositHistory{}).Where("status = 1 and user_org_id = ? ", orgid).Where("ctime >= ? and ctime <= ?", stime, etime)
	offset := (page - 1) * limit
	//退款类型
	switch refundtype {
	case 0:
		db = db.Where(" deposit_status in (3,4) ")
	case 3, 4:
		db = db.Where(" deposit_status = ? ", refundtype)
	default:
		err = fmt.Errorf("退款类型错误")
		return
	}
	//审核状态
	switch examinetype {
	case 0, 1, 2:
		db = db.Where(" trial_status = ? ", examinetype)
	case 3: //代表查询全部
		db = db
	default:
		err = fmt.Errorf("审核状态错误")
		return
	}
	if len(keyword) > 0 {
		tmp := "deposit_code like ? "
		if len(slicekey) > 0 {
			for i := 0; i < len(slicekey); i++ {
				tmp = tmp + " or his_patient_id = " + strconv.FormatInt(slicekey[i], 10)
			}
		}
		keyword = "%" + keyword + "%"
		db = db.Where(tmp, keyword)
	}
	err = db.Count(&total).Offset(offset).Order("ctime desc").Limit(limit).Find(&depo).Error
	return

}

// 退回患者的押金,并生成一条退费历史记录
// orgid 机构id
// his_user_id 患者id
// code 编号
// deposit 本次退费的金额,支持float64、int、int64、decimal.Decimal类型
func MoneyIncrease(orgid, his_user_id int64, code string, deposit interface{}) (err error) {
	tmp_deposit := decimal.Decimal{}
	tmp_deposit, err = ToDecimal(deposit)
	if err != nil {
		return
	}
	//开事务
	tx := XTWriteDB().Begin()
	defer func() {
		if err != nil {
			utils.ErrorLog("事务失败,原因为: %v", err.Error())
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	//获取当前患者押金
	tmp := models.Deposit{}
	err = tx.Model(&models.Deposit{}).Where("his_patient_id = ? and user_org_id = ? and status = 1", his_user_id, orgid).Find(&tmp).Error
	if err != nil {
		return
	}
	//退回患者押金
	err = tx.Model(&models.Deposit{}).Where("id = ? and status = 1", tmp.ID).Updates(map[string]interface{}{
		"mtime":   time.Now().Unix(),
		"deposit": tmp.Deposit.Add(tmp_deposit),
	}).Error
	if err != nil {
		return
	}
	//生成一条退费记录
	dehistory := models.DepositHistory{
		UserOrgId:      orgid,
		HisPatientId:   his_user_id,
		DepositCode:    code,
		Deposit:        tmp_deposit,
		SurplusDeposit: tmp.Deposit.Add(tmp_deposit),
		DepositStatus:  4,
		Status:         1,
		CreateId:       0,
		Ctime:          time.Now().Unix(),
		Mtime:          time.Now().Unix(),
		TrialStatus:    1,
	}
	err = tx.Create(&dehistory).Error
	return
}
func GetorgName(orgid int64) (name string) {
	tmp := models.GetorgName{}
	XTReadDB().Model(&models.GetorgName{}).Where("id = ? ", orgid).Find(&tmp)
	return tmp.OrgName
}

// 根据id查询就诊号
func FindcodeToid(id int64) (code string) {
	tmp := models.GetMdtrtId{}
	XTReadDB().Model(&models.GetMdtrtId{}).Where("id = ?", id).Find(&tmp)
	return tmp.MdtrtId
}

// 根据id查询就诊号
func FindnumberToid(id int64) (number string) {
	tmp := models.GetMdtrtId{}
	XTReadDB().Model(&models.GetMdtrtId{}).Where("id = ?", id).Find(&tmp)
	return tmp.Number
}

// 扣费明细列表,查看详情按钮是否显示,0隐藏,1显示
func IsButtonShow(code string, orgid, his_patient_id int64) (tmp int64) {
	var total int
	XTReadDB().Model(&models.RefundList{}).Where(" user_org_id = ? and his_patient_id = ? and deposit_code = ? and deposit_status = 4 and status = 1", orgid, his_patient_id, code).Count(&total)
	if total == 0 {
		return 1
	} else {
		//预防万一,多加一个验证
		if total%2 == 0 {
			return 1
		} else {
			return 0
		}
	}
}

// 把其他的类型转换成decimal.Decimal类型
func ToDecimal(i interface{}) (d decimal.Decimal, err error) {
	switch i.(type) {
	case float64:
		d = decimal.NewFromFloat(i.(float64))
	case decimal.Decimal:
		d = i.(decimal.Decimal)
	case int64:
		d = decimal.NewFromFloat(float64(i.(int64)))
	case int:
		d = decimal.NewFromFloat(float64(i.(int)))
	default:
		err = fmt.Errorf("类型解析错误")
	}
	return
}

func TypeConversion(tmp float64) (s string) {
	switch tmp {
	case 1:
		s = "g"
	case 2:
		s = "mg"
	case 3:
		s = "u"
	case 4:
		s = "ml"
	case 5:
		s = "万U"
	case 6:
		s = "枚"
	case 7:
		s = "粒"
	case 8:
		s = "片"
	case 9:
		s = "支"
	case 10:
		s = "μg"
	case 11:
		s = "iu"
	case 12:
		s = "包"
	case 13:
		s = "袋"
	case 14:
		s = "万"
	case 15:
		s = "万iu"
	case 16:
		s = "丸"
	case 17:
		s = "盒"
	case 18:
		s = "瓶"
	case 19:
		s = "瓶(袋)"
	case 20:
		s = "次"
	}
	return s
}

func TypeConversion02(tmp string) (s string) {
	switch tmp {
	case "1":
		s = "g"
	case "2":
		s = "mg"
	case "3":
		s = "u"
	case "4":
		s = "ml"
	case "5":
		s = "万U"
	case "6":
		s = "枚"
	case "7":
		s = "粒"
	case "8":
		s = "片"
	case "9":
		s = "支"
	case "10":
		s = "μg"
	case "11":
		s = "iu"
	case "12":
		s = "包"
	case "13":
		s = "袋"
	case "14":
		s = "万"
	case "15":
		s = "万iu"
	case "16":
		s = "丸"
	case "17":
		s = "盒"
	case "18":
		s = "瓶"
	case "19":
		s = "瓶(袋)"
	case "20":
		s = "次"
	default:
		s = tmp
	}
	return s
}

// 获取本段时间内患者退款的总额
// orgid:机构id,stime:开始时间,etime:结束时间,patient_id:患者id
func RefundListSum(orgid, stime, etime, patient_id int64) (sum decimal.Decimal, err error) {
	var depo []models.RefundList
	err = XTReadDB().Model(&models.DepositHistory{}).Where("status = 1 and user_org_id = ? and trial_status = 1 and ctime >= ? and ctime <= ? and deposit_status = 3 and his_patient_id = ? ", orgid, stime, etime, patient_id).Find(&depo).Error
	if err != nil {
		return decimal.NewFromFloat(0), err
	}
	for i := 0; i < len(depo); i++ {
		sum = sum.Add(depo[i].Deposit)
	}
	return

}