Example #1
0
 public static function getCreditDetail($orderId, $transferShares, $discountRate)
 {
     $data = [];
     $model = static::find()->where('status=2 and deal_number=:orderId', [':orderId' => $orderId])->one();
     //@todo Search and Fetch order object from Credit order table, if this orderId is credit order id.
     if ($model) {
         $deal = Deal::findOne($model->deal_id);
         if ($deal && $deal->deal_status == 5) {
             $repaymentOrders = RepaymentOrder::find()->where('deal_number=:dealOrderId and status<>3', [':dealOrderId' => $model->deal_number])->orderBy('deal_qishu')->all();
             $lastRepaymentDate = null;
             $nextRepaymentDate = null;
             $retrievedPrincipalAmt = 0.0;
             $retrievedInterestAmt = 0.0;
             $remainedPrincipalAmt = 0.0;
             $remainedInterestAmt = 0.0;
             $currentTermId = 1;
             $currentRepaymentOrder = $repaymentOrders[0];
             foreach ($repaymentOrders as $repaymentOrder) {
                 if ($repaymentOrder->status == 1) {
                     $remainedPrincipalAmt += $repaymentOrder->benjin;
                     $remainedInterestAmt += $repaymentOrder->lixi;
                     if ($nextRepaymentDate < $repaymentOrder->refund_time) {
                         $nextRepaymentDate = $repaymentOrder->refund_time;
                     }
                     if (time() < $repaymentOrder->refund_time) {
                         $currentTermId = min($currentTermId, $repaymentOrder->deal_qishu);
                         $currentRepaymentOrder = $repaymentOrder;
                     }
                 }
                 if ($repaymentOrder->status == 2) {
                     $retrievedPrincipalAmt += $repaymentOrder->benjin;
                     $retrievedInterestAmt += $repaymentOrder->lixi;
                     if ($lastRepaymentDate < $repaymentOrder->refund_time) {
                         $lastRepaymentDate = $repaymentOrder->refund_time;
                     }
                 }
             }
             $orderEffectiveDate = max($deal->full_time, $model->order_time);
             $holdingPeriodInDay = static::loanTermCalc(date('Y-m-d', $orderEffectiveDate), null, time(), 'd', false)['period']->days;
             $creditCount = intval($remainedPrincipalAmt / 100) ? intval($remainedPrincipalAmt / 100) : ($remainedPrincipalAmt ? 1 : 0);
             //如果有债权可以转让,则继续计算
             if ($creditCount) {
                 /** @var integer $creditTransferShares 债权转让份数 */
                 $creditTransferShares = min($transferShares, $creditCount);
                 /**
                  * 当期利息分账,债权转让时,只有当期中尚未还款的利息与债权出让人有关系,因此只针对当期未还的利息进行分账
                  * @var integer $currentTermLength 当期还款订单涵盖了多少天
                  * @var integer $accruedInterestDays 出让人的应计利息天数,本质是上一还款日到今天的天数,不含当天(当天的收益属于债权受让人)
                  * @var float $creditUnitPrincipalAmt 每份债权的本金金额
                  * @var float $creditUnitInterestAmt 每份债权的利息金额
                  * @var float $creditUnitAccruedInterestAmt 债权出让人的每份债权当期利息收入 即,应计利息
                  */
                 if (!$lastRepaymentDate) {
                     $lastRepaymentDate = $deal->full_time;
                 }
                 $currentTermLength = static::loanTermCalc(date('Y-m-d', $lastRepaymentDate), null, $currentRepaymentOrder->refund_time, 'd', false)['period']->days;
                 $accruedInterestDays = static::loanTermCalc(date('Y-m-d', $lastRepaymentDate), null, time(), 'd', false)['period']->days;
                 $accruedInterestDays = $accruedInterestDays > 1 ? $accruedInterestDays - 1 : $accruedInterestDays;
                 $totalAccruedInterestAmt = $currentRepaymentOrder->lixi / $currentTermLength * $accruedInterestDays;
                 //                    $remainedInterestAmt = $remainedInterestAmt - $totalAccruedInterestAmt;
                 $creditUnitPrincipalAmt = $remainedPrincipalAmt / $creditCount;
                 $creditUnitInterestAmt = $remainedInterestAmt / $creditCount;
                 $creditUnitAccruedInterestAmt = $totalAccruedInterestAmt / $creditCount;
                 /**
                  * 债权相关价值价格等计算
                  * @var integer $creditLeavingPeriodInDay 债权剩余期限
                  * @var float $creditUnitValue 每份债权实际价值
                  * @var float $creditDiscountRate 折让率
                  * @var float $creditUnitPrice 每份债权的出让价格
                  * @var float $creditUnitActualValue 每份债权的应收本息金额
                  * @var float $creditFeeRate 债权转让的手续费率,默认是千五
                  * @var float $creditUnitFeeAmt 每份债权的转让费金额
                  * @var float $creditUnitIncomingAmt 每份债权于转让人而言的实际收入
                  *
                  */
                 $creditLeavingPeriodInDay = static::loanTermCalc(null, null, $deal->deal_end_date, 'd', false)['period']->days + 1;
                 $creditUnitValue = $creditUnitPrincipalAmt + $creditUnitAccruedInterestAmt;
                 $creditDiscountRate = $discountRate;
                 $creditUnitPrice = $creditUnitPrincipalAmt * (1 - $creditDiscountRate / 100) + $creditUnitAccruedInterestAmt;
                 $creditUnitActualValue = $creditUnitPrincipalAmt + $creditUnitInterestAmt;
                 $creditFeeRate = 0.003;
                 $creditUnitFeeAmt = $creditUnitPrincipalAmt * (1 - $creditDiscountRate / 100) * $creditFeeRate;
                 $creditUnitIncomingAmt = $creditUnitPrice - $creditUnitFeeAmt;
             }
             $data = ['deal_id' => $deal->deal_id, 'deal_title' => $deal->title, 'deal_rate' => $deal->syl, 'deal_end_date' => date('Y-m-d', $deal->deal_end_date), 'bidAmt' => $model->order_money, 'unitRetrievedPrincipalAmt' => $retrievedPrincipalAmt / $creditCount, 'unitRetrievedInterestAmt' => $retrievedInterestAmt / $creditCount, 'totalAmt' => $creditUnitPrice * $creditTransferShares, 'totalFeeAmt' => $creditUnitPrincipalAmt * (1 - $creditDiscountRate / 100) * $creditTransferShares * $creditFeeRate, 'totalIncomingAmt' => $creditUnitIncomingAmt * $creditTransferShares, 'holdingPeriodInDay' => $holdingPeriodInDay, 'user_id' => $model->uid, 'order_id' => $model->deal_number, 'leaving_period' => $creditLeavingPeriodInDay, 'repayment_term_id' => $currentRepaymentOrder->deal_qishu, 'shares' => $creditCount, 'transfer_shares' => $creditTransferShares, 'discount_rate' => $creditDiscountRate, 'unit_principal_amt' => $creditUnitPrincipalAmt, 'unit_interest_amt' => $creditUnitInterestAmt, 'unit_accrued_interest_amt' => $creditUnitAccruedInterestAmt, 'actual_unit_value' => $creditUnitActualValue, 'unit_value' => $creditUnitValue, 'unit_price' => $creditUnitPrice, 'transfer_fee_rate' => $creditFeeRate, 'unit_fee_amt' => $creditUnitFeeAmt, 'unit_incoming_amt' => $creditUnitIncomingAmt, 'accruedInterestDays' => $accruedInterestDays];
         } else {
             die('订单虽然是正确的,但很显然,该订单所依附的标的已执行完毕,不可进行债权转让了!');
         }
     } else {
         die('对不起,找不到该订单号!');
     }
     return $data;
 }
