protected function CreditAssign() { if ($this->response[ChinaPNR::RESP_CODE] == '000') { if ($order = CreditOrder::find()->where('status=' . CreditOrder::STATUS_UNPAID . ' and serial=:orderId', [':orderId' => $this->response[ChinaPNR::PARAM_ORDID]])->one()) { $credit = Credit::find()->where('id=:creditId', [':creditId' => $order->credit_id])->one(); if ($credit->in_stock_shares >= $order->shares) { $order->status = CreditOrder::STATUS_PAID; if ($order->validate()) { if ($order->save()) { if ($order->status == CreditOrder::STATUS_PAID) { $repaymentOrders = RepaymentOrder::find()->where('deal_number=:dealOrderId and status=1', [':dealOrderId' => $credit->order_id])->orderBy('deal_qishu')->all(); $remainedPrincipalAmt = 0.0; $remainedInterestAmt = 0.0; foreach ($repaymentOrders as $val) { if ($val->status == 1) { $remainedPrincipalAmt += $val->benjin; $remainedInterestAmt += $val->lixi; } } $creditCount = intval($remainedPrincipalAmt / 100) ? intval($remainedPrincipalAmt / 100) : ($remainedPrincipalAmt ? 1 : 0); foreach ($repaymentOrders as $repaymentOrderItem) { $originalOrderInterestAmt = $repaymentOrderItem->lixi; $currentOrderInterestAmt = 0.0; $totalInterestAmt = $originalOrderInterestAmt; if ($totalInterestAmt) { $currentOrderInterestAmt = round($totalInterestAmt / $creditCount * $order->shares, 4); $originalOrderInterestAmt = round($totalInterestAmt - $currentOrderInterestAmt, 4); Yii::$app->log('begin'); Yii::$app->log(serialize(self::balanceSplit($totalInterestAmt, [$currentOrderInterestAmt, $originalOrderInterestAmt]))); Yii::$app->log('end'); if ($splitInterest = self::balanceSplit($totalInterestAmt, [$currentOrderInterestAmt, $originalOrderInterestAmt])) { list($currentOrderInterestAmt, $originalOrderInterestAmt) = $splitInterest; } } $repaymentOrder = new RepaymentOrder(); $repaymentOrder->uid = $order->user_id; $repaymentOrder->deal_id = $repaymentOrderItem->deal_id; $repaymentOrder->deal_number = $order->serial; $repaymentOrder->deal_time = date('Ymd', $order->created_at); $repaymentOrder->deal_qishu = $repaymentOrderItem->deal_qishu; $repaymentOrder->Buid = $repaymentOrderItem->Buid; $repaymentOrder->benjin = $order->principal_amt * $order->shares; $repaymentOrder->lixi = $currentOrderInterestAmt; $repaymentOrder->benxi = $repaymentOrder->benjin + $repaymentOrder->lixi; $repaymentOrder->refund_time = $repaymentOrderItem->refund_time; $repaymentOrder->log = ''; if ($repaymentOrder->save()) { $originalOrderPrincipalAmt = $repaymentOrderItem->benjin - $repaymentOrder->benjin; if ($originalOrderPrincipalAmt > 0 || $originalOrderInterestAmt > 0) { $originalRepaymentOrder = new RepaymentOrder(); $originalRepaymentOrder->uid = $repaymentOrderItem->uid; $originalRepaymentOrder->deal_id = $repaymentOrderItem->deal_id; $originalRepaymentOrder->deal_number = $repaymentOrderItem->deal_number; $originalRepaymentOrder->deal_time = $repaymentOrderItem->deal_time; $originalRepaymentOrder->deal_qishu = $repaymentOrderItem->deal_qishu; $originalRepaymentOrder->Buid = $repaymentOrderItem->Buid; $originalRepaymentOrder->benjin = $originalOrderPrincipalAmt; $originalRepaymentOrder->lixi = $originalOrderInterestAmt; $originalRepaymentOrder->benxi = $originalRepaymentOrder->benjin + $originalRepaymentOrder->lixi; $originalRepaymentOrder->refund_time = $repaymentOrderItem->refund_time; $originalRepaymentOrder->log = $repaymentOrderItem->log; if ($originalRepaymentOrder->validate()) { $originalRepaymentOrder->save(); } } $repaymentOrderItem->status = 3; $repaymentOrderItem->save(); } } } } else { exit('抱歉,订单状态未能保存!'); } } else { var_dump($order->errors); } } } else { exit("矮油,订单无法找到哦,可能该单不存在,更可能是该单已经被处理过啦!"); } } else { exit("汇付说处理失败哦!" . urldecode($this->response[ChinaPNR::RESP_DESC])); } }
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; }