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;