Example #2
0
 /**
  * @param $creditId
  * @param $shares
  * @param $userId
  */
 public function actionBuy($creditId, $shares, $userId, $orderId)
 {
     $respCode = -1;
     $link = null;
     $message = '请求异常';
     if ($credit = Credit::findOne($creditId)) {
         if ($credit->status == 0) {
             if ($credit->in_stock_shares >= $shares) {
                 $creditPrincipalAmt = number_format($credit->unit_principal_amt * $shares, 2, '.', '');
                 $bidOrder = DealOrder::find()->where('deal_number=:orderId', [':orderId' => $credit->order_id])->one();
                 $deal = Deal::find()->where('deal_id=:dealId', [':dealId' => $bidOrder->deal_id])->one();
                 $order = new CreditOrder();
                 $order->serial = $orderId;
                 $order->credit_id = $creditId;
                 $order->deal_id = $credit->deal_id;
                 $order->user_id = $userId;
                 $order->shares = $shares;
                 $order->amount = $credit->unit_price * $shares;
                 $order->fee = $credit->unit_fee_amt * $shares;
                 if ($order->validate()) {
                     if ($order->save()) {
                         $cnpnr = new ChinaPNR();
                         $cnpnr->creditAssign(CnpnrAccount::find()->where('uid=:userId', [':userId' => $bidOrder->uid])->one()->UsrCustId, CnpnrAccount::find()->where('uid=:userId', [':userId' => $userId])->one()->UsrCustId, $creditPrincipalAmt, $order->amount, $order->fee);
                         $bidDetails = ['BidDetails' => [['BidOrdId' => $bidOrder->deal_number, 'BidOrdDate' => $bidOrder->OrdDate, 'BidCreditAmt' => $creditPrincipalAmt, 'BorrowerDetails' => [['BorrowerCustId' => CnpnrAccount::find()->where('uid=:userId', [':userId' => $deal->uid])->one()->UsrCustId, 'BorrowerCreditAmt' => $creditPrincipalAmt, 'PrinAmt' => number_format(0, 2, '.', '')]]]]];
                         $cnpnr->BidDetails = Json::encode($bidDetails);
                         $cnpnr->ordId = $order->serial;
                         $cnpnr->ordDate = substr($order->serial, 0, 8);
                         $link = $cnpnr->getLink();
                         $respCode = 0;
                         $message = '成功';
                     }
                 }
             } else {
                 $respCode = -4;
             }
             //库存不足
         } else {
             $respCode = -3;
         }
     } else {
         $respCode = -2;
     }
     if ($respCode == -2) {
         $message = '指定的债权不存在,无法完成购买!';
     }
     if ($respCode == -3) {
         $message = '债权未在发售中,无法完成购买!';
     }
     if ($respCode == -4) {
         $message = '债权数量不足,无法完成购买!';
     }
     Yii::$app->response->format = Response::FORMAT_JSON;
     return ['respCode' => $respCode, 'link' => $link, 'message' => $message];
 }