Joywork/engine/classes/Funnel.php
2026-05-22 21:21:54 +03:00

529 lines
25 KiB
PHP

<?php
class Funnel {
private $agency_id = 0;
private $user_id = 0;
private $db = null;
public function __construct($db = null){
if($db){
$this->db = $db;
} else {
$pdo = new MysqlPdo(hst, ndb, user, pass);
$sql = "SET NAMES 'utf8'";
$pdo->query($sql);
$this->db = $pdo;
}
}
/**
* Установка id агентства
*/
public function set_agency_id($agency_id){
$this->agency_id = (int)$agency_id;
}
/**
* Установка id user
*/
public function set_user_id($user_id){
$this->user_id = $user_id;
}
/**
* Получение воронок
*/
public function get_funnels($section = null){
$funnels = array();
if($this->agency_id > 0){
if ($this->agency_id != 6841 && $this->agency_id != 6426 && $this->agency_id != 7384 && $this->agency_id != 7478 && $this->agency_id != 8353 && $this->agency_id != 8867 && $this->agency_id != 9588) {
$useCustomFunnel = true;
} else {
$useCustomFunnel = false;
}
$sqlCastom = "SELECT * FROM funnel_default WHERE agency_id = {$this->agency_id}";
$qCastom = $this->db->query($sqlCastom);
if($this->db->num_rows($qCastom) > 0){
$rCastom = $this->db->fetch_assoc($qCastom);
if($rCastom['is_client'] == 0) $useCustomFunnel = false;
}
if ($useCustomFunnel || $this->agency_id == 8353){
$sqlCastom = "SELECT * FROM funnel_default WHERE agency_id = {$this->agency_id}";
$qCastom = $this->db->query($sqlCastom);
if($this->db->num_rows($qCastom) > 0){
$rCastom = $this->db->fetch_assoc($qCastom);
$rCastom['is_no_see'] = 0;
$rCastom['id'] = 0;
if($section == 'requisitions' && $rCastom['is_req'] == 0){
/** */
} else
$arrayFunnel[] = $rCastom;
} else {
$arrayFunnel[] = array('id' => 0, 'name' => 'Обычные', 'is_client' => 1, 'is_req' => 1, 'is_stage' => 1, 'is_show_funnels' => 1, 'order_number' => 0, 'is_no_see' => 0);
}
}
$funnelsSql = "SELECT * FROM `funnel`
WHERE `agency_id` = '{$this->agency_id}' AND `deleted`= 0";
if($section == 'requisitions')
$funnelsSql .= " AND is_req = 1";
if($section == 'clients')
$funnelsSql .= " AND is_client = 1";
$funnelsSql .= " ORDER BY order_number, id";
$funnelsData = $this->db->query($funnelsSql);
while($funnel = $this->db->fetch_assoc($funnelsData)) {
$arrNoSeeUsers = array();
if($funnel['is_no_see']==1 && !empty($funnel['users_no_see'])){
$tempArrNoSee = json_decode($funnel['users_no_see'], true);
foreach($tempArrNoSee as $u){
if(strpos($u, 'all_') !== false){
$manId = str_replace('all_', '', $u);
$sql_u = "SELECT id FROM `users`
WHERE id = $manId OR
id_manager = $manId OR
id_manager IN (SELECT id FROM users WHERE id_manager = $manId)";
$q_u = $this->db->query($sql_u);
while($r_u = $this->db->fetch_row($q_u)){
$arrNoSeeUsers[] = (int)$r_u[0];
}
} else {
$arrNoSeeUsers[] = (int)$u;
}
}
}
$funnel['arr_no_see'] = $arrNoSeeUsers;
$arrayFunnel[] = $funnel;
}
foreach($arrayFunnel as $key=>$funnel){
$arrayOrder[$key]=$funnel['order_number'];
$arrayId[$key]=$funnel['id'];
}
array_multisort($arrayOrder, SORT_ASC, $arrayId, SORT_ASC, $arrayFunnel);
foreach($arrayFunnel as $key => $funnel){
$is_see = true;
if($this->user_id > 0){
if($funnel['is_no_see'] == 1 && !empty($funnel['users_no_see'])){
$is_see = false;
if(in_array($_SESSION['id'], $funnel['arr_no_see'])){
$is_see = true;
}
}
}
if($is_see){
$funnels[] = $funnel;
}
}
}
return $funnels;
}
/**
* Получение этапов воронки
*/
public function get_steps_funnel($funnel_id, $action){
$result = array();
if($funnel_id > 0){
$funnel_step = $this->db->query("SELECT id, name FROM funnel_steps WHERE funnel_id = ".$funnel_id." and deleted=0 order by order_number, branch");
$i = 0;
while($step = $this->db->fetch_assoc($funnel_step)){
if($action == 'transition_step' && $i==0){
/*** */
} else
$result[] = array('id'=>$step['id'], 'name'=>$step['name']);
$i++;
}
}
return $result;
}
/**
* Получение смежных воронок
*/
public function get_adjacent_funnels($data){
$error = array();
$result = array();
$steps = array();
$funnel_id = (int)$data->funnel_id;
if($this->agency_id == 0){
$error['empty_agency'] = 'Неверно задано агентство';
}
if(!empty($error)){
$result['error'] = $error;
return $error;
}
$sql = "SELECT * FROM `funnel` WHERE agency_id = {$this->agency_id} and id <> {$funnel_id} and deleted = 0 and is_no_see = 1 and (`users_no_see` is not null and `users_no_see` != '') order by order_number, id";
$q = $this->db->query($sql, true);
$funnels = [];
while($r = $this->db->fetch_assoc($q)){
$steps[$r['id']] = array('name'=>$r['name'], 'steps'=>array());
$r['users'] = array();
$r['users'][] = array('code'=>0, 'name'=>'Весь отдел (общие)');
if(!empty($r['users_no_see'])){
$ids_users_temp = json_decode($r['users_no_see']);
foreach($ids_users_temp as $uid){
if(strpos($uid, 'all_') !== false){
$manId = str_replace('all_', '', $uid);
$sql_u = "SELECT id FROM `users`
WHERE id = $manId OR
id_manager = $manId OR
id_manager IN (SELECT id FROM users WHERE id_manager = $manId)";
$q_u = $this->db->query($sql_u);
while($r_u = $this->db->fetch_row($q_u)){
$ids_users[] = (int)$r_u[0];
}
} else {
$ids_users[] = (int)$uid;
}
}
if(!empty($ids_users)){
$ids_users = array_unique($ids_users);
$sql_users = "SELECT * FROM users WHERE id in (".implode(',', $ids_users).")";
$q_users = $this->db->query($sql_users);
while($r_users = $this->db->fetch_assoc($q_users)){
$fio = trim($r_users['last_name'] . ' ' . $r_users['first_name'] . ' ' . $r_users['middle_name']);
$r['users'][] = array('code'=>(int)$r_users['id'], 'name'=>$fio);
}
}
}
$funnel_sql_steps = "SELECT id, name FROM funnel_steps WHERE funnel_id = {$r['id']} and deleted=0 order by order_number, branch";
/*if($_SESSION['id'] == 5238){
echo $funnel_sql;
}*/
$funnel_step = mysql_query($funnel_sql_steps);
while ($step = mysql_fetch_assoc($funnel_step)) {
$steps[$r['id']]['steps'][] = array('code'=>$step['id'], 'name'=>$step['name'], 'value'=>'');
}
$funnels[] = array('code'=>$r['id'], 'name'=>$r['name'], 'users'=>$r['users']);
}
$result['funnels'] = $funnels;
$result['steps'] = $steps;
return $result;
}
/**
* Получение списка воронок по заявке
*/
public function get_adjacent_funnels_req($data){
$result = array();
$req_id = (int)$data->req_id;
$funnels_adjacent = array();
$funnels_adjacent_text = '';
// $req_class = new Requisitions($this->db, true);
if($req_id > 0){
$html = '';
$steps = array();
$sql_adjacent_funnels = "SELECT * FROM adjacent_funnels WHERE req_id = {$req_id}";
$q_adjacent_funnels = $this->db->query($sql_adjacent_funnels);
while($r_adjacent_funnels = $this->db->fetch_assoc($q_adjacent_funnels)){
$funnels_adjacent[] = $r_adjacent_funnels;
$steps = $this->get_class_etap($r_adjacent_funnels);
$html .= $this->get_stagebar($steps);
}
$new_total = count($funnels_adjacent);
if($new_total > 0){
$new_text = 'Ещё '.$new_total;
if($new_total == 1){
$new_text .= ' воронка';
} else if($new_total > 1 && $new_total < 5){
$new_text .= ' воронки';
} else if($new_total > 4){
$new_text .= ' воронок';
}
$funnels_adjacent_text = $new_text;
}
$result['steps'] = $steps;
$result['html'] = $html;
$result['funnels_adjacent'] = $funnels_adjacent;
$result['funnels_adjacent_text'] = $funnels_adjacent_text;
return $result;
}
}
public function get_stagebar($steps){
$html = '';
$html .='<div class="stagebar">
<div class="stagebar_title">'.$steps['funnel_name'].'</div>
<div class="crm__small-stagebar">
<table>
<tbody>
<tr>';
foreach($steps['bar'] as $st){
$html .= '<td title="'.$st['name'].'" class="stage stage-funnel '.$st['classF'].' stageFunnel__'.$st['id'].'"><div data-stage="'.$st['id'].'" data-req="'.$steps['req_id'].'" data-adjacent="'.$steps['adjacent_id'].'" data-main="'.$st['main'].'" class="crm__small-step"></div></td>';
}/*
<td title="Первый звонок клиенту (исходящий)" class="stage stage-funnel active stageFunnel__132"><div data-stage="132" data-req="407744" data-main="1" class="crm__small-step"></div> <span class="next-stage">Первый звонок клиенту (исходящий)</span></td>
<td title="Отправка презентаций" class="stage stage-funnel nextStep stageFunnel__133"><div data-stage="133" data-req="407744" data-main="0" class="crm__small-step"></div> <span class="next-stage">Отправка презентаций</span></td>
<td title="Взял в работу" class="stage stage-funnel stageFunnel__135"><div data-stage="135" data-req="407744" data-main="0" class="crm__small-step"></div> <span class="next-stage">Взял в работу</span></td>
<td title="Бронь" class="stage stage-funnel stageFunnel__136"><div data-stage="136" data-req="407744" data-main="0" class="crm__small-step"></div> <span class="next-stage">Бронь</span></td><td title="Сделка" class="stage stage-funnel stageFunnel__138"><div data-stage="138" data-req="407744" data-main="0" class="crm__small-step"></div> <span class="next-stage">Сделка</span></td>
<td title="Отказ от брони" class="stage stage-funnel expired stageFunnel__141"><div data-stage="141" data-req="407744" data-main="0" class="crm__small-step"></div> <span class="next-stage">Отказ от брони</span></td>
<td title="Встреча на объекте/офисе" class="stage stage-funnel stageFunnel__134"><div data-stage="134" data-req="407744" data-main="0" class="crm__small-step"></div> <span class="next-stage">Встреча на объекте/офисе</span></td>
<td title="Клиент закрыт" class="stage stage-funnel expired stageFunnel__139"><div data-stage="139" data-req="407744" data-main="0" class="crm__small-step"></div> <span class="next-stage">Клиент закрыт</span></td>*/
$html .= '</tr>
<tr>
<td colspan="8">
<span id="step_funnel_erroradjacent_'.$steps['adjacent_id'].'" class="stepError"></span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="clear"></div>';
return $html;
}
//Определение воронки
public function get_class_etap($adjacent_funnel = array(), $reqId = 0, $funnel_id = false, $id = false) {
if(empty($adjacent_funnel) && ($reqId > 0 || $id > 0)){
if($id > 0){
$sql_adjacent_funnels = "SELECT * FROM adjacent_funnels WHERE id = {$id}";
} else {
$sql_adjacent_funnels = "SELECT * FROM adjacent_funnels WHERE req_id = {$reqId}";
if($funnel_id){
$sql_adjacent_funnels .= " AND funnel_id = {$funnel_id}";
}
}
$q_adjacent_funnels = $this->db->query($sql_adjacent_funnels);
$adjacent_funnel = $this->db->fetch_assoc($q_adjacent_funnels);
}
if(!empty($adjacent_funnel)){
$funnelId = (int)$adjacent_funnel['funnel_id'];
$stageId = (int)$adjacent_funnel['step_id'];
$reqId = (int)$adjacent_funnel['req_id'];
$id_adjacent_funnel = (int)$adjacent_funnel['id'];
$res = array('bar'=>array());
$res['req_id'] = $reqId;
$res['adjacent_id'] = $id_adjacent_funnel;
if($funnelId == 0){
$req_class = new Requisitions($this->db, true);
$steps = $req_class->steps;
$stage = "Новый";
foreach($steps as $step){
if($step['id'] == $stageId){
$stage = $step['name'];
}
}
$res['bar'] = $steps;
$res['stage'] = $stage;
$res['stageId'] = $stageId;
return $res;
} else {
// $change_step_query = $this->db->query("SELECT * FROM clients_funnel_step WHERE req_id = " . $reqId);
$next_id = 0;
$change_step = array('step_id' => 0);
//$lostDate = $client['date_create'];
if (!empty($adjacent_funnel['values'])) {
$change_step = $adjacent_funnel;
$next_id = $adjacent_funnel['next_id'];
$lostDate = $adjacent_funnel['updated_at'];
} else {
$lostDate = $adjacent_funnel['created_at'];
}
$next_steps = array();
$funnel_sql = "SELECT *, (SELECT name FROM funnel WHERE id = funnel_steps.funnel_id) as funnel_name FROM funnel_steps WHERE funnel_id = " . $funnelId . " and deleted=0 order by order_number, branch";
$funnel_step = $this->db->query($funnel_sql);
$isActive = true;
$classF = ' active';
$stage = '';
$stageId = 0;
if ((int)$change_step['step_id'] == 0) {
$isActive = false;
}
$arr_steps = array();
$countStep = $this->db->num_rows($funnel_step);
while ($step = $this->db->fetch_assoc($funnel_step)) {
$res['funnel_name'] = $step['funnel_name'];
$step['isActive'] = (int)$isActive;
$step['nextStep'] = false;
if ($step['main'] == 1 && !$isActive) {
$next_steps[] = $step['id'];
}
if ($step['id'] == (int)$change_step['step_id']) {
//$stage = $step['name'];
$next_steps = json_decode(htmlspecialchars_decode($step['next_step']));
if ($next_id == 0) {
//$stage = $step['name'];
//$next_steps = json_decode( htmlspecialchars_decode($step['next_step']));
//if($step['branch'] < $branch){
$isActive = false;
// }
}
} else if ($step['id'] == (int)$next_id) {
$isActive = false;
}
$arr_steps[$step['id']] = $step;
}
if ($next_id != 0 && !empty($next_steps)) {
foreach ($next_steps as $key => $st) {
if ($st != $next_id) {
unset($next_steps[$key]);
}
}
}
foreach ($arr_steps as $idstep => $step) {
$arr_steps[$idstep]['isNext'] = 0;
if (in_array($idstep, $next_steps)) {
$stage = $step['name'];
$stageId = $step['id'];
$arr_steps[$idstep]['isNext'] = 1;
}
}
$isActive = true;
foreach ($arr_steps as $idstep => $step) {
$classF = '';
if ($isActive) $classF = ' active';
if ($step['isNext'] == 1) {
$classF = ' nextStep';
$isActive = false;
}
// Покажет сколько мне дней
if(!isset($lostDate)) $lostDate = date('d.m.Y H:i:s');
$interval = date_diff(new DateTime(), new DateTime($lostDate))->days;
if ($interval >= $step['days_step']) {
$classF .= ' expired';
}
$step['classF'] = $classF;
$res['bar'][] = $step;
$res['stage'] = $stage;
$res['stageId'] = $stageId;
}
if($stageId == 0) $stageId = -1;
$sql = "UPDATE adjacent_funnels SET step_id_active = {$stageId} WHERE id = {$id_adjacent_funnel}";
$this->db->query($sql);
$res['sql'] = $sql;
return $res;
}
} else {
return array('error'=> 'empty_bar');
}
}
//Смена ответственного
public function save_who_work($data){
$id = (int)$data->id;
$who_work = (int)$data->who_work;
$confirm = 1;
if($who_work == 0){
$confirm = 0;
}
$sql = "UPDATE adjacent_funnels SET who_work = {$who_work}, confirm = {$confirm} WHERE id={$id}";
$this->db->query($sql);
}
//Добавление в смежную воронку
public function save_adjacent_funnels($data){
$req_id = (int)$data->req_id;
$who_work = (int)$data->who_work;
$funnel_id = (int)$data->funnel_id;
$user_id = (int)$data->user_id;
$confirm = 0;
if($who_work > 0){
$confirm = 1;
}
if($req_id > 0 && $funnel_id > 0){
$sql_a_f = "SELECT id FROM adjacent_funnels WHERE funnel_id = {$funnel_id} AND req_id = {$req_id}";
$row_a_f = $this->db->num_rows($this->db->query($sql_a_f));
if($row_a_f == 0){
$sqlreq = "SELECT * FROM requisitions WHERE id = {$req_id}";
$req = $this->db->fetch_assoc($this->db->query($sqlreq));
$this->db->query("INSERT INTO adjacent_funnels (funnel_id, req_id, parent_funnel_id, parent_step_id, confirm, who_work) VALUES ({$funnel_id}, {$req_id}, {$req['funnel_id']}, {$req['step_id']}, {$confirm}, {$who_work})");
$comment = "Заявка переведена в смежную воронку ";
$sql_funnel = "SELECT name FROM funnel WHERE id = {$funnel_id}";
$nameFunnel = "«".$this->db->fetch_assoc($this->db->query($sql_funnel))['name']."»";
$comment = $comment.' '.$nameFunnel;
$sql_event_adj = "INSERT INTO user_client_events SET req_id = {$req_id}, user_id = {$user_id}, type = 'comment', comment = '{$comment}', from_id = {$req['who_work']}";
$this->db->query($sql_event_adj);
}
}
}
/**
* Установка админских воронок юзеру
*/
public function set_template_funnels($agency_id, $user_id, $funnels){
$funnel_block_id = 0;
$i = 0;
if(is_array($funnels)){
foreach($funnels as $funnelId) {
$sql = "INSERT INTO funnel (`name`, `role`, `client_type`, `user_id`, `agency_id`, `order_number`, `is_req`, `is_client`)
SELECT `name`, `role`, `client_type`, {$user_id}, {$agency_id}, `order_number`, `is_req`, `is_client`
FROM funnel_admin WHERE id = {$funnelId}";
$this->db->query($sql);
$funnel_new_id = $this->db->insert_id();
if($i == 0){
$funnel_block_id = $funnel_new_id;
}
$array_steps_update = array();
$array_old_steps = array();
$sql_steps = "SELECT * FROM funnel_steps WHERE funnel_id = {$funnelId}";
$q_steps = $this->db->query($sql_steps);
while($r_steps = $this->db->fetch_assoc($q_steps)){
$sql_step = "INSERT INTO funnel_steps (`funnel_id`, `name`, `color_step`, `days_step`, `is_move_end_srok`, `tasks_move`, `start_parallel`, `stage`, `pole_end_list`, `tasks_list`, `name_step_task`, `docs_step_task`, `next_step_change`, `next_step`, `branch`, `main`, `order_number`, `arr_next_steps`, `pole_dop`, `pole_prev`, `deleted`, `doers`)
SELECT $funnel_new_id, `name`, `color_step`, `days_step`, `is_move_end_srok`, `tasks_move`, `start_parallel`, `stage`, `pole_end_list`, `tasks_list`, `name_step_task`, `docs_step_task`, `next_step_change`, `next_step`, `branch`, `main`, `order_number`, `arr_next_steps`, `pole_dop`, `pole_prev`, `deleted`, '[]' FROM funnel_steps
WHERE id = {$r_steps['id']}";
$this->db->query($sql_step);
$array_steps_update[$r_steps['id']] = $this->db->insert_id();
$array_old_steps[$r_steps['id']] = $r_steps;
}
foreach($array_steps_update as $step_old => $step_new){
$sql_update_step = "UPDATE funnel_steps SET
next_step = REPLACE(next_step, '&quot;".$step_old."&quot;', '&quot;".$step_new."&quot;'),
arr_next_steps = REPLACE(arr_next_steps, '&quot;".$step_old."&quot;', '&quot;".$step_new."&quot;')
WHERE funnel_id = {$funnel_new_id}";
//echo $sql_update_step."\n";
$this->db->query($sql_update_step);
}
$i++;
}
}
return $funnel_block_id;
}
}
?>