/** * 取消还款 * * @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; }