Esempio n. 1
0
 /**
  * 提前还款 - 全部(可人工指定还款金额)
  *
  * @param string $order_id 订单编号
  * @param int $money 还款金额
  * @param int $pay_type 还款类型:0(默认)管理员手工;1系统自动-来自支付宝;2系统自动-来自桂林银行
  * @param string $pay_trade_no 支付交易单号
  */
 public function repayAllCustom($order_id, $money, $pay_type = 0, $pay_trade_no = '')
 {
     if ($money <= 0) {
         return $this->_error('暂不支持还款金额<=0!');
     }
     $user = $pay_type > 0 ? ['uid' => 0, 'uname' => '系统'] : get_user();
     if (!$user) {
         return $this->_error('无法读取当前操作人信息!');
     }
     // 获取订单并判断状态
     $orderModel = new \Loan\Model\OrderModel();
     $order = $orderModel->find($order_id);
     if (!$order) {
         return $this->_error('订单不存在!');
     }
     if (!in_array($order['status'], $orderModel->allowRepayStatus($pay_type == 0))) {
         return $this->_error('当前订单状态不允许执行还款!');
     }
     if ($order['is_allow_prepayment'] < 1) {
         return $this->_error('此订单不允许提前还款!');
     }
     $time_limit = strtotime(date('Y-m-d 00:00:00'));
     // 开启事务,逐个账单进行处理
     $this->startTrans();
     $now = time();
     // 获取所有未还的账单
     $bills = $this->where(['order_id' => $order_id, 'status' => ['in', '0,1']])->order('issue')->select();
     if (!$bills) {
         return $this->_error('找不到待还款账单信息!');
     }
     // 获取缺少的本金
     $total_money_principal_remain = 0;
     foreach ($bills as $bill) {
         $total_money_principal_remain += max(0, $bill['money_principal'] - $bill['return_money']);
     }
     // 判断本金
     if (bccomp($money, $total_money_principal_remain, 2) < 0) {
         $this->rollback();
         return $this->_error('还款金额不足以支付本金!');
     }
     // 新增订单日志
     M('loan_order_log')->add(['order_id' => $order_id, 'created' => $now, 'uid' => $user['uid'], 'uname' => $user['uname'], 'status' => $order['status'], 'action' => '提前全部还款', 'remark' => $this->_payTypeName($pay_type) . '自定义金额还款:' . number_format($money, 2, '.', '')]);
     // 处理每一个账单
     $money_remain = $money;
     $total_money_principal = 0;
     foreach ($bills as $pos => $bill) {
         // 验证统计字段
         if (bccomp($bill['money_total'], $bill['money_principal'] + $bill['money_fee'] + $bill['money_delay'], 2) != 0) {
             $this->rollback();
             system_warn('检测到账单money_total字段异常!');
             return $this->_error('检测money_total字段存在异常,请检查!');
         }
         // 填满本金
         $bill_repay_money = max(0, $bill['money_principal'] - $bill['return_money']);
         // 计算实际还款金额(最后一期的还款金额是把剩余可用金额)
         if ($pos == count($bills) - 1) {
             $real_repay_money = $money_remain;
         } else {
             $real_repay_money = bccomp($money_remain, $bill_repay_money, 2) >= 0 ? $bill_repay_money : $money_remain;
         }
         $total_money_principal += $bill['money_principal'];
         if ($this->where(['order_id' => $order_id, 'issue' => $bill['issue'], 'return_money' => $bill['return_money'], 'status' => $bill['status']])->save(['status' => 2, 'return_time' => $now, 'return_money' => $bill['return_money'] + $real_repay_money]) != 1) {
             $this->rollback();
             return $this->_error('更新账单操作失败,请稍后重试!');
         }
         // 新增支付日志
         M('loan_bill_pay')->add(['order_id' => $order_id, 'issue' => $bill['issue'], 'created' => $now, 'type' => $pay_type, 'trade_no' => $pay_trade_no, 'money' => $real_repay_money]);
         // 更新剩余金额
         $money_remain -= $real_repay_money;
     }
     // 更新用户已归还金额(仅限本金)
     M('loan_user')->where('uid=' . $order['uid'])->setInc('total_money_return', $total_money_principal);
     M('loan_user')->where('uid=' . $order['uid'])->setInc('total_money_remain', $total_money_principal);
     // 更新 - 订单最后还款期号和已还款金额
     if (!$orderModel->where(['id' => $order_id, 'status' => $order['status']])->save(['status' => $orderModel::STATUS_FINISH_SUCCESS, 'last_bill_issue' => 0, 'loan_money_return' => ['exp', 'loan_money_return+' . $total_money_principal]])) {
         $this->rollback();
         return $this->_error('更新账单状态失败,请刷新后重试!');
     }
     // 新增日志
     M('loan_order_log')->add(['order_id' => $order_id, 'created' => time(), 'uid' => $user['uid'], 'uname' => $user['uname'], 'status' => $order['status'], 'action' => '还款全部完成']);
     // 更新资金流
     $orderModel->moneyFlow(3, $order_id, 0, $money, $user, $pay_trade_no);
     // 提交事务
     $this->commit();
     // 提醒短信
     if ($pay_type == 0) {
         $this->_sms($order['uid'], $money);
     }
     // 还款完成后处理
     $this->_after_success($order);
     return true;
 }