Actual prod

This commit is contained in:
mac 2026-07-03 10:04:01 +03:00
parent 1c5027406b
commit b14570835a
2 changed files with 179 additions and 110 deletions

View File

@ -4836,6 +4836,36 @@
$sql = "SELECT * FROM `requisitions` WHERE id = $id";
$requisistion = $this->db->fetch_assoc($this->db->query($sql));
// Вычисляем последний этап воронки
$lastStage = 8; // значение по умолчанию
$funnelId = intval($requisistion['funnel_id']);
if ($funnelId > 0) {
$q_step = $this->db->query("SELECT MAX(order_number) as last_stage FROM funnel_steps WHERE funnel_id = $funnelId AND deleted = 0");
if ($q_step && $this->db->num_rows($q_step) > 0) {
$r_step = $this->db->fetch_assoc($q_step);
if ($r_step['last_stage'] !== null) {
$lastStage = intval($r_step['last_stage']);
}
}
} else {
// funnel_id = 0 — дефолтная воронка, берём по agency_id
$agencyId = $this->user->agencyId;
$q_default = $this->db->query("SELECT id FROM funnel_default WHERE agency_id = $agencyId LIMIT 1");
if ($q_default && $this->db->num_rows($q_default) > 0) {
$r_default = $this->db->fetch_assoc($q_default);
$defaultFunnelId = intval($r_default['id']);
if ($defaultFunnelId > 0) {
$q_step = $this->db->query("SELECT MAX(order_number) as last_stage FROM funnel_steps WHERE funnel_id = $defaultFunnelId AND deleted = 0");
if ($q_step && $this->db->num_rows($q_step) > 0) {
$r_step = $this->db->fetch_assoc($q_step);
if ($r_step['last_stage'] !== null) {
$lastStage = intval($r_step['last_stage']);
}
}
}
}
}
if ($requisistion['complex_status_id'] && $requisistion['complex_room_id'])
{
$complexStatus = new ComplexStatus((int)$requisistion['complex_status_id']);
@ -4845,11 +4875,12 @@
], false, false);
}
$sql = "UPDATE requisitions SET reason='".$select_text.". ".$post['reason']."', who_delete = '$user_id', deleted=1, stage=8, denial = $post[denial] WHERE id=$id";
$sql = "UPDATE requisitions SET reason='".$select_text.". ".$post['reason']."', who_delete = '$user_id', deleted=1, stage=$lastStage, denial = $post[denial] WHERE id=$id";
if(isset($post['summa']) && $post['luck']){
if($dop_text != '') $dop_text .= " ";
$dop_text1 .= "Совершена сделка на ".$post['summa']." руб. ".$formatted_dateZajavki;
$sql = "UPDATE requisitions SET reason='$post[reason]', who_delete = '$user_id', deleted=1, summa='$post[summa]', confirm='$post[luck]' WHERE id=$id";
$commission = isset($post['commission']) ? intval($post['commission']) : 0;
$dop_text1 = "Совершена сделка на ".$commission." руб. ".$formatted_dateZajavki;
$sql = "UPDATE requisitions SET reason='".$dop_text1."', who_delete = '$user_id', deleted=1, summa='$post[summa]', confirm='$post[luck]' WHERE id=$id";
}
if ($this->db->query($sql)) {

252
js/crm.js
View File

@ -1772,7 +1772,7 @@ function editEvent(id, type, client_id, req_id) {
return false;
}
function editEventObj(id, type) {
function editEventObj(id, type, object_id) {
if (type != 'comment') {
$("#addTaskBgObj").show();
@ -1828,7 +1828,10 @@ function editEventObj(id, type) {
}
} else {
$.post("/ajax/getEventForObjId.php", { event_id: id }, function(data) {
// object_id (id найденного листинга) — чтобы getEventForObjId читал external_listing_events,
// а не чужую user_object_events при пересечении id; res.object_id вернётся id листинга и save (changeEventsObj)
// уйдёт в листинговую таблицу.
$.post("/ajax/getEventForObjId.php", { event_id: id, object_id: object_id }, function(data) {
var res = JSON.parse(data);
//console.log(type);
@ -1918,8 +1921,8 @@ function editEventObj(id, type) {
}
function editNoteObj(id) {
$.post("/ajax/getNoteForObjId.php", { note_id: id }, function(data) {
function editNoteObj(id, object_id) {
$.post("/ajax/getNoteForObjId.php", { note_id: id, object_id: object_id }, function(data) {
let res = JSON.parse(data);
//console.log(data);
@ -2107,21 +2110,27 @@ function sendEventFilesWin(id, from) {
$("body").addClass("lock");
}
function deleteEvent(id, from) {
if (confirm("Вы точно хотите удалить эту задачу?")) {
$.post('/ajax/deleteEvent.php', {
deleteId: id,
from: from || null
}, function() {
if ($('#chat_content_' + id).length > 0) {
$('#chat_content_' + id).closest('.chat-block').remove();
}
$("#merepriation_bg").hide();
$("#merepriation-history").hide();
$("body").removeClass("lock");
getCalendar();
});
}
function deleteEvent(id, from, kind) {
var isFile = (kind === 'file');
jwConfirm({
title: isFile ? 'Удаление файлов' : 'Удаление задачи',
text: isFile ? 'Вы точно хотите удалить эти файлы?' : 'Вы точно хотите удалить эту задачу?',
btnText: 'Удалить',
onConfirm: function() {
$.post('/ajax/deleteEvent.php', {
deleteId: id,
from: from || null
}, function() {
if ($('#chat_content_' + id).length > 0) {
$('#chat_content_' + id).closest('.chat-block').remove();
}
$("#merepriation_bg").hide();
$("#merepriation-history").hide();
$("body").removeClass("lock");
getCalendar();
});
}
});
}
function showEventSubComment(id, from, event, sub_id) {
@ -2171,6 +2180,9 @@ function showEventSubComment(id, from, event, sub_id) {
}
function addEventSubComment(id, from, id_object, req_id, type = null) {
// листинг: id_object приходит числовым el.id без маркера; помечаем EXT-{n}, иначе reload панелей
// (getObjectInfoForEvents/getLogForEvents) примет el.id за objects.id (коллизия) → пустые паны (белая модалка)
if (from === 'listing' && String(id_object).indexOf('EXT-') !== 0) id_object = 'EXT-' + id_object;
user_for = 0;
if (!isEmpty(type) && type == 'moderation') {
user_for = $('#sub_comment_who_work_' + id).val();
@ -2215,75 +2227,95 @@ function addEventSubComment(id, from, id_object, req_id, type = null) {
}
function deleteEventSubComment(id, from, id_object, sub_id) {
// листинг: id_object приходит числовым el.id без маркера; помечаем EXT-{n}, иначе reload панелей
// (getObjectInfoForEvents/getLogForEvents) примет el.id за objects.id (коллизия) → пустые паны (белая модалка)
if (from === 'listing' && String(id_object).indexOf('EXT-') !== 0) id_object = 'EXT-' + id_object;
var subId = 0;
if (!isEmpty(sub_id)) {
subId = sub_id;
}
if (confirm("Вы точно хотите удалить комментарий МОП?")) {
$.post('/ajax/deleteEventSubComment.php', {
eventId: id,
from: from || null,
sub_id: subId
}, function() {
$.ajax({
url: '/ajax/getObjectInfoForEvents.php?id=' + id_object,
success: function(data) {
$('#object-info-block').html(data);
jwConfirm({
title: 'Удаление комментария',
text: 'Вы точно хотите удалить комментарий?',
btnText: 'Удалить',
onConfirm: function() {
$.post('/ajax/deleteEventSubComment.php', {
eventId: id,
from: from || null,
sub_id: subId
}, function() {
$.ajax({
url: '/ajax/getObjectInfoForEvents.php?id=' + id_object,
success: function(data) {
$('#object-info-block').html(data);
$.ajax({
url: '/ajax/getLogForEvents.php?object_id=' + id_object,
success: function(data) {
$('#event-chat').html(data);
$('.history__chat').scrollTop($('#event-chat').prop("scrollHeight"));
}
});
$.ajax({
url: '/ajax/getLogForEvents.php?object_id=' + id_object,
success: function(data) {
$('#event-chat').html(data);
$('.history__chat').scrollTop($('#event-chat').prop("scrollHeight"));
}
});
setTimeout(function() {
$('#object-info-block .fotorama').fotorama();
initializeMapOnEventWindow();
}, 100);
}
setTimeout(function() {
$('#object-info-block .fotorama').fotorama();
initializeMapOnEventWindow();
}, 100);
}
});
});
});
}
}
});
}
function deleteNoteObj(id) {
if (confirm("Вы точно хотите удалить данное примечание?")) {
$.post('/ajax/deleteNote.php', {
deleteId: id
}, function() {
function deleteNoteObj(id, from) {
jwConfirm({
title: 'Удаление примечания',
text: 'Вы точно хотите удалить данное примечание?',
btnText: 'Удалить',
onConfirm: function() {
// from='listing' → удаление в external_listing_notes, иначе object_notes (id-нумерации разные)
$.post('/ajax/deleteNote.php', {
deleteId: id,
from: from || 'objects'
}, function() {
if ($('#chat_content_' + id).length > 0) {
if ($('#chat_content_' + id).length > 0) {
let chat = $('#chat_content_' + id).closest('#object-notes');
let object_id = chat.find('#submitTextButton2').data('id');
$('#chat_content_' + id).closest('.chat-block').remove();
if (chat.find('.chat-block').length == 0)
$('.addEditNote[data-id="' + object_id + '"]').removeClass('haveNotes');
let chat = $('#chat_content_' + id).closest('#object-notes');
let object_id = chat.find('#submitTextButton2').data('id');
$('#chat_content_' + id).closest('.chat-block').remove();
if (chat.find('.chat-block').length == 0)
$('.addEditNote[data-id="' + object_id + '"]').removeClass('haveNotes');
}
}
$("body").removeClass("lock");
});
}
$("body").removeClass("lock");
});
}
});
}
//Отменить задачу
function cancelEvent(id) {
if (confirm("Вы точно хотите отменить эту задачу?")) {
$.post('/ajax/cancelEvent.php', { cancelId: id }, function() {
if ($('#chat_content_' + id).length > 0) {
$('#chat_content_' + id).closest('.chat-message').addClass('cancel');
}
$('#groupAB__' + id).attr("data-cancel", "1");
jwConfirm({
title: 'Отмена задачи',
text: 'Вы точно хотите отменить эту задачу?',
btnText: 'Отменить задачу',
onConfirm: function() {
$.post('/ajax/cancelEvent.php', { cancelId: id }, function() {
if ($('#chat_content_' + id).length > 0) {
$('#chat_content_' + id).closest('.chat-message').addClass('cancel');
}
$('#groupAB__' + id).attr("data-cancel", "1");
/*$("#merepriation_bg").hide();
$("#merepriation-history").hide();
$("body").removeClass("lock");*/
getCalendar();
});
}
/*$("#merepriation_bg").hide();
$("#merepriation-history").hide();
$("body").removeClass("lock");*/
getCalendar();
});
}
});
}
//Для фильтра клиентов в отправке презентаций
@ -3418,6 +3450,9 @@ function get_select_who_work_task(selector, section, id){
id = $('#submitTextButton').attr('data-id');
}
// offset-free: для найденного листинга (section=object) ответственного берём по иерархии видимости, а не по
// владельцу objects-строки (её нет, el.id коллизит). Маркер листинга — data-src="ext" окна задач (openEventsWindow).
var isExternal = (section == 'object') && ($('#submitTextButton').attr('data-src') === 'ext');
$(selector+" .check_who_work").html('<img src="../images/rocket-spinner.svg" width="45px">');
if(id > 0) {
@ -3425,7 +3460,8 @@ function get_select_who_work_task(selector, section, id){
axios.post('/ajax/select_form_who_work_tasks.php',
{
id: id,
section: section
section: section,
is_external: isExternal ? 1 : 0
}
).then((response) => {
@ -4423,6 +4459,8 @@ $(document).ready(function() {
$('body').on('click', '.complete-action-button-obj', function() {
var event_id = $(this).attr('id').replace('groupAB__', '');
// событие найденного листинга парсера завершается в своей таблице (data-from='listing'), иначе user_object_events
var from = $(this).attr('data-from') || 'objects';
var done = 0;
$(this).toggleClass('active');
@ -4430,7 +4468,7 @@ $(document).ready(function() {
done = 1;
}
//console.log(done);
$.post('/ajax/addEditObject.php', { done_event: event_id, done: done }, function(data) {
$.post('/ajax/addEditObject.php', { done_event: event_id, done: done, from: from }, function(data) {
//console.log(data);
if (typeof type_calendar == 'object') {
@ -6249,11 +6287,12 @@ $(document).ready(function() {
if (window.dealCloseData && window.dealCloseData.id) {
param.luck = 10;
var factPrice = $('#fact_contract_price').val();
var factCommission = $('#fact_agent_commission').val();
param.summa = (factPrice !== '' && !isNaN(parseInt(factPrice))) ? parseInt(factPrice) : (window.dealCloseData.contract_price || 0);
param.commission = (factCommission !== '' && !isNaN(parseInt(factCommission))) ? parseInt(factCommission) : (window.dealCloseData.agent_commission || 0);
param.datazakl = Date.parse(dataZZ);
var factPayload = {};
var factCommission = $('#fact_agent_commission').val();
if (factPrice !== '' && !isNaN(parseInt(factPrice))) factPayload.contract_price = parseInt(factPrice) || 0;
if (factCommission !== '' && !isNaN(parseInt(factCommission))) factPayload.agent_commission = parseInt(factCommission) || 0;
if (Object.keys(factPayload).length > 0) {
@ -6264,7 +6303,7 @@ $(document).ready(function() {
data: JSON.stringify(factPayload)
});
}
} else {Про
} else {
if (isNaN(parseInt($('#summa_sdelki').val()))) {
alert("Введите сумму сделки");
return;
@ -6275,46 +6314,45 @@ $(document).ready(function() {
}
$.post('/ajax/delClient.php', param, function(data) {
//console.log(data)
$('#client__' + id_client + ' .stage').addClass('active');
$('#addEditNew .stage').addClass('active');
requisitions_client.getList();
$("#del_client_bg").fadeOut(500);
$("#del_client").toggle(10);
$("body").removeClass("lock");
//$('#client__'+id_client+' .stagebar-title').text('Закрыт');
//console.log($('#client_history').css('display'));
if ($('#client_history').css('display') != 'none') {
if (req_id > 0) {
openClientEventsWindowNew(0, $('#session_to_send').val(), 1, req_id);
} else {
openClientEventsWindowNew(id_client, $('#session_to_send').val(), 1);
}
//console.log(data)
$('#client__' + id_client + ' .stage').addClass('active');
$('#addEditNew .stage').addClass('active');
requisitions_client.getList();
$("#del_client_bg").fadeOut(500);
$("#del_client").toggle(10);
$("body").removeClass("lock");
//$('#client__'+id_client+' .stagebar-title').text('Закрыт');
//console.log($('#client_history').css('display'));
if ($('#client_history').css('display') != 'none') {
if (req_id > 0) {
openClientEventsWindowNew(0, $('#session_to_send').val(), 1, req_id);
} else {
openClientEventsWindowNew(id_client, $('#session_to_send').val(), 1);
}
if ($('.view-kanban.active').length > 0) {
}
if ($('.view-kanban.active').length > 0) {
var stage = $('#kanban_item_li_' + id_client).closest('.kanban__sortable').data("stage");
var stage = $('#kanban_item_li_' + id_client).closest('.kanban__sortable').data("stage");
if (document.location.pathname == '/requisitions.php') {
requisitions.getList();
} else {
get_kanban_li(id_client, stage, 0);
}
} else {
if ($('#requisitions_list_object').css('display') == 'none') {
let sort_order = $('select[name=sort_order]').val();
get_list($('.pagination li.active a').text(), sort_order, false);
if (document.location.pathname == '/requisitions.php') {
requisitions.getList();
} else {
get_kanban_li(id_client, stage, 0);
}
} else {
if ($('#requisitions_list_object').css('display') == 'none') {
let sort_order = $('select[name=sort_order]').val();
get_list($('.pagination li.active a').text(), sort_order, false);
if (document.location.pathname == '/requisitions.php') {
requisitions.getList();
}
} else {
requisitions_object.getList();
requisitions_object.getList();
}
}
$('#del_client #temp_id').val(0);
});
}
}
$('#del_client #temp_id').val(0);
});
} else {
param.denial = $('#denial_work').val();
//console.log(reason);
@ -11695,8 +11733,8 @@ function bindObjReq(clientId) {
}
//Открыть модл объекта
function openObjectModal(object_id, zindex) {
object_card.open(object_id, zindex);
function openObjectModal(object_id, zindex, is_external) {
object_card.open(object_id, zindex, is_external);
}
//Проверка на пустату