| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 | <?phpnamespace App\Modules\Finance\Services;use App\Modules\Channel\Models\Channel;use App\Modules\Finance\Models\Bill;use App\Modules\Finance\Models\CommissionRate;use App\Modules\Finance\Models\FinancialPayMerchantBalance;use App\Modules\Finance\Models\FinancialStat;use App\Modules\Trade\Models\Order;use DB;use Exception;/** * 渠道结算 *  * @property \App\Modules\Channel\Models\Channel $channel 渠道Model * @property string $day 日期 * @property float $rate 结算比例 */class CalcChannel{    private $channel;    private $day;    private $rate;    public function __construct(Channel $channel)    {        $this->day = date('Y-m-d', strtotime("-1 day"));        $this->channel = $channel;        $this->rate = $this->getRate();    }    /**     * 获取渠道当前结算比例     * @return float     */    private function getRate()    {        $rate = 0.0;        $commissionRates = CommissionRate::where('distribution_channel_id', $this->channel->id)            ->orderBy('begin_amount', 'asc')            ->get()            ->all();        if (count($commissionRates) == 1) {            $commissionRate = $commissionRates[0];            $rate = $commissionRate->rate;        } else if ($commissionRates) {            $startMonth = date('Y-m-01');            $endMonth = date('Y-m-d', strtotime("$startMonth +1 month -1 day"));            $rechargeAmountCount = Bill::where('distribution_channel_id', $this->channel->id)                ->where('date', '<=', $endMonth)                ->where('date', '>=', $startMonth)                ->sum('recharge_amount');            foreach ($commissionRates as $commissionRate) {                if ($rechargeAmountCount >=  $commissionRate->begin_amount) {                    //结束金额存在,并且结算金额小于结束金额,结束                    if (                        is_numeric($commissionRate->end_amount) &&                        $commissionRate->end_amount > 0 &&                        $rechargeAmountCount < $commissionRate->end_amount                    ) {                        $rate = $commissionRate->rate;                        break;                    }                    $rate = $commissionRate->rate;                }            }        }        return $rate;    }    /**     * 计算结算数据     */    public function calc()    {        $amount = $this->getChannelOrdersAmount();        $pay_merchants_amount = $this->getChannelPayMerchantsOrdersAmount();        try {            DB::beginTransaction();            $this->createBill($amount);            $this->createPayMerchantBills($pay_merchants_amount);            DB::commit();        } catch (Exception $e) {            DB::rollback();        }    }    /**     * 获取结算金额     * @return float     */    private function getChannelOrdersAmount()    {        return Order::join('pay_merchants', 'pay_merchants.id', 'orders.pay_merchant_id')            ->where('orders.status', 'PAID')->where('orders.distribution_channel_id', $this->channel->id)            ->where('orders.created_at', '<=', $this->day . '23:59:59')->where('orders.created_at', '>=', $this->day)            ->where('pay_merchants.is_self_channel', 1)            ->sum('orders.price');    }    /**     * 创建结算单     */    private function createBill(float $amount)    {        $params = [            'distribution_channel_id' => $this->channel->id,            'distribution_channel_name' => $this->channel->nickname,            'date' => $this->day,            'recharge_amount' => $amount,            'settlement_price' => $amount * $this->rate,            'rate' => $this->rate,            'tallage' => 0,        ];        Bill::create($params);        $this->updateFinance($params);    }    /**     * 更新渠道可提现金额     */    private function updateFinance(array $data)    {        $financialStat = FinancialStat::where('distribution_channel_id', $this->channel->id)->first();        if ($financialStat) {            $financialStat->enable_withdrawal_amount = (float) $financialStat->enable_withdrawal_amount + (float) $data['settlement_price'];            $financialStat->commission_rate = $this->rate;            $financialStat->save();        } else {            $params = [                'distribution_channel_id' => $this->channel->id,                'accumulative_withdrawal_amount' => 0,                'enable_withdrawal_amount' => $data['settlement_price'],                'latest_withdrawal_amount' => 0,                'withdraw_pending_amount' => 0,                'commission_rate' => $this->rate            ];            FinancialStat::create($params);        }    }    /**     * 获取不同的支付通道的结算金额     * @return array     */    private function getChannelPayMerchantsOrdersAmount()    {        return Order::join('pay_merchants', 'pay_merchants.id', 'orders.pay_merchant_id')            ->where('orders.status', 'PAID')->where('orders.distribution_channel_id', $this->channel->id)            ->where('orders.created_at', '<=', $this->day . '23:59:59')->where('orders.created_at', '>=', $this->day)            ->where('pay_merchants.is_self_channel', 1)            ->groupBy('pay_merchants.pay_company_id')            ->selectRaw('sum(orders.price) as amount,pay_company_id,pay_company_name')            ->get()            ->all();    }    /**     * 创建不同支付通道的结算单     */    private function createPayMerchantBills(array $pay_merchants_amount)    {        foreach ($pay_merchants_amount as $item) {            $params = [                'distribution_channel_id' => $this->channel->id,                'date' => $this->day,                'recharge_amount' => $item->amount,                'settlement_price' => $item->amount * $this->rate,                'rate' => $this->rate,                'pay_company_id' => $item->pay_company_id,                'tallage' => 0,            ];            BillPayMerchant::create($params);            $this->updatePayMerchantFinance($params);        }    }    /**     * 更新不同支付通道的可提现金额     */    private function updatePayMerchantFinance(array $data)    {        $financialStat = FinancialPayMerchantBalance::where('distribution_channel_id', $this->channel->id)            ->where('pay_merchant_company_id', $data['pay_company_id'])            ->first();        if ($financialStat) {            $financialStat->enable_withdrawal_amount = (float) $financialStat->enable_withdrawal_amount + (float) $data['settlement_price'];            $financialStat->commission_rate = $this->rate;            $financialStat->save();        } else {            $params = [                'distribution_channel_id' => $this->channel->id,                'pay_merchant_company_id' => $data['pay_company_id'],                'accumulative_withdrawal_amount' => 0,                'enable_withdrawal_amount' => $data['settlement_price'],                'latest_withdrawal_amount' => 0,                'withdraw_pending_amount' => 0,                'commission_rate' => $this->rate            ];            FinancialPayMerchantBalance::create($params);        }    }}
 |