<?php
/**
 * Created by PhpStorm.
 * User: stanley-king
 * Date: 16/4/12
 * Time: 下午4:57
 */


require_once(BASE_ROOT_PATH . '/helper/model_helper.php');
require_once(BASE_ROOT_PATH . '/helper/bonus_helper.php');
require_once(BASE_ROOT_PATH . '/helper/account_helper.php');


class RateMoney
{
    const ASC  = 1;
    const DESC = 2;
    const PRED_RATE = 30;
    private $mRates;
    private $mDirty;

    public function __construct($rates)
    {
        $this->mDirty = false;

        $this->mRates = [];
        foreach ($rates as $key => $val)
        {
            $val = intval(100 * $val + 0.5);
            if($val > 0) {
                $this->mRates[$key] = $val / 100;
            }
        }
        krsort($this->mRates);
    }

    public function add_bonuses($items)
    {
        foreach ($items as $item)
        {
            $bonus = \bonus\user_bonus::create_by_param($item);
            $rate = $bonus->bonus_rate();
            $amount = intval($bonus->remain_amount() * 100 + 0.5);

            if($amount <= 0) continue;

            $this->mDirty = true;
            if(isset($this->mRates[$rate]) == false) {
                $this->mRates[$rate] = 0.00;
            }
            $this->mRates[$rate] += $bonus->remain_amount();
        }
        krsort($this->mRates);
    }

    public function resort()
    {
        krsort($this->mRates);
    }

    public function is_enough(&$rate,$amount)
    {
        $amount = intval($amount * 100 + 0.5);
        foreach ($this->mRates as $key => $val)
        {
            $val = intval($val * 100 + 0.5);
            if($rate == -1)
            {
                if($val >= $amount) {
                    $rate = $key;
                    return true;
                }
            }
            else
            {
                if($rate == $key)
                {
                    $rate = $key;
                    if($val >= $amount) {
                        return true;
                    } else {
                        return false;
                    }
                }
            }
        }

        return false;
    }

    public function with_hold($rate,$amount)
    {
        if(isset($this->mRates[$rate])) {
            $this->mDirty = true;
            $this->mRates[$rate] = $this->mRates[$rate] - $amount;
        }
    }

    public function find_rate($amount)
    {
        if(empty($this->mRates)) return false;

        $rates = $this->mRates;
        ksort($rates);
        foreach ($rates as $rate => $money)
        {
            $money = intval($money * 100 + 0.5);
            $amount = intval($amount * 100 + 0.5);
            if($amount >= $money) {
                return array('rate' => $rate,'amount' => $money / 100);
            } else {
                return array('rate' => $rate,'amount' => $amount / 100);
            }
        }

        return false;
    }

    public function format()
    {
        $result = [];
        foreach ($this->mRates as $key => $val)
        {
            $val = intval($val * 100 + 0.5);
            if($val > 0) {
                $result[$key] = $val / 100;
            }
        }
        return $result;
    }
    public function total()
    {
        $total = 0.00;
        foreach ($this->mRates as $key => $amount) {
            $total += $amount;
        }
        return $total;
    }

    public function dirty() {
        return $this->mDirty;
    }
    public function clean() {
        $this->mDirty = false;
    }

    public function calc_rates($amount)
    {
        $rates = [];

        $left = intval($amount * 100 + 0.5);
        foreach ($this->mRates as $rate => $total)
        {
            if($left <= 0) break;
            if($rate > 100) continue;

            $total = intval($total * 100 + 0.5);
            if($total <= 0) {
                continue;
            }
            else
            {
                if($total >= $left) {
                    $rates[$rate] = $left / 100;
                    $left = 0;
                } else {
                    $rates[$rate] = $total / 100;
                    $left -= $total;
                }
            }
        }
        return $rates;
    }

    public function calc_money($price,&$rates)
    {
        $rates = [];
        $disc = 0;
        $left = intval($price * 100 + 0.5);
        foreach ($this->mRates as $rate => $total)
        {
            if($left <= 0) break;
            if($rate > 100) continue;

            $total = intval($total * 100 + 0.5);
            if($total <= 0) {
                continue;
            }
            else
            {
                $max_rate = intval($left * $rate / 100 + 0.5);
                if($total >= $max_rate) {
                    $disc += $max_rate;
                    $left = 0;
                    $rates[$rate] = $max_rate / 100;
                } else {
                    $disc += $total;
                    $left -= intval($total * 100 / $rate + 0.5);
                    $rates[$rate] = $total / 100;
                }
            }
        }
        $cur_price = intval($price * 100 + 0.5) - $disc;
        return $cur_price / 100;
    }

