From b67a39532ac15b1b8cd3656adf2a980c8b098a40 Mon Sep 17 00:00:00 2001 From: mac Date: Mon, 6 Jul 2026 21:13:55 +0300 Subject: [PATCH] actual prod --- ajax/ajax_vue_requisitions.php | 1000 +++++++++++++++++----------- js/requisitions_client_vue.js | 1105 ++++++++++++++++++------------- js/requisitions_vue.js | 1119 +++++++++++++++++++------------- 3 files changed, 1916 insertions(+), 1308 deletions(-) diff --git a/ajax/ajax_vue_requisitions.php b/ajax/ajax_vue_requisitions.php index f10f44e..bc75e09 100644 --- a/ajax/ajax_vue_requisitions.php +++ b/ajax/ajax_vue_requisitions.php @@ -23,7 +23,7 @@ if($request == 'get_all'){ ini_set('display_errors', 1); error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE); }*/ - $start = microtime(true); + $start = microtime(true); $user_id = null; $funnel_id = false; @@ -48,7 +48,7 @@ if($request == 'get_all'){ } } if(isset($data->funnel_id)){ - $funnel_id = $data->funnel_id; + $funnel_id = $data->funnel_id; } if(isset($data->client_id)){ $client_id = $data->client_id; @@ -79,8 +79,8 @@ if($request == 'get_all'){ $req = new Requisitions($pdo); if(isset($data->view)){ - - $req->set_view($data->view); + + $req->set_view($data->view); } $req->set_agencyId($agency->agencyId); @@ -114,9 +114,9 @@ if($request == 'get_all'){ } $res = $req->get_all($user_id, $filtr, $funnel_id, $client_id, $object_id, true, $complex_room_id, $reqs_id, $is_cancel); - $end = round((microtime(true) - $start), 2) . "s."; - if (is_array($res)) - $res['_time_overage'] = $end; + $end = round((microtime(true) - $start), 2) . "s."; + if (is_array($res)) + $res['_time_overage'] = $end; $res['step_filter'] = $htmlFilter; @@ -153,7 +153,7 @@ if($request == 'add_edit') { $params['hot'] = $data->hot; $params['activities'] = $data->activities; $params['asfilter_id'] = (!empty($data->autosearch_filter_id) ? $data->autosearch_filter_id : 'NULL'); - + $params['employee_id'] = $data->employee_id; $params['field_models'] = $data->field_models; $params['contracts'] = $data->contracts; @@ -178,7 +178,13 @@ if($request == 'add_edit') { if ($data->complex_room_id) { $params['complex_room_id'] = $data->complex_room_id; } - + + // Заявку нельзя привязать к найденному листингу парсера — листинг read-only, сначала копирование объекта в свои. + // Offset-free: признак листинга — явный флаг is_external из JSON-тела (el.id коллизит с objects.id). + require_once $_SERVER['DOCUMENT_ROOT'] . '/engine/helpers/listing_guard.php'; + $objIsExternal = (isset($data->is_external) && $data->is_external) || (isset($data->src) && $data->src === 'ext'); + reject_if_external_listing($params['object_id'], $objIsExternal); + $req = new Requisitions($pdo); $result = $req->add_edit($params); if(isset($result['error'])){ @@ -198,7 +204,7 @@ if($request == 'add_edit') { $res['reservations']['data'] = $reservations; $res['reservations']['can_change_queue'] = $can_change_queue; - + //if($fu) echo json_encode($res); exit(); @@ -226,6 +232,11 @@ if($request == 'update_req'){ if(!empty($objects)){ $object = $objects[0]; } + // Привязать к заявке найденный листинг парсера нельзя — листинг read-only. + // Offset-free: признак листинга — явный флаг is_external из JSON-тела (el.id коллизит с objects.id). + require_once $_SERVER['DOCUMENT_ROOT'] . '/engine/helpers/listing_guard.php'; + $objIsExternal = (isset($data->is_external) && $data->is_external) || (isset($data->src) && $data->src === 'ext'); + reject_if_external_listing($object, $objIsExternal); $req_id_arr = explode(',',$req_id); foreach($req_id_arr as $req){ $object_id_req = 0; @@ -253,22 +264,22 @@ if($request == 'update_req'){ //Заявка по id if($request == 'get_req_id'){ - $req_id = $data->req_id; - $is_kanban = false; - if(isset($data->is_kanban) && $data->is_kanban > 0){ - $is_kanban = true; - } - $req = new Requisitions($pdo); - if(isset($data->user_id)){ - $agency = new User; - $agency->get($data->user_id); - $req->set_user($agency); - $req->set_agencyId($agency->agencyId); - $req->set_userId($data->user_id); - } - $res = $req->get_req_id((int) str_replace('req', '', $req_id), false, $is_kanban); - echo json_encode($res); - exit(); + $req_id = $data->req_id; + $is_kanban = false; + if(isset($data->is_kanban) && $data->is_kanban > 0){ + $is_kanban = true; + } + $req = new Requisitions($pdo); + if(isset($data->user_id)){ + $agency = new User; + $agency->get($data->user_id); + $req->set_user($agency); + $req->set_agencyId($agency->agencyId); + $req->set_userId($data->user_id); + } + $res = $req->get_req_id((int) str_replace('req', '', $req_id), false, $is_kanban); + echo json_encode($res); + exit(); } //Проверка на сочитание клиент/объект тип заявки @@ -279,18 +290,18 @@ if($request == 'check_object'){ $agency_id = $data->agency_id; $agency = new User; $agency->get($user_id); - + $filtr = (object) array('object_id'=>$object_id, 'type' => [2]); if ($req_id > 0) { - $filtr = (object) array('object_id'=>$req_id, 'not_id'=>$req_id, 'type' => [2]); + $filtr = (object) array('object_id'=>$req_id, 'not_id'=>$req_id, 'type' => [2]); } $res['result'] = 'done'; $req = new Requisitions($pdo); $req->set_user($agency); $req->set_agencyId($agency_id); $req->set_userId($user_id); - $search = $req->get_all($agency_id, $filtr, false, false, false, false); + $search = $req->get_all($agency_id, $filtr, false, false, false, false); if (!empty($search['req'])) { $res['result'] = 'error'; $res['mes'] = "Этот объект уже добавлен в заявку"; @@ -311,7 +322,7 @@ if($request == 'get_req_fields'){ $agency_id = (int)$data->agency_id; $req_id = (int)$data->req_id; $funnel_id = (int)$data->funnel_id; - $user_id = (int)$data->user_id; + $user_id = (int)$data->user_id; $req = new Requisitions($pdo); $res = $req->get_req_fields($agency_id, $req_id, $funnel_id, $user_id); @@ -334,12 +345,12 @@ if ($request == 'renew_req') { $req = new Requisitions($pdo); if ($req->renewReq($req_id, $user_id) === true) { - echo json_encode(['success' => true]); + echo json_encode(['success' => true]); } else { - echo json_encode(['success' => false]); + echo json_encode(['success' => false]); } - exit(); + exit(); } //Востановить несколько заявок @@ -353,7 +364,7 @@ if ($request == 'renew_reqs') { $ids = $data->ids_exception; } - $success = true; + $success = true; $req = new Requisitions($pdo); if($all == 1){ if(isset($_SESSION['where_req_campaigns'])){ @@ -364,24 +375,24 @@ if ($request == 'renew_reqs') { $q = $pdo->query($sql); while($r = $pdo->fetch_assoc($q)) { $reqs_id[] = $r['id']; - } + } } else { exit(); } } foreach($reqs_id as $req_id){ if (!($req->renewReq($req_id, $user_id) === true)) { - $success = false; + $success = false; } } - if ($success) { - echo json_encode(['success' => true]); - } else { - echo json_encode(['success' => false]); - } + if ($success) { + echo json_encode(['success' => true]); + } else { + echo json_encode(['success' => false]); + } - exit(); + exit(); } if ($request == 'take_from_closed_reqs') { @@ -478,11 +489,11 @@ if($request == 'get_bar_funnel'){ //Этапы воронки для канбана if($request == 'get_step_funnel'){ - $funnel_id = $data->funnel_id; - $req = new Requisitions($pdo); - $res = $req->get_etap_funnel($funnel_id); - echo json_encode($res); - exit(); + $funnel_id = $data->funnel_id; + $req = new Requisitions($pdo); + $res = $req->get_etap_funnel($funnel_id); + echo json_encode($res); + exit(); } //Получение клиента @@ -663,8 +674,8 @@ if($request == 'get_object'){ if ($pdo->num_rows($rezPhotoInfo) > 0) { while ($photoInfo = $pdo->fetch_assoc($rezPhotoInfo)) { - $obj['photo' . $photoInfo['sort_order']] = $photoInfo['photo']; - } + $obj['photo' . $photoInfo['sort_order']] = $photoInfo['photo']; + } } list($dateAdd, $timeAdd) = explode(" ", $obj['date_add']); @@ -686,7 +697,7 @@ if($request == 'get_object'){ if($request == 'get_objects_ids'){ error_reporting(E_ALL | E_STRICT); ini_set('display_errors', 1); - + $objectsId = $data->objects_id; $res = array(); $sql_obj = "SELECT * @@ -696,7 +707,7 @@ if($request == 'get_objects_ids'){ $q_obj = $pdo->query($sql_obj); if($pdo->num_rows($q_obj) > 0){ while ($obj = $pdo->fetch_assoc($q_obj)){ - + $res[] = $obj; } @@ -782,13 +793,13 @@ if($request == 'get_objects'){ //Найденный объект if($request == 'get_objects_find'){ - $object_id = $data->object_id; - $sql_obj = "SELECT id, nazv, adres FROM objects objects WHERE id=$object_id"; - $q_obj = $pdo->query($sql_obj); - $r_obj = $pdo->fetch_assoc($q_obj); - $res = array('id'=>$r_obj['id'], 'nazv'=>$r_obj['nazv'], 'adres'=>$r_obj['adres']); - echo json_encode($res); - exit(); + $object_id = $data->object_id; + $sql_obj = "SELECT id, nazv, adres FROM objects objects WHERE id=$object_id"; + $q_obj = $pdo->query($sql_obj); + $r_obj = $pdo->fetch_assoc($q_obj); + $res = array('id'=>$r_obj['id'], 'nazv'=>$r_obj['nazv'], 'adres'=>$r_obj['adres']); + echo json_encode($res); + exit(); } //Фильтр по умолчанию @@ -805,187 +816,187 @@ if($request == 'get_filtr'){ if($request == 'get_type'){ /* error_reporting(E_ALL | E_STRICT); ini_set('display_errors', 1);*/ - $req = new Requisitions($pdo); - $setting = false; - $active = false; - $no_archive = false; - if(isset($data->setting)){ + $req = new Requisitions($pdo); + $setting = false; + $active = false; + $no_archive = false; + if(isset($data->setting)){ $setting = $data->setting; - } - if(isset($data->agency_id)){ + } + if(isset($data->agency_id)){ $req->set_agencyId($data->agency_id); - } - if(isset($data->active)){ - $active = true; - } - if(isset($data->no_archive)){ + } + if(isset($data->active)){ + $active = true; + } + if(isset($data->no_archive)){ $no_archive = true; - } - $res = $req->get_type($setting,$active,$no_archive); - echo json_encode($res); - exit(); - - } - - //Смена очереди - if($request == 'set_type_order'){ - /*error_reporting(E_ALL | E_STRICT); - ini_set('display_errors', 1);*/ - $id = (int)$data->id; - $sort_order = (int)$data->sort_order; - $direct = $data->direct; - $req = new Requisitions($pdo); - if(isset($data->agency_id)){ - $req->set_agencyId($data->agency_id); - } - $res = $req->set_type_order($id, $sort_order, $direct); - - echo json_encode($res); - exit(); - } - - //Редактирование/добавление типа - if($request == 'edit_add_type') - { - /* error_reporting(E_ALL | E_STRICT); - ini_set('display_errors', 1);*/ - $result = array(); - $agency_id = (int)$data->agency_id; - $user_id = (int)$data->user_id; - $id = (int)$data->id; - $type = $data->type; - $heir = $data->heir; - $order = $data->order; - $type_type = $data->type_type; - - $req = new Requisitions($pdo); - $req->set_agencyId($agency_id); - $req->set_userId($user_id); - $result = $req->editAddType($id, $type, $heir, $order, $type_type); - - echo json_encode($result, JSON_UNESCAPED_UNICODE); - exit; - } - - //Удаление типа заявки - if($request == 'del_type_req') - { - $result = array(); - $agency_id = (int)$data->agency_id; - $user_id = (int)$data->user_id; - $id = (int)$data->id; - - if($id > 0){ - $req = new Requisitions($pdo); - $req->set_agencyId($agency_id); - $req->set_userId($user_id); - $result = $req->deletedType($id); - } - echo json_encode($result, JSON_UNESCAPED_UNICODE); - exit; - } - - //Архивирование типа заявки - if($request == 'archive_type_req') - { - $result = array(); - $agency_id = (int)$data->agency_id; - $user_id = (int)$data->user_id; - $id = (int)$data->id; - $order = $data->order; - - if($id > 0){ - $req = new Requisitions($pdo); - $req->set_agencyId($agency_id); - $req->set_userId($user_id); - $result = $req->archiveType($id, $order); - } - echo json_encode($result, JSON_UNESCAPED_UNICODE); - exit; - } - - //Архивирование типа заявки - if($request == 'recover_type_req') - { - $result = array(); - $agency_id = (int)$data->agency_id; - $user_id = (int)$data->user_id; - $id = (int)$data->id; - $order = $data->order; - - if($id > 0){ - $req = new Requisitions($pdo); - $req->set_agencyId($agency_id); - $req->set_userId($user_id); - $result = $req->recoverType($id, $order); - } - echo json_encode($result, JSON_UNESCAPED_UNICODE); - exit; - } - - //Установка причин закрытия - if($request == 'set_type_denial'){ - $type_id = (int)$data->type_id; - $agency_id = (int)$data->agency_id; - $denial_id = (int)$data->denial_id; - $check = (int)$data->check; - $req = new Requisitions($pdo); - // echo $agency_id; - $req->set_agencyId($agency_id); - $req->set_type_denial($type_id, $denial_id, $check); - } - - //Список причин - if($request == 'get_denials'){ - $result = array(); - $agency_id = (int)$data->agency_id; - $req = new Requisitions($pdo); - $req->set_agencyId($agency_id); - $result = $req->get_denial_work(1); - echo json_encode($result, JSON_UNESCAPED_UNICODE); - exit; - } - - - //Редактирование причин закрытия - if($request == 'edit_denial'){ - /*error_reporting(E_ALL | E_STRICT); - ini_set('display_errors', 1);*/ - $result = array(); - $agency_id = (int)$data->agency_id; - // $user_id = (int)$data->user_id; - $id = (int)$data->id; - $name = $data->name; - $req = new Requisitions($pdo); - $req->set_agencyId($agency_id); - // $req->set_userId($user_id); - $result = $req->editAddDenial($id, $name); - - echo json_encode($result, JSON_UNESCAPED_UNICODE); - exit; - } - - //Удаление причины - if($request == 'del_denial'){ - $result = array(); - $agency_id = (int)$data->agency_id; - // $user_id = (int)$data->user_id; - $id = (int)$data->id; - - $req = new Requisitions($pdo); - $req->set_agencyId($agency_id); - // $req->set_userId($user_id); - $result = $req->deleteDenial($id); - - echo json_encode($result, JSON_UNESCAPED_UNICODE); - exit; - - } + } + $res = $req->get_type($setting,$active,$no_archive); + echo json_encode($res); + exit(); + +} + +//Смена очереди +if($request == 'set_type_order'){ + /*error_reporting(E_ALL | E_STRICT); + ini_set('display_errors', 1);*/ + $id = (int)$data->id; + $sort_order = (int)$data->sort_order; + $direct = $data->direct; + $req = new Requisitions($pdo); + if(isset($data->agency_id)){ + $req->set_agencyId($data->agency_id); + } + $res = $req->set_type_order($id, $sort_order, $direct); + + echo json_encode($res); + exit(); +} + +//Редактирование/добавление типа +if($request == 'edit_add_type') +{ + /* error_reporting(E_ALL | E_STRICT); + ini_set('display_errors', 1);*/ + $result = array(); + $agency_id = (int)$data->agency_id; + $user_id = (int)$data->user_id; + $id = (int)$data->id; + $type = $data->type; + $heir = $data->heir; + $order = $data->order; + $type_type = $data->type_type; + + $req = new Requisitions($pdo); + $req->set_agencyId($agency_id); + $req->set_userId($user_id); + $result = $req->editAddType($id, $type, $heir, $order, $type_type); + + echo json_encode($result, JSON_UNESCAPED_UNICODE); + exit; +} + +//Удаление типа заявки +if($request == 'del_type_req') +{ + $result = array(); + $agency_id = (int)$data->agency_id; + $user_id = (int)$data->user_id; + $id = (int)$data->id; + + if($id > 0){ + $req = new Requisitions($pdo); + $req->set_agencyId($agency_id); + $req->set_userId($user_id); + $result = $req->deletedType($id); + } + echo json_encode($result, JSON_UNESCAPED_UNICODE); + exit; +} + +//Архивирование типа заявки +if($request == 'archive_type_req') +{ + $result = array(); + $agency_id = (int)$data->agency_id; + $user_id = (int)$data->user_id; + $id = (int)$data->id; + $order = $data->order; + + if($id > 0){ + $req = new Requisitions($pdo); + $req->set_agencyId($agency_id); + $req->set_userId($user_id); + $result = $req->archiveType($id, $order); + } + echo json_encode($result, JSON_UNESCAPED_UNICODE); + exit; +} + +//Архивирование типа заявки +if($request == 'recover_type_req') +{ + $result = array(); + $agency_id = (int)$data->agency_id; + $user_id = (int)$data->user_id; + $id = (int)$data->id; + $order = $data->order; + + if($id > 0){ + $req = new Requisitions($pdo); + $req->set_agencyId($agency_id); + $req->set_userId($user_id); + $result = $req->recoverType($id, $order); + } + echo json_encode($result, JSON_UNESCAPED_UNICODE); + exit; +} + +//Установка причин закрытия +if($request == 'set_type_denial'){ + $type_id = (int)$data->type_id; + $agency_id = (int)$data->agency_id; + $denial_id = (int)$data->denial_id; + $check = (int)$data->check; + $req = new Requisitions($pdo); + // echo $agency_id; + $req->set_agencyId($agency_id); + $req->set_type_denial($type_id, $denial_id, $check); +} + +//Список причин +if($request == 'get_denials'){ + $result = array(); + $agency_id = (int)$data->agency_id; + $req = new Requisitions($pdo); + $req->set_agencyId($agency_id); + $result = $req->get_denial_work(1); + echo json_encode($result, JSON_UNESCAPED_UNICODE); + exit; +} + + +//Редактирование причин закрытия +if($request == 'edit_denial'){ + /*error_reporting(E_ALL | E_STRICT); + ini_set('display_errors', 1);*/ + $result = array(); + $agency_id = (int)$data->agency_id; + // $user_id = (int)$data->user_id; + $id = (int)$data->id; + $name = $data->name; + $req = new Requisitions($pdo); + $req->set_agencyId($agency_id); + // $req->set_userId($user_id); + $result = $req->editAddDenial($id, $name); + + echo json_encode($result, JSON_UNESCAPED_UNICODE); + exit; +} + +//Удаление причины +if($request == 'del_denial'){ + $result = array(); + $agency_id = (int)$data->agency_id; + // $user_id = (int)$data->user_id; + $id = (int)$data->id; + + $req = new Requisitions($pdo); + $req->set_agencyId($agency_id); + // $req->set_userId($user_id); + $result = $req->deleteDenial($id); + + echo json_encode($result, JSON_UNESCAPED_UNICODE); + exit; + +} //Подсчет количества заявок или клиентов if($request == 'confirmation_total_item'){ - /* error_reporting(E_ALL | E_STRICT); - ini_set('display_errors', 1);*/ + /* error_reporting(E_ALL | E_STRICT); + ini_set('display_errors', 1);*/ $result = 0; $razdel = $data->razdel; $ids = array(); @@ -998,7 +1009,7 @@ if($request == 'confirmation_total_item'){ if (!empty($ids)){ $sql .= " AND ID NOT IN (".implode(',', $ids).")"; } - } + } //echo $sql; if($razdel == 'client'){ $where = $_SESSION['where_campaigns']; @@ -1007,7 +1018,7 @@ if($request == 'confirmation_total_item'){ if($sql != ''){ $q = $pdo->query($sql, true); - $rezult = $pdo->num_rows($q); + $rezult = $pdo->num_rows($q); } echo $rezult; @@ -1031,7 +1042,7 @@ if ($request == 'confirm_reqs') { $sql = "SELECT * FROM requisitions WHERE id in (".implode(',', $reqs).")"; if($all == 1){ if(isset($_SESSION['where_req_campaigns'])){ - $sql = $_SESSION['where_req_campaigns']; + $sql = $_SESSION['where_req_campaigns']; if (!empty($ids)){ $sql .= " AND ID NOT IN (".implode(',', $ids).")"; } @@ -1044,9 +1055,9 @@ if ($request == 'confirm_reqs') { while($r = $pdo->fetch_assoc($q)) { $confirm = 0; if ($new_who_work == $user_id) { - $confirm = 1; + $confirm = 1; } - if ($r['who_work'] != $new_who_work) { + if ($r['who_work'] != $new_who_work) { if (!$pdo->query("UPDATE requisitions SET who_work='{$new_who_work}', confirm={$confirm} WHERE id=".$r['id'])){ echo "error: "; } @@ -1295,7 +1306,7 @@ if ($request == 'send_transfer_closed_notifications') { file_put_contents(__DIR__ . '/debug_max.txt', "Max error: " . $e->getMessage() . "\n", FILE_APPEND); } } - + // Уведомление директору/админу, если лимит исчерпан if ($actual_after !== null && $limit_after !== null && $actual_after >= $limit_after) { @@ -1367,7 +1378,7 @@ if ($request == 'confirm_on_reqs') { $sql = "SELECT * FROM requisitions WHERE id in (".implode(',', $reqs).")"; if($all == 1){ if(isset($_SESSION['where_req_campaigns'])){ - $sql = $_SESSION['where_req_campaigns']; + $sql = $_SESSION['where_req_campaigns']; if (!empty($ids)){ $sql .= " AND ID NOT IN (".implode(',', $ids).")"; } @@ -1384,8 +1395,8 @@ if ($request == 'confirm_on_reqs') { $confirm = 1; $sql = "UPDATE requisitions SET confirm=1, who_work=$user_id WHERE id=$r[id]"; $pdo->query($sql); - // echo $sql."\n"; - + // echo $sql."\n"; + $sql = "UPDATE user_client_events SET user_id=$user_id WHERE req_id=$r[id] and type != 'step' and type != 'file'"; $pdo->query($sql); //echo $sql."\n"; @@ -1393,8 +1404,8 @@ if ($request == 'confirm_on_reqs') { //echo $sql."\n"; $pdo->query($sql); - $accepted = 'accepted'; - $sql = "INSERT INTO `events_clients` (user_id, req_id, from_id, event, `read`) VALUES ('".$user_id."', '".$r['id']."', '".$user_id."', '".$accepted."', '1')"; + $accepted = 'accepted'; + $sql = "INSERT INTO `events_clients` (user_id, req_id, from_id, event, `read`) VALUES ('".$user_id."', '".$r['id']."', '".$user_id."', '".$accepted."', '1')"; //echo $sql."\n"; $pdo->query($sql); @@ -1404,12 +1415,12 @@ if ($request == 'confirm_on_reqs') { $sql_op_step = "UPDATE clients_funnel_step SET date_update = NOW() WHERE req_id = {$r['id']}"; $pdo->query($sql_op_step); } else { - + if($r['funnel_id'] > 0){ $pdo->query("INSERT INTO clients_funnel_step (req_id) VALUES ({$r['id']})"); } } - + } @@ -1420,7 +1431,7 @@ if ($request == 'confirm_on_reqs') { if ($request == 'confirm_on_clients') { /*error_reporting(E_ALL | E_STRICT); ini_set('display_errors', 1);*/ - + $clients = $data->clients_id; $user_id = $data->user_id; $all = $data->all; @@ -1428,7 +1439,7 @@ if ($request == 'confirm_on_clients') { $sql = "SELECT * FROM clients WHERE id in (".implode(',', $clients).")"; if($all == 1){ if(isset($_SESSION['where_campaigns'])){ - $where = $_SESSION['where_campaigns']; + $where = $_SESSION['where_campaigns']; $sql = "SELECT * FROM clients WHERE 1 ".$where; } else { exit(); @@ -1444,31 +1455,31 @@ if ($request == 'confirm_on_clients') { $sql = "UPDATE clients SET confirm=1, who_work=$user_id WHERE id=$r[id]"; $pdo->query($sql); //echo $sql."\n"; - + $sql = "UPDATE user_client_events SET user_id=$user_id WHERE client_id=$r[id] and type != 'step' and type != 'file'"; $pdo->query($sql); //echo $sql."\n"; $sql = "UPDATE `events_clients` set `read` = 1, date_update='".date('Y-m-d H:i:s')."' WHERE client_id=$r[id] and from_id = ".$user_id; - // echo $sql."\n"; + // echo $sql."\n"; $pdo->query($sql); - $accepted = 'accepted'; - $sql = "INSERT INTO `events_clients` (user_id, client_id, from_id, event, `read`) VALUES ('".$user_id."', '".$r['id']."', '".$user_id."', '".$accepted."', '1')"; - // echo $sql."\n"; + $accepted = 'accepted'; + $sql = "INSERT INTO `events_clients` (user_id, client_id, from_id, event, `read`) VALUES ('".$user_id."', '".$r['id']."', '".$user_id."', '".$accepted."', '1')"; + // echo $sql."\n"; $pdo->query($sql); $sql_step = "SELECT * FROM clients_funnel_step WHERE client_id = {$r['id']}"; - $q_step = $pdo->query($sql_step); - if($pdo->num_rows($q_step) > 0){ - $sql_op_step = "UPDATE clients_funnel_step SET date_update = NOW() WHERE client_id = {$r['id']}"; - $pdo->query($sql_op_step); - } else { - - if($r['funnel_id'] > 0){ - $pdo->query("INSERT INTO clients_funnel_step (client_id) VALUES ({$r['id']})"); - } + $q_step = $pdo->query($sql_step); + if($pdo->num_rows($q_step) > 0){ + $sql_op_step = "UPDATE clients_funnel_step SET date_update = NOW() WHERE client_id = {$r['id']}"; + $pdo->query($sql_op_step); + } else { + + if($r['funnel_id'] > 0){ + $pdo->query("INSERT INTO clients_funnel_step (client_id) VALUES ({$r['id']})"); } - + } + } @@ -1488,11 +1499,11 @@ if($request == 'funnel_check') { } - + if($all == 1){ $reqs = array(); if(isset($_SESSION['where_req_campaigns'])){ - $sql = $_SESSION['where_req_campaigns']; + $sql = $_SESSION['where_req_campaigns']; if (!empty($ids)){ $sql .= " AND ID NOT IN (".implode(',', $ids).")"; } @@ -1504,7 +1515,7 @@ if($request == 'funnel_check') { exit(); } } - + $req = new Requisitions($pdo); foreach($reqs as $req_id){ @@ -1590,7 +1601,7 @@ if ($request == 'change_client_phone') { $sqlCheck = "SELECT `id` FROM `clients` WHERE (phone='$new_client_phone' OR id in (SELECT client_id FROM clients_phone2 WHERE phone = '$new_client_phone')) and (id_agent in (".implode(',', $usersIds).") or who_work in (".implode(',', $usersIds)."))"; - + $qCheck = mysql_query($sqlCheck); if (mysql_num_rows($qCheck) > 0) { @@ -1608,7 +1619,7 @@ if ($request == 'change_client_phone') { $sql_dop = "INSERT INTO clients_phone2 (client_id, phone) VALUES ({$client_id}, '{$new_client_phone}')"; if(!mysql_query($sql_dop)){ echo json_encode([ - 'success' => mysql_errno(), + 'success' => mysql_errno(), ]); } else { $phones2 = []; @@ -1630,9 +1641,9 @@ if ($request == 'change_client_phone') { } } else { echo json_encode([ - 'success' => 'empty_data', - ]); - } + 'success' => 'empty_data', + ]); + } exit(); } @@ -1651,49 +1662,49 @@ if($request == 'save_activites') { //получение договоров if($request == 'get_contracts'){ - $agency = new User; - $agency->checkPermissions(); - $parent_id = $data->parent_id; - $parent_type = $data->type; - $parent = null; - $id = 0; - if($parent_type == 'req'){ - $table = 'contracts_req'; - $id = (int)str_replace('req', '', $parent_id); - $parent = 'req_id'; - } else if ($parent_type == 'client') { - $table = 'contracts_client'; - $id = (int)$parent_id; - $parent = 'client_id'; - } else if ($parent_type == 'object') { - $table = 'contracts_object'; - $id = (int)$parent_id; - $parent = 'object_id'; - } - $contract = new Contract($pdo); - $contract->setAgencyId($agency->agencyId); - - $typesContracs = $contract->getTypesName(); - - $result['contracts'] = array(); - $result['contracts_name'] = ''; - if($id > 0){ - $sql = "SELECT * FROM $table WHERE {$parent} = {$id}"; - $q = $pdo->query($sql); - while($r = $pdo->fetch_assoc($q)){ - $name = $typesContracs[$r['type']]['type']." №".$r['number']." от ".date('d.m.Y',$r['date_start']). " по ".date('d.m.Y', $r['date_end']); - $expired = false; - $diff_date = ($r['date_end'] - time())/86400; - if($diff_date < (int)$r['days']){ - $expired = true; - } - $result['contracts'][] = array('id'=>$r['id'], 'name'=>$name, 'expired'=>$expired); - if($result['contracts_name'] != '') $result['contracts_name'] .= ", "; - $result['contracts_name'] .= $name; + $agency = new User; + $agency->checkPermissions(); + $parent_id = $data->parent_id; + $parent_type = $data->type; + $parent = null; + $id = 0; + if($parent_type == 'req'){ + $table = 'contracts_req'; + $id = (int)str_replace('req', '', $parent_id); + $parent = 'req_id'; + } else if ($parent_type == 'client') { + $table = 'contracts_client'; + $id = (int)$parent_id; + $parent = 'client_id'; + } else if ($parent_type == 'object') { + $table = 'contracts_object'; + $id = (int)$parent_id; + $parent = 'object_id'; } - } - echo json_encode($result, JSON_UNESCAPED_UNICODE); - exit; + $contract = new Contract($pdo); + $contract->setAgencyId($agency->agencyId); + + $typesContracs = $contract->getTypesName(); + + $result['contracts'] = array(); + $result['contracts_name'] = ''; + if($id > 0){ + $sql = "SELECT * FROM $table WHERE {$parent} = {$id}"; + $q = $pdo->query($sql); + while($r = $pdo->fetch_assoc($q)){ + $name = $typesContracs[$r['type']]['type']." №".$r['number']." от ".date('d.m.Y',$r['date_start']). " по ".date('d.m.Y', $r['date_end']); + $expired = false; + $diff_date = ($r['date_end'] - time())/86400; + if($diff_date < (int)$r['days']){ + $expired = true; + } + $result['contracts'][] = array('id'=>$r['id'], 'name'=>$name, 'expired'=>$expired); + if($result['contracts_name'] != '') $result['contracts_name'] .= ", "; + $result['contracts_name'] .= $name; + } + } + echo json_encode($result, JSON_UNESCAPED_UNICODE); + exit; } @@ -1718,7 +1729,7 @@ if($request == 'get_clientid_req'){ } -//Клиенты +//Клиенты if($request == 'get_clients_list'){ $search = $data->search; $searchUserId = $_SESSION['id']; @@ -1826,7 +1837,7 @@ if($request == 'get_clients_list'){ foreach($usersIds as $mm2) { $arrIdUser[] = $mm2; - //$wid[] = "doers like '%"".$mm2."":1%'"; + //$wid[] = "doers like '%"".$mm2."":1%'"; } @@ -1866,12 +1877,12 @@ if($request == 'get_clients_list'){ $res['phones_dop'] = ''; - $sql_cl2 = "SELECT phone FROM `clients_phone2` WHERE client_id = {$r['id']}"; - $q_cl2 = $pdo->query($sql_cl2); - while($r_cl2 = $pdo->fetch_assoc($q_cl2)){ - if($res['phones_dop'] != '') $res['phones_dop'] .= ', '; - $res['phones_dop'] .= mask_phone_value_if_needed($r_cl2['phone']); - } + $sql_cl2 = "SELECT phone FROM `clients_phone2` WHERE client_id = {$r['id']}"; + $q_cl2 = $pdo->query($sql_cl2); + while($r_cl2 = $pdo->fetch_assoc($q_cl2)){ + if($res['phones_dop'] != '') $res['phones_dop'] .= ', '; + $res['phones_dop'] .= mask_phone_value_if_needed($r_cl2['phone']); + } $clients_all[] = $res; } @@ -1880,8 +1891,8 @@ if($request == 'get_clients_list'){ exit; } - //Типы недвижимости - if($request == 'get_property_types'){ +//Типы недвижимости +if($request == 'get_property_types'){ $result = array(); $sql = "SELECT * FROM `property_types`"; $q = $pdo->query($sql); @@ -1890,10 +1901,10 @@ if($request == 'get_clients_list'){ } echo json_encode($result, JSON_UNESCAPED_UNICODE); exit; - } +} - //Заявки для объединения - if($request == 'get_union_reqs') { +//Заявки для объединения +if($request == 'get_union_reqs') { $result = array(); $reqs = $data->reqs; $agency_id = $data->agency_id; @@ -1908,15 +1919,15 @@ if($request == 'get_clients_list'){ echo json_encode($result, JSON_UNESCAPED_UNICODE); exit; - } +} - //Сохранение объединения заявок - if($request == 'save_union_req'){ +//Сохранение объединения заявок +if($request == 'save_union_req'){ $main_id = $data->main_id; $reqs = $data->reqs; $user_id = (int)$data->user_id; $agency_id = (int)$data->agency_id; - + if($user_id > 0 && !empty($reqs) && $main_id > 0){ $req = new Requisitions($pdo, true); $req->set_agencyId($agency_id); @@ -1926,10 +1937,10 @@ if($request == 'get_clients_list'){ echo json_encode($result, JSON_UNESCAPED_UNICODE); exit; - } +} - //Список присоединенных заявок - if($request == 'get_reqs_joint'){ +//Список присоединенных заявок +if($request == 'get_reqs_joint'){ $result = array(); $req_id = (int)$data->req_id; if($req_id > 0){ @@ -1941,7 +1952,7 @@ if($request == 'get_clients_list'){ } echo json_encode($result, JSON_UNESCAPED_UNICODE); exit; - } +} if ($request == 'mass_take_from_closed') { $reqs = $data->reqs_id; @@ -1995,12 +2006,12 @@ if ($request == 'mass_take_from_closed') { } if($request == 'get_view_page'){ - + $user_id = (int)$data->user_id; $viewPage = 'list'; $sql_view = "SELECT * FROM user_views_page WHERE user_id = {$user_id}"; - - + + $q_view = $pdo->query($sql_view); if($pdo->num_rows($q_view) > 0){ $r_view = $pdo->fetch_assoc($q_view); @@ -2010,30 +2021,30 @@ if($request == 'get_view_page'){ exit; } - /** - * Сохранение настроек вида страницы - * - */ - if($request == 'set_view_page'){ +/** + * Сохранение настроек вида страницы + * + */ +if($request == 'set_view_page'){ $user_id = (int)$data->user_id; $view = $data->view; $sql = "SELECT * FROM user_views_page WHERE user_id = {$user_id}"; $q = $pdo->query($sql); if($pdo->num_rows($q) > 0){ - $r = $pdo->fetch_assoc($q); - $sql_up = "UPDATE user_views_page SET view_req = '{$view}' WHERE id = {$r['id']}"; - $pdo->query($sql_up); + $r = $pdo->fetch_assoc($q); + $sql_up = "UPDATE user_views_page SET view_req = '{$view}' WHERE id = {$r['id']}"; + $pdo->query($sql_up); } else { - $sql_in = "INSERT INTO user_views_page (user_id, view_req) values ({$user_id}, '{$view}')"; - $pdo->query($sql_in); + $sql_in = "INSERT INTO user_views_page (user_id, view_req) values ({$user_id}, '{$view}')"; + $pdo->query($sql_in); } - } +} - /** - * Финансы - */ - if($request == 'req_finance_info'){ +/** + * Финансы + */ +if($request == 'req_finance_info'){ $is_block = false; $html = ''; $req_id = (int)$data->req_id; @@ -2110,28 +2121,28 @@ if($request == 'get_view_page'){ } } - + if($is_block){ if($expected_commission > 0){ - - if($r['deleted'] == 0) { + + if($r['deleted'] == 0) { $html .= '

'; $html .= 'Ожидаемая комиссия '.$expected_commission; - + $html .= ''; - + $html .= ''; $html .= ''; - $html .= '

'; - } - + $html .= '

'; + } + } if($r['deleted'] == 1 && $r['confirm'] == 10){ $summa = (int)$r['summa']; $html .= '

Фактическая комиссия '.$summa.'

'; } - + if($deposit > 0){ $html .= '

'.$nameEventDeposit.' '.$deposit; if($r['deleted'] == 0) { @@ -2145,7 +2156,7 @@ if($request == 'get_view_page'){ if($expected_commission > 0 && $r['deleted'] == 0){ $surcharge = $expected_commission - $deposit; $html .= '

Доплата '.$surcharge.'

'; - + } if($expensesTotal > 0){ @@ -2156,7 +2167,7 @@ if($request == 'get_view_page'){ $html .= '

'.$expense['name'].' '.$amount.' Комментарий: '.$expense['comment']; if($r['deleted'] == 0){ $html .= ''; - + $html .= ''; $html .= ''; $html .= ''; @@ -2171,12 +2182,12 @@ if($request == 'get_view_page'){ $result = array('is_block'=>$is_block, 'html'=>$html); echo json_encode($result, JSON_UNESCAPED_UNICODE); exit; - } +} - /** - * Редактирование финансов - */ - if($request == 'edit_req_finance_info'){ +/** + * Редактирование финансов + */ +if($request == 'edit_req_finance_info'){ $reqId = (int)$data->req_id; $userId = (int)$data->user_id; $depositId = 0; @@ -2210,7 +2221,7 @@ if($request == 'get_view_page'){ $sql_up = "UPDATE requisitions SET expected_commission = {$value} WHERE id = {$reqId}"; if($pdo->query($sql_up)) { $sql_event = "INSERT INTO events_clients (user_id, from_id, req_id, `event`, dop_text, `read`) VALUES ({$userId}, {$userId}, {$reqId}, 'update', '{$text_commission}', 1)"; - + $pdo->query($sql_event); } } @@ -2218,7 +2229,7 @@ if($request == 'get_view_page'){ if($field == 'deposit'){ $who_work = $userId; - $nameEvent = "Аванс"; + $nameEvent = "Аванс"; if($r_req['who_work'] > 0){ $who_work = (int)$r_req['who_work']; } @@ -2244,22 +2255,22 @@ if($request == 'get_view_page'){ $sql_up_d = "UPDATE deposits_clients_req SET deposit = {$deposit}, created_at= NOW(), user_id={$who_work} WHERE id = {$id_d}"; $pdo->query($sql_up_d); - + if((int)$r_d['deposit'] != $deposit){ $text_deposit = "Изменено: {$nameEvent} с {$r_d['deposit']} на {$deposit}"; $sql_event = "INSERT INTO events_clients (user_id, from_id, req_id, `event`, dop_text, `read`) VALUES ({$userId}, {$userId}, {$reqId}, 'update', '{$text_deposit}', 1)"; - + $pdo->query($sql_event); } - - } + + } } if($field == 'expense'){ $who_work = $userId; - $nameEvent = "Расходы"; - + $nameEvent = "Расходы"; + $sql_d = "SELECT * FROM expenses_req WHERE id = {$expenseId}"; $q_d = $pdo->query($sql_d); $expense = (int)$value; @@ -2279,23 +2290,248 @@ if($request == 'get_view_page'){ } $sql_up_d = "UPDATE expenses_req SET amount = '{$expense}', comment = '{$comment}' WHERE id = {$expenseId}"; $pdo->query($sql_up_d); - + if((int)$r_d['amount'] != $expense){ $text_expense = "Изменено: {$nameEvent} с {$r_d['amount']} на {$expense}"; if(!empty($comment)){ $text_expense .= " Добавлен комментарий: ".$comment; } $sql_event = "INSERT INTO events_clients (user_id, from_id, req_id, `event`, dop_text, `read`) VALUES ({$userId}, {$userId}, {$reqId}, 'update', '{$text_expense}', 1)"; - + $pdo->query($sql_event); } - - } + + } } - - } + +} + +// copy_preview — дефолты для модалки копирования (funnel/who_work/base_type_id/warnings). +if($request == 'copy_preview') { + $srcId = isset($data->req_id) ? (int)$data->req_id : 0; + if ($srcId <= 0) { + echo json_encode(array('success' => false, 'error' => 'req_id обязателен')); + exit(); + } + + // ВАЖНО: $pdo здесь — MySQL, не Sphinx. + $qSrc = $pdo->query("SELECT * FROM requisitions WHERE id = {$srcId} LIMIT 1"); + $src = $pdo->fetch_assoc($qSrc); + if (!$src) { + echo json_encode(array('success' => false, 'error' => 'Заявка не найдена')); + exit(); + } + if ((int)$src['deleted'] === 1) { + echo json_encode(array('success' => false, 'error' => 'Заявка удалена')); + exit(); + } + + // set_user — для checkMenuPermissions внутри user_can_edit_req. + $reqCheck = new Requisitions($pdo); + $userForCheck = new User(); + $userForCheck->checkPermissions(); + $reqCheck->set_user($userForCheck); + + if (!$reqCheck->user_can_edit_req($src, $_SESSION['id'])) { + echo json_encode(array('success' => false, 'error' => 'Нет прав на копирование этой заявки')); + exit(); + } + + $srcTypeId = (int)$src['type_id']; + $qType = $pdo->query("SELECT id, heir FROM requisitions_type WHERE id = {$srcTypeId} LIMIT 1"); + $typeRow = $pdo->fetch_assoc($qType); + $baseTypeId = $typeRow ? requisition_base_type_id($typeRow) : 0; + + // warning contract_without_object — object_id не копируется, но у исходника есть договор продажи. + $warnings = array(); + if (!requisition_should_copy_object($baseTypeId) && (int)$src['object_id'] > 0) { + $qContract = $pdo->query( + "SELECT id FROM contracts_req WHERE req_id = {$srcId} AND type = 2 LIMIT 1" + ); + $hasSaleContract = $pdo->fetch_assoc($qContract); + if ($hasSaleContract) { + $warnings[] = 'contract_without_object'; + } + } + + echo json_encode(array( + 'success' => true, + 'default_funnel_id' => (int)$src['funnel_id'], + 'default_who_work_id' => (int)$src['who_work'], + 'base_type_id' => $baseTypeId, + 'warnings' => $warnings, + )); + exit(); +} + +// copy — валидация payload/прав/воронки/ответственного → Requisitions::copy(). +if($request == 'copy') { + $srcId = isset($data->req_id) ? (int)$data->req_id : 0; + $funnelId = isset($data->funnel_id) ? (int)$data->funnel_id : 0; + $whoWorkId = isset($data->who_work_id) ? (int)$data->who_work_id : 0; + $currentId = (int)$_SESSION['id']; + $userAgency = (int)$_SESSION['agency_id']; + + // funnel_id = 0 — дефолтная воронка (funnel_default). + if ($srcId <= 0 || $funnelId < 0 || $whoWorkId <= 0) { + echo json_encode(array( + 'success' => false, + 'error' => 'req_id, funnel_id, who_work_id обязательны', + 'code' => 'bad_payload', + )); + exit(); + } + + $qSrc = $pdo->query("SELECT * FROM requisitions WHERE id = {$srcId} LIMIT 1"); + $src = $pdo->fetch_assoc($qSrc); + if (!$src) { + echo json_encode(array( + 'success' => false, + 'error' => 'Заявка не найдена', + 'code' => 'src_not_found', + )); + exit(); + } + if ((int)$src['deleted'] === 1) { + echo json_encode(array( + 'success' => false, + 'error' => 'Заявка удалена', + 'code' => 'src_not_found', + )); + exit(); + } + + $reqCheck = new Requisitions($pdo); + $userForCheck = new User(); + $userForCheck->checkPermissions(); + $reqCheck->set_user($userForCheck); + + // Право на копирование == право на редактирование исходника. + if (!$reqCheck->user_can_edit_req($src, $currentId)) { + echo json_encode(array( + 'success' => false, + 'error' => 'Нет прав на копирование этой заявки', + 'code' => 'no_edit_right', + )); + exit(); + } + + // Доступ к воронке. funnel_id=0 — проверяем funnel_default.is_req. + if ($funnelId === 0) { + $qFunnel = $pdo->query( + "SELECT `is_req` FROM `funnel_default` + WHERE `agency_id` = {$userAgency} + LIMIT 1" + ); + $funnelDef = $pdo->fetch_assoc($qFunnel); + if ($funnelDef && (int)$funnelDef['is_req'] === 0) { + echo json_encode(array( + 'success' => false, + 'error' => 'Воронка недоступна', + 'code' => 'funnel_forbidden', + )); + exit(); + } + } else { + // Проверка доступности воронки — через канонический Funnel::get_funnels(): там корректно учитывается + // is_no_see + раскрытие 'all_X' (подчинённые), users_no_see — это whitelist при is_no_see=1, имя обманчиво. + $funnelCheckClass = new Funnel($pdo); + $funnelCheckClass->set_agency_id($userAgency); + $funnelCheckClass->set_user_id($currentId); + $availableFunnels = $funnelCheckClass->get_funnels('requisitions'); + $isFunnelAvailable = false; + if (is_array($availableFunnels)) { + foreach ($availableFunnels as $af) { + if ((int)$af['id'] === $funnelId) { $isFunnelAvailable = true; break; } + } + } + if (!$isFunnelAvailable) { + echo json_encode(array( + 'success' => false, + 'error' => 'Воронка недоступна', + 'code' => 'funnel_forbidden', + )); + exit(); + } + } + + // Ответственный. Себя всегда можно назначить. + if ($whoWorkId !== $currentId) { + if ($funnelId === 0) { + // user_can_be_responsible требует funnel_id > 0 — для дефолтной проверяем вручную (agency + blocked). + $candidateAgency = (int)User::getUserAgencyID($whoWorkId); + if ($candidateAgency !== $userAgency) { + echo json_encode(array( + 'success' => false, + 'error' => 'Выбранный ответственный недоступен', + 'code' => 'who_work_forbidden', + )); + exit(); + } + $blockedQ = mysql_query("SELECT `blocked` FROM `users` WHERE `id` = {$whoWorkId} LIMIT 1"); + $blockedRow = mysql_fetch_assoc($blockedQ); + if (!$blockedRow || (int)$blockedRow['blocked'] === 1) { + echo json_encode(array( + 'success' => false, + 'error' => 'Выбранный ответственный недоступен', + 'code' => 'who_work_forbidden', + )); + exit(); + } + } else if (!$reqCheck->user_can_be_responsible($whoWorkId, $userAgency, $funnelId)) { + echo json_encode(array( + 'success' => false, + 'error' => 'Выбранный ответственный недоступен', + 'code' => 'who_work_forbidden', + )); + exit(); + } + } + + $result = $reqCheck->copy($srcId, $funnelId, $whoWorkId, $currentId); + echo json_encode($result); + exit(); +} + +if ($request == 'get_requisitions_by_stage') { + $stageId = (int)(isset($data->stage_id) ? $data->stage_id : 0); + $funnelId = (int)(isset($data->funnel_id) ? $data->funnel_id : 0); + $page = max(1, (int)(isset($data->page) ? $data->page : 1)); + $search = trim(isset($data->search) ? $data->search : ''); + $period = isset($data->period) ? $data->period : ''; + $responsible = is_array($data->responsible) ? $data->responsible : []; + $limit = 20; + $offset = ($page - 1) * $limit; + + $userId = (int)$_SESSION['id']; + $user = new User($pdo); + $user->getUserById($userId); + + $req = new Requisitions($pdo); + $req->set_userId($userId); + $req->set_agencyId($user->agencyId); + + $result = $req->getRequisitionsByStage($stageId, $funnelId, $search, $period, $responsible, $offset, $limit); + + $html = ''; + foreach ($result['items'] as $item) { + $html .= '

  • '; + $html .= '
    '; + $html .= '
    '; + $html .= '' . htmlspecialchars(isset($item['fio']) ? $item['fio'] : 'Без имени') . ''; + $html .= '
    '; + $html .= '
  • '; + } + + echo json_encode([ + 'html' => $html, + 'has_more' => count($result['items']) == $limit, + 'page' => $page + ]); + exit(); +} if($request == 'get_deal_by_req'){ $req_id = intval($data->req_id); diff --git a/js/requisitions_client_vue.js b/js/requisitions_client_vue.js index 25bda4f..b03d02e 100644 --- a/js/requisitions_client_vue.js +++ b/js/requisitions_client_vue.js @@ -2,6 +2,31 @@ Vue.config.devtools = true; Vue.component('v-select', VueSelect.VueSelect); +// JW-style toast (стили — crm.css). Дубликат из requisitions_vue.js с idempotent-гардом. +if (typeof window.jwShowCopyToast !== 'function') { + window.jwShowCopyToast = function (text) { + var container = document.getElementById('jw-toast-container'); + if (!container) { + container = document.createElement('div'); + container.id = 'jw-toast-container'; + container.className = 'jw-toast-container'; + document.body.appendChild(container); + } + var toast = document.createElement('div'); + toast.className = 'jw-toast'; + toast.textContent = String(text || ''); + container.appendChild(toast); + void toast.offsetWidth; // reflow для transition + toast.classList.add('jw-toast-show'); + setTimeout(function () { + toast.classList.remove('jw-toast-show'); + setTimeout(function () { + if (toast.parentNode) toast.parentNode.removeChild(toast); + }, 250); + }, 3500); + }; +} + var requisitions_client = new Vue({ el: '#requisitions_list_client', name: 'requisitions_list_client', @@ -34,11 +59,11 @@ var requisitions_client = new Vue({ } //requisitions_client.isPreloader=true; axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_all', - client_id: this.clientId, - funnel_id: this.funnel_id, - //user_id: this.user_id, - }, ) + request: 'get_all', + client_id: this.clientId, + funnel_id: this.funnel_id, + //user_id: this.user_id, + }, ) .then((response) => { this.req = response.data.req; //requisitions_client.isPreloader=false; @@ -59,10 +84,10 @@ var requisitions_client = new Vue({ getBarFunnel(reqId) { if (this.req['req' + reqId]) { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_bar_funnel', - funnel_id: this.req['req' + reqId].funnel_id, - req_id: reqId - }, ) + request: 'get_bar_funnel', + funnel_id: this.req['req' + reqId].funnel_id, + req_id: reqId + }, ) .then((response) => { this.req['req' + reqId].steps = response.data; requisitions_client.isPreloader = 0; @@ -82,9 +107,9 @@ var requisitions_client = new Vue({ if (this.req[id] === undefined) { //console.log(this.req[id]); axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_req_id', - req_id: id - }, ) + request: 'get_req_id', + req_id: id + }, ) .then((response) => { //console.log(response.data); requisitions_client.$set(requisitions_client, 'req', response.data); @@ -126,9 +151,9 @@ var requisitions_client = new Vue({ //Получение объекта getObject(object_id, reqId, forma) { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_object', - object_id: object_id - }, ) + request: 'get_object', + object_id: object_id + }, ) .then((response) => { console.log(response.data); this.req[reqId].object = response.data; @@ -145,9 +170,9 @@ var requisitions_client = new Vue({ //Получение клиента getClient(client_id, reqId, forma) { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_client', - client_id: client_id - }, ) + request: 'get_client', + client_id: client_id + }, ) .then((response) => { console.log(response.data); this.req[reqId].client = response.data; @@ -356,10 +381,10 @@ var requisitions_object = new Vue({ getBarFunnel(reqId) { if (this.req['req' + reqId]) { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_bar_funnel', - funnel_id: this.req['req' + reqId].funnel_id, - req_id: reqId - }, ) + request: 'get_bar_funnel', + funnel_id: this.req['req' + reqId].funnel_id, + req_id: reqId + }, ) .then((response) => { this.req['req' + reqId].steps = response.data; requisitions_client.isPreloader = 0; @@ -379,9 +404,9 @@ var requisitions_object = new Vue({ if (this.req[id] === undefined) { //console.log(this.req[id]); axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_req_id', - req_id: id - }, ) + request: 'get_req_id', + req_id: id + }, ) .then((response) => { //console.log(response.data); requisitions_object.$set(requisitions_object, 'req', response.data); @@ -423,9 +448,9 @@ var requisitions_object = new Vue({ //Получение объекта getObject(object_id, reqId, forma) { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_object', - object_id: object_id - }, ) + request: 'get_object', + object_id: object_id + }, ) .then((response) => { console.log(response.data); this.req[reqId].object = response.data; @@ -442,9 +467,9 @@ var requisitions_object = new Vue({ //Получение клиента getClient(client_id, reqId, forma) { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_client', - client_id: client_id - }, ) + request: 'get_client', + client_id: client_id + }, ) .then((response) => { console.log(response.data); this.req[reqId].client = response.data; @@ -544,10 +569,10 @@ var room_requisitions = new Vue({ name: 'room_requisitions', el: '#room_requisitions', components: - { - Multiselect: window.VueMultiselect.default, - vuejsDatepicker: window.vuejsDatepicker - }, + { + Multiselect: window.VueMultiselect.default, + vuejsDatepicker: window.vuejsDatepicker + }, data() { return { @@ -564,297 +589,455 @@ var room_requisitions = new Vue({ ot: 0, do: 0, pagePagin: [], - complexBus: null + complexBus: null, + // Состояние модалки копирования заявки. employees — серверный пререндер window.__copyEmployeesList; фильтр в Vue (без Select2). + copyModal: { + open: false, + srcId: null, + funnels: [], + funnelId: null, + employees: [], + whoWorkId: null, + whoWorkSearch: '', + whoWorkOpen: false, + whoWorkLabel: '', + defaultWhoWorkId: null, + warnings: [], + submitting: false, + error: null, + }, + } + }, + computed: { + // Фильтр сотрудников по whoWorkSearch (case-insensitive). + copyFilteredEmployees: function() { + var q = (this.copyModal.whoWorkSearch || '').toLowerCase().trim(); + var emps = this.copyModal.employees || []; + if (!q) return emps; + return emps.filter(function(e) { + return (e.name || '').toLowerCase().indexOf(q) !== -1; + }); } }, methods: - { - //Список - getList() { - this.requisitions = []; - this.inProgress = true; - this.pagePagin = []; - this.ot = 0; - this.do = 0; - - axios.post('/ajax/ajax_vue_requisitions.php', { + //Список + getList() + { + this.requisitions = []; + this.inProgress = true; + this.pagePagin = []; + this.ot = 0; + this.do = 0; + + axios.post('/ajax/ajax_vue_requisitions.php', { request: 'get_all', complex_room_id: this.complexRoomId, page: this.page, per_page: 5, }) - .then((response) => { - this.requisitions = response.data.req; + .then((response) => { + this.requisitions = response.data.req; - if (!this.isEmpty(this.requisitions)) { - this.all_pages = parseInt(response.data.allPages); - if (this.all_pages > 1) { - if (this.page > 1) - this.prevPage = this.page - 1; - } - if (this.all_pages > 8) { - if (this.page > 4) { - this.ot = this.page - 3; + if (!this.isEmpty(this.requisitions)) { + this.all_pages = parseInt(response.data.allPages); + if (this.all_pages > 1) { + if (this.page > 1) + this.prevPage = this.page - 1; + } + if (this.all_pages > 8) { + if (this.page > 4) { + this.ot = this.page - 3; + } else { + this.ot = 2; + } + + if (this.page < this.all_pages - 4) { + this.do = this.page + 3; + } else { + this.do = this.all_pages; + } } else { this.ot = 2; - } - - if (this.page < this.all_pages - 4) { - this.do = this.page + 3; - } else { this.do = this.all_pages; } - } else { - this.ot = 2; - this.do = this.all_pages; + for (var i = this.ot; i < this.do; i++) { + this.pagePagin.push(i); + } + //$("#requisitions_list_client .clients").show(); } - for (var i = this.ot; i < this.do; i++) { - this.pagePagin.push(i); - } - //$("#requisitions_list_client .clients").show(); + }) + .catch(function(error) { + console.log(error); + }) + .finally(() => this.inProgress = false); + + }, + + //Пагинация + pagin(page) + { + this.page = page; + this.getList(); + }, + + //Пагинация + goToRequisitionsPage(event) + { + if (event.keyCode === 13) { + var pageNum = $('#requisitionClientPageNumberInputForManualGoToPage').val(); + + if (pageNum) { + this.page = Number.parseInt(pageNum); + this.getList(); + $('#requisitionClientPageNumberInputForManualGoToPage').val(''); } - }) - .catch(function(error) { - console.log(error); - }) - .finally(() => this.inProgress = false); - - }, - - //Пагинация - pagin(page) - { - this.page = page; - this.getList(); - }, - - //Пагинация - goToRequisitionsPage(event) - { - if (event.keyCode === 13) { - var pageNum = $('#requisitionClientPageNumberInputForManualGoToPage').val(); - - if (pageNum) { - this.page = Number.parseInt(pageNum); - this.getList(); - $('#requisitionClientPageNumberInputForManualGoToPage').val(''); } - } - }, + }, - //Получение бара воронки - getBarFunnel(reqId) - { - if (this.requisitions['req' + reqId]) { - axios.post('/ajax/ajax_vue_requisitions.php', { + //Получение бара воронки + getBarFunnel(reqId) + { + if (this.requisitions['req' + reqId]) { + axios.post('/ajax/ajax_vue_requisitions.php', { request: 'get_bar_funnel', funnel_id: this.requisitions['req' + reqId].funnel_id, req_id: reqId }, ) - .then((response) => { - this.requisitions['req' + reqId].steps = response.data; - requisitions_client.isPreloader = 0; - }) - .catch(function(error) { - console.log(error); - }); - } - }, + .then((response) => { + this.requisitions['req' + reqId].steps = response.data; + requisitions_client.isPreloader = 0; + }) + .catch(function(error) { + console.log(error); + }); + } + }, - //Для редактирования - getReq(id) - { - $('#send_bg_new .closer').click(); - req_form.openReqForm(); + //Для редактирования + getReq(id) + { + $('#send_bg_new .closer').click(); + req_form.openReqForm(); - if (this.requisitions[id] === undefined) { - //console.log(this.req[id]); - axios.post('/ajax/ajax_vue_requisitions.php', { + if (this.requisitions[id] === undefined) { + //console.log(this.req[id]); + axios.post('/ajax/ajax_vue_requisitions.php', { request: 'get_req_id', req_id: id }, ) + .then((response) => { + this.$set(this, 'requisitions', response.data); + + if (this.requisitions[id].complex_room_id > 0 && this.isEmpty(this.requisitions[id].object)) { + + this.getRoom(this.requisitions[id].complex_room_id, id, 1); + } else { + req_form.setReq(this.requisitions[id]); + } + + if (this.requisitions[id].client_id > 0 && this.isEmpty(this.requisitions[id].client)) { + this.getClient(this.requisitions[id].client_id, id, 1); + } else { + req_form.setReq(this.requisitions[id]); + } + }) + .catch(function(error) { + console.log(error); + }); + } else { + + if (this.requisitions[id].complex_room_id > 0 && this.isEmpty(this.requisitions[id].object)) { + this.getRoom(this.requisitions[id].complex_room_id, id, 1); + } else { + req_form.setReq(this.requisitions[id]); + } + + if (this.requisitions[id].client_id > 0 && this.isEmpty(this.requisitions[id].client)) { + this.getClient(this.requisitions[id].client_id, id, 1); + } else { + req_form.setReq(this.requisitions[id]); + } + } + + }, + + //Получение объекта + getRoom(complex_room_id, reqId, forma) + { + axios.post('/ajax/vue_ajax/complex_axios.php', { + request: 'get_room_requisitions', + complex_room_id + }, ) .then((response) => { - this.$set(this, 'requisitions', response.data); - - if (this.requisitions[id].complex_room_id > 0 && this.isEmpty(this.requisitions[id].object)) { - - this.getRoom(this.requisitions[id].complex_room_id, id, 1); - } else { - req_form.setReq(this.requisitions[id]); + this.requisitions[reqId].object = response.data; + if (forma) { + req_form.setReq(this.requisitions[reqId]); } - if (this.requisitions[id].client_id > 0 && this.isEmpty(this.requisitions[id].client)) { - this.getClient(this.requisitions[id].client_id, id, 1); - } else { - req_form.setReq(this.requisitions[id]); - } }) .catch(function(error) { console.log(error); }); - } else { + }, - if (this.requisitions[id].complex_room_id > 0 && this.isEmpty(this.requisitions[id].object)) { - this.getRoom(this.requisitions[id].complex_room_id, id, 1); - } else { - req_form.setReq(this.requisitions[id]); - } - - if (this.requisitions[id].client_id > 0 && this.isEmpty(this.requisitions[id].client)) { - this.getClient(this.requisitions[id].client_id, id, 1); - } else { - req_form.setReq(this.requisitions[id]); - } - } - - }, - - //Получение объекта - getRoom(complex_room_id, reqId, forma) - { - axios.post('/ajax/vue_ajax/complex_axios.php', { - request: 'get_room_requisitions', - complex_room_id - }, ) - .then((response) => { - this.requisitions[reqId].object = response.data; - if (forma) { - req_form.setReq(this.requisitions[reqId]); - } - - }) - .catch(function(error) { - console.log(error); - }); - }, - - //Получение клиента - getClient(client_id, reqId, forma) - { - axios.post('/ajax/ajax_vue_requisitions.php', { + //Получение клиента + getClient(client_id, reqId, forma) + { + axios.post('/ajax/ajax_vue_requisitions.php', { request: 'get_client', client_id: client_id }, ) - .then((response) => { - this.requisitions[reqId].client = response.data; - if (forma) { - req_form.setReq(this.requisitions[reqId]); + .then((response) => { + this.requisitions[reqId].client = response.data; + if (forma) { + req_form.setReq(this.requisitions[reqId]); + } + + }) + .catch(function(error) { + console.log(error); + }); + }, + + //открыть/закрыть подробности + toggleClient(id) + { + + if (this.requisitions[id].isMainInfo) { + this.requisitions[id].isMainInfo = false; + } else { + + if (this.requisitions[id].complex_room_id > 0 && this.isEmpty(this.requisitions[id].object)) { + this.getRoom(this.requisitions[id].complex_room_id, id); } - }) - .catch(function(error) { - console.log(error); + if (this.requisitions[id].client_id > 0 && this.isEmpty(this.requisitions[id].client)) { + this.getClient(this.requisitions[id].client_id, id); + } + this.requisitions[id].isMainInfo = true; + } + }, + + //показать объект + showObject() + { + $('#liObject').click(); + }, + + //показать клиента + showClient() + { + $('#liGlobal').click(); + }, + + //Открыть форму + openForm(complexRoomId) + { + this.page = 1; + this.isShow = true; + this.complexRoomId = complexRoomId; + this.getList(); + $("body").addClass("lock"); + }, + + //закрыть форму + closeForm() + { + this.isShow = false; + $("body").removeClass("lock"); + }, + + openCardClient(client_id, ignoreFunnelsUpdate = false) { + openClientEventsWindowNew(client_id, $('#session_to_send').val(), 0, undefined, undefined, ignoreFunnelsUpdate); + }, + + //Проверка на пустоту + isEmpty(data) + { + if (typeof(data) === 'object') { + if (JSON.stringify(data) === '{}' || JSON.stringify(data) === '[]') { + return true; + } else if (!data) { + return true; + } + return false; + } else if (typeof(data) === 'string') { + if (!data.trim()) { + return true; + } + return false; + } else if (typeof(data) === 'undefined') { + return true; + } else { + return false; + } + }, + + observeRefs() + { + setInterval(() => { + if (window.complexBus) { + this.complexBus = window.complexBus + } + }, 200) + }, + + // Открыть модалку копирования. Funnels/employees — серверный пререндер из room_requisitions.php / footer.php. + openCopyRequisitionModal: function(reqId) { + var self = this; + var preFunnels = Array.isArray(window.__copyFunnelsList) ? window.__copyFunnelsList : []; + var preEmployees = Array.isArray(window.__copyEmployeesList) ? window.__copyEmployeesList : []; + var employeesNormalized = preEmployees.map(function (e) { + return { + id: parseInt(e.id, 10), + name: e.name, + group: e.group || null, + }; }); - }, + self.copyModal = { + open: true, + srcId: reqId, + funnels: preFunnels.map(function (f) { + return { id: parseInt(f.id, 10), name: f.name }; + }), + funnelId: null, + employees: employeesNormalized, + whoWorkId: null, + whoWorkSearch: '', + whoWorkOpen: false, + whoWorkLabel: '', + defaultWhoWorkId: null, + warnings: [], + submitting: false, + error: null, + }; - //открыть/закрыть подробности - toggleClient(id) - { + axios.post('/ajax/ajax_vue_requisitions.php', {request: 'copy_preview', req_id: reqId}) + .then(function (res) { + if (!res.data.success) { + self.copyModal.error = res.data.error || 'Не удалось загрузить данные'; + return; + } + self.copyModal.warnings = res.data.warnings || []; + // Дефолтная воронка — из исходника, иначе первая доступная. + var defaultFunnelId = res.data.default_funnel_id; + var funnelMatch = self.copyModal.funnels.find(function (f) { + return parseInt(f.id, 10) === parseInt(defaultFunnelId, 10); + }); + if (funnelMatch) { + self.copyModal.funnelId = parseInt(defaultFunnelId, 10); + } else if (self.copyModal.funnels.length > 0) { + self.copyModal.funnelId = self.copyModal.funnels[0].id; + } else { + self.copyModal.funnelId = null; + } + self.copyModal.defaultWhoWorkId = res.data.default_who_work_id; + var defaultId = res.data.default_who_work_id; + var hasInList = employeesNormalized.some(function (e) { return e.id === parseInt(defaultId, 10); }); + var chosenId = hasInList + ? parseInt(defaultId, 10) + : (employeesNormalized.length > 0 ? employeesNormalized[0].id : null); + self.copyModal.whoWorkId = chosenId; + // whoWorkLabel — имя в свернутом поле; whoWorkSearch держим пустым (полный список при открытии). + var chosenEmp = employeesNormalized.find(function (e) { return e.id === chosenId; }); + self.copyModal.whoWorkLabel = chosenEmp ? chosenEmp.name : ''; + self.copyModal.whoWorkSearch = ''; + self.copyModal.whoWorkOpen = false; + }) + .catch(function () { + self.copyModal.error = 'Сетевая ошибка'; + }); + }, - if (this.requisitions[id].isMainInfo) { - this.requisitions[id].isMainInfo = false; - } else { + // Выбор сотрудника. Сбрасываем whoWorkSearch, чтобы следующий раз показать полный список. + selectCopyWhoWork: function(emp) { + this.copyModal.whoWorkId = emp.id; + this.copyModal.whoWorkLabel = emp.name; + this.copyModal.whoWorkSearch = ''; + this.copyModal.whoWorkOpen = false; + }, - if (this.requisitions[id].complex_room_id > 0 && this.isEmpty(this.requisitions[id].object)) { - this.getRoom(this.requisitions[id].complex_room_id, id); + // Отправка копии: создаёт заявку и обновляет список комнаты. + submitCopy: function() { + var self = this; + if (self.copyModal.submitting) return; + + var whoWorkId = parseInt(self.copyModal.whoWorkId, 10); + + if (isNaN(whoWorkId) || self.copyModal.funnelId === null || self.copyModal.funnelId === undefined) { + self.copyModal.error = 'Заполните воронку и ответственного'; + return; } - if (this.requisitions[id].client_id > 0 && this.isEmpty(this.requisitions[id].client)) { - this.getClient(this.requisitions[id].client_id, id); - } - this.requisitions[id].isMainInfo = true; + self.copyModal.submitting = true; + self.copyModal.error = null; + + axios.post('/ajax/ajax_vue_requisitions.php', { + request: 'copy', + req_id: self.copyModal.srcId, + funnel_id: self.copyModal.funnelId, + who_work_id: whoWorkId, + }).then(function (res) { + self.copyModal.submitting = false; + if (!res.data.success) { + self.copyModal.error = res.data.error || 'Не удалось создать копию'; + return; + } + self.copyModal.open = false; + if (typeof window.jwShowCopyToast === 'function') { + window.jwShowCopyToast('Копия заявки создана'); + } + if (typeof self.getList === 'function') self.getList(); + }).catch(function () { + self.copyModal.submitting = false; + self.copyModal.error = 'Сетевая ошибка'; + }); + }, + + // Закрыть модалку копирования. + closeCopyModal: function() { + this.copyModal.open = false; + }, + + // Закрытие picker сотрудников по клику вне него (mousedown, чтобы опередить click внутри). + onCopyModalDocumentClick: function(e) { + if (!this.copyModal.whoWorkOpen) return; + var picker = this.$refs && this.$refs.copyWhoWorkPicker; + if (picker && (picker === e.target || picker.contains(e.target))) return; + this.copyModal.whoWorkOpen = false; } }, - - //показать объект - showObject() - { - $('#liObject').click(); - }, - - //показать клиента - showClient() - { - $('#liGlobal').click(); - }, - - //Открыть форму - openForm(complexRoomId) - { - this.page = 1; - this.isShow = true; - this.complexRoomId = complexRoomId; - this.getList(); - $("body").addClass("lock"); - }, - - //закрыть форму - closeForm() - { - this.isShow = false; - $("body").removeClass("lock"); - }, - - openCardClient(client_id, ignoreFunnelsUpdate = false) { - openClientEventsWindowNew(client_id, $('#session_to_send').val(), 0, undefined, undefined, ignoreFunnelsUpdate); - }, - - //Проверка на пустоту - isEmpty(data) - { - if (typeof(data) === 'object') { - if (JSON.stringify(data) === '{}' || JSON.stringify(data) === '[]') { - return true; - } else if (!data) { - return true; - } - return false; - } else if (typeof(data) === 'string') { - if (!data.trim()) { - return true; - } - return false; - } else if (typeof(data) === 'undefined') { - return true; - } else { - return false; - } - }, - - observeRefs() - { - setInterval(() => { - if (window.complexBus) { - this.complexBus = window.complexBus - } - }, 200) - } - }, mounted() - { + { this.$nextTick(() => { this.observeRefs(); }); + document.addEventListener('mousedown', this.onCopyModalDocumentClick); + }, + beforeDestroy: function() + { + document.removeEventListener('mousedown', this.onCopyModalDocumentClick); }, watch: - { - complexBus(complexBus) { - if (complexBus) { - complexBus.$on('apartment-open-requisitions', (apartment) => { - if (apartment) - { - this.complexRoomId = apartment.id - this.apartmentTitle = apartment.title - this.getList(); - this.isShow = true; - } - }); - } - } - }, + complexBus(complexBus) + { + if (complexBus) { + complexBus.$on('apartment-open-requisitions', (apartment) => { + if (apartment) + { + this.complexRoomId = apartment.id + this.apartmentTitle = apartment.title + this.getList(); + this.isShow = true; + } + }); + } + }, + // Watch 'copyModal.funnelId' удалён: список сотрудников не зависит от воронки, заполняется один раз из window.__copyEmployeesList. + }, created: function() { $("#room_requisitions").removeClass("hidden"); @@ -866,10 +1049,10 @@ var room_reservation = new Vue({ name: 'room_reservation', el: '#room_reservation', components: - { - Multiselect: window.VueMultiselect.default, - vuejsDatepicker: window.vuejsDatepicker - }, + { + Multiselect: window.VueMultiselect.default, + vuejsDatepicker: window.vuejsDatepicker + }, data() { return { @@ -884,237 +1067,237 @@ var room_reservation = new Vue({ } }, methods: - { - getReservation() { - this.reservation = []; - this.inProgress = true; - - axios.post('/ajax/ajax_vue_requisitions.php', { + getReservation() + { + this.reservation = []; + this.inProgress = true; + + axios.post('/ajax/ajax_vue_requisitions.php', { request: 'get_req_id', req_id: this.reservationId }) - .then((response) => { - this.reservation = response.data[`req${this.reservationId}`]; - }) - .catch(function(error) { - console.error(error); - }) - .finally(() => this.inProgress = false); - }, + .then((response) => { + this.reservation = response.data[`req${this.reservationId}`]; + }) + .catch(function(error) { + console.error(error); + }) + .finally(() => this.inProgress = false); + }, - //Получение бара воронки - getBarFunnel(reqId) - { - if (this.reservationId == reqId) { - axios.post('/ajax/ajax_vue_requisitions.php', { + //Получение бара воронки + getBarFunnel(reqId) + { + if (this.reservationId == reqId) { + axios.post('/ajax/ajax_vue_requisitions.php', { request: 'get_bar_funnel', funnel_id: this.reservation.funnel_id, req_id: reqId }, ) - .then((response) => { - this.reservation.steps = response.data; - requisitions_client.isPreloader = 0; - }) - .catch(function(error) { - console.error(error); - }); - } - }, + .then((response) => { + this.reservation.steps = response.data; + requisitions_client.isPreloader = 0; + }) + .catch(function(error) { + console.error(error); + }); + } + }, - //Для редактирования - getReq(id) - { - $('#send_bg_new .closer').click(); - req_form.openReqForm(); + //Для редактирования + getReq(id) + { + $('#send_bg_new .closer').click(); + req_form.openReqForm(); - if (this.reservationId === undefined) { - //console.log(this.req[id]); - axios.post('/ajax/ajax_vue_requisitions.php', { + if (this.reservationId === undefined) { + //console.log(this.req[id]); + axios.post('/ajax/ajax_vue_requisitions.php', { request: 'get_req_id', req_id: id }, ) + .then((response) => { + this.$set(this, 'reservation', response.data); + + if (this.reservation.complex_room_id > 0 && this.isEmpty(this.reservation.object)) { + + this.getRoom(this.reservation.complex_room_id, id, 1); + } else { + req_form.setReq(this.reservation); + } + + if (this.reservation.client_id > 0 && this.isEmpty(this.reservation.client)) { + this.getClient(this.reservation.client_id, id, 1); + } else { + req_form.setReq(this.reservation); + } + }) + .catch(function(error) { + console.error(error); + }); + } else { + + if (this.reservation.complex_room_id > 0 && this.isEmpty(this.reservation.object)) { + this.getRoom(this.reservation.complex_room_id, id, 1); + } else { + req_form.setReq(this.reservation); + } + + if (this.reservation.client_id > 0 && this.isEmpty(this.reservation.client)) { + this.getClient(this.reservation.client_id, id, 1); + } else { + req_form.setReq(this.reservation); + } + } + + }, + + //Получение объекта + getRoom(complex_room_id, reqId, forma) + { + axios.post('/ajax/vue_ajax/complex_axios.php', { + request: 'get_room_requisitions', + complex_room_id + }) .then((response) => { - this.$set(this, 'reservation', response.data); - - if (this.reservation.complex_room_id > 0 && this.isEmpty(this.reservation.object)) { - - this.getRoom(this.reservation.complex_room_id, id, 1); - } else { + this.reservation.object = response.data; + if (forma) { req_form.setReq(this.reservation); } - if (this.reservation.client_id > 0 && this.isEmpty(this.reservation.client)) { - this.getClient(this.reservation.client_id, id, 1); - } else { + }) + .catch(function(error) { + console.error(error); + }); + }, + + //Получение клиента + getClient(client_id, reqId, forma) + { + axios.post('/ajax/ajax_vue_requisitions.php', { + request: 'get_client', + client_id: client_id + }, ) + .then((response) => { + this.reservation.client = response.data; + if (forma) { req_form.setReq(this.reservation); } }) .catch(function(error) { console.error(error); }); - } else { + }, - if (this.reservation.complex_room_id > 0 && this.isEmpty(this.reservation.object)) { - this.getRoom(this.reservation.complex_room_id, id, 1); + //открыть/закрыть подробности + toggleClient(id) + { + + if (this.reservation.isMainInfo) { + this.reservation.isMainInfo = false; } else { - req_form.setReq(this.reservation); - } - if (this.reservation.client_id > 0 && this.isEmpty(this.reservation.client)) { - this.getClient(this.reservation.client_id, id, 1); - } else { - req_form.setReq(this.reservation); - } - } - - }, - - //Получение объекта - getRoom(complex_room_id, reqId, forma) - { - axios.post('/ajax/vue_ajax/complex_axios.php', { - request: 'get_room_requisitions', - complex_room_id - }) - .then((response) => { - this.reservation.object = response.data; - if (forma) { - req_form.setReq(this.reservation); + if (this.reservation.complex_room_id > 0 && this.isEmpty(this.reservation.object)) { + this.getRoom(this.reservation.complex_room_id, id); } - }) - .catch(function(error) { - console.error(error); - }); - }, - - //Получение клиента - getClient(client_id, reqId, forma) - { - axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_client', - client_id: client_id - }, ) - .then((response) => { - this.reservation.client = response.data; - if (forma) { - req_form.setReq(this.reservation); + if (this.reservation.client_id > 0 && this.isEmpty(this.reservation.client)) { + this.getClient(this.reservation.client_id, id); } - }) - .catch(function(error) { - console.error(error); - }); - }, - - //открыть/закрыть подробности - toggleClient(id) - { - - if (this.reservation.isMainInfo) { - this.reservation.isMainInfo = false; - } else { - - if (this.reservation.complex_room_id > 0 && this.isEmpty(this.reservation.object)) { - this.getRoom(this.reservation.complex_room_id, id); + this.reservation.isMainInfo = true; } + }, - if (this.reservation.client_id > 0 && this.isEmpty(this.reservation.client)) { - this.getClient(this.reservation.client_id, id); + //показать объект + showObject() + { + $('#liObject').click(); + }, + + //показать клиента + showClient() + { + $('#liGlobal').click(); + }, + + //Открыть форму + openForm(reservationId) + { + this.page = 1; + this.isShow = true; + this.reservationId = reservationId; + this.getList(); + $("body").addClass("lock"); + }, + + //закрыть форму + closeForm() + { + this.isShow = false; + $("body").removeClass("lock"); + }, + + openCardClient(client_id, ignoreFunnelsUpdate = false) { + openClientEventsWindowNew(client_id, $('#session_to_send').val(), 0, undefined, undefined, ignoreFunnelsUpdate); + }, + + //Проверка на пустоту + isEmpty(data) + { + if (typeof(data) === 'object') { + if (JSON.stringify(data) === '{}' || JSON.stringify(data) === '[]') { + return true; + } else if (!data) { + return true; + } + return false; + } else if (typeof(data) === 'string') { + if (!data.trim()) { + return true; + } + return false; + } else if (typeof(data) === 'undefined') { + return true; + } else { + return false; } - this.reservation.isMainInfo = true; + }, + + observeRefs() + { + setInterval(() => { + if (window.complexBus) { + this.complexBus = window.complexBus + } + }, 200) } }, - - //показать объект - showObject() - { - $('#liObject').click(); - }, - - //показать клиента - showClient() - { - $('#liGlobal').click(); - }, - - //Открыть форму - openForm(reservationId) - { - this.page = 1; - this.isShow = true; - this.reservationId = reservationId; - this.getList(); - $("body").addClass("lock"); - }, - - //закрыть форму - closeForm() - { - this.isShow = false; - $("body").removeClass("lock"); - }, - - openCardClient(client_id, ignoreFunnelsUpdate = false) { - openClientEventsWindowNew(client_id, $('#session_to_send').val(), 0, undefined, undefined, ignoreFunnelsUpdate); - }, - - //Проверка на пустоту - isEmpty(data) - { - if (typeof(data) === 'object') { - if (JSON.stringify(data) === '{}' || JSON.stringify(data) === '[]') { - return true; - } else if (!data) { - return true; - } - return false; - } else if (typeof(data) === 'string') { - if (!data.trim()) { - return true; - } - return false; - } else if (typeof(data) === 'undefined') { - return true; - } else { - return false; - } - }, - - observeRefs() - { - setInterval(() => { - if (window.complexBus) { - this.complexBus = window.complexBus - } - }, 200) - } - }, mounted() - { + { this.$nextTick(() => { this.observeRefs(); }); }, watch: - { - complexBus(complexBus) { - if (complexBus) { - complexBus.$on('apartment-open-reservation', (reservation) => { - if (reservation) - { - openClientEventsWindowNew(0, $('#session_to_send').val(), 0, reservation.id); - // this.reservationId = reservation.id - // this.apartmentTitle = reservation.apartment_title - // this.getReservation(); - // this.isShow = true; - } - }); + complexBus(complexBus) + { + if (complexBus) { + complexBus.$on('apartment-open-reservation', (reservation) => { + if (reservation) + { + openClientEventsWindowNew(0, $('#session_to_send').val(), 0, reservation.id); + // this.reservationId = reservation.id + // this.apartmentTitle = reservation.apartment_title + // this.getReservation(); + // this.isShow = true; + } + }); + } } - } - }, + }, created: function() { $("#room_reservation").removeClass("hidden"); diff --git a/js/requisitions_vue.js b/js/requisitions_vue.js index 850514a..1512d96 100644 --- a/js/requisitions_vue.js +++ b/js/requisitions_vue.js @@ -3,6 +3,31 @@ Vue.config.devtools = true; Vue.component('v-select', VueSelect.VueSelect) Vue.directive('mask', VueMask.VueMaskDirective); +// JW-style toast (стили — crm.css). Idempotent guard на случай повторной загрузки файла. +if (typeof window.jwShowCopyToast !== 'function') { + window.jwShowCopyToast = function (text) { + var container = document.getElementById('jw-toast-container'); + if (!container) { + container = document.createElement('div'); + container.id = 'jw-toast-container'; + container.className = 'jw-toast-container'; + document.body.appendChild(container); + } + var toast = document.createElement('div'); + toast.className = 'jw-toast'; + toast.textContent = String(text || ''); + container.appendChild(toast); + void toast.offsetWidth; // reflow для transition + toast.classList.add('jw-toast-show'); + setTimeout(function () { + toast.classList.remove('jw-toast-show'); + setTimeout(function () { + if (toast.parentNode) toast.parentNode.removeChild(toast); + }, 250); + }, 3500); + }; +} + if ($('#requisitions_list').length > 0) { var requisitions = new Vue({ el: '#requisitions_list', @@ -47,22 +72,49 @@ if ($('#requisitions_list').length > 0) { add_tag_contract: null, req_id_contract_tag: 0, prev_selectors: { 'li': null, 'ul': null }, + // Состояние модалки копирования заявки. employees — серверный пререндер window.__copyEmployeesList (см. requisitions.php); фильтр в Vue (без Select2). + copyModal: { + open: false, + srcId: null, + funnels: [], + funnelId: null, + employees: [], + whoWorkId: null, + whoWorkSearch: '', + whoWorkOpen: false, + whoWorkLabel: '', + defaultWhoWorkId: null, + warnings: [], + submitting: false, + error: null, + }, + } + }, + computed: { + // Фильтр сотрудников по whoWorkSearch (case-insensitive). + copyFilteredEmployees: function() { + var q = (this.copyModal.whoWorkSearch || '').toLowerCase().trim(); + var emps = this.copyModal.employees || []; + if (!q) return emps; + return emps.filter(function(e) { + return (e.name || '').toLowerCase().indexOf(q) !== -1; + }); } }, watch: { totalReqs(newVal) { if (!newVal) { newVal = localStorage.getItem('totalReqs') - } - this.$nextTick(() => { + } + this.$nextTick(() => { const totalCount = newVal - + let countValues = $('.task-count-holder .task-count:not(.task-count-percent)') - .map(function () { - return parseInt($(this).text(), 10); - }) - .get() - + .map(function () { + return parseInt($(this).text(), 10); + }) + .get() + $('.task-count-holder').each(function (index) { const rawCount = countValues[index] || 0; let rawPercent = (rawCount / totalCount) * 100 || 0; @@ -70,11 +122,11 @@ if ($('#requisitions_list').length > 0) { const color = $(this).find('.task-count-percent').css('color') || '#00aaff'; const bg = `conic-gradient(${color} 0% ${percent}%, #dfdfdf ${percent}% 100%)`; - $(this).find('.circle-progress').css('background', bg); + $(this).find('.circle-progress').css('background', bg); $(this).find('.task-count-percent').text(percent + '%'); - }); - - }) + }); + + }) }, view(newVal) { @@ -82,9 +134,10 @@ if ($('#requisitions_list').length > 0) { const totalFromSt = localStorage.getItem('totalReqs') this.totalReqs = totalFromSt } - - } - }, + + }, + // Watch 'copyModal.funnelId' удалён: список сотрудников не зависит от воронки, заполняется один раз из window.__copyEmployeesList. + }, methods: { setAutosearch(reqs) { if (!this.isEmpty(reqs)) { @@ -139,54 +192,54 @@ if ($('#requisitions_list').length > 0) { user_id: this.userId }, ) - .then((response) => { - // console.log(response.data); - const union_req = response.data; + .then((response) => { + // console.log(response.data); + const union_req = response.data; - Object.entries(union_req).forEach(([reqKey, unionIds]) => { - // console.log(unionIds); - let found = false; - // Перебираем все шаги (кроме 'count' и других не-шагов) - for (const step in this.req) { - if (step === 'count' || step === 'union_req' || !this.req.hasOwnProperty(step)) continue; - - if (this.req[step] && step == reqKey) { - this.$set(this.req[step], 'union_req', unionIds); - found = true; - - console.log(`[setUnionReq] Updated ${reqKey} in step ${step}`); + Object.entries(union_req).forEach(([reqKey, unionIds]) => { + // console.log(unionIds); + let found = false; + // Перебираем все шаги (кроме 'count' и других не-шагов) + for (const step in this.req) { + if (step === 'count' || step === 'union_req' || !this.req.hasOwnProperty(step)) continue; + + if (this.req[step] && step == reqKey) { + this.$set(this.req[step], 'union_req', unionIds); + found = true; + + console.log(`[setUnionReq] Updated ${reqKey} in step ${step}`); + } + if(this.req[step][reqKey]) + this.$set(this.req[step][reqKey], 'union_req', unionIds); } - if(this.req[step][reqKey]) - this.$set(this.req[step][reqKey], 'union_req', unionIds); - } - if (!found) { - console.warn(`[setUnionReq] req "${reqKey}" not found in any step`); - } - }); + if (!found) { + console.warn(`[setUnionReq] req "${reqKey}" not found in any step`); + } + }); - /* Object.entries(union_req).forEach((item, index) => { - this.req[item[0]].union_req = item[1]; - if(this.req.count !== undefined){ - for(var step in this.req.count){ - if(this.req[step][item[0]] !== undefined){ - this.req[step][item[0]].union_req = item[1]; + /* Object.entries(union_req).forEach((item, index) => { + this.req[item[0]].union_req = item[1]; + if(this.req.count !== undefined){ + for(var step in this.req.count){ + if(this.req[step][item[0]] !== undefined){ + this.req[step][item[0]].union_req = item[1]; + } } } - } - });*/ - // console.log(this.req); - // this.steps = response.data; + });*/ + // console.log(this.req); + // this.steps = response.data; - }) - .catch(function(error) { - console.error(error); - }) + }) + .catch(function(error) { + console.error(error); + }) } }, open_union_req_form(reqs_id, req_id){ - + reqs_id.push(req_id); if(typeof union_reqs_form == 'object'){ union_reqs_form.main_id = req_id; @@ -196,9 +249,9 @@ if ($('#requisitions_list').length > 0) { }, open_joint_req(req_id){ - + if(typeof union_reqs_form == 'object'){ - // union_reqs_form.main_id = req_id; + // union_reqs_form.main_id = req_id; union_reqs_form.is_union = 0; } union_reqs_form.openFormJoint(req_id); @@ -206,11 +259,11 @@ if ($('#requisitions_list').length > 0) { //Список getList() { - + if (this.funnel_id == "all") { this.view = "list"; - + } console.log(this.view); @@ -218,7 +271,7 @@ if ($('#requisitions_list').length > 0) { // console.log(this.page); let funnel_id = $('#funnelIdClients').val(); let use_custom_funnel = $('#useCustomFunnel').val(); - // get_funnels(funnel_id, 'requisitions', use_custom_funnel); + // get_funnels(funnel_id, 'requisitions', use_custom_funnel); if (this.page > 1 && this.view == 'kanban') { //////// } else { @@ -243,7 +296,7 @@ if ($('#requisitions_list').length > 0) { this.getStepsFunnel(); this.funnel_id = $('#funnelIdClients').val(); $('#groupClients').hide(); - + } else if (this.view == 'table') { this.isList = false; this.isKanban = false; @@ -257,14 +310,14 @@ if ($('#requisitions_list').length > 0) { if(this.filtr.order === false || this.filtr.order == 0){ $('#sort_order_req').val(2); } - } + } //удаление вспомогательной таблицы $("#req_table2").bootgrid("destroy"); $("#req_table2").remove(); // console.log(this.filtr); return get_funnels(funnel_id, 'requisitions', use_custom_funnel).then(() => { - + return axios.post('/ajax/ajax_vue_requisitions.php', { request: 'get_all', user_id: this.user_id, @@ -273,228 +326,228 @@ if ($('#requisitions_list').length > 0) { filtr: this.filtr, page: this.page, }, ) - .then((response) => { + .then((response) => { - const totalReqsSt = localStorage.getItem('totalReqs') - if (!totalReqsSt) { - localStorage.setItem('totalReqs', this.totalReqs); - this.totalReqs = response.data.total_req - } - console.log(response.data); - if (this.view == 'kanban' && this.page > 1) { - this.req.count = response.data.req.count; - const totalFromSt = localStorage.getItem('totalReqs') - this.totalReqs = totalFromSt - //console.log(response.data); - setTimeout(() => { - for (var i in response.data.req) { + const totalReqsSt = localStorage.getItem('totalReqs') + if (!totalReqsSt) { + localStorage.setItem('totalReqs', this.totalReqs); + this.totalReqs = response.data.total_req + } + console.log(response.data); + if (this.view == 'kanban' && this.page > 1) { + this.req.count = response.data.req.count; + const totalFromSt = localStorage.getItem('totalReqs') + this.totalReqs = totalFromSt + //console.log(response.data); + setTimeout(() => { + for (var i in response.data.req) { - if (!isNaN(parseInt(i))) { - for (var ii in response.data.req[i]) { - if (ii.indexOf("req") > -1) { - if (!requisitions.req[i]) { - console.log('r.q is undefined'); - continue + if (!isNaN(parseInt(i))) { + for (var ii in response.data.req[i]) { + if (ii.indexOf("req") > -1) { + if (!requisitions.req[i]) { + console.log('r.q is undefined'); + continue + } + requisitions.$set(requisitions.req[i], ii, response.data.req[i][ii]); } - requisitions.$set(requisitions.req[i], ii, response.data.req[i][ii]); } + } else if (i.indexOf("req") > -1) { + add_knban = true; + requisitions.$set(requisitions.req, i, response.data.req[i]); } - } else if (i.indexOf("req") > -1) { - add_knban = true; - requisitions.$set(requisitions.req, i, response.data.req[i]); } - } - //requisitions.totalReqs = response.data.total_req - - requisitions.setAutosearch(response.data.req); - //if(this.agencyId == 5238 || this.agencyId == 4) + //requisitions.totalReqs = response.data.total_req + + requisitions.setAutosearch(response.data.req); + //if(this.agencyId == 5238 || this.agencyId == 4) requisitions.setUnionReq(response.data.req); - let countValues = $('.task-count-holder .task-count:not(.task-count-percent)').map(function () { - return parseInt($(this).text(), 10); - }) - .get() - - $('.task-count-holder').each(function (index) { - const rawCount = countValues[index] || 0; - let rawPercent = (rawCount / parseInt(totalFromSt)) * 100 || 0; - - const percent = Number.isInteger(rawPercent) ? rawPercent.toString() : rawPercent.toFixed(2) || 0; - const color = $(this).find('.task-count-percent').css('color') || '#00aaff'; - const bg = `conic-gradient(${color} 0% ${percent}%, #dfdfdf ${percent}% 100%)`; + let countValues = $('.task-count-holder .task-count:not(.task-count-percent)').map(function () { + return parseInt($(this).text(), 10); + }) + .get() - $(this).find('.circle-progress').css('background', bg); - $(this).find('.task-count-percent').text(percent + '%'); - }); + $('.task-count-holder').each(function (index) { + const rawCount = countValues[index] || 0; + let rawPercent = (rawCount / parseInt(totalFromSt)) * 100 || 0; - }, 500); - //this.totalReqs = response.data.total_req - if (this.totalReqs) { - localStorage.setItem('totalReqs', this.totalReqs); - } - - } else { + const percent = Number.isInteger(rawPercent) ? rawPercent.toString() : rawPercent.toFixed(2) || 0; + const color = $(this).find('.task-count-percent').css('color') || '#00aaff'; + const bg = `conic-gradient(${color} 0% ${percent}%, #dfdfdf ${percent}% 100%)`; - this.req = response.data.req; - this.setAutosearch(response.data.req); - //if(this.agencyId == 5238 || this.agencyId == 4) - this.totalReqs = response.data.total_req - if (this.totalReqs) { - localStorage.setItem('totalReqs', this.totalReqs); - } - // if(this.agencyId == 5238 || this.agencyId == 4) + $(this).find('.circle-progress').css('background', bg); + $(this).find('.task-count-percent').text(percent + '%'); + }); + + }, 500); + //this.totalReqs = response.data.total_req + if (this.totalReqs) { + localStorage.setItem('totalReqs', this.totalReqs); + } + + } else { + + this.req = response.data.req; + this.setAutosearch(response.data.req); + //if(this.agencyId == 5238 || this.agencyId == 4) + this.totalReqs = response.data.total_req + if (this.totalReqs) { + localStorage.setItem('totalReqs', this.totalReqs); + } + // if(this.agencyId == 5238 || this.agencyId == 4) this.setUnionReq(response.data.req); - } - - $('#req_filter_etap_input').html(response.data.step_filter); - this.getSelect('req_filter_etap_input', 'req_filter_etap', 'Этап', this.filtr.step); + } - $('#totalCountReq .text').text(response.data.total_req); - $('#totalCountReqComission .text').text(response.data.total_comission); - console.log(this.filtr); - if(this.filtr.stages.hit == 1){ - $('#totalCountReqComission').hide(); - } else { - $('#totalCountReqComission').show(); - } - this.activities = response.data.activities; - this.activities_name = response.data.activities_name; + $('#req_filter_etap_input').html(response.data.step_filter); + this.getSelect('req_filter_etap_input', 'req_filter_etap', 'Этап', this.filtr.step); - this.all_pages = parseInt(response.data.allPages); - if (this.all_pages > 1) { - if (this.page > 1) - this.prevPage = this.page - 1; - } - if (this.all_pages > 8) { - if (this.page > 4) { - this.ot = this.page - 3; + $('#totalCountReq .text').text(response.data.total_req); + $('#totalCountReqComission .text').text(response.data.total_comission); + console.log(this.filtr); + if(this.filtr.stages.hit == 1){ + $('#totalCountReqComission').hide(); + } else { + $('#totalCountReqComission').show(); + } + this.activities = response.data.activities; + this.activities_name = response.data.activities_name; + + this.all_pages = parseInt(response.data.allPages); + if (this.all_pages > 1) { + if (this.page > 1) + this.prevPage = this.page - 1; + } + if (this.all_pages > 8) { + if (this.page > 4) { + this.ot = this.page - 3; + } else { + this.ot = 2; + } + + if (this.page < this.all_pages - 4) { + this.do = this.page + 3; + } else { + this.do = this.all_pages; + } } else { this.ot = 2; - } - - if (this.page < this.all_pages - 4) { - this.do = this.page + 3; - } else { this.do = this.all_pages; } - } else { - this.ot = 2; - this.do = this.all_pages; - } - for (var i = this.ot; i < this.do; i++) { - this.pagePagin.push(i); - } - - requisitions.isPreloader = 0; - if (this.view == 'kanban') { - - setTimeout(function() { - kanbanOverscroll(); - }, 500); - } else if (this.view == 'table') { - - setTimeout(function() { - reqBootgrid(); - }, 500); - } - - autosearch_objs.$on('change_autosearch_counters', function(filter_id, counter) { - console.log({ filter_id, counter }); - if (counter.total > 0) { - $('.fltr-objects-list[data-id="' + filter_id + '"] .counter').fadeIn(); - $('.fltr-objects-list[data-id="' + filter_id + '"] .counter').text('+' + counter.match); - $('.fltr-objects-list[data-id="' + filter_id + '"] .error').addClass('with-counter'); - } else { - $('.fltr-objects-list[data-id="' + filter_id + '"] .counter').fadeOut(); - $('.fltr-objects-list[data-id="' + filter_id + '"] .counter').text('0'); - $('.fltr-objects-list[data-id="' + filter_id + '"] .error').removeClass('with-counter'); + for (var i = this.ot; i < this.do; i++) { + this.pagePagin.push(i); } + + requisitions.isPreloader = 0; + if (this.view == 'kanban') { + + setTimeout(function() { + kanbanOverscroll(); + }, 500); + } else if (this.view == 'table') { + + setTimeout(function() { + reqBootgrid(); + }, 500); + } + + autosearch_objs.$on('change_autosearch_counters', function(filter_id, counter) { + console.log({ filter_id, counter }); + if (counter.total > 0) { + $('.fltr-objects-list[data-id="' + filter_id + '"] .counter').fadeIn(); + $('.fltr-objects-list[data-id="' + filter_id + '"] .counter').text('+' + counter.match); + $('.fltr-objects-list[data-id="' + filter_id + '"] .error').addClass('with-counter'); + } else { + $('.fltr-objects-list[data-id="' + filter_id + '"] .counter').fadeOut(); + $('.fltr-objects-list[data-id="' + filter_id + '"] .counter').text('0'); + $('.fltr-objects-list[data-id="' + filter_id + '"] .error').removeClass('with-counter'); + } + }); + + }) + .catch(function(error) { + console.error(error); }); + }); - }) - .catch(function(error) { - console.error(error); - }); - }); + }, - }, + get_req_id(id, is_kanban = 0){ - get_req_id(id, is_kanban = 0){ - - axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_req_id', - req_id: id, - user_id: this.user_id, - is_kanban: is_kanban - }, ).then((response) => { - - var new_req = response.data; - - for(var index in this.req){ - - if(this.req[index] && (index.indexOf('req') == -1 && index.indexOf('count') == -1)){ - - for(var index1 in this.req[index]){ - if(index1 == 'req'+id){ - var temp_req = this.req[index][index1]; - - this.req[index][index1] = new_req['req'+id]; - requisitions.setUnionReq(this.req); - - - if(is_kanban){ + axios.post('/ajax/ajax_vue_requisitions.php', { + request: 'get_req_id', + req_id: id, + user_id: this.user_id, + is_kanban: is_kanban + }, ).then((response) => { - let is_update = false; - if(index != new_req['req'+id].step_id) { - if(this.req[index][index1].funnel_id !=0){ - delete this.req[index][index1]; + var new_req = response.data; + + for(var index in this.req){ + + if(this.req[index] && (index.indexOf('req') == -1 && index.indexOf('count') == -1)){ + + for(var index1 in this.req[index]){ + if(index1 == 'req'+id){ + var temp_req = this.req[index][index1]; + + this.req[index][index1] = new_req['req'+id]; + requisitions.setUnionReq(this.req); + + + if(is_kanban){ + + let is_update = false; + if(index != new_req['req'+id].step_id) { + if(this.req[index][index1].funnel_id !=0){ + delete this.req[index][index1]; + is_update = true; + } + } + if(this.filtr.stages.close == 0 && temp_req.deleted == 0 && new_req['req'+id].deleted == 1){ + // console.log($(`#kanban_item_li_${id}`)); + $(`#kanban_item_li_${id}`).hide(); is_update = true; } - } - if(this.filtr.stages.close == 0 && temp_req.deleted == 0 && new_req['req'+id].deleted == 1){ - // console.log($(`#kanban_item_li_${id}`)); - $(`#kanban_item_li_${id}`).hide(); - is_update = true; - } - if(temp_req.funnel_id != new_req['req'+id].funnel_id){ - - $(`#kanban_item_li_${id}`).hide(); - is_update = true; + if(temp_req.funnel_id != new_req['req'+id].funnel_id){ + + $(`#kanban_item_li_${id}`).hide(); + is_update = true; + } + + if(is_update){ + + requisitions.page = requisitions.page+1; + requisitions.getList(); + } } - if(is_update){ - - requisitions.page = requisitions.page+1; - requisitions.getList(); - } } - + } + } else if (index == 'req'+id){ + this.req[index] = new_req['req'+id]; + + } + }; + + if(new_req.is_kanban){ + for(var indexCount in this.req.count){ + console.log(indexCount) + if(indexCount == new_req['req'+id].step_id){ + if(this.req[indexCount]){ + /** */ + } else { + this.$set(this.req, indexCount, {}); + } + this.$set(this.req[indexCount], 'req'+id, new_req['req'+id]); } } - } else if (index == 'req'+id){ - this.req[index] = new_req['req'+id]; - } - }; - if(new_req.is_kanban){ - for(var indexCount in this.req.count){ - console.log(indexCount) - if(indexCount == new_req['req'+id].step_id){ - if(this.req[indexCount]){ - /** */ - } else { - this.$set(this.req, indexCount, {}); - } - this.$set(this.req[indexCount], 'req'+id, new_req['req'+id]); - } - } - } - - }).catch(function(error) { - console.debug(error); - }); - }, + }).catch(function(error) { + console.debug(error); + }); + }, getSelect(id, idf, name, value) { if ($('#' + idf).length > 0) { @@ -558,10 +611,10 @@ if ($('#requisitions_list').length > 0) { //Для канбана этапы воронки getStepsFunnel() { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_step_funnel', - funnel_id: this.funnel_id, + request: 'get_step_funnel', + funnel_id: this.funnel_id, - }, ) + }, ) .then((response) => { // console.log(response.data); this.steps = response.data; @@ -576,11 +629,11 @@ if ($('#requisitions_list').length > 0) { getBarFunnel(reqId, adjacent_id = 0) { if (this.req['req' + reqId]) { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_bar_funnel', - funnel_id: this.req['req' + reqId].funnel_id, - req_id: reqId, - adjacent_id: adjacent_id, - }, ) + request: 'get_bar_funnel', + funnel_id: this.req['req' + reqId].funnel_id, + req_id: reqId, + adjacent_id: adjacent_id, + }, ) .then((response) => { ac.closesStep = false; ac.is_looad = false; @@ -603,7 +656,7 @@ if ($('#requisitions_list').length > 0) { if ($('#client-history__bg').css('display') != 'none') { $('#client-history__bg .crm__small-stagebar .stage').removeClass('nextStep'); $('#client-history__bg .crm__small-stagebar .stage').removeClass('active'); - for (var i in bar.bar) { + for (var i in bar.bar) { $('#client-history__bg .crm__small-stagebar .stageFunnel__' + bar.bar[i].id).addClass(bar.bar[i].classF); } $('#client-history__bg .stagebar-title').text(bar.stage); @@ -653,9 +706,9 @@ if ($('#requisitions_list').length > 0) { //Получение объекта getObject(object_id, reqId, forma, obj) { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_object', - object_id: object_id - }, ) + request: 'get_object', + object_id: object_id + }, ) .then((response) => { //console.log(response.data); this.req[reqId].object = response.data; @@ -675,9 +728,9 @@ if ($('#requisitions_list').length > 0) { //Получение клиента getClient(client_id, reqId, forma) { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_client', - client_id: client_id - }, ) + request: 'get_client', + client_id: client_id + }, ) .then((response) => { //console.log(response.data); this.req[reqId].client = response.data; @@ -743,9 +796,9 @@ if ($('#requisitions_list').length > 0) { cancelReq(id) { if (confirm('Вы точно хотите безвозвратно удалить эту заявку?')) { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'cancel_req', - req_id: id - }, ) + request: 'cancel_req', + req_id: id + }, ) .then((response) => { this.getList(); }) @@ -759,10 +812,10 @@ if ($('#requisitions_list').length > 0) { renewReq(id) { if (confirm('Вы точно хотите восстановить эту заявку?')) { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'renew_req', - req_id: id, - user_id: this.user_id - }, ) + request: 'renew_req', + req_id: id, + user_id: this.user_id + }, ) .then((response) => { this.getList(); }) @@ -781,18 +834,18 @@ if ($('#requisitions_list').length > 0) { all = 1; if (localStorage['ids_exception_req']) { var ids_exception_req = localStorage.getItem('ids_exception_req'); - + ids = JSON.parse(ids_exception_req); } } axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'renew_reqs', - reqs_id: reqs, - user_id: this.user_id, - all: all, - ids_exception: ids, - }, ) + request: 'renew_reqs', + reqs_id: reqs, + user_id: this.user_id, + all: all, + ids_exception: ids, + }, ) .then((response) => { console.log(response.data); this.getList(); @@ -844,7 +897,7 @@ if ($('#requisitions_list').length > 0) { allOnCheckId(id, 'req'); } } else { - + $('#changeReq' + id).prop('checked', true); $('#checked-clt' + id).addClass('active'); if($('#changeReqAllFilter').prop('checked')){ @@ -856,7 +909,7 @@ if ($('#requisitions_list').length > 0) { //Общая передача заявок confirm__User_req() { var ids = []; - + var user_id = $('#confirm__user_id_req').val(); var who_work = $('#confirm__who_work_req').val(); var reqs_id = $('#confirm_reqs_id').val(); @@ -865,18 +918,18 @@ if ($('#requisitions_list').length > 0) { all = 1; if (localStorage['ids_exception_req']) { var ids_exception_req = localStorage.getItem('ids_exception_req'); - + ids = JSON.parse(ids_exception_req); } } axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'confirm_reqs', - reqs_id: reqs_id, - user_id: user_id, - who_work: who_work, - all: all, - ids_exception: ids, - }, ) + request: 'confirm_reqs', + reqs_id: reqs_id, + user_id: user_id, + who_work: who_work, + all: all, + ids_exception: ids, + }, ) .then((response) => { console.log(response.data); closeConfirmReq(); @@ -897,17 +950,17 @@ if ($('#requisitions_list').length > 0) { all = 1; if (localStorage['ids_exception_req']) { var ids_exception_req = localStorage.getItem('ids_exception_req'); - + ids = JSON.parse(ids_exception_req); } } axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'funnel_check', - reqs_id: reqs_id, - funnel_check: funnel_check, - all: all, - ids_exception: ids, - }, ) + request: 'funnel_check', + reqs_id: reqs_id, + funnel_check: funnel_check, + all: all, + ids_exception: ids, + }, ) .then((response) => { //console.log(response.data); closeFunnelReqs(); @@ -954,14 +1007,14 @@ if ($('#requisitions_list').length > 0) { //Открыть добавление тегов или договоров open_popup_tag(id) { - + for (var i in this.req) { this.req[i].add_tag_contract = false; this.req[i].add_tag = false; - + if (i != id) { - // this.req[i].poup_tag_contract = false; + // this.req[i].poup_tag_contract = false; this.req[i].popup_tag = false; } else { this.req[i].popup_tag = !this.req[i].popup_tag; @@ -1000,10 +1053,10 @@ if ($('#requisitions_list').length > 0) { return_contract_form(req_id) { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_contracts', - parent_id: req_id, - type: 'req', - }, ) + request: 'get_contracts', + parent_id: req_id, + type: 'req', + }, ) .then((response) => { var res = response.data; console.log(this.req); @@ -1034,11 +1087,11 @@ if ($('#requisitions_list').length > 0) { //this.req[id].activities_name = name_tag; this.req[id].add_tag = false; axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'save_activites', - req_id: this.req[id].id, - activities: this.req[id].activities_temp, + request: 'save_activites', + req_id: this.req[id].id, + activities: this.req[id].activities_temp, - }, ) + }, ) .then((response) => { console.log(response.data); @@ -1080,7 +1133,7 @@ if ($('#requisitions_list').length > 0) { } else { this.req['req'+req_id].is_active_funnels_adjacent = true; this.get_adjacent_funnels_req(req_id); - } + } }, get_adjacent_funnels_req(req_id){ @@ -1088,25 +1141,25 @@ if ($('#requisitions_list').length > 0) { request: 'get_adjacent_funnels_req', agency_id: this.agencyId, req_id: req_id, - + }) - .then((response) => { - if(typeof ac == 'object'){ - ac.closesStep = false; - ac.is_looad = false; - ac.is_load_open = false; - ac.isOpenPrevStep = false; - } - console.log(response.data); - if(response.data.html){ - $('#funnels_adjacent_req_'+req_id).html(response.data.html); - } - - - }) - .catch(function(error) { - console.log(error); - }); + .then((response) => { + if(typeof ac == 'object'){ + ac.closesStep = false; + ac.is_looad = false; + ac.is_load_open = false; + ac.isOpenPrevStep = false; + } + console.log(response.data); + if(response.data.html){ + $('#funnels_adjacent_req_'+req_id).html(response.data.html); + } + + + }) + .catch(function(error) { + console.log(error); + }); }, //Открыть карточку объекту @@ -1130,28 +1183,28 @@ if ($('#requisitions_list').length > 0) { const clientHeight = container.clientHeight; const divUl = $(container).find('.kanban__items-list'); - + if(divUl){ for(let i=0; i this.lastScrollTop; //this.lastScrollTop = scrollTop; //console.log(this.isLoading, heigthLi >=clientHeight+scrollTop-250); - if (heigthLi >=clientHeight+scrollTop-250 && !this.isLoading) { + if (heigthLi >=clientHeight+scrollTop-250 && !this.isLoading) { this.isLoading = true; // Устанавливаем флаг загрузки console.log('loading reqs li'); this.page = this.page + 1; await this.getList(); this.isLoading = false; - - + + } } } @@ -1159,24 +1212,159 @@ if ($('#requisitions_list').length > 0) { const isScrollingDown = scrollTop > this.lastScrollTop; this.lastScrollTop = scrollTop; // Обновляем позицию скролла - - // Проверка с учетом зазора в 50 пикселей - //if(this.userId != 5238){ - if (isScrollingDown && scrollTop + clientHeight >= scrollHeight - 50 && !this.isLoading) { - this.isLoading = true; // Устанавливаем флаг загрузки - console.log('loading reqs'); - this.page = this.page + 1; - await this.getList(); - this.isLoading = false; - } - // } + + // Проверка с учетом зазора в 50 пикселей + //if(this.userId != 5238){ + if (isScrollingDown && scrollTop + clientHeight >= scrollHeight - 50 && !this.isLoading) { + this.isLoading = true; // Устанавливаем флаг загрузки + console.log('loading reqs'); + this.page = this.page + 1; + await this.getList(); + this.isLoading = false; + } + // } }, - + + // Открыть модалку копирования: preview-запрос → defaults + warnings. + // Списки воронок/сотрудников приходят из window.__copyFunnelsList / window.__copyEmployeesList (server-embed в requisitions.php). + openCopyRequisitionModal: function(reqId) { + var self = this; + var preFunnels = Array.isArray(window.__copyFunnelsList) ? window.__copyFunnelsList : []; + var preEmployees = Array.isArray(window.__copyEmployeesList) ? window.__copyEmployeesList : []; + var employeesNormalized = preEmployees.map(function (e) { + return { + id: parseInt(e.id, 10), + name: e.name, + group: e.group || null, + }; + }); + // Полное переприсваивание copyModal — чтобы Vue точно зарегистрировал изменения всех полей. + self.copyModal = { + open: true, + srcId: reqId, + funnels: preFunnels.map(function (f) { + return { id: parseInt(f.id, 10), name: f.name }; + }), + funnelId: null, + employees: employeesNormalized, + whoWorkId: null, + whoWorkSearch: '', + whoWorkOpen: false, + whoWorkLabel: '', + defaultWhoWorkId: null, + warnings: [], + submitting: false, + error: null, + }; + + axios.post('/ajax/ajax_vue_requisitions.php', {request: 'copy_preview', req_id: reqId}) + .then(function (res) { + if (!res.data.success) { + self.copyModal.error = res.data.error || 'Не удалось загрузить данные'; + return; + } + self.copyModal.warnings = res.data.warnings || []; + // Дефолтная воронка — из исходной заявки; если недоступна юзеру — fallback на первую. + var defaultFunnelId = res.data.default_funnel_id; + var funnelMatch = self.copyModal.funnels.find(function (f) { + return parseInt(f.id, 10) === parseInt(defaultFunnelId, 10); + }); + if (funnelMatch) { + self.copyModal.funnelId = parseInt(defaultFunnelId, 10); + } else if (self.copyModal.funnels.length > 0) { + self.copyModal.funnelId = self.copyModal.funnels[0].id; + } else { + self.copyModal.funnelId = null; + } + self.copyModal.defaultWhoWorkId = res.data.default_who_work_id; + // Дефолтный ответственный — из preview; иначе первая опция списка. + var defaultId = res.data.default_who_work_id; + var hasInList = employeesNormalized.some(function (e) { return e.id === parseInt(defaultId, 10); }); + var chosenId = hasInList + ? parseInt(defaultId, 10) + : (employeesNormalized.length > 0 ? employeesNormalized[0].id : null); + self.copyModal.whoWorkId = chosenId; + // whoWorkLabel — отображаемое имя в свернутом поле; whoWorkSearch держим пустым. + var chosenEmp = employeesNormalized.find(function (e) { return e.id === chosenId; }); + self.copyModal.whoWorkLabel = chosenEmp ? chosenEmp.name : ''; + self.copyModal.whoWorkSearch = ''; + self.copyModal.whoWorkOpen = false; + }) + .catch(function () { + self.copyModal.error = 'Сетевая ошибка'; + }); + }, + + // Выбор сотрудника. Сбрасываем whoWorkSearch — следующий раз показать полный список. + selectCopyWhoWork: function(emp) { + this.copyModal.whoWorkId = emp.id; + this.copyModal.whoWorkLabel = emp.name; + this.copyModal.whoWorkSearch = ''; + this.copyModal.whoWorkOpen = false; + }, + + // Отправка копии: создаёт новую заявку и обновляет список. + submitCopy: function() { + var self = this; + if (self.copyModal.submitting) return; + + var whoWorkId = parseInt(self.copyModal.whoWorkId, 10); + + // funnel_id может быть 0 («Обычные») — проверяем именно на null/undefined. + // who_work_id может быть 0 («Всё агентство») — проверяем только NaN. + if (isNaN(whoWorkId) || self.copyModal.funnelId === null || self.copyModal.funnelId === undefined) { + self.copyModal.error = 'Заполните воронку и ответственного'; + return; + } + + self.copyModal.submitting = true; + self.copyModal.error = null; + + axios.post('/ajax/ajax_vue_requisitions.php', { + request: 'copy', + req_id: self.copyModal.srcId, + funnel_id: self.copyModal.funnelId, + who_work_id: whoWorkId, + }).then(function (res) { + self.copyModal.submitting = false; + if (!res.data.success) { + self.copyModal.error = res.data.error || 'Не удалось создать копию'; + return; + } + self.copyModal.open = false; + if (typeof window.jwShowCopyToast === 'function') { + window.jwShowCopyToast('Копия заявки создана'); + } + if (typeof self.getList === 'function') self.getList(); + }).catch(function () { + self.copyModal.submitting = false; + self.copyModal.error = 'Сетевая ошибка'; + }); + }, + + // Закрыть модалку копирования — никаких Select2 destroy, просто скрываем. + closeCopyModal: function() { + this.copyModal.open = false; + }, + + // Закрытие picker сотрудников по клику вне него (mousedown, чтобы опередить click внутри). + onCopyModalDocumentClick: function(e) { + if (!this.copyModal.whoWorkOpen) return; + var picker = this.$refs && this.$refs.copyWhoWorkPicker; + if (picker && (picker === e.target || picker.contains(e.target))) return; + this.copyModal.whoWorkOpen = false; + }, + }, mounted() { if (document.location.pathname == '/requisitions.php') { - + } + document.addEventListener('mousedown', this.onCopyModalDocumentClick); + }, + beforeDestroy: function() { + // Снимаем document-level слушатель, чтобы не утекал при пересборке инстанса. + document.removeEventListener('mousedown', this.onCopyModalDocumentClick); }, created: function() { //this.getList(); @@ -1288,7 +1476,7 @@ var req_form = new Vue({ //Открыть форму openReqForm(no_clear) { - + this.is_looad = false; this.isClear = false; @@ -1297,7 +1485,7 @@ var req_form = new Vue({ } else { this.clearReq(); } - + if ( $('input[name=complex_room_id]').length) { this.selectedType = +this.selectedType ? this.selectedType : 1; $('#status').show() @@ -1317,10 +1505,10 @@ var req_form = new Vue({ if ($('input[name=complex_room_id]').length) { this.getStatuses(4); } - + if (document.location.pathname == '/requisitions.php' && $('#funnelIdClients').length > 0) { this.funnel_id = $('#funnelIdClients').val(); - + this.getFunnel(this.funnel_id); } else if (this.funnel_id === undefined || this.funnel_id == 0 || isNaN(this.funnel_id)) { @@ -1333,7 +1521,7 @@ var req_form = new Vue({ req_form.getReqFields(); }) } else { - + this.getFunnel(this.funnel_id); } this.getReqFields(); @@ -1342,7 +1530,7 @@ var req_form = new Vue({ $("#req_form .tabs__content").removeAttr("style"); this.isReqForm = true; - // console.log(this); + // console.log(this); $("body").addClass("lock"); $('.jw__add-popup').removeClass('is__show'); }, @@ -1430,7 +1618,7 @@ var req_form = new Vue({ this.getSources(req.source); this.getPartner(req.employee_id); - if ( !$('input[name=complex_room_id]').length) { + if ( !$('input[name=complex_room_id]').length) { if (!this.isEmpty(req.complex_room_id)) { const reqForm = document.querySelector('#req_form') if (reqForm) { @@ -1438,7 +1626,7 @@ var req_form = new Vue({ input.type = 'hidden'; input.name = 'complex_room_id'; input.value = req.complex_room_id; - + reqForm.appendChild(input) } } @@ -1451,7 +1639,7 @@ var req_form = new Vue({ $('#status').show() this.getStatuses(req.complex_status_id) } - + this.hot = req.hot; if (req.activities) { this.getActivities(req.activities_temp); @@ -1460,7 +1648,7 @@ var req_form = new Vue({ }, - + //Получение дополнительных полей getReqFields() { console.log(this.funnel_id); @@ -1535,9 +1723,9 @@ var req_form = new Vue({ //console.log(this.user_id); $("#req-new-object-input").html(''); axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_objects', - user_id: this.user_id, - }, ) + request: 'get_objects', + user_id: this.user_id, + }, ) .then((response) => { $("#req-new-object-input").html(response.data); @@ -1550,12 +1738,12 @@ var req_form = new Vue({ //console.debug(val.value); req_form.getObjPrices(val.value); axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_client', - client_id: 0, - object_id: val.value - }, ) + request: 'get_client', + client_id: 0, + object_id: val.value + }, ) .then((response) => { - // console.log(response.data); + // console.log(response.data); if (!req_form.isEmpty(response.data)) { $("#req-new-client-input").html(''); req_form.client = response.data; @@ -1582,9 +1770,9 @@ var req_form = new Vue({ getObjectFind(who_work, obj) { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_objects_find', - object_id: this.objectId, - }, ) + request: 'get_objects_find', + object_id: this.objectId, + }, ) .then((response) => { console.log(response.data); this.findObj = response.data; @@ -1672,14 +1860,14 @@ var req_form = new Vue({ }, showClientPhoneInput() { - + this.inputClientPhone = true; this.newClientPhone = ''; this.is_national_phone = false; this.dopPhonesClient = this.clientSelect.phones_dop; this.is_error_dop_phone = false; $('.ui-tooltip.ui-widget').remove(); - + }, hideClientPhoneInput() { this.inputClientPhone = false; @@ -1690,7 +1878,7 @@ var req_form = new Vue({ $('.ui-tooltip.ui-widget').remove(); }, checkIsNationalPhone(){ - + this.newClientPhone = ''; }, @@ -1719,7 +1907,7 @@ var req_form = new Vue({ this.newClientPhone = ''; this.clientSelect.phones_dop = this.dopPhonesClient; } - + }).catch(function(error) { if (error) console.debug(error); @@ -1806,18 +1994,18 @@ var req_form = new Vue({ funnel_id: this.funnel_id, user_id: this.user_id, }) - .then((response) => { - //console.log(response.data); - $('#req-new-client-work-input-div').html(response.data); - $("#req-new-client-work").val(who_work); - $('#req-new-client-work').fastselect({ - placeholder: 'Ответственный', - onItemCreate: function() { $(this).find('.fstQueryInput').hide() }, - }); - }) - .catch(function(error) { - console.error(error); + .then((response) => { + //console.log(response.data); + $('#req-new-client-work-input-div').html(response.data); + $("#req-new-client-work").val(who_work); + $('#req-new-client-work').fastselect({ + placeholder: 'Ответственный', + onItemCreate: function() { $(this).find('.fstQueryInput').hide() }, }); + }) + .catch(function(error) { + console.error(error); + }); } else { if ($('#req-new-client-work').length < 1) { @@ -1976,9 +2164,9 @@ var req_form = new Vue({ getClient(client_id, forma) { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_client', - client_id: client_id - }, ) + request: 'get_client', + client_id: client_id + }, ) .then((response) => { console.log(response.data); this.client = response.data; @@ -2015,13 +2203,13 @@ var req_form = new Vue({ //Получение типов заявок getTypes() { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_type', - agency_id: this.agency_id, - active: 1, - no_archive: 1 - }, + request: 'get_type', + agency_id: this.agency_id, + active: 1, + no_archive: 1 + }, - ) + ) .then((response) => { // console.log(response.data); this.types_req = response.data.type; @@ -2039,7 +2227,7 @@ var req_form = new Vue({ params.selector = 'req-new-funnel'; params.section = 'req'; - + $('#req-new-funnel-input').html(''); if ($('#req-new-funnel').length < 1) { axios.post('/ajax/select_form_funnel.php', params) @@ -2056,7 +2244,7 @@ var req_form = new Vue({ console.error(error); }); } else { - + $('#req-new-funnel').fastselect().data('fastselect').destroy(); $("#req-new-funnel").val(funnelId); $("#req-new-funnel option[value='" + funnelId + "']").prop("selected", true); @@ -2117,9 +2305,9 @@ var req_form = new Vue({ search_val = search; } axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_clients_list', - search: search_val, - }) + request: 'get_clients_list', + search: search_val, + }) .then((response) => { //console.log(response.data); this.clients = response.data; @@ -2356,7 +2544,7 @@ var req_form = new Vue({ old_whowork: this.who_work, hot: this.hot, activities: tags, - // source: $("#ms-req-source").val(), + // source: $("#ms-req-source").val(), employee_id: $("#ms-req-partner").val(), status: statusId, complex_room_id: apartmentId, @@ -2372,7 +2560,7 @@ var req_form = new Vue({ confirm_recommendation: this.confirm_recommendation, friend_client_id: this.friend_client_id, is_manual: 1 - } + } if(this.source_see == 1){ params.source = $("#ms-req-source").val(); } @@ -2386,7 +2574,7 @@ var req_form = new Vue({ this.errorText += "

    " + res.mes + "

    "; $('.full_modal-bg').stop().animate({ scrollTop: 0 }, '500'); } else { - + let req_id = parseInt(res.req_id); autosearch_filtr.setReqToFilter(req_id, this.autosearch_filter_id); this.closeReqform(); @@ -2478,7 +2666,7 @@ var req_form = new Vue({ this.contracts = []; this.heir = 0; this.confirm_recommendation = null, - this.friend_client_id = 0 + this.friend_client_id = 0 }, selectType(val) { @@ -2720,10 +2908,10 @@ var req_form = new Vue({ }, - //Поиск и сравнение + //Поиск и сравнение isFindValue(val1, val2){ let res = false; - + if(!this.isEmpty(val2)){ if(Array.isArray(val2)){ for(let i=0; i 0) { methods: { //Список getFilter(clear) { - + this.filtr = { search: "", stages: { 'work': 1, 'hot': 0, 'close': 0, 'hit': 0, 'ahency': 0, 'confirm': 0, 'send': 0 }, @@ -2909,9 +3098,9 @@ if ($('#req_filtr').length > 0) { //Типы договоров getTypesContract() { axios.post('/ajax/ajax_vue_contract.php', { - request: 'get_types_contract', - agency_id: this.agency_id, - }, ) + request: 'get_types_contract', + agency_id: this.agency_id, + }, ) .then((response) => { this.types_contract = response.data; }) @@ -2923,11 +3112,11 @@ if ($('#req_filtr').length > 0) { //Типы недвижимости getPropertyType() { axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_property_types' + request: 'get_property_types' }).then((response) => { //console.log(response.data); this.property_types = response.data; - + }).catch(function(error) { console.log(error); @@ -3069,11 +3258,11 @@ if ($('#req_filtr').length > 0) { }, searchButtonClick() { - + this.checkFiltr(); this.search(0); $('.crm__filter-popup').removeClass("is__show"); - + }, //Поиск @@ -3086,7 +3275,7 @@ if ($('#req_filtr').length > 0) { if(this.filtr.order === false || this.filtr.order == 0){ $('#sort_order_req').val(2); } - } + } if (isLupa && !requisitions.isKanban) { requisitions.funnel_id = 'all'; } else { @@ -3106,12 +3295,12 @@ if ($('#req_filtr').length > 0) { $('.transfer_reqs_closed').show(); } if (this.filtr.stages.ahency == 1 || this.filtr.stages.confirm == 1) { - + $('.confirm_on_reqs').show(); - + $('#popup__reqs .closed_all').hide(); - - + + } else { if (this.filtr.stages.close == 0){ $('#popup__reqs .closed_all').show(); @@ -3200,7 +3389,7 @@ if ($('#req_filtr').length > 0) { }, checkFiltr() { - + var denial = $('#req_denial_work').val(); this.filtr.denial = denial; console.log(decodeURI(window.location.search)); @@ -3216,7 +3405,7 @@ if ($('#req_filtr').length > 0) { if (queryParams) { console.log(queryParams); - + if (queryParams.emp !== undefined) { this.filtr.userId = queryParams.emp; } else if(queryParams.responsible !== undefined){ @@ -3295,20 +3484,20 @@ if ($('#req_filtr').length > 0) { var tempemp = $("#req_filter_emp").val(); var emp = []; - + if(!this.isEmpty(tempemp)){ for(var i=0; i < tempemp.length; i++){ - - emp.push(tempemp[i].replace('I_','')); + + emp.push(tempemp[i].replace('I_','')); } } - + this.filtr.emp = emp; var types = $('#filter-req-type').val(); this.filtr.type = types; var step = $('#req_filter_etap').val(); this.filtr.step = step; - + if (period == 'period') { $('#reqDates').removeClass('hidden'); @@ -3329,7 +3518,7 @@ if ($('#req_filtr').length > 0) { this.filtr.offDateContract = offDateContract; this.filtr.onDateStep = $('#dateStepReqOnDate').val(); this.filtr.offDateStep = $('#dateStepReqOffDate').val(); - + this.tempModel = {}; if (!this.isEmpty(this.filtr.fields)) { @@ -3338,11 +3527,11 @@ if ($('#req_filtr').length > 0) { this.$set(this.tempModel, index, this.filtr.fields[index]); } } - + } console.log(this.filtr); - + this.checkFields(); this.get_option(); @@ -3431,18 +3620,18 @@ if ($('#req_filtr').length > 0) { } }, - getViews(){ + getViews(){ axios.post('/ajax/ajax_vue_requisitions.php', { request: 'get_view_page', user_id: this.user_id, - }, ).then((response) => { - console.log(response.data); - this.viewUser = response.data.view; - this.view = response.data.view; - this.search(); - }).catch(function(error) { - console.error(error); - }) + }, ).then((response) => { + console.log(response.data); + this.viewUser = response.data.view; + this.view = response.data.view; + this.search(); + }).catch(function(error) { + console.error(error); + }) }, setViews(view){ @@ -3450,21 +3639,21 @@ if ($('#req_filtr').length > 0) { request: 'set_view_page', user_id: this.user_id, view: view - }, ).then((response) => { - console.log(response.data); - - }).catch(function(error) { - console.error(error); - }) + }, ).then((response) => { + console.log(response.data); + + }).catch(function(error) { + console.error(error); + }) if(this.view != view) { requisitions.view = view; requisitions.getList(); - } + } this.viewUser = view; this.view = view; - }, + }, + - //Проверка на пустоту isEmpty(data) { @@ -3489,7 +3678,7 @@ if ($('#req_filtr').length > 0) { }, mounted() { - + if (document.location.pathname == '/requisitions.php') { this.getTypesContract(); this.getPropertyType(); @@ -3503,11 +3692,11 @@ if ($('#req_filtr').length > 0) { } this.checkFiltr(); this.getViews(); - - - /* if (localStorage['view_req']) { - this.view = localStorage['view_req']; - }*/ + + + /* if (localStorage['view_req']) { + this.view = localStorage['view_req']; + }*/ } else { localStorage.removeItem('req_filter'); @@ -3584,12 +3773,12 @@ if ($("#client_fields").length > 0) { var agencyID = $('#agencyIdClients').val(); axios.post('/ajax/ajax_vue_fields.php', { - request: 'add_edit', - client_id: client_id, - field_models: poles, - }, + request: 'add_edit', + client_id: client_id, + field_models: poles, + }, - ) + ) .then((response) => { refreshCalendar(); console.log(response.data); @@ -3610,7 +3799,7 @@ if ($("#client_fields").length > 0) { //Поиск и сравнение isFindValue(val1, val2){ let res = false; - + if(!this.isEmpty(val2)){ if(Array.isArray(val2)){ for(let i=0; i 0) { } } } - + return res; }, @@ -3763,9 +3952,9 @@ if ($("#client_fields_filtr").length > 0) { //Типы договоров getTypesContract() { axios.post('/ajax/ajax_vue_contract.php', { - request: 'get_types_contract', - agency_id: this.agency_id, - }, ) + request: 'get_types_contract', + agency_id: this.agency_id, + }, ) .then((response) => { this.types_contract = response.data; }) @@ -3883,9 +4072,9 @@ if ($('#object-new-client-input-vue').length > 0) { } axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_clients_list', - search: search_val, - }) + request: 'get_clients_list', + search: search_val, + }) .then((response) => { // console.log(response.data); this.clients = response.data; @@ -3909,9 +4098,9 @@ if ($('#object-new-client-input-vue').length > 0) { if (parseInt(client_id) > 0) { // $("#object-new-client-vue").val(client_id); axios.post('/ajax/ajax_vue_requisitions.php', { - request: 'get_client', - client_id: client_id - }, ) + request: 'get_client', + client_id: client_id + }, ) .then((response) => { console.log(response.data); var this_client = response.data;