コード例 #1
0
ファイル: BillModel.class.php プロジェクト: torry999/lingshi
 /**
  * 取消还款
  *
  * @param int $order_id 订单号
  * @param mixed $issue 期数,字符串all表示取消全部还款,其它为数字,表示指定一期
  */
 public function repayCancel($order_id, $issue)
 {
     $user = get_user();
     if (!$user) {
         return $this->_error('无法读取当前操作人信息!');
     }
     // 获取订单并判断状态
     $orderModel = new \Loan\Model\OrderModel();
     $order = $orderModel->find($order_id);
     if (!$order) {
         return $this->_error('订单不存在!');
     }
     // 判断借款人
     $loan_user = get_user($order['uid']);
     if (!$loan_user) {
         return $this->_error('无法读取借款人信息!');
     }
     // 取消提前部分/全部还款
     if ($issue === 'part' || $issue == 'all') {
         $check_status = $issue == 'part' ? [$orderModel::STATUS_DELIVERY, $orderModel::STATUS_REPAY, $orderModel::STATUS_FINISH_SUCCESS] : [$orderModel::STATUS_FINISH_SUCCESS];
         if (!in_array($order['status'], $check_status)) {
             return $this->_error('当前订单状态不允许执行取消还款!');
         }
         $log = M('loan_order_log')->where(['order_id' => $order_id, 'action' => $issue == 'part' ? [['like', '提前部分%'], ['like', '提前全部%期还款'], 'or'] : '提前全部还款'])->order('id desc')->find();
         if (!$log) {
             return $this->_error('找不到还款操作日志!');
         }
         $total_money = explode(':', $log['remark'])[1] + 0;
         if ($total_money <= 0) {
             return $this->_error('无法读取操作的还款金额!');
         }
         // 根据操作时间读取当时操作的账单
         $bills = $this->where(['order_id' => $order_id, 'status' => 2, 'return_time' => $log['created']])->select();
         if (!$bills) {
             return $this->_error('无法读取当初操作的账单!');
         }
         // 判断订单涉及到的总金额
         $total_bill_money = 0;
         $total_money_principal = 0;
         $total_money_fee = 0;
         foreach ($bills as $vo) {
             $total_bill_money += $vo['return_money'];
             $total_money_principal += $vo['money_principal'];
             $total_money_fee += max(0, $vo['return_money'] - $vo['money_principal']);
         }
         if (bccomp($total_bill_money, $total_money, 2) != 0) {
             return $this->_error('账单还款金额[' . $total_bill_money . ']与操作日志金额[' . $total_money . ']不符,请联系技术改进!');
         }
         // 读取资金记录,判断金额
         $last_money_log = M('loan_money')->where(['type' => ['in', '2,3'], 'order_id' => $order_id, 'issue' => 0])->order('id desc')->field('id,money')->find();
         if (!$last_money_log) {
             return $this->_error('找不到资金记录编号!');
         }
         if (bccomp($last_money_log['money'], $total_money, 2) != 0) {
             return $this->_error('日志还款金额[' . $last_money_log['money'] . ']与资金记录金额[' . $total_money . ']不一致!');
         }
         // 开启事务,逐个账单进行处理
         $this->startTrans();
         $now = time();
         // 更新账单信息
         $this->where(['order_id' => $order_id, 'status' => 2, 'return_time' => $log['created']])->save(['status' => 0, 'return_time' => 0, 'return_money' => 0]);
         // 更新用户已归还金额(仅限本金)
         M('loan_user')->where('uid=' . $order['uid'])->setDec('total_money_return', $total_money_principal);
         M('loan_user')->where('uid=' . $order['uid'])->setDec('total_money_remain', $total_money_principal);
         // 更新 - 金额统计
         if ($total_money_fee > 0) {
             $statModel = new \Loan\Model\StatModel();
             $statModel->update($statModel::TYPE_ORDER_MONEY_FEE, $loan_user['university_id'], $total_money_fee * -1, $log['created']);
         }
         // 更新 - 订单最后还款期号和已还款金额
         if (!$orderModel->where(['id' => $order_id, 'status' => $order['status']])->save(['status' => $log['status'], 'last_bill_issue' => ['exp', '(select min(issue) from zj_loan_bill where order_id=id and status in (0,1))'], 'loan_money_return' => ['exp', 'loan_money_return-' . $total_money_principal]])) {
             return $this->_error('更新账单状态失败,请刷新后重试!', true);
         }
         // 新增订单日志
         M('loan_order_log')->add(['order_id' => $order_id, 'created' => $now, 'uid' => $user['uid'], 'uname' => $user['uname'], 'status' => $order['status'], 'action' => '取消' . $log['action'], 'remark' => '共' . count($bills) . '期,原提前还款金额' . $total_money . '元,涉及本金:' . $total_money_principal . '元']);
         // 删除资金记录
         M('loan_money')->where(['id' => $last_money_log['id']])->delete();
         // 删除账单支付记录
         M('loan_bill_pay')->where(['order_id' => $order_id, 'created' => $log['created']])->delete();
         // 订单金融数据
         M('loan_order_finance')->where(['order_id' => $order_id])->setDec('return_money', $total_money);
         // 提交事务
         $this->commit();
         return true;
     }
     // 指定某一期
     $issue = intval($issue);
     if ($issue < 1) {
         return $this->_error('还款期数必需大于0!');
     }
     if (!in_array($order['status'], [$orderModel::STATUS_DELIVERY, $orderModel::STATUS_LEND, $orderModel::STATUS_REPAY, $orderModel::STATUS_BREACH_CONTRACT, $orderModel::STATUS_FINISH_SUCCESS])) {
         return $this->_error('当前订单状态不允许执行取消还款!');
     }
     // 读取账单并判断状态
     $bill = $this->where(['order_id' => $order_id, 'issue' => $issue])->find();
     if (!$bill) {
         return $this->_error('找不到此账单信息!');
     }
     if (!in_array($bill['status'], [0, 2])) {
         return $this->_error('账单状态异常!');
     }
     // 所要取消的金额
     $total_money = $bill['return_money'];
     if ($total_money <= 0) {
         return $this->_error('此账单尚未还款!');
     }
     // 获取需要删除的支付日志
     $pay_logs = M('loan_bill_pay')->where(['order_id' => $order_id, 'issue' => $issue])->select();
     if (count($pay_logs) < 1) {
         return $this->_error('找不到账单支付记录!');
     }
     // 判断账单金额是否正确
     $pay_log_money = 0;
     foreach ($pay_logs as $pay_log) {
         $pay_log_money += $pay_log['money'];
     }
     if (bccomp($pay_log_money, $total_money, 2) != 0) {
         return $this->_error('账单支付日志总金额[' . $pay_log_money . ']与账单已返款金额[' . $total_money . ']不符!');
     }
     // 判断资金流金额是否正确
     $money_logs = M('loan_money')->where(['type' => ['in', '2,3'], 'order_id' => $order_id, 'issue' => $issue])->select();
     if (count($money_logs) < 1) {
         return $this->_error('找不到资金记录!');
     }
     $money_log_money = 0;
     foreach ($money_logs as $money_log) {
         $money_log_money += $money_log['money'];
     }
     if (bccomp($money_log_money, $total_money, 2) != 0) {
         return $this->_error('资金交易总金额[' . $money_log_money . ']与账单已返款金额[' . $total_money . ']不符!');
     }
     $now = time();
     // 更新 - 账单
     $this->startTrans();
     if (!$this->where(['order_id' => $order_id, 'issue' => $issue, 'status' => $bill['status']])->save(['status' => 0, 'return_time' => 0, 'return_money' => 0])) {
         $this->rollback();
         return $this->_error('操作失败,请稍后重试!');
     }
     // 删除支付日志
     M('loan_bill_pay')->where(['order_id' => $order_id, 'issue' => $issue])->delete();
     // 删除资金记录
     M('loan_money')->where(['type' => ['in', '2,3'], 'order_id' => $order_id, 'issue' => $issue])->delete();
     // 获取之前的状态,用于回退状态
     $before_status = M('loan_order_log')->where(['order_id' => $order_id])->order('id desc')->getField('status');
     // 新增订单日志
     M('loan_order_log')->add(['order_id' => $bill['order_id'], 'created' => $now, 'uid' => $user['uid'], 'uname' => $user['uname'], 'status' => $order['status'], 'action' => '取消还款', 'is_system' => 1, 'remark' => '第' . $issue . '期,金额:' . $total_money]);
     // 更新 - 订单状态
     if ($order['status'] == $orderModel::STATUS_FINISH_SUCCESS) {
         if (!$before_status || !$orderModel->where(['id' => $order_id, 'status' => $order['status']])->save(['status' => $before_status])) {
             $this->rollback();
             return $this->_error('更新账单状态失败,请联系技术检查!');
         }
     }
     // 账单从已还款变为未返款
     if ($bill['status'] == 2) {
         // 更新用户已归还金额(仅限本金)
         M('loan_user')->where('uid=' . $order['uid'])->setDec('total_money_return', $bill['money_principal']);
         M('loan_user')->where('uid=' . $order['uid'])->setDec('total_money_remain', $bill['money_principal']);
         // 更新 - 金额统计
         $money_fee = $bill['return_money'] - $bill['money_principal'];
         if ($money_fee > 0) {
             $statModel = new \Loan\Model\StatModel();
             $statModel->update($statModel::TYPE_ORDER_MONEY_FEE, $loan_user['university_id'], $money_fee * -1, $pay_log['created']);
         }
         // 更新 - 订单最后还款期号和已还款金额
         $orderModel->where(['id' => $order_id])->save(['loan_money_return' => ['exp', 'loan_money_return-' . $bill['money_principal']]]);
     }
     // 更新 - 订单最后还款期号
     $orderModel->where(['id' => $order_id])->save(['last_bill_issue' => ['exp', '(select min(issue) from zj_loan_bill where order_id=id and status in (0,1))']]);
     M('loan_order_finance')->where(['order_id' => $order_id])->setDec('return_money', $total_money);
     $this->commit();
     return true;
 }