    public function calc_price($price,&$rates)
    {
        $cur_price = intval($this->calc_money($price,$rates) * 100 + 0.5);
        return $cur_price / 100;
    }
    static function scale() {
        return (100 - self::PRED_RATE) / 100;
    }
}

class predeposit_helper
{
    private $model_pd;
    private $member_id;
    private $mRates;
    private $mBonusState;
    private $mRateVersion; //用来记录，红包过期带来的红包变化

    public function __construct($member_id)
    {
        $this->model_pd = Model('predeposit');
        $this->member_id = $member_id;

        $pd_array = Model('member')->getMemberPdInfo($this->member_id);
        $this->mRateVersion  = intval($pd_array['rate_version']);
        $this->init_rate();
    }

    private function init_rate()
    {
        $fUpdate = false;
        if(isset($_SESSION['bonus_rate_version']) == false) {
            $fUpdate = true;
        }
        else
        {
            $version = $_SESSION['bonus_rate_version'];
            if($version != $this->mRateVersion) {
                $fUpdate = true;
            }
            else
            {
                if(isset($_SESSION['bonus_rate']) && isset($_SESSION['bonus_state'])) {
                    $this->mRates = new RateMoney($_SESSION['bonus_rate']);
                    $this->mBonusState = $_SESSION['bonus_state'];
                } else {
                    $fUpdate = true;
                }
            }
        }

        if($fUpdate || $this->need_update())
        {
            $mod_bonus = Model('user_bonus');
            $this->mRates = new RateMoney(array());
            $items = $mod_bonus->getUsableBonus($this->member_id);
            $this->mRates->add_bonuses($items);
            $bonus_rate = $this->mRates->format();

            $this->mBonusState = [];
            $querys = array('usable','expiring','used','expired');
            foreach ($querys as $state) {
                $cond = $this->query_cond($state);
                if($state == 'used') {
                    $sum = $mod_bonus->getSum($cond,'bonus_value');
                } else {
                    $sum = $mod_bonus->getSum($cond);
                }
                $this->mBonusState[$state] = doubleval($sum);
            }
            $this->write_rates($this->mBonusState,$bonus_rate);
            $this->mRates->clean();
            $_SESSION['bonus_update_time'] = time();
        }
    }

    private function need_update()
    {
        if(!isset($_SESSION['bonus_update_time'])) return true;

        $time = intval($_SESSION['bonus_update_time']);
        if(time() - $time > 86400) {
            return true;
        } else {
            return false;
        }
    }

    public function __destruct()
    {
        if($this->mRates != null && $this->mRates->dirty()) {
            $this->del_rates();
        }
    }

    public function bonus_rate() {
        return $this->mRates;
    }

    static public function order_cash($goods_amount, &$rates)
    {
        if(isset($_SESSION['bonus_rate']) == false) {
            $pred = new predeposit_helper($_SESSION['member_id']);
            $bonus_rate = $pred->bonus_rate();
        } else {
            $bonus_rate = new RateMoney($_SESSION['bonus_rate']);
        }

        return $bonus_rate->calc_money($goods_amount,$rates);
    }

    static public function login_bonus_price($goods_price, &$rates)
    {
        if(session_helper::isLogin())
        {
            if(isset($_SESSION['bonus_rate']) == false) {
                $pred = new predeposit_helper($_SESSION['member_id']);
                $bonus_rate = $pred->bonus_rate();
            } else {
                $bonus_rate = new RateMoney($_SESSION['bonus_rate']);
            }

            return $bonus_rate->calc_price($goods_price,$rates);
        }
        else
        {
            return ($goods_price);
        }
    }

    static public function unlogin_bonus_price($goods_price,$rate_moneys,&$rates)
    {
        if(!empty($rate_moneys)) {
            $bonus_rate = new RateMoney($rate_moneys);
            return $bonus_rate->calc_price($goods_price,$rates);
        } else {
            return $goods_price;
        }
    }

    static public function discount_gap($bonus_price,$goods_price)
    {
        $bonus_price = intval($bonus_price* 100 + 0.5);
        $discount = intval($goods_price * 70 + 0.5);

        if($bonus_price <= $discount) {
            return 0;
        } else {
            return ($bonus_price - $discount) / 100;
        }
    }

    public function bonus_state() {
        return $this->mBonusState;
    }

