Answer the question
In order to leave comments, you need to log in
Please do a code review, ok, not ok?
The task is to build a partner grid referral tree according to the following criteria:
calculate the total volume volume * coeff_h * coeff_cr for all levels of the referral system for a period of time
calculate profitability (amount profit) for a certain period of time
calculate the number of direct referrals and the number of all client referrals
<?php
namespace app\commands;
use app\models\Users;
use yii\console\Controller;
use \yii\helpers\BaseConsole;
use yii\helpers\Console;
/**
* Class ReferralController
* @package app\commands
*/
class ReferralController extends Controller
{
/**
* Метод для построения дерева и вывода общего количества рефералов
*/
public function actionTree(){
//Вводим uid полльзователя
$client_uid = BaseConsole::input("Введите uid пользователя: ");
$this->checkValidUid($client_uid);
//Получаем всех пользователей
$users = Users::find()
->select(['client_uid', 'partner_id'])
->asArray()
->all();
/**
* Функция прохода по всем пользователя и поиск рефералов (используется рекурсивный метод)
*
* @param $users //массив пользователей
* @param $client_uid //uid клиента
* @param int $level // уровень, то есть вложенность рефералов меняется если находим у реферала реферала
*/
function printBuildTree($users, $client_uid, $level = 0) {
foreach ($users as $arr) {
if ($arr['partner_id'] == $client_uid) {
if ($level == 0){
//Печать дерева
echo "|" . " |-- " . $arr['client_uid'] ."\n";
}
else{
//Печать дерева
echo "|" . str_repeat(" |-- ", $level + 1) . $arr['client_uid'] . "\n";
}
//Сама рекурсия, то есть находим реферала и для него ищем реферала
printBuildTree($users, $arr['client_uid'], $level + 1);
}
}
}
/**
* Функция подсчета прямых рефералов
*
* @param $users
* @param $client_uid
* @param int $level
* @param int $i
* @return int
*/
function getDirectReferral($users, $client_uid, $level = 0, $i = 0) {
foreach ($users as $arr) {
if ($arr['partner_id'] == $client_uid) {
if ($level == 0){
$i++;
$i += getDirectReferral($users, $arr['client_uid'], $level + 1);
}
}
}
return $i;
}
/**
* Функция подсчета всех рефералов
*
* @param $users
* @param $client_uid
* @param int $level
* @param int $i
* @return int
*/
function getAllReferral($users, $client_uid, $level = 0, $i = 0) {
foreach ($users as $arr) {
if ($arr['partner_id'] == $client_uid) {
$i++;
$i += getAllReferral($users, $arr['client_uid'], $level + 1);
}
}
return $i;
}
echo "|-- " . $client_uid . "\n";
$result = printBuildTree($users, $client_uid);
echo $result;
echo "Всего прямых рефералов: " . getDirectReferral($users, $client_uid) . "\n";
echo "Всего всех рефералов: " . getAllReferral($users, $client_uid) . "\n";
//82824897
}
/**
* Метод получения Прибыльности и Суммарного объема
*/
public function actionTotalVolume(){
//Вводим uid полльзователя
$client_uid = BaseConsole::input("Введите uid пользователя: ");
//Вводим дату ОТ
$date_from = BaseConsole::input("Введите дату ОТ в формате ГОД-Месяц-День ЧАСЫ:МИНУТЫ:СЕКУНДЫ ");
//Вводим дату ДО
$date_to = BaseConsole::input("Введите дату ДО в формате ГОД-Месяц-День ЧАСЫ:МИНУТЫ:СЕКУНДЫ ");
$this->checkValidUid($client_uid);
//Проверяем если ввели дату то делаем условие
if (!empty($date_from)){
$date_from_condition = ['>=', 't.close_time',
$date_from];
}
else{
$date_from_condition = [];
}
//Проверяем если ввели дату то делаем условие
if (!empty($date_to)){
$date_to_condition = ['<=', 't.close_time',
$date_to];
}
else{
$date_to_condition = [];
}
//Получаем всех пользователей
$users = (new \yii\db\Query())
->select(['volume', 'coeff_h', 'coeff_cr', 'a.client_uid', 'profit', 'partner_id'])
->from(['u' => 'users'])
->leftJoin(['a' => 'accounts'], 'a.client_uid = u.client_uid')
->leftJoin(['t' => 'trades'], 't.login = a.login')
->where(['u.client_uid' => $client_uid])
->andWhere($date_from_condition)
->andWhere($date_to_condition)
->all();
$total_volume = 0;
$sum_profit = 0;
foreach ($users as $arr) {
$total_volume += $arr['volume'] * $arr['coeff_h'] * $arr['coeff_cr'];
$sum_profit += $arr['profit'];
}
echo "Прибыльность: " . $sum_profit . "\n";
echo "Суммарный объем: " . $total_volume . "\n";
}
/**
* Функция проверки на пустоту и валидность uid
*
* @param $client_uid
*/
protected function checkValidUid($client_uid){
if (empty($client_uid) || !is_numeric($client_uid)){
$this->stdout("uid не может быть пустым и должен содержать число \n", Console::FG_RED);
exit();
}
}
}
Answer the question
In order to leave comments, you need to log in
In short, the main thing is that it works, in your case.
If a little expanded:
I agree with Maxim and add on my own that with complex selections using aggregating functions such as summation, etc. it is worth considering the option of denormalizing data to speed up and simplify calculations. Those. create a copy of the data with a structure that makes counting easier and faster.
Description of the data denormalization method
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question