    private function query_cond($query_state)
    {
        static $stQuerys = array('usable','expiring','used','expired');
        static $day_secs = 24 * 3600;

        $cond = array('user_id' => $_SESSION['member_id'],'bonus_status' => 3);

        if(!empty($query_state) && in_array($query_state,$stQuerys))
        {
            if($query_state == 'usable') {
                $cond['remain_amount'] = ['gt','0.00'];
                $cond['usable_time'] = ['gt',time()];
                $cond['expired'] = 0;
            } elseif ($query_state == 'expiring') {
                $cond['usable_time&usable_time'] = ['_multi'=>true,['gt',time()],['elt',time() + 5 * $day_secs]];
                $cond['remain_amount'] = ['gt','0.00'];
                $cond['expired'] = 0;
            } elseif ($query_state == 'used') {
                $cond['remain_amount'] = '0.00';
                $cond['expired'] = 0;
            } elseif ($query_state == 'expired') {
                $cond['usable_time'] = ['lt',time()];
                $cond['expired'] = 1;
                $cond['remain_amount'] = ['gt','0.00'];
            } else {
            }
        }

        return $cond;
    }

    private function write_rates($bonus_state,$bonus_rate)
    {
        $_SESSION['bonus_state'] = $bonus_state;
        $_SESSION['bonus_rate'] = $bonus_rate;
        $_SESSION['bonus_rate_version'] = $this->mRateVersion;
    }

    private function del_rates()
    {
        if(isset($_SESSION['bonus_state'])) {
            unset($_SESSION['bonus_state']);
        }
        if(isset($_SESSION['bonus_rate'])) {
            unset($_SESSION['bonus_rate']);
        }

        if(isset($_SESSION['bonus_rate_version'])) {
            unset($_SESSION['bonus_rate_version']);
        }
    }

    public function topup_bonus($mobile)
    {
        $bonuses = bonus_helper::topup_bonus($this,$mobile);
        if($bonuses != false) {
            $this->del_rates();
        }

        return $bonuses;
    }

    public function total_bonus()
    {
        return $this->mRates->total();
    }

    public function is_enough($money) {
        return intval($this->total_bonus() * 100) >= intval($money * 100);
    }

    public function person_enough($money,&$bonus_rate)
    {
        if($this->mRates == null) return false;
        return $this->mRates->is_enough($bonus_rate,$money);
    }

    public function rates() {
        return $this->mRates == null ? false : $this->mRates;
    }

    public function makeby_bonus($param, $rate_moneys, $bonus_sn)
    {
        $result = bonus_helper::make_bonus($param,$rate_moneys);
        if($result == false) return false;

        foreach ($rate_moneys as $item) {
            $rate = intval($item['rate']);
            $val = $item['hold_amount'];
            bonus_helper::withold_bonus($this->member_id,$bonus_sn,$rate,$val,bonus_helper::send_bonus_withold);
        }

        $type_sn = $result['type_sn'];
        $money = $result['money'];
        $this->handout_bonus($money,$type_sn,session_helper::nickname(),"发送了{$money}元的红包.",\bonus\type::MakeSendType);

        foreach ($rate_moneys as $item) {
            $this->mRates->with_hold($item['rate'],$item['amount']);
        }

        return $result;
    }

    public function make_bonus($param,$rate_moneys)
    {
        $result = bonus_helper::make_bonus($param,$rate_moneys);
        if($result == false) return false;

        $rates = [];
        foreach ($rate_moneys as $item) {
            $rate = intval($item['rate']);
            $val = $item['hold_amount'];
            $rates[$rate] = $val;
        }
        bonus_helper::withold($this->member_id,$rates,bonus_helper::send_bonus_withold);

        $type_sn = $result['type_sn'];
        $money = $result['money'];
        $this->handout_bonus($money,$type_sn,session_helper::nickname(),"发送了{$money}元的红包.",\bonus\type::MakeSendType);

        foreach ($rate_moneys as $item) {
            $this->mRates->with_hold($item['rate'],$item['amount']);
        }

        return $result;
    }

    public function make_vote_type($param,$rate_moneys)
    {
        $result = bonus_helper::make_vote_type($param,$rate_moneys);
        if($result == false) return false;

        $rates = [];
        foreach ($rate_moneys as $item) {
            $rate = intval($item['rate']);
            $val = $item['hold_amount'];
            $rates[$rate] = $val;
        }
        bonus_helper::withold($this->member_id,$rates,bonus_helper::send_bonus_withold);

        $type_sn = $result['type_sn'];
        $money = $result['money'];
        $this->handout_bonus($money,$type_sn,session_helper::nickname(),"发送了{$money}元的红包.",\bonus\type::MakeSendType);

        foreach ($rate_moneys as $item) {
            $this->mRates->with_hold($item['rate'],$item['amount']);
        }

        return $result;
    }


    private function base_param($amount,$total_num)
    {
        $param = array();
        $param['total_amount'] = $amount;
        $param['total_num'] = $total_num;
        $param['send_type'] = 1;

        return $param;
    }

    public function share_bonus($bonus_sn,&$msg)
    {
        $bonus = bonus\user_bonus::create_by_sn($bonus_sn);
        if($bonus->spend_over()) {
            $msg = "该红包现金已经花光了~";
            return false;
        }

        $amount = $bonus->remain_amount();
        $param = $this->base_param($amount,1);

        $minfo = new member_info($this->member_id);
        $param['sender_id'] = $this->member_id;
        $param['sender_mobile'] = $minfo->mobile();
        $param['sender_name'] = $minfo->nickname();
        $param['make_type'] = \bonus\type::MakeSendType;
        $name = $minfo->nickname();
        $param['type_name'] = "{$name}";

        $type = \bonus\type::crate_by_input($param);

        $rate_moneys = [];
        $item['amount'] = $type->getTotal_amount();
        $item['num'] = $type->getTotal_num();
        $item['rate'] = $bonus->bonus_rate();
        $rate_moneys[] = $item;

        $result = bonus_helper::make_bonus($param,$rate_moneys);
        if($result == false) {
            return false;
        }
        else
        {
            if(bonus_helper::withold_bonus($this->member_id,$bonus->bonus_rate(),
                $bonus_sn,$type->getTotal_amount(),bonus_helper::send_bonus_withold))
            {
                $type_sn = $result['type_sn'];
                $money = $result['money'];
                $this->handout_bonus($money,$type_sn,session_helper::nickname(),"发送了{$money}元的红包.",\bonus\type::MakeSendType);
            }
            return $result;
        }
    }

    public function admin_make_bonus($param,$rate_moneys)
    {
        return bonus_helper::make_bonus($param,$rate_moneys);
    }

    public function bonus_expire($bouns)
    {
        try
        {
            $bonus_obj = bonus\user_bonus::create_by_param($bouns);
            if($bonus_obj->spend_over()) {
                return false;
            }
            $this->inc_rate_version();

            $minfo = new member_info($this->member_id);
            $data = array();
            $data['member_id'] = $this->member_id;
            $data['member_name'] = $minfo->nickname();
            $data['amount'] = $bonus_obj->remain_amount();
            $data['order_sn'] = $bonus_obj->bonus_sn();
            $data['admin_name'] = "熊猫美妆";
            $data['pdr_sn'] = $bonus_obj->bonus_sn();
            $data['lg_desc'] = "红包过期扣款";
            $this->model_pd->changePd("bonus_expire", $data);
            return true;
        } catch (Exception $ex) {
            return false;
        }
    }

    public function bonus_refund($bonus_type)
    {
        $types = bonus\type::create_by_paramer($bonus_type);
        QueueClient::push('onPredeposit',
            array('change_type' => 'bonus_refund','buyer_id'=>$types->sender_id(),'order_sn'=>$types->getType_sn()));
    }

    public function transform_money($member_id,$name,$amount)
    {
        $data = array();
        $data['member_id'] = $member_id;
        $data['member_name'] = is_null($name) ? '' : $name;
        $data['amount'] = $amount;
        $order_sn = $this->model_pd->makeSn();

        $data['order_sn'] = $order_sn;
        $data['admin_name'] = '平台管理员';
        $data['pdr_sn'] = $order_sn;
        $data['lg_desc'] = '版本升级，余额迁移.';
        $this->model_pd->changePd("sys_add_money",$data);
    }
    public function bonus_add_money($amount,$bonus_sn,$sender_name,$info,$make_type = 0)
    {
        $minfo = new member_info($this->member_id);

        $data = array();
        $data['member_id'] = $this->member_id;
        $data['member_name'] = $minfo->nickname();
        $data['amount'] = $amount;
        $data['order_sn'] = $bonus_sn;
        $data['admin_name'] = $sender_name;
        $data['pdr_sn'] = $bonus_sn;
        $data['lg_desc'] = $info;
        $this->model_pd->changePd("bonus_add_money", $data);
    }

    private function send_name($sender_name,$relay_id)
    {
        if($relay_id > 0) {
            $info = new member_info($relay_id);
            $nick = $info->nickname();
            if(!empty($nick)) return $nick;
        }
        return $sender_name;
    }
    public function add_bonus(bonus\user_bonus $bonus,bonus\type $type)
    {
        $this->inc_rate_version();

        $minfo = new member_info($this->member_id);
        $data = array();
        $data['member_id'] = $this->member_id;
        $data['member_name'] = $minfo->nickname();
        $data['amount'] = $bonus->bonus_value();
        $data['order_sn'] = $bonus->bonus_sn();
        $data['admin_name'] = $this->send_name($type->sender_name(),$type->relayer_id());
        $data['pdr_sn'] = $bonus->bonus_sn();
        $data['lg_desc'] = "";
        $data['make_type'] = $type->make_type();
        $this->model_pd->changePd("bonus_add_money", $data);
    }

    public function reduce_pred($amount)
    {
        $minfo = new member_info($this->member_id);
        $data = array();
        $data['member_id'] = $this->member_id;
        $data['member_name'] = $minfo->nickname();
        $data['amount'] = $amount;
        $data['pdr_sn'] = '';
        $data['lg_desc'] = "";
        $this->model_pd->changePd("sys_del_money", $data);
        $this->inc_rate_version();
    }

    public function handout_bonus($amount, $type_sn, $sender_name, $info,$make_type = 0)
    {
        $this->inc_rate_version();
        $minfo = new member_info($this->member_id);
        $data = array();
        $data['member_id'] = $this->member_id;
        $data['member_name'] = $minfo->nickname();
        $data['amount'] = $amount;
        $data['order_sn'] = $type_sn;
        $data['admin_name'] = $sender_name;
        $data['pdr_sn'] = $type_sn;
        $data['lg_desc'] = $info;
        $data['make_type'] = $make_type;

        $this->model_pd->changePd("hand_out_bonus", $data);
    }

    private function filter_sn($lg_desc)
    {
        $pos = mb_strpos($lg_desc,':');
        if($pos != false) {
            return mb_substr($lg_desc,$pos + 1);
        }
        return '';
    }
    private function filter_make_type($lg_desc)
    {
        $reg = '/make_type=(\d+)/i';
        $ret = preg_match($reg, $lg_desc, $arr);
        if($ret > 0) {
            return intval($arr[1]);
        } else {
            return 0;
        }
    }

    private function gen_send_title($sender_name,$make_type)
    {
        switch ($make_type) {
            case bonus\type::MakeSendType:
                return "发出红包";
            case bonus\type::MakeShakeGainType:
                return "被{$sender_name}摇走的红包";
            case bonus\type::MakeShakeLostType:
                return "摇飞红包到{$sender_name}";
            default:
                return "";
        }
    }

    private function gen_gain_title($sender_name,$make_type)
    {
        switch ($make_type) {
            case bonus\type::MakeSendType:
                return "{$sender_name}的红包";
            case bonus\type::MakeInviteType:
                return "{$sender_name}发出的邀请红包";
            case bonus\type::MakeBonusRefundType:
                return "未领红包退款";
            case bonus\type::MakeShakeGainType:
                return "摇到{$sender_name}的红包";
            case bonus\type::MakeShakeLostType:
                return "{$sender_name}摇到你这儿的红包";
            case bonus\type::MakePayRefundType:
                return "购物退款红包";
            case bonus\type::MakePayType:
                return "购物分享红包";
            case bonus\type::MakeOrderCancelType:
                return "订单取消退款";
            case bonus\type::MakeRegisterType:
                return "新人福利";
            case bonus\type::MakeEvaluateType:
                return "评论奖励红包";
            case bonus\type::MakeInviteRewardType:
                return "邀请好友，奖励红包";
            case bonus\type::MakeVoteType:
                return "投票或答题红包";
            case bonus\type::MakePayRewardInviterType:
                return "粉丝购物，奖励红包";
            case bonus\type::MakePayRewardInviteeType:
                return "雨露均沾红包";
            case bonus\type::MakeAllowanceType:
                return "购物津贴红包";

            default:
                return "";
        }
    }

    public function filter_pd_log($items)
    {
        $pdlogs = [];
        foreach($items as $val)
        {
            $item = array();
            $av_amount = $val['lg_av_amount'];
            $freeze_amount = $val['lg_freeze_amount'];
            $admin_name = $val['lg_admin_name'];
            $add_time = $val['lg_add_time'];
            $type = $val['lg_type'];
            $sn = $this->filter_sn($val['lg_desc']);

            $item['av_amount'] = $av_amount;
            $item['freeze_amount'] = $freeze_amount;
            $item['add_time'] = $add_time;

            $fAdd = true;
            if($type == 'order_pay') {
                $item['title'] = "支付订单";
                $item['sn'] = "订单号:{$sn}";
            }
            else if($type == 'order_freeze') {
                $item['title'] = "下单扣除红包";
                $item['sn'] = "订单号:{$sn}";
            }
            else if($type == 'order_cancel') {
                $item['title'] = "取消订单，解冻红包";
                $item['sn'] = "订单号:{$sn}";
            }
            else if($type == 'order_comb_pay') {
                $item['title'] = "下单，支付被冻结的红包";
                $item['sn'] = "订单号:{$sn}";
                $item['av_amount'] = $freeze_amount;
            }
            else if($type == 'recharge') {
                $item['title'] = "充值";
                $item['sn'] = "充值单号:{$sn}";
            }
            else if($type == 'refund') {
                $item['title'] = "确认退款";
            }
            else if($type == 'vr_refund') {
                $item['title'] = "虚拟兑码退款成功";
            }
            else if($type == 'hand_out_bonus') {
                $make_type = $this->filter_make_type($val['lg_desc']);
                $item['title'] = $this->gen_send_title($admin_name,$make_type);
                $item['sn'] = '';
            }
            else if($type == 'bonus_refund') {
                $item['title'] = "红包退款";
                $item['sn'] = '';
            }
            else if($type == 'bonus_add_money') {
                $make_type = $this->filter_make_type($val['lg_desc']);
                $item['title'] = $this->gen_gain_title($admin_name,$make_type);
                $item['sn'] = '';
            }
            else if($type == 'bonus_expire') {
                $item['title'] = "红包过期扣款";
                $item['sn'] = '';
            }
            else if($type == 'sys_add_money') {
                $item['title'] = "管理员调节预存款";
                $item['sn'] = '';
            }
            else if($type == 'sys_del_money') {
                $item['title'] = "管理员调节预存款";
                $item['sn'] = '';
            }
            else if($type == 'sys_freeze_money') {
                $item['title'] = "管理员冻结预存款";
                $item['sn'] = "充值单号:{$sn}";
            }
            else if($type == 'sys_unfreeze_money') {
                $item['title'] = "管理员解冻预存款";
                $item['sn'] = "充值单号:{$sn}";
            }
            else {
                $fAdd = false;
            }

            if($fAdd) {
                $pdlogs[] = $item;
            }
        }

        return $pdlogs;
    }

    public function calc_rates($order_pd_amount)
    {
        $rates = $this->mRates->calc_rates($order_pd_amount);
        return $rates;
    }

    public function calc_pred($order_info,$pd_amount,&$no_cash,&$rates)
    {
        $order_id = intval($order_info['order_id']);
        $mod_order = Model('order');

        $pred_amount = 0.00;
        $goods_list = $mod_order->getOrderGoodsList(array('order_id' => $order_id));
        foreach ($goods_list as $goods)
        {
            $goods_type = intval($goods['goods_type']);
            if($goods_type == 1) {
                $pred_amount += doubleval($goods['goods_pay_price']);
            }
        }

        $pred_amount = $pred_amount - $this->mRates->calc_money($pred_amount,$rates);
        $cur_used = intval($pred_amount * 100 + 0.5);
        $cur_used = $cur_used > $pd_amount  ? $pd_amount : $cur_used;

        $order_amount = intval($order_info['order_amount'] * 100 + 0.5);
        $order_pd_amount = intval($order_info['pd_amount'] * 100 + 0.5);

        if($order_amount == $cur_used) {
            $no_cash = true;
        } else {
            $no_cash = false;
        }

        return $cur_used - $order_pd_amount;
    }

    public function pay_bonus($rates)
    {
        $ret = bonus_helper::withold($this->member_id,$rates,bonus_helper::pay_order_withold);
        if($ret == true) {
            $this->inc_rate_version();
            $this->del_rates();
        }
        else
        {
            $cent = intval($ret * 100 + 0.5);
            if($cent > 0) {
                $this->inc_rate_version();
                $this->del_rates();
            }
        }

        return $ret;
    }

    public function find_bonus($amount)
    {
        $bonus_rate = $this->bonus_rate();
        return $bonus_rate->find_rate($amount);
    }

    public function inc_rate_version()
    {
        Model('member')->inc_rate_version($this->member_id);
    }
}